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

Comparing trunk/src/nonbonded/GB.cpp (file contents):
Revision 1782 by gezelter, Wed Aug 22 02:28:28 2012 UTC vs.
Revision 2071 by gezelter, Sat Mar 7 21:41:51 2015 UTC

# Line 35 | Line 35
35   *                                                                      
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).          
38 > * [3]  Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).          
39   * [4]  Kuang & Gezelter,  J. Chem. Phys. 133, 164101 (2010).
40   * [5]  Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41   */
# Line 88 | Line 88 | namespace OpenMD {
88     */
89  
90  
91 <  GB::GB() : name_("GB"), initialized_(false), mu_(2.0), nu_(1.0), forceField_(NULL) {}
91 >  GB::GB() : initialized_(false), name_("GB"), forceField_(NULL),
92 >             mu_(2.0), nu_(1.0) {}
93      
94    void GB::initialize() {    
95      
96 +    GBtypes.clear();
97 +    GBtids.clear();
98 +    MixingMap.clear();
99 +    nGB_ = 0;
100 +
101 +    GBtids.resize( forceField_->getNAtomType(), -1);
102 +
103      ForceFieldOptions& fopts = forceField_->getForceFieldOptions();
104      mu_ = fopts.getGayBerneMu();
105      nu_ = fopts.getGayBerneNu();
98    ForceField::AtomTypeContainer* atomTypes = forceField_->getAtomTypes();
99    ForceField::AtomTypeContainer::MapTypeIterator i;
100    AtomType* at;
106  
107      // GB handles all of the GB-GB interactions as well as GB-LJ cross
108      // interactions:
109 +    set<AtomType*>::iterator at;
110 +    for (at = simTypes_.begin(); at != simTypes_.end(); ++at) {
111 +      if ((*at)->isGayBerne()) nGB_++;
112 +      if ((*at)->isLennardJones()) nGB_++;
113 +    }
114  
115 <    for (at = atomTypes->beginType(i); at != NULL;
116 <         at = atomTypes->nextType(i)) {
117 <      
108 <      LennardJonesAdapter lja = LennardJonesAdapter(at);
109 <      GayBerneAdapter gba = GayBerneAdapter(at);
110 <
111 <      if (gba.isGayBerne() || lja.isLennardJones())
112 <        addType(at);
115 >    MixingMap.resize(nGB_);
116 >    for (at = simTypes_.begin(); at != simTypes_.end(); ++at) {
117 >      if ((*at)->isGayBerne() || (*at)->isLennardJones()) addType( *at );
118      }
119 <  
119 >    
120      initialized_ = true;
121    }
122        
123    void GB::addType(AtomType* atomType){
119    // add it to the map:
124  
125 <    pair<map<int,AtomType*>::iterator,bool> ret;    
126 <    ret = GBMap.insert( pair<int, AtomType*>(atomType->getIdent(), atomType) );
125 >    // add it to the map:
126 >    int atid = atomType->getIdent();
127 >    int gbtid = GBtypes.size();
128 >  
129 >    pair<set<int>::iterator,bool> ret;    
130 >    ret = GBtypes.insert( atid );
131      if (ret.second == false) {
132        sprintf( painCave.errMsg,
133                 "GB already had a previous entry with ident %d\n",
134 <               atomType->getIdent() );
134 >               atid) ;
135        painCave.severity = OPENMD_INFO;
136        painCave.isFatal = 0;
137        simError();        
138      }
139 +
140 +    GBtids[atid] = gbtid;
141 +    MixingMap[gbtid].resize( nGB_ );
142      
143 <    RealType d1, l1, eX1, eS1, eE1, dw1;
144 <        
143 >    RealType d1(0.0), l1(0.0), eX1(0.0), eS1(0.0), eE1(0.0), dw1(0.0);
144 >    
145      LennardJonesAdapter lja1 = LennardJonesAdapter(atomType);
146      GayBerneAdapter gba1 = GayBerneAdapter(atomType);
147      if (gba1.isGayBerne()) {
# Line 157 | Line 168 | namespace OpenMD {
168        simError();
169      }
170        
171 <
171 >    
172      // Now, iterate over all known types and add to the mixing map:
173      
174 <    map<int, AtomType*>::iterator it;
175 <    for( it = GBMap.begin(); it != GBMap.end(); ++it) {
174 >    std::set<int>::iterator it;
175 >    for( it = GBtypes.begin(); it != GBtypes.end(); ++it) {
176        
177 <      AtomType* atype2 = (*it).second;
177 >      int gbtid2 = GBtids[ (*it) ];
178 >      AtomType* atype2 = forceField_->getAtomType( (*it) );
179 >
180        LennardJonesAdapter lja2 = LennardJonesAdapter(atype2);
181        GayBerneAdapter gba2 = GayBerneAdapter(atype2);
182 <      RealType d2, l2, eX2, eS2, eE2, dw2;
182 >      RealType d2(0.0), l2(0.0), eX2(0.0), eS2(0.0), eE2(0.0), dw2(0.0);
183        
184        if (gba2.isGayBerne()) {
185          d2 = gba2.getD();
# Line 182 | Line 195 | namespace OpenMD {
195          eS2 = eX2;
196          eE2 = eX2;
197          dw2 = 1.0;
198 <      }
199 <                      
198 >      } else {
199 >        sprintf( painCave.errMsg,
200 >                 "GB::addType found an atomType (%s) that does not\n"
201 >                 "\tappear to be a Gay-Berne or Lennard-Jones atom.\n",
202 >                 atype2->getName().c_str());
203 >        painCave.severity = OPENMD_ERROR;
204 >        painCave.isFatal = 1;
205 >        simError();
206 >      }
207 >      
208 >      
209        GBInteractionData mixer1, mixer2;    
210        
211        //  Cleaver paper uses sqrt of squares to get sigma0 for
212        //  mixed interactions.
213 <            
213 >      
214        mixer1.sigma0 = sqrt(d1*d1 + d2*d2);
215        mixer1.xa2 = (l1*l1 - d1*d1)/(l1*l1 + d2*d2);
216        mixer1.xai2 = (l2*l2 - d2*d2)/(l2*l2 + d1*d1);
217        mixer1.x2 = (l1*l1 - d1*d1) * (l2*l2 - d2*d2) /
218          ((l2*l2 + d1*d1) * (l1*l1 + d2*d2));
219 <
219 >      
220        mixer2.sigma0 = mixer1.sigma0;
221        // xa2 and xai2 for j-i pairs are reversed from the same i-j pairing.
222        // Swapping the particles reverses the anisotropy parameters:
223        mixer2.xa2 = mixer1.xai2;
224        mixer2.xai2 = mixer1.xa2;
225        mixer2.x2 = mixer1.x2;
226 <
226 >      
227        // assumed LB mixing rules for now:
228 <
228 >      
229        mixer1.dw = 0.5 * (dw1 + dw2);
230        mixer1.eps0 = sqrt(eX1 * eX2);
231  
232        mixer2.dw = mixer1.dw;
233        mixer2.eps0 = mixer1.eps0;
234 <
234 >      
235        RealType mi = RealType(1.0)/mu_;
236        
237        mixer1.xpap2  = (pow(eS1, mi) - pow(eE1, mi)) / (pow(eS1, mi) + pow(eE2, mi));
238        mixer1.xpapi2 = (pow(eS2, mi) - pow(eE2, mi)) / (pow(eS2, mi) + pow(eE1, mi));
239        mixer1.xp2    = (pow(eS1, mi) - pow(eE1, mi)) * (pow(eS2, mi) - pow(eE2, mi))  /
240          (pow(eS2, mi) + pow(eE1, mi)) / (pow(eS1, mi) + pow(eE2, mi)) ;
241 <
241 >      
242        // xpap2 and xpapi2 for j-i pairs are reversed from the same i-j pairing.
243        // Swapping the particles reverses the anisotropy parameters:
244        mixer2.xpap2 = mixer1.xpapi2;
245        mixer2.xpapi2 = mixer1.xpap2;
246        mixer2.xp2 = mixer1.xp2;
247 +      // keep track of who is the LJ atom:
248 +      mixer1.i_is_LJ = atomType->isLennardJones();
249 +      mixer1.j_is_LJ = atype2->isLennardJones();
250 +      mixer2.i_is_LJ = mixer1.j_is_LJ;
251 +      mixer2.j_is_LJ = mixer1.i_is_LJ;
252  
253 +
254        // only add this pairing if at least one of the atoms is a Gay-Berne atom
255  
256        if (gba1.isGayBerne() || gba2.isGayBerne()) {
257 <
258 <        pair<AtomType*, AtomType*> key1, key2;
259 <        key1 = make_pair(atomType, atype2);
260 <        key2 = make_pair(atype2, atomType);
261 <        
234 <        MixingMap[key1] = mixer1;
235 <        if (key2 != key1) {
236 <          MixingMap[key2] = mixer2;
237 <        }
257 >        MixingMap[gbtid2].resize( nGB_ );        
258 >        MixingMap[gbtid][gbtid2] = mixer1;
259 >        if (gbtid2 != gbtid)  {
260 >          MixingMap[gbtid2][gbtid] = mixer2;
261 >        }          
262        }
263 <    }      
263 >    }
264    }
265    
266    void GB::calcForce(InteractionData &idat) {
267  
268      if (!initialized_) initialize();
269      
270 <    GBInteractionData mixer = MixingMap[idat.atypes];
270 >    GBInteractionData &mixer = MixingMap[GBtids[idat.atid1]][GBtids[idat.atid2]];
271  
272      RealType sigma0 = mixer.sigma0;
273      RealType dw     = mixer.dw;
# Line 255 | Line 279 | namespace OpenMD {
279      RealType xpap2  = mixer.xpap2;
280      RealType xpapi2 = mixer.xpapi2;
281  
258    // cerr << "atypes = " << idat.atypes.first->getName() << " " << idat.atypes.second->getName() << "\n";
259    // cerr << "sigma0 = " <<mixer.sigma0 <<"\n";
260    // cerr << "dw     = " <<mixer.dw <<"\n";
261    // cerr << "eps0   = " <<mixer.eps0 <<"\n";  
262    // cerr << "x2     = " <<mixer.x2 <<"\n";    
263    // cerr << "xa2    = " <<mixer.xa2 <<"\n";  
264    // cerr << "xai2   = " <<mixer.xai2 <<"\n";  
265    // cerr << "xp2    = " <<mixer.xp2 <<"\n";  
266    // cerr << "xpap2  = " <<mixer.xpap2 <<"\n";
267    // cerr << "xpapi2 = " <<mixer.xpapi2 <<"\n";
268
282      Vector3d ul1 = idat.A1->getRow(2);
283      Vector3d ul2 = idat.A2->getRow(2);
284  
272    // cerr << "ul1 = " <<ul1<<"\n";
273    // cerr << "ul2 = " <<ul2<<"\n";
274
285      RealType a, b, g;
276
277    // This is not good.  We should store this in the mixing map, and not
278    // query atom types in calc force.
279    bool i_is_LJ = idat.atypes.first->isLennardJones();
280    bool j_is_LJ = idat.atypes.second->isLennardJones();
286      
287 <    if (i_is_LJ) {
287 >    if (mixer.i_is_LJ) {
288        a = 0.0;
289        ul1 = V3Zero;
290      } else {
291        a = dot(*(idat.d), ul1);
292      }
293  
294 <    if (j_is_LJ) {
294 >    if (mixer.j_is_LJ) {
295        b = 0.0;
296        ul2 = V3Zero;
297      } else {
298        b = dot(*(idat.d), ul2);
299      }
300  
301 <    if (i_is_LJ || j_is_LJ)
301 >    if (mixer.i_is_LJ || mixer.j_is_LJ)
302        g = 0.0;
303      else
304        g = dot(ul1, ul2);
# Line 308 | Line 313 | namespace OpenMD {
313      RealType H  = (xa2 * au2 + xai2 * bu2 - 2.0*x2*au*bu*g)  / (1.0 - x2*g2);
314      RealType Hp = (xpap2*au2 + xpapi2*bu2 - 2.0*xp2*au*bu*g) / (1.0 - xp2*g2);
315  
311    // cerr << "au2 = " << au2 << "\n";
312    // cerr << "bu2 = " << bu2 << "\n";
313    // cerr << "g2 = " << g2 << "\n";
314    // cerr << "H = " << H << "\n";
315    // cerr << "Hp = " << Hp << "\n";
316
316      RealType sigma = sigma0 / sqrt(1.0 - H);
317      RealType e1 = 1.0 / sqrt(1.0 - x2*g2);
318      RealType e2 = 1.0 - Hp;
# Line 331 | Line 330 | namespace OpenMD {
330      RealType s3 = sigma*sigma*sigma;
331      RealType s03 = sigma0*sigma0*sigma0;
332  
334    // cerr << "vdwMult = " << *(idat.vdwMult) << "\n";
335    // cerr << "eps = " << eps <<"\n";
336    // cerr << "mu = " << mu_ << "\n";
337    // cerr << "R12 = " << R12 << "\n";
338    // cerr << "R6 = " << R6 << "\n";
339    // cerr << "R13 = " << R13 << "\n";
340    // cerr << "R7 = " << R7 << "\n";
341    // cerr << "e2 = " << e2 << "\n";
342    // cerr << "rij = " << *(idat.rij) << "\n";
343    // cerr << "s3 = " << s3 << "\n";
344    // cerr << "s03 = " << s03 << "\n";
345    // cerr << "dw = " << dw << "\n";
346
333      RealType pref1 = - *(idat.vdwMult) * 8.0 * eps * mu_ * (R12 - R6) /
334        (e2 * *(idat.rij));
335  
# Line 358 | Line 344 | namespace OpenMD {
344      
345      RealType dUdb = pref1 * (xpapi2*bu - xp2*au*g) / (1.0 - xp2 * g2)
346        + pref2 * (xai2 * bu - x2 *au*g) / (1.0 - x2 * g2);
347 <
347 >    
348      RealType dUdg = 4.0 * eps * nu_ * (R12 - R6) * x2 * g / (1.0 - x2*g2)
349        + 8.0 * eps * mu_ * (R12 - R6) * (xp2*au*bu - Hp*xp2*g) /
350        (1.0 - xp2 * g2) / e2 + 8.0 * eps * s3 * (3.0 * R7 - 6.0 * R13) *
351        (x2 * au * bu - H * x2 * g) / (1.0 - x2 * g2) / (dw * s03);
352 <
367 <    // cerr << "pref = " << pref1 << " " << pref2 << "\n";
368 <    // cerr << "dU = " << dUdr << " " << dUda <<" " << dUdb << " " << dUdg << "\n";
369 <
352 >    
353      Vector3d rhat = *(idat.d) / *(idat.rij);  
354      Vector3d rxu1 = cross(*(idat.d), ul1);
355      Vector3d rxu2 = cross(*(idat.d), ul2);
356      Vector3d uxu = cross(ul1, ul2);
357 <
357 >    
358      (*(idat.pot))[VANDERWAALS_FAMILY] += U *  *(idat.sw);
359      *(idat.f1) += (dUdr * rhat + dUda * ul1 + dUdb * ul2) * *(idat.sw);
360      *(idat.t1) += (dUda * rxu1 - dUdg * uxu) * *(idat.sw);
361      *(idat.t2) += (dUdb * rxu2 + dUdg * uxu) * *(idat.sw);
362      *(idat.vpair) += U;
363  
381    // cerr << "f1 term = " <<  (dUdr * rhat + dUda * ul1 + dUdb * ul2) * *(idat.sw) << "\n";
382    // cerr << "t1 term = " << (dUda * rxu1 - dUdg * uxu) * *(idat.sw) << "\n";
383    // cerr << "t2 term = " << (dUdb * rxu2 + dUdg * uxu) * *(idat.sw) << "\n";
384    // cerr << "vp term = " << U << "\n";
385
364      return;
365  
366    }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines