48#include "nonbonded/RepulsivePower.hpp"
54#include "types/RepulsivePowerInteractionType.hpp"
55#include "utils/simError.h"
61 RepulsivePower::RepulsivePower() :
62 initialized_(false), forceField_(NULL), name_(
"RepulsivePower") {}
64 void RepulsivePower::initialize() {
68 RPtids.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->isRepulsivePower()) {
80 keys = nbiTypes->getKeys(j);
81 AtomType* at1 = forceField_->getAtomType(keys[0]);
83 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
84 "RepulsivePower::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 "RepulsivePower::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 (RPtids[atid1] == -1) {
105 rptid1 = RPtypes.size();
106 RPtypes.insert(atid1);
107 RPtids[atid1] = rptid1;
109 int atid2 = at2->getIdent();
110 if (RPtids[atid2] == -1) {
111 rptid2 = RPtypes.size();
112 RPtypes.insert(atid2);
113 RPtids[atid2] = rptid2;
116 RepulsivePowerInteractionType* rpit =
117 dynamic_cast<RepulsivePowerInteractionType*
>(nbt);
120 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
121 "RepulsivePower::initialize could not convert "
122 "NonBondedInteractionType\n"
123 "\tto RepulsivePowerInteractionType 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 sigma = rpit->getSigma();
131 RealType epsilon = rpit->getEpsilon();
132 int nRep = rpit->getNrep();
134 addExplicitInteraction(at1, at2, sigma, epsilon, nRep);
140 void RepulsivePower::addExplicitInteraction(AtomType* atype1,
141 AtomType* atype2, RealType sigma,
142 RealType epsilon,
int nRep) {
143 RPInteractionData mixer;
145 mixer.epsilon = epsilon;
146 mixer.sigmai = 1.0 / mixer.sigma;
149 int nRP = RPtypes.size();
150 int atid1 = atype1->getIdent();
151 int atid2 = atype2->getIdent();
154 pair<set<int>::iterator,
bool> ret;
155 ret = RPtypes.insert(atid1);
156 if (ret.second ==
false) {
158 rptid1 = RPtids[atid1];
166 ret = RPtypes.insert(atid2);
167 if (ret.second ==
false) {
169 rptid2 = RPtids[atid2];
177 MixingMap.resize(nRP);
178 MixingMap[rptid1].resize(nRP);
180 MixingMap[rptid1][rptid2] = mixer;
181 if (rptid2 != rptid1) {
182 MixingMap[rptid2].resize(nRP);
183 MixingMap[rptid2][rptid1] = mixer;
187 void RepulsivePower::calcForce(InteractionData& idat) {
188 if (!initialized_) initialize();
190 RPInteractionData& mixer =
191 MixingMap[RPtids[idat.atid1]][RPtids[idat.atid2]];
192 RealType sigmai = mixer.sigmai;
193 RealType epsilon = mixer.epsilon;
194 int nRep = mixer.nRep;
198 RealType myPot = 0.0;
199 RealType myPotC = 0.0;
200 RealType myDeriv = 0.0;
201 RealType myDerivC = 0.0;
203 ros = idat.rij * sigmai;
205 getNRepulsionFunc(ros, nRep, myPot, myDeriv);
207 if (idat.shiftedPot) {
208 rcos = idat.rcut * sigmai;
209 getNRepulsionFunc(rcos, nRep, myPotC, myDerivC);
211 }
else if (idat.shiftedForce) {
212 rcos = idat.rcut * sigmai;
213 getNRepulsionFunc(rcos, nRep, myPotC, myDerivC);
214 myPotC = myPotC + myDerivC * (idat.rij - idat.rcut) * sigmai;
220 RealType pot_temp = idat.vdwMult * epsilon * (myPot - myPotC);
221 idat.vpair += pot_temp;
224 idat.sw * idat.vdwMult * epsilon * (myDeriv - myDerivC) * sigmai;
229 idat.f1 += idat.d * dudr / idat.rij;
234 void RepulsivePower::getNRepulsionFunc(
const RealType& r,
int& n,
235 RealType& pot, RealType& deriv) {
236 RealType ri = 1.0 / r;
237 RealType rin = pow(ri, n);
238 RealType rin1 = rin * ri;
246 RealType RepulsivePower::getSuggestedCutoffRadius(
247 pair<AtomType*, AtomType*> atypes) {
248 if (!initialized_) initialize();
250 int atid1 = atypes.first->getIdent();
251 int atid2 = atypes.second->getIdent();
252 int rptid1 = RPtids[atid1];
253 int rptid2 = RPtids[atid2];
255 if (rptid1 == -1 || rptid2 == -1)
258 RPInteractionData mixer = MixingMap[rptid1][rptid2];
259 return 2.5 * mixer.sigma;
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.