00001 // 00002 // energy.h 00003 // 00004 // Copyright (C) 1996 Limit Point Systems, Inc. 00005 // 00006 // Author: Curtis Janssen <cljanss@limitpt.com> 00007 // Maintainer: LPS 00008 // 00009 // This file is part of the SC Toolkit. 00010 // 00011 // The SC Toolkit is free software; you can redistribute it and/or modify 00012 // it under the terms of the GNU Library General Public License as published by 00013 // the Free Software Foundation; either version 2, or (at your option) 00014 // any later version. 00015 // 00016 // The SC Toolkit is distributed in the hope that it will be useful, 00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 // GNU Library General Public License for more details. 00020 // 00021 // You should have received a copy of the GNU Library General Public License 00022 // along with the SC Toolkit; see the file COPYING.LIB. If not, write to 00023 // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 00024 // 00025 // The U.S. Government is granted a limited license as per AL 91-7. 00026 // 00027 00028 #ifndef _chemistry_molecule_energy_h 00029 #define _chemistry_molecule_energy_h 00030 00031 #ifdef __GNUC__ 00032 #pragma interface 00033 #endif 00034 00035 #include <iostream> 00036 00037 #include <math/optimize/function.h> 00038 #include <math/optimize/conv.h> 00039 #include <chemistry/molecule/molecule.h> 00040 #include <chemistry/molecule/coor.h> 00041 #include <chemistry/molecule/hess.h> 00042 00043 00047 class MolecularEnergy: public Function { 00048 private: 00049 RefSCDimension moldim_; // the number of cartesian variables 00050 Ref<MolecularCoor> mc_; 00051 Ref<Molecule> mol_; 00052 Ref<MolecularHessian> hess_; 00053 Ref<MolecularHessian> guesshess_; 00054 00055 RefSCVector cartesian_gradient_; 00056 RefSymmSCMatrix cartesian_hessian_; 00057 protected: 00058 Ref<PointGroup> initial_pg_; 00059 00060 void failure(const char *); 00061 00063 virtual void set_energy(double); 00064 00067 virtual void set_gradient(RefSCVector&); 00068 virtual void set_hessian(RefSymmSCMatrix&); 00069 00070 void x_to_molecule(); 00071 void molecule_to_x(); 00072 00073 int print_molecule_when_changed_; 00074 public: 00075 MolecularEnergy(const MolecularEnergy&); 00100 MolecularEnergy(const Ref<KeyVal>&); 00101 MolecularEnergy(StateIn&); 00102 ~MolecularEnergy(); 00103 00104 void save_data_state(StateOut&); 00105 00106 MolecularEnergy & operator=(const MolecularEnergy&); 00107 00109 virtual double energy(); 00110 00111 virtual Ref<Molecule> molecule() const; 00112 virtual RefSCDimension moldim() const; 00113 00114 void guess_hessian(RefSymmSCMatrix&); 00115 RefSymmSCMatrix inverse_hessian(RefSymmSCMatrix&); 00116 00119 RefSymmSCMatrix hessian(); 00120 int hessian_implemented() const; 00121 00122 void set_x(const RefSCVector&); 00123 00125 RefSCVector get_cartesian_x(); 00127 RefSCVector get_cartesian_gradient(); 00129 RefSymmSCMatrix get_cartesian_hessian(); 00130 00131 Ref<MolecularCoor> molecularcoor() { return mc_; } 00132 00135 virtual void symmetry_changed(); 00136 00137 Ref<NonlinearTransform> change_coordinates(); 00138 00140 void print_natom_3(const RefSCVector &, 00141 const char *t=0, std::ostream&o=ExEnv::out()) const; 00142 void print_natom_3(double **, const char *t=0, std::ostream&o=ExEnv::out()) const; 00143 void print_natom_3(double *, const char *t=0, std::ostream&o=ExEnv::out()) const; 00144 00145 virtual void print(std::ostream& = ExEnv::out()) const; 00146 }; 00147 00148 00149 class SumMolecularEnergy: public MolecularEnergy { 00150 protected: 00151 int n_; 00152 Ref<MolecularEnergy> *mole_; 00153 double *coef_; 00154 void compute(); 00155 public: 00156 SumMolecularEnergy(const Ref<KeyVal> &); 00157 SumMolecularEnergy(StateIn&); 00158 ~SumMolecularEnergy(); 00159 00160 void save_data_state(StateOut&); 00161 00162 int value_implemented() const; 00163 int gradient_implemented() const; 00164 int hessian_implemented() const; 00165 00166 void set_x(const RefSCVector&); 00167 }; 00168 00169 00170 /* The MolEnergyConvergence class derives from the Convergence class. The 00171 MolEnergyConvergence class allows the user to request that cartesian 00172 coordinates be used in evaluating the convergence criteria. This is 00173 useful, since the internal coordinates can be somewhat arbitary. If the 00174 optimization is constrained, then the fixed internal coordinates will be 00175 projected out of the cartesian gradients. The input is similar to that for 00176 Convergence class with the exception that giving none of the convergence 00177 criteria keywords is the same as providing the following input to the 00178 KeyVal constructor: 00179 00180 <pre> 00181 conv<MolEnergyConvergence>: ( 00182 max_disp = 1.0e-4 00183 max_grad = 1.0e-4 00184 graddisp = 1.0e-4 00185 ) 00186 </pre> 00187 00188 For MolEnergyConverence to work, the Function object given to the Optimizer 00189 object must derive from MolecularEnergy. 00190 */ 00191 class MolEnergyConvergence: public Convergence { 00192 protected: 00193 Ref<MolecularEnergy> mole_; 00194 int cartesian_; 00195 00196 void set_defaults(); 00197 public: 00198 // Standard constructors and destructor. 00199 MolEnergyConvergence(); 00200 MolEnergyConvergence(StateIn&); 00218 MolEnergyConvergence(const Ref<KeyVal>&); 00219 virtual ~MolEnergyConvergence(); 00220 00221 void save_data_state(StateOut&); 00222 00223 // Set the current gradient and position information. These 00224 //will possibly grab the cartesian infomation if we have a 00225 //MolecularEnergy. 00226 void get_grad(const Ref<Function> &); 00227 void get_x(const Ref<Function> &); 00228 void set_nextx(const RefSCVector &); 00229 00230 // Return nonzero if the optimization has converged. 00231 int converged(); 00232 }; 00233 00234 00235 #endif 00236 00237 // Local Variables: 00238 // mode: c++ 00239 // c-file-style: "CLJ" 00240 // End: