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

Comparing trunk/OOPSE/libmdtools/NPTf.cpp (file contents):
Revision 577 by gezelter, Wed Jul 9 01:41:11 2003 UTC vs.
Revision 578 by gezelter, Wed Jul 9 02:15:29 2003 UTC

# Line 9 | Line 9
9   #include "simError.h"
10  
11  
12 < // Basic isotropic thermostating and barostating via the Melchionna
12 > // Basic non-isotropic thermostating and barostating via the Melchionna
13   // modification of the Hoover algorithm:
14   //
15   //    Melchionna, S., Ciccotti, G., and Holian, B. L., 1993,
# Line 39 | Line 39 | void NPTf::moveA() {
39    double Tb[3];
40    double ji[3];
41    double rj[3];
42 +  double ident[3][3], eta1[3][3], eta2[3][3], hmnew[3][3];
43 +  double hm[9];
44 +  double vx, vy, vz;
45 +  double scx, scy, scz;
46    double instaTemp, instaPress, instaVol;
47    double tt2, tb2;
48    double angle;
# Line 160 | Line 164 | void NPTf::moveA() {
164    }
165  
166    // Scale the box after all the positions have been moved:
163  
167  
168 +  // Use a taylor expansion for eta products:  Hmat = Hmat . exp(dt * etaMat)
169 +  //  Hmat = Hmat . ( Ident + dt * etaMat  + dt^2 * etaMat*etaMat / 2)
170  
171 <  // Use a taylor expansion for eta products
171 >
172 >  for(i=0; i<3; i++){
173 >    for(j=0; j<3; j++){
174 >      ident[i][j] = 0.0;
175 >      eta1[i][j] = eta[3*i+j];
176 >      eta2[i][j] = 0.0;
177 >      for(k=0; k<3; k++){
178 >        eta2[i][j] += eta[3*i+k] * eta[3*k+j];
179 >      }
180 >    }
181 >    ident[i][i] = 1.0;
182 >  }
183 >
184    
185    info->getBoxM(hm);
186 +
187 +  for(i=0; i<3; i++){
188 +    for(j=0; j<3; j++){      
189 +      hmnew[i][j] = 0.0;
190 +      for(k=0; k<3; k++){
191 +        // remember that hmat has transpose ordering for Fortran compat:
192 +        hmnew[i][j] += hm[3*k+i] * (ident[k][j]
193 +                                    + dt * eta1[k][j]
194 +                                    + 0.5 * dt * dt * eta2[k][j]);
195 +      }
196 +    }
197 +  }
198    
199 +  for (i = 0; i < 3; i++) {
200 +    for (j = 0; j < 3; j++) {
201 +      // remember that hmat has transpose ordering for Fortran compat:
202 +      hm[3*j + 1] = hmnew[i][j];
203 +    }
204 +  }
205  
206 <
207 <
173 <
174 <
175 <   info->scaleBox(exp(dt*eta));
176 <
177 <
206 >  info->setBoxM(hm);
207 >  
208   }
209  
210 < void NPTi::moveB( void ){
210 > void NPTf::moveB( void ){
211    int i,j,k;
212    int atomIndex;
213    DirectionalAtom* dAtom;
214    double Tb[3];
215    double ji[3];
216 <  double instaTemp, instaPress, instaVol;
216 >  double press[9];
217 >  double instaTemp, instaVol;
218    double tt2, tb2;
219 +  double vx, vy, vz;
220 +  double scx, scy, scz;
221 +  const double p_convert = 1.63882576e8;
222    
223    tt2 = tauThermostat * tauThermostat;
224    tb2 = tauBarostat * tauBarostat;
225  
226    instaTemp = tStats->getTemperature();
227 <  instaPress = tStats->getPressure();
194 <  instaVol = tStats->getVolume();
227 >  tStats->getPressureTensor(press);
228  
229 +  for (i=0; i < 9; i++) press[i] *= p_convert;
230 +
231 +  instaVol = tStats->getVolume();
232 +  
233 +  // first evolve chi a half step
234 +  
235    chi += dt2 * ( instaTemp / targetTemp - 1.0) / tt2;
197  eta += dt2 * ( instaVol * (instaPress - targetPressure) / (NkBT*tb2));
236    
237 +  eta[0] += dt2 * instaVol * (press[0] - targetPressure) / (NkBT*tb2);
238 +  eta[1] += dt2 * instaVol * press[1] / (NkBT*tb2);
239 +  eta[2] += dt2 * instaVol * press[2] / (NkBT*tb2);
240 +  eta[3] += dt2 * instaVol * press[3] / (NkBT*tb2);
241 +  eta[4] += dt2 * instaVol * (press[4] - targetPressure) / (NkBT*tb2);
242 +  eta[5] += dt2 * instaVol * press[5] / (NkBT*tb2);
243 +  eta[6] += dt2 * instaVol * press[6] / (NkBT*tb2);
244 +  eta[7] += dt2 * instaVol * press[7] / (NkBT*tb2);
245 +  eta[8] += dt2 * instaVol * (press[8] - targetPressure) / (NkBT*tb2);
246 +
247    for( i=0; i<nAtoms; i++ ){
248      atomIndex = i * 3;
249 <    
249 >
250      // velocity half step
203    for( j=atomIndex; j<(atomIndex+3); j++ )
204    for( j=atomIndex; j<(atomIndex+3); j++ )
205      vel[j] += dt2 * ((frc[j]/atoms[i]->getMass())*eConvert
206                       - vel[j]*(chi+eta));
251      
252 +    vx = vel[atomIndex];
253 +    vy = vel[atomIndex+1];
254 +    vz = vel[atomIndex+2];
255 +    
256 +    scx = (chi + eta[0])*vx + eta[1]*vy + eta[2]*vz;
257 +    scy = eta[3]*vx + (chi + eta[4])*vy + eta[5]*vz;
258 +    scz = eta[6]*vx + eta[7]*vy + (chi + eta[8])*vz;
259 +    
260 +    vx += dt2 * ((frc[atomIndex]  /atoms[i]->getMass())*eConvert - scx);
261 +    vy += dt2 * ((frc[atomIndex+1]/atoms[i]->getMass())*eConvert - scy);
262 +    vz += dt2 * ((frc[atomIndex+2]/atoms[i]->getMass())*eConvert - scz);
263 +
264 +    vel[atomIndex] = vx;
265 +    vel[atomIndex+1] = vy;
266 +    vel[atomIndex+2] = vz;
267 +    
268      if( atoms[i]->isDirectional() ){
269        
270        dAtom = (DirectionalAtom *)atoms[i];

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines