MADNESS  0.10.1
mp2.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 /*!
33  \file mp2.h
34  \brief Solves molecular MP2 equations
35  \defgroup Solves molecular MP2 equations
36  \ingroup examples
37 */
38 
39 #ifndef MP2_H_
40 #define MP2_H_
41 
42 #include <madness/mra/mra.h>
43 #include <madness/mra/lbdeux.h>
45 #include<madness/chem/SCF.h>
46 #include <madness/mra/nonlinsol.h>
51 #include<madness/chem/nemo.h>
52 
54 
57 
58 
59 #include <iostream>
60 
61 namespace madness {
62 
63 struct LBCost {
64  double leaf_value;
65  double parent_value;
66 
67  LBCost(double leaf_value = 1.0, double parent_value = 1.0)
69 
70  double operator()(const Key<6>& key, const FunctionNode<double, 6>& node) const {
71  return node.coeff().size();
72  }
73 };
74 
75 
76 class HartreeFock {
78 public:
79  std::shared_ptr<Nemo> nemo_ptr;
80 private:
81  mutable double coords_sum; // sum of square of coords at last solved geometry
82 
83  // save the Coulomb potential
85 
86  /// reconstructed orbitals: R * phi, where R is the nuclear correlation factor
87  std::vector<real_function_3d> orbitals_;
88 
89  /// R^2 * phi, where R is the nuclear correlation factor, corresponds
90  /// to the bra space of the transformed operators
91  std::vector<real_function_3d> R2orbitals_;
92 
93 public:
94 
95  HartreeFock(World& world, std::shared_ptr<Nemo> nemo) :
96  world(world), nemo_ptr(nemo), coords_sum(-1.0) {
97  }
98 
99  World& get_world() {return world;} // just to silence compiler about unused private variable
100 
101  bool provides_gradient() const { return true; }
102 
103  double value() {
104  return value(nemo_ptr->get_calc()->molecule.get_all_coords());
105  }
106 
107  double value(const Tensor<double>& x) {
108 
109  // fast return if the reference is already solved at this geometry
110  double xsq = x.sumsq();
111  if (xsq == coords_sum) return nemo_ptr->get_calc()->current_energy;
112 
113  nemo_ptr->get_calc()->molecule.set_all_coords(x.reshape(nemo_ptr->get_calc()->molecule.natom(), 3));
114  coords_sum = xsq;
115  nemo_ptr->value(x);
116 
117  MolecularOrbitals<double,3> mos(nemo_ptr->get_calc()->amo,nemo_ptr->get_calc()->aeps);
118  reset_orbitals(mos);
119  return nemo_ptr->get_calc()->current_energy;
120  }
121 
123  nemo_ptr->get_calc()->amo=mos.get_mos();
124  nemo_ptr->get_calc()->aeps=mos.get_eps();
125  MADNESS_CHECK(size_t(nemo_ptr->get_calc()->aeps.size())==nemo_ptr->get_calc()->amo.size());
126  orbitals_ = nemo_ptr->R*nemo_ptr->get_calc()->amo;
127  R2orbitals_ = nemo_ptr->ncf->square()*nemo_ptr->get_calc()->amo;
128  }
129 
131 
132  value(x); // Ensures DFT equations are solved at this geometry
133  return nemo_ptr->gradient(x);
134  }
135 
136  double coord_chksum() const { return coords_sum; }
137 
138  const SCF& get_calc() const { return *nemo_ptr->get_calc(); }
139 
140  SCF& get_calc() { return *nemo_ptr->get_calc(); }
141 
142  /// return full orbital i, multiplied with the nuclear correlation factor
143 
144  /// note that nemo() and orbital() are the same if no nuclear
145  /// correlation factor is used
146  real_function_3d orbital(const int i) const {
147  MADNESS_ASSERT(nemo_ptr->get_param().spin_restricted());
148  return orbitals_[i];
149  }
150 
151  /// return full orbitals, multiplied with the nuclear correlation factor
152 
153  /// note that nemo() and orbital() are the same if no nuclear
154  /// correlation factor is used
155  std::vector<real_function_3d> orbitals() const {
156  MADNESS_ASSERT(nemo_ptr->get_param().spin_restricted());
157  return orbitals_;
158  }
159 
160  /// return orbitals, multiplied with the square nuclear correlation factor
161 
162  /// note that nemo() and orbital() are the same if no nuclear
163  /// correlation factor is used
164  std::vector<real_function_3d> R2orbitals() const {
165  MADNESS_ASSERT(nemo_ptr->get_param().spin_restricted());
166  return R2orbitals_;
167  }
168 
169  /// return orbital i, multiplied with the square nuclear correlation factor
170 
171  /// note that nemo() and orbital() are the same if no nuclear
172  /// correlation factor is used
173  real_function_3d R2orbital(const int i) const {
174  MADNESS_ASSERT(nemo_ptr->get_param().spin_restricted());
175  return R2orbitals_[i];
176  }
177 
178  /// return nemo i, which is the regularized orbital
179 
180  /// note that nemo() and orbital() are the same if no nuclear
181  /// correlation factor is used
182  real_function_3d nemo(const int i) const {
183  MADNESS_ASSERT(nemo_ptr->get_param().spin_restricted());
184  return nemo_ptr->get_calc()->amo[i];
185  }
186 
187  /// return nemo, which are the regularized orbitals
188 
189  /// note that nemo() and orbital() are the same if no nuclear
190  /// correlation factor is used
191  std::vector<real_function_3d> nemos() const {
192  MADNESS_ASSERT(nemo_ptr->get_param().spin_restricted());
193  return nemo_ptr->get_calc()->amo;
194  }
195 
196  /// return orbital energy i
197  double orbital_energy(const int i) const {
198  MADNESS_ASSERT(nemo_ptr->get_param().spin_restricted());
199  return nemo_ptr->get_calc()->aeps[i];
200  }
201 
202  /// return the Coulomb potential
204  MADNESS_ASSERT(nemo_ptr->get_param().spin_restricted());
205  if (coulomb.is_initialized()) return copy(coulomb);
206  functionT rho = 2.0*nemo_ptr->compute_density(nemos())*nemo_ptr->R_square;
207  coulomb = (nemo_ptr->get_calc()->make_coulomb_potential(rho)).truncate();
208  return copy(coulomb);
209  }
210 
211  /// return the nuclear potential
213  return nemo_ptr->get_calc()->potentialmanager->vnuclear();
214  }
215 
216  /// return the number of occupied orbitals
217  int nocc() const {
218  MADNESS_ASSERT(nemo_ptr->get_param().spin_restricted());
219  return nemo_ptr->get_param().nalpha();
220  }
221 };
222 
223 
224 /// enhanced POD for the pair functions
226 
227 public:
228  /// default ctor; initialize energies with a large number
229  ElectronPair() : ElectronPair(-1, -1) {}
230 
231  /// ctor; initialize energies with a large number
232  ElectronPair(const int i, const int j)
235  }
236 
237  /// print the pair's energy
238  void print_energy() const {
239  if (function.world().rank() == 0) {
240  printf("final correlation energy %2d %2d %12.8f %12.8f\n",
241  i, j, e_singlet, e_triplet);
242  }
243  }
244 
245  static double uninitialized() { return 1.e10; }
246 
247  int i, j; ///< orbitals i and j
248  real_function_6d function; ///< pair function for a specific pair w/o correlation factor part
249  real_function_6d constant_term; ///< the first order contribution to the MP1 wave function
250 
251  double e_singlet; ///< the energy of the singlet pair ij
252  double e_triplet; ///< the energy of the triplet pair ij
253 
254  double ij_gQf_ij; ///< <ij | g12 Q12 f12 | ij>
255  double ji_gQf_ij; ///< <ji | g12 Q12 f12 | ij>
256 
257  int iteration; ///< current iteration for restart
258  bool converged; ///< is the pair function converged
259 
260  /// serialize this ElectronPair
261 
262  /// store the function only if it has been initialized
263  /// load the function only if there is one
264  /// don't serialize recomputable intermediates r12phi, Uphi, KffKphi
265  template<typename Archive>
266  void serialize(Archive& ar) {
267  bool fexist = function.is_initialized();
268  bool cexist = constant_term.is_initialized();
270  & iteration & fexist & cexist;
271  if (fexist) ar & function;
272  if (cexist) ar & constant_term;
273  }
274 
275  bool load_pair(World& world) {
276  std::string name = "pair_" + stringify(i) + stringify(j);
278  if (exists) {
279  if (world.rank() == 0) printf("loading matrix elements %s", name.c_str());
281  ar & *this;
282  if (world.rank() == 0) printf(" %s\n", (converged) ? " converged" : " not converged");
283  if (function.is_initialized()) function.set_thresh(FunctionDefaults<6>::get_thresh());
285  } else {
286  if (world.rank() == 0) print("could not find pair ", i, j, " on disk");
287  }
288  return exists;
289  }
290 
291  void store_pair(World& world) {
292  std::string name = "pair_" + stringify(i) + stringify(j);
293  if (world.rank() == 0) printf("storing matrix elements %s\n", name.c_str());
295  ar & *this;
296  }
297 
298  // print information
299  void info(World& world) const {
300  if (world.rank() == 0) {
301  std::cout << std::setw(20) << std::setfill(' ') << " *Information about Electron Pair " << i << j << " "
302  << std::setw(20) << std::setfill(' ') << std::endl;
303  std::cout << std::setw(20) << std::setfill(' ') << " *e_singlet " << e_singlet << " " << std::setw(20)
304  << std::setfill(' ') << std::endl;
305  std::cout << std::setw(20) << std::setfill(' ') << " *e_triplet " << e_triplet << " " << std::setw(20)
306  << std::setfill(' ') << std::endl;
307  std::cout << std::setw(20) << std::setfill(' ') << " *ij_gQf_ij " << ij_gQf_ij << " " << std::setw(20)
308  << std::setfill(' ') << std::endl;
309  std::cout << std::setw(20) << std::setfill(' ') << " *ji_gQf_ij " << ji_gQf_ij << " " << std::setw(20)
310  << std::setfill(' ') << std::endl;
311  }
312  }
313 };
314 
315 
316 /// a class for computing the first order wave function and MP2 pair energies
318 
319  /// POD for MP2 keywords
321 
322  /// use OEP orbitals
323  bool do_oep1 = false;
324 
326  /// the map with initial values
327  initialize < double > ("thresh", 1.e-3, "recommended values: 1.e-4 < econv < 1.e-8");
328  initialize < double > ("econv", 1.e-3, "recommended values: 1.e-4 < econv < 1.e-8");
329  initialize < double > ("dconv", 1.e-3, "recommended values: 1.e-4 < econv < 1.e-8");
330  initialize < std::vector<int> > ("pair", {-1, -1});
331  initialize < int > ("freeze", 0);
332  initialize < int > ("maxsub", 2);
333  initialize < bool > ("restart", true);
334  initialize < bool > ("no_compute", false);
335  initialize < int > ("maxiter", 5);
336  }
337 
338  /// ctor reading out the input file
341 
342  // print final parameters
343  if (world.rank() == 0) print("mp2", "end");
344  }
345 
348 
349  set_derived_value("dconv", sqrt(get<double>("econv")) * 0.1);
350  set_derived_value("thresh",get<double>("econv"));
351  }
352 
353  /// check the user input
354  void check_input(const std::shared_ptr<HartreeFock> hf) const {
355  if (freeze() > hf->nocc()) MADNESS_EXCEPTION("you froze more orbitals than you have", 1);
356  if (i() >= hf->nocc()) MADNESS_EXCEPTION("there is no i-th orbital", 1);
357  if (j() >= hf->nocc()) MADNESS_EXCEPTION("there is no j-th orbital", 1);
358  if (thresh() < 0.0) MADNESS_EXCEPTION("please provide the accuracy threshold for MP2", 1);
359  }
360 
361  double thresh() const { return get<double>("thresh"); } /// convenience function
362  double econv() const { return get<double>("econv"); } /// convenience function
363  double dconv() const { return this->get<double>("dconv"); } /// convenience function
364  int freeze() const { return this->get<int>("freeze"); } /// convenience function
365  int i() const { return this->get<std::vector<int> >("pair")[0]; } /// convenience function
366  int j() const { return this->get<std::vector<int> >("pair")[1]; } /// convenience function
367  int restart() const { return this->get<bool>("restart"); } /// convenience function
368  int no_compute() const { return this->get<bool>("no_compute"); } /// convenience function
369  int maxiter() const { return this->get<int>("maxiter"); } /// convenience function
370  int maxsub() const { return this->get<int>("maxsub"); } /// convenience function
371  bool do_oep() const { return do_oep1;}
372  };
373 
374  /// POD holding all electron pairs with easy access
375  template<typename T>
376  struct Pairs {
377 
378  typedef std::map<std::pair<int, int>, T> pairmapT;
380 
381  /// getter
382  const T& operator()(int i, int j) const {
383  return allpairs.find(std::make_pair(i, j))->second;
384  }
385 
386  /// getter
387  T& operator()(int i, int j) {
388  return allpairs[std::make_pair(i, j)];
389  }
390 
391  /// setter
392  void insert(int i, int j, T pair) {
393  std::pair<int, int> key = std::make_pair(i, j);
394  allpairs.insert(std::make_pair(key, pair));
395  }
396  };
397 
398 
399  World& world; ///< the world
400  Parameters param; ///< SCF parameters for MP2
401  std::shared_ptr<HartreeFock> hf; ///< our reference
402  CorrelationFactor corrfac; ///< correlation factor: Slater
403  std::shared_ptr<NuclearCorrelationFactor> nuclear_corrfac;
404  mutable Tensor<double> fock; ///< the Fock matrix
405 
406  Pairs<ElectronPair> pairs; ///< pair functions and energies
407  double correlation_energy; ///< the correlation energy
408  double coords_sum; ///< check sum for the geometry
409 
411 
412 private:
413 
414  std::shared_ptr<real_convolution_3d> poisson;
415 
416 public:
417 
418  /// ctor
419  MP2(World& world, const commandlineparser& parser);
420  std::string name() const {return "MP2";};
421 
422  static void help() {
423  print_header2("help page for MP2 ");
424  print("The mp2 code computes second order correlation energies based on a moldft or nemo calculation");
425  print("You can print all available calculation parameters by running\n");
426  print("mp2 --print_parameters\n");
427  print("You can perform a simple calculation by running\n");
428  print("mp2 --geometry=h2o.xyz\n");
429  print("provided you have an xyz file in your directory.");
430 
431  }
432 
433  static void print_parameters() {
435  print("default parameters for the mp2 program are");
436  param.print("mp2", "end");
437  print("\n\nthe molecular geometry must be specified in a separate block:");
439  }
440  virtual bool selftest() {
441  return true;
442  };
443 
444  /// return a checksum for the geometry
445  double coord_chksum() const { return coords_sum; }
446 
447  /// return the molecular correlation energy energy (without the HF energy)
448  double value();
449 
450  /// return the molecular correlation energy as a function of the coordinates
451  double value(const Tensor<double>& x);
452 
453  /// make sure frozen orbitals don't couple with correlated ones -- relocalize if necessary
454  bool check_core_valence_separation() const;
455 
456  /// make sure frozen orbitals don't couple with correlated ones -- relocalize if necessary
458 
459  /// return the underlying HF reference
460  HartreeFock& get_hf() { return *hf; }
461 
462  /// return the 0th order energy of pair ij (= sum of orbital energies)
463  double zeroth_order_energy(const int i, const int j) const {
464  return hf->orbital_energy(i) + hf->orbital_energy(j);
465  }
466 
467  /// solve the residual equation for electron pair (i,j)
468 
469  /// \todo Parameter documentation. Below are un-doxygenated comments that no longer seem relevant?
470  // @param[in] pair electron pair to solve
471  // @param[in] econv energy convergence criterion (for a single pair)
472  // @param[in] dconv density convergence criterion (for a single pair)
474  ElectronPair tmp(0, 0);
475  tmp.function = copy(f);
476  tmp.constant_term = copy(f);
477  tmp.ij_gQf_ij = compute_gQf(0, 0, tmp);
478  tmp.ji_gQf_ij = tmp.ij_gQf_ij;
479  solve_residual_equations(tmp, 10.0, 10.0);
480  return tmp.function;
481  }
482 
484  const double econv, const double dconv) const;
485 
486  /// solve the coupled MP1 equations (e.g. for local orbitals)
487 
488  /// @param[in] pairs set of (coupled) electron pairs to solve
489  /// @param[in] econv energy convergence criterion (for all pairs)
490  /// @param[in] dconv density convergence criterion (for all pairs)
492  const double econv, const double dconv) const;
493 
494  /// compute increments: psi^1 = C + GV C + GVGV C + GVGVGV C + ..
495 
496  /// for pre-optimization of the mp1 wave function
497  /// no restart option here for now
498  /// param[inout] pair the electron pair
499  /// param[in] green the Green's function
500  void increment(ElectronPair& pair, real_convolution_6d& green);
501 
502  double asymmetry(const real_function_6d& f, const std::string s) const;
503 
504  /// compute the matrix element <ij | g12 Q12 f12 | phi^0>
505 
506  /// scales quartically. I think I can get this down to cubically by
507  /// setting Q12 = (1 - O1)(1 - O2) = 1- O1(1 - 0.5 O2) - O2 (1 - 0.5 O1)
508  /// as for the formulas cf the article mra_molecule
509  /// @return the energy <ij | g Q f | kl>
510  double compute_gQf_cc2interface(const int i, const int j, const real_function_6d& f) const {
511  ElectronPair tmp(0, 0);
512  tmp.function = copy(f);
513  tmp.constant_term = copy(f);
514  return compute_gQf(i, j, tmp);
515  }
516 
517  double compute_gQf(const int i, const int j, ElectronPair& pair) const;
518 
519  /// pretty print the options
520 
521  /// invoke only in (world.rank()==0) !!
522  template<typename T>
523  void print_options(const std::string option, const T val) const {
524  std::cout << std::setfill(' ') << std::setw(30);
525  std::cout << option << " " << val << std::endl;
526  }
527 
528  real_function_6d debug_cc2(const real_function_6d& f, const size_t& i, const size_t& j) const {
530  }
531 
532 public:
533 
534  /// save a function
535  template<typename T, size_t NDIM>
536  void save_function(const Function<T, NDIM>& f, const std::string name) const;
537 
538  /// load a function
539  template<typename T, size_t NDIM>
540  void load_function(Function<T, NDIM>& f, const std::string name) const;
541 
542 private:
543  /// return the function Uphi0; load from disk if available
545 
546  /// return the function [K,f] phi0; load from disk if available
548 
549 
550  /// compute some matrix elements that don't change during the SCF
551  ElectronPair make_pair(const int i, const int j) const;
552 
553  /// compute the first iteration of the residual equations and all intermediates
554  void guess_mp1_3(ElectronPair& pair) const;
555 
556 private:
557 
558  /// compute the singlet and triplet energy for a given electron pair
559 
560  /// @return the energy of 1 degenerate triplet and 1 singlet pair
561  double compute_energy(ElectronPair& pair) const;
562 
563  /// apply the exchange operator on an orbital
564 
565  /// @param[in] phi the orbital
566  /// @param[in] hc hermitian conjugate -> swap bra and ket space
567  /// @return Kphi
568  real_function_3d K(const real_function_3d& phi, const bool hc = false) const;
569 
570  /// apply the exchange operator on a pair function
571 
572  /// @param[in] phi the pair function
573  /// @param[in] is_symmetric is the function symmetric wrt particle exchange
574  /// @return (K1 + K2) |phi >
575  real_function_6d K(const real_function_6d& phi, const bool is_symmetric = false) const;
576 
577  /// apply the Coulomb operator a on orbital
578 
579  /// @param[in] phi the orbital
580  /// @return Jphi
582 
584 
585  /// apply the exchange operator on f
586 
587  /// if the exchange operator is similarity transformed (R-1 K R) the
588  /// orbital spaces differ for the orbitals underneath the integral sign
589  /// R-1 K R = \phi-ket(1) * \int \phi-bra(1') * f(1',2)
590  /// @param[in] f the pair function
591  /// @param[in] orbital_bra the orbital underneath the integral sign (typically R2orbitals)
592  /// @param[in] orbital_ket the orbital to be pre-multiplied with (typically orbitals)
593  /// @return the pair function, on which the exchange operator has been applied
595  const real_function_3d& orbital_ket,
596  const real_function_3d& orbital_bra, const int particle) const;
597 
598  /// make the quantity chi_k
599 
600  /// chi is the Poisson kernel applied on an orbital product of the
601  /// input function and the vector of orbitals
602  /// \f[ \chi_{k{*} i}(1) = \int dr_2 \frac{k(2) i(2)}{|r_1-r_2|} \f]
603  /// \f[ \chi_{ki{*}}(1) = \int dr_2 \frac{k(2) i(2)}{|r_1-r_2|} \f] if hc
604  /// @param[in] phi orbital phi_i
605  /// @param[in] op the operator in SeparatedConvolution form
606  /// @param[in] hc compute hermitian conjugate -> pass the correct phi!
607  /// @return a vector of length nocc
608  std::vector<real_function_3d> make_chi(const real_function_3d& phi,
609  const real_convolution_3d& op,
610  const bool hc = false) const;
611 
612  /// make the quantity xi_k
613 
614  /// xi is chi multiplied with an orbital j
615  /// \f[ \xi_{k{*}i,j}(1) = \chi_{ki}(1) j(1) \f]
616  /// \f[ \xi_{ki{*},j{*}}(1) = \chi_{k{*}i}(1) j(1) \f] if hc
617  /// @param[in] phi_i orbital i
618  /// @param[in] phi_j orbital j
619  /// @param[in] op the operator in SeparatedConvolution form
620  /// @param[in] hc compute hermitian conjugate -> pass the correct phi!
621  /// @return a vector of length k=0,..,nocc
622  std::vector<real_function_3d> make_xi(const real_function_3d& phi_i,
623  const real_function_3d& phi_j, const real_convolution_3d& op,
624  const bool hc = false) const;
625 
626  /// apply the operator K on the reference and multiply with f; fK |phi^0>
627 
628  /// @param[in] i index of orbital i
629  /// @param[in] j index of orbital j
630  /// @return the function f12 (K(1)+K(2))|phi^0>
631  real_function_6d make_fKphi0(const int i, const int j) const;
632 
633  /// return the function (J(1)-K(1)) |phi0> as on-demand function
634 
635  /// @param[in] hc compute hermitian conjugate -> swap bra and ket space
636  real_function_6d JK1phi0_on_demand(const int i, const int j,
637  const bool hc = false) const;
638 
639  /// return the function (J(2)-K(2)) |phi0> as on-demand function
640  real_function_6d JK2phi0_on_demand(const int i, const int j,
641  const bool hc = false) const;
642 
643  /// return the function |phi0> as on-demand function
644  real_function_6d phi0_on_demand(const int i, const int j) const;
645 
646  /// return the function |F1F2> as on-demand function
647  real_function_6d nemo0_on_demand(const int i, const int j) const;
648 
649 
650  /// multiply the given function with the 0th order Hamiltonian, exluding the 0th order energy
651 
652  /// @param[in] f the function we apply H^0 on
653  /// @return the function g=H^0 f, which is NOT orthogonalized against f
655  const int i, const int j) const;
656 
657  // need this for CC2 debug
658 public:
660  const int i, const int j) {
661  hf->value(); // make sure the reference is converged
662  nuclear_corrfac = hf->nemo_ptr->ncf;
663  // set all orbitals spaces
664  // When a nuclear correlation factor is used the residual equations
665  // are similarity transformed. Therefore the orbitals in the
666  // projection operator must be set accordingly.
668  Q12.set_spaces(hf->get_calc().amo);
669  } else {
670  // only valid for closed shell
671  MADNESS_ASSERT(hf->get_calc().param.spin_restricted());
672  const std::vector<real_function_3d>& nemos = hf->nemos();
673  const std::vector<real_function_3d>& R2amo = hf->R2orbitals();
674  Q12.set_spaces(R2amo, nemos, R2amo, nemos);
675  if (world.rank() == 0) {
676  print("set orbital spaces for the SO projector");
677  print("Q12,R = (1-|nemo><nemo|R2) (1-|nemo><nemo|R2)");
678  }
679  }
680 
682  }
683 
684 private:
685  // compute some intermediates
687  if (fock.has_data()) return copy(fock);
688  const tensorT occ = hf->get_calc().aocc;
689  fock = hf->nemo_ptr->compute_fock_matrix(hf->nemos(), occ);
690  if (world.rank() == 0 and hf->nocc() < 10) {
691  print("The Fock matrix");
692  print(fock);
693  }
694  return copy(fock);
695  }
696 
697 
698 
699  /// add the coupling terms for local MP2
700 
701  /// \sum_{k\neq i} f_ki |u_kj> + \sum_{l\neq j} f_lj |u_il>
702  /// @todo Verify this doxygen block.
704 
705  mutable double ttt, sss;
706 
707  void START_TIMER(World& world) const {
708  world.gop.fence();
709  ttt = wall_time();
710  sss = cpu_time();
711  }
712 
713  void END_TIMER(World& world, const char *msg) const {
714  ttt = wall_time() - ttt;
715  sss = cpu_time() - sss;
716  if (world.rank() == 0) printf("timer: %20.20s %8.2fs %8.2fs\n", msg, sss, ttt);
717  }
718 
719 };
720 };
721 
722 #endif /* MP2_H_ */
723 
enhanced POD for the pair functions
Definition: mp2.h:225
void print_energy() const
print the pair's energy
Definition: mp2.h:238
double ij_gQf_ij
<ij | g12 Q12 f12 | ij>
Definition: mp2.h:254
ElectronPair(const int i, const int j)
ctor; initialize energies with a large number
Definition: mp2.h:232
double ji_gQf_ij
<ji | g12 Q12 f12 | ij>
Definition: mp2.h:255
void store_pair(World &world)
Definition: mp2.h:291
bool converged
is the pair function converged
Definition: mp2.h:258
void serialize(Archive &ar)
serialize this ElectronPair
Definition: mp2.h:266
ElectronPair()
default ctor; initialize energies with a large number
Definition: mp2.h:229
double e_singlet
the energy of the singlet pair ij
Definition: mp2.h:251
bool load_pair(World &world)
Definition: mp2.h:275
double e_triplet
the energy of the triplet pair ij
Definition: mp2.h:252
int j
orbitals i and j
Definition: mp2.h:247
int iteration
current iteration for restart
Definition: mp2.h:257
int i
Definition: mp2.h:247
real_function_6d function
pair function for a specific pair w/o correlation factor part
Definition: mp2.h:248
static double uninitialized()
Definition: mp2.h:245
real_function_6d constant_term
the first order contribution to the MP1 wave function
Definition: mp2.h:249
void info(World &world) const
Definition: mp2.h:299
FunctionDefaults holds default paramaters as static class members.
Definition: funcdefaults.h:204
FunctionNode holds the coefficients, etc., at each node of the 2^NDIM-tree.
Definition: funcimpl.h:124
coeffT & coeff()
Returns a non-const reference to the tensor containing the coeffs.
Definition: funcimpl.h:223
void set_thresh(double value, bool fence=true)
Sets the value of the truncation threshold. Optional global fence.
Definition: mra.h:577
bool is_initialized() const
Returns true if the function is initialized.
Definition: mra.h:147
long size() const
Definition: lowranktensor.h:482
Definition: hartreefock.h:138
real_function_3d R2orbital(const int i) const
return orbital i, multiplied with the square nuclear correlation factor
Definition: mp2.h:173
bool provides_gradient() const
Definition: mp2.h:101
Tensor< double > gradient(const Tensor< double > &x)
Definition: mp2.h:130
double value()
Definition: mp2.h:103
double value(const Tensor< double > &x)
Definition: mp2.h:107
std::vector< real_function_3d > orbitals_
reconstructed orbitals: R * phi, where R is the nuclear correlation factor
Definition: mp2.h:87
std::vector< real_function_3d > R2orbitals_
Definition: mp2.h:91
real_function_3d nemo(const int i) const
return nemo i, which is the regularized orbital
Definition: mp2.h:182
std::shared_ptr< Nemo > nemo_ptr
Definition: mp2.h:79
int nocc() const
return the number of occupied orbitals
Definition: mp2.h:217
SCF & get_calc()
Definition: mp2.h:140
World & world
Definition: mp2.h:77
HartreeFock(World &world, std::shared_ptr< Nemo > nemo)
Definition: mp2.h:95
const SCF & get_calc() const
Definition: mp2.h:138
real_function_3d coulomb
Definition: mp2.h:84
std::vector< real_function_3d > R2orbitals() const
return orbitals, multiplied with the square nuclear correlation factor
Definition: mp2.h:164
World & get_world()
Definition: mp2.h:99
double orbital_energy(const int i) const
return orbital energy i
Definition: mp2.h:197
double coord_chksum() const
Definition: mp2.h:136
void reset_orbitals(const MolecularOrbitals< double, 3 > &mos)
Definition: mp2.h:122
double coords_sum
Definition: mp2.h:81
real_function_3d orbital(const int i) const
return full orbital i, multiplied with the nuclear correlation factor
Definition: mp2.h:146
real_function_3d get_coulomb_potential() const
return the Coulomb potential
Definition: mp2.h:203
std::vector< real_function_3d > orbitals() const
return full orbitals, multiplied with the nuclear correlation factor
Definition: mp2.h:155
std::vector< real_function_3d > nemos() const
return nemo, which are the regularized orbitals
Definition: mp2.h:191
real_function_3d get_nuclear_potential() const
return the nuclear potential
Definition: mp2.h:212
Key is the index for a node of the 2^NDIM-tree.
Definition: key.h:66
a class for computing the first order wave function and MP2 pair energies
Definition: mp2.h:317
double asymmetry(const real_function_6d &f, const std::string s) const
Definition: madness/chem/mp2.cc:490
CorrelationFactor corrfac
correlation factor: Slater
Definition: mp2.h:402
ElectronPair make_pair(const int i, const int j) const
compute some matrix elements that don't change during the SCF
bool check_core_valence_separation() const
make sure frozen orbitals don't couple with correlated ones – relocalize if necessary
Definition: madness/chem/mp2.cc:140
Tensor< double > fock
the Fock matrix
Definition: mp2.h:404
std::vector< real_function_3d > make_chi(const real_function_3d &phi, const real_convolution_3d &op, const bool hc=false) const
make the quantity chi_k
void END_TIMER(World &world, const char *msg) const
Definition: mp2.h:713
real_function_6d JK2phi0_on_demand(const int i, const int j, const bool hc=false) const
return the function (J(2)-K(2)) |phi0> as on-demand function
real_function_6d apply_exchange(const real_function_6d &f, const real_function_3d &orbital_ket, const real_function_3d &orbital_bra, const int particle) const
apply the exchange operator on f
real_function_6d get_residue(const real_function_6d &f, const int i, const int j)
Definition: mp2.h:659
virtual bool selftest()
Definition: mp2.h:440
Parameters param
SCF parameters for MP2.
Definition: mp2.h:400
double value()
return the molecular correlation energy energy (without the HF energy)
Definition: madness/chem/mp2.cc:134
double coord_chksum() const
return a checksum for the geometry
Definition: mp2.h:445
real_function_6d phi0_on_demand(const int i, const int j) const
return the function |phi0> as on-demand function
std::string name() const
Definition: mp2.h:420
real_function_6d make_Uphi0(ElectronPair &pair) const
return the function Uphi0; load from disk if available
Definition: madness/chem/mp2.cc:640
double solve_coupled_equations(Pairs< ElectronPair > &pairs, const double econv, const double dconv) const
solve the coupled MP1 equations (e.g. for local orbitals)
Definition: madness/chem/mp2.cc:366
double coords_sum
check sum for the geometry
Definition: mp2.h:408
double compute_energy(ElectronPair &pair) const
compute the singlet and triplet energy for a given electron pair
std::shared_ptr< HartreeFock > hf
our reference
Definition: mp2.h:401
real_function_6d make_fKphi0(const int i, const int j) const
apply the operator K on the reference and multiply with f; fK |phi^0>
MP2(World &world, const commandlineparser &parser)
ctor
Definition: madness/chem/mp2.cc:80
void add_local_coupling(const Pairs< ElectronPair > &pairs, Pairs< real_function_6d > &coupling) const
add the coupling terms for local MP2
void guess_mp1_3(ElectronPair &pair) const
compute the first iteration of the residual equations and all intermediates
World & world
the world
Definition: mp2.h:399
std::vector< real_function_3d > make_xi(const real_function_3d &phi_i, const real_function_3d &phi_j, const real_convolution_3d &op, const bool hc=false) const
make the quantity xi_k
real_function_6d nemo0_on_demand(const int i, const int j) const
return the function |F1F2> as on-demand function
Pairs< ElectronPair > pairs
pair functions and energies
Definition: mp2.h:406
real_function_6d K(const real_function_6d &phi, const bool is_symmetric=false) const
apply the exchange operator on a pair function
double ttt
Definition: mp2.h:705
void enforce_core_valence_separation()
make sure frozen orbitals don't couple with correlated ones – relocalize if necessary
Definition: madness/chem/mp2.cc:171
StrongOrthogonalityProjector< double, 3 > Q12
Definition: mp2.h:410
void save_function(const Function< T, NDIM > &f, const std::string name) const
save a function
Definition: madness/chem/mp2.cc:620
real_function_6d make_KffKphi0(const ElectronPair &pair) const
return the function [K,f] phi0; load from disk if available
std::shared_ptr< real_convolution_3d > poisson
Definition: mp2.h:414
void print_options(const std::string option, const T val) const
pretty print the options
Definition: mp2.h:523
double compute_gQf_cc2interface(const int i, const int j, const real_function_6d &f) const
compute the matrix element <ij | g12 Q12 f12 | phi^0>
Definition: mp2.h:510
std::shared_ptr< NuclearCorrelationFactor > nuclear_corrfac
Definition: mp2.h:403
static void help()
Definition: mp2.h:422
void load_function(Function< T, NDIM > &f, const std::string name) const
load a function
Definition: madness/chem/mp2.cc:631
Tensor< double > get_fock_matrix() const
Definition: mp2.h:686
real_function_6d multiply_with_0th_order_Hamiltonian(const real_function_6d &f, const int i, const int j) const
multiply the given function with the 0th order Hamiltonian, exluding the 0th order energy
double compute_gQf(const int i, const int j, ElectronPair &pair) const
compute the matrix element <ij | g12 Q12 f12 | phi^0>
Definition: madness/chem/mp2.cc:506
static void print_parameters()
Definition: mp2.h:433
double correlation_energy
the correlation energy
Definition: mp2.h:407
real_function_6d JK1phi0_on_demand(const int i, const int j, const bool hc=false) const
return the function (J(1)-K(1)) |phi0> as on-demand function
void solve_residual_equations(ElectronPair &pair, const double econv, const double dconv) const
solve the residual equation for electron pair (i,j)
Definition: madness/chem/mp2.cc:273
double zeroth_order_energy(const int i, const int j) const
return the 0th order energy of pair ij (= sum of orbital energies)
Definition: mp2.h:463
real_function_6d iterate(const real_function_6d &f) const
solve the residual equation for electron pair (i,j)
Definition: mp2.h:473
real_function_6d apply_exchange_vector(const real_function_6d &f, const int particle) const
HartreeFock & get_hf()
return the underlying HF reference
Definition: mp2.h:460
real_function_3d K(const real_function_3d &phi, const bool hc=false) const
apply the exchange operator on an orbital
void increment(ElectronPair &pair, real_convolution_6d &green)
compute increments: psi^1 = C + GV C + GVGV C + GVGVGV C + ..
Definition: madness/chem/mp2.cc:453
double sss
Definition: mp2.h:705
void START_TIMER(World &world) const
Definition: mp2.h:707
real_function_3d J(const real_function_3d &phi) const
apply the Coulomb operator a on orbital
real_function_6d debug_cc2(const real_function_6d &f, const size_t &i, const size_t &j) const
Definition: mp2.h:528
Definition: MolecularOrbitals.h:24
std::vector< Function< T, NDIM > > get_mos() const
Definition: MolecularOrbitals.h:64
Tensor< double > get_eps() const
Definition: MolecularOrbitals.h:68
static void print_parameters()
Definition: molecule.cc:110
@ None
Definition: correlationfactor.h:85
class for holding the parameters for calculation
Definition: QCCalculationParametersBase.h:290
virtual void read_input_and_commandline_options(World &world, const commandlineparser &parser, const std::string tag)
Definition: QCCalculationParametersBase.h:325
void print(const std::string header="", const std::string footer="") const
print all parameters
Definition: QCCalculationParametersBase.cc:22
void set_derived_value(const std::string &key, const T &value)
Definition: QCCalculationParametersBase.h:403
class implementing properties of QC models
Definition: QCPropertyInterface.h:11
Definition: SCF.h:187
Convolutions in separated form (including Gaussian)
Definition: operator.h:136
void set_spaces(const vecfuncT &p)
set the same spaces for the projectors for particle 1 and 2
Definition: projector.h:281
Tensor< T > reshape(int ndimnew, const long *d)
Returns new view/tensor reshaping size/number of dimensions to conforming tensor.
Definition: tensor.h:1384
T sumsq() const
Returns the sum of the squares of the elements.
Definition: tensor.h:1669
bool has_data() const
Definition: tensor.h:1886
void fence(bool debug=false)
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition: worldgop.cc:161
A parallel world class.
Definition: world.h:132
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition: world.h:318
WorldGopInterface & gop
Global operations.
Definition: world.h:205
static std::enable_if_t< std::is_same< X, BinaryFstreamInputArchive >::value||std::is_same< X, BinaryFstreamOutputArchive >::value, bool > exists(World &world, const char *filename)
Returns true if the named, unopened archive exists on disk with read access.
Definition: parallel_archive.h:224
An archive for storing local or parallel data, wrapping a BinaryFstreamInputArchive.
Definition: parallel_archive.h:366
An archive for storing local or parallel data wrapping a BinaryFstreamOutputArchive.
Definition: parallel_archive.h:321
Objects that implement their own parallel archive interface should derive from this class.
Definition: parallel_archive.h:58
Wraps an archive around a text filestream for input.
Definition: text_fstream_archive.h:148
Wraps an archive around a text filestream for output.
Definition: text_fstream_archive.h:54
auto T(World &world, response_space &f) -> response_space
Definition: global_functions.cc:34
Tensor< double > op(const Tensor< double > &x)
Definition: kain.cc:508
Implements (2nd generation) static load/data balancing for functions.
#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:190
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition: madness_exception.h:119
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition: madness_exception.h:134
Main include file for MADNESS and defines Function interface.
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
static std::string stringify(T arg)
Definition: funcplot.h:1034
void print_header2(const std::string &s)
medium section heading
Definition: print.cc:54
static double cpu_time()
Returns the cpu time in seconds relative to an arbitrary origin.
Definition: timers.h:127
void truncate(World &world, response_space &v, double tol, bool fence)
Definition: basic_operators.cc:30
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:2002
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:225
NDIM & f
Definition: mra.h:2416
double wall_time()
Returns the wall time in seconds relative to an arbitrary origin.
Definition: timers.cc:48
std::string name(const FuncType &type, const int ex=-1)
Definition: ccpairfunction.h:28
Implementation of Krylov-subspace nonlinear equation solver.
Definition: mp2.h:63
double leaf_value
Definition: mp2.h:64
double operator()(const Key< 6 > &key, const FunctionNode< double, 6 > &node) const
Definition: mp2.h:70
LBCost(double leaf_value=1.0, double parent_value=1.0)
Definition: mp2.h:67
double parent_value
Definition: mp2.h:65
POD holding all electron pairs with easy access.
Definition: mp2.h:376
std::map< std::pair< int, int >, T > pairmapT
Definition: mp2.h:378
pairmapT allpairs
Definition: mp2.h:379
const T & operator()(int i, int j) const
getter
Definition: mp2.h:382
T & operator()(int i, int j)
getter
Definition: mp2.h:387
void insert(int i, int j, T pair)
setter
Definition: mp2.h:392
POD for MP2 keywords.
Definition: mp2.h:320
bool do_oep1
use OEP orbitals
Definition: mp2.h:323
int i() const
convenience function
Definition: mp2.h:365
Parameters()
Definition: mp2.h:325
int restart() const
convenience function
Definition: mp2.h:367
double dconv() const
convenience function
Definition: mp2.h:363
int maxsub() const
convenience function
Definition: mp2.h:370
int freeze() const
convenience function
Definition: mp2.h:364
int maxiter() const
convenience function
Definition: mp2.h:369
bool do_oep() const
convenience function
Definition: mp2.h:371
void read_and_set_derived_values(World &world, const commandlineparser &parser)
Definition: mp2.h:346
Parameters(World &world, const commandlineparser &parser)
ctor reading out the input file
Definition: mp2.h:339
int j() const
convenience function
Definition: mp2.h:366
double thresh() const
Definition: mp2.h:361
double econv() const
convenience function
Definition: mp2.h:362
int no_compute() const
convenience function
Definition: mp2.h:368
void check_input(const std::shared_ptr< HartreeFock > hf) const
check the user input
Definition: mp2.h:354
The interface to be provided by functions to be optimized.
Definition: solvers.h:176
Definition: CCStructures.h:421
very simple command line parser
Definition: commandlineparser.h:15
Definition: lowrankfunction.h:332
Implements an archive wrapping text filestream.