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: 1910
Committed: Fri Jan 7 21:50:13 2005 UTC (19 years, 8 months ago) by tim
File size: 18107 byte(s)
Log Message:
ZConstraintForceManager in progress

File Contents

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

Properties

Name Value
svn:executable *