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 1504 by gezelter, Sat Oct 2 19:53:32 2010 UTC vs.
Revision 1505 by gezelter, Sun Oct 3 22:18:59 2010 UTC

# Line 191 | Line 191 | namespace OpenMD {
191      if (!initialized_) initialize();
192      
193      pair<AtomType*, AtomType*> key = make_pair(idat.atype1, idat.atype2);
194 <    StickyInteractionData mixer = MixingMap[key];
195 <
196 <    RealType w0  = mixer.w0;
197 <    RealType v0  = mixer.v0;
198 <    RealType v0p = mixer.v0p;
199 <    RealType rl  = mixer.rl;
200 <    RealType ru  = mixer.ru;
201 <    RealType rlp = mixer.rlp;
202 <    RealType rup = mixer.rup;
203 <    RealType rbig = mixer.rbig;
204 <    bool isPower = mixer.isPower;
205 <
206 <    if (idat.rij <= rbig) {
207 <
208 <      RealType r3 = idat.r2 * idat.rij;
209 <      RealType r5 = r3 * idat.r2;
210 <          
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 = idat.A1 * idat.d;
218 <
219 <      // negative sign because this is the vector from j to i:
220 <
221 <      Vector3d rj = - idat.A2 * idat.d;
222 <
223 <      RealType xi = ri.x();
224 <      RealType yi = ri.y();
225 <      RealType zi = ri.z();
226 <
227 <      RealType xj = rj.x();
228 <      RealType yj = rj.y();
229 <      RealType zj = rj.z();
230 <
231 <      RealType xi2 = xi * xi;
232 <      RealType yi2 = yi * yi;
233 <      RealType zi2 = zi * zi;
234 <
235 <      RealType xj2 = xj * xj;
236 <      RealType yj2 = yj * yj;
237 <      RealType zj2 = zj * zj;    
238 <
239 <      // calculate the switching info. from the splines
240 <
241 <      RealType s = 0.0;
242 <      RealType dsdr = 0.0;
243 <      RealType sp = 0.0;
244 <      RealType dspdr = 0.0;
245 <
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(idat.rij);
254 <          s = res.first;
255 <          dsdr = res.second;
256 <        }
257 <      }
258 <
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(idat.rij);
267 <          sp = res.first;
268 <          dspdr = res.second;
269 <        }
270 <      }
271 <
272 <      RealType wi = 2.0*(xi2-yi2)*zi / r3;
273 <      RealType wj = 2.0*(xj2-yj2)*zj / r3;
274 <      RealType w = wi+wj;
275 <
276 <
277 <      RealType zif = zi/idat.rij - 0.6;
278 <      RealType zis = zi/idat.rij + 0.8;
279 <
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;
285 <      RealType wp = wip + wjp;
194 >    map<pair<AtomType*, AtomType*>, StickyInteractionData>::iterator it;
195 >    it = MixingMap.find(key);
196 >    if (it != MixingMap.end()) {
197  
198 <      Vector3d dwi(4.0*xi*zi/r3  - 6.0*xi*zi*(xi2-yi2)/r5,
288 <                   - 4.0*yi*zi/r3  - 6.0*yi*zi*(xi2-yi2)/r5,
289 <                   2.0*(xi2-yi2)/r3  - 6.0*zi2*(xi2-yi2)/r5);
198 >      StickyInteractionData mixer = (*it).second;
199        
200 <      Vector3d dwj(4.0*xj*zj/r3  - 6.0*xj*zj*(xj2-yj2)/r5,
201 <                   - 4.0*yj*zj/r3  - 6.0*yj*zj*(xj2-yj2)/r5,
202 <                   2.0*(xj2-yj2)/r3  - 6.0*zj2*(xj2-yj2)/r5);
203 <
204 <      RealType uglyi = zif*zif*zis + zif*zis*zis;
205 <      RealType uglyj = zjf*zjf*zjs + zjf*zjs*zjs;
206 <
207 <      Vector3d dwip(-2.0*xi*zi*uglyi/r3,
208 <                    -2.0*yi*zi*uglyi/r3,
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/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,
308 <                     - 8.0*xi*yi*zi/r3);
309 <
310 <      Vector3d dwjdu(4.0*(yj*zj2 + 0.5*yj*(xj2-yj2))/r3,
311 <                     4.0*(xj*zj2 - 0.5*xj*(xj2-yj2))/r3,
312 <                     - 8.0*xj*yj*zj/r3);
200 >      RealType w0  = mixer.w0;
201 >      RealType v0  = mixer.v0;
202 >      RealType v0p = mixer.v0p;
203 >      RealType rl  = mixer.rl;
204 >      RealType ru  = mixer.ru;
205 >      RealType rlp = mixer.rlp;
206 >      RealType rup = mixer.rup;
207 >      RealType rbig = mixer.rbig;
208 >      bool isPower = mixer.isPower;
209        
210 <      Vector3d dwipdu(2.0*yi*uglyi/idat.rij,
211 <                      -2.0*xi*uglyi/idat.rij,
212 <                      0.0);
213 <
214 <      Vector3d dwjpdu(2.0*yj*uglyj/idat.rij,
215 <                      -2.0*xj*uglyj/idat.rij,
216 <                      0.0);
210 >      if (idat.rij <= rbig) {
211 >        
212 >        RealType r3 = idat.r2 * idat.rij;
213 >        RealType r5 = r3 * idat.r2;
214 >        
215 >        RotMat3x3d A1trans = idat.A1.transpose();
216 >        RotMat3x3d A2trans = idat.A2.transpose();
217 >        
218 >        // rotate the inter-particle separation into the two different
219 >        // body-fixed coordinate systems:
220 >        
221 >        Vector3d ri = idat.A1 * idat.d;
222 >        
223 >        // negative sign because this is the vector from j to i:
224 >        
225 >        Vector3d rj = - idat.A2 * idat.d;
226 >        
227 >        RealType xi = ri.x();
228 >        RealType yi = ri.y();
229 >        RealType zi = ri.z();
230 >        
231 >        RealType xj = rj.x();
232 >        RealType yj = rj.y();
233 >        RealType zj = rj.z();
234 >        
235 >        RealType xi2 = xi * xi;
236 >        RealType yi2 = yi * yi;
237 >        RealType zi2 = zi * zi;
238 >        
239 >        RealType xj2 = xj * xj;
240 >        RealType yj2 = yj * yj;
241 >        RealType zj2 = zj * zj;    
242 >        
243 >        // calculate the switching info. from the splines
244 >        
245 >        RealType s = 0.0;
246 >        RealType dsdr = 0.0;
247 >        RealType sp = 0.0;
248 >        RealType dspdr = 0.0;
249 >        
250 >        if (idat.rij < ru) {
251 >          if (idat.rij < rl) {
252 >            s = 1.0;
253 >            dsdr = 0.0;
254 >          } else {          
255 >            // we are in the switching region
256 >            
257 >            pair<RealType, RealType> res = mixer.s->getValueAndDerivativeAt(idat.rij);
258 >            s = res.first;
259 >            dsdr = res.second;
260 >          }
261 >        }
262 >        
263 >        if (idat.rij < rup) {
264 >          if (idat.rij < rlp) {
265 >            sp = 1.0;
266 >            dspdr = 0.0;
267 >          } else {
268 >            // we are in the switching region
269 >            
270 >            pair<RealType, RealType> res =mixer.sp->getValueAndDerivativeAt(idat.rij);
271 >            sp = res.first;
272 >            dspdr = res.second;
273 >          }
274 >        }
275 >        
276 >        RealType wi = 2.0*(xi2-yi2)*zi / r3;
277 >        RealType wj = 2.0*(xj2-yj2)*zj / r3;
278 >        RealType w = wi+wj;
279 >        
280 >        
281 >        RealType zif = zi/idat.rij - 0.6;
282 >        RealType zis = zi/idat.rij + 0.8;
283 >        
284 >        RealType zjf = zj/idat.rij - 0.6;
285 >        RealType zjs = zj/idat.rij + 0.8;
286 >        
287 >        RealType wip = zif*zif*zis*zis - w0;
288 >        RealType wjp = zjf*zjf*zjs*zjs - w0;
289 >        RealType wp = wip + wjp;
290 >        
291 >        Vector3d dwi(4.0*xi*zi/r3  - 6.0*xi*zi*(xi2-yi2)/r5,
292 >                     - 4.0*yi*zi/r3  - 6.0*yi*zi*(xi2-yi2)/r5,
293 >                     2.0*(xi2-yi2)/r3  - 6.0*zi2*(xi2-yi2)/r5);
294 >        
295 >        Vector3d dwj(4.0*xj*zj/r3  - 6.0*xj*zj*(xj2-yj2)/r5,
296 >                     - 4.0*yj*zj/r3  - 6.0*yj*zj*(xj2-yj2)/r5,
297 >                     2.0*(xj2-yj2)/r3  - 6.0*zj2*(xj2-yj2)/r5);
298 >        
299 >        RealType uglyi = zif*zif*zis + zif*zis*zis;
300 >        RealType uglyj = zjf*zjf*zjs + zjf*zjs*zjs;
301  
302 <      if (isPower) {
303 <        RealType frac1 = 0.25;
304 <        RealType frac2 = 0.75;      
305 <        RealType wi2 = wi*wi;
306 <        RealType wj2 = wj*wj;
307 <        // sticky power has no w' function:
308 <        w = frac1 * wi * wi2 + frac2*wi + frac1*wj*wj2 + frac2*wj + v0p;
309 <        wp = 0.0;
310 <        dwi = frac1*3.0*wi2*dwi + frac2*dwi;
311 <        dwj = frac1*3.0*wj2*dwi + frac2*dwi;
312 <        dwip = V3Zero;
313 <        dwjp = V3Zero;
314 <        dwidu = frac1*3.0*wi2*dwidu + frac2*dwidu;
315 <        dwidu = frac1*3.0*wj2*dwjdu + frac2*dwjdu;
316 <        dwipdu = V3Zero;
317 <        dwjpdu = V3Zero;
318 <        sp = 0.0;
319 <        dspdr = 0.0;
302 >        Vector3d dwip(-2.0*xi*zi*uglyi/r3,
303 >                      -2.0*yi*zi*uglyi/r3,
304 >                      2.0*(1.0/idat.rij - zi2/r3)*uglyi);
305 >        
306 >        Vector3d dwjp(-2.0*xj*zj*uglyj/r3,
307 >                      -2.0*yj*zj*uglyj/r3,
308 >                      2.0*(1.0/idat.rij - zj2/r3)*uglyj);
309 >        
310 >        Vector3d dwidu(4.0*(yi*zi2 + 0.5*yi*(xi2-yi2))/r3,
311 >                       4.0*(xi*zi2 - 0.5*xi*(xi2-yi2))/r3,
312 >                       - 8.0*xi*yi*zi/r3);
313 >        
314 >        Vector3d dwjdu(4.0*(yj*zj2 + 0.5*yj*(xj2-yj2))/r3,
315 >                       4.0*(xj*zj2 - 0.5*xj*(xj2-yj2))/r3,
316 >                       - 8.0*xj*yj*zj/r3);
317 >        
318 >        Vector3d dwipdu(2.0*yi*uglyi/idat.rij,
319 >                        -2.0*xi*uglyi/idat.rij,
320 >                        0.0);
321 >        
322 >        Vector3d dwjpdu(2.0*yj*uglyj/idat.rij,
323 >                        -2.0*xj*uglyj/idat.rij,
324 >                        0.0);
325 >        
326 >        if (isPower) {
327 >          RealType frac1 = 0.25;
328 >          RealType frac2 = 0.75;      
329 >          RealType wi2 = wi*wi;
330 >          RealType wj2 = wj*wj;
331 >          // sticky power has no w' function:
332 >          w = frac1 * wi * wi2 + frac2*wi + frac1*wj*wj2 + frac2*wj + v0p;
333 >          wp = 0.0;
334 >          dwi = frac1*3.0*wi2*dwi + frac2*dwi;
335 >          dwj = frac1*3.0*wj2*dwi + frac2*dwi;
336 >          dwip = V3Zero;
337 >          dwjp = V3Zero;
338 >          dwidu = frac1*3.0*wi2*dwidu + frac2*dwidu;
339 >          dwidu = frac1*3.0*wj2*dwjdu + frac2*dwjdu;
340 >          dwipdu = V3Zero;
341 >          dwjpdu = V3Zero;
342 >          sp = 0.0;
343 >          dspdr = 0.0;
344 >        }
345 >        
346 >        idat.vpair += 0.5*(v0*s*w + v0p*sp*wp);
347 >        idat.pot += 0.5*(v0*s*w + v0p*sp*wp)*idat.sw;
348 >        
349 >        // do the torques first since they are easy:
350 >        // remember that these are still in the body-fixed axes
351 >        
352 >        Vector3d ti = 0.5*idat.sw*(v0*s*dwidu + v0p*sp*dwipdu);
353 >        Vector3d tj = 0.5*idat.sw*(v0*s*dwjdu + v0p*sp*dwjpdu);
354 >        
355 >        // go back to lab frame using transpose of rotation matrix:
356 >        
357 >        idat.t1 += A1trans * ti;
358 >        idat.t2 += A2trans * tj;
359 >        
360 >        // Now, on to the forces:
361 >        
362 >        // first rotate the i terms back into the lab frame:
363 >        
364 >        Vector3d radcomi = (v0 * s * dwi + v0p * sp * dwip) * idat.sw;
365 >        Vector3d radcomj = (v0 * s * dwj + v0p * sp * dwjp) * idat.sw;
366 >        
367 >        Vector3d fii = A1trans * radcomi;
368 >        Vector3d fjj = A2trans * radcomj;
369 >        
370 >        // now assemble these with the radial-only terms:
371 >        
372 >        idat.f1 += 0.5 * ((v0*dsdr*w + v0p*dspdr*wp) * idat.d /
373 >                          idat.rij + fii - fjj);
374 >        
375        }
341
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*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      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) * 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      idat.f1 += 0.5 * ((v0*dsdr*w + v0p*dspdr*wp) * idat.d /
369                        idat.rij + fii - fjj);
370
376      }
372      
373    return;
377      
378 +    return;      
379    }
380 +
381 +  RealType Sticky::getSuggestedCutoffRadius(AtomType* at1, AtomType* at2) {
382 +    if (!initialized_) initialize();  
383 +    pair<AtomType*, AtomType*> key = make_pair(at1, at2);
384 +    map<pair<AtomType*, AtomType*>, StickyInteractionData>::iterator it;
385 +    it = MixingMap.find(key);
386 +    if (it == MixingMap.end())
387 +      return 0.0;
388 +    else  {
389 +      StickyInteractionData mixer = (*it).second;
390 +      return mixer.rbig;
391 +    }
392 +  }
393   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines