• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files

forcefield.h

Go to the documentation of this file.
00001 /**********************************************************************
00002 forcefield.h - Handle OBForceField class.
00003  
00004 Copyright (C) 2006-2007 by Tim Vandermeersch <tim.vandermeersch@gmail.com>
00005  
00006 This file is part of the Open Babel project.
00007 For more information, see <http://openbabel.sourceforge.net/>
00008  
00009 This program is free software; you can redistribute it and/or modify
00010 it under the terms of the GNU General Public License as published by
00011 the Free Software Foundation version 2 of the License.
00012  
00013 This program is distributed in the hope that it will be useful,
00014 but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 GNU General Public License for more details.
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/babelconfig.h>
00029 #include <openbabel/base.h>
00030 #include <openbabel/mol.h>
00031 #include <openbabel/plugin.h>
00032 #include <openbabel/grid.h>
00033 #include <openbabel/griddata.h>
00034 #include <float.h>
00035 
00036 namespace OpenBabel
00037 {
00038   // log levels
00039 #define OBFF_LOGLVL_NONE        0   
00040 #define OBFF_LOGLVL_LOW         1   
00041 #define OBFF_LOGLVL_MEDIUM      2   
00042 #define OBFF_LOGLVL_HIGH        3   
00043 
00044   // terms
00045 #define OBFF_ENERGY             (1 << 0)   
00046 #define OBFF_EBOND              (1 << 1)   
00047 #define OBFF_EANGLE             (1 << 2)   
00048 #define OBFF_ESTRBND            (1 << 3)   
00049 #define OBFF_ETORSION           (1 << 4)   
00050 #define OBFF_EOOP               (1 << 5)   
00051 #define OBFF_EVDW               (1 << 6)   
00052 #define OBFF_EELECTROSTATIC     (1 << 7)   
00053 
00054   // constraint types
00055 #define OBFF_CONST_IGNORE       (1 << 0)   
00056 #define OBFF_CONST_ATOM         (1 << 1)   
00057 #define OBFF_CONST_ATOM_X       (1 << 2)   
00058 #define OBFF_CONST_ATOM_Y       (1 << 3)   
00059 #define OBFF_CONST_ATOM_Z       (1 << 4)   
00060 #define OBFF_CONST_DISTANCE     (1 << 5)   
00061 #define OBFF_CONST_ANGLE        (1 << 6)   
00062 #define OBFF_CONST_TORSION      (1 << 7)   
00063 #define OBFF_CONST_CHIRAL       (1 << 8)   
00064 
00065   // mode arguments for SteepestDescent, ConjugateGradients, ...
00066 #define OBFF_NUMERICAL_GRADIENT         (1 << 0)  
00067 #define OBFF_ANALYTICAL_GRADIENT        (1 << 1)  
00068 
00069 #define KCAL_TO_KJ      4.1868
00070 
00071   // inline if statements for logging.
00072 #define IF_OBFF_LOGLVL_LOW    if(_loglvl >= OBFF_LOGLVL_LOW)
00073 #define IF_OBFF_LOGLVL_MEDIUM if(_loglvl >= OBFF_LOGLVL_MEDIUM)
00074 #define IF_OBFF_LOGLVL_HIGH   if(_loglvl >= OBFF_LOGLVL_HIGH)
00075 
00077   struct LineSearchType 
00078   {
00079     enum {
00080       Simple, Newton2Num 
00081     };
00082   };
00083   /*
00084   struct ConstraintType
00085   {
00086     enum { 
00087       Ignore, Atom, AtomX, AtomY, AtomZ, Distance, Angle, Torsion, Chiral
00088     };
00089   };
00090   */
00091  
00094   class OBFPRT OBFFParameter {
00095   public:
00097     int         a, b, c, d;
00099     std::string _a, _b, _c, _d; 
00100 
00102     std::vector<int>    _ipar;
00104     std::vector<double> _dpar;
00105 
00107     OBFFParameter& operator=(const OBFFParameter &ai) 
00108       {
00109         if (this != &ai) {
00110           a = ai.a;
00111           b = ai.b;
00112           c = ai.c;
00113           d = ai.d;
00114           _a = ai._a;
00115           _b = ai._b;
00116           _c = ai._c;
00117           _d = ai._d;
00118           _ipar = ai._ipar;
00119           _dpar = ai._dpar;
00120         }
00121         
00122         return *this;
00123       }
00124 
00126     void clear () 
00127     {
00128       a = b = c = d = 0;
00129       _ipar.clear();
00130       _dpar.clear();
00131     }
00132   }; // class OBFFParameter
00133   
00134   // specific class introductions in forcefieldYYYY.cpp (for YYYY calculations)
00135 
00138   class OBFPRT OBFFCalculation2
00139   {
00140   public:
00142     double energy;
00144     OBAtom *a, *b;
00146     int idx_a, idx_b;
00148     double *pos_a, *pos_b;
00150     double force_a[3], force_b[3];
00152     virtual ~OBFFCalculation2() 
00153     {
00154     }    
00157     virtual void SetupPointers() 
00158     {
00159       if (!a || !b) return;
00160       pos_a = a->GetCoordinate();
00161       idx_a = a->GetIdx();
00162       pos_b = b->GetCoordinate();
00163       idx_b = b->GetIdx();
00164     }
00165   };
00166  
00169   class OBFPRT OBFFCalculation3: public OBFFCalculation2
00170   {
00171   public:
00173     OBAtom *c;
00175     int idx_c;
00177     double *pos_c;
00179     double force_c[3];
00181     virtual ~OBFFCalculation3() 
00182     {
00183     }    
00186     virtual void SetupPointers() 
00187     {
00188       if (!a || !b || !c) return;
00189       pos_a = a->GetCoordinate();
00190       idx_a = a->GetIdx();
00191       pos_b = b->GetCoordinate();
00192       idx_b = b->GetIdx();
00193       pos_c = c->GetCoordinate();
00194       idx_c = c->GetIdx();
00195     }
00196   };
00197 
00200   class OBFPRT OBFFCalculation4: public OBFFCalculation3
00201   {
00202   public:
00204     OBAtom *d;
00206     int idx_d;
00208     double *pos_d;
00210     double force_d[3];
00212     virtual ~OBFFCalculation4() 
00213     {
00214     }    
00217     void SetupPointers() 
00218     {
00219       if (!a || !b || !c || !d) return;
00220       pos_a = a->GetCoordinate();
00221       idx_a = a->GetIdx();
00222       pos_b = b->GetCoordinate();
00223       idx_b = b->GetIdx();
00224       pos_c = c->GetCoordinate();
00225       idx_c = c->GetIdx();
00226       pos_d = d->GetCoordinate();
00227       idx_d = d->GetIdx();
00228     }
00229   };
00230 
00234   class OBFPRT OBFFConstraint
00235   {
00236   public:
00238     double factor, constraint_value;
00239     double rab0, rbc0;
00241     int type, ia, ib, ic, id;
00243     OBAtom *a, *b, *c, *d;
00245     vector3 grada, gradb, gradc, gradd;
00246 
00248     OBFFConstraint() 
00249       {
00250         a = b = c = d = NULL;
00251         ia = ib = ic = id = 0;
00252         constraint_value = 0.0;
00253         factor = 0.0;
00254       }
00256     ~OBFFConstraint()
00257       {
00258       }
00259       
00260     vector3 GetGradient(int a) 
00261     {
00262       if (a == ia)
00263         return grada;
00264       else if (a == ib)
00265         return gradb;
00266       else if (a == ic)
00267         return gradc;
00268       else if (a == id)
00269         return gradd;
00270       else 
00271         return  VZero;
00272     }
00273   };
00274 
00278   class OBFPRT OBFFConstraints
00279   {
00280   public:
00282     OBFFConstraints();
00284     ~OBFFConstraints()
00285       {
00286         _constraints.clear();
00287         _ignored.Clear();
00288         _fixed.Clear();
00289         _Xfixed.Clear();
00290         _Yfixed.Clear();
00291         _Zfixed.Clear();
00292       }
00294     void Clear();
00296     double GetConstraintEnergy();
00298     vector3 GetGradient(int a);
00300     OBFFConstraints& operator=(const OBFFConstraints &ai) 
00301       {
00302         if (this != &ai) {
00303           _constraints = ai._constraints;
00304           _ignored = ai._ignored;
00305           _fixed = ai._fixed;
00306           _Xfixed = ai._Xfixed;
00307           _Yfixed = ai._Yfixed;
00308           _Zfixed = ai._Zfixed;
00309         }
00310         return *this;
00311       }
00312 
00316     void Setup(OBMol &mol);
00317 
00319     // Set Constraints                                                     //
00322 
00323 
00324     void SetFactor(double factor);
00326     void AddIgnore(int a);
00328     void AddAtomConstraint(int a);
00330     void AddAtomXConstraint(int a);
00332     void AddAtomYConstraint(int a);
00334     void AddAtomZConstraint(int a);
00336     void AddDistanceConstraint(int a, int b, double length);
00338     void AddAngleConstraint(int a, int b, int c, double angle);
00340     void AddTorsionConstraint(int a, int b, int c, int d, double torsion);
00343     void DeleteConstraint(int index);
00345 
00346     // Get Constraints                                                     //
00349 
00350 
00351     double GetFactor();
00353     int Size() const;
00363     int GetConstraintType(int index) const;
00367     double GetConstraintValue(int index) const;
00370     int GetConstraintAtomA(int index) const;
00373     int GetConstraintAtomB(int index) const;
00376     int GetConstraintAtomC(int index) const;
00379     int GetConstraintAtomD(int index) const;
00382     bool IsIgnored(int a);
00385     bool IsFixed(int a);
00388     bool IsXFixed(int a);
00391     bool IsYFixed(int a);
00394     bool IsZFixed(int a);
00398     OBBitVec GetIgnoredBitVec() { return _ignored; }
00400  
00401   private:
00402     std::vector<OBFFConstraint> _constraints;
00403     OBBitVec    _ignored;
00404     OBBitVec    _fixed;
00405     OBBitVec    _Xfixed;
00406     OBBitVec    _Yfixed;
00407     OBBitVec    _Zfixed;
00408     double _factor;
00409   };
00410  
00411   // Class OBForceField
00412   // class introduction in forcefield.cpp
00413   class OBFPRT OBForceField : public OBPlugin
00414   {
00415     MAKE_PLUGIN(OBForceField)
00416   
00417     protected:
00418 
00460     OBFFParameter* GetParameter(int a, int b, int c, int d, std::vector<OBFFParameter> &parameter);
00462     OBFFParameter* GetParameter(const char* a, const char* b, const char* c, const char* d, 
00463         std::vector<OBFFParameter> &parameter);
00465     int GetParameterIdx(int a, int b, int c, int d, std::vector<OBFFParameter> &parameter);
00466            
00475     vector3 NumericalDerivative(OBAtom *a, int terms = OBFF_ENERGY);
00477     vector3 NumericalSecondDerivative(OBAtom *a, int terms = OBFF_ENERGY);
00478     
00479     /* 
00480      *   NEW gradients functions
00481      */ 
00482     
00485     void SetGradient(double *grad, int idx) 
00486     { 
00487       const int coordIdx = (idx - 1) * 3;
00488       for (unsigned int i = 0; i < 3; ++i) {
00489         _gradientPtr[coordIdx + i] = grad[i]; 
00490       }
00491     }
00492     
00495     void AddGradient(double *grad, int idx) 
00496     { 
00497       const int coordIdx = (idx - 1) * 3;
00498       for (unsigned int i = 0; i < 3; ++i) {
00499         _gradientPtr[coordIdx + i] += grad[i];
00500       }
00501     }
00502     
00505     virtual vector3 GetGradient(OBAtom *a, int /*terms*/ = OBFF_ENERGY) 
00506     { 
00507       const int coordIdx = (a->GetIdx() - 1) * 3;
00508       return _gradientPtr + coordIdx;
00509     }
00510     
00513     double* GetGradientPtr() 
00514     { 
00515       return _gradientPtr;
00516     }
00517     
00520     virtual void ClearGradients() 
00521     { 
00522       // We cannot use memset because IEEE floating point representations
00523       // are not guaranteed by C/C++ standard, but this loop can be
00524       // unrolled or vectorized by compilers
00525       for (unsigned int i = 0; i < _ncoords; ++i)
00526         _gradientPtr[i] = 0.0;
00527       //      memset(_gradientPtr, '\0', sizeof(double)*_ncoords);
00528     }
00529 
00537     bool IsInSameRing(OBAtom* a, OBAtom* b);
00538  
00539     // general variables
00540     OBMol       _mol; 
00541     bool        _init; 
00542     std::string _parFile; 
00543     bool        _validSetup; 
00544     double      *_gradientPtr; 
00545     // logging variables
00546     std::ostream* _logos; 
00547     char        _logbuf[BUFF_SIZE+1]; 
00548     int         _loglvl; 
00549     int         _origLogLevel;
00550     // conformer genereation (rotor search) variables
00551     int         _current_conformer; 
00552     std::vector<double> _energies; 
00553     // minimization variables
00554     double      _econv, _e_n1; 
00555     int         _cstep, _nsteps; 
00556     double      *_grad1; 
00557     unsigned int _ncoords; 
00558     int         _linesearch; 
00559     // molecular dynamics variables
00560     double      _timestep; 
00561     double      _temp; 
00562     double      *_velocityPtr; 
00563     // contraint varibles
00564     static OBFFConstraints _constraints; 
00565     static int _fixAtom; 
00566     static int _ignoreAtom; 
00567     // cut-off variables
00568     bool        _cutoff; 
00569     double      _rvdw; 
00570     double      _rele; 
00571     OBBitVec    _vdwpairs; 
00572     OBBitVec    _elepairs; 
00573     int         _pairfreq; 
00574     // group variables
00575     std::vector<OBBitVec> _intraGroup; 
00576     std::vector<OBBitVec> _interGroup; 
00577     std::vector<std::pair<OBBitVec, OBBitVec> > _interGroups; 
00578 
00579   public:
00583     virtual OBForceField* MakeNewInstance()=0;
00584 
00586     virtual ~OBForceField()
00587     {
00588       if (_grad1 != NULL) {
00589         delete [] _grad1;
00590         _grad1 = NULL;
00591       }
00592     }
00593 
00595     const char* TypeID()
00596     {
00597       return "forcefields";
00598     }
00599 
00603     static OBForceField* FindForceField(const std::string& ID)
00604     { 
00605       return FindType(ID.c_str());
00606     } 
00610     static OBForceField* FindForceField(const char *ID)
00611     {
00612       return FindType(ID);
00613     }
00614     /*
00615      *
00616      */
00617     void SetParameterFile(const std::string &filename)
00618     {
00619       _parFile = filename;
00620       _init = false;
00621     }
00624     virtual std::string GetUnit() { return std::string("au"); }
00625     /* Does this force field have analytical gradients defined for all
00626      * calculation components (bonds, angles, non-bonded, etc.)
00627      * If this is true, code should default to using OBFF_ANALYTICAL_GRADIENT
00628      * for SteepestDescent() or ConjugateGradients().
00629      * \return True if all analytical gradients are implemented.
00630      */
00631     virtual bool HasAnalyticalGradients() { return false; }
00636     bool Setup(OBMol &mol); 
00642     bool Setup(OBMol &mol, OBFFConstraints &constraints);
00646     // move to protected in future version
00647     virtual bool ParseParamFile() { return false; } 
00651     // move to protected in future version
00652     virtual bool SetTypes() { return false; }
00656     // move to protected in future version
00657     virtual bool SetFormalCharges() { return false; }
00661     // move to protected in future version
00662     virtual bool SetPartialCharges() { return false; }
00666     // move to protected in future version
00667     virtual bool SetupCalculations() { return false; }
00672     // move to protected in future version
00673     virtual bool SetupPointers() { return false; }
00679     bool IsSetupNeeded(OBMol &mol);
00695     bool GetAtomTypes(OBMol &mol);
00711     bool GetPartialCharges(OBMol &mol);
00712 
00713 
00714 
00719     bool GetCoordinates(OBMol &mol);
00721     bool UpdateCoordinates(OBMol &mol) {return GetCoordinates(mol); } 
00726     bool GetConformers(OBMol &mol);
00728     bool UpdateConformers(OBMol &mol) { return GetConformers(mol); } 
00733     bool SetCoordinates(OBMol &mol);
00738     bool SetConformers(OBMol &mol);
00748     OBGridData *GetGrid(double step, double padding, const char *type, double pchg);
00749 
00751     // Interacting groups                                                  //
00753       
00755 
00756 
00760     void AddIntraGroup(OBBitVec &group);
00765     void AddInterGroup(OBBitVec &group);
00773     void AddInterGroups(OBBitVec &group1, OBBitVec &group2);
00776     void ClearGroups(); 
00779     bool HasGroups(); 
00781  
00783     // Cut-off                                                             //
00785       
00787 
00788 
00791     void EnableCutOff(bool enable)
00792     {
00793       _cutoff = enable;
00794     }
00797     bool IsCutOffEnabled()
00798     {
00799       return _cutoff;
00800     }
00804     void SetVDWCutOff(double r)
00805     {
00806       _rvdw = r;
00807     }
00811     double GetVDWCutOff()
00812     {
00813       return _rvdw;
00814     }
00819     void SetElectrostaticCutOff(double r)
00820     {
00821       _rele = r;
00822     }
00826     double GetElectrostaticCutOff()
00827     {
00828       return _rele;
00829     }
00835     void SetUpdateFrequency(int f)
00836     {
00837       _pairfreq = f;
00838     }
00842     int GetUpdateFrequency()
00843     {
00844       return _pairfreq;
00845     } 
00850     void UpdatePairsSimple();
00851 
00852     //void UpdatePairsGroup(); TODO
00853 
00857     unsigned int GetNumPairs();
00861     void EnableAllPairs()
00862     {
00863       // TODO: OBBitVec doesn't seem to be allocating it's memory correctly
00864       //_vdwpairs.SetRangeOn(0, _numpairs-1);
00865       //_elepairs.SetRangeOn(0, _numpairs-1);
00866     }
00868  
00870     // Energy Evaluation                                                   //
00872       
00874 
00875 
00884     virtual double Energy(bool = true) { return 0.0f; }
00891     virtual double E_Bond(bool = true) { return 0.0f; }
00898     virtual double E_Angle(bool = true) { return 0.0f; }
00905     virtual double E_StrBnd(bool = true) { return 0.0f; }
00912     virtual double E_Torsion(bool = true) { return 0.0f; }
00919     virtual double E_OOP(bool = true) { return 0.0f; }
00926     virtual double E_VDW(bool = true) { return 0.0f; }
00933     virtual double E_Electrostatic(bool = true) { return 0.0f; }
00935      
00937     // Logging                                                             //
00939       
00941 
00942 
00944     void PrintTypes();
00948     void PrintFormalCharges();
00951     void PrintPartialCharges();
00954     void PrintVelocities();
00959     bool SetLogFile(std::ostream *pos);
00984     bool SetLogLevel(int level);
00987     int GetLogLevel() { return _loglvl; }
00991     void OBFFLog(std::string msg)
00992     {
00993       if (!_logos)
00994         return;
00995       
00996       *_logos << msg;
00997     }
01001     void OBFFLog(const char *msg)
01002     {
01003       if (!_logos)
01004         return;
01005       
01006       *_logos << msg;
01007     }
01009      
01011     // Structure Generation                                                //
01013       
01015 
01016 
01017     void DistanceGeometry();
01037     void SystematicRotorSearch(unsigned int geomSteps = 2500);
01055     int SystematicRotorSearchInitialize(unsigned int geomSteps = 2500);
01060     bool SystematicRotorSearchNextConformer(unsigned int geomSteps = 2500);
01081     void RandomRotorSearch(unsigned int conformers, unsigned int geomSteps = 2500);
01099     void RandomRotorSearchInitialize(unsigned int conformers, unsigned int geomSteps = 2500);
01104     bool RandomRotorSearchNextConformer(unsigned int geomSteps = 2500);
01126     void WeightedRotorSearch(unsigned int conformers, unsigned int geomSteps);
01127 
01129     // Energy Minimization                                                 //
01131       
01133 
01134 
01137     void SetLineSearchType(int type)
01138     {
01139       _linesearch = type;
01140     }
01144     int GetLineSearchType()
01145     {
01146       return _linesearch;
01147     }
01151     vector3 LineSearch(OBAtom *atom, vector3 &direction);
01165     double LineSearch(double *currentCoords, double *direction);
01178     double Newton2NumLineSearch(double *direction);
01184     void   LineSearchTakeStep(double *origCoords, double *direction, double step);
01200     void SteepestDescent(int steps, double econv = 1e-6f, int method = OBFF_ANALYTICAL_GRADIENT);
01227     void SteepestDescentInitialize(int steps = 1000, double econv = 1e-6f, int method = OBFF_ANALYTICAL_GRADIENT);
01242     bool SteepestDescentTakeNSteps(int n);
01258     void ConjugateGradients(int steps, double econv = 1e-6f, int method = OBFF_ANALYTICAL_GRADIENT);
01286     void ConjugateGradientsInitialize(int steps = 1000, double econv = 1e-6f, int method = OBFF_ANALYTICAL_GRADIENT);
01302     bool ConjugateGradientsTakeNSteps(int n);
01304     
01306     // Molecular Dynamics                                                  //
01308       
01310 
01311 
01313     void GenerateVelocities();
01333     void CorrectVelocities();
01349     void MolecularDynamicsTakeNSteps(int n, double T, double timestep = 0.001, int method = OBFF_ANALYTICAL_GRADIENT);
01351 
01353     // Constraints                                                         //
01355       
01357 
01358 
01361     OBFFConstraints& GetConstraints();
01365     void SetConstraints(OBFFConstraints& constraints);
01373     void SetFixAtom(int index);
01377     void UnsetFixAtom();
01386     void SetIgnoreAtom(int index);
01390     void UnsetIgnoreAtom();
01391    
01393     static bool IgnoreCalculation(int a, int b);
01395     static bool IgnoreCalculation(int a, int b, int c);
01397     static bool IgnoreCalculation(int a, int b, int c, int d);
01399 
01400  
01402     // Validation                                                          //
01404       
01406 
01407 
01408     bool DetectExplosion();
01410     vector3 ValidateLineSearch(OBAtom *atom, vector3 &direction);
01412     void ValidateSteepestDescent(int steps);
01414     void ValidateConjugateGradients(int steps);
01416     virtual bool Validate() { return false; }
01421     virtual bool ValidateGradients() { return false; }
01426     vector3 ValidateGradientError(vector3 &numgrad, vector3 &anagrad);
01428      
01430     // Vector Analysis                                                     //
01432       
01434 
01435 
01443     static double VectorBondDerivative(double *pos_a, double *pos_b, 
01444                                        double *force_a, double *force_b);
01448     static double VectorDistanceDerivative(const double* const pos_i, const double* const pos_j, 
01449                                            double *force_i, double *force_j);
01451     static double VectorLengthDerivative(vector3 &a, vector3 &b);
01452  
01463     static double VectorAngleDerivative(double *pos_a, double *pos_b, double *pos_c,
01464                                         double *force_a, double *force_b, double *force_c);
01466     static double VectorAngleDerivative(vector3 &a, vector3 &b, vector3 &c);
01479     static double VectorOOPDerivative(double *pos_a, double *pos_b, double *pos_c, double *pos_d,
01480                                       double *force_a, double *force_b, double *force_c, double *force_d);
01482     static double VectorOOPDerivative(vector3 &a, vector3 &b, vector3 &c, vector3 &d);
01494     static double VectorTorsionDerivative(double *pos_a, double *pos_b, double *pos_c, double *pos_d,
01495                                           double *force_a, double *force_b, double *force_c, double *force_d);
01497     static double VectorTorsionDerivative(vector3 &a, vector3 &b, vector3 &c, vector3 &d);
01498 
01504     static void VectorSubtract(double *i, double *j, double *result)
01505     {
01506       for (unsigned int c = 0; c < 3; ++c)
01507         result[c] = i[c] - j[c];
01508     }
01509     
01510     static void VectorSubtract(const double* const i, const double* const j, double *result)
01511     {
01512       for (unsigned int c = 0; c < 3; ++c)
01513         result[c] = i[c] - j[c];
01514     }
01515     
01521     static void VectorAdd(double *i, double *j, double *result)
01522     {
01523       for (unsigned int c = 0; c < 3; ++c)
01524         result[c] = i[c] + j[c];
01525     }
01526     
01532     static void VectorDivide(double *i, double n, double *result)
01533     {
01534       for (unsigned int c = 0; c < 3; ++c)
01535         result[c] = i[c] / n;
01536     }
01537     
01543     static void VectorMultiply(double *i, double n, double *result)
01544     {
01545       for (unsigned int c = 0; c < 3; ++c)
01546         result[c] = i[c] * n;
01547     }
01548     
01549     static void VectorMultiply(const double* const i, const double n, double *result)
01550     {
01551       for (unsigned int c = 0; c < 3; ++c)
01552         result[c] = i[c] * n;
01553     }
01554     
01559     static void VectorSelfMultiply(double *i, double n)
01560     {
01561       for (unsigned int c = 0; c < 3; ++c)
01562         i[c] *= n;
01563     }
01564     
01568     static void VectorNormalize(double *i)
01569     {  
01570       double length = VectorLength(i);
01571       for (unsigned int c = 0; c < 3; ++c)
01572         i[c] /= length;
01573     }
01574     
01579     static void VectorCopy(double *from, double *to)
01580     {  
01581       for (unsigned int c = 0; c < 3; ++c)
01582         to[c] = from[c];
01583     }
01584     
01589     static double VectorLength(double *i) 
01590     {
01591       return sqrt( i[0]*i[0] + i[1]*i[1] + i[2]*i[2] );
01592     }
01593     
01594     static double VectorDistance(double *pos_i, double *pos_j)
01595     {
01596       double ij[3];
01597       VectorSubtract(pos_i, pos_j, ij);
01598       const double rij = VectorLength(ij);
01599       return rij;
01600     }
01601     
01608     static double VectorAngle(double *i, double *j, double *k);
01609  
01617     static double VectorTorsion(double *i, double *j, double *k, double *l);
01618     
01626     static double VectorOOP(double *i, double *j, double *k, double *l);
01627 
01631     static void VectorClear(double *i) 
01632     {
01633       for (unsigned int c = 0; c < 3; ++c)
01634         i[c] = 0.0;
01635     }
01636    
01642     static double VectorDot(double *i, double *j)
01643     {
01644       double result = 0.0;
01645       // Written as a loop for vectorization
01646       // Loop will be unrolled by compiler otherwise
01647       for (unsigned int c = 0; c < 3; ++c)
01648         result += i[c]*j[c];
01649       return result;
01650     }
01651     
01657     static void VectorCross(double *i, double *j, double *result)
01658     {
01659       result[0] =   i[1]*j[2] - i[2]*j[1];
01660       result[1] = - i[0]*j[2] + i[2]*j[0];
01661       result[2] =   i[0]*j[1] - i[1]*j[0];
01662     }
01663     
01664     static void PrintVector(double *i)
01665     {
01666       std::cout << "<" << i[0] << ", " << i[1] << ", " << i[2] << ">" << std::endl;
01667     }
01669 
01670   }; // class OBForceField
01671 
01672 }// namespace OpenBabel
01673 
01674 #endif   // OB_FORCEFIELD_H
01675 

This file is part of the documentation for Open Babel, version 2.2.0.

Documentation copyright © 1998-2007, the Open Babel Developers.
Open Babel is hosted by: SourceForge Logo
Generated on Thu Jul 3 14:30:33 2008 by doxygen 1.5.6.