45#include "nonbonded/InversePowerSeries.hpp"
51#include "types/InversePowerSeriesInteractionType.hpp"
52#include "utils/simError.h"
58 InversePowerSeries::InversePowerSeries() :
59 initialized_(false), forceField_(NULL), name_(
"InversePowerSeries") {}
61 void InversePowerSeries::initialize() {
62 InversePowerSeriesTypes.clear();
63 InversePowerSeriesTids.clear();
65 InversePowerSeriesTids.resize(forceField_->getNAtomType(), -1);
67 ForceField::NonBondedInteractionTypeContainer* nbiTypes =
68 forceField_->getNonBondedInteractionTypes();
69 ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
70 ForceField::NonBondedInteractionTypeContainer::KeyType keys;
71 NonBondedInteractionType* nbt;
74 for (nbt = nbiTypes->beginType(j); nbt != NULL;
75 nbt = nbiTypes->nextType(j)) {
76 if (nbt->isInversePowerSeries()) {
77 keys = nbiTypes->getKeys(j);
78 AtomType* at1 = forceField_->getAtomType(keys[0]);
80 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
81 "InversePowerSeries::initialize could not find AtomType %s\n"
82 "\tto for for %s - %s interaction.\n",
83 keys[0].c_str(), keys[0].c_str(), keys[1].c_str());
84 painCave.severity = OPENMD_ERROR;
89 AtomType* at2 = forceField_->getAtomType(keys[1]);
91 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
92 "InversePowerSeries::initialize could not find AtomType %s\n"
93 "\tfor %s - %s nonbonded interaction.\n",
94 keys[1].c_str(), keys[0].c_str(), keys[1].c_str());
95 painCave.severity = OPENMD_ERROR;
100 int atid1 = at1->getIdent();
101 if (InversePowerSeriesTids[atid1] == -1) {
102 ipstid1 = InversePowerSeriesTypes.size();
103 InversePowerSeriesTypes.insert(atid1);
104 InversePowerSeriesTids[atid1] = ipstid1;
106 int atid2 = at2->getIdent();
107 if (InversePowerSeriesTids[atid2] == -1) {
108 ipstid2 = InversePowerSeriesTypes.size();
109 InversePowerSeriesTypes.insert(atid2);
110 InversePowerSeriesTids[atid2] = ipstid2;
113 InversePowerSeriesInteractionType* ipsit =
114 dynamic_cast<InversePowerSeriesInteractionType*
>(nbt);
116 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
117 "InversePowerSeries::initialize could not convert "
118 "NonBondedInteractionType\n"
119 "\tto InversePowerSeriesInteractionType for %s - %s "
121 at1->getName().c_str(), at2->getName().c_str());
122 painCave.severity = OPENMD_ERROR;
123 painCave.isFatal = 1;
127 std::vector<int> powers = ipsit->getPowers();
128 std::vector<RealType> coefficients = ipsit->getCoefficients();
130 addExplicitInteraction(at1, at2, powers, coefficients);
136 void InversePowerSeries::addExplicitInteraction(
137 AtomType* atype1, AtomType* atype2, std::vector<int> powers,
138 std::vector<RealType> coefficients) {
139 InversePowerSeriesInteractionData mixer;
140 mixer.powers = powers;
141 mixer.coefficients = coefficients;
143 int ipstid1 = InversePowerSeriesTids[atype1->getIdent()];
144 int ipstid2 = InversePowerSeriesTids[atype2->getIdent()];
145 int nInversePowerSeries = InversePowerSeriesTypes.size();
147 MixingMap.resize(nInversePowerSeries);
148 MixingMap[ipstid1].resize(nInversePowerSeries);
150 MixingMap[ipstid1][ipstid2] = mixer;
151 if (ipstid2 != ipstid1) {
152 MixingMap[ipstid2].resize(nInversePowerSeries);
153 MixingMap[ipstid2][ipstid1] = mixer;
157 void InversePowerSeries::calcForce(InteractionData& idat) {
158 if (!initialized_) initialize();
160 InversePowerSeriesInteractionData& mixer =
161 MixingMap[InversePowerSeriesTids[idat.atid1]]
162 [InversePowerSeriesTids[idat.atid2]];
163 std::vector<int> powers = mixer.powers;
164 std::vector<RealType> coefficients = mixer.coefficients;
166 RealType myPot = 0.0;
167 RealType myPotC = 0.0;
168 RealType myDeriv = 0.0;
169 RealType myDerivC = 0.0;
171 RealType ri = 1.0 / idat.rij;
172 RealType ric = 1.0 / idat.rcut;
176 for (
unsigned int i = 0; i < powers.size(); i++) {
177 fn = coefficients[i] * pow(ri, powers[i]);
178 fnc = coefficients[i] * pow(ric, powers[i]);
181 myDeriv -= powers[i] * fn * ri;
182 myDerivC -= powers[i] * fnc * ric;
185 if (idat.shiftedPot) {
187 }
else if (idat.shiftedForce) {
188 myPotC = myPotC + myDerivC * (idat.rij - idat.rcut);
194 RealType pot_temp = idat.vdwMult * (myPot - myPotC);
195 idat.vpair += pot_temp;
197 RealType dudr = idat.sw * idat.vdwMult * (myDeriv - myDerivC);
202 idat.f1 += idat.d * dudr / idat.rij;
207 RealType InversePowerSeries::getSuggestedCutoffRadius(
208 pair<AtomType*, AtomType*> atypes) {
209 if (!initialized_) initialize();
211 int atid1 = atypes.first->getIdent();
212 int atid2 = atypes.second->getIdent();
213 int ipstid1 = InversePowerSeriesTids[atid1];
214 int ipstid2 = InversePowerSeriesTids[atid2];
216 if (ipstid1 == -1 || ipstid2 == -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.