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

Comparing branches/development/src/nonbonded/Sticky.cpp (file contents):
Revision 1485 by gezelter, Wed Jul 28 19:52:00 2010 UTC vs.
Revision 1502 by gezelter, Sat Oct 2 19:53:32 2010 UTC

# Line 49 | Line 49 | namespace OpenMD {
49  
50   using namespace std;
51   namespace OpenMD {
52
53  bool Sticky::initialized_ = false;
54  ForceField* Sticky::forceField_ = NULL;
55  map<int, AtomType*> Sticky::StickyMap;
56  map<pair<AtomType*, AtomType*>, StickyInteractionData> Sticky::MixingMap;
52    
53 <  Sticky* Sticky::_instance = NULL;
53 >  Sticky::Sticky() : name_("Sticky"), initialized_(false), forceField_(NULL) {}
54    
60  Sticky* Sticky::Instance() {
61    if (!_instance) {
62      _instance = new Sticky();
63    }
64    return _instance;
65  }
66  
55    StickyParam Sticky::getStickyParam(AtomType* atomType) {
56      
57      // Do sanity checking on the AtomType we were passed before
# Line 189 | Line 177 | namespace OpenMD {
177      }
178    }
179  
180 <  RealType Sticky::getStickyCut(int atid) {
181 <    if (!initialized_) initialize();
182 <    std::map<int, AtomType*> :: const_iterator it;
183 <    it = StickyMap.find(atid);
184 <    if (it == StickyMap.end()) {
185 <      sprintf( painCave.errMsg,
186 <               "Sticky::getStickyCut could not find atid %d in StickyMap\n",
187 <               (atid));
188 <      painCave.severity = OPENMD_ERROR;
189 <      painCave.isFatal = 1;
190 <      simError();          
203 <    }
204 <
205 <    AtomType* atype = it->second;
206 <    return MixingMap[make_pair(atype, atype)].rbig;
207 <  }
208 <
209 <
210 <  void Sticky::calcForce(AtomType* at1, AtomType* at2, Vector3d d,
211 <                         RealType rij, RealType r2, RealType sw,
212 <                         RealType &vpair, RealType &pot,
213 <                         RotMat3x3d A1, RotMat3x3d A2, Vector3d &f1,
214 <                         Vector3d &t1, Vector3d &t2) {
215 <
216 <    // This routine does only the sticky portion of the SSD potential
217 <    // [Chandra and Ichiye, J. Chem. Phys. 111, 2701 (1999)].
218 <    // The Lennard-Jones and dipolar interaction must be handled separately.
219 <    
220 <    // We assume that the rotation matrices have already been calculated
221 <    // and placed in the A array.
222 <    
180 >  /**
181 >   * This function does the sticky portion of the SSD potential
182 >   * [Chandra and Ichiye, Journal of Chemical Physics 111, 2701
183 >   * (1999)].  The Lennard-Jones and dipolar interaction must be
184 >   * handled separately.  We assume that the rotation matrices have
185 >   * already been calculated and placed in the A1 & A2 entries in the
186 >   * idat structure.
187 >   */
188 >  
189 >  void Sticky::calcForce(InteractionData idat) {
190 >  
191      if (!initialized_) initialize();
192      
193 <    pair<AtomType*, AtomType*> key = make_pair(at1, at2);
193 >    pair<AtomType*, AtomType*> key = make_pair(idat.atype1, idat.atype2);
194      StickyInteractionData mixer = MixingMap[key];
195  
196      RealType w0  = mixer.w0;
# Line 235 | Line 203 | namespace OpenMD {
203      RealType rbig = mixer.rbig;
204      bool isPower = mixer.isPower;
205  
206 <    if (rij <= rbig) {
206 >    if (idat.rij <= rbig) {
207  
208 <      RealType r3 = r2 * rij;
209 <      RealType r5 = r3 * r2;
208 >      RealType r3 = idat.r2 * idat.rij;
209 >      RealType r5 = r3 * idat.r2;
210            
211 <      RotMat3x3d A1trans = A1.transpose();
212 <      RotMat3x3d A2trans = A2.transpose();
211 >      RotMat3x3d A1trans = idat.A1.transpose();
212 >      RotMat3x3d A2trans = idat.A2.transpose();
213  
214        // rotate the inter-particle separation into the two different
215        // body-fixed coordinate systems:
216  
217 <      Vector3d ri = A1 * d;
217 >      Vector3d ri = idat.A1 * idat.d;
218  
219        // negative sign because this is the vector from j to i:
220  
221 <      Vector3d rj = -A2 * d;
221 >      Vector3d rj = - idat.A2 * idat.d;
222  
223        RealType xi = ri.x();
224        RealType yi = ri.y();
# Line 275 | Line 243 | namespace OpenMD {
243        RealType sp = 0.0;
244        RealType dspdr = 0.0;
245  
246 <      if (rij < ru) {
247 <        if (rij < rl) {
246 >      if (idat.rij < ru) {
247 >        if (idat.rij < rl) {
248            s = 1.0;
249            dsdr = 0.0;
250          } else {          
251            // we are in the switching region
252  
253 <          pair<RealType, RealType> res = mixer.s->getValueAndDerivativeAt(rij);
253 >          pair<RealType, RealType> res = mixer.s->getValueAndDerivativeAt(idat.rij);
254            s = res.first;
255            dsdr = res.second;
256          }
257        }
258  
259 <      if (rij < rup) {
260 <        if (rij < rlp) {
259 >      if (idat.rij < rup) {
260 >        if (idat.rij < rlp) {
261            sp = 1.0;
262            dspdr = 0.0;
263          } else {
264            // we are in the switching region
265  
266 <          pair<RealType, RealType> res =mixer.sp->getValueAndDerivativeAt(rij);
266 >          pair<RealType, RealType> res =mixer.sp->getValueAndDerivativeAt(idat.rij);
267            sp = res.first;
268            dspdr = res.second;
269          }
# Line 306 | Line 274 | namespace OpenMD {
274        RealType w = wi+wj;
275  
276  
277 <      RealType zif = zi/rij - 0.6;
278 <      RealType zis = zi/rij + 0.8;
277 >      RealType zif = zi/idat.rij - 0.6;
278 >      RealType zis = zi/idat.rij + 0.8;
279  
280 <      RealType zjf = zj/rij - 0.6;
281 <      RealType zjs = zj/rij + 0.8;
280 >      RealType zjf = zj/idat.rij - 0.6;
281 >      RealType zjs = zj/idat.rij + 0.8;
282  
283        RealType wip = zif*zif*zis*zis - w0;
284        RealType wjp = zjf*zjf*zjs*zjs - w0;
# Line 329 | Line 297 | namespace OpenMD {
297  
298        Vector3d dwip(-2.0*xi*zi*uglyi/r3,
299                      -2.0*yi*zi*uglyi/r3,
300 <                    2.0*(1.0/rij - zi2/r3)*uglyi);
300 >                    2.0*(1.0/idat.rij - zi2/r3)*uglyi);
301  
302        Vector3d dwjp(-2.0*xj*zj*uglyj/r3,
303                      -2.0*yj*zj*uglyj/r3,
304 <                    2.0*(1.0/rij - zj2/r3)*uglyj);
304 >                    2.0*(1.0/idat.rij - zj2/r3)*uglyj);
305  
306        Vector3d dwidu(4.0*(yi*zi2 + 0.5*yi*(xi2-yi2))/r3,
307                       4.0*(xi*zi2 - 0.5*xi*(xi2-yi2))/r3,
# Line 343 | Line 311 | namespace OpenMD {
311                       4.0*(xj*zj2 - 0.5*xj*(xj2-yj2))/r3,
312                       - 8.0*xj*yj*zj/r3);
313        
314 <      Vector3d dwipdu(2.0*yi*uglyi/rij,
315 <                      -2.0*xi*uglyi/rij,
314 >      Vector3d dwipdu(2.0*yi*uglyi/idat.rij,
315 >                      -2.0*xi*uglyi/idat.rij,
316                        0.0);
317  
318 <      Vector3d dwjpdu(2.0*yj*uglyj/rij,
319 <                      -2.0*xj*uglyj/rij,
318 >      Vector3d dwjpdu(2.0*yj*uglyj/idat.rij,
319 >                      -2.0*xj*uglyj/idat.rij,
320                        0.0);
321  
322        if (isPower) {
# Line 371 | Line 339 | namespace OpenMD {
339          dspdr = 0.0;
340        }
341  
342 <      vpair += 0.5*(v0*s*w + v0p*sp*wp);
343 <      pot += 0.5*(v0*s*w + v0p*sp*wp)*sw;
342 >      idat.vpair += 0.5*(v0*s*w + v0p*sp*wp);
343 >      idat.pot += 0.5*(v0*s*w + v0p*sp*wp)*idat.sw;
344  
345        // do the torques first since they are easy:
346        // remember that these are still in the body-fixed axes
347  
348 <      Vector3d ti = 0.5*sw*(v0*s*dwidu + v0p*sp*dwipdu);
349 <      Vector3d tj = 0.5*sw*(v0*s*dwjdu + v0p*sp*dwjpdu);
348 >      Vector3d ti = 0.5*idat.sw*(v0*s*dwidu + v0p*sp*dwipdu);
349 >      Vector3d tj = 0.5*idat.sw*(v0*s*dwjdu + v0p*sp*dwjpdu);
350  
351        // go back to lab frame using transpose of rotation matrix:
352  
353 <      t1 += A1trans * ti;
354 <      t2 += A2trans * tj;
353 >      idat.t1 += A1trans * ti;
354 >      idat.t2 += A2trans * tj;
355  
356        // Now, on to the forces:
357  
358        // first rotate the i terms back into the lab frame:
359  
360 <      Vector3d radcomi = (v0 * s * dwi + v0p * sp * dwip) * sw;
361 <      Vector3d radcomj = (v0 * s * dwj + v0p * sp * dwjp) * sw;
360 >      Vector3d radcomi = (v0 * s * dwi + v0p * sp * dwip) * idat.sw;
361 >      Vector3d radcomj = (v0 * s * dwj + v0p * sp * dwjp) * idat.sw;
362  
363        Vector3d fii = A1trans * radcomi;
364        Vector3d fjj = A2trans * radcomj;
365        
366        // now assemble these with the radial-only terms:
367        
368 <      f1 += 0.5 * ((v0*dsdr*w + v0p*dspdr*wp) * d / rij + fii - fjj);
368 >      idat.f1 += 0.5 * ((v0*dsdr*w + v0p*dspdr*wp) * idat.d /
369 >                        idat.rij + fii - fjj);
370  
371      }
372        
373      return;
374      
375    }
407
408  void Sticky::do_sticky_pair(int *atid1, int *atid2, RealType *d,
409                              RealType *r, RealType *r2, RealType *sw,
410                              RealType *vpair, RealType *pot, RealType *A1,
411                              RealType *A2, RealType *f1,
412                              RealType *t1, RealType *t2) {
413    
414    if (!initialized_) initialize();
415    
416    AtomType* atype1 = StickyMap[*atid1];
417    AtomType* atype2 = StickyMap[*atid2];
418    
419    Vector3d disp(d);
420    Vector3d frc(f1);
421    Vector3d trq1(t1);
422    Vector3d trq2(t2);
423    RotMat3x3d Ai(A1);
424    RotMat3x3d Aj(A2);
425  
426    calcForce(atype1, atype2, disp, *r, *r2, *sw, *vpair, *pot,
427              Ai, Aj, frc, trq1, trq2);
428      
429    f1[0] = frc.x();
430    f1[1] = frc.y();
431    f1[2] = frc.z();
432
433    t1[0] = trq1.x();
434    t1[1] = trq1.y();
435    t1[2] = trq1.z();
436
437    t2[0] = trq2.x();
438    t2[1] = trq2.y();
439    t2[2] = trq2.z();
440
441    return;    
442  }
376   }
444
445 extern "C" {
446  
447 #define fortranGetStickyCut FC_FUNC(getstickycut, GETSTICKYCUT)
448 #define fortranDoStickyPair FC_FUNC(do_sticky_pair, DO_STICKY_PAIR)
449  
450  RealType fortranGetStickyCut(int* atid) {
451    return OpenMD::Sticky::Instance()->getStickyCut(*atid);
452  }
453
454  void fortranDoStickyPair(int *atid1, int *atid2, RealType *d, RealType *r,
455                       RealType *r2, RealType *sw, RealType *vpair, RealType *pot,
456                       RealType *A1, RealType *A2, RealType *f1,
457                       RealType *t1, RealType *t2){
458    
459    return OpenMD::Sticky::Instance()->do_sticky_pair(atid1, atid2, d, r, r2,
460                                                      sw, vpair, pot, A1, A2,
461                                                      f1, t1, t2);
462  }
463 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines