48#include "nonbonded/Buckingham.hpp"
54#include "types/BuckinghamInteractionType.hpp"
55#include "utils/simError.h"
61 Buckingham::Buckingham() :
62 initialized_(false), forceField_(NULL), name_(
"Buckingham") {}
64 void Buckingham::initialize() {
68 Btids.resize(forceField_->getNAtomType(), -1);
70 ForceField::NonBondedInteractionTypeContainer* nbiTypes =
71 forceField_->getNonBondedInteractionTypes();
72 ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
73 ForceField::NonBondedInteractionTypeContainer::KeyType keys;
74 NonBondedInteractionType* nbt;
77 for (nbt = nbiTypes->beginType(j); nbt != NULL;
78 nbt = nbiTypes->nextType(j)) {
79 if (nbt->isBuckingham()) {
80 keys = nbiTypes->getKeys(j);
81 AtomType* at1 = forceField_->getAtomType(keys[0]);
83 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
84 "Buckingham::initialize could not find AtomType %s\n"
85 "\tto for for %s - %s interaction.\n",
86 keys[0].c_str(), keys[0].c_str(), keys[1].c_str());
87 painCave.severity = OPENMD_ERROR;
92 AtomType* at2 = forceField_->getAtomType(keys[1]);
94 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
95 "Buckingham::initialize could not find AtomType %s\n"
96 "\tfor %s - %s nonbonded interaction.\n",
97 keys[1].c_str(), keys[0].c_str(), keys[1].c_str());
98 painCave.severity = OPENMD_ERROR;
103 int atid1 = at1->getIdent();
104 if (Btids[atid1] == -1) {
105 btid1 = Btypes.size();
106 Btypes.insert(atid1);
107 Btids[atid1] = btid1;
109 int atid2 = at2->getIdent();
110 if (Btids[atid2] == -1) {
111 btid2 = Btypes.size();
112 Btypes.insert(atid2);
113 Btids[atid2] = btid2;
116 BuckinghamInteractionType* bit =
117 dynamic_cast<BuckinghamInteractionType*
>(nbt);
120 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
121 "Buckingham::initialize could not convert "
122 "NonBondedInteractionType\n"
123 "\tto BuckinghamInteractionType for %s - %s interaction.\n",
124 at1->getName().c_str(), at2->getName().c_str());
125 painCave.severity = OPENMD_ERROR;
126 painCave.isFatal = 1;
130 RealType A = bit->getA();
131 RealType B = bit->getB();
132 RealType C = bit->getC();
134 BuckinghamType variant = bit->getInteractionType();
135 addExplicitInteraction(at1, at2, A, B, C, variant);
141 void Buckingham::addExplicitInteraction(AtomType* atype1, AtomType* atype2,
142 RealType A, RealType B, RealType C,
144 BuckinghamInteractionData mixer;
150 int btid1 = Btids[atype1->getIdent()];
151 int btid2 = Btids[atype2->getIdent()];
152 int nB = Btypes.size();
154 MixingMap.resize(nB);
155 MixingMap[btid1].resize(nB);
157 MixingMap[btid1][btid2] = mixer;
158 if (btid2 != btid1) {
159 MixingMap[btid2].resize(nB);
160 MixingMap[btid2][btid1] = mixer;
164 void Buckingham::addExplicitInteraction(AtomType* atype1, AtomType* atype2,
165 RealType A, RealType B, RealType C,
166 RealType sigma, RealType epsilon,
168 BuckinghamInteractionData mixer;
173 mixer.epsilon = epsilon;
176 int btid1 = Btids[atype1->getIdent()];
177 int btid2 = Btids[atype2->getIdent()];
178 int nB = Btypes.size();
180 MixingMap.resize(nB);
181 MixingMap[btid1].resize(nB);
183 MixingMap[btid1][btid2] = mixer;
184 if (btid2 != btid1) {
185 MixingMap[btid2].resize(nB);
186 MixingMap[btid2][btid1] = mixer;
190 void Buckingham::calcForce(InteractionData& idat) {
191 if (!initialized_) initialize();
193 BuckinghamInteractionData& mixer =
194 MixingMap[Btids[idat.atid1]][Btids[idat.atid2]];
196 RealType myPot = 0.0;
197 RealType myPotC = 0.0;
198 RealType myDeriv = 0.0;
199 RealType myDerivC = 0.0;
201 RealType A = mixer.A;
202 RealType B = mixer.B;
203 RealType C = mixer.C;
204 RealType sigma = mixer.sigma;
205 RealType epsilon = mixer.epsilon;
206 BuckinghamType variant = mixer.variant;
208 RealType expt = -B * idat.rij;
209 RealType expfnc = exp(expt);
210 RealType fnc6 = 1.0 / pow(idat.rij, 6);
211 RealType fnc7 = fnc6 / idat.rij;
213 RealType exptC = 0.0;
214 RealType expfncC = 0.0;
215 RealType fnc6C = 0.0;
216 RealType fnc7C = 0.0;
218 if (idat.shiftedPot || idat.shiftedForce) {
219 exptC = -B * idat.rcut;
220 expfncC = exp(exptC);
221 fnc6C = 1.0 / pow(idat.rcut, 6);
222 fnc7C = fnc6C / idat.rcut;
226 case btTraditional: {
228 myPot = A * expfnc - C * fnc6;
229 myDeriv = -A * B * expfnc + C * fnc7;
231 if (idat.shiftedPot) {
232 myPotC = A * expfncC - C * fnc6C;
234 }
else if (idat.shiftedForce) {
235 myPotC = A * expfncC - C * fnc6C;
236 myDerivC = -A * B * expfncC + C * fnc7C;
237 myPotC += myDerivC * (idat.rij - idat.rcut);
245 RealType s6 = pow(sigma, 6);
246 RealType s7 = pow(sigma, 7);
247 RealType fnc30 = pow(sigma / idat.rij, 30);
248 RealType fnc31 = fnc30 * sigma / idat.rij;
249 RealType fnc30C = 0.0;
250 RealType fnc31C = 0.0;
252 if (idat.shiftedPot || idat.shiftedForce) {
253 fnc30C = pow(sigma / idat.rcut, 30);
254 fnc31C = fnc30C * sigma / idat.rcut;
258 myPot = A * expfnc - C * fnc6 + 4.0 * epsilon * (fnc30 - s6 * fnc6);
259 myDeriv = -A * B * expfnc + C * fnc7 +
260 4.0 * epsilon * (-30.0 * fnc31 + 6.0 * s7 * fnc7) / sigma;
262 if (idat.shiftedPot) {
264 A * expfncC - C * fnc6C + 4.0 * epsilon * (fnc30C - s6 * fnc6C);
266 }
else if (idat.shiftedForce) {
268 A * expfncC - C * fnc6C + 4.0 * epsilon * (fnc30C - s6 * fnc6C);
269 myDeriv = -A * B * expfncC + C * fnc7C +
270 4.0 * epsilon * (-30.0 * fnc31C + 6.0 * s7 * fnc7C) / sigma;
271 myPotC += myDerivC * (idat.rij - idat.rcut);
285 RealType pot_temp = idat.vdwMult * (myPot - myPotC);
286 idat.vpair += pot_temp;
288 RealType dudr = idat.sw * idat.vdwMult * (myDeriv - myDerivC);
293 idat.f1 += idat.d * dudr / idat.rij;
298 RealType Buckingham::getSuggestedCutoffRadius(
299 pair<AtomType*, AtomType*> atypes) {
300 if (!initialized_) initialize();
302 int atid1 = atypes.first->getIdent();
303 int atid2 = atypes.second->getIdent();
304 int btid1 = Btids[atid1];
305 int btid2 = Btids[atid2];
307 if (btid1 == -1 || btid2 == -1)
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
@ VANDERWAALS_FAMILY
Long-range dispersion and short-range pauli repulsion.