| [0b990d] | 1 | //
 | 
|---|
 | 2 | // energy.h
 | 
|---|
 | 3 | //
 | 
|---|
 | 4 | // Copyright (C) 1996 Limit Point Systems, Inc.
 | 
|---|
 | 5 | //
 | 
|---|
 | 6 | // Author: Curtis Janssen <cljanss@limitpt.com>
 | 
|---|
 | 7 | // Maintainer: LPS
 | 
|---|
 | 8 | //
 | 
|---|
 | 9 | // This file is part of the SC Toolkit.
 | 
|---|
 | 10 | //
 | 
|---|
 | 11 | // The SC Toolkit is free software; you can redistribute it and/or modify
 | 
|---|
 | 12 | // it under the terms of the GNU Library General Public License as published by
 | 
|---|
 | 13 | // the Free Software Foundation; either version 2, or (at your option)
 | 
|---|
 | 14 | // any later version.
 | 
|---|
 | 15 | //
 | 
|---|
 | 16 | // The SC Toolkit is distributed in the hope that it will be useful,
 | 
|---|
 | 17 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|---|
 | 18 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|---|
 | 19 | // GNU Library General Public License for more details.
 | 
|---|
 | 20 | //
 | 
|---|
 | 21 | // You should have received a copy of the GNU Library General Public License
 | 
|---|
 | 22 | // along with the SC Toolkit; see the file COPYING.LIB.  If not, write to
 | 
|---|
 | 23 | // the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 | 
|---|
 | 24 | //
 | 
|---|
 | 25 | // The U.S. Government is granted a limited license as per AL 91-7.
 | 
|---|
 | 26 | //
 | 
|---|
 | 27 | 
 | 
|---|
 | 28 | #ifndef _chemistry_molecule_energy_h
 | 
|---|
 | 29 | #define _chemistry_molecule_energy_h
 | 
|---|
 | 30 | 
 | 
|---|
 | 31 | #ifdef __GNUC__
 | 
|---|
 | 32 | #pragma interface
 | 
|---|
 | 33 | #endif
 | 
|---|
 | 34 | 
 | 
|---|
 | 35 | #include <iostream>
 | 
|---|
 | 36 | 
 | 
|---|
 | 37 | #include <math/optimize/function.h>
 | 
|---|
 | 38 | #include <math/optimize/conv.h>
 | 
|---|
 | 39 | #include <chemistry/molecule/molecule.h>
 | 
|---|
 | 40 | #include <chemistry/molecule/coor.h>
 | 
|---|
 | 41 | #include <chemistry/molecule/hess.h>
 | 
|---|
 | 42 | 
 | 
