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

Comparing trunk/OOPSE/libmdtools/NPTfm.cpp (file contents):
Revision 606 by gezelter, Tue Jul 15 03:28:05 2003 UTC vs.
Revision 763 by tim, Mon Sep 15 16:52:02 2003 UTC

# Line 1 | Line 1
1 + #include <cmath>
2   #include "Atom.hpp"
3   #include "Molecule.hpp"
4   #include "SRI.hpp"
# Line 9 | Line 10
10   #include "Integrator.hpp"
11   #include "simError.h"
12  
13 +
14   // Basic non-isotropic thermostating and barostating via the Melchionna
15   // modification of the Hoover algorithm:
16   //
# Line 22 | Line 24
24   //  The NPTfm variant scales the molecular center-of-mass coordinates
25   //  instead of the atomic coordinates
26  
27 < NPTfm::NPTfm ( SimInfo *theInfo, ForceFields* the_ff):
28 <  Integrator( theInfo, the_ff )
27 > template<typename T> NPTfm<T>::NPTfm ( SimInfo *theInfo, ForceFields* the_ff):
28 >  T( theInfo, the_ff )
29   {
30    int i, j;
31    chi = 0.0;
32 <
32 >  integralOfChidt = 0.0;
33 >  
34    for(i = 0; i < 3; i++)
35      for (j = 0; j < 3; j++)
36        eta[i][j] = 0.0;
# Line 38 | Line 41 | NPTfm::NPTfm ( SimInfo *theInfo, ForceFields* the_ff):
41    have_target_pressure = 0;
42   }
43  
44 < void NPTfm::moveA() {
44 > template<typename T> void NPTfm<T>::moveA() {
45    
46    int i, j, k;
47    DirectionalAtom* dAtom;
# Line 51 | Line 54 | void NPTfm::moveA() {
54    double instaTemp, instaPress, instaVol;
55    double tt2, tb2;
56    double sc[3];
57 <  double eta2ij;
57 >  double eta2ij, smallScale, bigScale, offDiagMax;
58    double press[3][3], vScale[3][3], hm[3][3], hmnew[3][3], scaleMat[3][3];
59  
60    int nInMol;
# Line 127 | Line 130 | void NPTfm::moveA() {
130  
131          for (k = 0; k < 3; k++ )
132            pos[k] += dt * (vel[k] + sc[k]);
133 +
134 +        myAtoms[j]->setPos( pos );
135    
136          if( myAtoms[j]->isDirectional() ){
137  
# Line 183 | Line 188 | void NPTfm::moveA() {
188    //  Hmat = Hmat . ( Ident + dt * etaMat  + dt^2 * etaMat*etaMat / 2)
189    
190    
191 +  bigScale = 1.0;
192 +  smallScale = 1.0;
193 +  offDiagMax = 0.0;
194 +
195    for(i=0; i<3; i++){
196      for(j=0; j<3; j++){
197        
# Line 199 | Line 208 | void NPTfm::moveA() {
208        if (i == j) scaleMat[i][j] = 1.0;
209        // Taylor expansion for the exponential truncated at second order:
210        scaleMat[i][j] += dt*eta[i][j]  + 0.5*dt*dt*eta2ij;
211 <      
211 >
212 >      if (i != j)
213 >        if (fabs(scaleMat[i][j]) > offDiagMax)
214 >          offDiagMax = fabs(scaleMat[i][j]);      
215      }
216 +    if (scaleMat[i][i] > bigScale) bigScale = scaleMat[i][i];
217 +    if (scaleMat[i][i] < smallScale) smallScale = scaleMat[i][i];
218    }
219    
220 <  info->getBoxM(hm);
221 <  info->matMul3(hm, scaleMat, hmnew);
222 <  info->setBoxM(hmnew);
223 <  
220 >  if ((bigScale > 1.1) || (smallScale < 0.9)) {
221 >    sprintf( painCave.errMsg,
222 >             "NPTf error: Attempting a Box scaling of more than 10 percent.\n"
223 >             " Check your tauBarostat, as it is probably too small!\n\n"
224 >             " scaleMat = [%lf\t%lf\t%lf]\n"
225 >             "            [%lf\t%lf\t%lf]\n"
226 >             "            [%lf\t%lf\t%lf]\n",
227 >             scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
228 >             scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
229 >             scaleMat[2][0],scaleMat[2][1],scaleMat[2][2]);
230 >    painCave.isFatal = 1;
231 >    simError();
232 >  } else if (offDiagMax > 0.1) {
233 >    sprintf( painCave.errMsg,
234 >             "NPTf error: Attempting an off-diagonal Box scaling of more than 10 percent.\n"
235 >             " Check your tauBarostat, as it is probably too small!\n\n"
236 >             " scaleMat = [%lf\t%lf\t%lf]\n"
237 >             "            [%lf\t%lf\t%lf]\n"
238 >             "            [%lf\t%lf\t%lf]\n",
239 >             scaleMat[0][0],scaleMat[0][1],scaleMat[0][2],
240 >             scaleMat[1][0],scaleMat[1][1],scaleMat[1][2],
241 >             scaleMat[2][0],scaleMat[2][1],scaleMat[2][2]);
242 >    painCave.isFatal = 1;
243 >    simError();
244 >  } else {
245 >    info->getBoxM(hm);
246 >    info->matMul3(hm, scaleMat, hmnew);
247 >    info->setBoxM(hmnew);
248 >  }  
249   }
250  
251 < void NPTfm::moveB( void ){
251 > template<typename T> void NPTfm<T>::moveB( void ){
252  
253    int i, j;
254    DirectionalAtom* dAtom;
# Line 291 | Line 330 | void NPTfm::moveB( void ){
330    }
331   }
332  
333 < int NPTfm::readyCheck() {
334 <
333 > template<typename T> void NPTfm<T>::resetIntegrator() {
334 >  int i,j;
335 >  
336 >  chi = 0.0;
337 >
338 >  for(i = 0; i < 3; i++)
339 >    for (j = 0; j < 3; j++)
340 >      eta[i][j] = 0.0;
341 > }
342 >
343 > template<typename T> int NPTfm<T>::readyCheck() {
344 >
345 >  //check parent's readyCheck() first
346 >  if (T::readyCheck() == -1)
347 >    return -1;
348 >  
349    // First check to see if we have a target temperature.
350    // Not having one is fatal.
351    
# Line 344 | Line 397 | int NPTfm::readyCheck() {
397  
398    return 1;
399   }
400 +
401 + template<typename T> double NPTfm<T>::getConservedQuantity(void){
402 +
403 +  double conservedQuantity;
404 +  double tb2;
405 +  double trEta;
406 +
407 +  //HNVE
408 +  conservedQuantity = tStats->getTotalE();
409 +
410 +  //HNVT
411 +  conservedQuantity += (info->getNDF() * kB * targetTemp *
412 +                        (integralOfChidt + tauThermostat * tauThermostat * chi * chi / 2.0)) / eConvert ;
413 +
414 +  //HNPT
415 +  tb2 = tauBarostat *tauBarostat;
416 +
417 +  trEta = info->matTrace3(eta);
418 +  
419 +  conservedQuantity += (targetPressure * tStats->getVolume() / p_convert +
420 +                        3*NkBT/2 * tb2 * trEta * trEta) / eConvert;
421 +  
422 +  return conservedQuantity;
423 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines