MADNESS 0.10.1
SCFOperators.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30*/
31
32/// \file SCFOperators.h
33/// \brief Operators for the molecular HF and DFT code
34/// \defgroup chem The molecular density functional and Hartree-Fock code
35
36
37#ifndef MADNESS_CHEM_SCFOPERATORS_H_
38#define MADNESS_CHEM_SCFOPERATORS_H_
39
40#include <madness.h>
41#include <madness/mra/macrotaskq.h> // otherwise issues with install
42
43namespace madness {
44
45// forward declaration
46class SCF;
47class Nemo;
48class NemoBase;
49class OEP;
50class NuclearCorrelationFactor;
51class XCfunctional;
52struct nemo_u1_functors;
53class MacroTaskQ;
54class Molecule;
55
56typedef std::vector<real_function_3d> vecfuncT;
57
58template<typename T, std::size_t NDIM>
60
61public:
63 typedef std::vector<functionT> vecfuncT;
65 mutable nlohmann::json statistics;
66
67 SCFOperatorBase() = default;
68 SCFOperatorBase(std::shared_ptr<MacroTaskQ> taskq) : taskq(taskq) {}
69
70 virtual ~SCFOperatorBase() {}
71
72 std::shared_ptr<MacroTaskQ> taskq=0;
73
74 /// print some information about this operator
75 virtual std::string info() const = 0;
76
77 /// apply this operator on the argument function
78 ///
79 /// \param ket the argument function
80 /// \return op(ket)
81 virtual functionT operator()(const functionT& ket) const = 0;
82
83 /// apply this operator on the argument vector of functions
84
85 /// \param vket argument vector
86 /// \return op(vket)
87 virtual vecfuncT operator()(const vecfuncT& vket) const = 0;
88
89 /// compute the matrix element <bra | op | ket>
90
91 /// \param bra bra state
92 /// \param ket ket state
93 /// \return the matrix element <bra | op | ket>
94 virtual T operator()(const functionT& bra, const functionT& ket) const = 0;
95
96 /// compute the matrix <vbra | op | vket>
97
98 /// \param vbra vector of bra states
99 /// \param vket vector of ket states
100 /// \return the matrix <vbra | op | vket>
101 virtual tensorT operator()(const vecfuncT& vbra, const vecfuncT& vket) const = 0;
102
103};
104
105template<typename T, std::size_t NDIM>
106class Exchange : public SCFOperatorBase<T,NDIM> {
107public:
108
109 class ExchangeImpl;
110 using implT = std::shared_ptr<ExchangeImpl>;
112 typedef std::vector<functionT> vecfuncT;
114private:
116
117public:
121 // print out algorithm
122 friend std::ostream& operator<<(std::ostream& os, const ExchangeAlgorithm& alg) {
123 switch (alg) {
124 case small_memory:
125 os << "smallmem";
126 break;
127 case large_memory:
128 os << "largemem";
129 break;
131 os << "multiworld";
132 break;
134 os << "multiworld_row";
135 break;
136 case fetch_compute:
137 os << "fetch_compute";
138 break;
139 default:
140 os << "unknown algorithm";
141 }
142 return os;
143 }
144
145 static std::string to_string(const ExchangeAlgorithm alg) {
146 std::stringstream ss;
147 ss << alg;
148 return ss.str();
149 }
150
151 static ExchangeAlgorithm string2algorithm(const std::string& alg_string) {
153 std::string alg_lc=commandlineparser::tolower(alg_string);
154 if (alg_lc=="smallmem") alg=small_memory;
155 else if (alg_lc=="largemem") alg=large_memory;
156 else if (alg_lc=="multiworld") alg=multiworld_efficient;
157 else if (alg_lc=="multiworld_row") alg=multiworld_efficient_row;
158 else if (alg_lc=="fetch_compute") alg=fetch_compute;
159 else {
160 std::string msg="unknown Exchange algorithm: "+alg_string;
161 MADNESS_EXCEPTION(msg.c_str(),1);
162 }
163 return alg;
164 }
165
166 Exchange(World& world, const double lo, const double thresh=FunctionDefaults<NDIM>::get_thresh());
167
168 /// ctor with a conventional calculation
169 Exchange(World& world, const SCF *calc, const int ispin);
170
171 /// ctor with a nemo calculation
172 Exchange(World& world, const Nemo *nemo, const int ispin);
173
174 std::string info() const {return "K";}
175
176 bool is_symmetric() const;
177
178 Exchange& set_symmetric(const bool flag);
179
181
182 /// how the cloud will handle the data
184 Exchange& set_macro_task_info(const std::vector<std::string>& info) {
186 return *this;
187 }
188
189
190 Exchange& set_printlevel(const long& level);
191
192 /// batches per rank in the owner-pinned symmetric partition (>= 1)
193 Exchange& set_batch_granularity(const long level);
194
195 /// 1 = gather tile results per subworld, 2 = also gather per node first
196 Exchange& set_accumulation_mode(const int mode);
197
198 /// place tasks by their measured cost rather than by counting them
199 Exchange& set_cost_aware_assignment(const bool flag);
200
201 Exchange& set_taskq(std::shared_ptr<MacroTaskQ> taskq1) {
202 this->taskq=taskq1;
203 return *this;
204 }
205
206 Exchange& set_bra_and_ket(const vecfuncT& bra, const vecfuncT& ket);
207
209 vecfuncT vket(1, ket);
210 vecfuncT vKket = this->operator()(vket);
211 return vKket[0];
212 }
213
214 /// apply the exchange operator on a vector of functions
215
216 /// note that only one spin is used (either alpha or beta orbitals)
217 /// @param[in] vket the orbitals |i> that the operator is applied on
218 /// @return a vector of orbitals K| i>
219 vecfuncT operator()(const vecfuncT& vket) const;
220
221 /// compute the matrix element <bra | K | ket>
222
223 /// @param[in] bra real_function_3d, the bra state
224 /// @param[in] ket real_function_3d, the ket state
225 T operator()(const Function<T, NDIM>& bra, const Function<T, NDIM>& ket) const {
226 return inner(bra, this->operator()(ket));
227 }
228
229 /// compute the matrix < vbra | K | vket >
230
231 /// @param[in] vbra vector of real_function_3d, the set of bra states
232 /// @param[in] vket vector of real_function_3d, the set of ket states
233 /// @return K_ij
234 Tensor<T> operator()(const vecfuncT& vbra, const vecfuncT& vket) const {
235 vecfuncT vKket = this->operator()(vket);
236 World& world=vket[0].world();
237 auto result = matrix_inner(world, vbra, vKket);
238 return result;
239 }
240
241
242};
243
244
245template<typename T, std::size_t NDIM>
246class Kinetic : public SCFOperatorBase<T,NDIM> {
249 typedef std::vector<functionT> vecfuncT;
251
252public:
254 gradop = gradient_operator<T,NDIM>(world);
255 }
256
257 std::string info() const {return "T";}
258
259 functionT operator()(const functionT& ket) const {
260 MADNESS_EXCEPTION("do not apply the kinetic energy operator on a function!",1);
261 return ket;
262 }
263
264 vecfuncT operator()(const vecfuncT& vket) const {
265 MADNESS_EXCEPTION("do not apply the kinetic energy operator on a function!",1);
266 return vket;
267 }
268
269 T operator()(const functionT& bra, const functionT& ket) const {
270 vecfuncT vbra(1,bra), vket(1,ket);
271 Tensor<T> tmat=this->operator()(vbra,vket);
272 return tmat(0l,0l);
273 }
274
275 tensorT operator()(const vecfuncT& vbra, const vecfuncT& vket) const {
276 distmatT dkinetic;
277 if (&vbra==&vket) {
278 dkinetic = kinetic_energy_matrix(world,vbra);
279 } else {
280 dkinetic = kinetic_energy_matrix(world,vbra,vket);
281 }
282 tensorT kinetic(vbra.size(),vket.size());
283 dkinetic.copy_to_replicated(kinetic);
284 return kinetic;
285 }
286
287private:
289 std::vector< std::shared_ptr<Derivative<T,NDIM> > > gradop;
290
293 const vecfuncT & vket) const;
294
295};
296
297
298template<typename T, std::size_t NDIM>
299class DerivativeOperator : public SCFOperatorBase<T,NDIM> {
301 typedef std::vector<functionT> vecfuncT;
303
304public:
305
306 DerivativeOperator(World& world, const int axis1) : world(world), axis(axis1) {
307 gradop = free_space_derivative<T,NDIM>(world, axis);
308 }
309
310 std::string info() const {return "D";}
311
312 functionT operator()(const functionT& ket) const {
313 vecfuncT vket(1,ket);
314 return this->operator()(vket)[0];
315 }
316
317 vecfuncT operator()(const vecfuncT& vket) const {
318 vecfuncT dvket=apply(world, gradop, vket, false);
319 world.gop.fence();
320 return dvket;
321 }
322
323 T operator()(const functionT& bra, const functionT& ket) const {
324 vecfuncT vbra(1,bra), vket(1,ket);
325 Tensor<T> tmat=this->operator()(vbra,vket);
326 return tmat(0l,0l);
327 }
328
329 tensorT operator()(const vecfuncT& vbra, const vecfuncT& vket) const {
330 const auto bra_equiv_ket = &vbra == &vket;
331 vecfuncT dvket=this->operator()(vket);
332 return matrix_inner(world,vbra,dvket, bra_equiv_ket);
333 }
334
335private:
337 int axis;
339
340};
341
342
343/// the Laplacian operator: \sum_i \nabla^2_i
344
345/// note that the application of the Laplacian operator is in general
346/// unstable and very sensitive to noise and cusps in the argument.
347///
348/// !!! BE SURE YOU KNOW WHAT YOU ARE DOING !!!
349///
350/// For computing matrix elements, which is reasonably stable, we refer
351template<typename T, std::size_t NDIM>
352class Laplacian : public SCFOperatorBase<T,NDIM> {
354 typedef std::vector<functionT> vecfuncT;
356
357public:
358
359 Laplacian(World& world, const double e=0.0) : world(world), eps(e) {
360 gradop = gradient_operator<T,NDIM>(world);
361 }
362
363 std::string info() const {return "D^2";}
364
365 functionT operator()(const functionT& ket) const {
366 vecfuncT vket(1,ket);
367 return this->operator()(vket)[0];
368 }
369
370 vecfuncT operator()(const vecfuncT& vket) const;
371
372 T operator()(const functionT& bra, const functionT& ket) const {
373 vecfuncT vbra(1,bra), vket(1,ket);
374 Tensor<T> tmat=this->operator()(vbra,vket);
375 return tmat(0l,0l);
376 }
377
378 tensorT operator()(const vecfuncT& vbra, const vecfuncT& vket) const {
380 return -2.0*t(vbra,vket);
381 }
382
383private:
385 std::vector< std::shared_ptr< Derivative<T,NDIM> > > gradop;
386 double eps;
387};
388
389
390
391template<typename T, std::size_t NDIM>
392class Coulomb : public SCFOperatorBase<T,NDIM> {
393public:
394
396 public:
397 // you need to define the exact argument(s) of operator() as tuple
398 typedef std::tuple<const Function<double,NDIM>&, const std::vector<Function<T,NDIM>> &> argtupleT;
399
400 using resultT = std::vector<Function<T,NDIM>>;
401
403 public:
404 partitionT do_partitioning(const std::size_t& vsize1, const std::size_t& vsize2,
405 const std::string policy) const override {
406 partitionT p={std::pair(Batch(_,_),1.0)};
407 return p;
408 }
409 };
410
414
415 // you need to define an empty constructor for the result
416 // resultT must implement operator+=(const resultT&)
417 resultT allocator(World &world, const argtupleT &argtuple) const {
418 std::size_t n = std::get<1>(argtuple).size();
419 resultT result = zero_functions_compressed<T,NDIM>(world, n);
420 return result;
421 }
422
424 return truncate(vcoul * arg);
425 }
426 };
427
428 /// default empty ctor
430
431 /// default empty ctor
435
436 /// ctor with an SCF calculation providing the MOs and density
437 Coulomb(World& world, const SCF* calc);
438
439 /// ctor with a Nemo calculation providing the MOs and density
440 Coulomb(World& world, const Nemo* nemo);
441
442 std::string info() const {return "J";}
443
444 Coulomb& set_taskq(std::shared_ptr<MacroTaskQ> taskq1) {
445 this->taskq=taskq1;
446 return *this;
447 }
448
449 void reset_poisson_operator_ptr(const double lo, const double econv);
450
452 std::vector<Function<T,NDIM> > vket(1,ket);
453 return this->operator()(vket)[0];
454 }
455
456 std::vector<Function<T,NDIM> > operator()(const std::vector<Function<T,NDIM> >& vket) const {
458 World& world=vket.front().world();
459 MacroTask task(world, t, this->taskq);
460 auto result=task(vcoul,vket);
461 return result;
462 }
463
464 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
465 return inner(bra,vcoul*ket);
466 }
467
468 Tensor<T> operator()(const std::vector<Function<T,NDIM> >& vbra,
469 const std::vector<Function<T,NDIM> >& vket) const {
470 const auto bra_equiv_ket = &vbra == &vket;
471 std::vector<Function<T,NDIM> > vJket;
472 for (std::size_t i=0; i<vket.size(); ++i) {
473 vJket.push_back(this->operator()(vket[i]));
474 }
475 return matrix_inner(world,vbra,vJket,bra_equiv_ket);
476 }
477
478 /// getter for the Coulomb potential
479 const real_function_3d& potential() const {return vcoul;}
480
481 /// setter for the Coulomb potential
483
484 real_function_3d compute_density(const SCF* calc) const;
485
486 /// given a density compute the Coulomb potential
487
488 /// this function uses a newly constructed Poisson operator. Note that
489 /// the accuracy parameters must be consistent with the exchange operator.
491 return (*poisson)(density).truncate();
492 }
493
494 /// given a set of MOs in an SCF calculation, compute the Coulomb potential
495
496 /// this function uses the Poisson operator of the SCF calculation
497 real_function_3d compute_potential(const SCF* calc) const;
498
499 /// given a set of MOs in an SCF calculation, compute the Coulomb potential
500
501 /// this function uses the Poisson operator of the SCF calculation
503
504private:
506 std::shared_ptr<real_convolution_3d> poisson;
507 double lo=1.e-4;
508 real_function_3d vcoul; ///< the coulomb potential
509};
510
511
512template<typename T, std::size_t NDIM>
513class Nuclear : public SCFOperatorBase<T,NDIM> {
514public:
515
516 Nuclear(World& world, const SCF* calc);
517
518 Nuclear(World& world, const NemoBase* nemo);
519
520 /// simple constructor takes a molecule, no nuclear correlation factor or core potentials
522
523 Nuclear(World& world, std::shared_ptr<NuclearCorrelationFactor> ncf)
524 : world(world), ncf(ncf) {}
525
526 std::string info() const {return "Vnuc";}
527
529 std::vector<Function<T,NDIM> > vket(1,ket);
530 return this->operator()(vket)[0];
531 }
532
533 std::vector<Function<T,NDIM> > operator()(const std::vector<Function<T,NDIM> >& vket) const;
534
535 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
536 return inner(bra,this->operator()(ket));
537 }
538
539 Tensor<T> operator()(const std::vector<Function<T,NDIM> >& vbra,
540 const std::vector<Function<T,NDIM> >& vket) const {
541 const auto bra_equiv_ket = &vbra == &vket;
542 std::vector<Function<T,NDIM> > vVket=this->operator()(vket);
543 return matrix_inner(world,vbra,vVket,bra_equiv_ket);
544 }
545
546private:
548 std::shared_ptr<NuclearCorrelationFactor> ncf;
549
550};
551
552
553/// the z component of the angular momentum
554
555/// takes real and complex functions as input, will return complex functions
556template<typename T, std::size_t NDIM>
557class Lz : public SCFOperatorBase<T,NDIM> {
558private:
560public:
561
562 bool use_bsplines=true;
563
564 Lz(World& world, bool use_bspline_derivative=true) : world(world), use_bsplines(use_bspline_derivative) {};
565
566 std::string info() const {return "Lz";}
567
568
570 std::vector<Function<T,NDIM> > vket(1,ket);
571 return this->operator()(vket)[0];
572 }
573
574 std::vector<Function<T,NDIM> > operator()(const std::vector<Function<T,NDIM> >& vket) const {
575
576 // the operator in cartesian components as
577 // L_z = - i (x del_y - y del_x)
578
579 if (vket.size()==0) return std::vector<complex_function_3d>(0);
580
581 real_function_3d x=real_factory_3d(world).functor([] (const coord_3d& r) {return r[0];});
582 real_function_3d y=real_factory_3d(world).functor([] (const coord_3d& r) {return r[1];});
583
584 Derivative<T,NDIM> Dx = free_space_derivative<T,NDIM>(world, 0);
585 Derivative<T,NDIM> Dy = free_space_derivative<T,NDIM>(world, 1);
586 if (use_bsplines) {
587 Dx.set_bspline1();
588 Dy.set_bspline1();
589 }
590
591 reconstruct(world,vket,true);
592 std::vector<Function<T,NDIM> > delx=apply(world,Dx,vket,false);
593 std::vector<Function<T,NDIM> > dely=apply(world,Dy,vket,true);
594
595 std::vector<Function<T,NDIM> > result1=x*dely - y*delx;
596 std::vector<complex_function_3d> cresult1=convert<T,double_complex,NDIM>(world,result1);
597 std::vector<complex_function_3d> result=double_complex(0.0,-1.0)*cresult1;
598 return result;
599 }
600
601 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
602 return inner(bra,this->operator()(ket));
603 }
604
605 Tensor<T> operator()(const std::vector<Function<T,NDIM> >& vbra,
606 const std::vector<Function<T,NDIM> >& vket) const {
607 const auto bra_equiv_ket = &vbra == &vket;
608 std::vector<complex_function_3d> vVket=this->operator()(vket);
609 return matrix_inner(world,vbra,vVket,bra_equiv_ket);
610 }
611
612};
613
614
615
616/// derivative of the (regularized) nuclear potential wrt nuclear displacements
617template<typename T, std::size_t NDIM>
618class DNuclear : public SCFOperatorBase<T,NDIM> {
619public:
620
621 DNuclear(World& world, const SCF* calc, const int iatom, const int iaxis);
622
623 DNuclear(World& world, const Nemo* nemo, const int iatom, const int iaxis);
624
625 DNuclear(World& world, std::shared_ptr<NuclearCorrelationFactor> ncf,
626 const int iatom, const int iaxis)
627 : world(world), ncf(ncf), iatom(iatom), iaxis(iaxis) {}
628
629 std::string info() const {return "DVnuc";}
630
632 std::vector<Function<T,NDIM>> vket(1,ket);
633 return this->operator()(vket)[0];
634 }
635
636 std::vector<Function<T,NDIM>> operator()(const std::vector<Function<T,NDIM>>& vket) const;
637
638 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
639 return inner(bra,this->operator()(ket));
640 }
641
642 Tensor<T> operator()(const std::vector<Function<T,NDIM>>& vbra, const std::vector<Function<T,NDIM>>& vket) const {
643 const auto bra_equiv_ket = &vbra == &vket;
644 std::vector<Function<T,NDIM>> vVket=this->operator()(vket);
645 return matrix_inner(world,vbra,vVket,bra_equiv_ket);
646 }
647
648private:
650 std::shared_ptr<NuclearCorrelationFactor> ncf;
651 int iatom; ///< index of the atom which is displaced
652 int iaxis; ///< x,y,z component of the atom
653
654};
655
656template<typename T, std::size_t NDIM>
658public:
662
663 std::string info() const {return info_str;}
664
665 void set_info(const std::string new_info) {
666 info_str=new_info;
667 }
668
669 void set_potential(const Function<T,NDIM>& new_potential) {
670 potential=copy(new_potential);
671 }
672
674 return (potential*ket).truncate();
675 }
676
677 std::vector<Function<T,NDIM> > operator()(const std::vector<Function<T,NDIM> >& vket) const {
678 return truncate(potential*vket);
679 }
680
681 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
682 return inner(bra,potential*ket);
683 }
684
685 Tensor<T> operator()(const std::vector<Function<T,NDIM> >& vbra,
686 const std::vector<Function<T,NDIM> >& vket) const {
687 const auto bra_equiv_ket = &vbra == &vket;
688 return matrix_inner(world,vbra,potential*vket,bra_equiv_ket);
689 }
690
691private:
693 std::string info_str="Vlocal";
695};
696
697/// operator class for the handling of DFT exchange-correlation functionals
698template<typename T, std::size_t NDIM>
699class XCOperator : public SCFOperatorBase<T,NDIM> {
700public:
701
702 /// default ctor without information about the XC functional
704 extra_truncation(FunctionDefaults<3>::get_thresh()*0.01) {}
705
706 /// custom ctor with information about the XC functional
707 XCOperator(World& world, std::string xc_data, const bool spin_polarized,
708 const real_function_3d& arho, const real_function_3d& brho,
709 std::string deriv="abgv");
710
711 /// custom ctor with the XC functional
712 XCOperator(World& world, std::shared_ptr<XCfunctional> xc,
713 const bool spin_polarized,
714 int ispin,
715 int nbeta,
716 const real_function_3d& arho, const real_function_3d& brho,
717 std::string deriv="abgv");
718
719 /// ctor with an SCF calculation, will initialize the necessary intermediates
720 XCOperator(World& world, const SCF* scf, int ispin=0, std::string deriv="abgv");
721
722 /// ctor with a Nemo calculation, will initialize the necessary intermediates
723 XCOperator(World& world, const Nemo* nemo, int ispin=0);
724
725 /// ctor for the regularized (nemo) path, without a Nemo object
726
727 /// @param[in] arho,brho the physical densities rho_s
728 /// @param[in] ncf_ the nuclear correlation factor
729 /// @param[in] arho_reg,brho_reg the regularized densities rho_s/R^2, which let
730 /// prep_xc_args build zeta without putting the
731 /// nuclear cusp under a numerical derivative
732 XCOperator(World& world, std::string xc_data, const bool spin_polarized,
733 const real_function_3d& arho, const real_function_3d& brho,
734 std::shared_ptr<NuclearCorrelationFactor> ncf_,
735 const real_function_3d& arho_reg_, const real_function_3d& brho_reg_,
736 std::string deriv="abgv");
737
738 /// ctor with an SCF calculation, will initialize the necessary intermediates
739 XCOperator(World& world, const SCF* scf, const real_function_3d& arho,
740 const real_function_3d& brho, int ispin=0, std::string deriv="abgv");
741
742 /// ctor with an Nemo calculation, will initialize the necessary intermediates
743 XCOperator(World& world, const Nemo* scf, const real_function_3d& arho,
744 const real_function_3d& brho, int ispin=0);
745
746 std::string info() const {return "Vxc";}
747
748 XCOperator& set_extra_truncation(const double& fac) {
750 if (world.rank()==0)
751 print("set extra truncation in XCOperator to", extra_truncation);
752 return *this;
753 }
754
755 /// set the spin state this operator is acting on
756 void set_ispin(const int i) const {ispin=i;}
757
758 /// print the meta-gga de/dtau range each time the operator is applied
759 XCOperator& set_print_level(const int p) {print_level=p; return *this;}
760
761 /// apply the xc potential on a set of orbitals
762 std::vector<Function<T,NDIM> > operator()(const std::vector<Function<T,NDIM> >& vket) const;
763
764 /// apply the xc potential on an orbitals
766 std::vector<Function<T,3> > vket(1,ket);
767 std::vector<Function<T,3> > vKket=this->operator()(vket);
768 return vKket[0];
769 }
770
771 /// the xc contribution to the Fock matrix, as a matrix element
772
773 /// The 1x1 case of the vector form below; the same bra convention applies.
774 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
775 std::vector<Function<T,NDIM> > vbra(1,bra), vket(1,ket);
776 return this->operator()(vbra,vket)(0l,0l);
777 }
778
779 /// the xc contribution to the Fock matrix
780
781 /// With a nuclear correlation factor the bra must carry R^2 -- call it as
782 /// xcoperator(R2nemo, nemo), the way Kinetic is called in
783 /// Nemo::compute_fock_matrix. Without one, bra and ket are the same orbitals.
784 Tensor<T> operator()(const std::vector<Function<T,NDIM>>& vbra,
785 const std::vector<Function<T,NDIM>>& vket) const;
786
787 /// opt in to the weak form, if the `xc_weak_gga` parameter asks for it
788
789 /// Load-bearing: in weak form make_xc_potential() returns only de/drho, so a
790 /// caller that does not also apply weak_xc_terms() and add the matrix form's
791 /// contribution (operator()(vbra,vket)) would silently drop the whole semilocal
792 /// contribution and return a plausible but wrong energy. Only
793 /// Nemo::compute_nemo_potentials implements the split, so only it opts in; SCF,
794 /// OEP, TDHF and the response kernels keep the multiplicative potential.
795 XCOperator& allow_weak_form() {weak_form_ok=true; return *this;}
796
797 /// override CalculationParameters::xc_weak_gga(), for callers without one
798 XCOperator& set_weak_gga(const bool flag) {weak_gga=flag; return *this;}
799
800 /// true if this operator is running in weak form, i.e. make_xc_potential()
801 /// returns only de/drho and the flux is carried separately
802
803 /// Requires both the caller's allow_weak_form() opt-in and the user's
804 /// `xc_weak_gga` parameter. A functional with no sigma dependence has no flux,
805 /// so it is never in weak form either.
806 ///
807 /// Why it exists: the semilocal potential is -div(X) with
808 /// X = 2 de/dsigma grad(rho), and X has a jump at every nucleus
809 /// (zeta = grad log rho -> -2Z r_hat, whose Cartesian components flip sign
810 /// across the origin). Differentiating that jump is what produces the +-8e4
811 /// excursions, and no rearrangement of the multiplicative form avoids it,
812 /// because div(X) *is* a derivative of X.
813 ///
814 /// The weak form never differentiates X:
815 /// <phi|v|psi> = int (df/drho) phi psi + int X . grad(phi psi)
816 /// and in a Green's-function code the same holds for the orbital update,
817 /// because a radial convolution commutes with the gradient:
818 /// G * (psi div X) = div(G * (X psi)) - G * (X . grad psi)
819 /// so the divergence acts on G*(X psi), which is C^1, and the jump is only
820 /// ever convolved. Same for the meta-gga term -1/2 div(v_tau grad psi).
821 bool is_weak_form() const;
822
823 /// the semilocal flux X = 2 (de/dsigma_ss) grad(rho_s) + (de/dsigma_ab) grad(rho_s')
824
825 /// Only assigned in weak form, by make_xc_potential(). Same-spin and cross-spin
826 /// contributions are summed: they enter as a single divergence.
828
829 /// weak-form split of the non-multiplicative xc terms
830
831 /// Writes the decomposition
832 /// v_xc^{semilocal+tau} psi_i = mult_i - div(Y_i)
833 /// with (nemo kets F_i, W_i = v_tau (grad F_i - U1 F_i))
834 /// mult_i = X.grad(F_i) + 1/2 U1.W_i, Y_i = X F_i + 1/2 W_i.
835 /// `mult` goes into V psi; `flux` is what the caller pushes through the
836 /// Green's function, as 2 div(G*Y_i), so that neither X nor v_tau is ever
837 /// differentiated. Requires make_xc_potential() first.
838 void weak_xc_terms(const std::vector<Function<T,NDIM> >& vket,
839 std::vector<Function<T,NDIM> >& mult,
840 std::vector<std::vector<Function<T,NDIM> > >& flux) const;
841
842 /// compute the xc energy using the precomputed intermediates vf and delrho
843 double compute_xc_energy() const;
844
845 /// the multiplicative part of the potential, as make_xc_potential() returned it
847
848 /// return the local xc potential
850
851 /// true if the functional contributes a non-multiplicative (meta-gga) term
852 bool has_tau_term() const;
853
854 /// compute the kinetic energy density and add it to the intermediates
855
856 /// tau is orbital-dependent, so unlike the density it cannot be recovered
857 /// from what the ctors are given -- it has to be supplied separately. Call
858 /// this after construction and before make_xc_potential() whenever
859 /// has_tau_term() is true; make_xc_potential() throws otherwise.
860 /// The occupation numbers are required, not optional: amo/bmo may carry
861 /// virtual orbitals (occupation zero), which contribute nothing to the
862 /// density but would inflate an unweighted sum of |grad psi|^2, and
863 /// occupations may be fractional.
864 /// @param[in] amo alpha orbitals (nemos if a nuclear correlation factor is set)
865 /// @param[in] aocc occupation numbers of amo
866 /// @param[in] bmo beta orbitals, ignored if the calculation is spin-restricted
867 /// @param[in] bocc occupation numbers of bmo
868 /// how the two U1 terms of tau's product rule are evaluated
869
870 /// U1 = -grad(R)/R is analytic but componentwise non-smooth at each nucleus
871 /// (U1_x ~ x/r), so carrying it as an MRA Function costs depth ~18 and every
872 /// product with it inherits that depth -- which refine_to_common_level then
873 /// imposes on every xc intermediate.
874 enum class TauU1 {
875 mra, ///< U1 and |U1|^2 projected into Functions and multiplied
876 pointwise ///< U1 evaluated from its functor at the orbital tree's
877 ///< quadrature points; nothing involving it is projected
878 };
879
880 void set_tau(const vecfuncT& amo, const Tensor<double>& aocc,
881 const vecfuncT& bmo=vecfuncT(),
882 const Tensor<double>& bocc=Tensor<double>(),
883 const TauU1 u1mode=TauU1::pointwise) const;
884
885 /// the kinetic energy density of one spin channel, as set by set_tau()
886
887 /// exposed for diagnostics and for the exact check int(tau) == T
888 real_function_3d get_tau(const int spin=0) const;
889
890 /// de/dtau, as computed by make_xc_potential()
892
893 /// apply the non-multiplicative meta-gga term on a set of orbitals
894
895 /// \f[
896 /// \hat v_\tau \psi_i = -\frac{1}{2}\nabla\cdot
897 /// \left(\frac{\partial e_{xc}}{\partial\tau_\sigma}\nabla\psi_i\right)
898 /// \f]
899 /// evaluated as \f$ -\frac{1}{2}\sum_x D_x(v_\tau D_x\psi_i) \f$, so that
900 /// \f$ v_\tau \f$ is only ever multiplied and never differentiated. That
901 /// nested form is also self-adjoint by construction, while the expanded
902 /// \f$ -\frac{1}{2}(v_\tau\nabla^2\psi + \nabla v_\tau\cdot\nabla\psi) \f$
903 /// is symmetric only up to discretization error and needs \f$\nabla^2\psi\f$.
904 /// Requires make_xc_potential() to have been called first, which is where
905 /// \f$ v_\tau \f$ is computed.
906 std::vector<Function<T,NDIM> > apply_tau_term(const std::vector<Function<T,NDIM> >& vket) const;
907
908 /// construct the xc kernel and apply it directly on the (response) density
909
910 /// the xc kernel is the second derivative of the xc functions wrt the density
911 /// @param[in] density the (response) density on which the kernel is applied
912 /// @return kernel * density
914 const vecfuncT grad_dens_pt=vecfuncT()) const;
915
916private:
917
918 /// the world
920
921 /// which derivative operator to use
922 std::string dft_deriv;
923
924 /// print level; >=2 logs the meta-gga de/dtau range
926
927public:
928 /// interface to the actual XC functionals
929 std::shared_ptr<XCfunctional> xc;
930
931private:
932 /// number of beta orbitals
933 int nbeta;
934
935 /// the XC functionals depend on the spin of the orbitals they act on
936 mutable int ispin;
937
938 /// additional truncation for the densities in the XC kernel
939
940 /// the densities in the DFT kernal are processed as their inverses,
941 /// so noise in the small density regions might amplify and lead to inaccurate
942 /// results. Extra truncation will tighten the truncation threshold by a
943 /// specified factor, default is 0.01.
945
946 /// the nuclear correlation factor, if it exists, for computing derivatives for GGA
947 std::shared_ptr<NuclearCorrelationFactor> ncf;
948
949 /// functions that are need for the computation of the XC operator
950
951 /// the ordering of the intermediates is fixed, but the code can handle
952 /// non-initialized functions, so if e.g. no GGA is requested, all the
953 /// corresponding vector components may be left empty.
954 /// For the ordering of the intermediates see xcfunctional::xc_arg
956
957 /// de/dtau, the prefactor of the non-multiplicative meta-gga term
958
959 /// falls out of the same pointwise pass as the multiplicative potential, so
960 /// it is stashed by make_xc_potential() rather than recomputed
962
963 /// gradient operator honouring dft_deriv, for the meta-gga term
964 std::shared_ptr<Derivative<T,NDIM> > make_derivative(const int axis) const;
965
966 /// divergence of a vector field, honouring dft_deriv
968
969 /// caller has opted in to the weak form, see allow_weak_form()
970 bool weak_form_ok=false;
971
972 /// the user asked for the weak form: CalculationParameters::xc_weak_gga()
973
974 /// Two independent conditions, and both are needed. weak_form_ok says the
975 /// *caller* implements the split; this says the *user* wants it.
976 bool weak_gga=false;
977
978 /// the semilocal flux, assigned by make_xc_potential() in weak form only
980
981 /// the multiplicative potential, stashed by make_xc_potential()
983
984 /// the body of make_xc_potential(); the wrapper only stashes vlocal
986
987 /// true once set_tau() has supplied tau, by either route
988 bool has_tau_args() const;
989
990 /// the four analytic U1 quantities the xc ops evaluate pointwise
991
992 /// Empty unless the pointwise route is in use. They are handed to the op rather
993 /// than projected into xc_args precisely because a projected product with U1 is
994 /// what rings; see nemo_u1_functors.
996
997 /// compute the intermediates for the XC functionals
998
999 /// @param[in] arho density of the alpha orbitals
1000 /// @param[in] brho density of the beta orbitals (necessary only if spin-polarized)
1001 /// @return xc_args vector of intermediates as described above
1002 /// compute the intermediates for the XC functionals
1003
1004 /// If the regularized densities are supplied, zeta = grad log(rho) is built as
1005 /// grad log(rho_reg) - 2 U1 -- exact, and it keeps the nuclear cusp of
1006 /// rho = R^2 rho_reg out from under the numerical derivative.
1007 vecfuncT prep_xc_args(const real_function_3d& arho, const real_function_3d& brho,
1008 const real_function_3d& arho_reg = real_function_3d(),
1009 const real_function_3d& brho_reg = real_function_3d()) const;
1010
1011 /// compute the intermediates for the XC functionals
1012
1013 /// @param[in] dens_pt perturbed densities from CPHF or TDDFT equations
1014 /// @param[in,out] xc_args vector of intermediates as described above
1015 /// @param[out] ddens_pt xyz-derivatives of dens_pt
1016 void prep_xc_args_response(const real_function_3d& dens_pt,
1017 vecfuncT& xc_args, vecfuncT& ddens_pt) const;
1018
1019 /// check if the intermediates are initialized
1020 bool is_initialized() const {
1021 return (xc_args.size()>0);
1022 }
1023
1024 /// simple structure to take the pointwise logarithm of a function, shifted by +14
1025 struct logme{
1026 typedef double resultT;
1027 struct logme1 {
1028 double operator()(const double& val) {return log(std::max(1.e-14,val))+14.0;}
1029 };
1030 Tensor<double> operator()(const Key<3>& key, const Tensor<double>& val) const {
1031 Tensor<double> result=copy(val);
1032 logme1 op;
1033 return result.unaryop(op);
1034 }
1035
1036 template <typename Archive>
1037 void serialize(Archive& ar) {}
1038 };
1039
1040 /// simple structure to take the pointwise exponential of a function, shifted by +14
1041 struct expme{
1042 typedef double resultT;
1043 struct expme1 {
1044 double operator()(const double& val) {return exp(val-14.0);}
1045 };
1046 Tensor<double> operator()(const Key<3>& key, const Tensor<double>& val) const {
1047 Tensor<double> result=copy(val);
1048 expme1 op;
1049 return result.unaryop(op);
1050 }
1051
1052 template <typename Archive>
1053 void serialize(Archive& ar) {}
1054
1055 };
1056};
1057
1058/// Computes matrix representation of the Fock operator
1059template<typename T, std::size_t NDIM>
1060class Fock : public SCFOperatorBase<T,NDIM> {
1061public:
1063
1067
1068 /// pretty print what this is actually computing
1069 std::string info() const {
1070 std::string s;
1071 for (auto& op : operators) {
1072 double number=std::get<0>(op.second);
1073 if (number==-1.0) {
1074 s+=" - ";
1075 } else if (number!=1.0) {
1076 std::stringstream snumber;
1077 snumber << std::fixed << std::setw(2) << number;
1078 s+=" "+snumber.str()+ " ";
1079 } else {
1080 MADNESS_CHECK(number==1.0);
1081 s+=" + ";
1082 }
1083 s+=op.first;
1084 }
1085 return s;
1086 }
1087
1088 /// add an operator with default prefactor 1.0
1089 void add_operator(std::string name, std::shared_ptr<SCFOperatorBase<T,NDIM>> new_op) {
1090 operators.insert({name,valueT(1.0,new_op)});
1091 }
1092
1093 /// add an operator with custom prefactor (e.g. -1.0 for the exchange, supposedly)
1094 void add_operator(std::string name, std::tuple<double,std::shared_ptr<SCFOperatorBase<T,NDIM>>> new_op) {
1095 operators.insert({name,new_op});
1096 }
1097
1098 /// remove operator, returns 0 if no operator was found
1099 int remove_operator(std::string name) {
1100 return operators.erase(name);
1101 }
1102
1104 MADNESS_EXCEPTION("Fock(ket) not yet implemented",1);
1105 Function<T,NDIM> result;
1106 return result;
1107 }
1108
1109 std::vector<Function<T,NDIM>> operator()(const std::vector<Function<T,NDIM>>& vket) const {
1110 // make sure T is not part of the Fock operator, it's numerically unstable!
1111 MADNESS_CHECK(operators.count("T")==0);
1112 std::vector<Function<T,NDIM>> result = zero_functions_compressed<T, NDIM>(world, vket.size());
1113 for (const auto& op : operators) {
1114 result+=std::get<0>(op.second) * (*std::get<1>(op.second))(vket);
1115 }
1116 return result;
1117 }
1118
1119 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
1120 std::vector<Function<T,NDIM>> vbra(1,bra), vket(1,ket);
1121 return (*this)(vbra,vket)(0,0);
1122 }
1123
1124 /// compute the Fock matrix by summing up all contributions
1125 Tensor<T> operator()(const std::vector<Function<T,NDIM>>& vbra, const std::vector<Function<T,NDIM>>& vket) const {
1126 return this->operator()(vbra,vket,false);
1127 }
1128
1129 /// compute the Fock matrix by summing up all contributions
1130 Tensor<T> operator()(const std::vector<Function<T,NDIM>>& vbra, const std::vector<Function<T,NDIM>>& vket,
1131 const bool symmetric) const {
1132 Tensor<T> fock(vbra.size(),vket.size());
1133 for (const auto& op : operators) {
1134 Tensor<T> tmp=std::get<0>(op.second) * (*std::get<1>(op.second))(vbra,vket);
1135// print("Operator",std::get<1>(op.second)->info());
1136// print(tmp);
1137 fock+=tmp;
1138 }
1139 return fock;
1140 }
1141
1142
1143private:
1144 /// the world
1146
1147 /// type defining Fock operator contribution including prefactor
1148 typedef std::tuple<double,std::shared_ptr<SCFOperatorBase<T,NDIM> > > valueT;
1149
1150 /// all the Fock operator contribution
1151 std::map<std::string,valueT> operators;
1152};
1153
1154}
1155#endif /* MADNESS_CHEM_SCFOPERATORS_H_ */
std::complex< double > double_complex
Definition cfft.h:14
partitionT do_partitioning(const std::size_t &vsize1, const std::size_t &vsize2, const std::string policy) const override
override this if you want your own partitioning
Definition SCFOperators.h:404
Definition SCFOperators.h:395
std::vector< Function< T, NDIM > > resultT
Definition SCFOperators.h:400
MacroTaskCoulomb()
Definition SCFOperators.h:411
resultT allocator(World &world, const argtupleT &argtuple) const
Definition SCFOperators.h:417
std::tuple< const Function< double, NDIM > &, const std::vector< Function< T, NDIM > > & > argtupleT
Definition SCFOperators.h:398
resultT operator()(const Function< double, NDIM > &vcoul, const std::vector< Function< T, NDIM > > &arg) const
Definition SCFOperators.h:423
Definition SCFOperators.h:392
Function< T, NDIM > compute_potential(const Function< T, NDIM > &density) const
given a density compute the Coulomb potential
Definition SCFOperators.h:490
real_function_3d compute_density(const SCF *calc) const
Definition SCFOperators.cc:204
Coulomb & set_taskq(std::shared_ptr< MacroTaskQ > taskq1)
Definition SCFOperators.h:444
real_function_3d & potential()
setter for the Coulomb potential
Definition SCFOperators.h:482
World & world
Definition SCFOperators.h:505
Coulomb(World &world)
default empty ctor
Definition SCFOperators.h:429
Coulomb(World &world, const double lo, const double thresh=FunctionDefaults< 3 >::get_thresh())
default empty ctor
Definition SCFOperators.h:432
const real_function_3d & potential() const
getter for the Coulomb potential
Definition SCFOperators.h:479
std::string info() const
print some information about this operator
Definition SCFOperators.h:442
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:456
std::shared_ptr< real_convolution_3d > poisson
Definition SCFOperators.h:506
real_function_3d vcoul
the coulomb potential
Definition SCFOperators.h:508
double lo
Definition SCFOperators.h:507
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:468
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:451
void reset_poisson_operator_ptr(const double lo, const double econv)
Definition SCFOperators.cc:199
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:464
derivative of the (regularized) nuclear potential wrt nuclear displacements
Definition SCFOperators.h:618
World & world
Definition SCFOperators.h:649
std::string info() const
print some information about this operator
Definition SCFOperators.h:629
DNuclear(World &world, std::shared_ptr< NuclearCorrelationFactor > ncf, const int iatom, const int iaxis)
Definition SCFOperators.h:625
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:638
std::shared_ptr< NuclearCorrelationFactor > ncf
Definition SCFOperators.h:650
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:642
int iatom
index of the atom which is displaced
Definition SCFOperators.h:651
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:631
int iaxis
x,y,z component of the atom
Definition SCFOperators.h:652
Definition SCFOperators.h:299
tensorT operator()(const vecfuncT &vbra, const vecfuncT &vket) const
compute the matrix <vbra | op | vket>
Definition SCFOperators.h:329
functionT operator()(const functionT &ket) const
Definition SCFOperators.h:312
int axis
Definition SCFOperators.h:337
DerivativeOperator(World &world, const int axis1)
Definition SCFOperators.h:306
T operator()(const functionT &bra, const functionT &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:323
std::string info() const
print some information about this operator
Definition SCFOperators.h:310
Derivative< T, NDIM > gradop
Definition SCFOperators.h:338
Tensor< T > tensorT
Definition SCFOperators.h:302
Function< T, NDIM > functionT
Definition SCFOperators.h:300
vecfuncT operator()(const vecfuncT &vket) const
apply this operator on the argument vector of functions
Definition SCFOperators.h:317
World & world
Definition SCFOperators.h:336
std::vector< functionT > vecfuncT
Definition SCFOperators.h:301
Implements derivatives operators with variety of boundary conditions on simulation domain.
Definition derivative.h:337
void set_bspline1()
Definition derivative.h:683
Manages data associated with a row/column/block distributed array.
Definition distributed_matrix.h:388
Definition exchangeoperator.h:601
Definition SCFOperators.h:106
Exchange & set_cost_aware_assignment(const bool flag)
place tasks by their measured cost rather than by counting them
Definition exchangeoperator.cc:474
Function< T, NDIM > functionT
Definition SCFOperators.h:111
Exchange & set_taskq(std::shared_ptr< MacroTaskQ > taskq1)
Definition SCFOperators.h:201
Exchange & set_printlevel(const long &level)
Definition exchangeoperator.cc:456
Exchange & set_batch_granularity(const long level)
batches per rank in the owner-pinned symmetric partition (>= 1)
Definition exchangeoperator.cc:462
Exchange & set_macro_task_info(const std::vector< std::string > &info)
Definition SCFOperators.h:184
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | K | ket>
Definition SCFOperators.h:225
static std::string to_string(const ExchangeAlgorithm alg)
Definition SCFOperators.h:145
ExchangeAlgorithm
Definition SCFOperators.h:118
@ fetch_compute
Definition SCFOperators.h:119
@ multiworld_efficient_row
Definition SCFOperators.h:119
@ multiworld_efficient
Definition SCFOperators.h:119
@ small_memory
Definition SCFOperators.h:119
@ large_memory
Definition SCFOperators.h:119
static ExchangeAlgorithm string2algorithm(const std::string &alg_string)
Definition SCFOperators.h:151
Tensor< T > tensorT
Definition SCFOperators.h:113
bool is_symmetric() const
Definition exchangeoperator.cc:433
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:208
Exchange & set_symmetric(const bool flag)
Definition exchangeoperator.cc:438
implT impl
Definition SCFOperators.h:115
std::shared_ptr< ExchangeImpl > implT
Definition SCFOperators.h:110
Exchange & set_accumulation_mode(const int mode)
1 = gather tile results per subworld, 2 = also gather per node first
Definition exchangeoperator.cc:468
Tensor< T > operator()(const vecfuncT &vbra, const vecfuncT &vket) const
compute the matrix < vbra | K | vket >
Definition SCFOperators.h:234
Exchange & set_bra_and_ket(const vecfuncT &bra, const vecfuncT &ket)
Definition exchangeoperator.cc:426
std::vector< functionT > vecfuncT
Definition SCFOperators.h:112
vecfuncT operator()(const vecfuncT &vket) const
apply the exchange operator on a vector of functions
Exchange & set_macro_task_info(const MacroTaskInfo &info)
how the cloud will handle the data
Definition exchangeoperator.cc:450
std::string info() const
print some information about this operator
Definition SCFOperators.h:174
friend std::ostream & operator<<(std::ostream &os, const ExchangeAlgorithm &alg)
Definition SCFOperators.h:122
Exchange & set_algorithm(const ExchangeAlgorithm &alg)
Definition exchangeoperator.cc:444
Computes matrix representation of the Fock operator.
Definition SCFOperators.h:1060
int remove_operator(std::string name)
remove operator, returns 0 if no operator was found
Definition SCFOperators.h:1099
Fock(World &world)
Definition SCFOperators.h:1062
World & world
the world
Definition SCFOperators.h:1145
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket) const
compute the Fock matrix by summing up all contributions
Definition SCFOperators.h:1125
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket, const bool symmetric) const
compute the Fock matrix by summing up all contributions
Definition SCFOperators.h:1130
Fock(World &world, const OEP *nemo)
Fock(World &world, const NemoBase *nemo)
Fock(World &world, const Nemo *nemo)
std::map< std::string, valueT > operators
all the Fock operator contribution
Definition SCFOperators.h:1151
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:1119
std::tuple< double, std::shared_ptr< SCFOperatorBase< T, NDIM > > > valueT
type defining Fock operator contribution including prefactor
Definition SCFOperators.h:1148
void add_operator(std::string name, std::tuple< double, std::shared_ptr< SCFOperatorBase< T, NDIM > > > new_op)
add an operator with custom prefactor (e.g. -1.0 for the exchange, supposedly)
Definition SCFOperators.h:1094
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:1103
std::string info() const
pretty print what this is actually computing
Definition SCFOperators.h:1069
void add_operator(std::string name, std::shared_ptr< SCFOperatorBase< T, NDIM > > new_op)
add an operator with default prefactor 1.0
Definition SCFOperators.h:1089
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:1109
FunctionDefaults holds default paramaters as static class members.
Definition funcdefaults.h:101
A multiresolution adaptive numerical function.
Definition mra.h:144
Key is the index for a node of the 2^NDIM-tree.
Definition key.h:70
Definition SCFOperators.h:246
Tensor< T > tensorT
Definition SCFOperators.h:250
std::vector< std::shared_ptr< Derivative< T, NDIM > > > gradop
Definition SCFOperators.h:289
tensorT operator()(const vecfuncT &vbra, const vecfuncT &vket) const
compute the matrix <vbra | op | vket>
Definition SCFOperators.h:275
World & world
Definition SCFOperators.h:288
Kinetic(World &world)
Definition SCFOperators.h:253
std::vector< functionT > vecfuncT
Definition SCFOperators.h:249
Function< T, NDIM > functionT
Definition SCFOperators.h:248
std::string info() const
print some information about this operator
Definition SCFOperators.h:257
distmatT kinetic_energy_matrix(World &world, const vecfuncT &v) const
Definition SCFOperators.cc:51
DistributedMatrix< T > distmatT
Definition SCFOperators.h:247
vecfuncT operator()(const vecfuncT &vket) const
apply this operator on the argument vector of functions
Definition SCFOperators.h:264
T operator()(const functionT &bra, const functionT &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:269
functionT operator()(const functionT &ket) const
Definition SCFOperators.h:259
the Laplacian operator: \sum_i \nabla^2_i
Definition SCFOperators.h:352
T operator()(const functionT &bra, const functionT &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:372
double eps
Definition SCFOperators.h:386
Tensor< T > tensorT
Definition SCFOperators.h:355
functionT operator()(const functionT &ket) const
Definition SCFOperators.h:365
Function< T, NDIM > functionT
Definition SCFOperators.h:353
std::string info() const
print some information about this operator
Definition SCFOperators.h:363
tensorT operator()(const vecfuncT &vbra, const vecfuncT &vket) const
compute the matrix <vbra | op | vket>
Definition SCFOperators.h:378
std::vector< functionT > vecfuncT
Definition SCFOperators.h:354
vecfuncT operator()(const vecfuncT &vket) const
apply this operator on the argument vector of functions
Laplacian(World &world, const double e=0.0)
Definition SCFOperators.h:359
std::vector< std::shared_ptr< Derivative< T, NDIM > > > gradop
Definition SCFOperators.h:385
World & world
Definition SCFOperators.h:384
Definition SCFOperators.h:657
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:685
std::string info() const
print some information about this operator
Definition SCFOperators.h:663
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:681
void set_info(const std::string new_info)
Definition SCFOperators.h:665
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:677
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:673
Function< T, NDIM > potential
Definition SCFOperators.h:694
LocalPotentialOperator(World &world)
Definition SCFOperators.h:659
World & world
Definition SCFOperators.h:692
std::string info_str
Definition SCFOperators.h:693
LocalPotentialOperator(World &world, const std::string info, const Function< T, NDIM > potential)
Definition SCFOperators.h:660
void set_potential(const Function< T, NDIM > &new_potential)
Definition SCFOperators.h:669
the z component of the angular momentum
Definition SCFOperators.h:557
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:601
Lz(World &world, bool use_bspline_derivative=true)
Definition SCFOperators.h:564
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:605
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:574
World & world
Definition SCFOperators.h:559
std::string info() const
print some information about this operator
Definition SCFOperators.h:566
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:569
bool use_bsplines
Definition SCFOperators.h:562
Definition macrotaskq.h:1604
std::shared_ptr< MacroTaskPartitioner > partitioner
Definition macrotaskq.h:1612
partition one (two) vectors into 1D (2D) batches.
Definition macrotaskpartitioner.h:182
std::string policy
how to partition the batches
Definition macrotaskpartitioner.h:190
std::list< std::pair< Batch, double > > partitionT
Definition macrotaskpartitioner.h:186
friend class Batch
Definition macrotaskpartitioner.h:183
Definition macrotaskq.h:991
Definition molecule.h:129
Definition nemo.h:70
The Nemo class.
Definition nemo.h:362
Definition SCFOperators.h:513
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:528
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:535
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:539
std::string info() const
print some information about this operator
Definition SCFOperators.h:526
World & world
Definition SCFOperators.h:547
Nuclear(World &world, std::shared_ptr< NuclearCorrelationFactor > ncf)
Definition SCFOperators.h:523
std::shared_ptr< NuclearCorrelationFactor > ncf
Definition SCFOperators.h:548
Definition oep.h:152
Definition SCFOperators.h:59
std::vector< functionT > vecfuncT
Definition SCFOperators.h:63
Tensor< T > tensorT
Definition SCFOperators.h:64
virtual std::string info() const =0
print some information about this operator
nlohmann::json statistics
Definition SCFOperators.h:65
std::shared_ptr< MacroTaskQ > taskq
Definition SCFOperators.h:72
Function< T, NDIM > functionT
Definition SCFOperators.h:62
SCFOperatorBase(std::shared_ptr< MacroTaskQ > taskq)
Definition SCFOperators.h:68
virtual ~SCFOperatorBase()
Definition SCFOperators.h:70
virtual tensorT operator()(const vecfuncT &vbra, const vecfuncT &vket) const =0
compute the matrix <vbra | op | vket>
virtual vecfuncT operator()(const vecfuncT &vket) const =0
apply this operator on the argument vector of functions
virtual functionT operator()(const functionT &ket) const =0
virtual T operator()(const functionT &bra, const functionT &ket) const =0
compute the matrix element <bra | op | ket>
Definition SCF.h:200
A tensor is a multidimensional array.
Definition tensor.h:318
Tensor< T > & unaryop(opT &op)
Inplace apply a unary function to each element of the tensor.
Definition tensor.h:1794
void fence(bool debug=false)
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition worldgop.cc:177
A parallel world class.
Definition world.h:134
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition world.h:344
ProcessID size() const
Returns the number of processes in this World (same as MPI_Comm_size()).
Definition world.h:354
WorldGopInterface & gop
Global operations.
Definition world.h:216
operator class for the handling of DFT exchange-correlation functionals
Definition SCFOperators.h:699
bool has_tau_term() const
true if the functional contributes a non-multiplicative (meta-gga) term
Definition SCFOperators.cc:487
XCOperator(World &world)
default ctor without information about the XC functional
Definition SCFOperators.h:703
TauU1
compute the kinetic energy density and add it to the intermediates
Definition SCFOperators.h:874
@ mra
U1 and |U1|^2 projected into Functions and multiplied.
vecfuncT xc_args
functions that are need for the computation of the XC operator
Definition SCFOperators.h:955
void weak_xc_terms(const std::vector< Function< T, NDIM > > &vket, std::vector< Function< T, NDIM > > &mult, std::vector< std::vector< Function< T, NDIM > > > &flux) const
weak-form split of the non-multiplicative xc terms
Definition SCFOperators.cc:766
XCOperator & allow_weak_form()
opt in to the weak form, if the xc_weak_gga parameter asks for it
Definition SCFOperators.h:795
bool is_initialized() const
check if the intermediates are initialized
Definition SCFOperators.h:1020
bool weak_gga
the user asked for the weak form: CalculationParameters::xc_weak_gga()
Definition SCFOperators.h:976
double compute_xc_energy() const
compute the xc energy using the precomputed intermediates vf and delrho
Definition SCFOperators.cc:909
std::shared_ptr< Derivative< T, NDIM > > make_derivative(const int axis) const
gradient operator honouring dft_deriv, for the meta-gga term
Definition SCFOperators.cc:737
real_function_3d get_tau(const int spin=0) const
the kinetic energy density of one spin channel, as set by set_tau()
Definition SCFOperators.cc:493
XCOperator & set_weak_gga(const bool flag)
override CalculationParameters::xc_weak_gga(), for callers without one
Definition SCFOperators.h:798
std::string info() const
print some information about this operator
Definition SCFOperators.h:746
real_function_3d div_dft_deriv(const vecfuncT &v) const
divergence of a vector field, honouring dft_deriv
Definition SCFOperators.cc:750
real_function_3d make_xc_potential() const
return the local xc potential
Definition SCFOperators.cc:960
bool has_tau_args() const
true once set_tau() has supplied tau, by either route
Definition SCFOperators.cc:934
XCOperator & set_extra_truncation(const double &fac)
Definition SCFOperators.h:748
real_function_3d vtau
de/dtau, the prefactor of the non-multiplicative meta-gga term
Definition SCFOperators.h:961
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
apply the xc potential on an orbitals
Definition SCFOperators.h:765
void prep_xc_args_response(const real_function_3d &dens_pt, vecfuncT &xc_args, vecfuncT &ddens_pt) const
compute the intermediates for the XC functionals
Definition SCFOperators.cc:1179
vecfuncT prep_xc_args(const real_function_3d &arho, const real_function_3d &brho, const real_function_3d &arho_reg=real_function_3d(), const real_function_3d &brho_reg=real_function_3d()) const
compute the intermediates for the XC functionals
Definition SCFOperators.cc:1105
XCOperator & set_print_level(const int p)
print the meta-gga de/dtau range each time the operator is applied
Definition SCFOperators.h:759
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
the xc contribution to the Fock matrix, as a matrix element
Definition SCFOperators.h:774
nemo_u1_functors make_u1_functors() const
the four analytic U1 quantities the xc ops evaluate pointwise
Definition SCFOperators.cc:943
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vket) const
apply the xc potential on a set of orbitals
Definition SCFOperators.cc:477
real_function_3d get_vtau() const
de/dtau, as computed by make_xc_potential()
Definition SCFOperators.h:891
std::string dft_deriv
which derivative operator to use
Definition SCFOperators.h:922
void set_tau(const vecfuncT &amo, const Tensor< double > &aocc, const vecfuncT &bmo=vecfuncT(), const Tensor< double > &bocc=Tensor< double >(), const TauU1 u1mode=TauU1::pointwise) const
compute tau = 1/2 sum_i |grad psi_i|^2 and store it in the intermediates
Definition SCFOperators.cc:500
std::shared_ptr< NuclearCorrelationFactor > ncf
the nuclear correlation factor, if it exists, for computing derivatives for GGA
Definition SCFOperators.h:947
std::vector< Function< T, NDIM > > apply_tau_term(const std::vector< Function< T, NDIM > > &vket) const
apply the non-multiplicative meta-gga term on a set of orbitals
Definition SCFOperators.cc:662
real_function_3d get_vlocal() const
the multiplicative part of the potential, as make_xc_potential() returned it
Definition SCFOperators.h:846
void set_ispin(const int i) const
set the spin state this operator is acting on
Definition SCFOperators.h:756
double extra_truncation
additional truncation for the densities in the XC kernel
Definition SCFOperators.h:944
int print_level
print level; >=2 logs the meta-gga de/dtau range
Definition SCFOperators.h:925
std::shared_ptr< XCfunctional > xc
interface to the actual XC functionals
Definition SCFOperators.h:929
real_function_3d vlocal
the multiplicative potential, stashed by make_xc_potential()
Definition SCFOperators.h:982
bool is_weak_form() const
Definition SCFOperators.cc:759
real_function_3d make_xc_potential_impl() const
the body of make_xc_potential(); the wrapper only stashes vlocal
Definition SCFOperators.cc:967
World & world
the world
Definition SCFOperators.h:919
const vecfuncT & get_semilocal_flux() const
the semilocal flux X = 2 (de/dsigma_ss) grad(rho_s) + (de/dsigma_ab) grad(rho_s')
Definition SCFOperators.h:827
vecfuncT semilocal_flux
the semilocal flux, assigned by make_xc_potential() in weak form only
Definition SCFOperators.h:979
real_function_3d apply_xc_kernel(const real_function_3d &density, const vecfuncT grad_dens_pt=vecfuncT()) const
construct the xc kernel and apply it directly on the (response) density
Definition SCFOperators.cc:1066
int ispin
the XC functionals depend on the spin of the orbitals they act on
Definition SCFOperators.h:936
int nbeta
number of beta orbitals
Definition SCFOperators.h:933
bool weak_form_ok
caller has opted in to the weak form, see allow_weak_form()
Definition SCFOperators.h:970
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition derivatives.cc:72
static double lo
Definition dirac-hatom.cc:23
Tensor< typename Tensor< T >::scalar_type > arg(const Tensor< T > &t)
Return a new tensor holding the argument of each element of t (complex types only)
Definition tensor.h:2757
static const double v
Definition hatom_sf_dirac.cc:20
Tensor< double > op(const Tensor< double > &x)
Definition kain.cc:508
Declares the macrotaskq and MacroTaskBase classes.
General header file for using MADNESS.
#define MADNESS_CHECK(condition)
Check a condition — even in a release build the condition is always evaluated so it can have side eff...
Definition madness_exception.h:182
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition madness_exception.h:119
Namespace for all elements and tools of MADNESS.
Definition DFConvergence.h:9
void truncate(World &world, std::vector< Function< T, NDIM > > &v, double tol=0.0, bool fence=true)
Truncates a vector of functions.
Definition vmra.h:336
const std::vector< Function< T, NDIM > > & reconstruct(const std::vector< Function< T, NDIM > > &v)
reconstruct a vector of functions
Definition vmra.h:163
static const Slice _(0,-1, 1)
FunctionFactory< double, 3 > real_factory_3d
Definition functypedefs.h:108
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition print.h:227
Function< double, 3 > real_function_3d
Definition functypedefs.h:80
vector< functionT > vecfuncT
Definition corepotential.cc:58
CCPairFunction< T, NDIM > apply(const SeparatedConvolution< T, NDIM/2 > &op, const CCPairFunction< T, NDIM > &arg)
apply the operator to the argument
Definition ccpairfunction.h:896
Function< T, CCPairFunction< T, NDIM >::LDIM > inner(const CCPairFunction< T, NDIM > &c, const Function< T, CCPairFunction< T, NDIM >::LDIM > &f, const std::tuple< int, int, int > v1, const std::tuple< int, int, int > v2)
Definition ccpairfunction.h:993
std::string name(const FuncType &type, const int ex=-1)
Definition ccpairfunction.h:28
void matrix_inner(DistributedMatrix< T > &A, const std::vector< Function< T, NDIM > > &f, const std::vector< Function< T, NDIM > > &g, bool sym=false)
Definition distpm.cc:46
Function< T, NDIM > copy(const Function< T, NDIM > &f, const std::shared_ptr< WorldDCPmapInterface< Key< NDIM > > > &pmap, bool fence=true)
Create a new copy of the function with different distribution and optional fence.
Definition mra.h:2233
@ nemo
nemo's regularized orbitals F = psi/R
static const double thresh
Definition rk.cc:45
Definition macrotaskq.h:280
Definition SCFOperators.h:1043
double operator()(const double &val)
Definition SCFOperators.h:1044
simple structure to take the pointwise exponential of a function, shifted by +14
Definition SCFOperators.h:1041
Tensor< double > operator()(const Key< 3 > &key, const Tensor< double > &val) const
Definition SCFOperators.h:1046
void serialize(Archive &ar)
Definition SCFOperators.h:1053
double resultT
Definition SCFOperators.h:1042
Definition SCFOperators.h:1027
double operator()(const double &val)
Definition SCFOperators.h:1028
simple structure to take the pointwise logarithm of a function, shifted by +14
Definition SCFOperators.h:1025
Tensor< double > operator()(const Key< 3 > &key, const Tensor< double > &val) const
Definition SCFOperators.h:1030
void serialize(Archive &ar)
Definition SCFOperators.h:1037
double resultT
Definition SCFOperators.h:1026
static std::string tolower(std::string s)
make lower case
Definition commandlineparser.h:128
the cuspy half of the nemo tau decomposition, supplied pointwise
Definition xcfunctional.h:503
Definition dirac-hatom.cc:112
int task(int i)
Definition test_runtime.cpp:4
void e()
Definition test_sig.cc:75
std::size_t axis
Definition testpdiff.cc:59
static Molecule molecule
Definition testperiodicdft.cc:39