00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef OB_FORCEFIELD_H
00020 #define OB_FORCEFIELD_H
00021
00022 #include <vector>
00023 #include <string>
00024 #include <map>
00025
00026 #include <list>
00027 #include <set>
00028 #include <openbabel/base.h>
00029 #include <openbabel/mol.h>
00030 #include <openbabel/pluginiter.h>
00031
00032 namespace OpenBabel
00033 {
00034
00035 #define OBFF_LOGLVL_NONE 0
00036 #define OBFF_LOGLVL_LOW 1
00037 #define OBFF_LOGLVL_MEDIUM 2
00038 #define OBFF_LOGLVL_HIGH 3
00039
00040
00041 #define OBFF_ENERGY (1 << 0)
00042 #define OBFF_EBOND (1 << 1)
00043 #define OBFF_EANGLE (1 << 2)
00044 #define OBFF_ESTRBND (1 << 3)
00045 #define OBFF_ETORSION (1 << 4)
00046 #define OBFF_EOOP (1 << 5)
00047 #define OBFF_EVDW (1 << 6)
00048 #define OBFF_EELECTROSTATIC (1 << 7)
00049
00050
00051 #define OBFF_NUMERICAL_GRADIENT (1 << 0)
00052 #define OBFF_ANALYTICAL_GRADIENT (1 << 1)
00053
00054 #define KCAL_TO_KJ 4.1868
00055
00056
00057 #define IF_OBFF_LOGLVL_LOW if(loglvl >= OBFF_LOGLVL_LOW)
00058 #define IF_OBFF_LOGLVL_MEDIUM if(loglvl >= OBFF_LOGLVL_MEDIUM)
00059 #define IF_OBFF_LOGLVL_HIGH if(loglvl >= OBFF_LOGLVL_HIGH)
00060
00063 class OBFFParameter {
00064 public:
00066 int a, b, c, d;
00068 std::string _a, _b, _c, _d;
00069
00071 int ipar1, ipar2, ipar3, ipar4, ipar5;
00073 double dpar1, dpar2, dpar3, dpar4, dpar5;
00074
00076 OBFFParameter& operator=(const OBFFParameter &ai)
00077 {
00078 if (this != &ai) {
00079 a = ai.a;
00080 b = ai.b;
00081 c = ai.c;
00082 d = ai.d;
00083 _a = ai._a;
00084 _b = ai._b;
00085 _c = ai._c;
00086 _d = ai._d;
00087 ipar1 = ai.ipar1;
00088 ipar2 = ai.ipar2;
00089 ipar3 = ai.ipar3;
00090 ipar4 = ai.ipar4;
00091 ipar5 = ai.ipar5;
00092 dpar1 = ai.dpar1;
00093 dpar2 = ai.dpar2;
00094 dpar3 = ai.dpar3;
00095 dpar4 = ai.dpar4;
00096 dpar5 = ai.dpar5;
00097 }
00098
00099 return *this;
00100 }
00101
00103 void clear ()
00104 {
00105 a = 0;
00106 b = 0;
00107 c = 0;
00108 d = 0;
00109 ipar1 = 0;
00110 ipar2 = 0;
00111 ipar3 = 0;
00112 ipar4 = 0;
00113 ipar5 = 0;
00114 dpar1 = 0.0f;
00115 dpar2 = 0.0f;
00116 dpar3 = 0.0f;
00117 dpar4 = 0.0f;
00118 dpar5 = 0.0f;
00119 }
00120 };
00121
00122
00125 class OBFFCalculation
00126 {
00127 public:
00129 double energy;
00131 vector3 grada, gradb, gradc, gradd;
00133 OBAtom *a, *b, *c, *d;
00134
00136 OBFFCalculation()
00137 {
00138 a = NULL;
00139 b = NULL;
00140 c = NULL;
00141 d = NULL;
00142 energy = 0.0f;
00143 grada = VZero;
00144 gradb = VZero;
00145 gradc = VZero;
00146 gradd = VZero;
00147 }
00149 virtual ~OBFFCalculation()
00150 {
00151 }
00152
00154 virtual void Compute(bool gradients = true)
00155 {
00156 }
00158 virtual double GetEnergy()
00159 {
00160 if (!energy)
00161 Compute(false);
00162
00163 return energy;
00164 }
00166 virtual vector3 GetGradient(OBAtom *atom)
00167 {
00168 if (atom == a)
00169 return grada;
00170 else if (atom == b)
00171 return gradb;
00172 else if (atom == c)
00173 return gradc;
00174 else if (atom == d)
00175 return gradd;
00176 else
00177 return VZero;
00178 }
00179 };
00180
00181
00182
00183 class OBAPI OBForceField
00184 {
00185
00186 MAKE_PLUGIN(OBForceField)
00187
00188 protected:
00230 OBFFParameter* GetParameter(int a, int b, int c, int d, std::vector<OBFFParameter> ¶meter);
00232 OBFFParameter* GetParameter(const char* a, const char* b, const char* c, const char* d, std::vector<OBFFParameter> ¶meter);
00233
00235
00240 vector3 NumericalDerivative(OBAtom *a, int terms = OBFF_ENERGY);
00242 vector3 NumericalSecondDerivative(OBAtom *a, int terms = OBFF_ENERGY);
00252 virtual vector3 GetGradient(OBAtom *a, int terms = OBFF_ENERGY)
00253 {
00254 return -NumericalDerivative(a, terms);
00255 }
00261 bool IsInSameRing(OBAtom* a, OBAtom* b);
00262
00263 OBMol _mol;
00264
00266 std::ostream* logos;
00267 char logbuf[200];
00268 int loglvl;
00269
00271 int current_conformer;
00272
00274 double _econv, _e_n1;
00275 int _method, _cstep, _nsteps;
00276 std::vector<vector3> _grad1, _dir1;
00277
00278 public:
00280 virtual ~OBForceField()
00281 {
00282 }
00284
00288 static OBForceField* FindForceField(const std::string& ID)
00289 {
00290 return Iter().FindType(ID);
00291 }
00295 static OBForceField* FindForceField(const char *ID)
00296 {
00297 std::string ffname(ID);
00298 return FindForceField(ffname);
00299 }
00301 virtual std::string GetUnit() { return std::string("au"); }
00306 virtual bool Setup(OBMol &mol) { return false; }
00311 bool UpdateCoordinates(OBMol &mol);
00316 bool UpdateConformers(OBMol &mol);
00320 void OBFFLog(std::string msg)
00321 {
00322 if (!logos)
00323 return;
00324
00325 *logos << msg;
00326 }
00330 void OBFFLog(const char *msg)
00331 {
00332 if (!logos)
00333 return;
00334
00335 *logos << msg;
00336 }
00337
00339
00341
00343
00344
00352 virtual double Energy(bool gradients = true) { return 0.0f; }
00358 virtual double E_Bond(bool gradients = true) { return 0.0f; }
00364 virtual double E_Angle(bool gradients = true) { return 0.0f; }
00370 virtual double E_StrBnd(bool gradients = true) { return 0.0f; }
00376 virtual double E_Torsion(bool gradients = true) { return 0.0f; }
00382 virtual double E_OOP(bool gradients = true) { return 0.0f; }
00388 virtual double E_VDW(bool gradients = true) { return 0.0f; }
00394 virtual double E_Electrostatic(bool gradients = true) { return 0.0f; }
00396
00398
00400
00402
00403
00407 bool SetLogFile(std::ostream *pos);
00436 bool SetLogLevel(int level);
00438 int GetLogLevel() { return loglvl; }
00440
00442
00444
00446
00447
00464 void SystematicRotorSearch();
00465
00467
00469
00471
00472
00484 vector3 LineSearch(OBAtom *atom, vector3 &direction);
00499 void SteepestDescent(int steps, double econv = 1e-6f, int method = OBFF_ANALYTICAL_GRADIENT);
00527 void SteepestDescentInitialize(int steps = 1000, double econv = 1e-6f, int method = OBFF_ANALYTICAL_GRADIENT);
00543 bool SteepestDescentTakeNSteps(int n);
00559 void ConjugateGradients(int steps, double econv = 1e-6f, int method = OBFF_ANALYTICAL_GRADIENT);
00586 void ConjugateGradientsInitialize(int steps = 1000, double econv = 1e-6f, int method = OBFF_ANALYTICAL_GRADIENT);
00601 bool ConjugateGradientsTakeNSteps(int n);
00603
00605
00607
00609
00610
00611 virtual bool Validate() { return false; }
00616 virtual bool ValidateGradients() { return false; }
00621 vector3 ValidateGradientError(vector3 &numgrad, vector3 &anagrad);
00623
00625
00627
00629
00630
00636 static double VectorLengthDerivative(vector3 &a, vector3 &b);
00643 static double VectorAngleDerivative(vector3 &a, vector3 &b, vector3 &c);
00651 static double VectorTorsionDerivative(vector3 &a, vector3 &b, vector3 &c, vector3 &d);
00653
00658 void kludge()
00659 {
00660 PluginIter<OBForceField> it;
00661 (++it)->SetLogLevel(1);
00662 if(it)it.ID();
00663 }
00664
00665 };
00666
00667 }
00668
00669 #endif // OB_FORCEFIELD_H
00670