ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/group/branches/new_design/OOPSE-3.0/src/constraints/ZconstraintForceManager.cpp
Revision: 1911
Committed: Mon Jan 10 18:05:45 2005 UTC (19 years, 8 months ago) by tim
File size: 18858 byte(s)
Log Message:
more work in zconstraint

File Contents

# User Rev Content
1 tim 1911 #include <cmath>
2     #include "constraints/ZconstraintForceManager.hpp"
3     #include "integrators/Integrator.hpp"
4     #include "utils/simError.h"
5     #include "utils/OOPSEConstant.hpp"
6    
7     namespace oopse {
8     ZconstraintForceManager::ZconstraintForceManager(SimInfo* info): ForceManager(info) {
9     currSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
10     Globals* simParam = info_->getSimParams();
11    
12     if (simParam->haveDt()){
13     dt_ = simParam->getDt();
14     } else {
15     sprintf(painCave.errMsg,
16     "Integrator Error: dt is not set\n");
17     painCave.isFatal = 1;
18     simError();
19     }
20    
21     if (simParam->haveZconstraintTime()){
22     zconsTime_ = simParam->getZconsTime();
23     }
24     else{
25     sprintf(painCave.errMsg,
26     "ZConstraint error: If you use a ZConstraint,\n"
27     "\tyou must set zconsTime.\n");
28     painCave.isFatal = 1;
29     simError();
30     }
31    
32     if (simParam->haveZconsTol()){
33     zconsTol_ = simParam->getZconsTol();
34     }
35     else{
36     zconsTol_ = 0.01;
37     sprintf(painCave.errMsg,
38     "ZConstraint Warning: Tolerance for z-constraint method is not specified.\n"
39     "\tOOPSE will use a default value of %f.\n"
40     "\tTo set the tolerance, use the zconsTol variable.\n",
41     zconsTol_);
42     painCave.isFatal = 0;
43     simError();
44     }
45    
46     //set zcons gap
47     if (simParam->haveZConsGap()){
48     zconsGap_ = simParam->getZconsGap();
49     }else {
50     zconsGap_ = false;
51     }
52    
53     //set zcons fixtime
54     if (simParam->haveZConsFixTime()){
55     zconsFixingTime_ = simParam->getZconsFixtime();
56     } else {
57     zconsFixingTime_ = infiniteTime;
58     }
59    
60     //set zconsUsingSMD
61     if (simParam->haveZConsUsingSMD()){
62     usingSMD_ = simParam->getZconsUsingSMD();
63     }else {
64     usingSMD_ =false;
65     }
66    
67     std::string zconsOutput = getPrefix(info_->getFinalConfigFileName()) + ".fz";
68    
69     //estimate the force constant of harmonical potential
70     Mat3x3d hmat = currSnapshot_->getHmat();
71     double halfOfLargestBox = std::max(hmat(0, 0), std::max(hmat(1, 1), hmat(2, 2))) /2;
72     double targetTemp;
73     if (simParam->haveTargetTemp()) {
74     targetTemp = simParam->getTargetTemp();
75     } else {
76     targetTemp = 298.0;
77     }
78     double zforceConstant = OOPSEConstant::kb * targetTemp / (halfOfLargestBox * halfOfLargestBox);
79    
80     int nZconstraints = simParam->getNzConstraints();
81     ZconStamp** stamp = simParam->getZconStamp();
82     //
83     for (int i = 0; i < nZconstraints; i++){
84    
85     ZconstraintParam param;
86     int zmolIndex = stamp[i]->getMolIndex();
87     if (stamp[i]->haveZpos()) {
88     param.zTargetPos = getZTargetPos(zmolIndex);
89     } else {
90     param.zTargetPos = stamp[i]->getZpos();
91     }
92    
93     param.kz = zforceConstant * stamp[i]->getKratio();
94    
95     if (stamp[i]->haveCantVel()) {
96     param.cantVel = stamp[i]->getCantVel();
97     } else {
98     param.cantVel = 0.0;
99     }
100    
101     allZMolIndices_.insert(std::make_pair(zmolIndex, param));
102     }
103    
104     //create fixedMols_, movingMols_ and unconsMols lists
105     update();
106    
107     //calculate masss of unconstraint molecules in the whole system (never change during the simulation)
108     double totMassUnconsMols_local = 0.0;
109     std::vector<Molecule*>::iterator j;
110     for ( j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
111     totMassUnconsMols_local += (*j)->getMass();
112     }
113     #ifndef IS_MPI
114     totMassUnconsMols_ = totMassUnconsMols_local;
115     #else
116     MPI_Allreduce(&totMassUnconsMols_local, &totMassUnconsMols_, 1, MPI_DOUBLE,
117     MPI_SUM, MPI_COMM_WORLD);
118     #endif
119    
120     // creat zconsWriter
121     fzOut = new ZConsWriter(zconsOutput.c_str(), parameters);
122    
123     if (!fzOut){
124     sprintf(painCave.errMsg, "Memory allocation failure in class Zconstraint\n");
125     painCave.isFatal = 1;
126     simError();
127     }
128    
129     }
130    
131     ZconstraintForceManager::~ZConstraint(){
132    
133     if (fzOut){
134     delete fzOut;
135     }
136    
137     }
138    
139     void ZconstraintForceManager::update(){
140     fixedZMols_.clear();
141     movingZMols_.clear();
142     unzconsMols_.clear();
143    
144     std::map<int, ZconstraintParam>::iterator i;
145     for (i = allZMolIndices_.begin(); i != allZMolIndices_.end(); ++i) {
146     #ifdef IS_MPI
147     if (info_->getMolToProc(i->first) == worldRank) {
148     #endif
149     ZconstraintMol zmol;
150     zmol->mol = info_->getMoleculeByGlobalIndex(i->first);
151     assert(zmol->mol);
152     zmol->param = info_->getMoleculeByGlobalIndex(i->second);
153     zmol->cantPos = zmol->param->zTargetPos; /**@todo fixed me when zmol migrate, it is incorrect*/
154     Vector3d com = zmol->mol->getCom();
155     double diff = fabs(zmol->param->zTargetPos - com[whichDirection]);
156     if (diff < zconsTol_) {
157     fixedZMols_.push_back(zmol);
158     } else {
159     movingZMols_.push_back(zmol);
160     }
161    
162     #ifdef IS_MPI
163     }
164     #endif
165     }
166    
167     calcTotalMassMovingZMols();
168    
169     std::set<int> zmolSet;
170     std::list<ZconstraintMol>::iterator i;
171     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
172     zmolSet.insert(i->mol->getGlobalIndex());
173     }
174    
175     for ( i = fixedZMols_.begin(); i != movingZMols_.end(); ++i) {
176     zmolSet.insert(i->mol->getGlobalIndex());
177     }
178    
179     SimInfo::MoleculeIterator mi;
180     Molecule* mol;
181     for(mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
182     if (zmolSet->find(mol->getGlobalIndex()) == zmolSet.end()) {
183     unzconsMols_.push_back(zmolSet);
184     }
185     }
186    
187     }
188    
189     bool ZconstraintForceManager::isZMol(Molecule* mol){
190     return allZMolIndices.find(mol->getGlobalIndex()) == allZMolIndices_.end() ? false : true;
191     }
192    
193     void ZconstraintForceManager::integrate(){
194    
195    
196     //zero out the velocities of center of mass of unconstrained molecules
197     //and the velocities of center of mass of every single z-constrained molecueles
198     zeroVelocity();
199    
200     curZconsTime = zconsTime + info->getTime();
201    
202     T::integrate();
203     }
204    
205     void ZconstraintForceManager::calcForce(bool needPotential, bool needStress){
206     ForceManager::calcForce(needPotential, needStress);
207    
208     if (usingZconsGap_){
209     updateZPos();
210     }
211    
212     if (checkZConsState()){
213     zeroVelocity();
214     forcePolicy->update();
215     }
216    
217     //do zconstraint force;
218     if (haveFixedZMols()){
219     doZconstraintForce();
220     }
221    
222     //use external force to move the molecules to the specified positions
223     if (haveMovingZMols()){
224     doHarmonic();
225     }
226    
227     //write out forces and current positions of z-constraint molecules
228     if (currSnapshot_->getTime() >= curZconsTime_){
229     std::list<ZconstraintMol>::iterator i;
230     Vector3d com;
231     for(i = fixedZMols_.begin(); i != fixedZMols_.end() ++i) {
232     com = i->mol->getCom();
233     i->zpos = com[whichDirection];
234     }
235    
236     fzOut->writeFZ(fixedZMols_);
237     curZconsTime_ += zconsTime_;
238     }
239     }
240    
241     void ZconstraintForceManager::zeroVelocity(){
242    
243     Vector3d comVel;
244     Vector3d vel;
245     std::list<ZconstraintMol>::iterator i;
246     Molecule* mol;
247     StuntDouble* integrableObject;
248     Molecule::IntegrableObjectIteraot ii;
249    
250     //zero out the velocities of center of mass of fixed z-constrained molecules
251     for(i = fixedZMols_.begin(); i != fixedZMols_.end() ++i) {
252     mol = i->mol;
253     comVel = mol->getComVel();
254     for(integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
255     integrableObject = mol->nextIntegrableObject(ii)) {
256     vel[whichDirection] -= comVel[whichDirection];
257     integrableObject->setVel(vel);
258     }
259     }
260    
261     // calculate the vz of center of mass of moving molecules(include unconstrained molecules
262     // and moving z-constrained molecules)
263     double pzMovingMols_local;
264     double pzMovingMols;
265    
266     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
267     mol = i->mol;
268     comVel = mol->getComVel();
269     pzMovingMols_local += mol->getMass() * comVel[whichDirection];
270     }
271    
272     std::vector<Molecule*>::iterator j;
273     for ( j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
274     mol =*j;
275     comVel = mol->getCoMVel();
276     pzMovingMols_local += mol->getMass() * comVel[whichDirection];
277     }
278    
279     #ifndef IS_MPI
280     pzMovingMols = pzMovingMols_local;
281     #else
282     MPI_Allreduce(&pzMovingMols_local, &pzMovingMols, 1, MPI_DOUBLE,
283     MPI_SUM, MPI_COMM_WORLD);
284     #endif
285    
286     double vzMovingMols = pzMovingMols / totMassMovingMols_;
287    
288     //modify the velocities of moving z-constrained molecuels
289     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
290     mol = i->mol;
291     for(integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
292     integrableObject = mol->nextIntegrableObject(ii)) {
293    
294     vel = integrableObject->getVel();
295     vel[whichDirection] -= vzOfMovingMols;
296     integrableObject->setVel(vel);
297     }
298     }
299    
300     //modify the velocites of unconstrained molecules
301     for ( j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
302     mol =*j;
303     for(integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
304     integrableObject = mol->nextIntegrableObject(ii)) {
305    
306     vel = integrableObject->getVel();
307     vel[whichDirection] -= vzOfMovingMols;
308     integrableObject->setVel(vel);
309     }
310     }
311    
312     }
313    
314    
315     void ZconstraintForceManager::doZconstraintForce(){
316     Atom** zconsAtoms;
317     double totalFZ;
318     double totalFZ_local;
319     Vector3d com;
320     Vector3d force(0.0);
321    
322     //constrain the molecules which do not reach the specified positions
323    
324     //Zero Out the force of z-contrained molecules
325     totalFZ_local = 0;
326    
327    
328     //calculate the total z-contrained force of fixed z-contrained molecules
329     std::list<ZconstraintMol>::iterator i;
330     Molecule* mol;
331     StuntDouble* integrableObject;
332     Molecule::IntegrableObjectIteraot ii;
333    
334     for ( i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
335     mol = i->mol;
336     com = mol->getCom();
337    
338     i->fz = 0.0;
339    
340     totalFZ_local += harmonicF;
341    
342     //adjust force
343     for(integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
344     integrableObject = mol->nextIntegrableObject(ii)) {
345    
346     force = integrableObject->getFrc();
347     i->fz += force[whichDirection]
348     }
349     totalFZ_local += i->fz;
350     }
351    
352     //calculate total z-constraint force
353     #ifdef IS_MPI
354     MPI_Allreduce(&totalFZ_local, &totalFZ, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
355     #else
356     totalFZ = totalFZ_local;
357     #endif
358    
359    
360     // apply negative to fixed z-constrained molecues;
361     for ( i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
362     mol = i->mol;
363     for(integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
364     integrableObject = mol->nextIntegrableObject(ii)) {
365    
366     force[whichDirection] = -getZFOfFixedZMols(mol, integrableObject, i->fz);
367     integrableObject->addFrc(force);
368     }
369     }
370    
371     //modify the forces of moving z-constrained molecules
372     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
373     mol = i->mol;
374     for(integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
375     integrableObject = mol->nextIntegrableObject(ii)) {
376    
377     force[whichDirection] = -getZFOfMovingMols(mol, integrableObject, totalFZ);
378     integrableObject->addFrc(force);
379     }
380     }
381    
382     //modify the forces of unconstrained molecules
383     std::vector<Molecule*>::iterator j;
384     for ( j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
385     mol =*j;
386     for(integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
387     integrableObject = mol->nextIntegrableObject(ii)) {
388    
389     force[whichDirection] = -getZFOfMovingMols(mol, integrableObject, totalFZ);
390     integrableObject->addFrc(force);
391     }
392     }
393    
394     }
395    
396    
397     void ZconstraintForceManager::doHarmonic(){
398     double harmonicU;
399     double harmonicF;
400     double diff;
401     double totalFZ_local;
402     double totalFZ;
403    
404     Vector3d force(0.0);
405     Vector3d com;
406    
407     double totalFZ_local = 0;
408    
409     std::list<ZconstraintMol>::iterator i;
410     Molecule* mol;
411     StuntDouble* integrableObject;
412     Molecule::IntegrableObjectIteraot ii;
413    
414     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
415     mol = i->mol;
416     com = mol->getCom();
417     diff = com[whichDirection] - resPos;
418     harmonicU = 0.5 * kz * diff * diff;
419     currSnapshot->statData[Stats::LONG_RANGE_POTENTIAL] += harmonicU;
420     harmonicF = -kz * diff;
421     totalFZ_local += harmonicF;
422    
423     //adjust force
424     for(integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
425     integrableObject = mol->nextIntegrableObject(ii)) {
426    
427     force[whichDirection] = getHFOfFixedZMols(mol, integrableObject, harmonicF);
428     integrableObject->addFrc(force);
429     }
430     }
431    
432     #ifndef IS_MPI
433     totalFZ = totalFZ_local;
434     #else
435     MPI_Allreduce(&totalFZ_local, &totalFZ, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
436     #endif
437    
438     //modify the forces of unconstrained molecules
439     std::vector<Molecule*>::iterator j;
440     for ( j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
441     mol = *j;
442     for(integrableObject = mol->beginIntegrableObject(ii); integrableObject != NULL;
443     integrableObject = mol->nextIntegrableObject(ii)) {
444    
445     force[whichDirection] = getHFOfUnconsMols(mol, harmonicF);
446     integrableObject->addFrc(force);
447     }
448     }
449    
450     }
451    
452     bool ZconstraintForceManager::checkZConsState(){
453     Vector3d com;
454     double diff;
455     int changed_local = 0;
456    
457     std::list<ZconstraintMol>::iterator i;
458     std::list<ZconstraintMol>::iterator j;
459    
460     std::list<ZconstraintMol> newMovingZMols;
461     for ( i = fixedZMols_.begin(); i != fixedZMols_.end();) {
462     com = i->mol->getCom();
463     diff = fabs(com[whichDirection] - i->param.zTargetPos);
464     if (diff > zconsTol_) {
465     //this fixed zconstraint molecule is about to moving
466     //moved this molecule to
467     j = i++;
468     newMovingZMols.push_back(fixedZMols_.erase(j));
469     if (usingZconsGap_) {
470     i->endFixingTime = infiniteTime;
471     }
472     changed_local = 1;
473     }else {
474     ++i;
475     }
476     }
477    
478     std::list<ZconstraintMol> newFixedZMols;
479     for ( i = movingZMols_.begin(); i != movingZMols_.end();) {
480     com = i->mol->getCom();
481     diff = fabs(com[whichDirection] - i->param.zTargetPos);
482     if (diff <= zconsTol_) {
483     //this moving zconstraint molecule is about to fixed
484     //moved this molecule to
485     j = i++;
486     newFixedZMols.push_back(movingZMols_.erase(j));
487     if (usingZconsGap_) {
488     i->endFixingTime = currSnapshot_->getTime() + zconsFixingTime_;
489     }
490     changed_local = 1;
491     }else {
492     ++i;
493     }
494     }
495    
496     //merge the lists
497     fixedZMols_.merge(newFixedZMols);
498     movingZMols_.merge(newFixedZMols);
499    
500     int changed;
501     #ifndef IS_MPI
502     changed = changed_local;
503     #else
504     MPI_Allreduce(&changed_local, &changed, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
505     #endif
506    
507     return (changed > 0);
508     }
509    
510     bool ZconstraintForceManager::haveFixedZMols(){
511     int havingFixed;
512     int havingFixed_local = fixedZMols_.empty() ? 0 : 1;
513    
514     #ifndef IS_MPI
515     havingFixed = havingFixed_local;
516     #else
517     MPI_Allreduce(&havingFixed_local, &havingFixed, 1, MPI_INT, MPI_SUM,
518     MPI_COMM_WORLD);
519     #endif
520    
521     return havingFixed > 0;
522     }
523    
524    
525     bool ZconstraintForceManager::haveMovingZMols(){
526     int havingMoving_local;
527     int havingMoving;
528    
529     havingMoving_local = movingZMols_.empty()? 0 : 1;
530    
531     #ifndef IS_MPI
532     havingMoving = havingMoving_local;
533     #else
534     MPI_Allreduce(&havingMoving_local, &havingMoving, 1, MPI_INT, MPI_SUM,
535     MPI_COMM_WORLD);
536     #endif
537    
538     return havingMoving > 0;
539     }
540    
541     void ZconstraintForceManager::calcTotalMassMovingZMols(){
542    
543     double totMassMovingZMols_local = 0.0;
544     std::list<ZconstraintMol>::iterator i;
545     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
546     totMassMovingZMols_local += i->mol->getMass();
547     }
548    
549     #ifdef IS_MPI
550     MPI_Allreduce(&totMassMovingZMols_local, &totMassMovingZMols_, 1, MPI_DOUBLE,
551     MPI_SUM, MPI_COMM_WORLD);
552     #else
553     totMassMovingZMols_ = massOfMovingZAtoms_local;
554     #endif
555    
556     }
557    
558     double ZconstraintForceManager::getZFOfFixedZMols(Molecule* mol, StuntDouble* sd, double totalForce){
559     return totalForce * sd->getMass() / mol->getMass();
560     }
561    
562     double ZconstraintForceManager::getZFOfMovingMols(StuntDouble*sd, double totalForce){
563     return totalForce * sd->getMass() / (totMassUnconsMols_ + totMassMovingZMols_);
564     }
565    
566     double ZconstraintForceManager::getHFOfFixedZMols(Molecule* mol, StuntDouble*sd, double totalForce){
567     return totalForce * sd->getMass() / mol->getMass();
568     }
569    
570     double ZconstraintForceManager::getHFOfUnconsMols(StuntDouble*sd, double totalForce){
571     return totalForce * sd->getMass() / totMassUnconsMols_;
572     }
573    
574     void ZconstraintForceManager::updateZPos(){
575     double curTime = currSnapshot_->getTime();
576     std::list<ZconstraintMol>::iterator i;
577     for ( i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
578     i->param.zTargetPos += zconsGap_;
579     }
580     }
581    
582     void ZconstraintForceManager::updateCantPos(){
583     std::list<ZconstraintMol>::iterator i;
584     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
585     i->cantPos += i->param.cantVel * dt_;
586     }
587     }
588    
589     double ZconstraintForceManager::getZTargetPos(int index){
590     double zTargetPos;
591     #ifndef IS_MPI
592     Molecule* mol = info_->getMoleculeByGlobalIndex(index);
593     assert(!mol);
594     Vector3d com = mol->getCom();
595     zTargetPos = com[whichDirection];
596     #else
597     int whicProc = info_->getMolToProc(index);
598     MPI_Bcast(&zTargetPos, 1, MPI_DOUBLE, whicProc, MPI_COMM_WORLD);
599     #endif
600     return zTargetPos;
601     }
602    
603     }

Properties

Name Value
svn:executable *