RDKit
Open-source cheminformatics and machine learning.
ForceField.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2004-2006 Rational Discovery LLC
3 //
4 // @@ All Rights Reserved @@
5 // This file is part of the RDKit.
6 // The contents are covered by the terms of the BSD license
7 // which is included in the file license.txt, found at the root
8 // of the RDKit source tree.
9 //
10 #include <RDGeneral/export.h>
11 #ifndef __RD_FORCEFIELD_H__
12 #define __RD_FORCEFIELD_H__
13 
14 #include <vector>
15 #include <boost/smart_ptr.hpp>
16 #include <boost/foreach.hpp>
17 #include <Geometry/point.h>
19 
20 namespace RDKit {
21 namespace ForceFieldsHelper {
24  const RDGeom::PointPtrVect &pos, unsigned int idx1, unsigned int idx2,
25  unsigned int idx3, unsigned int idx4, double *dihedral = nullptr,
26  double *cosPhi = nullptr, RDGeom::Point3D r[4] = nullptr,
27  RDGeom::Point3D t[2] = nullptr, double d[2] = nullptr);
29  const double *pos, unsigned int idx1, unsigned int idx2, unsigned int idx3,
30  unsigned int idx4, double *dihedral = nullptr, double *cosPhi = nullptr,
31  RDGeom::Point3D r[4] = nullptr, RDGeom::Point3D t[2] = nullptr,
32  double d[2] = nullptr);
35  const RDGeom::Point3D *p3, const RDGeom::Point3D *p4,
36  double *dihedral = nullptr, double *cosPhi = nullptr,
37  RDGeom::Point3D r[4] = nullptr, RDGeom::Point3D t[2] = nullptr,
38  double d[2] = nullptr);
39 } // namespace ForceFieldsHelper
40 } // namespace RDKit
41 
42 namespace ForceFields {
43 class ForceFieldContrib;
44 typedef std::vector<int> INT_VECT;
45 typedef boost::shared_ptr<const ForceFieldContrib> ContribPtr;
46 typedef std::vector<ContribPtr> ContribPtrVect;
47 
48 //-------------------------------------------------------
49 //! A class to store forcefields and handle minimization
50 /*!
51  A force field is used like this (schematically):
52 
53  \verbatim
54  ForceField ff;
55 
56  // add contributions:
57  for contrib in contribs:
58  ff.contribs().push_back(contrib);
59 
60  // set up the points:
61  for positionPtr in positions:
62  ff.positions().push_back(point);
63 
64  // initialize:
65  ff.initialize()
66 
67  // and minimize:
68  needsMore = ff.minimize();
69 
70  \endverbatim
71 
72  <b>Notes:</b>
73  - The ForceField owns its contributions, which are stored using smart
74  pointers.
75  - Distance calculations are currently lazy; the full distance matrix is
76  never generated. In systems where the distance matrix is not sparse,
77  this is almost certainly inefficient.
78 
79 */
81  public:
82  //! construct with a dimension
83  ForceField(unsigned int dimension = 3)
84  : d_dimension(dimension)
85  {};
86 
88 
89  //! copy ctor, copies contribs.
90  ForceField(const ForceField &other);
91 
92  //! does initialization
93  void initialize();
94 
95  //! calculates and returns the energy (in kcal/mol) based on existing
96  // positions in the forcefield
97  /*!
98 
99  \return the current energy
100 
101  <b>Note:</b>
102  This function is less efficient than calcEnergy with postions passed in as
103  double *
104  the positions need to be converted to double * here
105  */
106  double calcEnergy(std::vector<double> *contribs = nullptr) const;
107 
108  // these next two aren't const because they may update our
109  // distance matrix
110 
111  //! calculates and returns the energy of the position passed in
112  /*!
113  \param pos an array of doubles. Should be \c 3*this->numPoints() long.
114 
115  \return the current energy
116 
117  <b>Side effects:</b>
118  - Calling this resets the current distance matrix
119  - The individual contributions may further update the distance matrix
120  */
121  double calcEnergy(double *pos);
122 
123  //! calculates the gradient of the energy at the current position
124  /*!
125 
126  \param forces an array of doubles. Should be \c 3*this->numPoints() long.
127 
128  <b>Note:</b>
129  This function is less efficient than calcGrad with positions passed in
130  the positions need to be converted to double * here
131  */
132  void calcGrad(double *forces) const;
133 
134  //! calculates the gradient of the energy at the provided position
135  /*!
136 
137  \param pos an array of doubles. Should be \c 3*this->numPoints() long.
138  \param forces an array of doubles. Should be \c 3*this->numPoints() long.
139 
140  <b>Side effects:</b>
141  - The individual contributions may modify the distance matrix
142  */
143  void calcGrad(double *pos, double *forces);
144 
145  //! minimizes the energy of the system by following gradients
146  /*!
147  \param maxIts the maximum number of iterations to try
148  \param forceTol the convergence criterion for forces
149  \param energyTol the convergence criterion for energies
150 
151  \return an integer value indicating whether or not the convergence
152  criteria were achieved:
153  - 0: indicates success
154  - 1: the minimization did not converge in \c maxIts iterations.
155  */
156  int minimize(unsigned int snapshotFreq, RDKit::SnapshotVect *snapshotVect,
157  unsigned int maxIts = 200, double forceTol = 1e-4,
158  double energyTol = 1e-6);
159 
160  //! minimizes the energy of the system by following gradients
161  /*!
162  \param maxIts the maximum number of iterations to try
163  \param forceTol the convergence criterion for forces
164  \param energyTol the convergence criterion for energies
165  \param snapshotFreq a snapshot of the minimization trajectory
166  will be stored after as many steps as indicated
167  through this parameter; defaults to 0 (no
168  trajectory stored)
169  \param snapshotVect a pointer to a std::vector<Snapshot> where
170  coordinates and energies will be stored
171 
172  \return an integer value indicating whether or not the convergence
173  criteria were achieved:
174  - 0: indicates success
175  - 1: the minimization did not converge in \c maxIts iterations.
176  */
177  int minimize(unsigned int maxIts = 200, double forceTol = 1e-4,
178  double energyTol = 1e-6);
179 
180  // ---------------------------
181  // setters and getters
182 
183  //! returns a reference to our points (a PointPtrVect)
184  RDGeom::PointPtrVect &positions() { return d_positions; };
185  const RDGeom::PointPtrVect &positions() const { return d_positions; };
186 
187  //! returns a reference to our contribs (a ContribPtrVect)
188  ContribPtrVect &contribs() { return d_contribs; };
189  const ContribPtrVect &contribs() const { return d_contribs; };
190 
191  //! returns the distance between two points
192  /*!
193  \param i point index
194  \param j point index
195  \param pos (optional) If this argument is provided, it will be used
196  to provide the positions of points. \c pos should be
197  \c 3*this->numPoints() long.
198 
199  \return the distance
200 
201  <b>Side effects:</b>
202  - if the distance between i and j has not previously been calculated,
203  our internal distance matrix will be updated.
204  */
205  double distance(unsigned int i, unsigned int j, double *pos = nullptr);
206 
207  //! returns the distance between two points
208  /*!
209  \param i point index
210  \param j point index
211  \param pos (optional) If this argument is provided, it will be used
212  to provide the positions of points. \c pos should be
213  \c 3*this->numPoints() long.
214 
215  \return the distance
216 
217  <b>Note:</b>
218  The internal distance matrix is not updated in this case
219  */
220  double distance(unsigned int i, unsigned int j, double *pos = nullptr) const;
221 
222  //! returns the dimension of the forcefield
223  unsigned int dimension() const { return d_dimension; }
224 
225  //! returns the number of points the ForceField is handling
226  unsigned int numPoints() const { return d_numPoints; };
227 
228  INT_VECT &fixedPoints() { return d_fixedPoints; };
229  const INT_VECT &fixedPoints() const { return d_fixedPoints; };
230 
231  protected:
232  unsigned int d_dimension;
233  bool df_init{false}; //!< whether or not we've been initialized
234  unsigned int d_numPoints{0}; //!< the number of active points
235  double *dp_distMat{nullptr}; //!< our internal distance matrix
236  RDGeom::PointPtrVect d_positions; //!< pointers to the points we're using
237  ContribPtrVect d_contribs; //!< contributions to the energy
239  unsigned int d_matSize = 0;
240  //! scatter our positions into an array
241  /*!
242  \param pos should be \c 3*this->numPoints() long;
243  */
244  void scatter(double *pos) const;
245 
246  //! update our positions from an array
247  /*!
248  \param pos should be \c 3*this->numPoints() long;
249  */
250  void gather(double *pos);
251 
252  //! initializes our internal distance matrix
254 };
255 } // namespace ForceFields
256 #endif
A class to store forcefields and handle minimization.
Definition: ForceField.h:80
ForceField(const ForceField &other)
copy ctor, copies contribs.
void initDistanceMatrix()
initializes our internal distance matrix
unsigned int dimension() const
returns the dimension of the forcefield
Definition: ForceField.h:223
void scatter(double *pos) const
scatter our positions into an array
double calcEnergy(double *pos)
calculates and returns the energy of the position passed in
const RDGeom::PointPtrVect & positions() const
Definition: ForceField.h:185
double calcEnergy(std::vector< double > *contribs=nullptr) const
calculates and returns the energy (in kcal/mol) based on existing
const INT_VECT & fixedPoints() const
Definition: ForceField.h:229
void calcGrad(double *forces) const
calculates the gradient of the energy at the current position
ForceField(unsigned int dimension=3)
construct with a dimension
Definition: ForceField.h:83
unsigned int d_dimension
Definition: ForceField.h:229
void calcGrad(double *pos, double *forces)
calculates the gradient of the energy at the provided position
INT_VECT & fixedPoints()
Definition: ForceField.h:228
ContribPtrVect d_contribs
contributions to the energy
Definition: ForceField.h:237
double distance(unsigned int i, unsigned int j, double *pos=nullptr)
returns the distance between two points
int minimize(unsigned int maxIts=200, double forceTol=1e-4, double energyTol=1e-6)
minimizes the energy of the system by following gradients
void initialize()
does initialization
unsigned int numPoints() const
returns the number of points the ForceField is handling
Definition: ForceField.h:226
RDGeom::PointPtrVect d_positions
pointers to the points we're using
Definition: ForceField.h:236
RDGeom::PointPtrVect & positions()
returns a reference to our points (a PointPtrVect)
Definition: ForceField.h:184
void gather(double *pos)
update our positions from an array
double distance(unsigned int i, unsigned int j, double *pos=nullptr) const
returns the distance between two points
const ContribPtrVect & contribs() const
Definition: ForceField.h:189
ContribPtrVect & contribs()
returns a reference to our contribs (a ContribPtrVect)
Definition: ForceField.h:188
int minimize(unsigned int snapshotFreq, RDKit::SnapshotVect *snapshotVect, unsigned int maxIts=200, double forceTol=1e-4, double energyTol=1e-6)
minimizes the energy of the system by following gradients
#define RDKIT_FORCEFIELD_EXPORT
Definition: export.h:294
std::vector< int > INT_VECT
Definition: ForceField.h:43
boost::shared_ptr< const ForceFieldContrib > ContribPtr
Definition: ForceField.h:45
std::vector< ContribPtr > ContribPtrVect
Definition: ForceField.h:46
std::vector< RDGeom::Point * > PointPtrVect
Definition: point.h:502
void RDKIT_FORCEFIELD_EXPORT normalizeAngleDeg(double &angleDeg)
void RDKIT_FORCEFIELD_EXPORT computeDihedral(const RDGeom::PointPtrVect &pos, unsigned int idx1, unsigned int idx2, unsigned int idx3, unsigned int idx4, double *dihedral=nullptr, double *cosPhi=nullptr, RDGeom::Point3D r[4]=nullptr, RDGeom::Point3D t[2]=nullptr, double d[2]=nullptr)
Std stuff.
Definition: Abbreviations.h:17
std::vector< Snapshot > SnapshotVect
Definition: Snapshot.h:19