|---|
 | 43 | namespace sc {
 | 
|---|
 | 44 | 
 | 
|---|
 | 45 | /** The MolecularEnergy abstract class inherits from the Function class.
 | 
|---|
 | 46 | It computes the energy of the molecule as a function of the geometry.  The
 | 
|---|
 | 47 | coordinate system used can be either internal or cartesian.  */
 | 
|---|
 | 48 | class MolecularEnergy: public Function {
 | 
|---|
 | 49 |   private:
 | 
|---|
 | 50 |     RefSCDimension moldim_; // the number of cartesian variables
 | 
|---|
 | 51 |     Ref<MolecularCoor> mc_;
 | 
|---|
 | 52 |     Ref<Molecule> mol_;
 | 
|---|
 | 53 |     Ref<MolecularHessian> hess_;
 | 
|---|
 | 54 |     Ref<MolecularHessian> guesshess_;
 | 
|---|
 | 55 | 
 | 
|---|
 | 56 |     RefSCVector cartesian_gradient_;
 | 
|---|
 | 57 |     RefSymmSCMatrix cartesian_hessian_;
 | 
|---|
 | 58 | 
 | 
|---|
 | 59 |     /// Whether to do intermediate checkpointing of this object
 | 
|---|
 | 60 |     bool ckpt_;
 | 
|---|
 | 61 |     /// Name of the file into which to checkpoint this object
 | 
|---|
 | 62 |     char *ckpt_file_;
 | 
|---|
 | 63 |     /// How often this object should be checkpointed (only matters in iterative methods)
 | 
|---|
 | 64 |     int ckpt_freq_;
 | 
|---|
 | 65 |     
 | 
|---|
 | 66 |   protected:
 | 
|---|
 | 67 |     Ref<PointGroup> initial_pg_;
 | 
|---|
 | 68 | 
 | 
|---|
 | 69 |     void failure(const char *);
 | 
|---|
 | 70 | 
 | 
|---|
 | 71 |     /// This is just a wrapper around set_value().
 | 
|---|
 | 72 |     virtual void set_energy(double);
 | 
|---|
 | 73 | 
 | 
|---|
 | 74 |     /** These are passed gradients and hessian in cartesian coordinates.
 | 
|---|
 | 75 |         The gradient and hessian in internal coordinates are computed. */
 | 
|---|
 | 76 |     virtual void set_gradient(RefSCVector&);
 | 
|---|
 | 77 |     virtual void set_hessian(RefSymmSCMatrix&);
 | 
|---|
 | 78 | 
 | 
|---|
 | 79 |     void x_to_molecule();
 | 
|---|
 | 80 |     void molecule_to_x();
 | 
|---|
 | 81 | 
 | 
|---|
 | 82 |     int print_molecule_when_changed_;
 | 
|---|
 | 83 |   public:
 | 
|---|
 | 84 |     MolecularEnergy(const MolecularEnergy&);
 | 
|---|
 | 85 |     /** The KeyVal constructor.
 | 
|---|
 | 86 |         <dl>
 | 
|---|
 | 87 | 
 | 
|---|
 | 88 |         <dt><tt>molecule</tt><dd> A Molecule object.  There is no default.
 | 
|---|
 | 89 | 
 | 
|---|
 | 90 |         <dt><tt>coor</tt><dd> A MolecularCoor object that describes the
 | 
|---|
 | 91 |         coordinates.  If this is not given cartesian coordinates will be
 | 
|---|
 | 92 |         used.  For convenience, two keywords needed by the MolecularCoor
 | 
|---|
 | 93 |         object are automatically provided: natom3 and matrixkit.
 | 
|---|
 | 94 | 
 | 
|---|
 | 95 |         <dt><tt>value_accuracy</tt><dd> Sets the accuracy to which values
 | 
|---|
 | 96 |         are computed.  The default is 1.0e-6 atomic units.
 | 
|---|
 | 97 | 
 | 
|---|
 | 98 |         <dt><tt>gradient_accuracy</tt><dd> Sets the accuracy to which
 | 
|---|
 | 99 |         gradients are computed.  The default is 1.0e-6 atomic units.
 | 
|---|
 | 100 | 
 | 
|---|
 | 101 |         <dt><tt>hessian_accuracy</tt><dd> Sets the accuracy to which
 | 
|---|
 | 102 |         hessians are computed.  The default is 1.0e-4 atomic units.
 | 
|---|
 | 103 | 
 | 
|---|
 | 104 |         <dt><tt>hessian</tt><dd>Specifies a MolecularHessian object that is
 | 
|---|
 | 105 |         used to compute the hessian.  If this MolecularEnergy
 | 
|---|
 | 106 |         specialization does not provide a hessian of its own, and a hessian
 | 
|---|
 | 107 |         is needed, then this keyword must be specified.
 | 
|---|
 | 108 | 
 | 
|---|
 | 109 |         <dt><tt>guess_hessian</tt><dd>Specifies a MolecularHessian object
 | 
|---|
 | 110 |         that is used to compute a guess hessian.  Guess hessians are used
 | 
|---|
 | 111 |         to improve the rate of convergence of optimizations.  If this
 | 
|---|
 | 112 |         keyword is not specified, and a MolecularCoor object is given by
 | 
|---|
 | 113 |         <tt>coor</tt>, then the guess hessian is obtained from the
 | 
|---|
 | 114 |         MolecularCoor object.  If neither this nor <tt>coor</tt> are given,
 | 
|---|
 | 115 |         then Function::guess_hessian is used, which returns a unit matrix.
 | 
|---|
 | 116 | 
 | 
|---|
 | 117 |         <dt><tt>print_molecule_when_changed</tt><dd> If true, then whenever
 | 
|---|
 | 118 |         the molecule's coordinates are updated they will be printed.  The
 | 
|---|
 | 119 |         default is true.
 | 
|---|
 | 120 | 
 | 
|---|
 | 121 |         <dt><tt>checkpoint</tt><dd> If true, then this object will be
 | 
|---|
 | 122 |         checkpointed during its evaluation. Not all implementations
 | 
|---|
 | 123 |         of <tt>MolecularEnergy</tt> support checkpointing.
 | 
|---|
 | 124 |         The default is false.
 | 
|---|
 | 125 | 
 | 
|---|
 | 126 |         <dt><tt>checkpoint_file</tt><dd> Specifies the name of the file
 | 
|---|
 | 127 |         into which this object will be checkpointed. Default is
 | 
|---|
 | 128 |         "<inpubasename>.ckpt", where "<inputbasename>" is the name of the input
 | 
|---|
 | 129 |         file without ".in".
 | 
|---|
 | 130 | 
 | 
|---|
 | 131 |         <dt><tt>checkpoint_freq</tt><dd> Specifies how often this object to
 | 
|---|
 | 132 |         be checkpointed. Only matters for objects which are computed
 | 
|---|
 | 133 |         iteratively. Default is 1.
 | 
|---|
 | 134 |         </dl> */
 | 
|---|
 | 135 |     MolecularEnergy(const Ref<KeyVal>&);
 | 
|---|
 | 136 |     MolecularEnergy(StateIn&);
 | 
|---|
 | 137 |     ~MolecularEnergy();
 | 
|---|
 | 138 | 
 | 
|---|
 | 139 |     void save_data_state(StateOut&);
 | 
|---|
 | 140 | 
 | 
|---|
 | 141 |     /// Set up checkpointing
 | 
|---|
 | 142 |     void set_checkpoint();
 | 
|---|
 | 143 |     void set_checkpoint_file(const char*);
 | 
|---|
 | 144 |     void set_checkpoint_freq(int freq);
 | 
|---|
 | 145 |     /// Check if need to checkpoint
 | 
|---|
 | 146 |     bool if_to_checkpoint() const;
 | 
|---|
 | 147 |     const char* checkpoint_file() const;
 | 
|---|
 | 148 |     int checkpoint_freq() const;
 | 
|---|
 | 149 |     
 | 
|---|
 | 150 |     MolecularEnergy & operator=(const MolecularEnergy&);
 | 
|---|
 | 151 |     
 | 
|---|
 | 152 |     /// A wrapper around value();
 | 
|---|
 | 153 |     virtual double energy();
 | 
|---|
 | 154 | 
 | 
|---|
 | 155 |     virtual Ref<Molecule> molecule() const;
 | 
|---|
 | 156 |     virtual RefSCDimension moldim() const;
 | 
|---|
 | 157 |     
 | 
|---|
 | 158 |     void guess_hessian(RefSymmSCMatrix&);
 | 
|---|
 | 159 |     RefSymmSCMatrix inverse_hessian(RefSymmSCMatrix&);
 | 
|---|
 | 160 | 
 | 
|---|
 | 161 |     /** If a molecule hessian object is given, it will be used to provide a
 | 
|---|
 | 162 |         hessian. */
 | 
|---|
 | 163 |     RefSymmSCMatrix hessian();
 | 
|---|
 | 164 |     int hessian_implemented() const;
 | 
|---|
 | 165 | 
 | 
|---|
 | 166 |     void set_x(const RefSCVector&);
 | 
|---|
 | 167 | 
 | 
|---|
 | 168 |     /// Return the cartesian coordinates.
 | 
|---|
 | 169 |     RefSCVector get_cartesian_x();
 | 
|---|
 | 170 |     /// Return the cartesian gradient.
 | 
|---|
 | 171 |     RefSCVector get_cartesian_gradient();
 | 
|---|
 | 172 |     /// Return the cartesian hessian.
 | 
|---|
 | 173 |     RefSymmSCMatrix get_cartesian_hessian();
 | 
|---|
 | 174 | 
 | 
|---|
 | 175 |     Ref<MolecularCoor> molecularcoor() { return mc_; }
 | 
|---|
 | 176 | 
 | 
|---|
 | 177 |     /** Call this if you have changed the molecular symmetry of the
 | 
|---|
 | 178 |         molecule contained by this MolecularEnergy. */
 | 
|---|
 | 179 |     virtual void symmetry_changed();
 | 
|---|
 | 180 | 
 | 
|---|
 | 181 |     Ref<NonlinearTransform> change_coordinates();
 | 
|---|
 | 182 |     
 | 
|---|
 | 183 |     /// Nicely print n x 3 data that are stored in a vector.
 | 
|---|
 | 184 |     void print_natom_3(const RefSCVector &,
 | 
|---|
 | 185 |                        const char *t=0, std::ostream&o=ExEnv::out0()) const;
 | 
|---|
 | 186 |     void print_natom_3(double **, const char *t=0, std::ostream&o=ExEnv::out0()) const;
 | 
|---|
 | 187 |     void print_natom_3(double *, const char *t=0, std::ostream&o=ExEnv::out0()) const;
 | 
|---|
 | 188 | 
 | 
|---|
 | 189 |     virtual void print(std::ostream& = ExEnv::out0()) const;
 | 
|---|
 | 190 | };
 | 
|---|
 | 191 | 
 | 
|---|
 | 192 | 
 | 
|---|
 | 193 | class SumMolecularEnergy: public MolecularEnergy {
 | 
|---|
 | 194 |   protected:
 | 
|---|
 | 195 |     int n_;
 | 
|---|
 | 196 |     Ref<MolecularEnergy> *mole_;
 | 
|---|
 | 197 |     double *coef_;
 | 
|---|
 | 198 |     void compute();
 | 
|---|
 | 199 |   public:
 | 
|---|
 | 200 |     SumMolecularEnergy(const Ref<KeyVal> &);
 | 
|---|
 | 201 |     SumMolecularEnergy(StateIn&);
 | 
|---|
 | 202 |     ~SumMolecularEnergy();
 | 
|---|
 | 203 | 
 | 
|---|
 | 204 |     void save_data_state(StateOut&);
 | 
|---|
 | 205 | 
 | 
|---|
 | 206 |     int value_implemented() const;
 | 
|---|
 | 207 |     int gradient_implemented() const;
 | 
|---|
 | 208 |     int hessian_implemented() const;
 | 
|---|
 | 209 | 
 | 
|---|
 | 210 |     void set_x(const RefSCVector&);
 | 
|---|
 | 211 | };
 | 
|---|
 | 212 | 
 | 
|---|
 | 213 | 
 | 
|---|
 | 214 | /* The MolEnergyConvergence class derives from the Convergence class.  The
 | 
|---|
 | 215 | MolEnergyConvergence class allows the user to request that cartesian
 | 
|---|
 | 216 | coordinates be used in evaluating the convergence criteria.  This is
 | 
|---|
 | 217 | useful, since the internal coordinates can be somewhat arbitary.  If the
 | 
|---|
 | 218 | optimization is constrained, then the fixed internal coordinates will be
 | 
|---|
 | 219 | projected out of the cartesian gradients.  The input is similar to that for
 | 
|---|
 | 220 | Convergence class with the exception that giving none of the convergence
 | 
|---|
 | 221 | criteria keywords is the same as providing the following input to the
 | 
|---|
 | 222 | KeyVal constructor:
 | 
|---|
 | 223 | 
 | 
|---|
 | 224 | <pre>
 | 
|---|
 | 225 |   conv<MolEnergyConvergence>: (
 | 
|---|
 | 226 |     max_disp = 1.0e-4
 | 
|---|
 | 227 |     max_grad = 1.0e-4
 | 
|---|
 | 228 |     graddisp = 1.0e-4
 | 
|---|
 | 229 |   )
 | 
|---|
 | 230 | </pre>
 | 
|---|
 | 231 | 
 | 
|---|
 | 232 | For MolEnergyConverence to work, the Function object given to the Optimizer
 | 
|---|
 | 233 | object must derive from MolecularEnergy.
 | 
|---|
 | 234 | */
 | 
|---|
 | 235 | class MolEnergyConvergence: public Convergence {
 | 
|---|
 | 236 |   protected:
 | 
|---|
 | 237 |     Ref<MolecularEnergy> mole_;
 | 
|---|
 | 238 |     int cartesian_;
 | 
|---|
 | 239 | 
 | 
|---|
 | 240 |     void set_defaults();
 | 
|---|
 | 241 |   public:
 | 
|---|
 | 242 |     // Standard constructors and destructor.
 | 
|---|
 | 243 |     MolEnergyConvergence();
 | 
|---|
 | 244 |     MolEnergyConvergence(StateIn&);
 | 
|---|
 | 245 |     /** The KeyVal constructor.
 | 
|---|
 | 246 | 
 | 
|---|
 | 247 |         In addition to the keywords read by Convergence, the following
 | 
|---|
 | 248 |         keywords are examined:
 | 
|---|
 | 249 | 
 | 
|---|
 | 250 |         <dl>
 | 
|---|
 | 251 | 
 | 
|---|
 | 252 |         <dt><tt>energy</tt><dd> The MolecularEnergy object.  This is
 | 
|---|
 | 253 |         required.
 | 
|---|
 | 254 | 
 | 
|---|
 | 255 |         <dt><tt>cartesian</tt><dd> If true, cartesian displacements and
 | 
|---|
 | 256 |         gradients will be compared to the convergence criteria.  The
 | 
|---|
 | 257 |         default is true.
 | 
|---|
 | 258 | 
 | 
|---|
 | 259 |         </dl>
 | 
|---|
 | 260 | 
 | 
|---|
 | 261 |      */
 | 
|---|
 | 262 |     MolEnergyConvergence(const Ref<KeyVal>&);
 | 
|---|
 | 263 |     virtual ~MolEnergyConvergence();
 | 
|---|
 | 264 | 
 | 
|---|
 | 265 |     void save_data_state(StateOut&);
 | 
|---|
 | 266 | 
 | 
|---|
 | 267 |     // Set the current gradient and position information.  These
 | 
|---|
 | 268 |     //will possibly grab the cartesian infomation if we have a
 | 
|---|
 | 269 |     //MolecularEnergy.
 | 
|---|
 | 270 |     void get_grad(const Ref<Function> &);
 | 
|---|
 | 271 |     void get_x(const Ref<Function> &);
 | 
|---|
 | 272 |     void set_nextx(const RefSCVector &);
 | 
|---|
 | 273 | 
 | 
|---|
 | 274 |     // Return nonzero if the optimization has converged.
 | 
|---|
 | 275 |     int converged();
 | 
|---|
 | 276 | };
 | 
|---|
 | 277 | 
 | 
|---|
 | 278 | }
 | 
|---|
 | 279 | 
 | 
|---|
 | 280 | #endif
 | 
|---|
 | 281 | 
 | 
|---|
 | 282 | // Local Variables:
 | 
|---|
 | 283 | // mode: c++
 | 
|---|
 | 284 | // c-file-style: "CLJ"
 | 
|---|
 | 285 | // End:
 | 
|---|