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

Comparing trunk/OOPSE/libmdtools/ZConstraint.cpp (file contents):
Revision 661 by tim, Fri Aug 1 16:18:13 2003 UTC vs.
Revision 693 by tim, Wed Aug 13 19:21:53 2003 UTC

# Line 1 | Line 1
1   #include "Integrator.hpp"
2   #include "simError.h"
3 <
3 > #include <cmath>
4   template<typename T> ZConstraint<T>::ZConstraint(SimInfo* theInfo, ForceFields* the_ff)
5 <                                    : T(theInfo, the_ff), fz(NULL), indexOfZConsMols(NULL)
5 >                                    : T(theInfo, the_ff), fz(NULL),
6 >                                      indexOfZConsMols(NULL)
7   {
8  
9    //get properties from SimInfo
10    GenericData* data;
11 <  IndexData* index;
11 >  ZConsParaData* zConsParaData;
12    DoubleData* sampleTime;
13 +  DoubleData* tolerance;
14    StringData* filename;
15 <  
14 <  
15 <  data = info->getProperty("zconsindex");
16 <  if(!data) {
15 >  double COM[3];
16  
17 <    sprintf( painCave.errMsg,
18 <               "ZConstraint error: If you use an ZConstraint\n"
19 <               " , you must set index of z-constraint molecules.\n");
20 <    painCave.isFatal = 1;
21 <    simError();  
23 <  }
24 <  else{
25 <    index = dynamic_cast<IndexData*>(data);
26 <    
27 <    if(!index){
17 >  //by default, the direction of constraint is z
18 >  // 0 --> x
19 >  // 1 --> y
20 >  // 2 --> z
21 >  whichDirection = 2;
22  
23 <      sprintf( painCave.errMsg,
24 <                 "ZConstraint error: Can not get property from SimInfo\n");
25 <      painCave.isFatal = 1;
26 <      simError();  
27 <    
34 <    }
35 <    else{
36 <          
37 <      indexOfAllZConsMols = index->getIndexData();
38 <      
39 <      //the maximum value of index is the last one(we sorted the index data in SimSetup.cpp)
40 <      int maxIndex;
41 <      int totalNumMol;
42 <      
43 <      maxIndex = indexOfAllZConsMols[indexOfAllZConsMols.size() - 1];
23 >  //estimate the force constant of harmonical potential
24 >  double Kb = 1.986E-3 ; //in kcal/K
25 >  
26 >  double halfOfLargestBox = max(info->boxL[0], max(info->boxL[1], info->boxL[2])) /2;
27 >  zForceConst = Kb * info->target_temp /(halfOfLargestBox * halfOfLargestBox);
28  
29 < #ifndef IS_MPI
30 <      totalNumMol = nMols;
47 < #else
48 <      totalNumMol = mpiSim->getTotNmol();  
49 < #endif      
50 <      
51 <      if(maxIndex > totalNumMol - 1){
52 <        sprintf( painCave.errMsg,
53 <               "ZConstraint error: index is out of range\n");
54 <        painCave.isFatal = 1;
55 <        simError();
56 <                
57 <      }
58 <      
59 <    }
60 <        
61 <  }
29 >  //retrieve sample time of z-contraint
30 >  data = info->getProperty(ZCONSTIME_ID);
31    
63  //retrive sample time of z-contraint
64  data = info->getProperty("zconstime");
65  
32    if(!data) {
33        
34      sprintf( painCave.errMsg,
# Line 89 | Line 55 | template<typename T> ZConstraint<T>::ZConstraint(SimIn
55  
56    }
57    
58 <  
59 <  //retrive output filename of z force
94 <  data = info->getProperty("zconsfilename");
58 >  //retrieve output filename of z force
59 >  data = info->getProperty(ZCONSFILENAME_ID);
60    if(!data) {
61  
62        
# Line 121 | Line 86 | template<typename T> ZConstraint<T>::ZConstraint(SimIn
86  
87    }
88  
89 <
90 <  //calculate reference z coordinate for z-constraint molecules
126 <  double totalMass_local;
127 <  double totalMass;
128 <  double totalMZ_local;
129 <  double totalMZ;
130 <  double massOfUncons_local;
131 <  double massOfCurMol;
132 <  double COM[3];
89 >  //retrieve tolerance for z-constraint molecuels
90 >  data = info->getProperty(ZCONSTOL_ID);
91    
92 <  totalMass_local = 0;
93 <  totalMass = 0;
94 <  totalMZ_local = 0;
95 <  totalMZ = 0;
96 <  massOfUncons_local = 0;
97 <    
140 <  
141 <  for(int i = 0; i < nMols; i++){
142 <    massOfCurMol = molecules[i].getTotalMass();
143 <    molecules[i].getCOM(COM);
144 <    
145 <    totalMass_local += massOfCurMol;
146 <    totalMZ_local += massOfCurMol * COM[2];
147 <    
148 <    if(isZConstraintMol(&molecules[i]) == -1){
149 <    
150 <      massOfUncons_local += massOfCurMol;
151 <    }  
152 <    
92 >  if(!data) {
93 >      
94 >    sprintf( painCave.errMsg,
95 >               "ZConstraint error: can not get tolerance \n");
96 >    painCave.isFatal = 1;
97 >    simError();      
98    }
99 +  else{
100    
101 <  
102 < #ifdef IS_MPI  
103 <  MPI_Allreduce(&totalMass_local, &totalMass, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
158 <  MPI_Allreduce(&totalMZ_local, &totalMZ, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);  
159 <  MPI_Allreduce(&massOfUncons_local, &totalMassOfUncons, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
160 < #else
161 <  totalMass = totalMass_local;
162 <  totalMZ = totalMZ_local;
163 <  totalMassOfUncons = massOfUncons_local;
164 < #endif  
101 >    tolerance = dynamic_cast<DoubleData*>(data);
102 >    
103 >    if(!tolerance){
104  
105 <  double zsys;
106 <  zsys = totalMZ / totalMass;
107 <
108 < #ifndef IS_MPI  
109 <  for(int i = 0; i < nMols; i++){
171 <    
172 <    if(isZConstraintMol(&molecules[i]) > -1 ){
173 <      molecules[i].getCOM(COM);
174 <      allRefZ.push_back(COM[2] - zsys);  
105 >      sprintf( painCave.errMsg,
106 >                 "ZConstraint error: Can not get property from SimInfo\n");
107 >      painCave.isFatal = 1;
108 >      simError();  
109 >      
110      }
111 <    
111 >    else{
112 >      this->zconsTol = tolerance->getData();
113 >    }
114 >
115    }
116 < #else
117 <
118 <  int whichNode;
119 <  enum CommType { RequestMolZPos, EndOfRequest} status;
120 <  //int status;
121 <  double zpos;
122 <  int localIndex;
123 <  MPI_Status ierr;
124 <  int tag = 0;
125 <  
188 <  if(worldRank == 0){
189 <    
190 <    int globalIndexOfCurMol;
191 <    int *MolToProcMap;
192 <    MolToProcMap = mpiSim->getMolToProcMap();
193 <    
194 <    for(int i = 0; i < indexOfAllZConsMols.size(); i++){
195 <      
196 <      whichNode = MolToProcMap[indexOfAllZConsMols[i]];
197 <      globalIndexOfCurMol = indexOfAllZConsMols[i];
198 <      
199 <      if(whichNode == 0){
200 <        
201 <        for(int j = 0; j < nMols; j++)
202 <          if(molecules[j].getGlobalIndex() == globalIndexOfCurMol){
203 <            localIndex = j;
204 <            break;
205 <          }
206 <                  
207 <        molecules[localIndex].getCOM(COM);
208 <        allRefZ.push_back(COM[2] - zsys);  
209 <              
210 <      }
211 <      else{
212 <        status = RequestMolZPos;
213 <        MPI_Send(&status, 1, MPI_INT, whichNode, tag, MPI_COMM_WORLD);
214 <        MPI_Send(&globalIndexOfCurMol, 1, MPI_INT, whichNode, tag, MPI_COMM_WORLD);
215 <        MPI_Recv(&zpos, 1, MPI_DOUBLE_PRECISION, whichNode, tag, MPI_COMM_WORLD, &ierr);
216 <        
217 <        allRefZ.push_back(zpos - zsys);
218 <      
219 <      }
220 <              
221 <    } //End of Request Loop
222 <    
223 <    //Send ending request message to slave nodes    
224 <    status = EndOfRequest;
225 <    for(int i =1; i < mpiSim->getNumberProcessors(); i++)
226 <      MPI_Send(&status, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
227 <    
116 >        
117 >  //retrieve index of z-constraint molecules
118 >  data = info->getProperty(ZCONSPARADATA_ID);
119 >  if(!data) {
120 >
121 >    sprintf( painCave.errMsg,
122 >               "ZConstraint error: If you use an ZConstraint\n"
123 >               " , you must set index of z-constraint molecules.\n");
124 >    painCave.isFatal = 1;
125 >    simError();  
126    }
127    else{
128    
129 <    int whichMol;
232 <    bool done = false;
233 <
234 <    while (!done){  
235 <      
236 <      MPI_Recv(&status, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &ierr);
129 >    zConsParaData = dynamic_cast<ZConsParaData*>(data);
130      
131 <      switch (status){
239 <          
240 <        case RequestMolZPos :
241 <          
242 <          MPI_Recv(&whichMol, 1, MPI_INT, 0, tag, MPI_COMM_WORLD,&ierr);
243 <          
244 <          for(int i = 0; i < nMols; i++)
245 <            if(molecules[i].getGlobalIndex() == whichMol){
246 <              localIndex = i;
247 <              break;
248 <            }
249 <          
250 <          molecules[localIndex].getCOM(COM);
251 <          zpos = COM[2];          
252 <          MPI_Send(&zpos, 1, MPI_DOUBLE_PRECISION, 0, tag, MPI_COMM_WORLD);      
253 <          
254 <          break;
255 <            
256 <        case EndOfRequest :
257 <        
258 <         done = true;
259 <         break;
260 <      }
261 <      
262 <    }
263 <          
264 <  }
131 >    if(!zConsParaData){
132  
133 <  //Brocast the allRefZ to slave nodes;
134 <  double* allRefZBuf;
135 <  int nZConsMols;
136 <  nZConsMols = indexOfAllZConsMols.size();
270 <  
271 <  allRefZBuf = new double[nZConsMols];
272 <  
273 <  if(worldRank == 0){
274 <
275 <    for(int i = 0; i < nZConsMols; i++)
276 <      allRefZBuf[i] = allRefZ[i];
277 <  }    
278 <  
279 <    MPI_Bcast(allRefZBuf, nZConsMols, MPI_DOUBLE_PRECISION, 0, MPI_COMM_WORLD);
280 <  
281 <  if(worldRank != 0){
133 >      sprintf( painCave.errMsg,
134 >                 "ZConstraint error: Can not get parameters of zconstraint method from SimInfo\n");
135 >      painCave.isFatal = 1;
136 >      simError();  
137      
138 <    for(int i = 0; i < nZConsMols; i++)
139 <      allRefZ.push_back(allRefZBuf[i]);  
140 <  }
141 <  
142 <  delete[] allRefZBuf;
138 >    }
139 >    else{
140 >      
141 >      parameters = zConsParaData->getData();
142 >
143 >      //check the range of zconsIndex
144 >      //and the minimum value of index is the first one (we already sorted the data)
145 >      //the maximum value of index is the last one
146 >
147 >      int maxIndex;
148 >      int minIndex;
149 >      int totalNumMol;
150 >
151 >      minIndex = (*parameters)[0].zconsIndex;
152 >      if(minIndex < 0){
153 >        sprintf( painCave.errMsg,
154 >               "ZConstraint error: index is out of range\n");
155 >        painCave.isFatal = 1;
156 >        simError();
157 >        }
158 >
159 >      maxIndex = (*parameters)[parameters->size() - 1].zconsIndex;
160 >
161 > #ifndef IS_MPI
162 >      totalNumMol = nMols;
163 > #else
164 >      totalNumMol = mpiSim->getTotNmol();  
165 > #endif      
166 >      
167 >      if(maxIndex > totalNumMol - 1){
168 >        sprintf( painCave.errMsg,
169 >               "ZConstraint error: index is out of range\n");
170 >        painCave.isFatal = 1;
171 >        simError();                  
172 >      }
173 >
174 >      //if user does not specify the zpos for the zconstraint molecule
175 >      //its initial z coordinate  will be used as default
176 >      for(int i = 0; i < parameters->size(); i++){
177 >
178 >              if(!(*parameters)[i].havingZPos){
179 >
180 > #ifndef IS_MPI
181 >            for(int j = 0; j < nMols; j++){
182 >              if (molecules[j].getGlobalIndex() == (*parameters)[i].zconsIndex){
183 >                 molecules[j].getCOM(COM);
184 >                          break;
185 >              }
186 >            }
187 > #else
188 >            //query which processor current zconstraint molecule belongs to
189 >           int *MolToProcMap;
190 >           int whichNode;
191 >                         double initZPos;
192 >           MolToProcMap = mpiSim->getMolToProcMap();
193 >           whichNode = MolToProcMap[(*parameters)[i].zconsIndex];
194 >                          
195 >           //broadcast the zpos of current z-contraint molecule
196 >           //the node which contain this
197 >          
198 >           if (worldRank == whichNode ){
199 >                                                
200 >             for(int j = 0; j < nMols; j++)
201 >               if (molecules[j].getGlobalIndex() == (*parameters)[i].zconsIndex){
202 >                 molecules[j].getCOM(COM);
203 >                                         break;
204 >               }
205 >                                
206 >           }
207 >
208 >            MPI_Bcast(&COM[whichDirection], 1, MPI_DOUBLE_PRECISION, whichNode, MPI_COMM_WORLD);                          
209   #endif
210 +            
211 +                 (*parameters)[i].zPos = COM[whichDirection];
212  
213 <  
213 >            sprintf( painCave.errMsg,
214 >                     "ZConstraint warningr: Does not specify zpos for z-constraint molecule "
215 >                     "initial z coornidate will be used \n");
216 >            painCave.isFatal = 0;
217 >            simError();  
218 >          
219 >              }
220 >            }
221 >                        
222 >    }//end if (!zConsParaData)
223 >  }//end  if (!data)
224 >            
225 > //  
226   #ifdef IS_MPI
227    update();
228   #else  
229    int searchResult;
230 <  
296 <  refZ = allRefZ;
297 <
230 >      
231    for(int i = 0; i < nMols; i++){
232      
233      searchResult = isZConstraintMol(&molecules[i]);
# Line 303 | Line 236 | template<typename T> ZConstraint<T>::ZConstraint(SimIn
236      
237        zconsMols.push_back(&molecules[i]);      
238        massOfZConsMols.push_back(molecules[i].getTotalMass());  
239 <      
239 >
240 >      zPos.push_back((*parameters)[searchResult].zPos);
241 >           kz.push_back((*parameters)[searchResult]. kRatio * zForceConst);
242 >      
243        molecules[i].getCOM(COM);
244      }
245      else
# Line 325 | Line 261 | template<typename T> ZConstraint<T>::ZConstraint(SimIn
261      simError();
262    }
263  
264 <  for(int i = 0; i < zconsMols.size(); i++)
264 >  //determine the states of z-constraint molecules
265 >  for(int i = 0; i < zconsMols.size(); i++){
266      indexOfZConsMols[i] = zconsMols[i]->getGlobalIndex();
267 +
268 +         zconsMols[i]->getCOM(COM);
269 +    if (fabs(zPos[i] - COM[whichDirection]) < zconsTol)
270 +                states.push_back(zcsFixed);
271 +         else
272 +                states.push_back(zcsMoving);
273 +  }
274    
275   #endif
276 +
277 +  //get total masss of unconstraint molecules
278 +  double totalMassOfUncons_local;
279 +  totalMassOfUncons_local = 0;
280    
281 +  for(int i = 0; i < unconsMols.size(); i++)
282 +    totalMassOfUncons_local += unconsMols[i]->getTotalMass();
283 +    
284 + #ifndef IS_MPI
285 +  totalMassOfUncons = totalMassOfUncons_local;
286 + #else
287 +  MPI_Allreduce(&totalMassOfUncons_local, &totalMassOfUncons, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);  
288 + #endif
289 +
290 +
291 +  //get total number of unconstrained atoms
292 +  int nUnconsAtoms_local;
293 +  nUnconsAtoms_local = 0;
294 +  for(int i = 0; i < unconsMols.size(); i++)
295 +    nUnconsAtoms_local += unconsMols[i]->getNAtoms();
296 +    
297 + #ifndef IS_MPI
298 +  totNumOfUnconsAtoms = nUnconsAtoms_local;
299 + #else
300 +  MPI_Allreduce(&nUnconsAtoms_local, &totNumOfUnconsAtoms, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);  
301 + #endif  
302 +
303 +  // creat zconsWriter  
304    fzOut = new ZConsWriter(zconsOutput.c_str());  
305    
306    if(!fzOut){
# Line 339 | Line 310 | template<typename T> ZConstraint<T>::ZConstraint(SimIn
310      simError();
311    }
312    
342  fzOut->writeRefZ(indexOfAllZConsMols, allRefZ);
313   }
314  
315   template<typename T> ZConstraint<T>::~ZConstraint()
# Line 362 | Line 332 | template<typename T> void ZConstraint<T>::update()
332    
333    zconsMols.clear();
334    massOfZConsMols.clear();
335 <  refZ.clear();
335 >  zPos.clear();
336 >  kz.clear();
337    
338    unconsMols.clear();
339    massOfUnconsMols.clear();
# Line 376 | Line 347 | template<typename T> void ZConstraint<T>::update()
347      if(index > -1){
348      
349        zconsMols.push_back(&molecules[i]);      
350 +      zPos.push_back((*parameters)[index].zPos);
351 +        kz.push_back((*parameters)[index].kRatio * zForceConst);
352 +                        
353        massOfZConsMols.push_back(molecules[i].getTotalMass());  
354        
355        molecules[i].getCOM(COM);
382      refZ.push_back(allRefZ[index]);      
356      }
357      else
358      {
# Line 389 | Line 362 | template<typename T> void ZConstraint<T>::update()
362  
363      }
364    }
365 +
366 +  //determine the states of z-constraint molecules
367 +  for(int i = 0; i < zconsMols.size(); i++){
368 +           zconsMols[i]->getCOM(COM);
369 +      if (fabs(zPos[i] - COM[whichDirection]) < zconsTol)
370 +                  states.push_back(zcsFixed);
371 +           else
372 +                  states.push_back(zcsMoving);
373 +  }
374 +
375      
376    //The reason to declare fz and indexOfZconsMols as pointer to array is
377    // that we want to make the MPI communication simple
# Line 441 | Line 424 | template<typename T> int ZConstraint<T>::isZConstraint
424    index = mol->getGlobalIndex();
425    
426    low = 0;
427 <  high = indexOfAllZConsMols.size() - 1;
427 >  high = parameters->size() - 1;
428    
429    //Binary Search (we have sorted the array)  
430    while(low <= high){
431      mid = (low + high) /2;
432 <    if (indexOfAllZConsMols[mid] == index)
432 >    if ((*parameters)[mid].zconsIndex == index)
433        return mid;
434 <    else if (indexOfAllZConsMols[mid] > index )
434 >    else if ((*parameters)[mid].zconsIndex > index )
435         high = mid -1;
436      else    
437        low = mid + 1;
# Line 457 | Line 440 | template<typename T> int ZConstraint<T>::isZConstraint
440    return -1;
441   }
442  
443 < /** Function Name: integrateStep
461 < ** Parameter:
462 < **   int calcPot;
463 < **   int calcStress;
464 < ** Description:
465 < **  Advance One Step.
466 < ** Memo:
467 < **   The best way to implement z-constraint is to override integrateStep
468 < **   Overriding constrainB is not a good choice, since in integrateStep,
469 < **   constrainB is invoked by below line,
470 < **                  if(nConstrained) constrainB();
471 < **   For instance, we would like to apply z-constraint without bond contrain,
472 < **   In that case, if we override constrainB, Z-constrain method will never be executed;
473 < */
474 < template<typename T> void ZConstraint<T>::integrateStep( int calcPot, int calcStress )
475 < {
476 <  T::integrateStep( calcPot, calcStress );
477 <  resetZ();
443 > template<typename T> void ZConstraint<T>::integrate(){
444    
445 <  double currZConsTime = 0;
446 <  
447 <  //write out forces of z constraint
448 <  if( info->getTime() >= currZConsTime){  
449 <      fzOut->writeFZ(info->getTime(), zconsMols.size(),indexOfZConsMols, fz);
450 <  }    
445 >  //zero out the velocities of center of mass of unconstrained molecules
446 >  //and the velocities of center of mass of every single z-constrained molecueles
447 >  zeroOutVel();
448 >  
449 >  T::integrate();
450 >
451   }
452 +
453  
454 < /** Function Name: resetZ
455 < ** Description:
456 < **  Reset the z coordinates
454 > /**
455 > *
456 > *
457 > *
458 > *
459   */
460  
461 < template<typename T> void ZConstraint<T>::resetZ()
461 >
462 > template<typename T> void ZConstraint<T>::calcForce(int calcPot, int calcStress){
463 >  double zsys;
464 >
465 >  T::calcForce(calcPot, calcStress);
466 >
467 >  if (checkZConsState())
468 >  zeroOutVel();
469 >  
470 >  zsys = calcZSys();
471 >  cout << "---------------------------------------------------------------------" <<endl;
472 >  cout << "current time: " << info->getTime() <<"\tcenter of mass at z: " << zsys << endl;      
473 >  cout << "before calcForce, the COMVel of unconstraint molecules is " << calcCOMVel() <<endl;
474 >        
475 >
476 >  //do zconstraint force;
477 >  if (haveFixedZMols())
478 >    this->doZconstraintForce();
479 >
480 >
481 >      
482 >  //use harmonical poteintial to move the molecules to the specified positions
483 >  if (haveMovingZMols())
484 >    this->doHarmonic();
485 >  
486 >  fzOut->writeFZ(info->getTime(), zconsMols.size(),indexOfZConsMols, fz);
487 >  cout << "after calcForce, the COMVel of unconstraint molecules is " << calcCOMVel() <<endl;
488 > }
489 >
490 > template<typename T> double ZConstraint<T>::calcZSys()
491   {
492 <  double deltaZ;
493 <  double mzOfZCons;   //total sum of m*z of z-constrain molecules
494 <  double mzOfUncons; //total sum of m*z of unconstrain molecuels;
495 <  double totalMZOfZCons;
496 <  double totalMZOfUncons;
492 >  //calculate reference z coordinate for z-constraint molecules
493 >  double totalMass_local;
494 >  double totalMass;
495 >  double totalMZ_local;
496 >  double totalMZ;
497 >  double massOfUncons_local;
498 >  double massOfCurMol;
499    double COM[3];
500 +  
501 +  totalMass_local = 0;
502 +  totalMass = 0;
503 +  totalMZ_local = 0;
504 +  totalMZ = 0;
505 +  massOfUncons_local = 0;
506 +    
507 +  
508 +  for(int i = 0; i < nMols; i++){
509 +    massOfCurMol = molecules[i].getTotalMass();
510 +    molecules[i].getCOM(COM);
511 +    
512 +    totalMass_local += massOfCurMol;
513 +    totalMZ_local += massOfCurMol * COM[whichDirection];
514 +    
515 +    if(isZConstraintMol(&molecules[i]) == -1){
516 +    
517 +      massOfUncons_local += massOfCurMol;
518 +    }  
519 +    
520 +  }
521 +  
522 +  
523 + #ifdef IS_MPI  
524 +  MPI_Allreduce(&totalMass_local, &totalMass, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
525 +  MPI_Allreduce(&totalMZ_local, &totalMZ, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);  
526 +  MPI_Allreduce(&massOfUncons_local, &totalMassOfUncons, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
527 + #else
528 +  totalMass = totalMass_local;
529 +  totalMZ = totalMZ_local;
530 +  totalMassOfUncons = massOfUncons_local;
531 + #endif  
532 +
533    double zsys;
534 <  Atom** zconsAtoms;
534 >  zsys = totalMZ / totalMass;
535  
536 <  mzOfZCons = 0;
537 <  mzOfUncons  = 0;
536 >  return zsys;
537 > }
538 >
539 > /**
540 > *
541 > */
542 > template<typename T> void ZConstraint<T>::thermalize( void ){
543 >
544 >  T::thermalize();
545 >  zeroOutVel();
546 > }
547 >
548 > /**
549 > *
550 > *
551 > *
552 > */
553 >
554 > template<typename T> void ZConstraint<T>::zeroOutVel(){
555 >
556 >  Atom** fixedZAtoms;  
557 >  double COMvel[3];
558 >  double vel[3];
559 >
560 >  double tempMass = 0;
561 >  double tempMVz =0;
562 >  double tempVz = 0;
563 >  for(int i = 0; i < nMols; i++){
564 >    molecules[i].getCOMvel(COMvel);
565 >    tempMass +=molecules[i].getTotalMass();  
566 >         tempMVz += molecules[i].getTotalMass() * COMvel[whichDirection];
567 >         tempVz += COMvel[whichDirection];
568 >  }
569 >  cout << "initial velocity of center of mass is " << tempMVz / tempMass << endl;
570 >
571 >  //zero out the velocities of center of mass of fixed z-constrained molecules
572    
573    for(int i = 0; i < zconsMols.size(); i++){
574 <    mzOfZCons += massOfZConsMols[i] * refZ[i];    
574 >
575 >    if (states[i] == zcsFixed){
576 >
577 >           zconsMols[i]->getCOMvel(COMvel);      
578 >                cout << "before resetting " << indexOfZConsMols[i] <<"'s vz is " << COMvel[whichDirection] << endl;
579 >
580 >      fixedZAtoms = zconsMols[i]->getMyAtoms();
581 >          
582 >      for(int j =0; j < zconsMols[i]->getNAtoms(); j++){
583 >        fixedZAtoms[j]->getVel(vel);
584 >             vel[whichDirection] -= COMvel[whichDirection];
585 >             fixedZAtoms[j]->setVel(vel);
586 >      }
587 >
588 >                zconsMols[i]->getCOMvel(COMvel);
589 >                cout << "after resetting " << indexOfZConsMols[i] <<"'s vz is " << COMvel[whichDirection] << endl;
590 >    }
591 >        
592    }
593  
594 < #ifdef IS_MPI
595 <  MPI_Allreduce(&mzOfZCons, &totalMZOfZCons, 1,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
594 >        cout << "before resetting the COMVel of unconstraint molecules is " << calcCOMVel() <<endl;    
595 >                  
596 >  // calculate the vz of center of mass of unconstrained molecules and moving z-constrained molecules
597 >  double MVzOfMovingMols_local;
598 >  double MVzOfMovingMols;
599 >  double totalMassOfMovingZMols_local;
600 >  double totalMassOfMovingZMols;
601 >      
602 >  MVzOfMovingMols_local = 0;
603 >  totalMassOfMovingZMols_local = 0;
604 >
605 >  for(int i =0; i < unconsMols.size(); i++){
606 >    unconsMols[i]->getCOMvel(COMvel);
607 >    MVzOfMovingMols_local += massOfUnconsMols[i] * COMvel[whichDirection];      
608 >  }
609 >
610 >  for(int i = 0; i < zconsMols.size(); i++){
611 >    if (states[i] == zcsMoving){
612 >      zconsMols[i]->getCOMvel(COMvel);
613 >      MVzOfMovingMols_local += massOfZConsMols[i] * COMvel[whichDirection];  
614 >      totalMassOfMovingZMols_local += massOfZConsMols[i];              
615 >    }
616 >                
617 >  }
618 >
619 > #ifndef IS_MPI
620 >  MVzOfMovingMols = MVzOfMovingMols_local;
621 >  totalMassOfMovingZMols = totalMassOfMovingZMols_local;
622   #else
623 <  totalMZOfZCons = mzOfZCons;
623 >  MPI_Allreduce(&MVzOfMovingMols_local, &MVzOfMovingMols, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
624 >  MPI_Allreduce(&totalMassOfMovingZMols_local, &totalMassOfMovingZMols, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);  
625   #endif
626  
627 +  double vzOfMovingMols;
628 +  vzOfMovingMols = MVzOfMovingMols / (totalMassOfUncons + totalMassOfMovingZMols);
629 +
630 +  //modify the velocites of unconstrained molecules  
631 +  Atom** unconsAtoms;
632    for(int i = 0; i < unconsMols.size(); i++){
517    unconsMols[i]->getCOM(COM);
518    mzOfUncons += massOfUnconsMols[i] * COM[2];
519  }
633    
634 < #ifdef IS_MPI
635 <  MPI_Allreduce(&mzOfUncons, &totalMZOfUncons, 1,MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
636 < #else
637 <  totalMZOfUncons = mzOfUncons;
638 < #endif  
634 >    unconsAtoms = unconsMols[i]->getMyAtoms();
635 >    for(int j = 0; j < unconsMols[i]->getNAtoms();j++){
636 >      unconsAtoms[j]->getVel(vel);
637 >      vel[whichDirection] -= vzOfMovingMols;
638 >      unconsAtoms[j]->setVel(vel);
639 >    }
640    
641 <  zsys = (totalMZOfZCons + totalMZOfUncons) /totalMassOfUncons;
642 <
643 <  for(int i = 0; i < zconsMols.size(); i++){  
641 >  }  
642 >
643 >  //modify the velocities of moving z-constrained molecuels
644 >  Atom** movingZAtoms;
645 >  for(int i = 0; i < zconsMols.size(); i++){
646 >
647 >    if (states[i] ==zcsMoving){
648    
649 <    zconsMols[i]->getCOM(COM);
649 >      movingZAtoms = zconsMols[i]->getMyAtoms();
650 >           for(int j = 0; j < zconsMols[i]->getNAtoms(); j++){
651 >        movingZAtoms[j]->getVel(vel);
652 >        vel[whichDirection] -= vzOfMovingMols;
653 >             movingZAtoms[j]->setVel(vel);
654 >          }
655 >          
656 >   }
657 >
658 > }
659 >
660 >        cout << "after resetting the COMVel of unconstraint molecules is " << calcCOMVel() <<endl;
661 >
662 > }
663 >
664 > template<typename T> void ZConstraint<T>::doZconstraintForce(){
665 >
666 >  Atom** zconsAtoms;
667 >  double totalFZ;
668 >  double totalFZ_local;
669 >  double COMvel[3];  
670 >  double COM[3];
671 >  double force[3];
672 >
673 >  int nMovingZMols_local;
674 >  int nMovingZMols;
675 >
676 >  //constrain the molecules which do not reach the specified positions  
677      
678 <    deltaZ = zsys + refZ[i] - COM[2];
679 <    //update z coordinate    
680 <    zconsAtoms = zconsMols[i]->getMyAtoms();    
681 <    for(int j =0; j < zconsMols[i]->getNAtoms(); j++){
682 <      zconsAtoms[j]->setZ(zconsAtoms[j]->getZ() + deltaZ);  
683 <    }    
678 >  //Zero Out the force of z-contrained molecules    
679 >  totalFZ_local = 0;
680 >
681 >  //calculate the total z-contrained force of fixed z-contrained molecules
682 >  cout << "Fixed Molecules" << endl;
683 >  for(int i = 0; i < zconsMols.size(); i++){
684 >                
685 >    if (states[i] == zcsFixed){
686 >                
687 >      zconsMols[i]->getCOM(COM);
688 >      zconsAtoms = zconsMols[i]->getMyAtoms();  
689 >
690 >      fz[i] = 0;      
691 >      for(int j =0; j < zconsMols[i]->getNAtoms(); j++) {
692 >        zconsAtoms[j]->getFrc(force);
693 >        fz[i] += force[whichDirection];      
694 >      }
695 >      totalFZ_local += fz[i];
696 >
697 >      cout << "index: " << indexOfZConsMols[i] <<"\tcurrent zpos: " << COM[whichDirection] << endl;
698 >
699 >    }
700 >          
701 >  }
702 >
703 >  //calculate the number of atoms of moving z-constrained molecules
704 >  nMovingZMols_local = 0;
705 >  for(int i = 0; i < zconsMols.size(); i++)
706 >    if(states[i] == zcsMoving)
707 >           nMovingZMols_local += massOfZConsMols[i];
708 >  
709 > #ifdef IS_MPI
710 >  MPI_Allreduce(&totalFZ_local, &totalFZ, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
711 >  MPI_Allreduce(&nMovingZMols_local, &nMovingZMols, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
712 > #else
713 >  totalFZ = totalFZ_local;
714 >  nMovingZMols = nMovingZMols_local;
715 > #endif
716 >
717 >  force[0]= 0;
718 >  force[1]= 0;
719 >  force[2]= 0;
720 >  force[whichDirection] = totalFZ / (totNumOfUnconsAtoms + nMovingZMols);
721 >
722 >  //modify the forces of unconstrained molecules
723 >  for(int i = 0; i < unconsMols.size(); i++){
724 >    
725 >     Atom** unconsAtoms = unconsMols[i]->getMyAtoms();
726 >    
727 >     for(int j = 0; j < unconsMols[i]->getNAtoms(); j++)          
728 >       unconsAtoms[j]->addFrc(force);
729 >    
730 >  }      
731 >
732 > //modify the forces of moving z-constrained molecules
733 >  for(int i = 0; i < zconsMols.size(); i++) {
734 >   if (states[i] == zcsMoving){
735 >                
736 >     Atom** movingZAtoms = zconsMols[i]->getMyAtoms();    
737 >
738 >     for(int j = 0; j < zconsMols[i]->getNAtoms(); j++)          
739 >       movingZAtoms[j]->addFrc(force);
740 >     }
741 >  }
742 >
743 >  // apply negative to fixed z-constrained molecues;
744 >  force[0]= 0;
745 >  force[1]= 0;
746 >  force[2]= 0;
747 >
748 >  for(int i = 0; i < zconsMols.size(); i++){
749 >
750 >    if (states[i] == zcsFixed){  
751 >        
752 >      int nAtomOfCurZConsMol = zconsMols[i]->getNAtoms();
753 >      zconsAtoms = zconsMols[i]->getMyAtoms();  
754      
755 <    //calculate z constrain force
756 <    fz[i] = massOfZConsMols[i]* deltaZ / dt2;
757 <    
755 >      for(int j =0; j < nAtomOfCurZConsMol; j++) {
756 >        force[whichDirection] = -fz[i]/ nAtomOfCurZConsMol;
757 >        zconsAtoms[j]->addFrc(force);
758 >      }
759 >                
760 >    }
761 >        
762 >  }
763 >
764 > }
765 >
766 > template<typename T> bool ZConstraint<T>::checkZConsState(){
767 >  double COM[3];
768 >  double diff;
769 >  
770 >  bool changed;
771 >  
772 >  changed = false;
773 >  
774 >  for(int i =0; i < zconsMols.size(); i++){
775 >
776 >    zconsMols[i]->getCOM(COM);
777 >    diff = fabs(COM[whichDirection] - zPos[i]);  
778 >    if (  diff <= zconsTol && states[i] == zcsMoving){
779 >      states[i] = zcsFixed;
780 >        changed = true;
781 >    }
782 >    else if ( diff > zconsTol && states[i] == zcsFixed){
783 >      states[i] = zcsMoving;
784 >        changed = true;  
785 >    }
786 >  
787    }
788  
789 +  return changed;
790 + }
791 +
792 + template<typename T> bool ZConstraint<T>::haveFixedZMols(){
793 +  for(int i = 0; i < zconsMols.size(); i++)
794 +    if (states[i] == zcsFixed)
795 +      return true;
796 +
797 +  return false;
798 + }
799 +
800 +
801 + /**
802 + *
803 + */
804 + template<typename T> bool ZConstraint<T>::haveMovingZMols(){
805 +  for(int i = 0; i < zconsMols.size(); i++)
806 +    if (states[i] == zcsMoving)
807 +      return true;
808 +
809 +  return false;
810 +  
811 + }
812 +
813 + /**
814 +  *
815 +  *
816 +  */
817 +
818 + template<typename T> void ZConstraint<T>::doHarmonic(){
819 +  double force[3];
820 +  double harmonicU;
821 +  double harmonicF;
822 +  double COM[3];
823 +  double diff;
824 +  double totalFZ;
825 +        
826 +  force[0] = 0;
827 +  force[1] = 0;
828 +  force[2] = 0;
829 +
830 +  totalFZ = 0;
831 +
832 +  cout << "Moving Molecules" << endl;  
833 +  for(int i = 0; i < zconsMols.size(); i++) {
834 +
835 +    if (states[i] == zcsMoving){
836 +      zconsMols[i]->getCOM(COM);
837 +      cout << "index: " << indexOfZConsMols[i] <<"\tcurrent zpos: " << COM[whichDirection] << endl;
838 +                
839 +                diff = COM[whichDirection] -zPos[i];
840 +                
841 +      harmonicU = 0.5 * kz[i] * diff * diff;  
842 +                info->lrPot += harmonicU;
843 +
844 +      harmonicF =  - kz[i] * diff / zconsMols[i]->getNAtoms();
845 +                force[whichDirection] = harmonicF;
846 +      totalFZ += harmonicF;
847 +                
848 +      Atom** movingZAtoms = zconsMols[i]->getMyAtoms();    
849 +
850 +       for(int j = 0; j < zconsMols[i]->getNAtoms(); j++)          
851 +         movingZAtoms[j]->addFrc(force);
852 +    }
853 +
854 +  }
855 +
856 +  force[0]= 0;
857 +  force[1]= 0;
858 +  force[2]= 0;
859 +  force[whichDirection] = -totalFZ /totNumOfUnconsAtoms;
860 +
861 +  //modify the forces of unconstrained molecules
862 +  for(int i = 0; i < unconsMols.size(); i++){
863 +    
864 +     Atom** unconsAtoms = unconsMols[i]->getMyAtoms();
865 +    
866 +     for(int j = 0; j < unconsMols[i]->getNAtoms(); j++)          
867 +       unconsAtoms[j]->addFrc(force);    
868 +  }  
869 +
870 + }
871 +
872 + template<typename T> double ZConstraint<T>::calcCOMVel()
873 + {
874 +  double MVzOfMovingMols_local;
875 +  double MVzOfMovingMols;
876 +  double totalMassOfMovingZMols_local;
877 +  double totalMassOfMovingZMols;
878 +  double COMvel[3];
879        
880 +  MVzOfMovingMols_local = 0;
881 +  totalMassOfMovingZMols_local = 0;
882 +
883 +  for(int i =0; i < unconsMols.size(); i++){
884 +    unconsMols[i]->getCOMvel(COMvel);
885 +    MVzOfMovingMols_local += massOfUnconsMols[i] * COMvel[whichDirection];      
886 +  }
887 +
888 +  for(int i = 0; i < zconsMols.size(); i++){
889 +
890 +    if (states[i] == zcsMoving){
891 +      zconsMols[i]->getCOMvel(COMvel);
892 +      MVzOfMovingMols_local += massOfZConsMols[i] * COMvel[whichDirection];  
893 +      totalMassOfMovingZMols_local += massOfZConsMols[i];              
894 +    }
895 +                
896 +  }
897 +
898 + #ifndef IS_MPI
899 +  MVzOfMovingMols = MVzOfMovingMols_local;
900 +  totalMassOfMovingZMols = totalMassOfMovingZMols_local;
901 + #else
902 +  MPI_Allreduce(&MVzOfMovingMols_local, &MVzOfMovingMols, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);
903 +  MPI_Allreduce(&totalMassOfMovingZMols_local, &totalMassOfMovingZMols, 1, MPI_DOUBLE,MPI_SUM, MPI_COMM_WORLD);  
904 + #endif
905 +
906 +  double vzOfMovingMols;
907 +  vzOfMovingMols = MVzOfMovingMols / (totalMassOfUncons + totalMassOfMovingZMols);
908 +
909 +  return vzOfMovingMols;
910   }
911 +
912 +
913 + template<typename T> double ZConstraint<T>::calcCOMVel2()
914 + {
915 +  double COMvel[3];
916 +  double tempMVz = 0;
917 +  int index;
918 +                
919 +  for(int i =0 ; i < nMols; i++){
920 +         index = isZConstraintMol(&molecules[i]);
921 +    if( index == -1){
922 +       molecules[i].getCOMvel(COMvel);
923 +            tempMVz += molecules[i].getTotalMass()*COMvel[whichDirection];
924 +    }
925 +         else if(states[i] == zcsMoving){
926 +       zconsMols[index]->getCOMvel(COMvel);
927 +            tempMVz += massOfZConsMols[index]*COMvel[whichDirection];    
928 +         }
929 +  }
930 +        
931 +  return tempMVz /totalMassOfUncons;
932 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines