# energy.h

    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 namespace sc {
    00044
    00048 class MolecularEnergy: public Function {
    00049   private:
    00050     RefSCDimension moldim_; // the number of cartesian variables
    00051     Ref<MolecularCoor> mc_;
    00052     Ref<Molecule> mol_;
    00053     Ref<MolecularHessian> hess_;
    00054     Ref<MolecularHessian> guesshess_;
    00055
    00056     RefSCVector cartesian_gradient_;
    00057     RefSymmSCMatrix cartesian_hessian_;
    00058
    00060     bool ckpt_;
    00062     char *ckpt_file_;
    00064     int ckpt_freq_;
    00065
    00066   protected:
    00067     Ref<PointGroup> initial_pg_;
    00068
    00069     void failure(const char *);
    00070
    00072     virtual void set_energy(double);
    00073
    00076     virtual void set_gradient(RefSCVector&);
    00077     virtual void set_hessian(RefSymmSCMatrix&);
    00078
    00079     void x_to_molecule();
    00080     void molecule_to_x();
    00081
    00082     int print_molecule_when_changed_;
    00083   public:
    00084     MolecularEnergy(const MolecularEnergy&);
    00135     MolecularEnergy(const Ref<KeyVal>&);
    00136     MolecularEnergy(StateIn&);
    00137     ~MolecularEnergy();
    00138
    00139     void save_data_state(StateOut&);
    00140
    00142     void set_checkpoint();
    00143     void set_checkpoint_file(const char*);
    00144     void set_checkpoint_freq(int freq);
    00146     bool if_to_checkpoint() const;
    00147     const char* checkpoint_file() const;
    00148     int checkpoint_freq() const;
    00149
    00150     MolecularEnergy & operator=(const MolecularEnergy&);
    00151
    00153     virtual double energy();
    00154
    00155     virtual Ref<Molecule> molecule() const;
    00156     virtual RefSCDimension moldim() const;
    00157
    00158     void guess_hessian(RefSymmSCMatrix&);
    00159     RefSymmSCMatrix inverse_hessian(RefSymmSCMatrix&);
    00160
    00163     RefSymmSCMatrix hessian();
    00164     int hessian_implemented() const;
    00165
    00166     void set_x(const RefSCVector&);
    00167
    00169     RefSCVector get_cartesian_x();
    00171     RefSCVector get_cartesian_gradient();
    00173     RefSymmSCMatrix get_cartesian_hessian();
    00174
    00175     Ref<MolecularCoor> molecularcoor() { return mc_; }
    00176
    00179     virtual void symmetry_changed();
    00180
    00181     Ref<NonlinearTransform> change_coordinates();
    00182
    00184     void print_natom_3(const RefSCVector &,
    00185                        const char *t=0, std::ostream&o=ExEnv::out0()) const;
    00186     void print_natom_3(double **, const char *t=0, std::ostream&o=ExEnv::out0()) const;
    00187     void print_natom_3(double *, const char *t=0, std::ostream&o=ExEnv::out0()) const;
    00188
    00189     virtual void print(std::ostream& = ExEnv::out0()) const;
    00190 };
    00191
    00192
    00193 class SumMolecularEnergy: public MolecularEnergy {
    00194   protected:
    00195     int n_;
    00196     Ref<MolecularEnergy> *mole_;
    00197     double *coef_;
    00198     void compute();
    00199   public:
    00200     SumMolecularEnergy(const Ref<KeyVal> &);
    00201     SumMolecularEnergy(StateIn&);
    00202     ~SumMolecularEnergy();
    00203
    00204     void save_data_state(StateOut&);
    00205
    00206     int value_implemented() const;
    00207     int gradient_implemented() const;
    00208     int hessian_implemented() const;
    00209
    00210     void set_x(const RefSCVector&);
    00211 };
    00212
    00213
    00214 /* The MolEnergyConvergence class derives from the Convergence class.  The
    00215 MolEnergyConvergence class allows the user to request that cartesian
    00216 coordinates be used in evaluating the convergence criteria.  This is
    00217 useful, since the internal coordinates can be somewhat arbitary.  If the
    00218 optimization is constrained, then the fixed internal coordinates will be
    00219 projected out of the cartesian gradients.  The input is similar to that for
    00220 Convergence class with the exception that giving none of the convergence
    00221 criteria keywords is the same as providing the following input to the
    00222 KeyVal constructor:
    00223
    00224 <pre>
    00225   conv<MolEnergyConvergence>: (
    00226     max_disp = 1.0e-4
    00227     max_grad = 1.0e-4
    00228     graddisp = 1.0e-4
    00229   )
    00230 </pre>
    00231
    00232 For MolEnergyConverence to work, the Function object given to the Optimizer
    00233 object must derive from MolecularEnergy.
    00234 */
    00235 class MolEnergyConvergence: public Convergence {
    00236   protected:
    00237     Ref<MolecularEnergy> mole_;
    00238     int cartesian_;
    00239
    00240     void set_defaults();
    00241   public:
    00242     // Standard constructors and destructor.
    00243     MolEnergyConvergence();
    00244     MolEnergyConvergence(StateIn&);
    00262     MolEnergyConvergence(const Ref<KeyVal>&);
    00263     virtual ~MolEnergyConvergence();
    00264
    00265     void save_data_state(StateOut&);
    00266
    00267     // Set the current gradient and position information.  These
    00268     //will possibly grab the cartesian infomation if we have a
    00269     //MolecularEnergy.
    00270     void get_grad(const Ref<Function> &);
    00271     void get_x(const Ref<Function> &);
    00272     void set_nextx(const RefSCVector &);
    00273
    00274     // Return nonzero if the optimization has converged.
    00275     int converged();
    00276 };
    00277
    00278 }
    00279
    00280 #endif
    00281
    00282 // Local Variables:
    00283 // mode: c++
    00284 // c-file-style: "CLJ"
    00285 // End: