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 763 by tim, Mon Sep 15 16:52:02 2003 UTC vs.
Revision 1221 by chrisfen, Wed Jun 2 14:56:18 2004 UTC

# Line 1 | Line 1
1   #include <iostream>
2 < #include <cstdlib>
3 < #include <cmath>
2 > #include <stdlib.h>
3 > #include <math.h>
4  
5   #ifdef IS_MPI
6   #include "mpiSimulation.hpp"
7   #include <unistd.h>
8   #endif //is_mpi
9  
10 + #ifdef PROFILE
11 + #include "mdProfile.hpp"
12 + #endif // profile
13 +
14   #include "Integrator.hpp"
15   #include "simError.h"
16  
# Line 25 | Line 29 | template<typename T> Integrator<T>::Integrator(SimInfo
29    if (info->the_integrator != NULL){
30      delete info->the_integrator;
31    }
28  info->the_integrator = this;
32  
33    nAtoms = info->n_atoms;
34 <
34 >  integrableObjects = info->integrableObjects;
35 >
36    // check for constraints
37  
38    constrainedA = NULL;
# Line 41 | Line 45 | template<typename T> Integrator<T>::Integrator(SimInfo
45    nConstrained = 0;
46  
47    checkConstraints();
48 +
49   }
50  
51   template<typename T> Integrator<T>::~Integrator(){
# Line 65 | Line 70 | template<typename T> void Integrator<T>::checkConstrai
70  
71    SRI** theArray;
72    for (int i = 0; i < nMols; i++){
73 <    theArray = (SRI * *) molecules[i].getMyBonds();
73 >
74 >          theArray = (SRI * *) molecules[i].getMyBonds();
75      for (int j = 0; j < molecules[i].getNBonds(); j++){
76        constrained = theArray[j]->is_constrained();
77  
# Line 111 | Line 117 | template<typename T> void Integrator<T>::checkConstrai
117      }
118    }
119  
120 +
121    if (nConstrained > 0){
122      isConstrained = 1;
123  
# Line 132 | Line 139 | template<typename T> void Integrator<T>::checkConstrai
139      }
140  
141  
142 <    // save oldAtoms to check for lode balanceing later on.
142 >    // save oldAtoms to check for lode balancing later on.
143  
144      oldAtoms = nAtoms;
145  
# Line 147 | Line 154 | template<typename T> void Integrator<T>::integrate(voi
154  
155  
156   template<typename T> void Integrator<T>::integrate(void){
150  int i, j;                         // loop counters
157  
158    double runTime = info->run_time;
159    double sampleTime = info->sampleTime;
# Line 155 | Line 161 | template<typename T> void Integrator<T>::integrate(voi
161    double thermalTime = info->thermalTime;
162    double resetTime = info->resetTime;
163  
164 <
164 >  double difference;
165    double currSample;
166    double currThermal;
167    double currStatus;
168    double currReset;
169 <  
169 >
170    int calcPot, calcStress;
165  int isError;
171  
172    tStats = new Thermo(info);
173    statOut = new StatWriter(info);
174    dumpOut = new DumpWriter(info);
175  
176    atoms = info->atoms;
172  DirectionalAtom* dAtom;
177  
178    dt = info->dt;
179    dt2 = 0.5 * dt;
180 +
181 +  readyCheck();
182 +
183 +  // remove center of mass drift velocity (in case we passed in a configuration
184 +  // that was drifting
185 +  tStats->removeCOMdrift();
186 +
187 +  // initialize the retraints if necessary
188 +  if (info->useSolidThermInt && !info->useLiquidThermInt) {
189 +    myFF->initRestraints();
190 +  }
191  
192    // initialize the forces before the first step
193  
194    calcForce(1, 1);
195    
196 +  if (nConstrained){
197 +    preMove();
198 +    constrainA();
199 +    calcForce(1, 1);
200 +    constrainB();
201 +  }
202 +  
203    if (info->setTemp){
204      thermalize();
205    }
# Line 192 | Line 214 | template<typename T> void Integrator<T>::integrate(voi
214    dumpOut->writeDump(info->getTime());
215    statOut->writeStat(info->getTime());
216  
195  readyCheck();
217  
218   #ifdef IS_MPI
219    strcpy(checkPointMsg, "The integrator is ready to go.");
220    MPIcheckPoint();
221   #endif // is_mpi
222  
223 <  while (info->getTime() < runTime){
224 <    if ((info->getTime() + dt) >= currStatus){
223 >  while (info->getTime() < runTime && !stopIntegrator()){
224 >    difference = info->getTime() + dt - currStatus;
225 >    if (difference > 0 || fabs(difference) < 1e-4 ){
226        calcPot = 1;
227        calcStress = 1;
228      }
229  
230 + #ifdef PROFILE
231 +    startProfile( pro1 );
232 + #endif
233 +    
234      integrateStep(calcPot, calcStress);
235  
236 + #ifdef PROFILE
237 +    endProfile( pro1 );
238 +
239 +    startProfile( pro2 );
240 + #endif // profile
241 +
242      info->incrTime(dt);
243  
244      if (info->setTemp){
# Line 222 | Line 254 | template<typename T> void Integrator<T>::integrate(voi
254      }
255  
256      if (info->getTime() >= currStatus){
257 <      statOut->writeStat(info->getTime());
258 <      calcPot = 0;
257 >      statOut->writeStat(info->getTime());
258 >      calcPot = 0;
259        calcStress = 0;
260        currStatus += statusTime;
261 <    }
261 >    }
262  
263      if (info->resetIntegrator){
264        if (info->getTime() >= currReset){
# Line 234 | Line 266 | template<typename T> void Integrator<T>::integrate(voi
266          currReset += resetTime;
267        }
268      }
269 +    
270 + #ifdef PROFILE
271 +    endProfile( pro2 );
272 + #endif //profile
273  
274   #ifdef IS_MPI
275      strcpy(checkPointMsg, "successfully took a time step.");
# Line 241 | Line 277 | template<typename T> void Integrator<T>::integrate(voi
277   #endif // is_mpi
278    }
279  
280 <  dumpOut->writeFinal(info->getTime());
280 >  // dump out a file containing the omega values for the final configuration
281 >  if (info->useSolidThermInt && !info->useLiquidThermInt)
282 >    myFF->dumpzAngle();
283 >  
284  
285    delete dumpOut;
286    delete statOut;
# Line 250 | Line 289 | template<typename T> void Integrator<T>::integrateStep
289   template<typename T> void Integrator<T>::integrateStep(int calcPot,
290                                                         int calcStress){
291    // Position full step, and velocity half step
292 +
293 + #ifdef PROFILE
294 +  startProfile(pro3);
295 + #endif //profile
296 +
297    preMove();
298  
299 + #ifdef PROFILE
300 +  endProfile(pro3);
301 +
302 +  startProfile(pro4);
303 + #endif // profile
304 +
305    moveA();
306  
307 <  if (nConstrained){
308 <    constrainA();
309 <  }
307 > #ifdef PROFILE
308 >  endProfile(pro4);
309 >  
310 >  startProfile(pro5);
311 > #endif//profile
312  
313  
314   #ifdef IS_MPI
# Line 264 | Line 316 | template<typename T> void Integrator<T>::integrateStep
316    MPIcheckPoint();
317   #endif // is_mpi
318  
267
319    // calc forces
269
320    calcForce(calcPot, calcStress);
321  
322   #ifdef IS_MPI
# Line 274 | Line 324 | template<typename T> void Integrator<T>::integrateStep
324    MPIcheckPoint();
325   #endif // is_mpi
326  
327 + #ifdef PROFILE
328 +  endProfile( pro5 );
329  
330 +  startProfile( pro6 );
331 + #endif //profile
332 +
333    // finish the velocity  half step
334  
335    moveB();
336  
337 <  if (nConstrained){
338 <    constrainB();
339 <  }
337 > #ifdef PROFILE
338 >  endProfile(pro6);
339 > #endif // profile
340  
341   #ifdef IS_MPI
342    strcpy(checkPointMsg, "Succesful moveB\n");
# Line 291 | Line 346 | template<typename T> void Integrator<T>::moveA(void){
346  
347  
348   template<typename T> void Integrator<T>::moveA(void){
349 <  int i, j;
349 >  size_t i, j;
350    DirectionalAtom* dAtom;
351    double Tb[3], ji[3];
297  double A[3][3], I[3][3];
298  double angle;
352    double vel[3], pos[3], frc[3];
353    double mass;
354 +  double omega;
355 +
356 +  for (i = 0; i < integrableObjects.size() ; i++){
357 +    integrableObjects[i]->getVel(vel);
358 +    integrableObjects[i]->getPos(pos);
359 +    integrableObjects[i]->getFrc(frc);
360 +    
361 +    mass = integrableObjects[i]->getMass();
362  
302  for (i = 0; i < nAtoms; i++){
303    atoms[i]->getVel(vel);
304    atoms[i]->getPos(pos);
305    atoms[i]->getFrc(frc);
306
307    mass = atoms[i]->getMass();
308
363      for (j = 0; j < 3; j++){
364        // velocity half step
365        vel[j] += (dt2 * frc[j] / mass) * eConvert;
# Line 313 | Line 367 | template<typename T> void Integrator<T>::moveA(void){
367        pos[j] += dt * vel[j];
368      }
369  
370 <    atoms[i]->setVel(vel);
371 <    atoms[i]->setPos(pos);
370 >    integrableObjects[i]->setVel(vel);
371 >    integrableObjects[i]->setPos(pos);
372  
373 <    if (atoms[i]->isDirectional()){
320 <      dAtom = (DirectionalAtom *) atoms[i];
373 >    if (integrableObjects[i]->isDirectional()){
374  
375        // get and convert the torque to body frame
376  
377 <      dAtom->getTrq(Tb);
378 <      dAtom->lab2Body(Tb);
377 >      integrableObjects[i]->getTrq(Tb);
378 >      integrableObjects[i]->lab2Body(Tb);
379  
380        // get the angular momentum, and propagate a half step
381  
382 <      dAtom->getJ(ji);
382 >      integrableObjects[i]->getJ(ji);
383  
384        for (j = 0; j < 3; j++)
385          ji[j] += (dt2 * Tb[j]) * eConvert;
386  
387 <      // use the angular velocities to propagate the rotation matrix a
335 <      // full time step
387 >      this->rotationPropagation( integrableObjects[i], ji );
388  
389 <      dAtom->getA(A);
338 <      dAtom->getI(I);
339 <
340 <      // rotate about the x-axis      
341 <      angle = dt2 * ji[0] / I[0][0];
342 <      this->rotate(1, 2, angle, ji, A);
343 <
344 <      // rotate about the y-axis
345 <      angle = dt2 * ji[1] / I[1][1];
346 <      this->rotate(2, 0, angle, ji, A);
347 <
348 <      // rotate about the z-axis
349 <      angle = dt * ji[2] / I[2][2];
350 <      this->rotate(0, 1, angle, ji, A);
351 <
352 <      // rotate about the y-axis
353 <      angle = dt2 * ji[1] / I[1][1];
354 <      this->rotate(2, 0, angle, ji, A);
355 <
356 <      // rotate about the x-axis
357 <      angle = dt2 * ji[0] / I[0][0];
358 <      this->rotate(1, 2, angle, ji, A);
359 <
360 <      dAtom->setJ(ji);
361 <      dAtom->setA(A);
389 >      integrableObjects[i]->setJ(ji);
390      }
391    }
392 +
393 +  if (nConstrained){
394 +    constrainA();
395 +  }
396   }
397  
398  
399   template<typename T> void Integrator<T>::moveB(void){
400    int i, j;
369  DirectionalAtom* dAtom;
401    double Tb[3], ji[3];
402    double vel[3], frc[3];
403    double mass;
404  
405 <  for (i = 0; i < nAtoms; i++){
406 <    atoms[i]->getVel(vel);
407 <    atoms[i]->getFrc(frc);
405 >  for (i = 0; i < integrableObjects.size(); i++){
406 >    integrableObjects[i]->getVel(vel);
407 >    integrableObjects[i]->getFrc(frc);
408  
409 <    mass = atoms[i]->getMass();
409 >    mass = integrableObjects[i]->getMass();
410  
411      // velocity half step
412      for (j = 0; j < 3; j++)
413        vel[j] += (dt2 * frc[j] / mass) * eConvert;
414  
415 <    atoms[i]->setVel(vel);
415 >    integrableObjects[i]->setVel(vel);
416  
417 <    if (atoms[i]->isDirectional()){
387 <      dAtom = (DirectionalAtom *) atoms[i];
417 >    if (integrableObjects[i]->isDirectional()){
418  
419 <      // get and convert the torque to body frame      
419 >      // get and convert the torque to body frame
420  
421 <      dAtom->getTrq(Tb);
422 <      dAtom->lab2Body(Tb);
421 >      integrableObjects[i]->getTrq(Tb);
422 >      integrableObjects[i]->lab2Body(Tb);
423  
424        // get the angular momentum, and propagate a half step
425  
426 <      dAtom->getJ(ji);
426 >      integrableObjects[i]->getJ(ji);
427  
428        for (j = 0; j < 3; j++)
429          ji[j] += (dt2 * Tb[j]) * eConvert;
430  
431  
432 <      dAtom->setJ(ji);
432 >      integrableObjects[i]->setJ(ji);
433      }
434    }
435 +
436 +  if (nConstrained){
437 +    constrainB();
438 +  }
439   }
440  
441   template<typename T> void Integrator<T>::preMove(void){
# Line 420 | Line 454 | template<typename T> void Integrator<T>::constrainA(){
454   }
455  
456   template<typename T> void Integrator<T>::constrainA(){
457 <  int i, j, k;
457 >  int i, j;
458    int done;
459    double posA[3], posB[3];
460    double velA[3], velB[3];
# Line 560 | Line 594 | template<typename T> void Integrator<T>::constrainA(){
594      painCave.isFatal = 1;
595      simError();
596    }
597 +
598   }
599  
600   template<typename T> void Integrator<T>::constrainB(void){
601 <  int i, j, k;
601 >  int i, j;
602    int done;
603    double posA[3], posB[3];
604    double velA[3], velB[3];
# Line 572 | Line 607 | template<typename T> void Integrator<T>::constrainB(vo
607    int a, b, ax, ay, az, bx, by, bz;
608    double rma, rmb;
609    double dx, dy, dz;
610 <  double rabsq, pabsq, rvab;
576 <  double diffsq;
610 >  double rvab;
611    double gab;
612    int iteration;
613  
# Line 663 | Line 697 | template<typename T> void Integrator<T>::rotate(int ax
697    }
698   }
699  
700 + template<typename T> void Integrator<T>::rotationPropagation
701 + ( StuntDouble* sd, double ji[3] ){
702 +
703 +  double angle;
704 +  double A[3][3], I[3][3];
705 +  int i, j, k;
706 +
707 +  // use the angular velocities to propagate the rotation matrix a
708 +  // full time step
709 +
710 +  sd->getA(A);
711 +  sd->getI(I);
712 +
713 +  if (sd->isLinear()) {
714 +    i = sd->linearAxis();
715 +    j = (i+1)%3;
716 +    k = (i+2)%3;
717 +    
718 +    angle = dt2 * ji[j] / I[j][j];
719 +    this->rotate( k, i, angle, ji, A );
720 +
721 +    angle = dt * ji[k] / I[k][k];
722 +    this->rotate( i, j, angle, ji, A);
723 +
724 +    angle = dt2 * ji[j] / I[j][j];
725 +    this->rotate( k, i, angle, ji, A );
726 +
727 +  } else {
728 +    // rotate about the x-axis
729 +    angle = dt2 * ji[0] / I[0][0];
730 +    this->rotate( 1, 2, angle, ji, A );
731 +    
732 +    // rotate about the y-axis
733 +    angle = dt2 * ji[1] / I[1][1];
734 +    this->rotate( 2, 0, angle, ji, A );
735 +    
736 +    // rotate about the z-axis
737 +    angle = dt * ji[2] / I[2][2];
738 +    sd->addZangle(angle);
739 +    this->rotate( 0, 1, angle, ji, A);
740 +    
741 +    // rotate about the y-axis
742 +    angle = dt2 * ji[1] / I[1][1];
743 +    this->rotate( 2, 0, angle, ji, A );
744 +    
745 +    // rotate about the x-axis
746 +    angle = dt2 * ji[0] / I[0][0];
747 +    this->rotate( 1, 2, angle, ji, A );
748 +    
749 +  }
750 +  sd->setA( A  );
751 + }
752 +
753   template<typename T> void Integrator<T>::rotate(int axes1, int axes2,
754                                                  double angle, double ji[3],
755                                                  double A[3][3]){
# Line 728 | Line 815 | template<typename T> void Integrator<T>::rotate(int ax
815      }
816    }
817  
818 <  // rotate the Rotation matrix acording to:
818 >  // rotate the Rotation matrix acording to:
819    //            A[][] = A[][] * transpose(rot[][])
820  
821  
# Line 756 | Line 843 | template<typename T> double Integrator<T>::getConserve
843  
844   template<typename T> double Integrator<T>::getConservedQuantity(void){
845    return tStats->getTotalE();
846 < }
846 > }
847 > template<typename T> string Integrator<T>::getAdditionalParameters(void){
848 >  //By default, return a null string
849 >  //The reason we use string instead of char* is that if we use char*, we will
850 >  //return a pointer point to local variable which might cause problem
851 >  return string();
852 > }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines