ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/nonbonded/MAW.cpp
(Generate patch)

Comparing branches/development/src/nonbonded/MAW.cpp (file contents):
Revision 1532 by gezelter, Wed Dec 29 19:59:21 2010 UTC vs.
Revision 1826 by gezelter, Wed Jan 9 19:41:48 2013 UTC

# Line 36 | Line 36
36   * [1]  Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).            
37   * [2]  Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).          
38   * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).          
39 < * [4]  Vardeman & Gezelter, in progress (2009).                        
39 > * [4]  Kuang & Gezelter,  J. Chem. Phys. 133, 164101 (2010).
40 > * [5]  Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41   */
42  
43   #include <stdio.h>
# Line 50 | Line 51 | namespace OpenMD {
51  
52   namespace OpenMD {
53  
54 <  MAW::MAW() : name_("MAW"), initialized_(false), forceField_(NULL),
54 <                   shiftedPot_(false), shiftedFrc_(false) {}
54 >  MAW::MAW() : name_("MAW"), initialized_(false), forceField_(NULL) {}
55    
56    void MAW::initialize() {    
57  
58      ForceField::NonBondedInteractionTypeContainer* nbiTypes = forceField_->getNonBondedInteractionTypes();
59      ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
60      NonBondedInteractionType* nbt;
61 +    ForceField::NonBondedInteractionTypeContainer::KeyType keys;
62  
63      for (nbt = nbiTypes->beginType(j); nbt != NULL;
64           nbt = nbiTypes->nextType(j)) {
65        
66        if (nbt->isMAW()) {
67 <        pair<AtomType*, AtomType*> atypes = nbt->getAtomTypes();
68 <        
69 <        GenericData* data = nbt->getPropertyByName("MAW");
70 <        if (data == NULL) {
71 <          sprintf( painCave.errMsg, "MAW::initialize could not find\n"
72 <                   "\tMAW parameters for %s - %s interaction.\n",
73 <                   atypes.first->getName().c_str(),
73 <                   atypes.second->getName().c_str());
74 <          painCave.severity = OPENMD_ERROR;
75 <          painCave.isFatal = 1;
76 <          simError();
77 <        }
78 <        
79 <        MAWData* mawData = dynamic_cast<MAWData*>(data);
80 <        if (mawData == NULL) {
67 >        keys = nbiTypes->getKeys(j);
68 >        AtomType* at1 = forceField_->getAtomType(keys[0]);
69 >        AtomType* at2 = forceField_->getAtomType(keys[1]);
70 >
71 >        MAWInteractionType* mit = dynamic_cast<MAWInteractionType*>(nbt);
72 >
73 >        if (mit == NULL) {
74            sprintf( painCave.errMsg,
75 <                   "MAW::initialize could not convert GenericData to\n"
76 <                   "\tMAWData for %s - %s interaction.\n",
77 <                   atypes.first->getName().c_str(),
78 <                   atypes.second->getName().c_str());
75 >                   "MAW::initialize could not convert NonBondedInteractionType\n"
76 >                   "\tto MAWInteractionType for %s - %s interaction.\n",
77 >                   at1->getName().c_str(),
78 >                   at2->getName().c_str());
79            painCave.severity = OPENMD_ERROR;
80            painCave.isFatal = 1;
81            simError();          
82          }
83          
84 <        MAWParam mawParam = mawData->getData();
85 <
86 <        RealType De = mawParam.De;
87 <        RealType beta = mawParam.beta;
88 <        RealType Re = mawParam.Re;
96 <        RealType ca1 = mawParam.ca1;
97 <        RealType cb1 = mawParam.cb1;
84 >        RealType De = mit->getD();
85 >        RealType beta = mit->getBeta();
86 >        RealType Re = mit->getR();
87 >        RealType ca1 = mit->getCA1();
88 >        RealType cb1 = mit->getCB1();
89          
90 <        addExplicitInteraction(atypes.first, atypes.second,
90 >        addExplicitInteraction(at1, at2,
91                                 De, beta, Re, ca1, cb1);
92        }
93      }  
# Line 124 | Line 115 | namespace OpenMD {
115      }    
116    }
117    
118 <  void MAW::calcForce(InteractionData idat) {
118 >  void MAW::calcForce(InteractionData &idat) {
119  
120      if (!initialized_) initialize();
121      
131    pair<AtomType*, AtomType*> key = make_pair(idat.atype1, idat.atype2);
122      map<pair<AtomType*, AtomType*>, MAWInteractionData>::iterator it;
123 <    it = MixingMap.find(key);
123 >    it = MixingMap.find( idat.atypes );
124      if (it != MixingMap.end()) {
125        MAWInteractionData mixer = (*it).second;
126        
# Line 145 | Line 135 | namespace OpenMD {
135        RealType ca1 = mixer.ca1;
136        RealType cb1 = mixer.cb1;
137  
138 <      bool j_is_Metal = idat.atype2->isMetal();
138 >      bool j_is_Metal = idat.atypes.second->isMetal();
139  
140        Vector3d r;
141        RotMat3x3d Atrans;
142        if (j_is_Metal) {
143          // rotate the inter-particle separation into the two different
144          // body-fixed coordinate systems:
145 <        r = idat.A1 * idat.d;
146 <        Atrans = idat.A1.transpose();
145 >        r = *(idat.A1) * *(idat.d);
146 >        Atrans = idat.A1->transpose();
147        } else {
148          // negative sign because this is the vector from j to i:      
149 <        r = -idat.A2 * idat.d;
150 <        Atrans = idat.A2.transpose();
149 >        r = -*(idat.A2) * *(idat.d);
150 >        Atrans = idat.A2->transpose();
151        }
152        
153        // V(r) = D_e exp(-a(r-re)(exp(-a(r-re))-2)
154        
155 <      RealType expt     = -beta*(idat.rij - R_e);
155 >      RealType expt     = -beta*( *(idat.rij) - R_e);
156        RealType expfnc   = exp(expt);
157        RealType expfnc2  = expfnc*expfnc;
158        
# Line 173 | Line 163 | namespace OpenMD {
163        myPot  = D_e * (expfnc2  - 2.0 * expfnc);
164        myDeriv   = 2.0 * D_e * beta * (expfnc - expfnc2);
165        
166 <      if (MAW::shiftedPot_ || MAW::shiftedFrc_) {
167 <        exptC     = -beta*(idat.rcut - R_e);
166 >      if (idat.shiftedPot || idat.shiftedForce) {
167 >        exptC     = -beta*( *(idat.rcut)  - R_e);
168          expfncC   = exp(exptC);
169          expfnc2C  = expfncC*expfncC;
170        }
171        
172 <      if (MAW::shiftedPot_) {
172 >      if (idat.shiftedPot) {
173          myPotC = D_e * (expfnc2C - 2.0 * expfncC);
174          myDerivC = 0.0;
175 <      } else if (MAW::shiftedFrc_) {
175 >      } else if (idat.shiftedForce) {
176          myPotC = D_e * (expfnc2C - 2.0 * expfncC);
177          myDerivC  = 2.0 * D_e * beta * (expfnc2C - expfnc2C);
178 <        myPotC += myDerivC * (idat.rij - idat.rcut);
178 >        myPotC += myDerivC * ( *(idat.rij)  -  *(idat.rcut) );
179        } else {
180          myPotC = 0.0;
181          myDerivC = 0.0;
# Line 195 | Line 185 | namespace OpenMD {
185        RealType y = r.y();
186        RealType z = r.z();
187        RealType x2 = x * x;
198      RealType y2 = y * y;
188        RealType z2 = z * z;
189  
190 <      RealType r3 = idat.r2 * idat.rij;
191 <      RealType r4 = idat.r2 * idat.r2;
190 >      RealType r3 = *(idat.r2) *  *(idat.rij) ;
191 >      RealType r4 = *(idat.r2) *  *(idat.r2);
192  
193        // angular modulation of morse part of potential to approximate
194        // the squares of the two HOMO lone pair orbitals in water:
# Line 217 | Line 206 | namespace OpenMD {
206        // Vmorse(r)*[a*x2/r2 + b*z/r + (1-a-b)]
207        
208        RealType Vmorse = (myPot - myPotC);
209 <      RealType Vang = ca1 * x2 / idat.r2 + cb1 * z / idat.rij + (0.8 - ca1 / 3.0);
210 <        
211 <      RealType pot_temp = idat.vdwMult * Vmorse * Vang;
212 <      idat.vpair += pot_temp;
213 <      idat.pot += idat.sw * pot_temp;
209 >      RealType Vang = ca1 * x2 / *(idat.r2) +
210 >        cb1 * z /  *(idat.rij)  + (0.8 - ca1 / 3.0);
211 >      
212 >      RealType pot_temp = *(idat.vdwMult) * Vmorse * Vang;
213 >      *(idat.vpair) += pot_temp;
214 >      (*(idat.pot))[VANDERWAALS_FAMILY] += *(idat.sw) * pot_temp;
215            
216 <      Vector3d dVmorsedr = (myDeriv - myDerivC) * Vector3d(x, y, z) / idat.rij;
227 <    
228 <      Vector3d dVangdr = Vector3d(-2.0 * ca1 * x2 * x / r4 + 2.0 * ca1 * x / idat.r2 - cb1 * x * z / r3,
229 <                                  -2.0 * ca1 * x2 * y / r4                           - cb1 * z * y / r3,
230 <                                  -2.0 * ca1 * x2 * z / r4 + cb1 / idat.rij          - cb1 * z2  / r3);
216 >      Vector3d dVmorsedr = (myDeriv - myDerivC) * Vector3d(x, y, z) /  *(idat.rij) ;
217        
218 +      Vector3d dVangdr = Vector3d(-2.0 * ca1 * x2 * x / r4 + 2.0 * ca1 * x / *(idat.r2) - cb1 * x * z / r3,
219 +                                  -2.0 * ca1 * x2 * y / r4 - cb1 * z * y / r3,
220 +                                  -2.0 * ca1 * x2 * z / r4 + cb1 /  *(idat.rij)           - cb1 * z2  / r3);
221 +      
222        // chain rule to put these back on x, y, z
223  
224        Vector3d dvdr = Vang * dVmorsedr + Vmorse * dVangdr;
# Line 236 | Line 226 | namespace OpenMD {
226        // Torques for Vang using method of Price:
227        // S. L. Price, A. J. Stone, and M. Alderton, Mol. Phys. 52, 987 (1984).
228        
229 <      Vector3d dVangdu = Vector3d(cb1 * y / idat.rij,
230 <                                  2.0 * ca1 * x * z / idat.r2 - cb1 * x / idat.rij,
231 <                                  -2.0 * ca1 * y * x / idat.r2);
229 >      Vector3d dVangdu = Vector3d(cb1 * y /  *(idat.rij) ,
230 >                                  2.0 * ca1 * x * z / *(idat.r2) - cb1 * x /  *(idat.rij),
231 >                                  -2.0 * ca1 * y * x / *(idat.r2));
232  
233        // do the torques first since they are easy:
234        // remember that these are still in the body fixed axes    
235  
236 <      Vector3d trq = idat.vdwMult * Vmorse * dVangdu * idat.sw;
236 >      Vector3d trq = *(idat.vdwMult) * Vmorse * dVangdu * *(idat.sw);
237  
238        // go back to lab frame using transpose of rotation matrix:
239        
240        if (j_is_Metal) {
241 <        idat.t1 += Atrans * trq;
241 >        *(idat.t1) += Atrans * trq;
242        } else {
243 <        idat.t2 += Atrans * trq;
243 >        *(idat.t2) += Atrans * trq;
244        }
245  
246        // Now, on to the forces (still in body frame of water)
247  
248 <      Vector3d ftmp = idat.vdwMult * idat.sw * dvdr;
248 >      Vector3d ftmp = *(idat.vdwMult) * *(idat.sw) * dvdr;
249  
250        // rotate the terms back into the lab frame:
251        Vector3d flab;
# Line 265 | Line 255 | namespace OpenMD {
255          flab = - Atrans * ftmp;
256        }
257        
258 <      idat.f1 += flab;
258 >      *(idat.f1) += flab;
259      }
260      return;
261      
262    }
263      
264 <  RealType MAW::getSuggestedCutoffRadius(AtomType* at1, AtomType* at2) {
264 >  RealType MAW::getSuggestedCutoffRadius(pair<AtomType*, AtomType*> atypes) {
265      if (!initialized_) initialize();  
276    pair<AtomType*, AtomType*> key = make_pair(at1, at2);
266      map<pair<AtomType*, AtomType*>, MAWInteractionData>::iterator it;
267 <    it = MixingMap.find(key);
267 >    it = MixingMap.find(atypes);
268      if (it == MixingMap.end())
269        return 0.0;
270      else  {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines