45#include "nonbonded/MAW.hpp" 
   51#include "utils/simError.h" 
   57  MAW::MAW() : initialized_(false), forceField_(NULL), name_(
"MAW") {}
 
   59  void MAW::initialize() {
 
   63    MAWtids.resize(forceField_->getNAtomType(), -1);
 
   65    ForceField::NonBondedInteractionTypeContainer* nbiTypes =
 
   66        forceField_->getNonBondedInteractionTypes();
 
   67    ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
 
   68    ForceField::NonBondedInteractionTypeContainer::KeyType keys;
 
   69    NonBondedInteractionType* nbt;
 
   72    for (nbt = nbiTypes->beginType(j); nbt != NULL;
 
   73         nbt = nbiTypes->nextType(j)) {
 
   75        keys          = nbiTypes->getKeys(j);
 
   76        AtomType* at1 = forceField_->getAtomType(keys[0]);
 
   78          snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
   79                   "MAW::initialize could not find AtomType %s\n" 
   80                   "\tto for for %s - %s interaction.\n",
 
   81                   keys[0].c_str(), keys[0].c_str(), keys[1].c_str());
 
   82          painCave.severity = OPENMD_ERROR;
 
   87        AtomType* at2 = forceField_->getAtomType(keys[1]);
 
   89          snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
   90                   "MAW::initialize could not find AtomType %s\n" 
   91                   "\tfor %s - %s nonbonded interaction.\n",
 
   92                   keys[1].c_str(), keys[0].c_str(), keys[1].c_str());
 
   93          painCave.severity = OPENMD_ERROR;
 
   98        int atid1 = at1->getIdent();
 
   99        if (MAWtids[atid1] == -1) {
 
  100          mtid1 = MAWtypes.size();
 
  101          MAWtypes.insert(atid1);
 
  102          MAWtids[atid1] = mtid1;
 
  104        int atid2 = at2->getIdent();
 
  105        if (MAWtids[atid2] == -1) {
 
  106          mtid2 = MAWtypes.size();
 
  107          MAWtypes.insert(atid2);
 
  108          MAWtids[atid2] = mtid2;
 
  111        MAWInteractionType* mit = 
dynamic_cast<MAWInteractionType*
>(nbt);
 
  115              painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
 
  116              "MAW::initialize could not convert NonBondedInteractionType\n" 
  117              "\tto MAWInteractionType 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 De   = mit->getD();
 
  125        RealType beta = mit->getBeta();
 
  126        RealType Re   = mit->getR();
 
  127        RealType ca1  = mit->getCA1();
 
  128        RealType cb1  = mit->getCB1();
 
  130        addExplicitInteraction(at1, at2, De, beta, Re, ca1, cb1);
 
  136  void MAW::addExplicitInteraction(AtomType* atype1, AtomType* atype2,
 
  137                                   RealType De, RealType beta, RealType Re,
 
  138                                   RealType ca1, RealType cb1) {
 
  139    MAWInteractionData mixer;
 
  145    mixer.j_is_Metal = atype2->isMetal();
 
  147    int mtid1 = MAWtids[atype1->getIdent()];
 
  148    int mtid2 = MAWtids[atype2->getIdent()];
 
  149    int nM    = MAWtypes.size();
 
  151    MixingMap.resize(nM);
 
  152    MixingMap[mtid1].resize(nM);
 
  154    MixingMap[mtid1][mtid2] = mixer;
 
  155    if (mtid2 != mtid1) {
 
  156      MixingMap[mtid2].resize(nM);
 
  157      mixer.j_is_Metal        = atype1->isMetal();
 
  158      MixingMap[mtid2][mtid1] = mixer;
 
  162  void MAW::calcForce(InteractionData& idat) {
 
  163    if (!initialized_) initialize();
 
  165    MAWInteractionData& mixer =
 
  166        MixingMap[MAWtids[idat.atid1]][MAWtids[idat.atid2]];
 
  168    RealType myPot    = 0.0;
 
  169    RealType myPotC   = 0.0;
 
  170    RealType myDeriv  = 0.0;
 
  171    RealType myDerivC = 0.0;
 
  173    RealType D_e  = mixer.De;
 
  174    RealType R_e  = mixer.Re;
 
  175    RealType beta = mixer.beta;
 
  176    RealType ca1  = mixer.ca1;
 
  177    RealType cb1  = mixer.cb1;
 
  181    if (mixer.j_is_Metal) {
 
  184      r      = idat.A1 * idat.d;
 
  185      Atrans = idat.A1.transpose();
 
  188      r      = -idat.A2 * idat.d;
 
  189      Atrans = idat.A2.transpose();
 
  194    RealType expt    = -beta * (idat.rij - R_e);
 
  195    RealType expfnc  = exp(expt);
 
  196    RealType expfnc2 = expfnc * expfnc;
 
  198    RealType exptC    = 0.0;
 
  199    RealType expfncC  = 0.0;
 
  200    RealType expfnc2C = 0.0;
 
  202    myPot   = D_e * (expfnc2 - 2.0 * expfnc);
 
  203    myDeriv = 2.0 * D_e * beta * (expfnc - expfnc2);
 
  205    if (idat.shiftedPot || idat.shiftedForce) {
 
  206      exptC    = -beta * (idat.rcut - R_e);
 
  207      expfncC  = exp(exptC);
 
  208      expfnc2C = expfncC * expfncC;
 
  211    if (idat.shiftedPot) {
 
  212      myPotC   = D_e * (expfnc2C - 2.0 * expfncC);
 
  214    } 
else if (idat.shiftedForce) {
 
  215      myPotC   = D_e * (expfnc2C - 2.0 * expfncC);
 
  216      myDerivC = 2.0 * D_e * beta * (expfncC - expfnc2C);
 
  217      myPotC += myDerivC * (idat.rij - idat.rcut);
 
  229    RealType r3 = idat.r2 * idat.rij;
 
  230    RealType r4 = idat.r2 * idat.r2;
 
  247    RealType Vmorse = (myPot - myPotC);
 
  248    RealType Vang = ca1 * x2 / idat.r2 + cb1 * z / idat.rij + (0.8 - ca1 / 3.0);
 
  250    RealType pot_temp = idat.vdwMult * Vmorse * Vang;
 
  251    idat.vpair += pot_temp;
 
  254    Vector3d dVmorsedr = (myDeriv - myDerivC) * Vector3d(x, y, z) / idat.rij;
 
  256    Vector3d dVangdr = Vector3d(
 
  257        -2.0 * ca1 * x2 * x / r4 + 2.0 * ca1 * x / idat.r2 - cb1 * x * z / r3,
 
  258        -2.0 * ca1 * x2 * y / r4 - cb1 * z * y / r3,
 
  259        -2.0 * ca1 * x2 * z / r4 + cb1 / idat.rij - cb1 * z2 / r3);
 
  263    Vector3d dvdr = Vang * dVmorsedr + Vmorse * dVangdr;
 
  268    Vector3d dVangdu = Vector3d(
 
  269        cb1 * y / idat.rij, 2.0 * ca1 * x * z / idat.r2 - cb1 * x / idat.rij,
 
  270        -2.0 * ca1 * y * x / idat.r2);
 
  275    Vector3d trq = idat.vdwMult * Vmorse * dVangdu * idat.sw;
 
  279    if (mixer.j_is_Metal) {
 
  280      idat.t1 += Atrans * trq;
 
  282      idat.t2 += Atrans * trq;
 
  287    Vector3d ftmp = idat.vdwMult * idat.sw * dvdr;
 
  291    if (mixer.j_is_Metal) {
 
  292      flab = Atrans * ftmp;
 
  294      flab = -Atrans * ftmp;
 
  302  RealType MAW::getSuggestedCutoffRadius(pair<AtomType*, AtomType*> atypes) {
 
  303    if (!initialized_) initialize();
 
  304    int atid1 = atypes.first->getIdent();
 
  305    int atid2 = atypes.second->getIdent();
 
  306    int mtid1 = MAWtids[atid1];
 
  307    int mtid2 = MAWtids[atid2];
 
  309    if (mtid1 == -1 || mtid2 == -1)
 
  312      MAWInteractionData mixer = MixingMap[mtid1][mtid2];
 
  313      RealType R_e             = mixer.Re;
 
  314      RealType beta            = mixer.beta;
 
  319      return (4.9 + beta * R_e) / 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.