ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/trunk/OOPSE/libmdtools/NPTi.cpp
(Generate patch)

Comparing trunk/OOPSE/libmdtools/NPTi.cpp (file contents):
Revision 763 by tim, Mon Sep 15 16:52:02 2003 UTC vs.
Revision 772 by gezelter, Fri Sep 19 16:01:07 2003 UTC

# Line 13 | Line 13
13   #include "mpiSimulation.hpp"
14   #endif
15  
16
16   // Basic isotropic thermostating and barostating via the Melchionna
17   // modification of the Hoover algorithm:
18   //
# Line 56 | Line 55 | template<typename T> void NPTi<T>::moveA() {
55   }
56  
57   template<typename T> void NPTi<T>::moveA() {
59
60
61 //   int i, j;
62 //   DirectionalAtom* dAtom;
63 //   double Tb[3], ji[3];
64 //   double A[3][3], I[3][3];
65 //   double angle, mass;
66 //   double vel[3], pos[3], frc[3];
67
68 //   double rj[3];
69 //   double instaTemp, instaPress, instaVol;
70 //   double tt2, tb2, scaleFactor;
71
72 //   tt2 = tauThermostat * tauThermostat;
73 //   tb2 = tauBarostat * tauBarostat;
74
75 //   instaTemp = tStats->getTemperature();
76 //   instaPress = tStats->getPressure();
77 //   instaVol = tStats->getVolume();
78  
79 //    // first evolve chi a half step
80  
81 //   chi += dt2 * ( instaTemp / targetTemp - 1.0) / tt2;
82 //   eta += dt2 * ( instaVol * (instaPress - targetPressure) /
83 //               (p_convert*NkBT*tb2));
84
85 //   integralOfChidt += dt2* chi;
86
87 //   for( i=0; i<nAtoms; i++ ){
88 //     atoms[i]->getVel( vel );
89 //     atoms[i]->getPos( pos );
90 //     atoms[i]->getFrc( frc );
91
92 //     mass = atoms[i]->getMass();
93
94 //     for (j=0; j < 3; j++) {
95 //       vel[j] += dt2 * ((frc[j] / mass ) * eConvert - vel[j]*(chi+eta));
96 //       rj[j] = pos[j];
97 //     }
98
99 //     atoms[i]->setVel( vel );
100
101 //     info->wrapVector(rj);
102
103 //     for (j = 0; j < 3; j++)
104 //       pos[j] += dt * (vel[j] + eta*rj[j]);
105
106 //     atoms[i]->setPos( pos );
107
108 //     if( atoms[i]->isDirectional() ){
109
110 //       dAtom = (DirectionalAtom *)atoms[i];
111          
112 //       // get and convert the torque to body frame
113      
114 //       dAtom->getTrq( Tb );
115 //       dAtom->lab2Body( Tb );
116      
117 //       // get the angular momentum, and propagate a half step
118
119 //       dAtom->getJ( ji );
120
121 //       for (j=0; j < 3; j++)
122 //         ji[j] += dt2 * (Tb[j] * eConvert - ji[j]*chi);
123      
124 //       // use the angular velocities to propagate the rotation matrix a
125 //       // full time step
126
127 //       dAtom->getA(A);
128 //       dAtom->getI(I);
129    
130 //       // rotate about the x-axis      
131 //       angle = dt2 * ji[0] / I[0][0];
132 //       this->rotate( 1, 2, angle, ji, A );
133
134 //       // rotate about the y-axis
135 //       angle = dt2 * ji[1] / I[1][1];
136 //       this->rotate( 2, 0, angle, ji, A );
137      
138 //       // rotate about the z-axis
139 //       angle = dt * ji[2] / I[2][2];
140 //       this->rotate( 0, 1, angle, ji, A);
141      
142 //       // rotate about the y-axis
143 //       angle = dt2 * ji[1] / I[1][1];
144 //       this->rotate( 2, 0, angle, ji, A );
145      
146 //        // rotate about the x-axis
147 //       angle = dt2 * ji[0] / I[0][0];
148 //       this->rotate( 1, 2, angle, ji, A );
149      
150 //       dAtom->setJ( ji );
151 //       dAtom->setA( A  );    
152 //     }                
153
154 //   }
155
156 //   // Scale the box after all the positions have been moved:
157  
158 //   scaleFactor = exp(dt*eta);
159
160 //   if ((scaleFactor > 1.1) || (scaleFactor < 0.9)) {
161 //     sprintf( painCave.errMsg,
162 //              "NPTi error: Attempting a Box scaling of more than 10 percent"
163 //              " check your tauBarostat, as it is probably too small!\n"
164 //              " eta = %lf, scaleFactor = %lf\n", eta, scaleFactor
165 //              );
166 //     painCave.isFatal = 1;
167 //     simError();
168 //   } else {        
169 //     info->scaleBox(exp(dt*eta));      
170 //   }
171  
58  
59    //new version of NPTi
60    int i, j, k;
# Line 201 | Line 87 | template<typename T> void NPTi<T>::moveA() {
87      mass = atoms[i]->getMass();
88  
89      for (j=0; j < 3; j++) {
90 <      // velocity half step  (use chi from previous step here):
90 >      // velocity half step
91        vel[j] += dt2 * ((frc[j] / mass ) * eConvert - vel[j]*(chi + eta));
206  
92      }
93  
94      atoms[i]->setVel( vel );
# Line 255 | Line 140 | template<typename T> void NPTi<T>::moveA() {
140      }    
141    }
142  
143 <  // evolve chi and eta  half step
143 >  // advance chi half step
144    
145    chi += dt2 * ( instaTemp / targetTemp - 1.0) / tt2;
261  eta += dt2 * ( instaVol * (instaPress - targetPressure) / (p_convert*NkBT*tb2));
146  
147 <  //calculate the integral of chidt
147 >  // calculate the integral of chidt
148 >
149    integralOfChidt += dt2*chi;
150  
151 +  // advance eta half step
152 +
153 +  eta += dt2 * ( instaVol * (instaPress - targetPressure) / (p_convert*NkBT*tb2));
154 +
155    //save the old positions
156    for(i = 0; i < nAtoms; i++){
157      atoms[i]->getPos(pos);
# Line 280 | Line 169 | template<typename T> void NPTi<T>::moveA() {
169        atoms[i]->getPos(pos);
170  
171        for(j = 0; j < 3; j++)
172 <        rj[j] = (oldPos[i*3 + j] + pos[j])/2 - COM[j];
284 <
172 >        rj[j] = (oldPos[i*3 + j] + pos[j])/2 - COM[j];    
173        
286      //wrapVector(r(t)) = r(t)-R0
287      //info->wrapVector(rj);
288      
174        for(j = 0; j < 3; j++)
175          pos[j] = oldPos[i*3 + j] + dt*(vel[j] + eta*rj[j]);
176  
177        atoms[i]->setPos( pos );
293
178      }
179 <
179 >    
180 >    if (nConstrained){
181 >      constrainA();
182 >    }
183    }
184      
185  
# Line 312 | Line 199 | template<typename T> void NPTi<T>::moveA() {
199      info->scaleBox(scaleFactor);      
200    }  
201  
315  //advance volume;
316  volume = volume * exp(dt*eta);
202   }
203  
204   template<typename T> void NPTi<T>::moveB( void ){
320
321 /*
322  int i, j;
323  DirectionalAtom* dAtom;
324  double Tb[3], ji[3];
325  double vel[3], frc[3];
326  double mass;
327
328  double instaTemp, instaPress, instaVol;
329  double tt2, tb2;
330  
331  tt2 = tauThermostat * tauThermostat;
332  tb2 = tauBarostat * tauBarostat;
333
334  instaTemp = tStats->getTemperature();
335  instaPress = tStats->getPressure();
336  instaVol = tStats->getVolume();
337
338  chi += dt2 * ( instaTemp / targetTemp - 1.0) / tt2;
339  eta += dt2 * ( instaVol * (instaPress - targetPressure) /
340                 (p_convert*NkBT*tb2));
341  integralOfChidt += dt2*chi;
342  
343  for( i=0; i<nAtoms; i++ ){
344
345    atoms[i]->getVel( vel );
346    atoms[i]->getFrc( frc );
347
348    mass = atoms[i]->getMass();
349
350    // velocity half step
351    for (j=0; j < 3; j++)
352      vel[j] += dt2 * ((frc[j] / mass ) * eConvert - vel[j]*(chi+eta));
353    
354    atoms[i]->setVel( vel );
355
356    if( atoms[i]->isDirectional() ){
357
358      dAtom = (DirectionalAtom *)atoms[i];
359
360      // get and convert the torque to body frame      
361
362      dAtom->getTrq( Tb );
363      dAtom->lab2Body( Tb );
364
365      // get the angular momentum, and propagate a half step
366
367      dAtom->getJ( ji );
368
369      for (j=0; j < 3; j++)
370        ji[j] += dt2 * (Tb[j] * eConvert - ji[j]*chi);    
371
372      dAtom->setJ( ji );
373    }
374  }
375
376 */
205    
206    //new version of NPTi
207    int i, j, k;
# Line 382 | Line 210 | template<typename T> void NPTi<T>::moveB( void ){
210    double vel[3], frc[3];
211    double mass;
212  
213 <  double instTemp, instPress, instVol;
213 >  double instaTemp, instaPress, instaVol;
214    double tt2, tb2;
215    double oldChi, prevChi;
216 <  double oldEta, preEta;
216 >  double oldEta, prevEta;
217    
218    tt2 = tauThermostat * tauThermostat;
219    tb2 = tauBarostat * tauBarostat;
220  
393
221    // Set things up for the iteration:
222  
223    oldChi = chi;
# Line 417 | Line 244 | template<typename T> void NPTi<T>::moveB( void ){
244  
245    // do the iteration:
246  
247 <  instVol = tStats->getVolume();
247 >  instaVol = tStats->getVolume();
248    
249    for (k=0; k < 4; k++) {
250      
251 <    instTemp = tStats->getTemperature();
252 <    instPress = tStats->getPressure();
251 >    instaTemp = tStats->getTemperature();
252 >    instaPress = tStats->getPressure();
253  
254      // evolve chi another half step using the temperature at t + dt/2
255  
256      prevChi = chi;
257 <    chi = oldChi + dt2 * ( instTemp / targetTemp - 1.0) /
431 <      (tauThermostat*tauThermostat);
257 >    chi = oldChi + dt2 * ( instaTemp / targetTemp - 1.0) / tt2;
258  
259 <    preEta = eta;
260 <    eta = oldEta + dt2 * ( instVol * (instPress - targetPressure) /
259 >    prevEta = eta;
260 >
261 >    // advance eta half step and calculate scale factor for velocity
262 >
263 >    eta = oldEta + dt2 * ( instaVol * (instaPress - targetPressure) /
264         (p_convert*NkBT*tb2));
265  
266    
# Line 463 | Line 292 | template<typename T> void NPTi<T>::moveB( void ){
292            dAtom->setJ( ji );
293        }
294      }
295 <
296 <    if (fabs(prevChi - chi) <= chiTolerance && fabs(preEta -eta) <= etaTolerance)
295 >    
296 >    if (nConstrained){
297 >      constrainB();
298 >    }    
299 >    
300 >    if (fabs(prevChi - chi) <=
301 >        chiTolerance && fabs(prevEta -eta) <= etaTolerance)
302        break;
303    }
304  
305 <  //calculate integral of chida
305 >  //calculate integral of chidt
306    integralOfChidt += dt2*chi;
307  
474
308   }
309  
310   template<typename T> void NPTi<T>::resetIntegrator() {
# Line 539 | Line 372 | template<typename T> int NPTi<T>::readyCheck() {
372      simError();
373    }
374  
375 <    if (!have_eta_tolerance) {
375 >  if (!have_eta_tolerance) {
376      sprintf( painCave.errMsg,
377               "NPTi warning: setting eta tolerance to 1e-6\n");
378      etaTolerance = 1e-6;
# Line 547 | Line 380 | template<typename T> int NPTi<T>::readyCheck() {
380      painCave.isFatal = 0;
381      simError();
382    }
383 <  // We need NkBT a lot, so just set it here:
384 <
383 >  
384 >  
385 >  // We need NkBT a lot, so just set it here: This is the RAW number
386 >  // of particles, so no subtraction or addition of constraints or
387 >  // orientational degrees of freedom:
388 >  
389    NkBT = (double)Nparticles * kB * targetTemp;
390 +  
391 +  // fkBT is used because the thermostat operates on more degrees of freedom
392 +  // than the barostat (when there are particles with orientational degrees
393 +  // of freedom).  ndf = 3 * (n_atoms + n_oriented -1) - n_constraint - nZcons
394 +  
395    fkBT = (double)info->ndf * kB * targetTemp;
396  
397    return 1;
# Line 558 | Line 400 | template<typename T> double NPTi<T>::getConservedQuant
400   template<typename T> double NPTi<T>::getConservedQuantity(void){
401  
402    double conservedQuantity;
403 <  double tb2;
404 <  double eta2;  
405 <  double E_NPT;
406 <  double U;
407 <  double TS;
408 <  double PV;
409 <  double extra;
403 >  double Three_NkBT;
404 >  double Energy;
405 >  double thermostat_kinetic;
406 >  double thermostat_potential;
407 >  double barostat_kinetic;
408 >  double barostat_potential;
409 >  double tb2;
410 >  double eta2;
411  
412 <  static double pre_U;
570 <  static double pre_TS;
571 <  static double pre_PV;
572 <  static double pre_extra;
573 <  static int hackCount = 0;
412 >  Energy = tStats->getTotalE();
413  
414 <  double delta_U;
415 <  double delta_TS;
577 <  double delta_PV;
578 <  double delta_extra;
414 >  thermostat_kinetic = fkBT* tauThermostat * tauThermostat * chi * chi /
415 >    (2.0 * eConvert);
416  
417 <  U = tStats->getTotalE();
417 >  thermostat_potential = fkBT* integralOfChidt / eConvert;
418  
582  TS = fkBT *
583    (integralOfChidt + tauThermostat * tauThermostat * chi * chi / 2.0) / eConvert;
419  
420 <  PV = (targetPressure * tStats->getVolume() / p_convert) / eConvert;
420 >  barostat_kinetic = 3.0 * NkBT * tauBarostat * tauBarostat * eta * eta /
421 >    (2.0 * eConvert);
422 >  
423 >  barostat_potential = (targetPressure * tStats->getVolume() / p_convert) /
424 >    eConvert;
425  
426 <  tb2 = tauBarostat * tauBarostat;
427 <  eta2 = eta * eta;
428 <
590 <  extra = (fkBT * tb2 * eta2 / 2.0 ) / eConvert;
591 <  /*
592 <  if(hackCount == 0){
593 <    pre_U = U;
594 <    pre_TS =TS;
595 <    pre_PV = PV;
596 <    pre_extra =extra;
597 <    hackCount ++;
598 <  }
599 <
600 <  delta_U = U - pre_U;
601 <  delta_TS = TS - pre_TS;
602 <  delta_PV = PV - pre_PV;
603 <  delta_extra = extra - pre_extra;
604 < */
426 >  conservedQuantity = Energy + thermostat_kinetic + thermostat_potential +
427 >    barostat_kinetic + barostat_potential;
428 >  
429    cout.width(8);
430    cout.precision(8);
431  
432 <  
433 <  cout << info->getTime() << "\t"
434 <       << chi << "\t"
611 <       << eta << "\t"
612 <       << U << "\t"
613 <       << TS << "\t"
614 <       << PV << "\t"
615 <       << extra << "\t"
616 <       << U+TS+PV+extra << endl;
432 >  cerr << info->getTime() << "\t" << Energy << "\t" << thermostat_kinetic <<
433 >      "\t" << thermostat_potential << "\t" << barostat_kinetic <<
434 >      "\t" << barostat_potential << "\t" << conservedQuantity << endl;
435  
618 /*
619    pre_U = U;
620    pre_TS =TS;
621    pre_PV = PV;
622    pre_extra =extra;
623
624
625  cout << info->getTime() << "\t"
626       << U << "\t"
627       << U+TS << "\t"
628       << U+TS+PV << "\t"
629       << U+TS+PV+extra << endl;
630 */
631  conservedQuantity = U+TS+PV+extra;
436    return conservedQuantity;
437   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines