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

Comparing:
branches/development/src/nonbonded/LJ.cpp (file contents), Revision 1683 by jmichalk, Wed Feb 29 20:33:01 2012 UTC vs.
trunk/src/nonbonded/LJ.cpp (file contents), Revision 2017 by gezelter, Tue Sep 2 18:31:44 2014 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 46 | Line 46
46   #include <cmath>
47   #include "nonbonded/LJ.hpp"
48   #include "utils/simError.h"
49 + #include "types/LennardJonesAdapter.hpp"
50   #include "types/LennardJonesInteractionType.hpp"
51  
52   namespace OpenMD {
53  
54    LJ::LJ() : name_("LJ"), initialized_(false), forceField_(NULL) {}
55  
56 <  LJParam LJ::getLJParam(AtomType* atomType) {
56 <    
57 <    // Do sanity checking on the AtomType we were passed before
58 <    // building any data structures:
59 <    if (!atomType->isLennardJones()) {
60 <      sprintf( painCave.errMsg,
61 <               "LJ::getLJParam was passed an atomType (%s) that does not\n"
62 <               "\tappear to be a Lennard-Jones atom.\n",
63 <               atomType->getName().c_str());
64 <      painCave.severity = OPENMD_ERROR;
65 <      painCave.isFatal = 1;
66 <      simError();
67 <    }
68 <    
69 <    GenericData* data = atomType->getPropertyByName("LennardJones");
70 <    if (data == NULL) {
71 <      sprintf( painCave.errMsg, "LJ::getLJParam could not find Lennard-Jones\n"
72 <               "\tparameters for atomType %s.\n", atomType->getName().c_str());
73 <      painCave.severity = OPENMD_ERROR;
74 <      painCave.isFatal = 1;
75 <      simError();
76 <    }
77 <    
78 <    LJParamGenericData* ljData = dynamic_cast<LJParamGenericData*>(data);
79 <    if (ljData == NULL) {
80 <      sprintf( painCave.errMsg,
81 <               "LJ::getLJParam could not convert GenericData to LJParam for\n"
82 <               "\tatom type %s\n", atomType->getName().c_str());
83 <      painCave.severity = OPENMD_ERROR;
84 <      painCave.isFatal = 1;
85 <      simError();          
86 <    }
87 <    
88 <    return ljData->getData();
89 <  }
56 >  RealType LJ::getSigma(AtomType* atomType1, AtomType* atomType2) {
57  
58 <  RealType LJ::getSigma(AtomType* atomType) {    
59 <    LJParam ljParam = getLJParam(atomType);
60 <    return ljParam.sigma;
61 <  }
95 <
96 <  RealType LJ::getSigma(AtomType* atomType1, AtomType* atomType2) {    
97 <    RealType sigma1 = getSigma(atomType1);
98 <    RealType sigma2 = getSigma(atomType2);
58 >    LennardJonesAdapter lja1 = LennardJonesAdapter(atomType1);
59 >    LennardJonesAdapter lja2 = LennardJonesAdapter(atomType2);
60 >    RealType sigma1 = lja1.getSigma();
61 >    RealType sigma2 = lja2.getSigma();
62      
63      ForceFieldOptions& fopts = forceField_->getForceFieldOptions();
64      string DistanceMix = fopts.getDistanceMixingRule();
# Line 107 | Line 70 | namespace OpenMD {
70        return 0.5 * (sigma1 + sigma2);
71    }
72  
73 <  RealType LJ::getEpsilon(AtomType* atomType) {    
74 <    LJParam ljParam = getLJParam(atomType);
75 <    return ljParam.epsilon;
76 <  }
77 <
78 <  RealType LJ::getEpsilon(AtomType* atomType1, AtomType* atomType2) {    
116 <    RealType epsilon1 = getEpsilon(atomType1);
117 <    RealType epsilon2 = getEpsilon(atomType2);
73 >  RealType LJ::getEpsilon(AtomType* atomType1, AtomType* atomType2) {  
74 >    LennardJonesAdapter lja1 = LennardJonesAdapter(atomType1);
75 >    LennardJonesAdapter lja2 = LennardJonesAdapter(atomType2);
76 >  
77 >    RealType epsilon1 = lja1.getEpsilon();
78 >    RealType epsilon2 = lja2.getEpsilon();
79      return sqrt(epsilon1 * epsilon2);
80    }
81  
82    void LJ::initialize() {    
122    ForceField::AtomTypeContainer* atomTypes = forceField_->getAtomTypes();
123    ForceField::AtomTypeContainer::MapTypeIterator i;
124    AtomType* at;
83  
84 <    for (at = atomTypes->beginType(i); at != NULL;
85 <         at = atomTypes->nextType(i)) {
86 <      if (at->isLennardJones()){
87 <         addType(at);
88 <      }
84 >    LJtypes.clear();
85 >    LJtids.clear();
86 >    MixingMap.clear();
87 >    nLJ_ = 0;
88 >
89 >    LJtids.resize( forceField_->getNAtomType(), -1);
90 >
91 >    set<AtomType*>::iterator at;
92 >    for (at = simTypes_.begin(); at != simTypes_.end(); ++at) {
93 >      if ((*at)->isLennardJones()) nLJ_++;
94      }
95 +
96 +    MixingMap.resize(nLJ_);
97 +
98 +    for (at = simTypes_.begin(); at != simTypes_.end(); ++at) {
99 +      if ((*at)->isLennardJones()) addType(*at);      
100 +    }
101 +
102      ForceField::NonBondedInteractionTypeContainer* nbiTypes = forceField_->getNonBondedInteractionTypes();
103      ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
104      NonBondedInteractionType* nbt;
105      ForceField::NonBondedInteractionTypeContainer::KeyType keys;
106  
137
107      for (nbt = nbiTypes->beginType(j); nbt != NULL;
108           nbt = nbiTypes->nextType(j)) {
109  
# Line 163 | Line 132 | namespace OpenMD {
132      }  
133      initialized_ = true;
134    }
166      
135  
136  
137    void LJ::addType(AtomType* atomType){
138 <    RealType sigma1 = getSigma(atomType);
139 <    RealType epsilon1 = getEpsilon(atomType);
138 >    LennardJonesAdapter lja1 = LennardJonesAdapter(atomType);
139 >
140 >    RealType sigma1 = lja1.getSigma();
141 >    RealType epsilon1 = lja1.getEpsilon();
142      
143      // add it to the map:
144 <    AtomTypeProperties atp = atomType->getATP();    
145 <
146 <    pair<map<int,AtomType*>::iterator,bool> ret;    
147 <    ret = LJMap.insert( pair<int, AtomType*>(atp.ident, atomType) );
144 >    int atid = atomType->getIdent();
145 >    int ljtid = LJtypes.size();
146 >  
147 >    pair<set<int>::iterator,bool> ret;    
148 >    ret = LJtypes.insert( atid );
149      if (ret.second == false) {
150        sprintf( painCave.errMsg,
151                 "LJ already had a previous entry with ident %d\n",
152 <               atp.ident);
152 >               atid) ;
153        painCave.severity = OPENMD_INFO;
154        painCave.isFatal = 0;
155        simError();        
156      }
157 <    
157 >
158 >    LJtids[atid] = ljtid;
159 >    MixingMap[ljtid].resize( nLJ_ );
160 >
161      // Now, iterate over all known types and add to the mixing map:
162      
163 <    std::map<int, AtomType*>::iterator it;
164 <    for( it = LJMap.begin(); it != LJMap.end(); ++it) {
191 <      
192 <      AtomType* atype2 = (*it).second;
163 >    std::set<int>::iterator it;
164 >    for( it = LJtypes.begin(); it != LJtypes.end(); ++it) {
165  
166 +      int ljtid2 = LJtids[ (*it) ];
167 +      AtomType* atype2 = forceField_->getAtomType( (*it) );
168 +
169        LJInteractionData mixer;
170        mixer.sigma = getSigma(atomType, atype2);
171        mixer.epsilon = getEpsilon(atomType, atype2);
172        mixer.sigmai = 1.0 / mixer.sigma;
173        mixer.explicitlySet = false;
174 +      MixingMap[ljtid2].resize( nLJ_ );
175  
176 <      std::pair<AtomType*, AtomType*> key1, key2;
177 <      key1 = std::make_pair(atomType, atype2);
178 <      key2 = std::make_pair(atype2, atomType);
203 <      
204 <      MixingMap[key1] = mixer;
205 <      if (key2 != key1) {
206 <        MixingMap[key2] = mixer;
176 >      MixingMap[ljtid][ljtid2] = mixer;
177 >      if (ljtid2 != ljtid) {
178 >        MixingMap[ljtid2][ljtid] = mixer;
179        }
180      }      
181    }
# Line 216 | Line 188 | namespace OpenMD {
188      mixer.sigmai = 1.0 / mixer.sigma;
189      mixer.explicitlySet = true;
190  
191 <    std::pair<AtomType*, AtomType*> key1, key2;
192 <    key1 = std::make_pair(atype1, atype2);
193 <    key2 = std::make_pair(atype2, atype1);
191 >    int atid1 = atype1->getIdent();
192 >    int atid2 = atype2->getIdent();
193 >
194 >    int ljtid1, ljtid2;
195 >
196 >    pair<set<int>::iterator,bool> ret;    
197 >    ret = LJtypes.insert( atid1 );
198 >    if (ret.second == false) {
199 >      // already had this type in the LJMap, just get the ljtid:
200 >      ljtid1 = LJtids[ atid1 ];
201 >    } else {
202 >      // didn't already have it, so make a new one and assign it:
203 >      ljtid1 = nLJ_;
204 >      LJtids[atid1] = nLJ_;
205 >      nLJ_++;
206 >    }
207 >
208 >    ret = LJtypes.insert( atid2 );
209 >    if (ret.second == false) {
210 >      // already had this type in the LJMap, just get the ljtid:
211 >      ljtid2 = LJtids[ atid2 ];
212 >    } else {
213 >      // didn't already have it, so make a new one and assign it:
214 >      ljtid2 = nLJ_;
215 >      LJtids[atid2] = nLJ_;
216 >      nLJ_++;
217 >    }
218      
219 <    MixingMap[key1] = mixer;
220 <    if (key2 != key1) {
221 <      MixingMap[key2] = mixer;
219 >    MixingMap.resize(nLJ_);
220 >    MixingMap[ljtid1].resize(nLJ_);
221 >
222 >    MixingMap[ljtid1][ljtid2] = mixer;
223 >    if (ljtid2 != ljtid1) {
224 >      MixingMap[ljtid2].resize(nLJ_);
225 >      MixingMap[ljtid2][ljtid1] = mixer;
226      }    
227    }
228  
229    void LJ::calcForce(InteractionData &idat) {
230      if (!initialized_) initialize();
231    map<pair<AtomType*, AtomType*>, LJInteractionData>::iterator it;
232    it = MixingMap.find( idat.atypes );
231      
232 <    if (it != MixingMap.end())  {
235 <      
236 <      LJInteractionData mixer = (*it).second;
237 <      
238 <      RealType sigmai = mixer.sigmai;
239 <      RealType epsilon = mixer.epsilon;
240 <      
241 <      RealType ros;
242 <      RealType rcos;
243 <      RealType myPot = 0.0;
244 <      RealType myPotC = 0.0;
245 <      RealType myDeriv = 0.0;
246 <      RealType myDerivC = 0.0;
247 <    
248 <      ros = *(idat.rij) * sigmai;    
249 <      
250 <      getLJfunc(ros, myPot, myDeriv);
251 <      
252 <      if (idat.shiftedPot) {
253 <        rcos = *(idat.rcut) * sigmai;
254 <        getLJfunc(rcos, myPotC, myDerivC);
255 <        myDerivC = 0.0;
256 <      } else if (idat.shiftedForce) {
257 <        rcos = *(idat.rcut) * sigmai;
258 <        getLJfunc(rcos, myPotC, myDerivC);
259 <        myPotC = myPotC + myDerivC * (*(idat.rij) - *(idat.rcut)) * sigmai;
260 <      } else {
261 <        myPotC = 0.0;
262 <        myDerivC = 0.0;        
263 <      }
232 >    LJInteractionData &mixer = MixingMap[LJtids[idat.atid1]][LJtids[idat.atid2]];
233  
234 <      RealType pot_temp = *(idat.vdwMult) * epsilon * (myPot - myPotC);
235 <      *(idat.vpair) += pot_temp;
236 <      
237 <      RealType dudr = *(idat.sw) * *(idat.vdwMult) * epsilon * (myDeriv -
238 <                                                                myDerivC)*sigmai;      
239 <
240 <      (*(idat.pot))[VANDERWAALS_FAMILY] += *(idat.sw) * pot_temp;
241 <      *(idat.f1) += *(idat.d) * dudr / *(idat.rij);
234 >    RealType sigmai = mixer.sigmai;
235 >    RealType epsilon = mixer.epsilon;
236 >    
237 >    RealType ros;
238 >    RealType rcos;
239 >    RealType myPot = 0.0;
240 >    RealType myPotC = 0.0;
241 >    RealType myDeriv = 0.0;
242 >    RealType myDerivC = 0.0;
243 >    
244 >    ros = *(idat.rij) * sigmai;    
245 >    
246 >    getLJfunc(ros, myPot, myDeriv);
247 >    
248 >    if (idat.shiftedPot) {
249 >      rcos = *(idat.rcut) * sigmai;
250 >      getLJfunc(rcos, myPotC, myDerivC);
251 >      myDerivC = 0.0;
252 >    } else if (idat.shiftedForce) {
253 >      rcos = *(idat.rcut) * sigmai;
254 >      getLJfunc(rcos, myPotC, myDerivC);
255 >      myPotC = myPotC + myDerivC * (*(idat.rij) - *(idat.rcut)) * sigmai;
256 >    } else {
257 >      myPotC = 0.0;
258 >      myDerivC = 0.0;        
259      }
260 +    
261 +    RealType pot_temp = *(idat.vdwMult) * epsilon * (myPot - myPotC);
262 +    *(idat.vpair) += pot_temp;
263 +    
264 +    RealType dudr = *(idat.sw) * *(idat.vdwMult) * epsilon * (myDeriv -
265 +                                                              myDerivC)*sigmai;      
266 +    (*(idat.pot))[VANDERWAALS_FAMILY] += *(idat.sw) * pot_temp;
267 +    *(idat.f1) += *(idat.d) * dudr / *(idat.rij);
268 +    
269      return;
270    }
271    
# Line 291 | Line 286 | namespace OpenMD {
286    
287    RealType LJ::getSuggestedCutoffRadius(pair<AtomType*, AtomType*> atypes) {
288      if (!initialized_) initialize();  
289 <    map<pair<AtomType*, AtomType*>, LJInteractionData>::iterator it;
290 <    it = MixingMap.find(atypes);
291 <    if (it == MixingMap.end())
292 <      return 0.0;
293 <    else  {
294 <      LJInteractionData mixer = (*it).second;
289 >    
290 >    int atid1 = atypes.first->getIdent();
291 >    int atid2 = atypes.second->getIdent();
292 >    int ljtid1 = LJtids[atid1];
293 >    int ljtid2 = LJtids[atid2];
294 >    
295 >    if (ljtid1 == -1 || ljtid2 == -1) return 0.0;
296 >    else {      
297 >      LJInteractionData mixer = MixingMap[ljtid1][ljtid2];
298        return 2.5 * mixer.sigma;
299      }
300    }
301 <
301 >  
302   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines