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 /// ctor with a nemo calculation whose bra R^2 F is already at hand; neither bra nor ket is copied
175 Exchange(World& world, const Nemo *nemo, const std::vector<Function<double,NDIM>>& R2mo, const int ispin);
176
177 std::string info() const {return "K";}
178
179 bool is_symmetric() const;
180
181 Exchange& set_symmetric(const bool flag);
182
184
185 /// how the cloud will handle the data
187 Exchange& set_macro_task_info(const std::vector<std::string>& info) {
189 return *this;
190 }
191
192
193 Exchange& set_printlevel(const long& level);
194
195 /// batches per rank in the owner-pinned symmetric partition (>= 1)
196 Exchange& set_batch_granularity(const long level);
197
198 /// 1 = gather tile results per subworld, 2 = also gather per node first
199 Exchange& set_accumulation_mode(const int mode);
200
201 /// place tasks by their measured cost rather than by counting them
202 Exchange& set_cost_aware_assignment(const bool flag);
203
204 Exchange& set_taskq(std::shared_ptr<MacroTaskQ> taskq1) {
205 this->taskq=taskq1;
206 return *this;
207 }
208
209 Exchange& set_bra_and_ket(const vecfuncT& bra, const vecfuncT& ket);
210
212 vecfuncT vket(1, ket);
213 vecfuncT vKket = this->operator()(vket);
214 return vKket[0];
215 }
216
217 /// apply the exchange operator on a vector of functions
218
219 /// note that only one spin is used (either alpha or beta orbitals)
220 /// @param[in] vket the orbitals |i> that the operator is applied on
221 /// @return a vector of orbitals K| i>
222 vecfuncT operator()(const vecfuncT& vket) const;
223
224 /// compute the matrix element <bra | K | ket>
225
226 /// @param[in] bra real_function_3d, the bra state
227 /// @param[in] ket real_function_3d, the ket state
228 T operator()(const Function<T, NDIM>& bra, const Function<T, NDIM>& ket) const {
229 return inner(bra, this->operator()(ket));
230 }
231
232 /// compute the matrix < vbra | K | vket >
233
234 /// @param[in] vbra vector of real_function_3d, the set of bra states
235 /// @param[in] vket vector of real_function_3d, the set of ket states
236 /// @return K_ij
237 Tensor<T> operator()(const vecfuncT& vbra, const vecfuncT& vket) const {
238 vecfuncT vKket = this->operator()(vket);
239 World& world=vket[0].world();
240 auto result = matrix_inner(world, vbra, vKket);
241 return result;
242 }
243
244
245};
246
247
248template<typename T, std::size_t NDIM>
249class Kinetic : public SCFOperatorBase<T,NDIM> {
252 typedef std::vector<functionT> vecfuncT;
254
255public:
257 gradop = gradient_operator<T,NDIM>(world);
258 }
259
260 std::string info() const {return "T";}
261
262 functionT operator()(const functionT& ket) const {
263 MADNESS_EXCEPTION("do not apply the kinetic energy operator on a function!",1);
264 return ket;
265 }
266
267 vecfuncT operator()(const vecfuncT& vket) const {
268 MADNESS_EXCEPTION("do not apply the kinetic energy operator on a function!",1);
269 return vket;
270 }
271
272 T operator()(const functionT& bra, const functionT& ket) const {
273 vecfuncT vbra(1,bra), vket(1,ket);
274 Tensor<T> tmat=this->operator()(vbra,vket);
275 return tmat(0l,0l);
276 }
277
278 tensorT operator()(const vecfuncT& vbra, const vecfuncT& vket) const {
279 distmatT dkinetic;
280 if (&vbra==&vket) {
281 dkinetic = kinetic_energy_matrix(world,vbra);
282 } else {
283 dkinetic = kinetic_energy_matrix(world,vbra,vket);
284 }
285 tensorT kinetic(vbra.size(),vket.size());
286 dkinetic.copy_to_replicated(kinetic);
287 return kinetic;
288 }
289
290private:
292 std::vector< std::shared_ptr<Derivative<T,NDIM> > > gradop;
293
296 const vecfuncT & vket) const;
297
298};
299
300
301template<typename T, std::size_t NDIM>
302class DerivativeOperator : public SCFOperatorBase<T,NDIM> {
304 typedef std::vector<functionT> vecfuncT;
306
307public:
308
309 DerivativeOperator(World& world, const int axis1) : world(world), axis(axis1) {
310 gradop = free_space_derivative<T,NDIM>(world, axis);
311 }
312
313 std::string info() const {return "D";}
314
315 functionT operator()(const functionT& ket) const {
316 vecfuncT vket(1,ket);
317 return this->operator()(vket)[0];
318 }
319
320 vecfuncT operator()(const vecfuncT& vket) const {
321 vecfuncT dvket=apply(world, gradop, vket, false);
322 world.gop.fence();
323 return dvket;
324 }
325
326 T operator()(const functionT& bra, const functionT& ket) const {
327 vecfuncT vbra(1,bra), vket(1,ket);
328 Tensor<T> tmat=this->operator()(vbra,vket);
329 return tmat(0l,0l);
330 }
331
332 tensorT operator()(const vecfuncT& vbra, const vecfuncT& vket) const {
333 const auto bra_equiv_ket = &vbra == &vket;
334 vecfuncT dvket=this->operator()(vket);
335 return matrix_inner(world,vbra,dvket, bra_equiv_ket);
336 }
337
338private:
340 int axis;
342
343};
344
345
346/// the Laplacian operator: \sum_i \nabla^2_i
347
348/// note that the application of the Laplacian operator is in general
349/// unstable and very sensitive to noise and cusps in the argument.
350///
351/// !!! BE SURE YOU KNOW WHAT YOU ARE DOING !!!
352///
353/// For computing matrix elements, which is reasonably stable, we refer
354template<typename T, std::size_t NDIM>
355class Laplacian : public SCFOperatorBase<T,NDIM> {
357 typedef std::vector<functionT> vecfuncT;
359
360public:
361
362 Laplacian(World& world, const double e=0.0) : world(world), eps(e) {
363 gradop = gradient_operator<T,NDIM>(world);
364 }
365
366 std::string info() const {return "D^2";}
367
368 functionT operator()(const functionT& ket) const {
369 vecfuncT vket(1,ket);
370 return this->operator()(vket)[0];
371 }
372
373 vecfuncT operator()(const vecfuncT& vket) const;
374
375 T operator()(const functionT& bra, const functionT& ket) const {
376 vecfuncT vbra(1,bra), vket(1,ket);
377 Tensor<T> tmat=this->operator()(vbra,vket);
378 return tmat(0l,0l);
379 }
380
381 tensorT operator()(const vecfuncT& vbra, const vecfuncT& vket) const {
383 return -2.0*t(vbra,vket);
384 }
385
386private:
388 std::vector< std::shared_ptr< Derivative<T,NDIM> > > gradop;
389 double eps;
390};
391
392
393
394template<typename T, std::size_t NDIM>
395class Coulomb : public SCFOperatorBase<T,NDIM> {
396public:
397
399 public:
400 // you need to define the exact argument(s) of operator() as tuple
401 typedef std::tuple<const Function<double,NDIM>&, const std::vector<Function<T,NDIM>> &> argtupleT;
402
403 using resultT = std::vector<Function<T,NDIM>>;
404
406 public:
407 partitionT do_partitioning(const std::size_t& vsize1, const std::size_t& vsize2,
408 const std::string policy) const override {
409 // one task per batch of the orbital vector, so that the subworld running a task
410 // holds only its batch of untruncated vcoul*F products; one task for the whole
411 // vector put every product on one rank (~100 GB at C40 k8 with 8 ranks)
412 return do_1d_partition(vsize1, policy);
413 }
414 };
415
419
420 // you need to define an empty constructor for the result
421 // resultT must implement operator+=(const resultT&)
422 resultT allocator(World &world, const argtupleT &argtuple) const {
423 std::size_t n = std::get<1>(argtuple).size();
424 resultT result = zero_functions_compressed<T,NDIM>(world, n);
425 return result;
426 }
427
429 // vcoul spans the molecule, each ket is local: screen like SCF's V*psi
430 const double vtol = FunctionDefaults<NDIM>::get_thresh() * 0.1;
431 return truncate(mul_sparse(vcoul.world(), vcoul, arg, vtol));
432 }
433 };
434
435 /// default empty ctor
437
438 /// default empty ctor
442
443 /// ctor with an SCF calculation providing the MOs and density
444 Coulomb(World& world, const SCF* calc);
445
446 /// ctor with a Nemo calculation providing the MOs and density
447 Coulomb(World& world, const Nemo* nemo);
448
449 std::string info() const {return "J";}
450
451 Coulomb& set_taskq(std::shared_ptr<MacroTaskQ> taskq1) {
452 this->taskq=taskq1;
453 return *this;
454 }
455
456 void reset_poisson_operator_ptr(const double lo, const double econv);
457
459 std::vector<Function<T,NDIM> > vket(1,ket);
460 return this->operator()(vket)[0];
461 }
462
463 std::vector<Function<T,NDIM> > operator()(const std::vector<Function<T,NDIM> >& vket) const {
465 World& world=vket.front().world();
466 MacroTask task(world, t, this->taskq);
467 auto result=task(vcoul,vket);
468 return result;
469 }
470
471 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
472 return inner(bra,vcoul*ket);
473 }
474
475 Tensor<T> operator()(const std::vector<Function<T,NDIM> >& vbra,
476 const std::vector<Function<T,NDIM> >& vket) const {
477 const auto bra_equiv_ket = &vbra == &vket;
478 std::vector<Function<T,NDIM> > vJket;
479 for (std::size_t i=0; i<vket.size(); ++i) {
480 vJket.push_back(this->operator()(vket[i]));
481 }
482 return matrix_inner(world,vbra,vJket,bra_equiv_ket);
483 }
484
485 /// getter for the Coulomb potential
486 const real_function_3d& potential() const {return vcoul;}
487
488 /// setter for the Coulomb potential
490
491 real_function_3d compute_density(const SCF* calc) const;
492
493 /// given a density compute the Coulomb potential
494
495 /// this function uses a newly constructed Poisson operator. Note that
496 /// the accuracy parameters must be consistent with the exchange operator.
498 return (*poisson)(density).truncate();
499 }
500
501 /// given a set of MOs in an SCF calculation, compute the Coulomb potential
502
503 /// this function uses the Poisson operator of the SCF calculation
504 real_function_3d compute_potential(const SCF* calc) const;
505
506 /// given a set of MOs in an SCF calculation, compute the Coulomb potential
507
508 /// this function uses the Poisson operator of the SCF calculation
510
511private:
513 std::shared_ptr<real_convolution_3d> poisson;
514 double lo=1.e-4;
515 real_function_3d vcoul; ///< the coulomb potential
516};
517
518
519template<typename T, std::size_t NDIM>
520class Nuclear : public SCFOperatorBase<T,NDIM> {
521public:
522
523 Nuclear(World& world, const SCF* calc);
524
525 Nuclear(World& world, const NemoBase* nemo);
526
527 /// simple constructor takes a molecule, no nuclear correlation factor or core potentials
529
530 Nuclear(World& world, std::shared_ptr<NuclearCorrelationFactor> ncf)
531 : world(world), ncf(ncf) {}
532
533 std::string info() const {return "Vnuc";}
534
536 std::vector<Function<T,NDIM> > vket(1,ket);
537 return this->operator()(vket)[0];
538 }
539
540 std::vector<Function<T,NDIM> > operator()(const std::vector<Function<T,NDIM> >& vket) const;
541
542 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
543 return inner(bra,this->operator()(ket));
544 }
545
546 Tensor<T> operator()(const std::vector<Function<T,NDIM> >& vbra,
547 const std::vector<Function<T,NDIM> >& vket) const {
548 const auto bra_equiv_ket = &vbra == &vket;
549 std::vector<Function<T,NDIM> > vVket=this->operator()(vket);
550 return matrix_inner(world,vbra,vVket,bra_equiv_ket);
551 }
552
553private:
555 std::shared_ptr<NuclearCorrelationFactor> ncf;
556
557};
558
559
560/// the z component of the angular momentum
561
562/// takes real and complex functions as input, will return complex functions
563template<typename T, std::size_t NDIM>
564class Lz : public SCFOperatorBase<T,NDIM> {
565private:
567public:
568
569 bool use_bsplines=true;
570
571 Lz(World& world, bool use_bspline_derivative=true) : world(world), use_bsplines(use_bspline_derivative) {};
572
573 std::string info() const {return "Lz";}
574
575
577 std::vector<Function<T,NDIM> > vket(1,ket);
578 return this->operator()(vket)[0];
579 }
580
581 std::vector<Function<T,NDIM> > operator()(const std::vector<Function<T,NDIM> >& vket) const {
582
583 // the operator in cartesian components as
584 // L_z = - i (x del_y - y del_x)
585
586 if (vket.size()==0) return std::vector<complex_function_3d>(0);
587
588 real_function_3d x=real_factory_3d(world).functor([] (const coord_3d& r) {return r[0];});
589 real_function_3d y=real_factory_3d(world).functor([] (const coord_3d& r) {return r[1];});
590
591 Derivative<T,NDIM> Dx = free_space_derivative<T,NDIM>(world, 0);
592 Derivative<T,NDIM> Dy = free_space_derivative<T,NDIM>(world, 1);
593 if (use_bsplines) {
594 Dx.set_bspline1();
595 Dy.set_bspline1();
596 }
597
598 reconstruct(world,vket,true);
599 std::vector<Function<T,NDIM> > delx=apply(world,Dx,vket,false);
600 std::vector<Function<T,NDIM> > dely=apply(world,Dy,vket,true);
601
602 std::vector<Function<T,NDIM> > result1=x*dely - y*delx;
603 std::vector<complex_function_3d> cresult1=convert<T,double_complex,NDIM>(world,result1);
604 std::vector<complex_function_3d> result=double_complex(0.0,-1.0)*cresult1;
605 return result;
606 }
607
608 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
609 return inner(bra,this->operator()(ket));
610 }
611
612 Tensor<T> operator()(const std::vector<Function<T,NDIM> >& vbra,
613 const std::vector<Function<T,NDIM> >& vket) const {
614 const auto bra_equiv_ket = &vbra == &vket;
615 std::vector<complex_function_3d> vVket=this->operator()(vket);
616 return matrix_inner(world,vbra,vVket,bra_equiv_ket);
617 }
618
619};
620
621
622
623/// derivative of the (regularized) nuclear potential wrt nuclear displacements
624template<typename T, std::size_t NDIM>
625class DNuclear : public SCFOperatorBase<T,NDIM> {
626public:
627
628 DNuclear(World& world, const SCF* calc, const int iatom, const int iaxis);
629
630 DNuclear(World& world, const Nemo* nemo, const int iatom, const int iaxis);
631
632 DNuclear(World& world, std::shared_ptr<NuclearCorrelationFactor> ncf,
633 const int iatom, const int iaxis)
634 : world(world), ncf(ncf), iatom(iatom), iaxis(iaxis) {}
635
636 std::string info() const {return "DVnuc";}
637
639 std::vector<Function<T,NDIM>> vket(1,ket);
640 return this->operator()(vket)[0];
641 }
642
643 std::vector<Function<T,NDIM>> operator()(const std::vector<Function<T,NDIM>>& vket) const;
644
645 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
646 return inner(bra,this->operator()(ket));
647 }
648
649 Tensor<T> operator()(const std::vector<Function<T,NDIM>>& vbra, const std::vector<Function<T,NDIM>>& vket) const {
650 const auto bra_equiv_ket = &vbra == &vket;
651 std::vector<Function<T,NDIM>> vVket=this->operator()(vket);
652 return matrix_inner(world,vbra,vVket,bra_equiv_ket);
653 }
654
655private:
657 std::shared_ptr<NuclearCorrelationFactor> ncf;
658 int iatom; ///< index of the atom which is displaced
659 int iaxis; ///< x,y,z component of the atom
660
661};
662
663template<typename T, std::size_t NDIM>
665public:
669
670 std::string info() const {return info_str;}
671
672 void set_info(const std::string new_info) {
673 info_str=new_info;
674 }
675
676 void set_potential(const Function<T,NDIM>& new_potential) {
677 potential=copy(new_potential);
678 }
679
681 return (potential*ket).truncate();
682 }
683
684 std::vector<Function<T,NDIM> > operator()(const std::vector<Function<T,NDIM> >& vket) const {
685 return truncate(potential*vket);
686 }
687
688 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
689 return inner(bra,potential*ket);
690 }
691
692 Tensor<T> operator()(const std::vector<Function<T,NDIM> >& vbra,
693 const std::vector<Function<T,NDIM> >& vket) const {
694 const auto bra_equiv_ket = &vbra == &vket;
695 return matrix_inner(world,vbra,potential*vket,bra_equiv_ket);
696 }
697
698private:
700 std::string info_str="Vlocal";
702};
703
704/// operator class for the handling of DFT exchange-correlation functionals
705template<typename T, std::size_t NDIM>
706class XCOperator : public SCFOperatorBase<T,NDIM> {
707public:
708
709 /// default ctor without information about the XC functional
711 extra_truncation(FunctionDefaults<3>::get_thresh()*0.01) {}
712
713 /// custom ctor with information about the XC functional
714 XCOperator(World& world, std::string xc_data, const bool spin_polarized,
715 const real_function_3d& arho, const real_function_3d& brho,
716 std::string deriv="abgv");
717
718 /// custom ctor with the XC functional
719 XCOperator(World& world, std::shared_ptr<XCfunctional> xc,
720 const bool spin_polarized,
721 int ispin,
722 int nbeta,
723 const real_function_3d& arho, const real_function_3d& brho,
724 std::string deriv="abgv");
725
726 /// ctor with an SCF calculation, will initialize the necessary intermediates
727 XCOperator(World& world, const SCF* scf, int ispin=0, std::string deriv="abgv");
728
729 /// ctor with a Nemo calculation, will initialize the necessary intermediates
730 XCOperator(World& world, const Nemo* nemo, int ispin=0);
731
732 /// ctor for the regularized (nemo) path, without a Nemo object
733
734 /// @param[in] arho,brho the physical densities rho_s
735 /// @param[in] ncf_ the nuclear correlation factor
736 /// @param[in] arho_reg,brho_reg the regularized densities rho_s/R^2, which let
737 /// prep_xc_args build zeta without putting the
738 /// nuclear cusp under a numerical derivative
739 XCOperator(World& world, std::string xc_data, const bool spin_polarized,
740 const real_function_3d& arho, const real_function_3d& brho,
741 std::shared_ptr<NuclearCorrelationFactor> ncf_,
742 const real_function_3d& arho_reg_, const real_function_3d& brho_reg_,
743 std::string deriv="abgv");
744
745 /// ctor with an SCF calculation, will initialize the necessary intermediates
746 XCOperator(World& world, const SCF* scf, const real_function_3d& arho,
747 const real_function_3d& brho, int ispin=0, std::string deriv="abgv");
748
749 /// ctor with an Nemo calculation, will initialize the necessary intermediates
750 XCOperator(World& world, const Nemo* scf, const real_function_3d& arho,
751 const real_function_3d& brho, int ispin=0);
752
753 std::string info() const {return "Vxc";}
754
755 XCOperator& set_extra_truncation(const double& fac) {
757 if (world.rank()==0)
758 print("set extra truncation in XCOperator to", extra_truncation);
759 return *this;
760 }
761
762 /// set the spin state this operator is acting on
763 void set_ispin(const int i) const {ispin=i;}
764
765 /// print the meta-gga de/dtau range each time the operator is applied
766 XCOperator& set_print_level(const int p) {print_level=p; return *this;}
767
768 /// apply the xc potential on a set of orbitals
769 std::vector<Function<T,NDIM> > operator()(const std::vector<Function<T,NDIM> >& vket) const;
770
771 /// apply the xc potential on an orbitals
773 std::vector<Function<T,3> > vket(1,ket);
774 std::vector<Function<T,3> > vKket=this->operator()(vket);
775 return vKket[0];
776 }
777
778 /// the xc contribution to the Fock matrix, as a matrix element
779
780 /// The 1x1 case of the vector form below; the same bra convention applies.
781 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
782 std::vector<Function<T,NDIM> > vbra(1,bra), vket(1,ket);
783 return this->operator()(vbra,vket)(0l,0l);
784 }
785
786 /// the xc contribution to the Fock matrix
787
788 /// With a nuclear correlation factor the bra must carry R^2 -- call it as
789 /// xcoperator(R2nemo, nemo), the way Kinetic is called in
790 /// Nemo::compute_fock_matrix. Without one, bra and ket are the same orbitals.
791 Tensor<T> operator()(const std::vector<Function<T,NDIM>>& vbra,
792 const std::vector<Function<T,NDIM>>& vket) const;
793
794 /// opt in to the weak form, if the `xc_weak_gga` parameter asks for it
795
796 /// Load-bearing: in weak form make_xc_potential() returns only de/drho, so a
797 /// caller that does not also apply weak_xc_terms() and add the matrix form's
798 /// contribution (operator()(vbra,vket)) would silently drop the whole semilocal
799 /// contribution and return a plausible but wrong energy. Only
800 /// Nemo::compute_nemo_potentials implements the split, so only it opts in; SCF,
801 /// OEP, TDHF and the response kernels keep the multiplicative potential.
802 XCOperator& allow_weak_form() {weak_form_ok=true; return *this;}
803
804 /// override CalculationParameters::xc_weak_gga(), for callers without one
805 XCOperator& set_weak_gga(const bool flag) {weak_gga=flag; return *this;}
806
807 /// true if this operator is running in weak form, i.e. make_xc_potential()
808 /// returns only de/drho and the flux is carried separately
809
810 /// Requires both the caller's allow_weak_form() opt-in and the user's
811 /// `xc_weak_gga` parameter. A functional with no sigma dependence has no flux,
812 /// so it is never in weak form either.
813 ///
814 /// Why it exists: the semilocal potential is -div(X) with
815 /// X = 2 de/dsigma grad(rho), and X has a jump at every nucleus
816 /// (zeta = grad log rho -> -2Z r_hat, whose Cartesian components flip sign
817 /// across the origin). Differentiating that jump is what produces the +-8e4
818 /// excursions, and no rearrangement of the multiplicative form avoids it,
819 /// because div(X) *is* a derivative of X.
820 ///
821 /// The weak form never differentiates X:
822 /// <phi|v|psi> = int (df/drho) phi psi + int X . grad(phi psi)
823 /// and in a Green's-function code the same holds for the orbital update,
824 /// because a radial convolution commutes with the gradient:
825 /// G * (psi div X) = div(G * (X psi)) - G * (X . grad psi)
826 /// so the divergence acts on G*(X psi), which is C^1, and the jump is only
827 /// ever convolved. Same for the meta-gga term -1/2 div(v_tau grad psi).
828 bool is_weak_form() const;
829
830 /// the semilocal flux X = 2 (de/dsigma_ss) grad(rho_s) + (de/dsigma_ab) grad(rho_s')
831
832 /// Only assigned in weak form, by make_xc_potential(). Same-spin and cross-spin
833 /// contributions are summed: they enter as a single divergence.
835
836 /// weak-form split of the non-multiplicative xc terms
837
838 /// Writes the decomposition
839 /// v_xc^{semilocal+tau} psi_i = mult_i - div(Y_i)
840 /// with (nemo kets F_i, W_i = v_tau (grad F_i - U1 F_i))
841 /// mult_i = X.grad(F_i) + 1/2 U1.W_i, Y_i = X F_i + 1/2 W_i.
842 /// `mult` goes into V psi; `flux` is what the caller pushes through the
843 /// Green's function, as 2 div(G*Y_i), so that neither X nor v_tau is ever
844 /// differentiated. Requires make_xc_potential() first.
845 void weak_xc_terms(const std::vector<Function<T,NDIM> >& vket,
846 std::vector<Function<T,NDIM> >& mult,
847 std::vector<std::vector<Function<T,NDIM> > >& flux) const;
848
849 /// compute the xc energy using the precomputed intermediates vf and delrho
850 double compute_xc_energy() const;
851
852 /// the multiplicative part of the potential, as make_xc_potential() returned it
854
855 /// return the local xc potential
857
858 /// true if the functional contributes a non-multiplicative (meta-gga) term
859 bool has_tau_term() const;
860
861 /// compute the kinetic energy density and add it to the intermediates
862
863 /// tau is orbital-dependent, so unlike the density it cannot be recovered
864 /// from what the ctors are given -- it has to be supplied separately. Call
865 /// this after construction and before make_xc_potential() whenever
866 /// has_tau_term() is true; make_xc_potential() throws otherwise.
867 /// The occupation numbers are required, not optional: amo/bmo may carry
868 /// virtual orbitals (occupation zero), which contribute nothing to the
869 /// density but would inflate an unweighted sum of |grad psi|^2, and
870 /// occupations may be fractional.
871 /// @param[in] amo alpha orbitals (nemos if a nuclear correlation factor is set)
872 /// @param[in] aocc occupation numbers of amo
873 /// @param[in] bmo beta orbitals, ignored if the calculation is spin-restricted
874 /// @param[in] bocc occupation numbers of bmo
875 /// how the two U1 terms of tau's product rule are evaluated
876
877 /// U1 = -grad(R)/R is analytic but componentwise non-smooth at each nucleus
878 /// (U1_x ~ x/r), so carrying it as an MRA Function costs depth ~18 and every
879 /// product with it inherits that depth -- which refine_to_common_level then
880 /// imposes on every xc intermediate.
881 enum class TauU1 {
882 mra, ///< U1 and |U1|^2 projected into Functions and multiplied
883 pointwise ///< U1 evaluated from its functor at the orbital tree's
884 ///< quadrature points; nothing involving it is projected
885 };
886
887 void set_tau(const vecfuncT& amo, const Tensor<double>& aocc,
888 const vecfuncT& bmo=vecfuncT(),
889 const Tensor<double>& bocc=Tensor<double>(),
890 const TauU1 u1mode=TauU1::pointwise) const;
891
892 /// the kinetic energy density of one spin channel, as set by set_tau()
893
894 /// exposed for diagnostics and for the exact check int(tau) == T
895 real_function_3d get_tau(const int spin=0) const;
896
897 /// de/dtau, as computed by make_xc_potential()
899
900 /// apply the non-multiplicative meta-gga term on a set of orbitals
901
902 /// \f[
903 /// \hat v_\tau \psi_i = -\frac{1}{2}\nabla\cdot
904 /// \left(\frac{\partial e_{xc}}{\partial\tau_\sigma}\nabla\psi_i\right)
905 /// \f]
906 /// evaluated as \f$ -\frac{1}{2}\sum_x D_x(v_\tau D_x\psi_i) \f$, so that
907 /// \f$ v_\tau \f$ is only ever multiplied and never differentiated. That
908 /// nested form is also self-adjoint by construction, while the expanded
909 /// \f$ -\frac{1}{2}(v_\tau\nabla^2\psi + \nabla v_\tau\cdot\nabla\psi) \f$
910 /// is symmetric only up to discretization error and needs \f$\nabla^2\psi\f$.
911 /// Requires make_xc_potential() to have been called first, which is where
912 /// \f$ v_\tau \f$ is computed.
913 std::vector<Function<T,NDIM> > apply_tau_term(const std::vector<Function<T,NDIM> >& vket) const;
914
915 /// construct the xc kernel and apply it directly on the (response) density
916
917 /// the xc kernel is the second derivative of the xc functions wrt the density
918 /// @param[in] density the (response) density on which the kernel is applied
919 /// @return kernel * density
921 const vecfuncT grad_dens_pt=vecfuncT()) const;
922
923private:
924
925 /// the world
927
928 /// which derivative operator to use
929 std::string dft_deriv;
930
931 /// print level; >=2 logs the meta-gga de/dtau range
933
934public:
935 /// interface to the actual XC functionals
936 std::shared_ptr<XCfunctional> xc;
937
938private:
939 /// number of beta orbitals
940 int nbeta;
941
942 /// the XC functionals depend on the spin of the orbitals they act on
943 mutable int ispin;
944
945 /// additional truncation for the densities in the XC kernel
946
947 /// the densities in the DFT kernal are processed as their inverses,
948 /// so noise in the small density regions might amplify and lead to inaccurate
949 /// results. Extra truncation will tighten the truncation threshold by a
950 /// specified factor, default is 0.01.
952
953 /// the nuclear correlation factor, if it exists, for computing derivatives for GGA
954 std::shared_ptr<NuclearCorrelationFactor> ncf;
955
956 /// functions that are need for the computation of the XC operator
957
958 /// the ordering of the intermediates is fixed, but the code can handle
959 /// non-initialized functions, so if e.g. no GGA is requested, all the
960 /// corresponding vector components may be left empty.
961 /// For the ordering of the intermediates see xcfunctional::xc_arg
963
964 /// de/dtau, the prefactor of the non-multiplicative meta-gga term
965
966 /// falls out of the same pointwise pass as the multiplicative potential, so
967 /// it is stashed by make_xc_potential() rather than recomputed
969
970 /// gradient operator honouring dft_deriv, for the meta-gga term
971 std::shared_ptr<Derivative<T,NDIM> > make_derivative(const int axis) const;
972
973 /// divergence of a vector field, honouring dft_deriv
975
976 /// caller has opted in to the weak form, see allow_weak_form()
977 bool weak_form_ok=false;
978
979 /// the user asked for the weak form: CalculationParameters::xc_weak_gga()
980
981 /// Two independent conditions, and both are needed. weak_form_ok says the
982 /// *caller* implements the split; this says the *user* wants it.
983 bool weak_gga=false;
984
985 /// the semilocal flux, assigned by make_xc_potential() in weak form only
987
988 /// the multiplicative potential, stashed by make_xc_potential()
990
991 /// the body of make_xc_potential(); the wrapper only stashes vlocal
993
994 /// true once set_tau() has supplied tau, by either route
995 bool has_tau_args() const;
996
997 /// the four analytic U1 quantities the xc ops evaluate pointwise
998
999 /// Empty unless the pointwise route is in use. They are handed to the op rather
1000 /// than projected into xc_args precisely because a projected product with U1 is
1001 /// what rings; see nemo_u1_functors.
1003
1004 /// compute the intermediates for the XC functionals
1005
1006 /// @param[in] arho density of the alpha orbitals
1007 /// @param[in] brho density of the beta orbitals (necessary only if spin-polarized)
1008 /// @return xc_args vector of intermediates as described above
1009 /// compute the intermediates for the XC functionals
1010
1011 /// If the regularized densities are supplied, zeta = grad log(rho) is built as
1012 /// grad log(rho_reg) - 2 U1 -- exact, and it keeps the nuclear cusp of
1013 /// rho = R^2 rho_reg out from under the numerical derivative.
1014 vecfuncT prep_xc_args(const real_function_3d& arho, const real_function_3d& brho,
1015 const real_function_3d& arho_reg = real_function_3d(),
1016 const real_function_3d& brho_reg = real_function_3d()) const;
1017
1018 /// compute the intermediates for the XC functionals
1019
1020 /// @param[in] dens_pt perturbed densities from CPHF or TDDFT equations
1021 /// @param[in,out] xc_args vector of intermediates as described above
1022 /// @param[out] ddens_pt xyz-derivatives of dens_pt
1023 void prep_xc_args_response(const real_function_3d& dens_pt,
1024 vecfuncT& xc_args, vecfuncT& ddens_pt) const;
1025
1026 /// check if the intermediates are initialized
1027 bool is_initialized() const {
1028 return (xc_args.size()>0);
1029 }
1030
1031 /// simple structure to take the pointwise logarithm of a function, shifted by +14
1032 struct logme{
1033 typedef double resultT;
1034 struct logme1 {
1035 double operator()(const double& val) {return log(std::max(1.e-14,val))+14.0;}
1036 };
1037 Tensor<double> operator()(const Key<3>& key, const Tensor<double>& val) const {
1038 Tensor<double> result=copy(val);
1039 logme1 op;
1040 return result.unaryop(op);
1041 }
1042
1043 template <typename Archive>
1044 void serialize(Archive& ar) {}
1045 };
1046
1047 /// simple structure to take the pointwise exponential of a function, shifted by +14
1048 struct expme{
1049 typedef double resultT;
1050 struct expme1 {
1051 double operator()(const double& val) {return exp(val-14.0);}
1052 };
1053 Tensor<double> operator()(const Key<3>& key, const Tensor<double>& val) const {
1054 Tensor<double> result=copy(val);
1055 expme1 op;
1056 return result.unaryop(op);
1057 }
1058
1059 template <typename Archive>
1060 void serialize(Archive& ar) {}
1061
1062 };
1063};
1064
1065/// Computes matrix representation of the Fock operator
1066template<typename T, std::size_t NDIM>
1067class Fock : public SCFOperatorBase<T,NDIM> {
1068public:
1070
1074
1075 /// pretty print what this is actually computing
1076 std::string info() const {
1077 std::string s;
1078 for (auto& op : operators) {
1079 double number=std::get<0>(op.second);
1080 if (number==-1.0) {
1081 s+=" - ";
1082 } else if (number!=1.0) {
1083 std::stringstream snumber;
1084 snumber << std::fixed << std::setw(2) << number;
1085 s+=" "+snumber.str()+ " ";
1086 } else {
1087 MADNESS_CHECK(number==1.0);
1088 s+=" + ";
1089 }
1090 s+=op.first;
1091 }
1092 return s;
1093 }
1094
1095 /// add an operator with default prefactor 1.0
1096 void add_operator(std::string name, std::shared_ptr<SCFOperatorBase<T,NDIM>> new_op) {
1097 operators.insert({name,valueT(1.0,new_op)});
1098 }
1099
1100 /// add an operator with custom prefactor (e.g. -1.0 for the exchange, supposedly)
1101 void add_operator(std::string name, std::tuple<double,std::shared_ptr<SCFOperatorBase<T,NDIM>>> new_op) {
1102 operators.insert({name,new_op});
1103 }
1104
1105 /// remove operator, returns 0 if no operator was found
1106 int remove_operator(std::string name) {
1107 return operators.erase(name);
1108 }
1109
1111 MADNESS_EXCEPTION("Fock(ket) not yet implemented",1);
1112 Function<T,NDIM> result;
1113 return result;
1114 }
1115
1116 std::vector<Function<T,NDIM>> operator()(const std::vector<Function<T,NDIM>>& vket) const {
1117 // make sure T is not part of the Fock operator, it's numerically unstable!
1118 MADNESS_CHECK(operators.count("T")==0);
1119 std::vector<Function<T,NDIM>> result = zero_functions_compressed<T, NDIM>(world, vket.size());
1120 for (const auto& op : operators) {
1121 result+=std::get<0>(op.second) * (*std::get<1>(op.second))(vket);
1122 }
1123 return result;
1124 }
1125
1126 T operator()(const Function<T,NDIM>& bra, const Function<T,NDIM>& ket) const {
1127 std::vector<Function<T,NDIM>> vbra(1,bra), vket(1,ket);
1128 return (*this)(vbra,vket)(0,0);
1129 }
1130
1131 /// compute the Fock matrix by summing up all contributions
1132 Tensor<T> operator()(const std::vector<Function<T,NDIM>>& vbra, const std::vector<Function<T,NDIM>>& vket) const {
1133 return this->operator()(vbra,vket,false);
1134 }
1135
1136 /// compute the Fock matrix by summing up all contributions
1137 Tensor<T> operator()(const std::vector<Function<T,NDIM>>& vbra, const std::vector<Function<T,NDIM>>& vket,
1138 const bool symmetric) const {
1139 Tensor<T> fock(vbra.size(),vket.size());
1140 for (const auto& op : operators) {
1141 Tensor<T> tmp=std::get<0>(op.second) * (*std::get<1>(op.second))(vbra,vket);
1142// print("Operator",std::get<1>(op.second)->info());
1143// print(tmp);
1144 fock+=tmp;
1145 }
1146 return fock;
1147 }
1148
1149
1150private:
1151 /// the world
1153
1154 /// type defining Fock operator contribution including prefactor
1155 typedef std::tuple<double,std::shared_ptr<SCFOperatorBase<T,NDIM> > > valueT;
1156
1157 /// all the Fock operator contribution
1158 std::map<std::string,valueT> operators;
1159};
1160
1161}
1162#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:407
Definition SCFOperators.h:398
std::vector< Function< T, NDIM > > resultT
Definition SCFOperators.h:403
MacroTaskCoulomb()
Definition SCFOperators.h:416
resultT allocator(World &world, const argtupleT &argtuple) const
Definition SCFOperators.h:422
std::tuple< const Function< double, NDIM > &, const std::vector< Function< T, NDIM > > & > argtupleT
Definition SCFOperators.h:401
resultT operator()(const Function< double, NDIM > &vcoul, const std::vector< Function< T, NDIM > > &arg) const
Definition SCFOperators.h:428
Definition SCFOperators.h:395
Function< T, NDIM > compute_potential(const Function< T, NDIM > &density) const
given a density compute the Coulomb potential
Definition SCFOperators.h:497
real_function_3d compute_density(const SCF *calc) const
Definition SCFOperators.cc:221
Coulomb & set_taskq(std::shared_ptr< MacroTaskQ > taskq1)
Definition SCFOperators.h:451
real_function_3d & potential()
setter for the Coulomb potential
Definition SCFOperators.h:489
World & world
Definition SCFOperators.h:512
Coulomb(World &world)
default empty ctor
Definition SCFOperators.h:436
Coulomb(World &world, const double lo, const double thresh=FunctionDefaults< 3 >::get_thresh())
default empty ctor
Definition SCFOperators.h:439
const real_function_3d & potential() const
getter for the Coulomb potential
Definition SCFOperators.h:486
std::string info() const
print some information about this operator
Definition SCFOperators.h:449
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:463
std::shared_ptr< real_convolution_3d > poisson
Definition SCFOperators.h:513
real_function_3d vcoul
the coulomb potential
Definition SCFOperators.h:515
double lo
Definition SCFOperators.h:514
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:475
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:458
void reset_poisson_operator_ptr(const double lo, const double econv)
Definition SCFOperators.cc:216
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:471
derivative of the (regularized) nuclear potential wrt nuclear displacements
Definition SCFOperators.h:625
World & world
Definition SCFOperators.h:656
std::string info() const
print some information about this operator
Definition SCFOperators.h:636
DNuclear(World &world, std::shared_ptr< NuclearCorrelationFactor > ncf, const int iatom, const int iaxis)
Definition SCFOperators.h:632
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:645
std::shared_ptr< NuclearCorrelationFactor > ncf
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:649
int iatom
index of the atom which is displaced
Definition SCFOperators.h:658
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:638
int iaxis
x,y,z component of the atom
Definition SCFOperators.h:659
Definition SCFOperators.h:302
tensorT operator()(const vecfuncT &vbra, const vecfuncT &vket) const
compute the matrix <vbra | op | vket>
Definition SCFOperators.h:332
functionT operator()(const functionT &ket) const
Definition SCFOperators.h:315
int axis
Definition SCFOperators.h:340
DerivativeOperator(World &world, const int axis1)
Definition SCFOperators.h:309
T operator()(const functionT &bra, const functionT &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:326
std::string info() const
print some information about this operator
Definition SCFOperators.h:313
Derivative< T, NDIM > gradop
Definition SCFOperators.h:341
Tensor< T > tensorT
Definition SCFOperators.h:305
Function< T, NDIM > functionT
Definition SCFOperators.h:303
vecfuncT operator()(const vecfuncT &vket) const
apply this operator on the argument vector of functions
Definition SCFOperators.h:320
World & world
Definition SCFOperators.h:339
std::vector< functionT > vecfuncT
Definition SCFOperators.h:304
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:494
Function< T, NDIM > functionT
Definition SCFOperators.h:111
Exchange & set_taskq(std::shared_ptr< MacroTaskQ > taskq1)
Definition SCFOperators.h:204
Exchange & set_printlevel(const long &level)
Definition exchangeoperator.cc:476
Exchange & set_batch_granularity(const long level)
batches per rank in the owner-pinned symmetric partition (>= 1)
Definition exchangeoperator.cc:482
Exchange & set_macro_task_info(const std::vector< std::string > &info)
Definition SCFOperators.h:187
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | K | ket>
Definition SCFOperators.h:228
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:453
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:211
Exchange & set_symmetric(const bool flag)
Definition exchangeoperator.cc:458
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:488
Tensor< T > operator()(const vecfuncT &vbra, const vecfuncT &vket) const
compute the matrix < vbra | K | vket >
Definition SCFOperators.h:237
Exchange & set_bra_and_ket(const vecfuncT &bra, const vecfuncT &ket)
Definition exchangeoperator.cc:446
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:470
std::string info() const
print some information about this operator
Definition SCFOperators.h:177
friend std::ostream & operator<<(std::ostream &os, const ExchangeAlgorithm &alg)
Definition SCFOperators.h:122
Exchange & set_algorithm(const ExchangeAlgorithm &alg)
Definition exchangeoperator.cc:464
Computes matrix representation of the Fock operator.
Definition SCFOperators.h:1067
int remove_operator(std::string name)
remove operator, returns 0 if no operator was found
Definition SCFOperators.h:1106
Fock(World &world)
Definition SCFOperators.h:1069
World & world
the world
Definition SCFOperators.h:1152
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:1132
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:1137
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:1158
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:1126
std::tuple< double, std::shared_ptr< SCFOperatorBase< T, NDIM > > > valueT
type defining Fock operator contribution including prefactor
Definition SCFOperators.h:1155
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:1101
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:1110
std::string info() const
pretty print what this is actually computing
Definition SCFOperators.h:1076
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:1096
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:1116
FunctionDefaults holds default paramaters as static class members.
Definition funcdefaults.h:101
static const double & get_thresh()
Returns the default threshold.
Definition funcdefaults.h:183
A multiresolution adaptive numerical function.
Definition mra.h:140
World & world() const
Returns the world.
Definition mra.h:754
Key is the index for a node of the 2^NDIM-tree.
Definition key.h:71
Definition SCFOperators.h:249
Tensor< T > tensorT
Definition SCFOperators.h:253
std::vector< std::shared_ptr< Derivative< T, NDIM > > > gradop
Definition SCFOperators.h:292
tensorT operator()(const vecfuncT &vbra, const vecfuncT &vket) const
compute the matrix <vbra | op | vket>
Definition SCFOperators.h:278
World & world
Definition SCFOperators.h:291
Kinetic(World &world)
Definition SCFOperators.h:256
std::vector< functionT > vecfuncT
Definition SCFOperators.h:252
Function< T, NDIM > functionT
Definition SCFOperators.h:251
std::string info() const
print some information about this operator
Definition SCFOperators.h:260
distmatT kinetic_energy_matrix(World &world, const vecfuncT &v) const
Definition SCFOperators.cc:51
DistributedMatrix< T > distmatT
Definition SCFOperators.h:250
vecfuncT operator()(const vecfuncT &vket) const
apply this operator on the argument vector of functions
Definition SCFOperators.h:267
T operator()(const functionT &bra, const functionT &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:272
functionT operator()(const functionT &ket) const
Definition SCFOperators.h:262
the Laplacian operator: \sum_i \nabla^2_i
Definition SCFOperators.h:355
T operator()(const functionT &bra, const functionT &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:375
double eps
Definition SCFOperators.h:389
Tensor< T > tensorT
Definition SCFOperators.h:358
functionT operator()(const functionT &ket) const
Definition SCFOperators.h:368
Function< T, NDIM > functionT
Definition SCFOperators.h:356
std::string info() const
print some information about this operator
Definition SCFOperators.h:366
tensorT operator()(const vecfuncT &vbra, const vecfuncT &vket) const
compute the matrix <vbra | op | vket>
Definition SCFOperators.h:381
std::vector< functionT > vecfuncT
Definition SCFOperators.h:357
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:362
std::vector< std::shared_ptr< Derivative< T, NDIM > > > gradop
Definition SCFOperators.h:388
World & world
Definition SCFOperators.h:387
Definition SCFOperators.h:664
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:692
std::string info() const
print some information about this operator
Definition SCFOperators.h:670
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:688
void set_info(const std::string new_info)
Definition SCFOperators.h:672
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:684
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:680
Function< T, NDIM > potential
Definition SCFOperators.h:701
LocalPotentialOperator(World &world)
Definition SCFOperators.h:666
World & world
Definition SCFOperators.h:699
std::string info_str
Definition SCFOperators.h:700
LocalPotentialOperator(World &world, const std::string info, const Function< T, NDIM > potential)
Definition SCFOperators.h:667
void set_potential(const Function< T, NDIM > &new_potential)
Definition SCFOperators.h:676
the z component of the angular momentum
Definition SCFOperators.h:564
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:608
Lz(World &world, bool use_bspline_derivative=true)
Definition SCFOperators.h:571
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:612
std::vector< Function< T, NDIM > > operator()(const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:581
World & world
Definition SCFOperators.h:566
std::string info() const
print some information about this operator
Definition SCFOperators.h:573
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:576
bool use_bsplines
Definition SCFOperators.h:569
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
partitionT do_1d_partition(const std::size_t vsize, const std::string policy) const
Definition macrotaskpartitioner.h:251
Definition macrotaskq.h:991
Definition molecule.h:129
Definition nemo.h:70
The Nemo class.
Definition nemo.h:375
Definition SCFOperators.h:520
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
Definition SCFOperators.h:535
T operator()(const Function< T, NDIM > &bra, const Function< T, NDIM > &ket) const
compute the matrix element <bra | op | ket>
Definition SCFOperators.h:542
Tensor< T > operator()(const std::vector< Function< T, NDIM > > &vbra, const std::vector< Function< T, NDIM > > &vket) const
Definition SCFOperators.h:546
std::string info() const
print some information about this operator
Definition SCFOperators.h:533
World & world
Definition SCFOperators.h:554
Nuclear(World &world, std::shared_ptr< NuclearCorrelationFactor > ncf)
Definition SCFOperators.h:530
std::shared_ptr< NuclearCorrelationFactor > ncf
Definition SCFOperators.h:555
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:706
bool has_tau_term() const
true if the functional contributes a non-multiplicative (meta-gga) term
Definition SCFOperators.cc:515
XCOperator(World &world)
default ctor without information about the XC functional
Definition SCFOperators.h:710
TauU1
compute the kinetic energy density and add it to the intermediates
Definition SCFOperators.h:881
@ 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:962
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:794
XCOperator & allow_weak_form()
opt in to the weak form, if the xc_weak_gga parameter asks for it
Definition SCFOperators.h:802
bool is_initialized() const
check if the intermediates are initialized
Definition SCFOperators.h:1027
bool weak_gga
the user asked for the weak form: CalculationParameters::xc_weak_gga()
Definition SCFOperators.h:983
double compute_xc_energy() const
compute the xc energy using the precomputed intermediates vf and delrho
Definition SCFOperators.cc:937
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:765
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:521
XCOperator & set_weak_gga(const bool flag)
override CalculationParameters::xc_weak_gga(), for callers without one
Definition SCFOperators.h:805
std::string info() const
print some information about this operator
Definition SCFOperators.h:753
real_function_3d div_dft_deriv(const vecfuncT &v) const
divergence of a vector field, honouring dft_deriv
Definition SCFOperators.cc:778
real_function_3d make_xc_potential() const
return the local xc potential
Definition SCFOperators.cc:988
bool has_tau_args() const
true once set_tau() has supplied tau, by either route
Definition SCFOperators.cc:962
XCOperator & set_extra_truncation(const double &fac)
Definition SCFOperators.h:755
real_function_3d vtau
de/dtau, the prefactor of the non-multiplicative meta-gga term
Definition SCFOperators.h:968
Function< T, NDIM > operator()(const Function< T, NDIM > &ket) const
apply the xc potential on an orbitals
Definition SCFOperators.h:772
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:1207
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:1133
XCOperator & set_print_level(const int p)
print the meta-gga de/dtau range each time the operator is applied
Definition SCFOperators.h:766
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:781
nemo_u1_functors make_u1_functors() const
the four analytic U1 quantities the xc ops evaluate pointwise
Definition SCFOperators.cc:971
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:505
real_function_3d get_vtau() const
de/dtau, as computed by make_xc_potential()
Definition SCFOperators.h:898
std::string dft_deriv
which derivative operator to use
Definition SCFOperators.h:929
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:528
std::shared_ptr< NuclearCorrelationFactor > ncf
the nuclear correlation factor, if it exists, for computing derivatives for GGA
Definition SCFOperators.h:954
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:690
real_function_3d get_vlocal() const
the multiplicative part of the potential, as make_xc_potential() returned it
Definition SCFOperators.h:853
void set_ispin(const int i) const
set the spin state this operator is acting on
Definition SCFOperators.h:763
double extra_truncation
additional truncation for the densities in the XC kernel
Definition SCFOperators.h:951
int print_level
print level; >=2 logs the meta-gga de/dtau range
Definition SCFOperators.h:932
std::shared_ptr< XCfunctional > xc
interface to the actual XC functionals
Definition SCFOperators.h:936
real_function_3d vlocal
the multiplicative potential, stashed by make_xc_potential()
Definition SCFOperators.h:989
bool is_weak_form() const
Definition SCFOperators.cc:787
real_function_3d make_xc_potential_impl() const
the body of make_xc_potential(); the wrapper only stashes vlocal
Definition SCFOperators.cc:995
World & world
the world
Definition SCFOperators.h:926
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:834
vecfuncT semilocal_flux
the semilocal flux, assigned by make_xc_potential() in weak form only
Definition SCFOperators.h:986
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:1094
int ispin
the XC functionals depend on the spin of the orbitals they act on
Definition SCFOperators.h:943
int nbeta
number of beta orbitals
Definition SCFOperators.h:940
bool weak_form_ok
caller has opted in to the weak form, see allow_weak_form()
Definition SCFOperators.h:977
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
FunctionFactory< double, 3 > real_factory_3d
Definition functypedefs.h:108
Function< double, 3 > real_function_3d
Definition functypedefs.h:80
void print(const T &t, Ts &&... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition print.h:232
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< TENSOR_RESULT_TYPE(L, R), NDIM > mul_sparse(const Function< L, NDIM > &left, const Function< R, NDIM > &right, double tol, bool fence=true, bool do_make_redundant=true)
Sparse multiplication; the scalar interface redirects to the vector one in vmra.h.
Definition mra.h:1973
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:2229
@ nemo
nemo's regularized orbitals F = psi/R
static const double thresh
Definition rk.cc:45
Definition macrotaskq.h:280
Definition SCFOperators.h:1050
double operator()(const double &val)
Definition SCFOperators.h:1051
simple structure to take the pointwise exponential of a function, shifted by +14
Definition SCFOperators.h:1048
Tensor< double > operator()(const Key< 3 > &key, const Tensor< double > &val) const
Definition SCFOperators.h:1053
void serialize(Archive &ar)
Definition SCFOperators.h:1060
double resultT
Definition SCFOperators.h:1049
Definition SCFOperators.h:1034
double operator()(const double &val)
Definition SCFOperators.h:1035
simple structure to take the pointwise logarithm of a function, shifted by +14
Definition SCFOperators.h:1032
Tensor< double > operator()(const Key< 3 > &key, const Tensor< double > &val) const
Definition SCFOperators.h:1037
void serialize(Archive &ar)
Definition SCFOperators.h:1044
double resultT
Definition SCFOperators.h:1033
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