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

Comparing trunk/OOPSE/libmdtools/Symplectic.cpp (file contents):
Revision 497 by chuckv, Mon Apr 14 21:16:37 2003 UTC vs.
Revision 542 by mmeineke, Fri May 30 21:31:48 2003 UTC

# Line 1 | Line 1
1   #include <iostream>
2   #include <cstdlib>
3  
4 + #ifdef IS_MPI
5 + #include "mpiSimulation.hpp"
6 + #include <unistd.h>
7 + #endif //is_mpi
8 +
9   #include "Integrator.hpp"
5 #include "Thermo.hpp"
6 #include "ReadWrite.hpp"
7 #include "ForceFields.hpp"
8 #include "ExtendedSystem.hpp"
10   #include "simError.h"
11  
11 extern "C"{
12  
13  void v_constrain_a_( double &dt, int &n_atoms, double* mass,
14                       double* Rx, double* Ry, double* Rz,
15                       double* Vx, double* Vy, double* Vz,
16                       double* Fx, double* Fy, double* Fz,
17                       int &n_constrained, double *constr_sqr,
18                       int* constr_i, int* constr_j,
19                       double &box_x, double &box_y, double &box_z );
12  
13 <  void v_constrain_b_( double &dt, int &n_atoms, double* mass,
14 <                       double* Rx, double* Ry, double* Rz,
15 <                       double* Vx, double* Vy, double* Vz,
24 <                       double* Fx, double* Fy, double* Fz,
25 <                       double &Kinetic,
26 <                       int &n_constrained, double *constr_sqr,
27 <                       int* constr_i, int* constr_j,
28 <                       double &box_x, double &box_y, double &box_z );
29 < }
30 <
31 <
32 <
33 <
34 < Symplectic::Symplectic( SimInfo* the_entry_plug, ForceFields* the_ff,
35 <                        ExtendedSystem* the_es ){
36 <  entry_plug = the_entry_plug;
13 > Symplectic::Symplectic( SimInfo* theInfo, ForceFields* the_ff ){
14 >  
15 >  info = theInfo;
16    myFF = the_ff;
38  myES = the_es;
17    isFirst = 1;
18  
19 <  molecules = entry_plug->molecules;
20 <  nMols = entry_plug->n_mol;
19 >  molecules = info->molecules;
20 >  nMols = info->n_mol;
21  
22    // give a little love back to the SimInfo object
23    
24 <  if( entry_plug->the_integrator != NULL ) delete entry_plug->the_integrator;
25 <  entry_plug->the_integrator = this;
24 >  if( info->the_integrator != NULL ) delete info->the_integrator;
25 >  info->the_integrator = this;
26  
49  // grab the masses
50
51  mass = new double[entry_plug->n_atoms];
52  for(int i = 0; i < entry_plug->n_atoms; i++){
53    mass[i] = entry_plug->atoms[i]->getMass();
54  }  
55
27    // check for constraints
28 +  
29 +  constrainedI = NULL;
30 +  constrainedJ = NULL;
31 +  constrainedDsqr = NULL;
32 +  nConstrained = 0;
33  
34 <  is_constrained = 0;
34 >  checkConstraints();
35 > }
36  
37 + Symplectic::~Symplectic() {
38 +  
39 +  if( nConstrained ){
40 +    delete[] constrainedI;
41 +    delete[] constrainedJ;
42 +    delete[] constrainedDsqr;
43 +  }
44 +  
45 + }
46 +
47 + void Symplectic::checkConstraints( void ){
48 +
49 +
50 +  isConstrained = 0;
51 +
52    Constraint *temp_con;
53    Constraint *dummy_plug;
54 <  temp_con = new Constraint[entry_plug->n_SRI];
55 <  n_constrained = 0;
54 >  temp_con = new Constraint[info->n_SRI];
55 >  nConstrained = 0;
56    int constrained = 0;
57    
58    SRI** theArray;
# Line 74 | Line 66 | Symplectic::Symplectic( SimInfo* the_entry_plug, Force
66        if(constrained){
67          
68          dummy_plug = theArray[j]->get_constraint();
69 <        temp_con[n_constrained].set_a( dummy_plug->get_a() );
70 <        temp_con[n_constrained].set_b( dummy_plug->get_b() );
71 <        temp_con[n_constrained].set_dsqr( dummy_plug->get_dsqr() );
69 >        temp_con[nConstrained].set_a( dummy_plug->get_a() );
70 >        temp_con[nConstrained].set_b( dummy_plug->get_b() );
71 >        temp_con[nConstrained].set_dsqr( dummy_plug->get_dsqr() );
72          
73 <        n_constrained++;
73 >        nConstrained++;
74          constrained = 0;
75        }
76      }
# Line 91 | Line 83 | Symplectic::Symplectic( SimInfo* the_entry_plug, Force
83        if(constrained){
84          
85          dummy_plug = theArray[j]->get_constraint();
86 <        temp_con[n_constrained].set_a( dummy_plug->get_a() );
87 <        temp_con[n_constrained].set_b( dummy_plug->get_b() );
88 <        temp_con[n_constrained].set_dsqr( dummy_plug->get_dsqr() );
86 >        temp_con[nConstrained].set_a( dummy_plug->get_a() );
87 >        temp_con[nConstrained].set_b( dummy_plug->get_b() );
88 >        temp_con[nConstrained].set_dsqr( dummy_plug->get_dsqr() );
89          
90 <        n_constrained++;
90 >        nConstrained++;
91          constrained = 0;
92        }
93      }
# Line 108 | Line 100 | Symplectic::Symplectic( SimInfo* the_entry_plug, Force
100        if(constrained){
101          
102          dummy_plug = theArray[j]->get_constraint();
103 <        temp_con[n_constrained].set_a( dummy_plug->get_a() );
104 <        temp_con[n_constrained].set_b( dummy_plug->get_b() );
105 <        temp_con[n_constrained].set_dsqr( dummy_plug->get_dsqr() );
103 >        temp_con[nConstrained].set_a( dummy_plug->get_a() );
104 >        temp_con[nConstrained].set_b( dummy_plug->get_b() );
105 >        temp_con[nConstrained].set_dsqr( dummy_plug->get_dsqr() );
106          
107 <        n_constrained++;
107 >        nConstrained++;
108          constrained = 0;
109        }
110      }
111    }
112  
113 <  if(n_constrained > 0){
113 >  if(nConstrained > 0){
114      
115 <    is_constrained = 1;
116 <    constrained_i = new int[n_constrained];
117 <    constrained_j = new int[n_constrained];
118 <    constrained_dsqr = new double[n_constrained];
115 >    isConstrained = 1;
116 >
117 >    if(constrainedI != NULL )    delete[] constrainedI;
118 >    if(constrainedJ != NULL )    delete[] constrainedJ;
119 >    if(constrainedDsqr != NULL ) delete[] constrainedDsqr;
120 >
121 >    constrainedI =    new int[nConstrained];
122 >    constrainedJ =    new int[nConstrained];
123 >    constrainedDsqr = new double[nConstrained];
124      
125 <    for( int i = 0; i < n_constrained; i++){
125 >    for( int i = 0; i < nConstrained; i++){
126        
127 <      /* add 1 to the index for the fortran arrays. */
128 <
129 <      constrained_i[i] = temp_con[i].get_a() + 1;
133 <      constrained_j[i] = temp_con[i].get_b() + 1;
134 <      constrained_dsqr[i] = temp_con[i].get_dsqr();
127 >      constrainedI[i] = temp_con[i].get_a();
128 >      constrainedJ[i] = temp_con[i].get_b();
129 >      constrainedDsqr[i] = temp_con[i].get_dsqr();
130      }
131    }
132    
133    delete[] temp_con;
134   }
135  
141 Symplectic::~Symplectic() {
142  
143  if( n_constrained ){
144    delete[] constrained_i;
145    delete[] constrained_j;
146    delete[] constrained_dsqr;
147  }
148  
149 }
136  
151
137   void Symplectic::integrate( void ){
138  
154  const double e_convert = 4.184e-4; // converts kcal/mol -> amu*A^2/fs^2
155
139    int i, j;                         // loop counters
140 <  int nAtoms = entry_plug->n_atoms; // the number of atoms
140 >  int nAtoms = info->n_atoms; // the number of atoms
141    double kE = 0.0;                  // the kinetic energy  
142    double rot_kE;
143    double trans_kE;
# Line 174 | Line 157 | void Symplectic::integrate( void ){
157  
158    int time;
159  
160 <  double dt          = entry_plug->dt;
161 <  double runTime     = entry_plug->run_time;
162 <  double sampleTime  = entry_plug->sampleTime;
163 <  double statusTime  = entry_plug->statusTime;
164 <  double thermalTime = entry_plug->thermalTime;
160 >  double dt          = info->dt;
161 >  double runTime     = info->run_time;
162 >  double sampleTime  = info->sampleTime;
163 >  double statusTime  = info->statusTime;
164 >  double thermalTime = info->thermalTime;
165  
166    int n_loops  = (int)( runTime / dt );
167    int sample_n = (int)( sampleTime / dt );
# Line 186 | Line 169 | void Symplectic::integrate( void ){
169    int vel_n    = (int)( thermalTime / dt );
170  
171    int calcPot, calcStress;
172 +  int isError;
173  
174 <  Thermo *tStats;
175 <  StatWriter*  e_out;
176 <  DumpWriter*  dump_out;
174 >  tStats   = new Thermo( info );
175 >  e_out    = new StatWriter( info );
176 >  dump_out = new DumpWriter( info );
177  
178 <  tStats   = new Thermo( entry_plug );
195 <  e_out    = new StatWriter( entry_plug );
196 <  dump_out = new DumpWriter( entry_plug );
197 <
198 <  Atom** atoms = entry_plug->atoms;
178 >  Atom** atoms = info->atoms;
179    DirectionalAtom* dAtom;
180    dt2 = 0.5 * dt;
181  
182 <  // initialize the forces the before the first step
182 >  // initialize the forces before the first step
183  
184    myFF->doForces(1,1);
185    
186 <  if( entry_plug->setTemp ){
186 >  if( info->setTemp ){
187      
188      tStats->velocitize();
189    }
# Line 213 | Line 193 | void Symplectic::integrate( void ){
193    
194    calcPot = 0;
195  
196 <  if (!strcasecmp( entry_plug->ensemble, "NPT")) {
217 <    calcStress = 1;
218 <  } else {
219 <    calcStress = 0;
220 <  }
196 >  for( tl=0; tl<nLoops; tl++){
197  
198 <  if( n_constrained ){
199 <
200 <    double *Rx = new double[nAtoms];
225 <    double *Ry = new double[nAtoms];
226 <    double *Rz = new double[nAtoms];
198 >    integrateStep( calcPot, calcStress );
199 >      
200 >    time = tl + 1;
201      
202 <    double *Vx = new double[nAtoms];
203 <    double *Vy = new double[nAtoms];
204 <    double *Vz = new double[nAtoms];
205 <    
206 <    double *Fx = new double[nAtoms];
207 <    double *Fy = new double[nAtoms];
208 <    double *Fz = new double[nAtoms];
209 <    
202 >    if( info->setTemp ){
203 >      if( !(time % vel_n) ) tStats->velocitize();
204 >    }
205 >    if( !(time % sample_n) ) dump_out->writeDump( time * dt );
206 >    if( !((time+1) % status_n) ) {
207 >      calcPot = 1;
208 >      calcStress = 1;
209 >    }
210 >    if( !(time % status_n) ){
211 >      e_out->writeStat( time * dt );
212 >      calcPot = 0;
213 >      if (!strcasecmp(info->ensemble, "NPT")) calcStress = 1;
214 >      else calcStress = 0;
215 >    }    
216  
217 <    for( tl=0; tl < n_loops; tl++ ){
217 >  
218 >  }
219  
220 <      
240 <      for( j=0; j<nAtoms; j++ ){
220 >  dump_out->writeFinal();
221  
222 <        Rx[j] = atoms[j]->getX();
223 <        Ry[j] = atoms[j]->getY();
224 <        Rz[j] = atoms[j]->getZ();
222 >  delete dump_out;
223 >  delete e_out;
224 > }
225  
246        Vx[j] = atoms[j]->get_vx();
247        Vy[j] = atoms[j]->get_vy();
248        Vz[j] = atoms[j]->get_vz();
226  
227 <        Fx[j] = atoms[j]->getFx();
228 <        Fy[j] = atoms[j]->getFy();
229 <        Fz[j] = atoms[j]->getFz();
227 > void Symplectic::moveA( void ){
228 >  
229 >  int i,j,k;
230 >  int atomIndex, aMatIndex;
231 >  DirectionalAtom* dAtom;
232 >  double Tb[3];
233 >  double ji[3];
234  
235 <      }
236 <        
237 <      v_constrain_a_( dt, nAtoms, mass, Rx, Ry, Rz, Vx, Vy, Vz,
238 <                      Fx, Fy, Fz,
239 <                      n_constrained, constrained_dsqr,
240 <                      constrained_i, constrained_j,
241 <                      entry_plug->box_x,
261 <                      entry_plug->box_y,
262 <                      entry_plug->box_z );
263 <      
264 <      for( j=0; j<nAtoms; j++ ){
235 >  for( i=0; i<nAtoms; i++ ){
236 >    atomIndex = i * 3;
237 >    aMatIndex = i * 9;
238 >    
239 >    // velocity half step
240 >    for( j=atomIndex; j<(atomIndex+3); j++ )
241 >      vel[j] += ( dt2 * frc[j] / atoms[i]->getMass() ) * eConvert;
242  
243 <        atoms[j]->setX(Rx[j]);
244 <        atoms[j]->setY(Ry[j]);
245 <        atoms[j]->setZ(Rz[j]);
269 <        
270 <        atoms[j]->set_vx(Vx[j]);
271 <        atoms[j]->set_vy(Vy[j]);
272 <        atoms[j]->set_vz(Vz[j]);
273 <      }
243 >    // position whole step    
244 >    for( j=atomIndex; j<(atomIndex+3); j++ )
245 >      pos[j] += dt * vel[j];
246  
247 +  
248 +    if( atoms[i]->isDirectional() ){
249  
250 <      for( i=0; i<nAtoms; i++ ){
277 <        if( atoms[i]->isDirectional() ){
278 <                  
279 <          dAtom = (DirectionalAtom *)atoms[i];
250 >      dAtom = (DirectionalAtom *)atoms[i];
251            
252 <          // get and convert the torque to body frame
282 <          
283 <          Tb[0] = dAtom->getTx();
284 <          Tb[1] = dAtom->getTy();
285 <          Tb[2] = dAtom->getTz();
286 <          
287 <          dAtom->lab2Body( Tb );
288 <          
289 <          // get the angular momentum, and propagate a half step
290 <          
291 <          ji[0] = dAtom->getJx() + ( dt2 * Tb[0] ) * e_convert;
292 <          ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * e_convert;
293 <          ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * e_convert;
294 <          
295 <          // get the atom's rotation matrix
296 <          
297 <          A[0][0] = dAtom->getAxx();
298 <          A[0][1] = dAtom->getAxy();
299 <          A[0][2] = dAtom->getAxz();
300 <          
301 <          A[1][0] = dAtom->getAyx();
302 <          A[1][1] = dAtom->getAyy();
303 <          A[1][2] = dAtom->getAyz();
304 <          
305 <          A[2][0] = dAtom->getAzx();
306 <          A[2][1] = dAtom->getAzy();
307 <          A[2][2] = dAtom->getAzz();
308 <          
309 <          
310 <          // use the angular velocities to propagate the rotation matrix a
311 <          // full time step
312 <          
313 <          
314 <          angle = dt2 * ji[0] / dAtom->getIxx();
315 <          this->rotate( 1, 2, angle, ji, A ); // rotate about the x-axis
316 <          
317 <          angle = dt2 * ji[1] / dAtom->getIyy();
318 <          this->rotate( 2, 0, angle, ji, A ); // rotate about the y-axis
319 <          
320 <          angle = dt * ji[2] / dAtom->getIzz();
321 <          this->rotate( 0, 1, angle, ji, A ); // rotate about the z-axis
322 <          
323 <          angle = dt2 * ji[1] / dAtom->getIyy();
324 <          this->rotate( 2, 0, angle, ji, A ); // rotate about the y-axis
325 <          
326 <          angle = dt2 * ji[0] / dAtom->getIxx();
327 <          this->rotate( 1, 2, angle, ji, A ); // rotate about the x-axis
328 <          
329 <          
330 <          dAtom->setA( A );
331 <          dAtom->setJx( ji[0] );
332 <          dAtom->setJy( ji[1] );
333 <          dAtom->setJz( ji[2] );
334 <        }
335 <      }
252 >      // get and convert the torque to body frame
253        
254 <      if (!strcasecmp( entry_plug->ensemble, "NVT"))
255 <        myES->NoseHooverNVT( dt / 2.0 , tStats->getKinetic() );
256 <
340 <      // calculate the forces
254 >      Tb[0] = dAtom->getTx();
255 >      Tb[1] = dAtom->getTy();
256 >      Tb[2] = dAtom->getTz();
257        
258 <      myFF->doForces(calcPot, calcStress);
258 >      dAtom->lab2Body( Tb );
259        
260 <      // move b
261 <
262 <      for( j=0; j<nAtoms; j++ ){
263 <
264 <        Rx[j] = atoms[j]->getX();
349 <        Ry[j] = atoms[j]->getY();
350 <        Rz[j] = atoms[j]->getZ();
351 <
352 <        Vx[j] = atoms[j]->get_vx();
353 <        Vy[j] = atoms[j]->get_vy();
354 <        Vz[j] = atoms[j]->get_vz();
355 <
356 <        Fx[j] = atoms[j]->getFx();
357 <        Fy[j] = atoms[j]->getFy();
358 <        Fz[j] = atoms[j]->getFz();
359 <      }
360 <        
361 <      v_constrain_b_( dt, nAtoms, mass, Rx, Ry, Rz, Vx, Vy, Vz,
362 <                      Fx, Fy, Fz,
363 <                      kE, n_constrained, constrained_dsqr,
364 <                      constrained_i, constrained_j,
365 <                      entry_plug->box_x,
366 <                      entry_plug->box_y,
367 <                      entry_plug->box_z );
260 >      // get the angular momentum, and propagate a half step
261 >      
262 >      ji[0] = dAtom->getJx() + ( dt2 * Tb[0] ) * eConvert;
263 >      ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * eConvert;
264 >      ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * eConvert;
265        
266 <      for( j=0; j<nAtoms; j++ ){
267 <
371 <        atoms[j]->setX(Rx[j]);
372 <        atoms[j]->setY(Ry[j]);
373 <        atoms[j]->setZ(Rz[j]);
374 <
375 <        atoms[j]->set_vx(Vx[j]);
376 <        atoms[j]->set_vy(Vy[j]);
377 <        atoms[j]->set_vz(Vz[j]);
378 <      }
266 >      // use the angular velocities to propagate the rotation matrix a
267 >      // full time step
268        
269 <      for( i=0; i< nAtoms; i++ ){
269 >      // rotate about the x-axis      
270 >      angle = dt2 * ji[0] / dAtom->getIxx();
271 >      this->rotate( 1, 2, angle, ji, &aMat[aMatIndex] );
272 >      
273 >      // rotate about the y-axis
274 >      angle = dt2 * ji[1] / dAtom->getIyy();
275 >      this->rotate( 2, 0, angle, ji, &aMat[aMatIndex] );
276 >      
277 >      // rotate about the z-axis
278 >      angle = dt * ji[2] / dAtom->getIzz();
279 >      this->rotate( 0, 1, angle, ji, &aMat[aMatIndex] );
280 >      
281 >      // rotate about the y-axis
282 >      angle = dt2 * ji[1] / dAtom->getIyy();
283 >      this->rotate( 2, 0, angle, ji, &aMat[aMatIndex] );
284 >      
285 >       // rotate about the x-axis
286 >      angle = dt2 * ji[0] / dAtom->getIxx();
287 >      this->rotate( 1, 2, angle, ji, &aMat[aMatIndex] );
288 >      
289 >      dAtom->setJx( ji[0] );
290 >      dAtom->setJy( ji[1] );
291 >      dAtom->setJz( ji[2] );
292 >    }
293 >    
294 >  }
295 > }
296  
382        if( atoms[i]->isDirectional() ){
297  
298 <          dAtom = (DirectionalAtom *)atoms[i];
299 <          
300 <          // get and convert the torque to body frame
301 <          
302 <          Tb[0] = dAtom->getTx();
303 <          Tb[1] = dAtom->getTy();
390 <          Tb[2] = dAtom->getTz();
391 <          
392 <          dAtom->lab2Body( Tb );
393 <          
394 <          // get the angular momentum, and complete the angular momentum
395 <          // half step
396 <          
397 <          ji[0] = dAtom->getJx() + ( dt2 * Tb[0] ) * e_convert;
398 <          ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * e_convert;
399 <          ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * e_convert;
400 <          
401 <          dAtom->setJx( ji[0] );
402 <          dAtom->setJy( ji[1] );
403 <          dAtom->setJz( ji[2] );
404 <        }
405 <      }
406 <    
298 > void Integrator::moveB( void ){
299 >  int i,j,k;
300 >  int atomIndex;
301 >  DirectionalAtom* dAtom;
302 >  double Tb[3];
303 >  double ji[3];
304  
305 <      if (!strcasecmp( entry_plug->ensemble, "NVT"))
306 <        myES->NoseHooverNVT( dt / 2.0, tStats->getKinetic() );
305 >  for( i=0; i<nAtoms; i++ ){
306 >    atomIndex = i * 3;
307  
308 <      if (!strcasecmp( entry_plug->ensemble, "NPT") ) {
309 <        tStats->getPressureTensor(press);
310 <        myES->NoseHooverAndersonNPT( dt,
414 <                                     tStats->getKinetic(),
415 <                                     press);
416 <      }
308 >    // velocity half step
309 >    for( j=atomIndex; j<(atomIndex+3); j++ )
310 >      vel[j] += ( dt2 * frc[j] / atoms[i]->getMass() ) * eConvert;
311  
312 <      time = tl + 1;
312 >    if( atoms[i]->isDirectional() ){
313        
314 <      if( entry_plug->setTemp ){
315 <        if( !(time % vel_n) ) tStats->velocitize();
316 <      }
317 <      if( !(time % sample_n) ) dump_out->writeDump( time * dt );
318 <      if( !((time+1) % status_n) ) {
319 <        calcPot = 1;
320 <        calcStress = 1;
321 <      }
322 <      if( !(time % status_n) ){
323 <        e_out->writeStat( time * dt );
324 <        calcPot = 0;
325 <        if (!strcasecmp(entry_plug->ensemble, "NPT")) calcStress = 1;
326 <        else calcStress = 0;
327 <      }
314 >      dAtom = (DirectionalAtom *)atoms[i];
315 >      
316 >      // get and convert the torque to body frame
317 >      
318 >      Tb[0] = dAtom->getTx();
319 >      Tb[1] = dAtom->getTy();
320 >      Tb[2] = dAtom->getTz();
321 >      
322 >      dAtom->lab2Body( Tb );
323 >      
324 >      // get the angular momentum, and complete the angular momentum
325 >      // half step
326 >      
327 >      ji[0] = dAtom->getJx() + ( dt2 * Tb[0] ) * eConvert;
328 >      ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * eConvert;
329 >      ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * eConvert;
330 >      
331 >      jx2 = ji[0] * ji[0];
332 >      jy2 = ji[1] * ji[1];
333 >      jz2 = ji[2] * ji[2];
334 >      
335 >      dAtom->setJx( ji[0] );
336 >      dAtom->setJy( ji[1] );
337 >      dAtom->setJz( ji[2] );
338      }
339    }
436  else{
340  
341 <    for( tl=0; tl<n_loops; tl++ ){
439 <      
440 <      kE = 0.0;
441 <      rot_kE= 0.0;
442 <      trans_kE = 0.0;
341 > }
342  
444      for( i=0; i<nAtoms; i++ ){
445        
446        // velocity half step
447        
448        vx = atoms[i]->get_vx() +
449          ( dt2 * atoms[i]->getFx() / atoms[i]->getMass() ) * e_convert;
450        vy = atoms[i]->get_vy() +
451          ( dt2 * atoms[i]->getFy() / atoms[i]->getMass() ) * e_convert;
452        vz = atoms[i]->get_vz() +
453          ( dt2 * atoms[i]->getFz() / atoms[i]->getMass() ) * e_convert;
454        
455        // position whole step
456        
457        rx = atoms[i]->getX() + dt * vx;
458        ry = atoms[i]->getY() + dt * vy;
459        rz = atoms[i]->getZ() + dt * vz;
460        
461        atoms[i]->setX( rx );
462        atoms[i]->setY( ry );
463        atoms[i]->setZ( rz );
464        
465        atoms[i]->set_vx( vx );
466        atoms[i]->set_vy( vy );
467        atoms[i]->set_vz( vz );
468        
469        if( atoms[i]->isDirectional() ){
343  
344 <          dAtom = (DirectionalAtom *)atoms[i];
472 <          
473 <          // get and convert the torque to body frame
474 <          
475 <          Tb[0] = dAtom->getTx();
476 <          Tb[1] = dAtom->getTy();
477 <          Tb[2] = dAtom->getTz();
478 <          
479 <          dAtom->lab2Body( Tb );
480 <          
481 <          // get the angular momentum, and propagate a half step
482 <          
483 <          ji[0] = dAtom->getJx() + ( dt2 * Tb[0] ) * e_convert;
484 <          ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * e_convert;
485 <          ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * e_convert;
486 <          
487 <          // get the atom's rotation matrix
488 <          
489 <          A[0][0] = dAtom->getAxx();
490 <          A[0][1] = dAtom->getAxy();
491 <          A[0][2] = dAtom->getAxz();
492 <          
493 <          A[1][0] = dAtom->getAyx();
494 <          A[1][1] = dAtom->getAyy();
495 <          A[1][2] = dAtom->getAyz();
496 <          
497 <          A[2][0] = dAtom->getAzx();
498 <          A[2][1] = dAtom->getAzy();
499 <          A[2][2] = dAtom->getAzz();
500 <          
501 <          
502 <          // use the angular velocities to propagate the rotation matrix a
503 <          // full time step
504 <          
505 <          
506 <          angle = dt2 * ji[0] / dAtom->getIxx();
507 <          this->rotate( 1, 2, angle, ji, A ); // rotate about the x-axis
508 <          
509 <          angle = dt2 * ji[1] / dAtom->getIyy();
510 <          this->rotate( 2, 0, angle, ji, A ); // rotate about the y-axis
511 <          
512 <          angle = dt * ji[2] / dAtom->getIzz();
513 <          this->rotate( 0, 1, angle, ji, A ); // rotate about the z-axis
514 <          
515 <          angle = dt2 * ji[1] / dAtom->getIyy();
516 <          this->rotate( 2, 0, angle, ji, A ); // rotate about the y-axis
517 <          
518 <          angle = dt2 * ji[0] / dAtom->getIxx();
519 <          this->rotate( 1, 2, angle, ji, A ); // rotate about the x-axis
520 <          
521 <          
522 <          dAtom->setA( A );
523 <          dAtom->setJx( ji[0] );
524 <          dAtom->setJy( ji[1] );
525 <          dAtom->setJz( ji[2] );
526 <        }
527 <      }
344 > void Integrator::constrainA(){
345  
346 <      if (!strcasecmp( entry_plug->ensemble, "NVT"))
530 <        myES->NoseHooverNVT( dt / 2.0, tStats->getKinetic() );
531 <      
532 <      
533 <      // calculate the forces
534 <      
535 <      myFF->doForces(calcPot,calcStress);
536 <      
537 <      for( i=0; i< nAtoms; i++ ){
538 <        
539 <        // complete the velocity half step
540 <        
541 <        vx = atoms[i]->get_vx() +
542 <          ( dt2 * atoms[i]->getFx() / atoms[i]->getMass() ) * e_convert;
543 <        vy = atoms[i]->get_vy() +
544 <          ( dt2 * atoms[i]->getFy() / atoms[i]->getMass() ) * e_convert;
545 <        vz = atoms[i]->get_vz() +
546 <          ( dt2 * atoms[i]->getFz() / atoms[i]->getMass() ) * e_convert;
547 <        
548 <        atoms[i]->set_vx( vx );
549 <        atoms[i]->set_vy( vy );
550 <        atoms[i]->set_vz( vz );
551 <        
552 <        vx2 = vx * vx;
553 <        vy2 = vy * vy;
554 <        vz2 = vz * vz;
555 <        
556 <        if( atoms[i]->isDirectional() ){
346 >  
347  
558          dAtom = (DirectionalAtom *)atoms[i];
559          
560          // get and convert the torque to body frame
561          
562          Tb[0] = dAtom->getTx();
563          Tb[1] = dAtom->getTy();
564          Tb[2] = dAtom->getTz();
565          
566          dAtom->lab2Body( Tb );
567          
568          // get the angular momentum, and complete the angular momentum
569          // half step
570          
571          ji[0] = dAtom->getJx() + ( dt2 * Tb[0] ) * e_convert;
572          ji[1] = dAtom->getJy() + ( dt2 * Tb[1] ) * e_convert;
573          ji[2] = dAtom->getJz() + ( dt2 * Tb[2] ) * e_convert;
574          
575          jx2 = ji[0] * ji[0];
576          jy2 = ji[1] * ji[1];
577          jz2 = ji[2] * ji[2];
578          
579          rot_kE += (jx2 / dAtom->getIxx()) + (jy2 / dAtom->getIyy())
580            + (jz2 / dAtom->getIzz());
581          
582          dAtom->setJx( ji[0] );
583          dAtom->setJy( ji[1] );
584          dAtom->setJz( ji[2] );
585        }
348  
349 <      }
588 <    
589 <      if (!strcasecmp( entry_plug->ensemble, "NVT"))
590 <        myES->NoseHooverNVT( dt / 2.0, tStats->getKinetic() );
349 > }
350  
592      if (!strcasecmp( entry_plug->ensemble, "NPT") ) {
593        tStats->getPressureTensor(press);
594        myES->NoseHooverAndersonNPT( dt,
595                                     tStats->getKinetic(),
596                                     press);
597      }
598  
599      time = tl + 1;
600      
601      if( entry_plug->setTemp ){
602        if( !(time % vel_n) ) tStats->velocitize();
603      }
604      if( !(time % sample_n) ) dump_out->writeDump( time * dt );
605      if( !((time+1) % status_n) ) {
606        calcPot = 1;
607        calcStress = 1;
608      }
609      if( !(time % status_n) ){
610        e_out->writeStat( time * dt );
611        calcPot = 0;
612        if (!strcasecmp(entry_plug->ensemble, "NPT")) calcStress = 1;
613        else calcStress = 0;
614      }      
615    }
616  }
351  
618  dump_out->writeFinal();
352  
620  delete dump_out;
621  delete e_out;
622 }
353  
354 +
355 +
356 +
357 +
358 +
359   void Symplectic::rotate( int axes1, int axes2, double angle, double ji[3],
360                           double A[3][3] ){
361  

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines