MADNESS  version 0.9
TDA.h
Go to the documentation of this file.
1 /*
2  * TDA.h
3  *
4  * Created on: Jul 14, 2014
5  * Author: kottmanj
6  */
7 
8 #ifndef TDA_H_
9 #define TDA_H_
10 
11 //#include<examples/dft_solver.h>
12 #include <chem/projector.h>
13 //#include<examples/nonlinsol.h> not used anymore
14 #include<chem/SCF.h>
15 #include <madness/mra/operator.h>
16 #include <madness/mra/mra.h>
17 #include <madness/mra/vmra.h>
18 #include <madness/mra/lbdeux.h>
19 #include <madness/misc/ran.h>
20 #include <chem/TDA_XC.h>
21 
22 #include <chem/TDA_exops.h>
23 
24 // Kain solver
25 #include<examples/nonlinsol.h>
26 
27 // std::sort
28 #include <algorithm>
29 
30 namespace madness {
31 
32 typedef std::vector<Function<double,3> > vecfuncT;
33 typedef SeparatedConvolution<double,3> operatorT;
36 
38 struct TDA_TIMER{
42  TDA_TIMER(World &world,std::string msg) : world(world),start_wall(wall_time()),start_cpu(cpu_time()),operation(msg){}
44  const double start_wall;
45  const double start_cpu;
47  double end_wall;
48  double end_cpu;
49  void update_time(){
50  end_wall = wall_time()-start_wall;
51  end_cpu = cpu_time()-start_cpu;
52  }
53 public:
55  void info(bool debug = true){
56  if(debug==true){
57  update_time();
58  if(world.rank()==0) std::cout<< std::setw(40) << operation << " : " << std::scientific << std::setprecision(1)
59  << end_wall << " (wall) "<< end_cpu << " (cpu)" << std::endl;
60  }
61  }
62 
63 };
64 
66 struct xfunction{
69  xfunction(World &world) :world(world),omega(0.00001),converged(false),number(100),iterations(0),kain(false),f_length(999),f_velocity(999) {}
73  xfunction(World& world, const vecfuncT& x1) : world(world), x(x1),omega(0.00001),converged(false),number(100),iterations(0),kain(true),f_length(999),f_velocity(999) {}
75  xfunction(const xfunction &other) : world(other.world),x(other.x),Vx(other.Vx),omega(other.omega),expectation_value(other.expectation_value),error(other.error),
76  delta(other.delta),converged(other.converged),number(other.number),iterations(other.iterations),kain(other.kain),f_length(other.f_length),f_velocity(other.f_velocity){}
77 
80  vecfuncT x;
82  vecfuncT Vx;
84  double omega;
86  std::vector<double> expectation_value;
88  std::vector<double> error;
90  std::vector<double> delta;
92  bool converged;
94  size_t number;
96  size_t iterations;
98  bool kain;
101 
104  double f_length;
105  double f_velocity;
106 
108  xfunction& operator=(const xfunction &other){
109  x=other.x;
110  Vx=other.Vx;
111  omega = other.omega;
112  expectation_value = other.expectation_value;
113  error=other.error;
114  delta=other.delta;
115  converged=other.converged;
116  number=other.number;
117  iterations=other.iterations;
118  kain=other.kain;
119  f_length = other.f_length;
120  f_velocity = other.f_velocity;
121 
122  return *this;
123  }
124 
125  // Operators needed by the KAIN solver
127  x=sub(world,x,b.x);
128  return *this;
129  }
130 
132  return xfunction(world,sub(world,x,b.x));
133  }
134 
135  xfunction operator+=(const xfunction& b) { // Operator+= necessary
136  x=add(world,x,b.x);
137  return *this;
138  }
139 
140  xfunction operator*(double a) const { // Scale by a constant necessary
141 
142  PROFILE_BLOCK(Vscale);
143  xfunction result(*this);
144  for (unsigned int i=0; i<x.size(); ++i) {
145  result.x[i]=mul(a,x[i],false);
146  }
147  world.gop.fence();
148 
149  // scale(world, x, a);
150  return result;
151  }
152 
153  // finally an operator that the result can be sorted after the energy
154  // sorting of xfunctions should not happen during the iterations
155  // therefore a warning is installed
156  bool operator<=(const xfunction &b)const{return omega<=b.omega;std::cout << "WARNING XFUNCTIONS ARE SORTED" << std::endl;}
157  bool operator< (const xfunction &b)const{return omega<b.omega; std::cout << "WARNING XFUNCTIONS ARE SORTED" << std::endl;}
158 
159 
160 
161 };
162 
163 struct allocator{
164  World& world;
165  const int noct;
166 
169  allocator(World& world, const int nnoct) : world(world), noct(nnoct) {}
170 
172  return xfunction(world,zero_functions<double,3>(world,noct));
173  }
175  allocator tmp(world,other.noct);
176  return tmp;
177  }
178 };
179 
181 static double inner(const xfunction &a, const xfunction &b) {
182  if (a.x.size()!=b.x.size()) MADNESS_EXCEPTION("ERROR :Inner product of two xfunction structures: Different sizes in x-vectors",1);
183  if (a.x.size()==0) return 0.0;
184  return madness::inner(a.x[0].world(),a.x,b.x).sum();
185 }
186 
187 // TYPEDEFS
188 typedef std::vector<xfunction> xfunctionsT;
190 
194 private:
196  size_t noct;
198  bool is_used;
200  std::vector<solverT> solver;
201 public:
202 
205  void sanity_check(const xfunctionsT &xfunctions)const{
206  if(xfunctions.size()!=solver.size()){
207  std::cout << "KAIN SOLVER SANITY CHECK FAILED: Unequal sizes " << xfunctions.size() << " xfunctions and " << solver.size() << " solvers" << std::endl;
208  MADNESS_EXCEPTION("Error in kain solver helper struct",1);
209  }
210  if(xfunctions[0].x.size()!=noct){
211  MADNESS_EXCEPTION("Error in kain solver helper struct, unequal sizes in occupied orbitals (check freeze_ keyword)",1);
212  }
213  }
214 
222  void initialize(World &world,const size_t excitations,const size_t nnoct,const bool kain){
223  noct=nnoct;
224  is_used = kain;
225  if(kain){
226  for(size_t i=0;i<excitations; i++){
227  solverT onesolver(allocator(world,noct));
228  onesolver.set_maxsub(3);
229  solver.push_back(onesolver);
230  }
231  }
232  }
235  void update(xfunctionsT &xfunctions){
236  if(not is_used) MADNESS_EXCEPTION("Kain update was requested, but kain should not be used",1);
237  if(is_used){
238  for(size_t k=0;k<xfunctions.size();k++){
239  // we need ot push this back if we update or not, because of the subspace transformation
240  xfunction tmp = solver[k].update(xfunction(xfunctions[k].world,xfunctions[k].x),xfunction(xfunctions[k].world,xfunctions[k].current_residuals));
241  if(xfunctions[k].kain){
242  xfunctions[k].x = tmp.x;
243  }else{
244  std::cout << "(convergence too low) forcing full step for " << k << std::endl;
245  xfunctions[k].x = sub(xfunctions[k].world,xfunctions[k].x,xfunctions[k].current_residuals);
246  }
247  }
248  }
249  }
253  void transform_subspace(World &world,const madness::Tensor<double> U){
254  if(solver[0].get_ulist().empty()){ std::cout<<"kain: empty ulist, no transformation in "; return;}
255  if(solver[0].get_rlist().empty()){ std::cout<<"kain: empty rlist, no transformation in "; return;}
256  for(int k=0;k<solver[0].get_ulist().size();k++){
257  std::vector<vecfuncT> all_x;
258  std::vector<vecfuncT> all_r;
259  for(size_t i=0;i<solver.size();i++){
260  all_x.push_back(solver[i].get_ulist()[k].x);
261  all_r.push_back(solver[i].get_rlist()[k].x);
262  }
263  std::vector<vecfuncT> new_x = transform_vecfunctions(world,all_x,U);
264  std::vector<vecfuncT> new_r = transform_vecfunctions(world,all_r,U);
265  for(size_t i=0;i<solver.size();i++){
266  solver[i].get_ulist()[k].x = new_x[i];
267  solver[i].get_rlist()[k].x = new_r[i];
268  }
269  }
270  }
274  void reduce_subspace(const size_t i){
275  solver.erase(solver.begin()+i);
276  }
280  void erase_subspace(const size_t i){
281  if(solver.size()<i) MADNESS_EXCEPTION("Tried to delete subspace of nonexisting solver",1);
282  solver[i].get_ulist().clear();
283  solver[i].get_rlist().clear();
284  }
289  void increase_subspace(World &world,const xfunctionsT &xfunctions){
290  // if the subspace is increased (means more solvers are added) the subspaces of the existing solvers must be erased
291  // else there will be problems with the next subspace transformation
292  // the simplest solution is to add cimpletely new solvers for all xfunctions
293 
294  // clean up: erase all old solvers
295  solver.clear();
296  // add new solvers
297  solverT onesolver(allocator(world,noct));
298  onesolver.set_maxsub(3);
299  for(size_t j=0;j<xfunctions.size();j++){
300  solver.push_back(onesolver);
301  }
302  sanity_check(xfunctions);
303  }
309  std::vector<vecfuncT> transform_vecfunctions(World &world,const std::vector<vecfuncT> &xfunctions,const madness::Tensor<double> U)const{
310 
311  std::vector<vecfuncT> new_xfunctions(xfunctions.size());
312  for (std::size_t i = 0; i < xfunctions.size(); i++) {
313  new_xfunctions[i] = zero_functions<double, 3>(world,
314  xfunctions[i].size());
315  compress(world, new_xfunctions[i]);
316  compress(world, xfunctions[i]);
317  }
318 
319  for (size_t i = 0; i < xfunctions.size(); i++) {
320  for (size_t j = 0; j < xfunctions.size(); ++j) {
321  gaxpy(world, 1.0, new_xfunctions[i], U(j, i), xfunctions[j]);
322  }
323  }
324 
325  // Return the transformed vector of vecfunctions
326  return new_xfunctions;
327 
328  }
329 };
330 
332 struct diffuse_functions : public FunctionFunctorInterface<double,3> {
333 public:
341  diffuse_functions(const double L,const std::vector<coord_3d> coord,const std::vector<int> signs, const size_t natoms, const size_t mode):
342  L(L), coord(coord), signs(signs),natoms(natoms),mode(mode)
343 {if(mode>1) MADNESS_EXCEPTION("mode in diffuse_function struct is not 0,1 or 2",1);}
344 
346  double operator()(const coord_3d &r)const{
347  std::vector<double> diffuse_1s_functions;
348  double exponent =1.0;
349  if(mode==0) exponent = 15.0;
350  if(mode==1) exponent = 20.0;
351  for(size_t i=0;i<natoms;i++){
352  if (signs[i]!=0){
353  // make diffuse 1s functions localized at the atoms
354  double x = r[0]-coord[i][0];
355  double y = r[1]-coord[i][0];
356  double z = r[2]-coord[i][0];
357  double rad = sqrt(x*x+y*y+z*z);
358  double diffuse_tmp = signs[i]*exp(-exponent/L*rad);
359  diffuse_1s_functions.push_back(diffuse_tmp);
360  }else diffuse_1s_functions.push_back(0.0);
361  }
362  double result=0;
363  for(size_t i=0;i<diffuse_1s_functions.size();i++) result+=diffuse_1s_functions[i];
364  return result;
365  }
366 
367 private:
369  const double L;
371  const std::vector<coord_3d> coord;
373  const std::vector<int> signs;
375  const size_t natoms;
377  const size_t mode;
379  double diffuse_2s (const coord_3d &r)const{return r_function(r)*exp(-10.0/L*r_function(r));}
380  double diffuse_2px(const coord_3d &r)const{return r[0]*exp(-10.0/L*r_function(r));}
381  double diffuse_2py(const coord_3d &r)const{return r[1]*exp(-10.0/L*r_function(r));}
382  double diffuse_2pz(const coord_3d &r)const{return r[2]*exp(-10.0/L*r_function(r));}
383  double diffuse_1s (const coord_3d &r)const{return exp(-10.0/L*r_function(r));}
385  double r_function(const coord_3d &r)const{return sqrt(r[0]*r[0]+r[1]*r[1]+r[2]*r[2]);}
386 
387 };
388 
389 
390 
392 class TDA {
393 public:
400  TDA(World &world,const SCF &calc,const vecfuncT &mos,const std::string input):
401  world(world),
402  dft_(false),
403  calc_(calc),
404  mos_(mos),
405  print_grid_(false),
406  guess_("physical"),
407  guess_iter_(15),
408  guess_mode_("physical"),
409  guess_exop_("quadrupole"),
410  guess_excitations_(6),
411  excitations_(4),
412  bsh_eps_(1.e-5),
413  iter_max_(100),
414  econv_(1.e-4),
415  dconv_(1.e-3),
416  hard_dconv_(1.e-3),
417  hard_econv_(5.e-5),
418  nfreeze_(0),
419  plot_(false),
420  debug_(false),
421  only_fock_(false),
422  only_GS_(false),
423  on_the_fly_(true),
424  read_(false),
425  only_sequential_(false),
426  xclib_interface_(world,calc),
427  ipot_(0.0),
428  rydberg_(false),
429  kain_(false),
430  kain_subspace_(3),
431  shift_(0.0),
432  safety_(1.0)
433 {
434  setup(mos,input);
435 }
437  void setup(const vecfuncT &mos,const std::string input){
438 
439 
440  // so that the thresh can be changed from the outside
441  mos_ = mos;
442 
443  size_t noct = calc_.aeps.size();
444  // The highest possible excitation (-homo_energy)
445  double highest_excitation_default = -calc_.aeps(noct-1);
446  highest_excitation_ = highest_excitation_default;
447  ipot_ = -calc_.aeps(noct-1)*2.0;
448 
449 
450  // The guessed lowest excitation (if no guess_omega_ is in the input)
451  double guess_omega_default = -0.1*calc_.aeps[noct-1];
452  guess_omega_ = guess_omega_default;
453 
454  std::ifstream f(input.c_str());
455  position_stream(f, "TDA");
456  std::string s, tag;
457  while (std::getline(f,s)) {
458  std::istringstream ss(s);
459  ss >> tag;
460  if (tag == "end") break;
461  else if (tag == "dft") dft_=true;
462  else if (tag == "excitations") ss >> excitations_;
463  else if (tag == "guess") ss >> guess_;
464  else if (tag == "hard_dconv") ss >> hard_dconv_;
465  else if (tag == "hard_econv") ss >> hard_econv_;
466  else if (tag == "guess_iter") ss >> guess_iter_;
467  else if (tag == "guess_omega") ss >> guess_omega_;
468  else if (tag == "guess_mode") ss >> guess_mode_;
469  else if (tag == "guess_exop") ss >> guess_exop_;
470  else if (tag == "guess_excitations") ss >> guess_excitations_;
471  else if (tag == "bsh_eps") ss >> bsh_eps_;
472  else if (tag == "iter_max") ss >> iter_max_;
473  else if (tag == "econv") ss >> econv_;
474  else if (tag == "dconv") ss >> dconv_;
475  else if (tag == "freeze") ss >> nfreeze_;
476  else if (tag == "print_grid") print_grid_=true;
477  else if (tag == "plot") plot_=true;
478  else if (tag == "debug") debug_=true;
479  else if (tag == "only_fock") only_fock_=true;
480  else if (tag == "only_GS") only_GS_=true;
481  else if (tag == "highest_excitation") ss >> highest_excitation_;
482  else if (tag == "no_otf") on_the_fly_=false;
483  else if (tag == "read") read_ = true;
484  else if (tag == "only_sequential") only_sequential_=true;
485  else if (tag == "ipot") ss >> ipot_;
486  else if (tag == "rydberg") rydberg_=true;
487  else if (tag == "kain") kain_=true;
488  else if (tag == "kain_subspace") ss>> kain_subspace_;
489  else if (tag == "exop1") {std::string tmp; ss >> tmp; custom_exops_.push_back(tmp);}
490  else if (tag == "exop2") {std::string tmp; ss >> tmp; custom_exops_.push_back(tmp);}
491  else if (tag == "exop3") {std::string tmp; ss >> tmp; custom_exops_.push_back(tmp);}
492  else if (tag == "exop4") {std::string tmp; ss >> tmp; custom_exops_.push_back(tmp);}
493  else if (tag == "exop5") {std::string tmp; ss >> tmp; custom_exops_.push_back(tmp);}
494  else if (tag == "exop6") {std::string tmp; ss >> tmp; custom_exops_.push_back(tmp);}
495  else if (tag == "exop7") {std::string tmp; ss >> tmp; custom_exops_.push_back(tmp);}
496  else if (tag == "exop8") {std::string tmp; ss >> tmp; custom_exops_.push_back(tmp);}
497  else if (tag == "exop9") {std::string tmp; ss >> tmp; custom_exops_.push_back(tmp);}
498  else if (tag == "exop10") {std::string tmp; ss >> tmp; custom_exops_.push_back(tmp);}
499  else if (tag == "truncate_safety") ss>>safety_;
500  else continue;
501  }
502 
503  // make potential shift = -ipot - homo
504  if(dft_) shift_= -ipot_ - get_calc().aeps[noct-1];
505  highest_excitation_=highest_excitation_-shift_;
506 
507 
508  if (world.rank() == 0) {
509  std::cout<< std::setw(60) <<"\n\n\n\n ======= TDA info =======\n\n\n" << std::endl;
510  if (nfreeze_==0) std::cout<< std::setw(40) <<"# frozen orbitals : "<<"none" << std::endl;
511  if (nfreeze_>0) std::cout<< std::setw(40) <<"# frozen orbitals : " << "0 to " << nfreeze_-1 << std::endl;
512  std::cout<< std::setw(40) <<"active orbitals : " << nfreeze_ << " to " << calc_.param.nalpha-1 << std::endl;
513  std::cout<< std::setw(40) << "guess from : " << guess_ << std::endl;
514  std::cout<< std::setw(40) << "Gram-Schmidt is used : " << !only_fock_ << std::endl;
515  std::cout<< std::setw(40) << "threshold 3D : " << FunctionDefaults<3>::get_thresh() << std::endl;
516  std::cout<< std::setw(40) << "energy convergence : " << econv_ << std::endl;
517  std::cout<< std::setw(40) << "max residual (dconv) : " << dconv_ << std::endl;
518  std::cout<< std::setw(40) << "number of excitations : " << excitations_ << std::endl;
519  std::cout<< std::setw(40) << "number of guess excitations : " << guess_excitations_ << std::endl;
520  std::cout<< std::setw(40) << "guessed lowest extitation energy : " << guess_omega_ << std::endl;
521  std::cout<< std::setw(40) << "guessed excitation operators : " << guess_exop_ << std::endl;
522  std::cout<< std::setw(40) << "highest possible excitation : " << highest_excitation_default << std::endl;
523  std::cout<< std::setw(40) << "used highest possible excitation : " << highest_excitation_ << std::endl;
524  std::cout<< std::setw(40) << "guessed ionization potential is : " << ipot_ << std::endl;
525  std::cout<< std::setw(40) << "potential shift is : " << shift_ << std::endl;
526  std::cout<< std::setw(40) << "guessed lowest excitation : " << guess_omega_default << std::endl;
527  std::cout<< std::setw(40) << "chosen lowest excitation : " << guess_omega_ << std::endl;
528  std::cout<< std::setw(40) << "orthonormalization : ";
529  if(only_fock_) std::cout << "only perturbed fock matrix"<< std::endl;
530  else if(only_GS_) std::cout << "only Gram-Schmidt"<< std::endl;
531  else std::cout << "use both"<< std::endl;
532  std::cout<< std::setw(40) << "potential calculation : " << "on_the_fly is " << on_the_fly_ << std::endl;
533  std::cout<< std::setw(40) << "use KAIN : " << kain_ << std::endl;
534  }
535 
536 
537 
538  lo=get_calc().param.lo;
539  bsh_eps_ = FunctionDefaults<3>::get_thresh()*0.1;
540  for(size_t i=nfreeze_;i<mos_.size();i++){active_mo_.push_back(mos_[i]);}
541 
542  // Initialize the projector on the occupied space
543  Projector<double,3> projector(mos_);
544  rho0 = projector;
545 
546  // make the unperturbed density (closed shell)
547  real_function_3d active_density = real_factory_3d(world);
548  for(size_t i=0;i<active_mo_.size();i++){active_density += 2.0*active_mo_[i]*active_mo_[i];}
549  active_density_ = active_density;
550  real_function_3d density = real_factory_3d(world);
551  for(size_t i=0;i<mos_.size();i++){density+=2.0*mos_[i]*mos_[i];}
552  density_=density;
553  std::cout <<std::setw(40) <<"Norm of unperturbed density is : " << density_.norm2() << std::endl;
554 
555  // Initialize the exchange intermediate
556  if(not dft_) {
557  exchange_intermediate_ = make_exchange_intermediate();
558  std::cout << std::setw(40) << "CIS is used" << " : LIBXC Interface is not initialized" << std::endl;
559  }if(dft_){
560  lda_intermediate_ = make_lda_intermediate();
561  }
562 
563  // Initialize the KAIN solvers
564  kain_solvers.initialize(world,excitations_,noct,kain_);
565 
566 
567  // Prevent misstakes:
568  if(shift_>0){MADNESS_EXCEPTION("Potential shift is positive",1);}
569  if(not dft_ and shift_ !=0.0){MADNESS_EXCEPTION("Non zero potential shift in TDHF calculation",1);}
570 
571  if(only_fock_ and only_GS_){
572  print("\nWARNING: only_fock and only_GS demanded ...use both");
573  only_fock_ = false;
574  only_GS_ = false;
575  }
576 
577  // make the truncate thresh
578  truncate_thresh_ = FunctionDefaults<3>::get_thresh() * safety_;
579  std::cout << "Truncate threshold is set to " << truncate_thresh_ << std::endl;
580 
581  // Truncate the current mos
582  truncate(world,mos_,truncate_thresh_);
583  std::cout << "truncate molecular orbitals to " << truncate_thresh_ << std::endl;
584 
585  std::cout << "setup of TDA class ended\n" << std::endl;
586  }
587 
589 
590  double memwatch(const xfunctionsT &xfunctions,const bool printout)const{
591  // sanity_check
592  if(xfunctions.empty())return 0.0;
593  double allx=0.0; double allVx=0.0; double allr=0.0;
594  if(printout)std::cout << "\n\n#" << " " << " x " << " Vx " << " r " << std::endl;
595  if(printout)print("-------------------------------");
596  for(size_t i=0;i<xfunctions.size();i++){
597  if(on_the_fly_ and not xfunctions[i].Vx.empty()) MADNESS_EXCEPTION("on the fly calculation used but Vx not empty",1);
598  if(not kain_ and not xfunctions[i].current_residuals.empty()) MADNESS_EXCEPTION("no kain is used but current residuals are not empty",1);
599 
600  // mem information
601  double x_size = get_size(world,xfunctions[i].x);
602  double Vx_size= get_size(world,xfunctions[i].Vx);
603  double r_size=get_size(world,xfunctions[i].current_residuals);
604  allx+=x_size; allVx+=Vx_size; allr=r_size;
605  if(printout)std::cout << i << " " << x_size <<" "<< Vx_size <<" "<< r_size << " (GB)" << std::endl;
606  }
607  if(printout)print("-------------------------------");
608  if(printout)std::cout << "all" << " " << allx <<" "<< allVx <<" "<< allr << " (GB)\n\n" << std::endl;
609  return allx+allVx+allr;
610  }
611 
612  //virtual ~TDA();
613 
615  void solve(xfunctionsT &xfunctions);
616 
618  void solve_sequential(xfunctionsT xfunctions);
619 
621  const SCF &get_calc() const {return calc_;}
622 
623  // Print out grid (e.g for Koala or other external program)
624  const bool print_grid_TDA() const {return print_grid_;}
625 
626  // returns a shallow copy the converged xfunctions
627  xfunctionsT get_converged_xfunctions(){return converged_xfunctions_;}
628 
629 private:
630 
632  World & world;
633 
636  bool dft_;
637 
639  const SCF &calc_;
640 
643  vecfuncT mos_;
644 
646  bool print_grid_;
647 
649 
652  std::string guess_;
654  size_t guess_iter_;
655  double guess_omega_;
656 
659  std::string guess_mode_;
660 
662  std::string guess_exop_;
664  size_t guess_excitations_;
665  std::vector<std::string> custom_exops_;
666 
668  size_t excitations_;
669 
671  double bsh_eps_;
672 
674  size_t iter_max_;
676  double econv_;
678  double dconv_;
679  // Convergence criteria (residual norm) for the high thresh sequential iterations in the end
680  double hard_dconv_;
681  double hard_econv_;
683  size_t nfreeze_;
684 
686  bool plot_;
687 
689  bool debug_;
690 
692  bool only_fock_;
694  bool only_GS_;
695 
697  double highest_excitation_;
698 
699  double lo;
700 
702  vecfuncT active_mo_;
703 
704  // the projector on the unperturbed density
705  Projector<double,3> rho0;
706 
708  real_function_3d active_density_;
709 
711  real_function_3d density_;
712 
714  bool on_the_fly_;
715 
717  bool read_;
718 
720  bool only_sequential_;
721 
723  bool sequential_;
724 
726  TDA_DFT xclib_interface_;
727 
729  double ipot_;
730 
732  bool rydberg_;
733 
735  bool kain_;
736  kain_solver_helper_struct kain_solvers;
737 
739  size_t kain_subspace_;
740 
742  double shift_;
743 
745  double truncate_thresh_;
746 
748  double safety_;
749 
751  real_function_3d unperturbed_vxc_;
752 
754  vecfuncT lda_intermediate_;
755 
761  std::vector<vecfuncT> exchange_intermediate_;
762 
764  mutable real_function_3d coulomb_;
765 
767  std::vector<xfunction> converged_xfunctions_;
768 
771  void print_status(const xfunctionsT & xfunctions)const;
772 
776  void print_xfunction(const xfunction &x)const;
777 
780  void initialize(xfunctionsT & xfunctions);
781 
783  void guess_physical(xfunctionsT & xfunctions);
784 
786  void add_diffuse_functions(vecfuncT &mos);
787 
791  vecfuncT make_excitation_operators()const;
792 
794  // Calls iterate_all with the right settings
795  void iterate_guess(xfunctionsT &xfunctions);
796 
798  // Calls iterate_all with the right settings
799  void iterate(xfunctionsT &xfunctions);
800 
802  // guess: guess inititialisation or final iterations
805  void iterate_all(xfunctionsT &xfunctions,bool guess);
806 
811  void iterate_one(xfunction & xfunction,bool ptfock,bool guess);
812 
814  // instead of x = G(-2VPsi) and G parametrized with epsilon+omega
815  // here: x= G(-2VPsi + 2omega x) and G aprametrized only with epsilon (always bound)
816  void iterate_one_unbound(xfunction & xfunction,bool ptfock,bool guess);
817 
818  void iterate_one_yanai(xfunction & xfunction,bool guess);
819 
821  void update_energies(xfunctionsT &xfunctions);
822 
824  void normalize(xfunctionsT &xfunctions);
825  void normalize(xfunction &xfunction);
826 
828  void project_out_converged_xfunctions(xfunctionsT & xfunctions);
829 
831  void orthonormalize_GS(xfunctionsT &xfunctions);
832 
834  // 1. Call make_perturbed_fock_matrix(xfunctions)
835  // 2. Diagonalize
836  // 3. Update Energy and xfunctions
840  bool orthonormalize_fock(xfunctionsT &xfunctions,const bool guess);
841 
843  double measure_offdiagonality(const madness::Tensor<double> &U,const size_t size)const;
844 
845  std::vector<vecfuncT> transform_vecfunctions(const std::vector<vecfuncT> &xfunctions,const madness::Tensor<double> U)const;
846 
848  // 1. Make projector
849  // 2. apply
850  void project_out_occupied_space(vecfuncT &x);
851 
853  double perturbed_fock_matrix_element(const vecfuncT &xr, const vecfuncT &Vxp,const vecfuncT &xp)const;
854 
856  // Can also be used to calculate diagonal elements of the fock matrix
857  double expectation_value(const xfunction &x,const vecfuncT &Vx);
858 
860  // 1. Calculate potential (V0 + Gamma) --> Call perturbed_potential(exfunctions)
861  // 2. Calculate Matrix Elements
862  Tensor<double> make_perturbed_fock_matrix(const xfunctionsT &xfunctions)const;
863 
865  // 1. Call get_V0
866  // 2. Call apply_gamma or apply_gamma_dft
867  // 3. return V0 + Gamma
868  vecfuncT apply_perturbed_potential(const xfunction & xfunction)const;
869 
873  vecfuncT apply_gamma(const xfunction &xfunction)const;
874  vecfuncT apply_gamma_dft(const xfunction &xfunction)const;
875 
880  vecfuncT apply_hartree_potential(const vecfuncT &x)const;
881 
883  // This has to be done just one time because only the unperturbed orbitals are needed
884  std::vector<vecfuncT> make_exchange_intermediate()const;
885 
886  vecfuncT make_lda_intermediate()const;
887 
889  vecfuncT get_V0(const vecfuncT &x)const;
890 
892  real_function_3d get_coulomb_potential() const;
893 
895  real_function_3d get_vxc_potential()const;
896 
901  void plot_vecfunction(const vecfuncT &x,std::string msg, bool plot = true)const;
902 
908  bool check_convergence(xfunctionsT &xfunctions);
909 
913  void print_performance(const xfunctionsT &xfunctions,const std::string prename)const;
914 
918  void truncate_xfunctions(xfunctionsT &xfunctions);
919 
921 
923 
930  double oscillator_strength_length(const xfunction& xfunction) const;
931 
933 
940  double oscillator_strength_velocity(const xfunction& root) const;
941 
943  void analyze(xfunctionsT& roots) const;
944 
945  void save_xfunctions(const xfunctionsT &xfunctions)const;
946  bool read_xfunctions(xfunctionsT &xfunctions);
947 };
948 
949 } /* namespace madness */
950 
951 #endif /* TDA_H_ */
double end_wall
Definition: TDA.h:47
WorldGopInterface & gop
Global operations.
Definition: worldfwd.h:462
xfunction operator-=(const xfunction &b)
Definition: TDA.h:126
const mpreal exp(const mpreal &v, mp_rnd_t rnd_mode)
Definition: mpreal.h:2234
std::string operation
Definition: TDA.h:46
allocator operator=(const allocator &other)
Definition: TDA.h:174
Main include file for MADNESS and defines Function interface.
double f_velocity
Definition: TDA.h:105
void gaxpy(World &world, Q alpha, std::vector< Function< T, NDIM > > &a, Q beta, const std::vector< Function< R, NDIM > > &b, bool fence=true)
Generalized A*X+Y for vectors of functions -— a[i] = alpha*a[i] + beta*b[i].
Definition: vmra.h:680
std::istream & position_stream(std::istream &f, const std::string &tag)
Definition: position_stream.cc:37
const bool debug
Definition: tdse1.cc:45
World & world
Definition: TDA.h:78
tensorT aeps
orbital energies for alpha and beta orbitals
Definition: chem/SCF.h:745
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:194
::std::string string
Definition: gtest-port.h:872
std::vector< xfunction > xfunctionsT
Definition: TDA.h:188
World & world
Definition: TDA.h:43
Definition: chem/SCF.h:712
xfunction(World &world)
Definition: TDA.h:69
Vector< double, 3 > coord_3d
Definition: funcplot.h:634
TDA_TIMER(World &world, std::string msg)
Definition: TDA.h:42
xfunction operator-(const xfunction &b) const
Definition: TDA.h:131
NDIM & f
Definition: mra.h:2179
diffuse_functions(const double L, const std::vector< coord_3d > coord, const std::vector< int > signs, const size_t natoms, const size_t mode)
Definition: TDA.h:341
std::shared_ptr< operatorT > poperatorT
Definition: chem/SCF.h:71
double operator()(const coord_3d &r) const
Make a rydberg guess function where the neRäar range area is 0.0 and the long range is a diffuse 2s or...
Definition: TDA.h:346
ProcessID size() const
Returns the number of processes in this world (same as MPI_Comm_size())
Definition: worldfwd.h:533
static const double & get_thresh()
Returns the default threshold.
Definition: funcdefaults.h:225
void solve(xfunctionsT &xfunctions)
Solves the CIS or TDA equations.
Definition: TDA.cc:21
POD holding excitation energy and response vector for a single excitation.
Definition: tdhf_CIS.h:134
Function< TENSOR_RESULT_TYPE(L, R), NDIM > add(const Function< L, NDIM > &left, const Function< R, NDIM > &right, bool fence=true)
Same as operator+ but with optional fence and no automatic compression.
Definition: mra.h:1734
Functor that adds diffuse 1s functions on given coordinates with given signs (phases) ...
Definition: TDA.h:332
std::vector< vecfuncT > transform_vecfunctions(World &world, const std::vector< vecfuncT > &xfunctions, const madness::Tensor< double > U) const
Definition: TDA.h:309
T inner(const vecfunc< T, NDIM > &a, const vecfunc< T, NDIM > &b)
the non-linear solver requires an inner product
Definition: nemo.h:112
double memwatch(const xfunctionsT &xfunctions, const bool printout) const
try to gain a little bit information about the used memory
Definition: TDA.h:590
std::shared_ptr< FunctionFunctorInterface< double, 3 > > functorT
Definition: chem/corepotential.cc:58
bool converged
true if the xfunctions has converged
Definition: TDA.h:92
Implements most functionality of separated operators.
void setup(const vecfuncT &mos, const std::string input)
reads the input file and calculates needed functions
Definition: TDA.h:437
std::vector< double > error
the errors after each bsh step
Definition: TDA.h:88
size_t iterations
number of iterations already taken
Definition: TDA.h:96
#define PROFILE_BLOCK(name)
Definition: worldprofile.h:197
The structure needed if the kain solver shall be used.
Definition: TDA.h:192
const SCF & get_calc() const
Returns the MolDFT calulation.
Definition: TDA.h:621
double norm2() const
Returns the 2-norm of the function ... global sum ... works in either basis.
Definition: mra.h:650
std::vector< double > expectation_value
the expectation values (as vector so the conergence can be plotted)
Definition: TDA.h:86
TDA(World &world, const SCF &calc, const vecfuncT &mos, const std::string input)
Definition: TDA.h:400
Defines operations on vectors of FunctionsThis file defines a number of operations on vectors of func...
double omega
the currrent excitation energy used to parametrize the BSH operator
Definition: TDA.h:84
The Root structure is needed by the TDA class.
Definition: TDA.h:66
CalculationParameters param
Definition: chem/SCF.h:717
const int k
Definition: dielectric.cc:184
Generalized version of NonlinearSolver not limited to a single madness function.
Definition: nonlinsol.h:174
void transform_subspace(World &world, const madness::Tensor< double > U)
Definition: TDA.h:253
Example implementation of Krylov-subspace nonlinear equation solver.
XNonlinearSolver< xfunction, double, allocator > solverT
Definition: TDA.h:189
double lo
Smallest length scale we need to resolve.
Definition: chem/SCF.h:305
Function< TENSOR_RESULT_TYPE(L, R), NDIM > sub(const Function< L, NDIM > &left, const Function< R, NDIM > &right, bool fence=true)
Same as operator- but with optional fence and no automatic compression.
Definition: mra.h:1778
xfunction & operator=(const xfunction &other)
assignment operator (needed by kain)
Definition: TDA.h:108
allocator(World &world, const int nnoct)
Definition: TDA.h:169
FLOAT a(int j, FLOAT z)
Definition: y1.cc:86
void update_time()
Definition: TDA.h:49
xfunctionsT get_converged_xfunctions()
Definition: TDA.h:627
xfunction(World &world, const vecfuncT &x1)
Definition: TDA.h:73
vector< functionT > vecfuncT
Definition: chem/corepotential.cc:61
xfunction operator*(double a) const
Definition: TDA.h:140
void set_maxsub(int maxsub)
Definition: nonlinsol.h:198
void update(xfunctionsT &xfunctions)
Definition: TDA.h:235
std::vector< double > delta
the errors in omega after each bsh step
Definition: TDA.h:90
tensorT sqrt(const tensorT &s, double tol=1e-8)
Computes matrix square root (not used any more?)
Definition: DFcode/moldft.cc:446
A parallel world with full functionality wrapping an MPI communicator.
Definition: worldfwd.h:416
void fence()
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition: worldgop.cc:52
SeparatedConvolution< double, 3 > operatorT
Definition: chem/SCF.h:70
kain_solver_helper_struct()
Definition: TDA.h:193
const double start_cpu
Definition: TDA.h:45
void initialize(World &world, const size_t excitations, const size_t nnoct, const bool kain)
Definition: TDA.h:222
void erase_subspace(const size_t i)
Definition: TDA.h:280
double f_length
Definition: TDA.h:104
void increase_subspace(World &world, const xfunctionsT &xfunctions)
Definition: TDA.h:289
xfunction(const xfunction &other)
the copy contructor
Definition: TDA.h:75
const mpreal sum(const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode)
Definition: mpreal.cc:241
Abstract base class interface required for functors used as input to Functions.
Definition: function_interface.h:58
void info(bool debug=true)
print out information about the passed time since the TDA_TIMER object was created ...
Definition: TDA.h:55
void plot(const char *filename, const real_function_3d &f)
Definition: 3dharmonic.cc:138
ProcessID rank() const
Returns the process rank in this world (same as MPI_Comm_rank()))
Definition: worldfwd.h:526
Definition: nemo.h:121
const int noct
Definition: TDA.h:165
World & world
Definition: nemo.h:122
bool kain
true if the kain update should be used, false if a full step update should be forced ...
Definition: TDA.h:98
The TDA class: computes TDA and CIS calculations.
Definition: TDA.h:392
double get_size(World &world, const std::vector< Function< T, NDIM > > &v)
Definition: vmra.h:774
Implements (2nd generation) static load/data balancing for functions.
void sanity_check(const xfunctionsT &xfunctions) const
Definition: TDA.h:205
double end_cpu
Definition: TDA.h:48
Definition: TDA_XC.h:201
bool operator<=(const xfunction &b) const
Definition: TDA.h:156
vecfuncT current_residuals
the residuals of the last bsh step, is needed if the kain solver should be used
Definition: TDA.h:100
vecfuncT Vx
the applied potentials (to save memory this will mostly be empty)
Definition: TDA.h:82
double guess(const coord_3d &r)
Definition: 3dharmonic.cc:128
size_t number
the number of the xfunction
Definition: TDA.h:94
const bool print_grid_TDA() const
Definition: TDA.h:624
void print(const A &a)
Print a single item to std::cout terminating with new line.
Definition: print.h:122
FunctionFactory< double, 3 > real_factory_3d
Definition: functypedefs.h:93
const double start_wall
Definition: TDA.h:44
#define MADNESS_EXCEPTION(msg, value)
Definition: worldexc.h:88
bool operator<(const xfunction &b) const
Definition: TDA.h:157
vecfuncT x
the response orbitals
Definition: TDA.h:80
Strucutre for TIMER.
Definition: TDA.h:38
void reduce_subspace(const size_t i)
Definition: TDA.h:274
void solve_sequential(xfunctionsT xfunctions)
Solves the CIS or TDA equations sequentially for a set of preconverged xfunctions.
Definition: TDA.cc:78
Holds machinery to set up Functions/FuncImpls using various Factories and Interfaces.
Definition: chem/atomutil.cc:45
xfunction operator()()
Definition: TDA.h:171
FLOAT b(int j, FLOAT z)
Definition: y1.cc:79
int nalpha
Number of alpha spin electrons.
Definition: chem/SCF.h:301
double wall_time()
Returns the wall time in seconds relative to arbitrary origin.
Definition: world.cc:248
xfunction operator+=(const xfunction &b)
Definition: TDA.h:135
Function< TENSOR_RESULT_TYPE(Q, T), NDIM > mul(const Q alpha, const Function< T, NDIM > &f, bool fence=true)
Returns new function equal to alpha*f(x) with optional fence.
Definition: mra.h:1528
void compress(World &world, const std::vector< Function< T, NDIM > > &v, bool fence=true)
Compress a vector of functions.
Definition: vmra.h:130