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