/src/openbabel/src/forcefields/forcefieldmmff94.h
Line | Count | Source |
1 | | /********************************************************************** |
2 | | forcefieldmmff94.h - MMFF94 |
3 | | |
4 | | Copyright (C) 2006 by Tim Vandermeersch <tim.vandermeersch@gmail.com> |
5 | | |
6 | | This file is part of the Open Babel project. |
7 | | For more information, see <http://openbabel.org/> |
8 | | |
9 | | This program is free software; you can redistribute it and/or modify |
10 | | it under the terms of the GNU General Public License as published by |
11 | | the Free Software Foundation version 2 of the License. |
12 | | |
13 | | This program is distributed in the hope that it will be useful, |
14 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | GNU General Public License for more details. |
17 | | ***********************************************************************/ |
18 | | |
19 | | #include <vector> |
20 | | #include <string> |
21 | | #include <map> |
22 | | |
23 | | #include <openbabel/parsmart.h> |
24 | | #include <openbabel/forcefield.h> |
25 | | #include <openbabel/base.h> |
26 | | #include <openbabel/mol.h> |
27 | | |
28 | | namespace OpenBabel |
29 | | { |
30 | | class OBFFBondCalculationMMFF94 : public OBFFCalculation2 |
31 | | { |
32 | | public: |
33 | | int bt; // bondtype (BTIJ) |
34 | | double kb, r0, rab, delta; |
35 | | |
36 | | template<bool> void Compute(); |
37 | | }; |
38 | | |
39 | | class OBFFAngleCalculationMMFF94 : public OBFFCalculation3 |
40 | | { |
41 | | public: |
42 | | int at; //angletype (ATIJK) |
43 | | bool linear; |
44 | | double ka, theta, theta0, delta; |
45 | | |
46 | | template<bool> void Compute(); |
47 | | }; |
48 | | |
49 | | class OBFFStrBndCalculationMMFF94 : public OBFFCalculation3 |
50 | | { |
51 | | public: |
52 | | int sbt; //strbndtype (SBTIJK) |
53 | | double kbaABC, kbaCBA, theta0, rab0, rbc0, delta_theta, delta_rab, delta_rbc; |
54 | | double theta, rab, rbc; |
55 | | double force_ab_a[3], force_ab_b[3], force_bc_b[3], force_bc_c[3]; |
56 | | double force_abc_a[3], force_abc_b[3], force_abc_c[3]; |
57 | | |
58 | | template<bool> void Compute(); |
59 | | }; |
60 | | |
61 | | class OBFFTorsionCalculationMMFF94 : public OBFFCalculation4 |
62 | | { |
63 | | public: |
64 | | int tt; //torsiontype (TTIJKL) |
65 | | double v1, v2, v3, tor, cosine; |
66 | | |
67 | | template<bool> void Compute(); |
68 | | }; |
69 | | |
70 | | class OBFFOOPCalculationMMFF94 : public OBFFCalculation4 |
71 | | { |
72 | | public: |
73 | | double koop, angle; |
74 | | |
75 | | template<bool> void Compute(); |
76 | | }; |
77 | | |
78 | | class OBFFVDWCalculationMMFF94 : public OBFFCalculation2 |
79 | | { |
80 | | public: |
81 | | int aDA, bDA; // hydrogen donor/acceptor (A=1, D=2, neither=0) |
82 | | double rab, epsilon, alpha_a, alpha_b, Na, Nb, Aa, Ab, Ga, Gb; |
83 | | double R_AB, R_AB7/*, erep, erep7, eattr*/; |
84 | | int pairIndex; // index into iteration using FOR_PAIRS_OF_MOL(..., _mol) |
85 | | |
86 | | template<bool> void Compute(); |
87 | | }; |
88 | | |
89 | | class OBFFElectrostaticCalculationMMFF94 : public OBFFCalculation2 |
90 | | { |
91 | | public: |
92 | | double qq, rab; |
93 | | int pairIndex; // index into iteration using FOR_PAIRS_OF_MOL(..., _mol) |
94 | | |
95 | | template<bool> void Compute(); |
96 | | }; |
97 | | |
98 | | // Class OBForceFieldMMFF94 |
99 | | // class introduction in forcefieldmmff94.cpp |
100 | | class OBForceFieldMMFF94: public OBForceField |
101 | | { |
102 | | protected: |
103 | | //! \return Parses the parameter file |
104 | | bool ParseParamFile() override; |
105 | | bool ParseParamProp(std::string &filename); |
106 | | bool ParseParamDef(std::string &filename); |
107 | | bool ParseParamBond(std::string &filename); |
108 | | bool ParseParamBndk(std::string &filename); |
109 | | bool ParseParamAngle(std::string &filename); |
110 | | bool ParseParamStrBnd(std::string &filename); |
111 | | bool ParseParamDfsb(std::string &filename); |
112 | | bool ParseParamOOP(std::string &filename); |
113 | | bool ParseParamTorsion(std::string &filename); |
114 | | bool ParseParamVDW(std::string &filename); |
115 | | bool ParseParamCharge(std::string &filename); |
116 | | bool ParseParamPbci(std::string &filename); |
117 | | //! detect which rings are aromatic |
118 | | bool PerceiveAromatic(); |
119 | | //! \return Get the MMFF94 atom type for atom |
120 | | int GetType(OBAtom *atom); |
121 | | //! \return Sets atomtypes to MMFF94 in _mol |
122 | | bool SetTypes() override; |
123 | | //! fill OBFFXXXCalculation vectors |
124 | | bool SetupCalculations() override; |
125 | | //! Setup pointers in OBFFXXXCalculation vectors |
126 | | bool SetupPointers() override; |
127 | | //! Sets formal charges |
128 | | bool SetFormalCharges() override; |
129 | | //! Sets partial charges |
130 | | bool SetPartialCharges() override; |
131 | | //! \return The row of the element atom in the periodic table |
132 | | int GetElementRow(OBAtom *atom); |
133 | | //! \return The bond type (BTIJ) |
134 | | int GetBondType(OBAtom* a, OBAtom* b); |
135 | | //! \return The angle type (ATIJK) |
136 | | int GetAngleType(OBAtom* a, OBAtom* b, OBAtom *c); |
137 | | //! \return The stretch-bend type (SBTIJK) |
138 | | int GetStrBndType(OBAtom* a, OBAtom* b, OBAtom *c); |
139 | | //! \return The torsion type (TTIJKL) |
140 | | int GetTorsionType(OBAtom* a, OBAtom* b, OBAtom *c, OBAtom *d); |
141 | | //! \return true if atomtype has sbmb set in mmffprop.par |
142 | | bool HasSbmbSet(int atomtype); |
143 | | //! \return true if atomtype has pilp set in mmffprop.par |
144 | | bool HasPilpSet(int atomtype); |
145 | | //! \return true if atomtype has arom set in mmffprop.par |
146 | | bool HasAromSet(int atomtype); |
147 | | //! \return true if atomtype has lin set in mmffprop.par |
148 | | bool HasLinSet(int atomtype); |
149 | | //! \return the crd value for the atomtype in mmffprop.par |
150 | | int GetCrd(int atomtype); |
151 | | //! \return the val value for the atomtype in mmffprop.par |
152 | | int GetVal(int atomtype); |
153 | | //! \return the mltb value for the atomtype in mmffprop.par |
154 | | int GetMltb(int atomtype); |
155 | | //! \return the level 2 equivalent atom type for type (mmffdef.par) |
156 | | int EqLvl2(int type); |
157 | | //! \return the level 3 equivalent atom type for type (mmffdef.par) |
158 | | int EqLvl3(int type); |
159 | | //! \return the level 4 equivalent atom type for type (mmffdef.par) |
160 | | int EqLvl4(int type); |
161 | | //! \return the level 5 equivalent atom type for type (mmffdef.par) |
162 | | int EqLvl5(int type); |
163 | | //! \return the canonical bond index |
164 | | unsigned int GetCXB(int type, int a, int b); |
165 | | //! \return the canonical angle index |
166 | | unsigned int GetCXA(int type, int a, int b, int c); |
167 | | //! \return the canonical stretch-bend index |
168 | | unsigned int GetCXS(int type, int a, int b, int c); |
169 | | //! \return the canonical out-of-plane index |
170 | | unsigned int GetCXO(int a, int b, int c, int d); |
171 | | //! \return the canonical torsion index |
172 | | unsigned int GetCXT(int type, int a, int b, int c, int d); |
173 | | //! \return the canonical bond-charge-increment index |
174 | | unsigned int GetCXQ(int type, int a, int b); |
175 | | //! \return the U value for the atom from table X page 631 |
176 | | double GetUParam(OBAtom* atom); |
177 | | //! \return the Z value for the atom from table VI page 628 |
178 | | double GetZParam(OBAtom* atom); |
179 | | //! \return the C value for the atom from table VI page 628 |
180 | | double GetCParam(OBAtom* atom); |
181 | | //! \return the V value for the atom from table X page 631 |
182 | | double GetVParam(OBAtom* atom); |
183 | | //! return the covalent radius from Blom and Haaland, value from etab if not available |
184 | | double GetCovalentRadius(OBAtom* a); |
185 | | //! return the bond length calculated with a modified version of the Schomaker-Stevenson rule |
186 | | double GetRuleBondLength(OBAtom* a, OBAtom* b); |
187 | | //! return the bond length from mmffbond.par, if not found, one is calculated with a modified version of the Schomaker-Stevenson rule |
188 | | double GetBondLength(OBAtom* a, OBAtom* b); |
189 | | |
190 | | //! Same as OBForceField::GetParameter, but takes (bond/angle/torsion) type in account and takes 0 as wildcart. |
191 | | OBFFParameter* GetParameter1Atom(int a, std::vector<OBFFParameter> ¶meter); |
192 | | OBFFParameter* GetParameter2Atom(int a, int b, std::vector<OBFFParameter> ¶meter); |
193 | | OBFFParameter* GetParameter3Atom(int a, int b, int c, std::vector<OBFFParameter> ¶meter); |
194 | | |
195 | | //! Same as OBForceField::GetParameter, but takes (bond/angle/torsion) type in account and takes 0 as wildcart. |
196 | | OBFFParameter* GetTypedParameter2Atom(int ffclass, int a, int b, std::vector<OBFFParameter> ¶meter); |
197 | | OBFFParameter* GetTypedParameter3Atom(int ffclass, int a, int b, int c, std::vector<OBFFParameter> ¶meter); |
198 | | OBFFParameter* GetTypedParameter4Atom(int ffclass, int a, int b, int c, int d, std::vector<OBFFParameter> ¶meter); |
199 | | |
200 | | |
201 | | // OBFFParameter vectors to contain the parameters |
202 | | std::vector<OBFFParameter> _ffbondparams; |
203 | | std::vector<OBFFParameter> _ffbndkparams; |
204 | | std::vector<OBFFParameter> _ffangleparams; |
205 | | std::vector<OBFFParameter> _ffstrbndparams; |
206 | | std::vector<OBFFParameter> _ffdfsbparams; |
207 | | std::vector<OBFFParameter> _fftorsionparams; |
208 | | std::vector<OBFFParameter> _ffoopparams; |
209 | | std::vector<OBFFParameter> _ffvdwparams; |
210 | | std::vector<OBFFParameter> _ffchgparams; |
211 | | std::vector<OBFFParameter> _ffpbciparams; |
212 | | std::vector<OBFFParameter> _ffdefparams; |
213 | | std::vector<OBFFParameter> _ffpropparams; |
214 | | OBBitVec _ffpropPilp; |
215 | | OBBitVec _ffpropArom; |
216 | | OBBitVec _ffpropLin; |
217 | | OBBitVec _ffpropSbmb; |
218 | | |
219 | | // OBFFXXXCalculationYYY vectors to contain the calculations |
220 | | std::vector<OBFFBondCalculationMMFF94> _bondcalculations; |
221 | | std::vector<OBFFAngleCalculationMMFF94> _anglecalculations; |
222 | | std::vector<OBFFStrBndCalculationMMFF94> _strbndcalculations; |
223 | | std::vector<OBFFTorsionCalculationMMFF94> _torsioncalculations; |
224 | | std::vector<OBFFOOPCalculationMMFF94> _oopcalculations; |
225 | | std::vector<OBFFVDWCalculationMMFF94> _vdwcalculations; |
226 | | std::vector<OBFFElectrostaticCalculationMMFF94> _electrostaticcalculations; |
227 | | |
228 | | bool mmff94s; |
229 | | |
230 | | public: |
231 | | //! Constructor |
232 | 12 | explicit OBForceFieldMMFF94(const char* ID, bool IsDefault=true) : OBForceField(ID, IsDefault) |
233 | 12 | { |
234 | 12 | _validSetup = false; |
235 | 12 | _init = false; |
236 | 12 | _rvdw = 7.0; |
237 | 12 | _rele = 15.0; |
238 | 12 | _epsilon = 1.0; // default electrostatics |
239 | 12 | _pairfreq = 15; |
240 | 12 | _cutoff = false; |
241 | 12 | _linesearch = LineSearchType::Newton2Num; |
242 | 12 | _gradientPtr = nullptr; |
243 | 12 | _grad1 = nullptr; |
244 | 12 | if (!strncmp(ID, "MMFF94s", 7)) { |
245 | 6 | mmff94s = true; |
246 | 6 | _parFile = std::string("mmff94s.ff"); |
247 | 6 | } else { |
248 | 6 | mmff94s = false; |
249 | 6 | _parFile = std::string("mmff94.ff"); |
250 | 6 | } |
251 | 12 | } |
252 | | |
253 | | //! Destructor |
254 | | virtual ~OBForceFieldMMFF94(); |
255 | | |
256 | | //! Assignment |
257 | | OBForceFieldMMFF94 &operator = (OBForceFieldMMFF94 &); |
258 | | |
259 | | //!Clone the current instance. May be desirable in multithreaded environments |
260 | | OBForceFieldMMFF94* MakeNewInstance() override |
261 | 0 | { |
262 | 0 | return new OBForceFieldMMFF94(_id, false); |
263 | 0 | } |
264 | | |
265 | | //! Get the description for this force field |
266 | | const char* Description() override |
267 | 0 | { |
268 | 0 | if (mmff94s) |
269 | 0 | return "MMFF94s force field."; |
270 | 0 | else |
271 | 0 | return "MMFF94 force field."; |
272 | 0 | } |
273 | | |
274 | | //! Get the unit in which the energy is expressed |
275 | | std::string GetUnit() override |
276 | 0 | { |
277 | 0 | return std::string("kcal/mol"); |
278 | 0 | } |
279 | | |
280 | | //! \return that analytical gradients are implemented for MMFF94 |
281 | 0 | bool HasAnalyticalGradients() override { return true; } |
282 | | |
283 | | //! Returns total energy |
284 | | double Energy(bool gradients = true) override; |
285 | | //! Returns the bond stretching energy |
286 | | template<bool> double E_Bond(); |
287 | | double E_Bond(bool gradients = true) override |
288 | 0 | { |
289 | 0 | return gradients ? E_Bond<true>() : E_Bond<false>(); |
290 | 0 | } |
291 | | //! Returns the angle bending energy |
292 | | template<bool> double E_Angle(); |
293 | | double E_Angle(bool gradients = true) override |
294 | 0 | { |
295 | 0 | return gradients ? E_Angle<true>() : E_Angle<false>(); |
296 | 0 | } |
297 | | //! Returns the stretch-bend energy |
298 | | template<bool> double E_StrBnd(); |
299 | | double E_StrBnd(bool gradients = true) override |
300 | 0 | { |
301 | 0 | return gradients ? E_StrBnd<true>() : E_StrBnd<false>(); |
302 | 0 | } |
303 | | //! Returns the torsional energy |
304 | | template<bool> double E_Torsion(); |
305 | | double E_Torsion(bool gradients = true) override |
306 | 0 | { |
307 | 0 | return gradients ? E_Torsion<true>() : E_Torsion<false>(); |
308 | 0 | } |
309 | | //! Returns the out-of-plane bending energy |
310 | | template<bool> double E_OOP(); |
311 | | double E_OOP(bool gradients = true) override |
312 | 0 | { |
313 | 0 | return gradients ? E_OOP<true>() : E_OOP<false>(); |
314 | 0 | } |
315 | | //! Returns the Van der Waals energy (Buckingham potential) |
316 | | template<bool> double E_VDW(); |
317 | | double E_VDW(bool gradients = true) override |
318 | 0 | { |
319 | 0 | return gradients ? E_VDW<true>() : E_VDW<false>(); |
320 | 0 | } |
321 | | //! Returns the dipole-dipole interaction energy |
322 | | template<bool> double E_Electrostatic(); |
323 | | double E_Electrostatic(bool gradients = true) override |
324 | 0 | { |
325 | 0 | return gradients ? E_Electrostatic<true>() : E_Electrostatic<false>(); |
326 | 0 | } |
327 | | |
328 | | //! Validate MMFF94 using validation suite |
329 | | bool Validate() override; |
330 | | //! Compare and print the numerical and analytical gradients |
331 | | bool ValidateGradients() override; |
332 | | |
333 | | }; // class OBForceFieldMM2 |
334 | | |
335 | | }// namespace OpenBabel |
336 | | |
337 | | //! \file forcefieldmmff94.h |
338 | | //! \brief MMFF94 force field |