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

Comparing branches/development/src/nonbonded/Morse.cpp (file contents):
Revision 1501 by gezelter, Wed Sep 15 19:32:10 2010 UTC vs.
Revision 1583 by gezelter, Thu Jun 16 22:00:08 2011 UTC

# Line 51 | Line 51 | namespace OpenMD {
51  
52   namespace OpenMD {
53  
54 <  bool Morse::initialized_ = false;
55 <  bool Morse::shiftedPot_ = false;
56 <  bool Morse::shiftedFrc_ = false;
57 <  ForceField* Morse::forceField_ = NULL;
58 <  map<int, AtomType*> Morse::MorseMap;
59 <  map<pair<AtomType*, AtomType*>, MorseInteractionData> Morse::MixingMap;
60 <  map<string, MorseInteractionType> Morse::stringToEnumMap_;
54 >  Morse::Morse() : name_("Morse"), initialized_(false), forceField_(NULL) {}
55    
62  Morse* Morse::_instance = NULL;
63
64  Morse* Morse::Instance() {
65    if (!_instance) {
66      _instance = new Morse();
67    }
68    return _instance;
69  }
70
56    void Morse::initialize() {    
57  
58      stringToEnumMap_["shiftedMorse"] = shiftedMorse;
# Line 140 | Line 125 | namespace OpenMD {
125                                       RealType De, RealType Re, RealType beta,
126                                       MorseInteractionType mit) {
127  
143    AtomTypeProperties atp = atype1->getATP();    
144    MorseMap.insert( pair<int, AtomType*>(atp.ident, atype1) );
145
146    atp = atype2->getATP();    
147    MorseMap.insert( pair<int, AtomType*>(atp.ident, atype2) );
148
128      MorseInteractionData mixer;
129      mixer.De = De;
130      mixer.Re = Re;
# Line 162 | Line 141 | namespace OpenMD {
141      }    
142    }
143    
144 <  void Morse::calcForce(AtomType* at1, AtomType* at2, Vector3d d,
166 <                        RealType r, RealType r2, RealType rcut, RealType sw,
167 <                        RealType vdwMult, RealType &vpair, RealType &pot,
168 <                        Vector3d &f1) {
144 >  void Morse::calcForce(InteractionData &idat) {
145  
146      if (!initialized_) initialize();
147      
148 <    RealType myPot = 0.0;
149 <    RealType myPotC = 0.0;
150 <    RealType myDeriv = 0.0;
151 <    RealType myDerivC = 0.0;
152 <
153 <    pair<AtomType*, AtomType*> key = make_pair(at1, at2);
154 <    MorseInteractionData mixer = MixingMap[key];
155 <
156 <    RealType De = mixer.De;
157 <    RealType Re = mixer.Re;
158 <    RealType beta = mixer.beta;
159 <    MorseInteractionType interactionType = mixer.interactionType;
160 <  
161 <    // V(r) = D_e exp(-a(r-re)(exp(-a(r-re))-2)
162 <    
163 <    RealType expt     = -beta*(r - Re);
164 <    RealType expfnc   = exp(expt);
165 <    RealType expfnc2  = expfnc*expfnc;
166 <
167 <    RealType exptC = 0.0;
168 <    RealType expfncC = 0.0;
169 <    RealType expfnc2C = 0.0;
170 <
171 <    if (Morse::shiftedPot_ || Morse::shiftedFrc_) {
172 <      exptC     = -beta*(rcut - Re);
173 <      expfncC   = exp(exptC);
174 <      expfnc2C  = expfncC*expfncC;
175 <    }
176 <
201 <
202 <    switch(interactionType) {
203 <    case shiftedMorse : {
204 <
205 <      myPot  = De * (expfnc2  - 2.0 * expfnc);
206 <      myDeriv   = 2.0 * De * beta * (expfnc - expfnc2);
207 <
208 <      if (Morse::shiftedPot_) {
209 <        myPotC = De * (expfnc2C - 2.0 * expfncC);
210 <        myDerivC = 0.0;
211 <      } else if (Morse::shiftedFrc_) {
212 <        myPotC = De * (expfnc2C - 2.0 * expfncC);
213 <        myDerivC  = 2.0 * De * beta * (expfnc2C - expfnc2C);
214 <        myPotC += myDerivC * (r - rcut);
215 <      } else {
216 <        myPotC = 0.0;
217 <        myDerivC = 0.0;
148 >    map<pair<AtomType*, AtomType*>, MorseInteractionData>::iterator it;
149 >    it = MixingMap.find( idat.atypes );
150 >    if (it != MixingMap.end()) {
151 >      MorseInteractionData mixer = (*it).second;
152 >      
153 >      RealType myPot = 0.0;
154 >      RealType myPotC = 0.0;
155 >      RealType myDeriv = 0.0;
156 >      RealType myDerivC = 0.0;
157 >      
158 >      RealType De = mixer.De;
159 >      RealType Re = mixer.Re;
160 >      RealType beta = mixer.beta;
161 >      MorseInteractionType interactionType = mixer.interactionType;
162 >      
163 >      // V(r) = D_e exp(-a(r-re)(exp(-a(r-re))-2)
164 >      
165 >      RealType expt     = -beta*( *(idat.rij) - Re);
166 >      RealType expfnc   = exp(expt);
167 >      RealType expfnc2  = expfnc*expfnc;
168 >      
169 >      RealType exptC = 0.0;
170 >      RealType expfncC = 0.0;
171 >      RealType expfnc2C = 0.0;
172 >      
173 >      if (idat.shiftedPot || idat.shiftedForce) {
174 >        exptC     = -beta*( *(idat.rcut) - Re);
175 >        expfncC   = exp(exptC);
176 >        expfnc2C  = expfncC*expfncC;
177        }
178 <
179 <      break;
180 <    }
181 <    case repulsiveMorse : {
182 <
183 <      myPot  = De * expfnc2;
184 <      myDeriv  = -2.0 * De * beta * expfnc2;
185 <
186 <      if (Morse::shiftedPot_) {
187 <        myPotC = De * expfnc2C;
188 <        myDerivC = 0.0;
189 <      } else if (Morse::shiftedFrc_) {
190 <        myPotC = De * expfnc2C;
191 <        myDerivC = -2.0 * De * beta * expfnc2C;
192 <        myPotC += myDerivC * (r - rcut);
193 <      } else {
194 <        myPotC = 0.0;
195 <        myDerivC = 0.0;
178 >      
179 >      
180 >      switch(interactionType) {
181 >      case shiftedMorse : {
182 >        
183 >        myPot  = De * (expfnc2  - 2.0 * expfnc);
184 >        myDeriv   = 2.0 * De * beta * (expfnc - expfnc2);
185 >        
186 >        if (idat.shiftedPot) {
187 >          myPotC = De * (expfnc2C - 2.0 * expfncC);
188 >          myDerivC = 0.0;
189 >        } else if (idat.shiftedForce) {
190 >          myPotC = De * (expfnc2C - 2.0 * expfncC);
191 >          myDerivC  = 2.0 * De * beta * (expfnc2C - expfnc2C);
192 >          myPotC += myDerivC * ( *(idat.rij) - *(idat.rcut) );
193 >        } else {
194 >          myPotC = 0.0;
195 >          myDerivC = 0.0;
196 >        }
197 >        
198 >        break;
199        }
200 <
201 <      break;
200 >      case repulsiveMorse : {
201 >        
202 >        myPot  = De * expfnc2;
203 >        myDeriv  = -2.0 * De * beta * expfnc2;
204 >        
205 >        if (idat.shiftedPot) {
206 >          myPotC = De * expfnc2C;
207 >          myDerivC = 0.0;
208 >        } else if (idat.shiftedForce) {
209 >          myPotC = De * expfnc2C;
210 >          myDerivC = -2.0 * De * beta * expfnc2C;
211 >          myPotC += myDerivC * ( *(idat.rij) - *(idat.rcut));
212 >        } else {
213 >          myPotC = 0.0;
214 >          myDerivC = 0.0;
215 >        }
216 >        
217 >        break;
218 >      }
219 >      }
220 >      
221 >      RealType pot_temp = *(idat.vdwMult) * (myPot - myPotC);
222 >      *(idat.vpair) += pot_temp;
223 >      
224 >      RealType dudr = *(idat.sw) * *(idat.vdwMult) * (myDeriv - myDerivC);
225 >      
226 >      (*(idat.pot))[VANDERWAALS_FAMILY] += *(idat.sw) * pot_temp;
227 >      *(idat.f1) = *(idat.d) * dudr / *(idat.rij);
228      }
241    }
242
243    RealType pot_temp = vdwMult * (myPot - myPotC);
244    vpair += pot_temp;
245
246    RealType dudr = sw * vdwMult * (myDeriv - myDerivC);
247    
248    pot += sw * pot_temp;
249    f1 = d * dudr / r;
250
229      return;
252
253  }
254
255  void Morse::do_morse_pair(int *atid1, int *atid2, RealType *d,
256                            RealType *rij, RealType *r2, RealType *rcut,
257                            RealType *sw, RealType *vdwMult,
258                            RealType *vpair, RealType *pot, RealType *f1) {
259
260    if (!initialized_) initialize();
230      
262    AtomType* atype1 = MorseMap[*atid1];
263    AtomType* atype2 = MorseMap[*atid2];
264    
265    Vector3d disp(d[0], d[1], d[2]);
266    Vector3d frc(f1[0], f1[1], f1[2]);
267    
268    calcForce(atype1, atype2, disp, *rij, *r2, *rcut, *sw, *vdwMult, *vpair,
269              *pot, frc);
270      
271    f1[0] = frc.x();
272    f1[1] = frc.y();
273    f1[2] = frc.z();
274
275    return;    
231    }
232      
233 <  void Morse::setMorseDefaultCutoff(RealType *thisRcut, int *sP, int *sF) {
234 <    shiftedPot_ = (bool)(*sP);
235 <    shiftedFrc_ = (bool)(*sF);
236 <  }
237 < }
233 >  RealType Morse::getSuggestedCutoffRadius(pair<AtomType*, AtomType*> atypes) {
234 >    if (!initialized_) initialize();  
235 >    map<pair<AtomType*, AtomType*>, MorseInteractionData>::iterator it;
236 >    it = MixingMap.find(atypes);
237 >    if (it == MixingMap.end())
238 >      return 0.0;
239 >    else  {
240 >      MorseInteractionData mixer = (*it).second;
241  
242 < extern "C" {
243 <  
244 < #define fortranSetMorseCutoff FC_FUNC(setmorsedefaultcutoff, SETMORSEDEFAULTCUTOFF)
245 < #define fortranDoMorsePair FC_FUNC(do_morse_pair, DO_MORSE_PAIR)
246 <  
247 <  void fortranSetMorseCutoff(RealType *rcut, int *shiftedPot, int *shiftedFrc) {
248 <    return OpenMD::Morse::Instance()->setMorseDefaultCutoff(rcut, shiftedPot,
249 <                                                            shiftedFrc);
242 >      RealType Re = mixer.Re;
243 >      RealType beta = mixer.beta;
244 >      // This value of the r corresponds to an energy about 1.48% of
245 >      // the energy at the bottom of the Morse well.  For comparison, the
246 >      // Lennard-Jones function is about 1.63% of it's minimum value at
247 >      // a distance of 2.5 sigma.
248 >      return (4.9 + beta * Re) / beta;
249 >    }
250    }
293  void fortranDoMorsePair(int *atid1, int *atid2, RealType *d, RealType *rij,
294                          RealType *r2, RealType *rcut, RealType *sw,
295                          RealType *vdwMult, RealType* vpair, RealType* pot,
296                          RealType *f1){
297    
298    return OpenMD::Morse::Instance()->do_morse_pair(atid1, atid2, d, rij, r2,
299                                                    rcut, sw, vdwMult, vpair,
300                                                    pot, f1);
301  }
251   }
252 +

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines