48#include "nonbonded/Morse.hpp"
54#include "types/MorseInteractionType.hpp"
55#include "utils/simError.h"
61 Morse::Morse() : initialized_(false), forceField_(NULL), name_(
"Morse") {}
63 void Morse::initialize() {
69 Mtids.resize(forceField_->getNAtomType(), -1);
71 ForceField::NonBondedInteractionTypeContainer* nbiTypes =
72 forceField_->getNonBondedInteractionTypes();
73 ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
74 ForceField::NonBondedInteractionTypeContainer::KeyType keys;
75 NonBondedInteractionType* nbt;
77 for (nbt = nbiTypes->beginType(j); nbt != NULL;
78 nbt = nbiTypes->nextType(j)) {
80 keys = nbiTypes->getKeys(j);
81 AtomType* at1 = forceField_->getAtomType(keys[0]);
83 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
84 "Morse::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 "Morse::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 MorseInteractionType* mit =
dynamic_cast<MorseInteractionType*
>(nbt);
107 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
108 "Morse::initialize could not convert NonBondedInteractionType\n"
109 "\tto MorseInteractionType for %s - %s interaction.\n",
110 at1->getName().c_str(), at2->getName().c_str());
111 painCave.severity = OPENMD_ERROR;
112 painCave.isFatal = 1;
116 RealType De = mit->getD();
117 RealType Re = mit->getR();
118 RealType beta = mit->getBeta();
120 MorseType variant = mit->getInteractionType();
121 addExplicitInteraction(at1, at2, De, Re, beta, variant);
127 void Morse::addExplicitInteraction(AtomType* atype1, AtomType* atype2,
128 RealType De, RealType Re, RealType beta,
130 MorseInteractionData mixer;
136 int atid1 = atype1->getIdent();
137 int atid2 = atype2->getIdent();
141 pair<set<int>::iterator,
bool> ret;
142 ret = Mtypes.insert(atid1);
143 if (ret.second ==
false) {
145 mtid1 = Mtids[atid1];
152 ret = Mtypes.insert(atid2);
153 if (ret.second ==
false) {
155 mtid2 = Mtids[atid2];
163 MixingMap.resize(nM_);
164 MixingMap[mtid1].resize(nM_);
165 MixingMap[mtid1][mtid2] = mixer;
166 if (mtid2 != mtid1) {
167 MixingMap[mtid2].resize(nM_);
168 MixingMap[mtid2][mtid1] = mixer;
172 void Morse::calcForce(InteractionData& idat) {
173 if (!initialized_) initialize();
175 MorseInteractionData& mixer =
176 MixingMap[Mtids[idat.atid1]][Mtids[idat.atid2]];
178 RealType myPot = 0.0;
179 RealType myPotC = 0.0;
180 RealType myDeriv = 0.0;
181 RealType myDerivC = 0.0;
183 RealType De = mixer.De;
184 RealType Re = mixer.Re;
185 RealType beta = mixer.beta;
186 MorseType variant = mixer.variant;
190 RealType expt = -beta * (idat.rij - Re);
191 RealType expfnc = exp(expt);
192 RealType expfnc2 = expfnc * expfnc;
194 RealType exptC = 0.0;
195 RealType expfncC = 0.0;
196 RealType expfnc2C = 0.0;
198 if (idat.shiftedPot || idat.shiftedForce) {
199 exptC = -beta * (idat.rcut - Re);
200 expfncC = exp(exptC);
201 expfnc2C = expfncC * expfncC;
206 myPot = De * (expfnc2 - 2.0 * expfnc);
207 myDeriv = 2.0 * De * beta * (expfnc - expfnc2);
209 if (idat.shiftedPot) {
210 myPotC = De * (expfnc2C - 2.0 * expfncC);
212 }
else if (idat.shiftedForce) {
213 myPotC = De * (expfnc2C - 2.0 * expfncC);
214 myDerivC = 2.0 * De * beta * (expfncC - expfnc2C);
215 myPotC += myDerivC * (idat.rij - idat.rcut);
224 myPot = De * expfnc2;
225 myDeriv = -2.0 * De * beta * expfnc2;
227 if (idat.shiftedPot) {
228 myPotC = De * expfnc2C;
230 }
else if (idat.shiftedForce) {
231 myPotC = De * expfnc2C;
232 myDerivC = -2.0 * De * beta * expfnc2C;
233 myPotC += myDerivC * (idat.rij - idat.rcut);
247 RealType pot_temp = idat.vdwMult * (myPot - myPotC);
248 idat.vpair += pot_temp;
250 RealType dudr = idat.sw * idat.vdwMult * (myDeriv - myDerivC);
255 idat.f1 += idat.d * dudr / idat.rij;
260 RealType Morse::getSuggestedCutoffRadius(pair<AtomType*, AtomType*> atypes) {
261 if (!initialized_) initialize();
263 int atid1 = atypes.first->getIdent();
264 int atid2 = atypes.second->getIdent();
265 int mtid1 = Mtids[atid1];
266 int mtid2 = Mtids[atid2];
268 if (mtid1 == -1 || mtid2 == -1)
271 MorseInteractionData mixer = MixingMap[mtid1][mtid2];
272 RealType Re = mixer.Re;
273 RealType beta = mixer.beta;
278 return (4.9 + beta * Re) / beta;
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.