45#include "nonbonded/Mie.hpp" 
   51#include "types/MieInteractionType.hpp" 
   52#include "utils/simError.h" 
   58  Mie::Mie() : initialized_(false), forceField_(NULL), name_(
"Mie") {}
 
   60  void Mie::initialize() {
 
   64    MieTids.resize(forceField_->getNAtomType(), -1);
 
   66    ForceField::NonBondedInteractionTypeContainer* nbiTypes =
 
   67        forceField_->getNonBondedInteractionTypes();
 
   68    ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
 
   69    ForceField::NonBondedInteractionTypeContainer::KeyType keys;
 
   70    NonBondedInteractionType* nbt;
 
   73    for (nbt = nbiTypes->beginType(j); nbt != NULL;
 
   74         nbt = nbiTypes->nextType(j)) {
 
   76        keys          = nbiTypes->getKeys(j);
 
   77        AtomType* at1 = forceField_->getAtomType(keys[0]);
 
   79          snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
   80                   "Mie::initialize could not find AtomType %s\n" 
   81                   "\tto for for %s - %s interaction.\n",
 
   82                   keys[0].c_str(), keys[0].c_str(), keys[1].c_str());
 
   83          painCave.severity = OPENMD_ERROR;
 
   88        AtomType* at2 = forceField_->getAtomType(keys[1]);
 
   90          snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
   91                   "Mie::initialize could not find AtomType %s\n" 
   92                   "\tfor %s - %s nonbonded interaction.\n",
 
   93                   keys[1].c_str(), keys[0].c_str(), keys[1].c_str());
 
   94          painCave.severity = OPENMD_ERROR;
 
   99        int atid1 = at1->getIdent();
 
  100        if (MieTids[atid1] == -1) {
 
  101          mietid1 = MieTypes.size();
 
  102          MieTypes.insert(atid1);
 
  103          MieTids[atid1] = mietid1;
 
  105        int atid2 = at2->getIdent();
 
  106        if (MieTids[atid2] == -1) {
 
  107          mietid2 = MieTypes.size();
 
  108          MieTypes.insert(atid2);
 
  109          MieTids[atid2] = mietid2;
 
  112        MieInteractionType* mit = 
dynamic_cast<MieInteractionType*
>(nbt);
 
  115              painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
  116              "Mie::initialize could not convert NonBondedInteractionType\n" 
  117              "\tto MieInteractionType for %s - %s interaction.\n",
 
  118              at1->getName().c_str(), at2->getName().c_str());
 
  119          painCave.severity = OPENMD_ERROR;
 
  120          painCave.isFatal  = 1;
 
  124        RealType sigma   = mit->getSigma();
 
  125        RealType epsilon = mit->getEpsilon();
 
  126        int nRep         = mit->getNrep();
 
  127        int mAtt         = mit->getMatt();
 
  129        addExplicitInteraction(at1, at2, sigma, epsilon, nRep, mAtt);
 
  135  void Mie::addExplicitInteraction(AtomType* atype1, AtomType* atype2,
 
  136                                   RealType sigma, RealType epsilon, 
int nRep,
 
  138    MieInteractionData mixer;
 
  140    mixer.epsilon = epsilon;
 
  141    mixer.sigmai  = 1.0 / mixer.sigma;
 
  145    RealType n = RealType(nRep);
 
  146    RealType m = RealType(mAtt);
 
  148    mixer.nmScale = n * pow(n / m, m / (n - m)) / (n - m);
 
  150    int nMie  = MieTypes.size();
 
  151    int atid1 = atype1->getIdent();
 
  152    int atid2 = atype2->getIdent();
 
  153    int mietid1, mietid2;
 
  155    pair<set<int>::iterator, 
bool> ret;
 
  156    ret = MieTypes.insert(atid1);
 
  157    if (ret.second == 
false) {
 
  159      mietid1 = MieTids[atid1];
 
  163      MieTids[atid1] = nMie;
 
  167    ret = MieTypes.insert(atid2);
 
  168    if (ret.second == 
false) {
 
  170      mietid2 = MieTids[atid2];
 
  174      MieTids[atid2] = nMie;
 
  178    MixingMap.resize(nMie);
 
  179    MixingMap[mietid1].resize(nMie);
 
  181    MixingMap[mietid1][mietid2] = mixer;
 
  182    if (mietid2 != mietid1) {
 
  183      MixingMap[mietid2].resize(nMie);
 
  184      MixingMap[mietid2][mietid1] = mixer;
 
  188  void Mie::calcForce(InteractionData& idat) {
 
  189    if (!initialized_) initialize();
 
  191    MieInteractionData& mixer =
 
  192        MixingMap[MieTids[idat.atid1]][MieTids[idat.atid2]];
 
  193    RealType sigmai  = mixer.sigmai;
 
  194    RealType epsilon = mixer.epsilon;
 
  195    int nRep         = mixer.nRep;
 
  196    int mAtt         = mixer.mAtt;
 
  197    RealType nmScale = mixer.nmScale;
 
  201    RealType myPot    = 0.0;
 
  202    RealType myPotC   = 0.0;
 
  203    RealType myDeriv  = 0.0;
 
  204    RealType myDerivC = 0.0;
 
  206    ros = idat.rij * sigmai;
 
  208    getMieFunc(ros, nRep, mAtt, myPot, myDeriv);
 
  210    if (idat.shiftedPot) {
 
  211      rcos = idat.rcut * sigmai;
 
  212      getMieFunc(rcos, nRep, mAtt, myPotC, myDerivC);
 
  214    } 
else if (idat.shiftedForce) {
 
  215      rcos = idat.rcut * sigmai;
 
  216      getMieFunc(rcos, nRep, mAtt, myPotC, myDerivC);
 
  217      myPotC = myPotC + myDerivC * (idat.rij - idat.rcut) * sigmai;
 
  223    RealType pot_temp = idat.vdwMult * nmScale * epsilon * (myPot - myPotC);
 
  224    idat.vpair += pot_temp;
 
  226    RealType dudr = idat.sw * idat.vdwMult * nmScale * epsilon *
 
  227                    (myDeriv - myDerivC) * sigmai;
 
  232    idat.f1 += idat.d * dudr / idat.rij;
 
  237  void Mie::getMieFunc(
const RealType& r, 
int& n, 
int& m, RealType& pot,
 
  239    RealType ri   = 1.0 / r;
 
  240    RealType rin  = pow(ri, n);
 
  241    RealType rim  = pow(ri, m);
 
  242    RealType rin1 = rin * ri;
 
  243    RealType rim1 = rim * ri;
 
  246    deriv = -n * rin1 + m * rim1;
 
  250  RealType Mie::getSuggestedCutoffRadius(pair<AtomType*, AtomType*> atypes) {
 
  251    if (!initialized_) initialize();
 
  253    int atid1   = atypes.first->getIdent();
 
  254    int atid2   = atypes.second->getIdent();
 
  255    int mietid1 = MieTids[atid1];
 
  256    int mietid2 = MieTids[atid2];
 
  258    if (mietid1 == -1 || mietid2 == -1)
 
  261      MieInteractionData mixer = MixingMap[mietid1][mietid2];
 
  262      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.