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

Comparing trunk/OOPSE/libmdtools/Integrator.cpp (file contents):
Revision 614 by mmeineke, Tue Jul 15 17:57:04 2003 UTC vs.
Revision 1284 by tim, Mon Jun 21 18:52:21 2004 UTC

# Line 1 | Line 1
1   #include <iostream>
2 < #include <cstdlib>
3 < #include <cmath>
4 <
2 > #include <stdlib.h>
3 > #include <math.h>
4 > #include "Rattle.hpp"
5 > #include "Roll.hpp"
6   #ifdef IS_MPI
7   #include "mpiSimulation.hpp"
8   #include <unistd.h>
9   #endif //is_mpi
10  
11 + #ifdef PROFILE
12 + #include "mdProfile.hpp"
13 + #endif // profile
14 +
15   #include "Integrator.hpp"
16   #include "simError.h"
17  
18  
19 < Integrator::Integrator( SimInfo *theInfo, ForceFields* the_ff ){
20 <  
19 > template<typename T> Integrator<T>::Integrator(SimInfo* theInfo,
20 >                                               ForceFields* the_ff){
21    info = theInfo;
22    myFF = the_ff;
23    isFirst = 1;
# Line 21 | Line 26 | Integrator::Integrator( SimInfo *theInfo, ForceFields*
26    nMols = info->n_mol;
27  
28    // give a little love back to the SimInfo object
24  
25  if( info->the_integrator != NULL ) delete info->the_integrator;
26  info->the_integrator = this;
29  
30 +  if (info->the_integrator != NULL){
31 +    delete info->the_integrator;
32 +  }
33 +
34    nAtoms = info->n_atoms;
35 +  integrableObjects = info->integrableObjects;
36  
37 <  // check for constraints
37 >  consFramework = new RattleFramework(info);
38 >
39 >  if(consFramework == NULL){
40 >    sprintf(painCave.errMsg,
41 >      "Integrator::Intergrator() Error: Memory allocation error for RattleFramework" );
42 >    painCave.isFatal = 1;
43 >    simError();
44 >  }
45    
46 <  constrainedA    = NULL;
47 <  constrainedB    = NULL;
46 > /*
47 >  // check for constraints
48 >
49 >  constrainedA = NULL;
50 >  constrainedB = NULL;
51    constrainedDsqr = NULL;
52 <  moving          = NULL;
53 <  moved           = NULL;
54 <  oldPos          = NULL;
55 <  
52 >  moving = NULL;
53 >  moved = NULL;
54 >  oldPos = NULL;
55 >
56    nConstrained = 0;
57  
58    checkConstraints();
59 + */
60   }
61  
62 < Integrator::~Integrator() {
63 <  
64 <  if( nConstrained ){
62 > template<typename T> Integrator<T>::~Integrator(){
63 >  if (consFramework != NULL)
64 >    delete consFramework;
65 > /*
66 >  if (nConstrained){
67      delete[] constrainedA;
68      delete[] constrainedB;
69      delete[] constrainedDsqr;
# Line 51 | Line 71 | Integrator::~Integrator() {
71      delete[] moved;
72      delete[] oldPos;
73    }
74 <  
74 > */
75   }
76  
77 < void Integrator::checkConstraints( void ){
78 <
59 <
77 > /*
78 > template<typename T> void Integrator<T>::checkConstraints(void){
79    isConstrained = 0;
80  
81 <  Constraint *temp_con;
82 <  Constraint *dummy_plug;
81 >  Constraint* temp_con;
82 >  Constraint* dummy_plug;
83    temp_con = new Constraint[info->n_SRI];
84    nConstrained = 0;
85    int constrained = 0;
86 <  
86 >
87    SRI** theArray;
88 <  for(int i = 0; i < nMols; i++){
89 <    
90 <    theArray = (SRI**) molecules[i].getMyBonds();
91 <    for(int j=0; j<molecules[i].getNBonds(); j++){
73 <      
88 >  for (int i = 0; i < nMols; i++){
89 >
90 >          theArray = (SRI * *) molecules[i].getMyBonds();
91 >    for (int j = 0; j < molecules[i].getNBonds(); j++){
92        constrained = theArray[j]->is_constrained();
93  
94 <      if(constrained){
94 >      if (constrained){
95 >        dummy_plug = theArray[j]->get_constraint();
96 >        temp_con[nConstrained].set_a(dummy_plug->get_a());
97 >        temp_con[nConstrained].set_b(dummy_plug->get_b());
98 >        temp_con[nConstrained].set_dsqr(dummy_plug->get_dsqr());
99  
100 <        dummy_plug = theArray[j]->get_constraint();
101 <        temp_con[nConstrained].set_a( dummy_plug->get_a() );
102 <        temp_con[nConstrained].set_b( dummy_plug->get_b() );
81 <        temp_con[nConstrained].set_dsqr( dummy_plug->get_dsqr() );
82 <        
83 <        nConstrained++;
84 <        constrained = 0;
85 <      }
100 >        nConstrained++;
101 >        constrained = 0;
102 >      }
103      }
104  
105 <    theArray = (SRI**) molecules[i].getMyBends();
106 <    for(int j=0; j<molecules[i].getNBends(); j++){
90 <      
105 >    theArray = (SRI * *) molecules[i].getMyBends();
106 >    for (int j = 0; j < molecules[i].getNBends(); j++){
107        constrained = theArray[j]->is_constrained();
108 <      
109 <      if(constrained){
110 <        
111 <        dummy_plug = theArray[j]->get_constraint();
112 <        temp_con[nConstrained].set_a( dummy_plug->get_a() );
113 <        temp_con[nConstrained].set_b( dummy_plug->get_b() );
114 <        temp_con[nConstrained].set_dsqr( dummy_plug->get_dsqr() );
115 <        
116 <        nConstrained++;
101 <        constrained = 0;
108 >
109 >      if (constrained){
110 >        dummy_plug = theArray[j]->get_constraint();
111 >        temp_con[nConstrained].set_a(dummy_plug->get_a());
112 >        temp_con[nConstrained].set_b(Dummy_plug->get_b());
113 >        temp_con[nConstrained].set_dsqr(dummy_plug->get_dsqr());
114 >
115 >        nConstrained++;
116 >        constrained = 0;
117        }
118      }
119  
120 <    theArray = (SRI**) molecules[i].getMyTorsions();
121 <    for(int j=0; j<molecules[i].getNTorsions(); j++){
107 <      
120 >    theArray = (SRI * *) molecules[i].getMyTorsions();
121 >    for (int j = 0; j < molecules[i].getNTorsions(); j++){
122        constrained = theArray[j]->is_constrained();
123 <      
124 <      if(constrained){
125 <        
126 <        dummy_plug = theArray[j]->get_constraint();
127 <        temp_con[nConstrained].set_a( dummy_plug->get_a() );
128 <        temp_con[nConstrained].set_b( dummy_plug->get_b() );
129 <        temp_con[nConstrained].set_dsqr( dummy_plug->get_dsqr() );
130 <        
131 <        nConstrained++;
118 <        constrained = 0;
123 >
124 >      if (constrained){
125 >        dummy_plug = theArray[j]->get_constraint();
126 >        temp_con[nConstrained].set_a(dummy_plug->get_a());
127 >        temp_con[nConstrained].set_b(dummy_plug->get_b());
128 >        temp_con[nConstrained].set_dsqr(dummy_plug->get_dsqr());
129 >
130 >        nConstrained++;
131 >        constrained = 0;
132        }
133      }
134    }
135  
136 <  if(nConstrained > 0){
137 <    
136 >
137 >  if (nConstrained > 0){
138      isConstrained = 1;
139  
140 <    if(constrainedA != NULL )    delete[] constrainedA;
141 <    if(constrainedB != NULL )    delete[] constrainedB;
142 <    if(constrainedDsqr != NULL ) delete[] constrainedDsqr;
140 >    if (constrainedA != NULL)
141 >      delete[] constrainedA;
142 >    if (constrainedB != NULL)
143 >      delete[] constrainedB;
144 >    if (constrainedDsqr != NULL)
145 >      delete[] constrainedDsqr;
146  
147 <    constrainedA =    new int[nConstrained];
148 <    constrainedB =    new int[nConstrained];
147 >    constrainedA = new int[nConstrained];
148 >    constrainedB = new int[nConstrained];
149      constrainedDsqr = new double[nConstrained];
150 <    
151 <    for( int i = 0; i < nConstrained; i++){
136 <      
150 >
151 >    for (int i = 0; i < nConstrained; i++){
152        constrainedA[i] = temp_con[i].get_a();
153        constrainedB[i] = temp_con[i].get_b();
154        constrainedDsqr[i] = temp_con[i].get_dsqr();
140
155      }
156  
157 <    
158 <    // save oldAtoms to check for lode balanceing later on.
159 <    
157 >
158 >    // save oldAtoms to check for lode balancing later on.
159 >
160      oldAtoms = nAtoms;
161 <    
161 >
162      moving = new int[nAtoms];
163 <    moved  = new int[nAtoms];
163 >    moved = new int[nAtoms];
164  
165 <    oldPos = new double[nAtoms*3];
165 >    oldPos = new double[nAtoms * 3];
166    }
167 <  
167 >
168    delete[] temp_con;
169   }
170 + */
171  
172 + template<typename T> void Integrator<T>::integrate(void){
173  
174 < void Integrator::integrate( void ){
175 <
176 <  int i, j;                         // loop counters
161 <
162 <  double runTime     = info->run_time;
163 <  double sampleTime  = info->sampleTime;
164 <  double statusTime  = info->statusTime;
174 >  double runTime = info->run_time;
175 >  double sampleTime = info->sampleTime;
176 >  double statusTime = info->statusTime;
177    double thermalTime = info->thermalTime;
178 +  double resetTime = info->resetTime;
179  
180 +  double difference;
181    double currSample;
182    double currThermal;
183    double currStatus;
184 <  double currTime;
184 >  double currReset;
185  
186    int calcPot, calcStress;
173  int isError;
187  
188 <  tStats   = new Thermo( info );
189 <  statOut  = new StatWriter( info );
190 <  dumpOut  = new DumpWriter( info );
188 >  tStats = new Thermo(info);
189 >  statOut = new StatWriter(info);
190 >  dumpOut = new DumpWriter(info);
191  
192    atoms = info->atoms;
180  DirectionalAtom* dAtom;
193  
194    dt = info->dt;
195    dt2 = 0.5 * dt;
196  
197 +  readyCheck();
198 +
199 +  // remove center of mass drift velocity (in case we passed in a configuration
200 +  // that was drifting
201 +  tStats->removeCOMdrift();
202 +
203 +  // initialize the retraints if necessary
204 +  if (info->useSolidThermInt && !info->useLiquidThermInt) {
205 +    myFF->initRestraints();
206 +  }
207 +
208    // initialize the forces before the first step
209  
210 <  myFF->doForces(1,1);
210 >  calcForce(1, 1);
211 >
212 >  //execute constraint algorithm to make sure at the very beginning the system is constrained  
213 >  //consFramework->doPreConstraint();
214 >  //consFramework->doConstrainA();
215 >  //calcForce(1, 1);
216 >  //consFramework->doConstrainB();
217    
218 <  if( info->setTemp ){
219 <    
191 <    tStats->velocitize();
218 >  if (info->setTemp){
219 >    thermalize();
220    }
221 <  
194 <  dumpOut->writeDump( 0.0 );
195 <  statOut->writeStat( 0.0 );
196 <  
221 >
222    calcPot     = 0;
223    calcStress  = 0;
224 <  currSample  = sampleTime;
225 <  currThermal = thermalTime;
226 <  currStatus  = statusTime;
227 <  currTime    = 0.0;;
224 >  currSample  = sampleTime + info->getTime();
225 >  currThermal = thermalTime+ info->getTime();
226 >  currStatus  = statusTime + info->getTime();
227 >  currReset   = resetTime  + info->getTime();
228  
229 +  dumpOut->writeDump(info->getTime());
230 +  statOut->writeStat(info->getTime());
231  
205  readyCheck();
232  
233   #ifdef IS_MPI
234 <  strcpy( checkPointMsg,
209 <          "The integrator is ready to go." );
234 >  strcpy(checkPointMsg, "The integrator is ready to go.");
235    MPIcheckPoint();
236   #endif // is_mpi
237  
238 <  while( currTime < runTime ){
239 <
240 <    if( (currTime+dt) >= currStatus ){
238 >  while (info->getTime() < runTime && !stopIntegrator()){
239 >    difference = info->getTime() + dt - currStatus;
240 >    if (difference > 0 || fabs(difference) < 1e-4 ){
241        calcPot = 1;
242        calcStress = 1;
243      }
244  
245 <    integrateStep( calcPot, calcStress );
246 <      
247 <    currTime += dt;
245 > #ifdef PROFILE
246 >    startProfile( pro1 );
247 > #endif
248 >    
249 >    integrateStep(calcPot, calcStress);
250  
251 <    if( info->setTemp ){
252 <      if( currTime >= currThermal ){
253 <        tStats->velocitize();
254 <        currThermal += thermalTime;
251 > #ifdef PROFILE
252 >    endProfile( pro1 );
253 >
254 >    startProfile( pro2 );
255 > #endif // profile
256 >
257 >    info->incrTime(dt);
258 >
259 >    if (info->setTemp){
260 >      if (info->getTime() >= currThermal){
261 >        thermalize();
262 >        currThermal += thermalTime;
263        }
264      }
265  
266 <    if( currTime >= currSample ){
267 <      dumpOut->writeDump( currTime );
266 >    if (info->getTime() >= currSample){
267 >      dumpOut->writeDump(info->getTime());
268        currSample += sampleTime;
269      }
270  
271 <    if( currTime >= currStatus ){
272 <      statOut->writeStat( currTime );
273 <      calcPot = 0;
271 >    if (info->getTime() >= currStatus){
272 >      statOut->writeStat(info->getTime());
273 >      calcPot = 0;
274        calcStress = 0;
275        currStatus += statusTime;
276 <    }
276 >    }
277  
278 +    if (info->resetIntegrator){
279 +      if (info->getTime() >= currReset){
280 +        this->resetIntegrator();
281 +        currReset += resetTime;
282 +      }
283 +    }
284 +    
285 + #ifdef PROFILE
286 +    endProfile( pro2 );
287 + #endif //profile
288 +
289   #ifdef IS_MPI
290 <    strcpy( checkPointMsg,
245 <            "successfully took a time step." );
290 >    strcpy(checkPointMsg, "successfully took a time step.");
291      MPIcheckPoint();
292   #endif // is_mpi
248
293    }
294  
295 <  dumpOut->writeFinal(currTime);
295 >  // dump out a file containing the omega values for the final configuration
296 >  if (info->useSolidThermInt && !info->useLiquidThermInt)
297 >    myFF->dumpzAngle();
298 >  
299  
300    delete dumpOut;
301    delete statOut;
302   }
303  
304 < void Integrator::integrateStep( int calcPot, int calcStress ){
304 > template<typename T> void Integrator<T>::integrateStep(int calcPot,
305 >                                                       int calcStress){
306 >  // Position full step, and velocity half step
307  
308 + #ifdef PROFILE
309 +  startProfile(pro3);
310 + #endif //profile
311  
312 <      
313 <  // Position full step, and velocity half step
312 >  //save old state (position, velocity etc)
313 >  consFramework->doPreConstraint();
314  
315 <  preMove();
315 > #ifdef PROFILE
316 >  endProfile(pro3);
317 >
318 >  startProfile(pro4);
319 > #endif // profile
320 >
321    moveA();
265  if( nConstrained ) constrainA();
322  
323 + #ifdef PROFILE
324 +  endProfile(pro4);
325    
326 +  startProfile(pro5);
327 + #endif//profile
328 +
329 +
330   #ifdef IS_MPI
331 <  strcpy( checkPointMsg, "Succesful moveA\n" );
331 >  strcpy(checkPointMsg, "Succesful moveA\n");
332    MPIcheckPoint();
333   #endif // is_mpi
272  
334  
335    // calc forces
336 +  calcForce(calcPot, calcStress);
337  
276  myFF->doForces(calcPot,calcStress);
277
338   #ifdef IS_MPI
339 <  strcpy( checkPointMsg, "Succesful doForces\n" );
339 >  strcpy(checkPointMsg, "Succesful doForces\n");
340    MPIcheckPoint();
341   #endif // is_mpi
282  
342  
343 + #ifdef PROFILE
344 +  endProfile( pro5 );
345 +
346 +  startProfile( pro6 );
347 + #endif //profile
348 +
349    // finish the velocity  half step
350 <  
350 >
351    moveB();
352 <  if( nConstrained ) constrainB();
353 <  
352 >
353 > #ifdef PROFILE
354 >  endProfile(pro6);
355 > #endif // profile
356 >
357   #ifdef IS_MPI
358 <  strcpy( checkPointMsg, "Succesful moveB\n" );
358 >  strcpy(checkPointMsg, "Succesful moveB\n");
359    MPIcheckPoint();
360   #endif // is_mpi
293  
294
361   }
362  
363  
364 < void Integrator::moveA( void ){
365 <  
300 <  int i, j;
364 > template<typename T> void Integrator<T>::moveA(void){
365 >  size_t i, j;
366    DirectionalAtom* dAtom;
367    double Tb[3], ji[3];
303  double A[3][3], I[3][3];
304  double angle;
368    double vel[3], pos[3], frc[3];
369    double mass;
370 +  double omega;
371 +
372 +  for (i = 0; i < integrableObjects.size() ; i++){
373 +    integrableObjects[i]->getVel(vel);
374 +    integrableObjects[i]->getPos(pos);
375 +    integrableObjects[i]->getFrc(frc);
376 +    
377 +    mass = integrableObjects[i]->getMass();
378  
379 <  for( i=0; i<nAtoms; i++ ){
309 <
310 <    atoms[i]->getVel( vel );
311 <    atoms[i]->getPos( pos );
312 <    atoms[i]->getFrc( frc );
313 <
314 <    mass = atoms[i]->getMass();
315 <
316 <    for (j=0; j < 3; j++) {
379 >    for (j = 0; j < 3; j++){
380        // velocity half step
381 <      vel[j] += ( dt2 * frc[j] / mass ) * eConvert;
381 >      vel[j] += (dt2 * frc[j] / mass) * eConvert;
382        // position whole step
383        pos[j] += dt * vel[j];
384      }
385  
386 <    atoms[i]->setVel( vel );
387 <    atoms[i]->setPos( pos );
386 >    integrableObjects[i]->setVel(vel);
387 >    integrableObjects[i]->setPos(pos);
388  
389 <    if( atoms[i]->isDirectional() ){
389 >    if (integrableObjects[i]->isDirectional()){
390  
328      dAtom = (DirectionalAtom *)atoms[i];
329          
391        // get and convert the torque to body frame
331      
332      dAtom->getTrq( Tb );
333      dAtom->lab2Body( Tb );
392  
393 +      integrableObjects[i]->getTrq(Tb);
394 +      integrableObjects[i]->lab2Body(Tb);
395 +
396        // get the angular momentum, and propagate a half step
397  
398 <      dAtom->getJ( ji );
398 >      integrableObjects[i]->getJ(ji);
399  
400 <      for (j=0; j < 3; j++)
400 >      for (j = 0; j < 3; j++)
401          ji[j] += (dt2 * Tb[j]) * eConvert;
341      
342      // use the angular velocities to propagate the rotation matrix a
343      // full time step
402  
403 <      dAtom->getA(A);
346 <      dAtom->getI(I);
347 <    
348 <      // rotate about the x-axis      
349 <      angle = dt2 * ji[0] / I[0][0];
350 <      this->rotate( 1, 2, angle, ji, A );
403 >      this->rotationPropagation( integrableObjects[i], ji );
404  
405 <      // rotate about the y-axis
406 <      angle = dt2 * ji[1] / I[1][1];
354 <      this->rotate( 2, 0, angle, ji, A );
355 <      
356 <      // rotate about the z-axis
357 <      angle = dt * ji[2] / I[2][2];
358 <      this->rotate( 0, 1, angle, ji, A);
359 <      
360 <      // rotate about the y-axis
361 <      angle = dt2 * ji[1] / I[1][1];
362 <      this->rotate( 2, 0, angle, ji, A );
363 <      
364 <       // rotate about the x-axis
365 <      angle = dt2 * ji[0] / I[0][0];
366 <      this->rotate( 1, 2, angle, ji, A );
367 <      
368 <
369 <      dAtom->setJ( ji );
370 <      dAtom->setA( A  );
371 <          
372 <    }    
405 >      integrableObjects[i]->setJ(ji);
406 >    }
407    }
408 +
409 +  consFramework->doConstrainA();
410   }
411  
412  
413 < void Integrator::moveB( void ){
413 > template<typename T> void Integrator<T>::moveB(void){
414    int i, j;
379  DirectionalAtom* dAtom;
415    double Tb[3], ji[3];
416    double vel[3], frc[3];
417    double mass;
418  
419 <  for( i=0; i<nAtoms; i++ ){
420 <
421 <    atoms[i]->getVel( vel );
387 <    atoms[i]->getFrc( frc );
419 >  for (i = 0; i < integrableObjects.size(); i++){
420 >    integrableObjects[i]->getVel(vel);
421 >    integrableObjects[i]->getFrc(frc);
422  
423 <    mass = atoms[i]->getMass();
423 >    mass = integrableObjects[i]->getMass();
424  
425      // velocity half step
426 <    for (j=0; j < 3; j++)
427 <      vel[j] += ( dt2 * frc[j] / mass ) * eConvert;
394 <    
395 <    atoms[i]->setVel( vel );
396 <
397 <    if( atoms[i]->isDirectional() ){
426 >    for (j = 0; j < 3; j++)
427 >      vel[j] += (dt2 * frc[j] / mass) * eConvert;
428  
429 <      dAtom = (DirectionalAtom *)atoms[i];
429 >    integrableObjects[i]->setVel(vel);
430  
431 <      // get and convert the torque to body frame      
431 >    if (integrableObjects[i]->isDirectional()){
432  
433 <      dAtom->getTrq( Tb );
404 <      dAtom->lab2Body( Tb );
433 >      // get and convert the torque to body frame
434  
435 +      integrableObjects[i]->getTrq(Tb);
436 +      integrableObjects[i]->lab2Body(Tb);
437 +
438        // get the angular momentum, and propagate a half step
439  
440 <      dAtom->getJ( ji );
440 >      integrableObjects[i]->getJ(ji);
441  
442 <      for (j=0; j < 3; j++)
442 >      for (j = 0; j < 3; j++)
443          ji[j] += (dt2 * Tb[j]) * eConvert;
412      
444  
445 <      dAtom->setJ( ji );
445 >
446 >      integrableObjects[i]->setJ(ji);
447      }
448    }
449 +
450 +  consFramework->doConstrainB();
451   }
452  
453 < void Integrator::preMove( void ){
453 > /*
454 > template<typename T> void Integrator<T>::preMove(void){
455    int i, j;
456    double pos[3];
457  
458 <  if( nConstrained ){
459 <
460 <    for(i=0; i < nAtoms; i++) {
426 <
427 <      atoms[i]->getPos( pos );
458 >  if (nConstrained){
459 >    for (i = 0; i < nAtoms; i++){
460 >      atoms[i]->getPos(pos);
461  
462 <      for (j = 0; j < 3; j++) {        
463 <        oldPos[3*i + j] = pos[j];
462 >      for (j = 0; j < 3; j++){
463 >        oldPos[3 * i + j] = pos[j];
464        }
432
465      }
466 <  }  
466 >  }
467   }
468  
469 < void Integrator::constrainA(){
470 <
439 <  int i,j,k;
469 > template<typename T> void Integrator<T>::constrainA(){
470 >  int i, j;
471    int done;
472    double posA[3], posB[3];
473    double velA[3], velB[3];
# Line 451 | Line 482 | void Integrator::constrainA(){
482    double gab;
483    int iteration;
484  
485 <  for( i=0; i<nAtoms; i++){    
485 >  for (i = 0; i < nAtoms; i++){
486      moving[i] = 0;
487 <    moved[i]  = 1;
487 >    moved[i] = 1;
488    }
489  
490    iteration = 0;
491    done = 0;
492 <  while( !done && (iteration < maxIteration )){
462 <
492 >  while (!done && (iteration < maxIteration)){
493      done = 1;
494 <    for(i=0; i<nConstrained; i++){
465 <
494 >    for (i = 0; i < nConstrained; i++){
495        a = constrainedA[i];
496        b = constrainedB[i];
468      
469      ax = (a*3) + 0;
470      ay = (a*3) + 1;
471      az = (a*3) + 2;
497  
498 <      bx = (b*3) + 0;
499 <      by = (b*3) + 1;
500 <      bz = (b*3) + 2;
498 >      ax = (a * 3) + 0;
499 >      ay = (a * 3) + 1;
500 >      az = (a * 3) + 2;
501  
502 <      if( moved[a] || moved[b] ){
503 <        
504 <        atoms[a]->getPos( posA );
505 <        atoms[b]->getPos( posB );
506 <        
507 <        for (j = 0; j < 3; j++ )
502 >      bx = (b * 3) + 0;
503 >      by = (b * 3) + 1;
504 >      bz = (b * 3) + 2;
505 >
506 >      if (moved[a] || moved[b]){
507 >        atoms[a]->getPos(posA);
508 >        atoms[b]->getPos(posB);
509 >
510 >        for (j = 0; j < 3; j++)
511            pab[j] = posA[j] - posB[j];
484        
485        //periodic boundary condition
512  
513 <        info->wrapVector( pab );
513 >        //periodic boundary condition
514  
515 <        pabsq = pab[0] * pab[0] + pab[1] * pab[1] + pab[2] * pab[2];
515 >        info->wrapVector(pab);
516  
517 <        rabsq = constrainedDsqr[i];
492 <        diffsq = rabsq - pabsq;
517 >        pabsq = pab[0] * pab[0] + pab[1] * pab[1] + pab[2] * pab[2];
518  
519 <        // the original rattle code from alan tidesley
520 <        if (fabs(diffsq) > (tol*rabsq*2)) {
496 <          rab[0] = oldPos[ax] - oldPos[bx];
497 <          rab[1] = oldPos[ay] - oldPos[by];
498 <          rab[2] = oldPos[az] - oldPos[bz];
519 >        rabsq = constrainedDsqr[i];
520 >        diffsq = rabsq - pabsq;
521  
522 <          info->wrapVector( rab );
522 >        // the original rattle code from alan tidesley
523 >        if (fabs(diffsq) > (tol * rabsq * 2)){
524 >          rab[0] = oldPos[ax] - oldPos[bx];
525 >          rab[1] = oldPos[ay] - oldPos[by];
526 >          rab[2] = oldPos[az] - oldPos[bz];
527  
528 <          rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
528 >          info->wrapVector(rab);
529  
530 <          rpabsq = rpab * rpab;
530 >          rpab = rab[0] * pab[0] + rab[1] * pab[1] + rab[2] * pab[2];
531  
532 +          rpabsq = rpab * rpab;
533  
507          if (rpabsq < (rabsq * -diffsq)){
534  
535 +          if (rpabsq < (rabsq * -diffsq)){
536   #ifdef IS_MPI
537 <            a = atoms[a]->getGlobalIndex();
538 <            b = atoms[b]->getGlobalIndex();
537 >            a = atoms[a]->getGlobalIndex();
538 >            b = atoms[b]->getGlobalIndex();
539   #endif //is_mpi
540 <            sprintf( painCave.errMsg,
541 <                     "Constraint failure in constrainA at atom %d and %d.\n",
542 <                     a, b );
543 <            painCave.isFatal = 1;
544 <            simError();
545 <          }
540 >            sprintf(painCave.errMsg,
541 >                    "Constraint failure in constrainA at atom %d and %d.\n", a,
542 >                    b);
543 >            painCave.isFatal = 1;
544 >            simError();
545 >          }
546  
547 <          rma = 1.0 / atoms[a]->getMass();
548 <          rmb = 1.0 / atoms[b]->getMass();
547 >          rma = 1.0 / atoms[a]->getMass();
548 >          rmb = 1.0 / atoms[b]->getMass();
549  
550 <          gab = diffsq / ( 2.0 * ( rma + rmb ) * rpab );
550 >          gab = diffsq / (2.0 * (rma + rmb) * rpab);
551  
552            dx = rab[0] * gab;
553            dy = rab[1] * gab;
554            dz = rab[2] * gab;
555  
556 <          posA[0] += rma * dx;
557 <          posA[1] += rma * dy;
558 <          posA[2] += rma * dz;
556 >          posA[0] += rma * dx;
557 >          posA[1] += rma * dy;
558 >          posA[2] += rma * dz;
559  
560 <          atoms[a]->setPos( posA );
560 >          atoms[a]->setPos(posA);
561  
562 <          posB[0] -= rmb * dx;
563 <          posB[1] -= rmb * dy;
564 <          posB[2] -= rmb * dz;
562 >          posB[0] -= rmb * dx;
563 >          posB[1] -= rmb * dy;
564 >          posB[2] -= rmb * dz;
565  
566 <          atoms[b]->setPos( posB );
566 >          atoms[b]->setPos(posB);
567  
568            dx = dx / dt;
569            dy = dy / dt;
570            dz = dz / dt;
571  
572 <          atoms[a]->getVel( velA );
572 >          atoms[a]->getVel(velA);
573  
574 <          velA[0] += rma * dx;
575 <          velA[1] += rma * dy;
576 <          velA[2] += rma * dz;
574 >          velA[0] += rma * dx;
575 >          velA[1] += rma * dy;
576 >          velA[2] += rma * dz;
577  
578 <          atoms[a]->setVel( velA );
578 >          atoms[a]->setVel(velA);
579  
580 <          atoms[b]->getVel( velB );
580 >          atoms[b]->getVel(velB);
581  
582 <          velB[0] -= rmb * dx;
583 <          velB[1] -= rmb * dy;
584 <          velB[2] -= rmb * dz;
582 >          velB[0] -= rmb * dx;
583 >          velB[1] -= rmb * dy;
584 >          velB[2] -= rmb * dz;
585  
586 <          atoms[b]->setVel( velB );
586 >          atoms[b]->setVel(velB);
587  
588 <          moving[a] = 1;
589 <          moving[b] = 1;
590 <          done = 0;
591 <        }
588 >          moving[a] = 1;
589 >          moving[b] = 1;
590 >          done = 0;
591 >        }
592        }
593      }
594 <    
595 <    for(i=0; i<nAtoms; i++){
569 <      
594 >
595 >    for (i = 0; i < nAtoms; i++){
596        moved[i] = moving[i];
597        moving[i] = 0;
598      }
# Line 574 | Line 600 | void Integrator::constrainA(){
600      iteration++;
601    }
602  
603 <  if( !done ){
604 <
605 <    sprintf( painCave.errMsg,
606 <             "Constraint failure in constrainA, too many iterations: %d\n",
581 <             iteration );
603 >  if (!done){
604 >    sprintf(painCave.errMsg,
605 >            "Constraint failure in constrainA, too many iterations: %d\n",
606 >            iteration);
607      painCave.isFatal = 1;
608      simError();
609    }
610  
611   }
612  
613 < void Integrator::constrainB( void ){
614 <  
590 <  int i,j,k;
613 > template<typename T> void Integrator<T>::constrainB(void){
614 >  int i, j;
615    int done;
616    double posA[3], posB[3];
617    double velA[3], velB[3];
# Line 596 | Line 620 | void Integrator::constrainB( void ){
620    int a, b, ax, ay, az, bx, by, bz;
621    double rma, rmb;
622    double dx, dy, dz;
623 <  double rabsq, pabsq, rvab;
600 <  double diffsq;
623 >  double rvab;
624    double gab;
625    int iteration;
626  
627 <  for(i=0; i<nAtoms; i++){
627 >  for (i = 0; i < nAtoms; i++){
628      moving[i] = 0;
629      moved[i] = 1;
630    }
631  
632    done = 0;
633    iteration = 0;
634 <  while( !done && (iteration < maxIteration ) ){
612 <
634 >  while (!done && (iteration < maxIteration)){
635      done = 1;
636  
637 <    for(i=0; i<nConstrained; i++){
616 <      
637 >    for (i = 0; i < nConstrained; i++){
638        a = constrainedA[i];
639        b = constrainedB[i];
640  
641 <      ax = (a*3) + 0;
642 <      ay = (a*3) + 1;
643 <      az = (a*3) + 2;
641 >      ax = (a * 3) + 0;
642 >      ay = (a * 3) + 1;
643 >      az = (a * 3) + 2;
644  
645 <      bx = (b*3) + 0;
646 <      by = (b*3) + 1;
647 <      bz = (b*3) + 2;
645 >      bx = (b * 3) + 0;
646 >      by = (b * 3) + 1;
647 >      bz = (b * 3) + 2;
648  
649 <      if( moved[a] || moved[b] ){
649 >      if (moved[a] || moved[b]){
650 >        atoms[a]->getVel(velA);
651 >        atoms[b]->getVel(velB);
652  
653 <        atoms[a]->getVel( velA );
654 <        atoms[b]->getVel( velB );
655 <          
633 <        vxab = velA[0] - velB[0];
634 <        vyab = velA[1] - velB[1];
635 <        vzab = velA[2] - velB[2];
653 >        vxab = velA[0] - velB[0];
654 >        vyab = velA[1] - velB[1];
655 >        vzab = velA[2] - velB[2];
656  
657 <        atoms[a]->getPos( posA );
658 <        atoms[b]->getPos( posB );
657 >        atoms[a]->getPos(posA);
658 >        atoms[b]->getPos(posB);
659  
660 <        for (j = 0; j < 3; j++)
660 >        for (j = 0; j < 3; j++)
661            rab[j] = posA[j] - posB[j];
642          
643        info->wrapVector( rab );
644        
645        rma = 1.0 / atoms[a]->getMass();
646        rmb = 1.0 / atoms[b]->getMass();
662  
663 <        rvab = rab[0] * vxab + rab[1] * vyab + rab[2] * vzab;
649 <          
650 <        gab = -rvab / ( ( rma + rmb ) * constrainedDsqr[i] );
663 >        info->wrapVector(rab);
664  
665 <        if (fabs(gab) > tol) {
666 <          
654 <          dx = rab[0] * gab;
655 <          dy = rab[1] * gab;
656 <          dz = rab[2] * gab;
657 <        
658 <          velA[0] += rma * dx;
659 <          velA[1] += rma * dy;
660 <          velA[2] += rma * dz;
665 >        rma = 1.0 / atoms[a]->getMass();
666 >        rmb = 1.0 / atoms[b]->getMass();
667  
668 <          atoms[a]->setVel( velA );
668 >        rvab = rab[0] * vxab + rab[1] * vyab + rab[2] * vzab;
669  
670 <          velB[0] -= rmb * dx;
665 <          velB[1] -= rmb * dy;
666 <          velB[2] -= rmb * dz;
670 >        gab = -rvab / ((rma + rmb) * constrainedDsqr[i]);
671  
672 <          atoms[b]->setVel( velB );
673 <          
674 <          moving[a] = 1;
675 <          moving[b] = 1;
676 <          done = 0;
677 <        }
672 >        if (fabs(gab) > tol){
673 >          dx = rab[0] * gab;
674 >          dy = rab[1] * gab;
675 >          dz = rab[2] * gab;
676 >
677 >          velA[0] += rma * dx;
678 >          velA[1] += rma * dy;
679 >          velA[2] += rma * dz;
680 >
681 >          atoms[a]->setVel(velA);
682 >
683 >          velB[0] -= rmb * dx;
684 >          velB[1] -= rmb * dy;
685 >          velB[2] -= rmb * dz;
686 >
687 >          atoms[b]->setVel(velB);
688 >
689 >          moving[a] = 1;
690 >          moving[b] = 1;
691 >          done = 0;
692 >        }
693        }
694      }
695  
696 <    for(i=0; i<nAtoms; i++){
696 >    for (i = 0; i < nAtoms; i++){
697        moved[i] = moving[i];
698        moving[i] = 0;
699      }
700 <    
700 >
701      iteration++;
702    }
684  
685  if( !done ){
703  
704 <  
705 <    sprintf( painCave.errMsg,
706 <             "Constraint failure in constrainB, too many iterations: %d\n",
707 <             iteration );
704 >  if (!done){
705 >    sprintf(painCave.errMsg,
706 >            "Constraint failure in constrainB, too many iterations: %d\n",
707 >            iteration);
708      painCave.isFatal = 1;
709      simError();
710 <  }
694 <
710 >  }
711   }
712 + */
713 + template<typename T> void Integrator<T>::rotationPropagation
714 + ( StuntDouble* sd, double ji[3] ){
715  
716 < void Integrator::rotate( int axes1, int axes2, double angle, double ji[3],
717 <                         double A[3][3] ){
716 >  double angle;
717 >  double A[3][3], I[3][3];
718 >  int i, j, k;
719  
720 <  int i,j,k;
720 >  // use the angular velocities to propagate the rotation matrix a
721 >  // full time step
722 >
723 >  sd->getA(A);
724 >  sd->getI(I);
725 >
726 >  if (sd->isLinear()) {
727 >    i = sd->linearAxis();
728 >    j = (i+1)%3;
729 >    k = (i+2)%3;
730 >    
731 >    angle = dt2 * ji[j] / I[j][j];
732 >    this->rotate( k, i, angle, ji, A );
733 >
734 >    angle = dt * ji[k] / I[k][k];
735 >    this->rotate( i, j, angle, ji, A);
736 >
737 >    angle = dt2 * ji[j] / I[j][j];
738 >    this->rotate( k, i, angle, ji, A );
739 >
740 >  } else {
741 >    // rotate about the x-axis
742 >    angle = dt2 * ji[0] / I[0][0];
743 >    this->rotate( 1, 2, angle, ji, A );
744 >    
745 >    // rotate about the y-axis
746 >    angle = dt2 * ji[1] / I[1][1];
747 >    this->rotate( 2, 0, angle, ji, A );
748 >    
749 >    // rotate about the z-axis
750 >    angle = dt * ji[2] / I[2][2];
751 >    sd->addZangle(angle);
752 >    this->rotate( 0, 1, angle, ji, A);
753 >    
754 >    // rotate about the y-axis
755 >    angle = dt2 * ji[1] / I[1][1];
756 >    this->rotate( 2, 0, angle, ji, A );
757 >    
758 >    // rotate about the x-axis
759 >    angle = dt2 * ji[0] / I[0][0];
760 >    this->rotate( 1, 2, angle, ji, A );
761 >    
762 >  }
763 >  sd->setA( A  );
764 > }
765 >
766 > template<typename T> void Integrator<T>::rotate(int axes1, int axes2,
767 >                                                double angle, double ji[3],
768 >                                                double A[3][3]){
769 >  int i, j, k;
770    double sinAngle;
771    double cosAngle;
772    double angleSqr;
# Line 709 | Line 778 | void Integrator::rotate( int axes1, int axes2, double
778  
779    // initialize the tempA
780  
781 <  for(i=0; i<3; i++){
782 <    for(j=0; j<3; j++){
781 >  for (i = 0; i < 3; i++){
782 >    for (j = 0; j < 3; j++){
783        tempA[j][i] = A[i][j];
784      }
785    }
786  
787    // initialize the tempJ
788  
789 <  for( i=0; i<3; i++) tempJ[i] = ji[i];
790 <  
789 >  for (i = 0; i < 3; i++)
790 >    tempJ[i] = ji[i];
791 >
792    // initalize rot as a unit matrix
793  
794    rot[0][0] = 1.0;
# Line 728 | Line 798 | void Integrator::rotate( int axes1, int axes2, double
798    rot[1][0] = 0.0;
799    rot[1][1] = 1.0;
800    rot[1][2] = 0.0;
801 <  
801 >
802    rot[2][0] = 0.0;
803    rot[2][1] = 0.0;
804    rot[2][2] = 1.0;
805 <  
805 >
806    // use a small angle aproximation for sin and cosine
807  
808 <  angleSqr  = angle * angle;
808 >  angleSqr = angle * angle;
809    angleSqrOver4 = angleSqr / 4.0;
810    top = 1.0 - angleSqrOver4;
811    bottom = 1.0 + angleSqrOver4;
# Line 748 | Line 818 | void Integrator::rotate( int axes1, int axes2, double
818  
819    rot[axes1][axes2] = sinAngle;
820    rot[axes2][axes1] = -sinAngle;
821 <  
821 >
822    // rotate the momentum acoording to: ji[] = rot[][] * ji[]
823 <  
824 <  for(i=0; i<3; i++){
823 >
824 >  for (i = 0; i < 3; i++){
825      ji[i] = 0.0;
826 <    for(k=0; k<3; k++){
826 >    for (k = 0; k < 3; k++){
827        ji[i] += rot[i][k] * tempJ[k];
828      }
829    }
830  
831 <  // rotate the Rotation matrix acording to:
831 >  // rotate the Rotation matrix acording to:
832    //            A[][] = A[][] * transpose(rot[][])
833  
834  
# Line 766 | Line 836 | void Integrator::rotate( int axes1, int axes2, double
836    // calculation as:
837    //                transpose(A[][]) = transpose(A[][]) * transpose(rot[][])
838  
839 <  for(i=0; i<3; i++){
840 <    for(j=0; j<3; j++){
839 >  for (i = 0; i < 3; i++){
840 >    for (j = 0; j < 3; j++){
841        A[j][i] = 0.0;
842 <      for(k=0; k<3; k++){
843 <        A[j][i] += tempA[i][k] * rot[j][k];
842 >      for (k = 0; k < 3; k++){
843 >        A[j][i] += tempA[i][k] * rot[j][k];
844        }
845      }
846    }
847   }
848 +
849 + template<typename T> void Integrator<T>::calcForce(int calcPot, int calcStress){
850 +  myFF->doForces(calcPot, calcStress);
851 + }
852 +
853 + template<typename T> void Integrator<T>::thermalize(){
854 +  tStats->velocitize();
855 + }
856 +
857 + template<typename T> double Integrator<T>::getConservedQuantity(void){
858 +  return tStats->getTotalE();
859 + }
860 + template<typename T> string Integrator<T>::getAdditionalParameters(void){
861 +  //By default, return a null string
862 +  //The reason we use string instead of char* is that if we use char*, we will
863 +  //return a pointer point to local variable which might cause problem
864 +  return string();
865 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines