MADNESS  0.10.1
molecular_optimizer.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 
34 /// \file chem/molecular_optimizer.h
35 /// \brief optimize the geometrical structure of a molecule
36 #ifndef MADNESS_CHEM_MOLECULAR_OPTIMIZER_H__INCLUDED
37 #define MADNESS_CHEM_MOLECULAR_OPTIMIZER_H__INCLUDED
38 
39 #include <madness/tensor/solvers.h>
42 
43 namespace madness {
44 
45 
47 
48  /// return the molecule of the target
49  virtual Molecule& molecule() {
50  MADNESS_EXCEPTION("you need to return a molecule",1);
51  return *(new Molecule()); // this is a memory leak silencing warnings
52  }
53 };
54 
55 
57 public:
58 
59  /// ctor reading out the input file
61  initialize < std::string > ("update", "bfgs", "Quasi-Newton update method",{"bfgs","sr1"});
62  initialize < int > ("maxiter", 20);
63  initialize < double > ("tol", 1.e-4,"geometry convergence threshold for the gradient norm");
64  initialize < double > ("value_precision", 1.e-12);
65  initialize < double > ("gradient_precision", 1.e-12);
66  initialize < bool > ("printtest", false);
67  initialize < std::string > ("cg_method", "polak_ribiere","conjugate gradients update",{"polak_ribiere","fletcher-reeves"});
68  initialize < std::vector<std::string> >
69  ("remove_dof", {"tx", "ty", "tz", "rx", "ry", "rz"}, "degree of freedom projected out: translation/rotation");
70  }
71 
74  // read input file
75  read_input_and_commandline_options(world,parser,"geoopt");
77  }
78 
80  }
81 
82  std::string update() const {return get<std::string>("update");}
83  std::string cg_method() const {return get<std::string>("cg_method");}
84  int maxiter() const {return get<int>("maxiter");}
85  double tol() const {return get<double>("tol");}
86  double value_precision() const {return get<double>("value_precision");}
87  double gradient_precision() const {return get<double>("gradient_precision");}
88  bool printtest() const {return get<bool>("printtest");}
89  std::vector<std::string> remove_dof() const {return get<std::vector<std::string> >("remove_dof");}
90 
91 };
92 
93 
94 
95 
96 /// Molecular optimizer derived from the QuasiNewton optimizer
97 
98 /// Essentially the QuasiNewton optimizer, but with the additional feature
99 /// of projecting out rotational and translational degrees of freedom
101 private:
102  /// How to update the hessian: BFGS or SR1
103  std::shared_ptr<MolecularOptimizationTargetInterface> target;
105  double f=1.e10;
106  double gnorm=1.e10;
107 
108 public:
110 
111  /// same ctor as the QuasiNewton optimizer
113  const std::shared_ptr<MolecularOptimizationTargetInterface>& tar)
114  : target(tar), parameters(world, parser) {
115  }
116 
117  /// optimize the underlying molecule
118 
119  /// @param[in] x the coordinates to compute energy and gradient
121  bool converge;
123 // converge=optimize_conjugate_gradients(x);
124  return converge;
125  }
126 
127  bool converged() const {
128  return gradient_norm();
129  }
130 
131  bool converged(const Tensor<double>& displacement) const {
132  return (gradient_norm()<parameters.tol() and (displacement.normf()/displacement.size())<parameters.tol());
133  }
134 
135  double value() const {return 0.0;}
136 
137  double gradient_norm() const {return gnorm;}
138 
139  /// set an (initial) hessian
140  void set_hessian(const Tensor<double>& hess) {
141  h=copy(hess);
142  }
143 
144 
145 private:
146 
148 
149  if(parameters.printtest()) target->test_gradient(x, parameters.value_precision());
150 
151  bool h_is_identity = (h.size() == 0);
152  if (h_is_identity) {
153  int n = x.dim(0);
154  h = Tensor<double>(n,n);
155 
156  // mass-weight the initial hessian
157  for (size_t i=0; i<target->molecule().natom(); ++i) {
158  h(3*i ,3*i )=1.0/(target->molecule().get_atom(i).mass);
159  h(3*i+1,3*i+1)=1.0/(target->molecule().get_atom(i).mass);
160  h(3*i+2,3*i+2)=1.0/(target->molecule().get_atom(i).mass);
161  }
162  h*=10.0;
163  madness::print("using the identity as initial Hessian");
164  } else {
165  Tensor<double> normalmodes;
167  target->molecule(),h,normalmodes,parameters.remove_dof());
168  madness::print("\ngopt: projected vibrational frequencies (cm-1)\n");
169  printf("frequency in cm-1 ");
170  for (int i=0; i<freq.size(); ++i) {
171  printf("%10.1f",constants::au2invcm*freq(i));
172  }
173 
174  }
175 
177 
178  // the previous gradient
179  Tensor<double> gp;
180  // the displacement
181  Tensor<double> dx;
182 
183  for (int iter=0; iter<parameters.maxiter(); ++iter) {
184  Tensor<double> gradient;
185 
186  target->value_and_gradient(x, f, gradient);
187 // print("gopt: new energy",f);
188 // const double rawgnorm = gradient.normf()/sqrt(gradient.size());
189 // print("gopt: raw gradient norm ",rawgnorm);
190 
191  // remove external degrees of freedom (translation and rotation)
193  gradient=inner(gradient,project_ext);
194  gnorm = gradient.normf()/sqrt(gradient.size());
195 // print("gopt: projected gradient norm ",gnorm);
196 // const double gradratio=rawgnorm/gnorm;
197 
198 
199 // if (iter == 1 && h_is_identity) {
200 // // Default initial Hessian is scaled identity but
201 // // prefer to reuse any existing approximation.
202 // h.scale(gradient.trace(gp)/gp.trace(dx));
203 // }
204 
205  if (iter > 0) {
206  if (parameters.update() == "bfgs") QuasiNewton::hessian_update_bfgs(dx, gradient-gp,h);
207  else QuasiNewton::hessian_update_sr1(dx, gradient-gp,h);
208  }
209 
210 
212  Tensor<double> v, e;
213  syev(h, v, e);
214  Tensor<double> normalmodes;
216  target->molecule(),h,normalmodes,parameters.remove_dof());
217  madness::print("\ngopt: projected vibrational frequencies (cm-1)\n");
218  printf("frequency in cm-1 ");
219  for (int i=0; i<freq.size(); ++i) {
220  printf("%10.3f",constants::au2invcm*freq(i));
221  }
222  printf("\n");
223 
224  // this will invert the hessian, multiply with the gradient and
225  // return the displacements
226  dx = new_search_direction2(gradient,h);
227 
228  // line search only for large displacements > 0.01 bohr = 2pm
229  double step=1.0;
230  double maxdx=dx.absmax();
231  if (h_is_identity and (maxdx>0.01)) step = QuasiNewton::line_search(1.0, f,
232  dx.trace(gradient), x, dx,target, parameters.value_precision());
233 
234  dx.scale(step);
235  x += dx;
236  gp = gradient;
237 
238  double disp2=dx.normf()/dx.size();
239  printf(" QuasiNewton iteration %2d energy: %16.8f gradient %.2e displacement %.2e \n", iter,f,gnorm, disp2);
240  if (converged(dx)) break;
241  }
242 
243  if (parameters.printtest()) {
244  print("final hessian");
245  print(h);
246  }
247  return converged(dx);
248  }
249 
251 
252 // Tensor<double> project_ext=projector_external_dof(target->molecule());
253 
254 
255  // initial energy and gradient gradient
256  double energy=0.0;
257  Tensor<double> gradient;
258 
259  // first step is steepest descent
261  Tensor<double> oldgradient;
262  Tensor<double> old_displacement(x.size());
263  old_displacement.fill(0.0);
264 
265  for (int iter=1; iter<parameters.maxiter(); ++iter) {
266 
267  // displace coordinates
268  if (iter>1) x+=displacement;
269 
270  // compute energy and gradient
271  target->value_and_gradient(x, energy, gradient);
272 // print("gopt: new energy",energy);
273  gnorm = gradient.normf()/sqrt(gradient.size());
274 // print("gopt: raw gradient norm ",gnorm);
275 
276  // remove external degrees of freedom (translation and rotation)
278  gradient=inner(gradient,project_ext);
279  gnorm = gradient.normf()/sqrt(gradient.size());
280 // print("gopt: projected gradient norm ",gnorm);
281 
282  // compute new displacement
283  if (iter==1) {
284  displacement=-gradient;
285  } else {
286  double beta=0.0;
287  if (parameters.cg_method()=="fletcher_reeves")
288  beta=gradient.normf()/oldgradient.normf();
289  if (parameters.cg_method()=="polak_ribiere")
290  beta=gradient.normf()/(gradient-oldgradient).normf();
291  displacement=-gradient + beta * old_displacement;
292  }
293 
294  // save displacement for the next step
295  old_displacement=displacement;
296 
297  if (converged(displacement)) break;
298  }
299 
300  return converged(displacement);
301  }
302 
303  /// effectively invert the hessian and multiply with the gradient
305  const Tensor<double>& hessian) const {
306  Tensor<double> dx, s;
307  double tol = parameters.gradient_precision();
308  double trust = 1.0; // This applied in spectral basis
309 
310  // diagonalize the hessian:
311  // VT H V = lambda
312  // H^-1 = V lambda^-1 VT
313  Tensor<double> v, e;
314  syev(hessian, v, e);
315 
316  // Transform gradient into spectral basis
317  // H^-1 g = V lambda^-1 VT g
318  Tensor<double> gv = inner(g,v); // this is VT g == gT V == gv
319 
320  // Take step applying restriction
321  int nneg=0, nsmall=0, nrestrict=0;
322  for (int i=0; i<e.size(); ++i) {
323  if (e[i] < -tol) {
324  if (parameters.printtest()) printf(
325  " forcing negative eigenvalue to be positive %d %.1e\n", i, e[i]);
326  nneg++;
327  //e[i] = -2.0*e[i]; // Enforce positive search direction
328  e[i] = -0.1*e[i]; // Enforce positive search direction
329  }
330  else if (e[i] < tol) {
331  if (parameters.printtest()) printf(
332  " forcing small eigenvalue to be zero %d %.1e\n", i, e[i]);
333  nsmall++;
334  e[i] = tol;
335  gv[i]=0.0; // effectively removing this direction
336  }
337 
338  // this is the step -lambda^-1 gv
339  gv[i] = -gv[i] / e[i];
340  if (std::abs(gv[i]) > trust) { // Step restriction
341  double gvnew = trust*std::abs(gv(i))/gv[i];
342  if (parameters.printtest()) printf(
343  " restricting step in spectral direction %d %.1e --> %.1e\n",
344  i, gv[i], gvnew);
345  nrestrict++;
346  gv[i] = gvnew;
347  }
348  }
349  if (nneg || nsmall || nrestrict)
350  printf(" nneg=%d nsmall=%d nrestrict=%d\n", nneg, nsmall, nrestrict);
351 
352  // Transform back from spectral basis to give the displacements
353  // disp = -V lambda^-1 VT g = V lambda^-1 gv
354  return inner(v,gv);
355  }
356 
357 public:
358 
359  /// compute the projector to remove transl. and rot. degrees of freedom
360 
361  /// taken from http://www.gaussian.com/g_whitepap/vib.htm
362  /// I don't really understand the concept behind the projectors, but it
363  /// seems to work, and it is not written down explicitly anywhere.
364  /// NOTE THE ERROR IN THE FORMULAS ON THE WEBPAGE !
365  /// @param[in] do_remove_dof which dof to remove: x,y,z,Rx,Ry,Rz (transl/rot)
367  const std::vector<std::string>& remove_dof) {
368 
369  // compute the translation vectors
370  Tensor<double> transx(3*mol.natom());
371  Tensor<double> transy(3*mol.natom());
372  Tensor<double> transz(3*mol.natom());
373  for (size_t i=0; i<mol.natom(); ++i) {
374  transx[3*i ]=sqrt(mol.get_atom(i).get_mass_in_au());
375  transy[3*i+1]=sqrt(mol.get_atom(i).get_mass_in_au());
376  transz[3*i+2]=sqrt(mol.get_atom(i).get_mass_in_au());
377  }
378 
379  // compute the rotation vectors
380 
381  // move the molecule to its center of mass and compute
382  // the moment of inertia tensor
383  Tensor<double> com=mol.center_of_mass();
384  Molecule mol2=mol;
385  mol2.translate(-1.0*com);
388 
389  // diagonalize the moment of inertia
391  syev(I, v, e); // v being the "X" tensor on the web site
392  v=transpose(v);
393 
394 // Tensor<double> B(e.size());
395 // for (long i=0; i<e.size(); ++i) B(i)=1.0/(2.0*e(i));
396 // print("rotational constants in cm-1");
397 // print(constants::au2invcm*B);
398 
399  // rotation vectors
400  Tensor<double> rotx(3*mol.natom());
401  Tensor<double> roty(3*mol.natom());
402  Tensor<double> rotz(3*mol.natom());
403 
404  for (size_t iatom=0; iatom<mol.natom(); ++iatom) {
405 
406  // coordinates wrt the center of mass ("R" on the web site)
407  Tensor<double> coord(3);
408  coord(0l)=mol.get_atom(iatom).x-com(0l);
409  coord(1l)=mol.get_atom(iatom).y-com(1l);
410  coord(2l)=mol.get_atom(iatom).z-com(2l);
411 
412  // note the wrong formula on the Gaussian website:
413  // multiply with sqrt(mass), do not divide!
414  coord.scale(sqrt(mol.get_atom(iatom).get_mass_in_au()));
415 
416  // p is the dot product of R and X on the web site
417  Tensor<double> p=inner(coord,v);
418 
419  // Eq. (5)
420  rotx(3*iatom + 0)=p(1)*v(0,2)-p(2)*v(0,1);
421  rotx(3*iatom + 1)=p(1)*v(1,2)-p(2)*v(1,1);
422  rotx(3*iatom + 2)=p(1)*v(2,2)-p(2)*v(2,1);
423 
424  roty(3*iatom + 0)=p(2)*v(0,0)-p(0l)*v(0,2);
425  roty(3*iatom + 1)=p(2)*v(1,0)-p(0l)*v(1,2);
426  roty(3*iatom + 2)=p(2)*v(2,0)-p(0l)*v(2,2);
427 
428  rotz(3*iatom + 0)=p(0l)*v(0,1)-p(1)*v(0,0);
429  rotz(3*iatom + 1)=p(0l)*v(1,1)-p(1)*v(1,0);
430  rotz(3*iatom + 2)=p(0l)*v(2,1)-p(1)*v(2,0);
431 
432  }
433 
434  // move the translational and rotational vectors to a common tensor
435  auto tmp=remove_dof;
436  for (auto& t : tmp) t=commandlineparser::tolower(t);
437  bool remove_Tx=std::find(tmp.begin(), tmp.end(), "tx")!=tmp.end();
438  bool remove_Ty=std::find(tmp.begin(), tmp.end(), "ty")!=tmp.end();
439  bool remove_Tz=std::find(tmp.begin(), tmp.end(), "tz")!=tmp.end();
440  bool remove_Rx=std::find(tmp.begin(), tmp.end(), "rx")!=tmp.end();
441  bool remove_Ry=std::find(tmp.begin(), tmp.end(), "ry")!=tmp.end();
442  bool remove_Rz=std::find(tmp.begin(), tmp.end(), "rz")!=tmp.end();
443  Tensor<double> ext_dof(6,3*mol.natom());
444  if (remove_Tx) ext_dof(0l,_)=transx;
445  if (remove_Ty) ext_dof(1l,_)=transy;
446  if (remove_Tz) ext_dof(2l,_)=transz;
447 
448  if (remove_Rx) ext_dof(3l,_)=rotx;
449  if (remove_Ry) ext_dof(4l,_)=roty;
450  if (remove_Rz) ext_dof(5l,_)=rotz;
451  print("removing dof ",remove_Tx, remove_Ty, remove_Tz, remove_Rx, remove_Ry, remove_Rz);
452 
453  // normalize
454  for (int i=0; i<6; ++i) {
455  double norm=ext_dof(i,_).normf();
456  if (norm>1.e-14) ext_dof(i,_).scale(1.0/norm);
457  else ext_dof(i,_)=0.0;
458  }
459 
460  // compute overlap to orthonormalize the projectors
461  Tensor<double> ovlp=inner(ext_dof,ext_dof,1,1);
462  syev(ovlp,v,e);
463  ext_dof=inner(v,ext_dof,0,0);
464 
465  // normalize or remove the dof if necessary (e.g. linear molecules)
466  for (int i=0; i<6; ++i) {
467  if (e(i)<1.e-14) {
468  ext_dof(i,_).scale(0.0); // take out this degree of freedom
469  } else {
470  ext_dof(i,_).scale(1.0/sqrt(e(i))); // normalize
471  }
472  }
473 
474  // construct projector on the complement of the rotations
475  Tensor<double> projector(3*mol.natom(),3*mol.natom());
476  for (size_t i=0; i<3*mol.natom(); ++i) projector(i,i)=1.0;
477 
478  // compute the outer products of the projectors
479  // 1- \sum_i | t_i >< t_i |
480  projector-=inner(ext_dof,ext_dof,0,0);
481 
482  return projector;
483 
484  }
485 
486  /// remove translational degrees of freedom from the hessian
487 
488  /// @param[in] do_remove_dof which dof to remove: x,y,z,Rx,Ry,Rz (transl/rot)
489  static void remove_external_dof(Tensor<double>& hessian, const Molecule& mol,
490  const std::vector<std::string>& remove_dof) {
491 
492  // compute the translation of the center of mass
493  Tensor<double> projector_ext=projector_external_dof(mol,remove_dof);
494 
495  // this is P^T * H * P
496  hessian=inner(projector_ext,inner(hessian,projector_ext),0,0);
497  }
498 
499 
500  /// returns the vibrational frequencies
501 
502  /// @param[in] hessian the hessian matrix (not mass-weighted)
503  /// @param[out] normalmodes the normal modes
504  /// @param[in] project_tr whether to project out translation and rotation
505  /// @param[in] print_hessian whether to print the hessian matrix
506  /// @return the frequencies in atomic units
508  const Tensor<double>& hessian, Tensor<double>& normalmodes,
509  const std::vector<std::string>& remove_dof={}, const bool print_hessian=false) {
510 
511  // compute mass-weighing matrices
512  Tensor<double> M=molecule.massweights();
513  Tensor<double> Minv(3*molecule.natom(),3*molecule.natom());
514  for (size_t i=0; i<3*molecule.natom(); ++i) Minv(i,i)=1.0/M(i,i);
515 
516  // mass-weight the hessian
517  Tensor<double> mwhessian=inner(M,inner(hessian,M));
518 
519  // remove translation and rotation
520  if (remove_dof.size()>0) MolecularOptimizer::remove_external_dof(mwhessian,molecule,remove_dof);
521 
522  if (print_hessian) {
523  if (remove_dof.size()>0) {
524  print("mass-weighted hessian with translation and rotation projected out");
525  } else {
526  print("mass-weighted unprojected hessian");
527  }
528  Tensor<double> mmhessian=inner(Minv,inner(mwhessian,Minv));
529  print(mwhessian);
530  print("mass-weighted unprojected hessian; mass-weighing undone");
531  print(mmhessian);
532  }
533 
534  Tensor<double> freq;
535  syev(mwhessian,normalmodes,freq);
536  for (long i=0; i<freq.size(); ++i) {
537  if (freq(i)>0.0) freq(i)=sqrt(freq(i)); // real frequencies
538  else freq(i)=-sqrt(-freq(i)); // imaginary frequencies
539  }
540  return freq;
541  }
542 
543 
545  const Tensor<double>& normalmodes) {
546 
547  Tensor<double> M=molecule.massweights();
548  Tensor<double> D=MolecularOptimizer::projector_external_dof(molecule,{"Tx","Ty","Tz","Rx","Ry","Rz"});
549  Tensor<double> L=copy(normalmodes);
550  Tensor<double> DL=inner(D,L);
551  Tensor<double> MDL=inner(M,DL);
552  Tensor<double> mu(3*molecule.natom());
553 
554  for (size_t i=0; i<3*molecule.natom(); ++i) {
555  double mu1=0.0;
556  for (size_t j=0; j<3*molecule.natom(); ++j) mu1+=MDL(j,i)*MDL(j,i);
557  if (mu1>1.e-14) mu(i)=1.0/(mu1*constants::atomic_mass_in_au);
558  }
559  return mu;
560  }
561 
562 };
563 
564 }
565 
566 #endif //MADNESS_CHEM_MOLECULAR_OPTIMIZER_H__INCLUDED
double y
Definition: molecule.h:60
double x
Definition: molecule.h:60
double z
Definition: molecule.h:60
double get_mass_in_au() const
return the mass in atomic units (electron mass = 1 a.u.)
Definition: molecule.h:104
long dim(int i) const
Returns the size of dimension i.
Definition: basetensor.h:147
long size() const
Returns the number of elements in the tensor.
Definition: basetensor.h:138
Definition: molecular_optimizer.h:56
MolecularOptimizationParameters(World &world, const commandlineparser &parser)
Definition: molecular_optimizer.h:72
MolecularOptimizationParameters()
ctor reading out the input file
Definition: molecular_optimizer.h:60
bool printtest() const
Definition: molecular_optimizer.h:88
double tol() const
Definition: molecular_optimizer.h:85
std::string cg_method() const
Definition: molecular_optimizer.h:83
double gradient_precision() const
Definition: molecular_optimizer.h:87
double value_precision() const
Definition: molecular_optimizer.h:86
std::string update() const
Definition: molecular_optimizer.h:82
std::vector< std::string > remove_dof() const
Definition: molecular_optimizer.h:89
void set_derived_values()
Definition: molecular_optimizer.h:79
int maxiter() const
Definition: molecular_optimizer.h:84
Molecular optimizer derived from the QuasiNewton optimizer.
Definition: molecular_optimizer.h:100
void set_hessian(const Tensor< double > &hess)
set an (initial) hessian
Definition: molecular_optimizer.h:140
bool optimize_quasi_newton(Tensor< double > &x)
Definition: molecular_optimizer.h:147
bool optimize(Tensor< double > &x)
optimize the underlying molecule
Definition: molecular_optimizer.h:120
Tensor< double > h
Definition: molecular_optimizer.h:104
double gradient_norm() const
Definition: molecular_optimizer.h:137
static Tensor< double > compute_reduced_mass(const Molecule &molecule, const Tensor< double > &normalmodes)
Definition: molecular_optimizer.h:544
static Tensor< double > compute_frequencies(const Molecule &molecule, const Tensor< double > &hessian, Tensor< double > &normalmodes, const std::vector< std::string > &remove_dof={}, const bool print_hessian=false)
returns the vibrational frequencies
Definition: molecular_optimizer.h:507
MolecularOptimizationParameters parameters
Definition: molecular_optimizer.h:109
static Tensor< double > projector_external_dof(const Molecule &mol, const std::vector< std::string > &remove_dof)
compute the projector to remove transl. and rot. degrees of freedom
Definition: molecular_optimizer.h:366
bool converged() const
Definition: molecular_optimizer.h:127
bool converged(const Tensor< double > &displacement) const
Definition: molecular_optimizer.h:131
double f
Definition: molecular_optimizer.h:105
bool optimize_conjugate_gradients(Tensor< double > &x)
Definition: molecular_optimizer.h:250
MolecularOptimizer(World &world, const commandlineparser &parser, const std::shared_ptr< MolecularOptimizationTargetInterface > &tar)
same ctor as the QuasiNewton optimizer
Definition: molecular_optimizer.h:112
std::shared_ptr< MolecularOptimizationTargetInterface > target
How to update the hessian: BFGS or SR1.
Definition: molecular_optimizer.h:103
Tensor< double > new_search_direction2(const Tensor< double > &g, const Tensor< double > &hessian) const
effectively invert the hessian and multiply with the gradient
Definition: molecular_optimizer.h:304
static void remove_external_dof(Tensor< double > &hessian, const Molecule &mol, const std::vector< std::string > &remove_dof)
remove translational degrees of freedom from the hessian
Definition: molecular_optimizer.h:489
double gnorm
Definition: molecular_optimizer.h:106
double value() const
Definition: molecular_optimizer.h:135
Definition: molecule.h:124
void translate(const Tensor< double > &translation)
translate the molecule
Definition: molecule.cc:670
const Atom & get_atom(unsigned int i) const
Definition: molecule.cc:447
Tensor< double > center_of_mass() const
compute the center of mass
Definition: molecule.cc:839
size_t natom() const
Definition: molecule.h:387
Tensor< double > moment_of_inertia() const
Definition: molecule.cc:855
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
static double line_search(double a1, double f0, double dxgrad, const Tensor< double > &x, const Tensor< double > &dx, std::shared_ptr< OptimizationTargetInterface > target, double value_precision)
make this static for other QN classed to have access to it
Definition: solvers.cc:113
static void hessian_update_bfgs(const Tensor< double > &dx, const Tensor< double > &dg, Tensor< double > &hessian)
make this static for other QN classed to have access to it
Definition: solvers.cc:179
static void hessian_update_sr1(const Tensor< double > &s, const Tensor< double > &y, Tensor< double > &hessian)
make this static for other QN classed to have access to it
Definition: solvers.cc:166
scalar_type absmax(long *ind=0) const
Return the absolute maximum value (and if ind is non-null, its index) in the Tensor.
Definition: tensor.h:1754
float_scalar_type normf() const
Returns the Frobenius norm of the tensor.
Definition: tensor.h:1726
Tensor< T > & fill(T x)
Inplace fill with a scalar (legacy name)
Definition: tensor.h:562
T trace(const Tensor< T > &t) const
Return the trace of two tensors (no complex conjugate invoked)
Definition: tensor.h:1776
IsSupported< TensorTypeData< Q >, Tensor< T > & >::type scale(Q x)
Inplace multiplication by scalar of supported type (legacy name)
Definition: tensor.h:686
A parallel world class.
Definition: world.h:132
double(* energy)()
Definition: derivatives.cc:58
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition: derivatives.cc:72
const double beta
Definition: gygi_soltion.cc:62
static const double v
Definition: hatom_sf_dirac.cc:20
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition: madness_exception.h:119
const double au2invcm
conversion from atomic units in reciprocal centimeter
Definition: constants.h:272
const double atomic_mass_in_au
Atomic mass in atomic units.
Definition: constants.h:269
double norm(const T &t)
Definition: adquad.h:42
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
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
response_space transpose(response_space &f)
Definition: basic_operators.cc:10
static const Slice _(0,-1, 1)
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 const Function< R, NDIM > & g
Definition: mra.h:2416
double inner(response_space &a, response_space &b)
Definition: response_functions.h:442
Key< NDIM > displacement(const Key< NDIM > &source, const Key< NDIM > &target)
given a source and a target, return the displacement in translation
Definition: key.h:359
void syev(const Tensor< T > &A, Tensor< T > &V, Tensor< typename Tensor< T >::scalar_type > &e)
Real-symmetric or complex-Hermitian eigenproblem.
Definition: lapack.cc:969
static long abs(long a)
Definition: tensor.h:218
const double mu
Definition: navstokes_cosines.cc:95
static const double L
Definition: rk.cc:46
Defines interfaces for optimization and non-linear equation solvers.
Definition: test_ar.cc:204
Definition: molecular_optimizer.h:46
virtual Molecule & molecule()
return the molecule of the target
Definition: molecular_optimizer.h:49
The interface to be provided by functions to be optimized.
Definition: solvers.h:176
The interface to be provided by optimizers.
Definition: solvers.h:206
very simple command line parser
Definition: commandlineparser.h:15
static std::string tolower(std::string s)
make lower case
Definition: commandlineparser.h:78
static const double_complex I
Definition: tdse1d.cc:164
void converge(World &world, functionT &potn, functionT &psi, double &eps)
Definition: tdse.cc:441
void e()
Definition: test_sig.cc:75
static Molecule molecule
Definition: testperiodicdft.cc:38