ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/constraints/ZconstraintForceManager.cpp
Revision: 1782
Committed: Wed Aug 22 02:28:28 2012 UTC (12 years, 8 months ago) by gezelter
File size: 19130 byte(s)
Log Message:
MERGE OpenMD development branch 1465:1781 into trunk

File Contents

# User Rev Content
1 gezelter 507 /*
2 gezelter 246 * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3     *
4     * The University of Notre Dame grants you ("Licensee") a
5     * non-exclusive, royalty free, license to use, modify and
6     * redistribute this software in source and binary code form, provided
7     * that the following conditions are met:
8     *
9 gezelter 1390 * 1. Redistributions of source code must retain the above copyright
10 gezelter 246 * notice, this list of conditions and the following disclaimer.
11     *
12 gezelter 1390 * 2. Redistributions in binary form must reproduce the above copyright
13 gezelter 246 * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the
15     * distribution.
16     *
17     * This software is provided "AS IS," without a warranty of any
18     * kind. All express or implied conditions, representations and
19     * warranties, including any implied warranty of merchantability,
20     * fitness for a particular purpose or non-infringement, are hereby
21     * excluded. The University of Notre Dame and its licensors shall not
22     * be liable for any damages suffered by licensee as a result of
23     * using, modifying or distributing the software or its
24     * derivatives. In no event will the University of Notre Dame or its
25     * licensors be liable for any lost revenue, profit or data, or for
26     * direct, indirect, special, consequential, incidental or punitive
27     * damages, however caused and regardless of the theory of liability,
28     * arising out of the use of or inability to use software, even if the
29     * University of Notre Dame has been advised of the possibility of
30     * such damages.
31 gezelter 1390 *
32     * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33     * research, please cite the appropriate papers when you publish your
34     * work. Good starting points are:
35     *
36     * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37     * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38     * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 24107 (2008).
39 gezelter 1782 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40     * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 gezelter 246 */
42    
43     #include <cmath>
44     #include "constraints/ZconstraintForceManager.hpp"
45     #include "integrators/Integrator.hpp"
46     #include "utils/simError.h"
47 gezelter 1390 #include "utils/PhysicalConstants.hpp"
48 gezelter 246 #include "utils/StringUtils.hpp"
49 gezelter 1782 #ifdef IS_MPI
50     #include <mpi.h>
51     #endif
52    
53 gezelter 1390 namespace OpenMD {
54 gezelter 507 ZconstraintForceManager::ZconstraintForceManager(SimInfo* info): ForceManager(info), infiniteTime(1e31) {
55 gezelter 246 currSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
56     Globals* simParam = info_->getSimParams();
57    
58     if (simParam->haveDt()){
59 gezelter 507 dt_ = simParam->getDt();
60 gezelter 246 } else {
61 gezelter 507 sprintf(painCave.errMsg,
62     "Integrator Error: dt is not set\n");
63     painCave.isFatal = 1;
64     simError();
65 gezelter 246 }
66    
67 tim 665 if (simParam->haveZconsTime()){
68 gezelter 507 zconsTime_ = simParam->getZconsTime();
69 gezelter 246 }
70     else{
71 gezelter 507 sprintf(painCave.errMsg,
72     "ZConstraint error: If you use a ZConstraint,\n"
73     "\tyou must set zconsTime.\n");
74     painCave.isFatal = 1;
75     simError();
76 gezelter 246 }
77    
78     if (simParam->haveZconsTol()){
79 gezelter 507 zconsTol_ = simParam->getZconsTol();
80 gezelter 246 }
81     else{
82 gezelter 507 zconsTol_ = 0.01;
83     sprintf(painCave.errMsg,
84     "ZConstraint Warning: Tolerance for z-constraint method is not specified.\n"
85 gezelter 1390 "\tOpenMD will use a default value of %f.\n"
86 gezelter 507 "\tTo set the tolerance, use the zconsTol variable.\n",
87     zconsTol_);
88     painCave.isFatal = 0;
89     simError();
90 gezelter 246 }
91    
92     //set zcons gap
93 tim 665 if (simParam->haveZconsGap()){
94 gezelter 507 usingZconsGap_ = true;
95     zconsGap_ = simParam->getZconsGap();
96 gezelter 246 }else {
97 gezelter 507 usingZconsGap_ = false;
98     zconsGap_ = 0.0;
99 gezelter 246 }
100    
101     //set zcons fixtime
102 tim 665 if (simParam->haveZconsFixtime()){
103 gezelter 507 zconsFixingTime_ = simParam->getZconsFixtime();
104 gezelter 246 } else {
105 gezelter 507 zconsFixingTime_ = infiniteTime;
106 gezelter 246 }
107    
108     //set zconsUsingSMD
109 tim 665 if (simParam->haveZconsUsingSMD()){
110 gezelter 507 usingSMD_ = simParam->getZconsUsingSMD();
111 gezelter 246 }else {
112 gezelter 507 usingSMD_ =false;
113 gezelter 246 }
114    
115     zconsOutput_ = getPrefix(info_->getFinalConfigFileName()) + ".fz";
116    
117     //estimate the force constant of harmonical potential
118     Mat3x3d hmat = currSnapshot_->getHmat();
119 tim 963 RealType halfOfLargestBox = std::max(hmat(0, 0), std::max(hmat(1, 1), hmat(2, 2))) /2;
120     RealType targetTemp;
121 gezelter 246 if (simParam->haveTargetTemp()) {
122 gezelter 507 targetTemp = simParam->getTargetTemp();
123 gezelter 246 } else {
124 gezelter 507 targetTemp = 298.0;
125 gezelter 246 }
126 gezelter 1390 RealType zforceConstant = PhysicalConstants::kb * targetTemp / (halfOfLargestBox * halfOfLargestBox);
127 gezelter 246
128 tim 770 int nZconstraints = simParam->getNZconsStamps();
129     std::vector<ZConsStamp*> stamp = simParam->getZconsStamps();
130 gezelter 246 //
131     for (int i = 0; i < nZconstraints; i++){
132    
133 gezelter 507 ZconstraintParam param;
134     int zmolIndex = stamp[i]->getMolIndex();
135     if (stamp[i]->haveZpos()) {
136     param.zTargetPos = stamp[i]->getZpos();
137     } else {
138     param.zTargetPos = getZTargetPos(zmolIndex);
139     }
140 gezelter 246
141 gezelter 507 param.kz = zforceConstant * stamp[i]->getKratio();
142 gezelter 246
143 gezelter 507 if (stamp[i]->haveCantVel()) {
144     param.cantVel = stamp[i]->getCantVel();
145     } else {
146     param.cantVel = 0.0;
147     }
148 gezelter 246
149 gezelter 507 allZMolIndices_.insert(std::make_pair(zmolIndex, param));
150 gezelter 246 }
151    
152     //create fixedMols_, movingMols_ and unconsMols lists
153     update();
154    
155     //calculate masss of unconstraint molecules in the whole system (never change during the simulation)
156 tim 963 RealType totMassUnconsMols_local = 0.0;
157 gezelter 246 std::vector<Molecule*>::iterator j;
158     for ( j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
159 gezelter 507 totMassUnconsMols_local += (*j)->getMass();
160 gezelter 246 }
161     #ifndef IS_MPI
162     totMassUnconsMols_ = totMassUnconsMols_local;
163     #else
164 tim 963 MPI_Allreduce(&totMassUnconsMols_local, &totMassUnconsMols_, 1, MPI_REALTYPE,
165 gezelter 507 MPI_SUM, MPI_COMM_WORLD);
166 gezelter 246 #endif
167    
168     // creat zconsWriter
169     fzOut = new ZConsWriter(info_, zconsOutput_.c_str());
170    
171     if (!fzOut){
172     sprintf(painCave.errMsg, "Fail to create ZConsWriter\n");
173     painCave.isFatal = 1;
174     simError();
175     }
176    
177 gezelter 507 }
178 gezelter 246
179 gezelter 507 ZconstraintForceManager::~ZconstraintForceManager(){
180 gezelter 246
181 gezelter 507 if (fzOut){
182     delete fzOut;
183     }
184    
185 gezelter 246 }
186    
187 gezelter 507 void ZconstraintForceManager::update(){
188 gezelter 246 fixedZMols_.clear();
189     movingZMols_.clear();
190     unzconsMols_.clear();
191    
192     for (std::map<int, ZconstraintParam>::iterator i = allZMolIndices_.begin(); i != allZMolIndices_.end(); ++i) {
193     #ifdef IS_MPI
194 gezelter 507 if (info_->getMolToProc(i->first) == worldRank) {
195 gezelter 246 #endif
196 gezelter 507 ZconstraintMol zmol;
197     zmol.mol = info_->getMoleculeByGlobalIndex(i->first);
198     assert(zmol.mol);
199     zmol.param = i->second;
200     zmol.cantPos = zmol.param.zTargetPos; /**@todo fixed me when zmol migrate, it is incorrect*/
201     Vector3d com = zmol.mol->getCom();
202 tim 963 RealType diff = fabs(zmol.param.zTargetPos - com[whichDirection]);
203 gezelter 507 if (diff < zconsTol_) {
204     fixedZMols_.push_back(zmol);
205     } else {
206     movingZMols_.push_back(zmol);
207     }
208 gezelter 246
209     #ifdef IS_MPI
210 gezelter 507 }
211 gezelter 246 #endif
212     }
213    
214     calcTotalMassMovingZMols();
215    
216     std::set<int> zmolSet;
217     for (std::list<ZconstraintMol>::iterator i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
218 gezelter 507 zmolSet.insert(i->mol->getGlobalIndex());
219 gezelter 246 }
220    
221     for (std::list<ZconstraintMol>::iterator i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
222 gezelter 507 zmolSet.insert(i->mol->getGlobalIndex());
223 gezelter 246 }
224    
225     SimInfo::MoleculeIterator mi;
226     Molecule* mol;
227     for(mol = info_->beginMolecule(mi); mol != NULL; mol = info_->nextMolecule(mi)) {
228 gezelter 507 if (zmolSet.find(mol->getGlobalIndex()) == zmolSet.end()) {
229     unzconsMols_.push_back(mol);
230     }
231 gezelter 246 }
232    
233 gezelter 507 }
234 gezelter 246
235 gezelter 507 bool ZconstraintForceManager::isZMol(Molecule* mol){
236 gezelter 246 return allZMolIndices_.find(mol->getGlobalIndex()) == allZMolIndices_.end() ? false : true;
237 gezelter 507 }
238 gezelter 246
239 gezelter 507 void ZconstraintForceManager::init(){
240 gezelter 246
241 gezelter 507 //zero out the velocities of center of mass of unconstrained molecules
242     //and the velocities of center of mass of every single z-constrained molecueles
243     zeroVelocity();
244 gezelter 246
245 gezelter 507 currZconsTime_ = currSnapshot_->getTime();
246     }
247 gezelter 246
248 gezelter 1464 void ZconstraintForceManager::calcForces(){
249     ForceManager::calcForces();
250 gezelter 246
251     if (usingZconsGap_){
252 gezelter 507 updateZPos();
253 gezelter 246 }
254    
255     if (checkZConsState()){
256 gezelter 507 zeroVelocity();
257     calcTotalMassMovingZMols();
258 gezelter 246 }
259    
260     //do zconstraint force;
261     if (haveFixedZMols()){
262 gezelter 507 doZconstraintForce();
263 gezelter 246 }
264    
265     //use external force to move the molecules to the specified positions
266     if (haveMovingZMols()){
267 gezelter 507 doHarmonic();
268 gezelter 246 }
269    
270     //write out forces and current positions of z-constraint molecules
271     if (currSnapshot_->getTime() >= currZconsTime_){
272 gezelter 507 std::list<ZconstraintMol>::iterator i;
273     Vector3d com;
274     for(i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
275     com = i->mol->getCom();
276     i->zpos = com[whichDirection];
277     }
278 gezelter 246
279 gezelter 507 fzOut->writeFZ(fixedZMols_);
280     currZconsTime_ += zconsTime_;
281 gezelter 246 }
282 gezelter 507 }
283 gezelter 246
284 gezelter 507 void ZconstraintForceManager::zeroVelocity(){
285 gezelter 246
286     Vector3d comVel;
287     Vector3d vel;
288     std::list<ZconstraintMol>::iterator i;
289     Molecule* mol;
290 gezelter 1782 StuntDouble* sd;
291 gezelter 246 Molecule::IntegrableObjectIterator ii;
292    
293     //zero out the velocities of center of mass of fixed z-constrained molecules
294     for(i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
295 gezelter 1782
296 gezelter 507 mol = i->mol;
297     comVel = mol->getComVel();
298 gezelter 1782
299     for(sd = mol->beginIntegrableObject(ii); sd != NULL;
300     sd = mol->nextIntegrableObject(ii)) {
301    
302     vel = sd->getVel();
303 gezelter 507 vel[whichDirection] -= comVel[whichDirection];
304 gezelter 1782 sd->setVel(vel);
305 gezelter 507 }
306 gezelter 246 }
307    
308     // calculate the vz of center of mass of moving molecules(include unconstrained molecules
309     // and moving z-constrained molecules)
310 tim 963 RealType pzMovingMols_local = 0.0;
311     RealType pzMovingMols;
312 gezelter 246
313     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
314 gezelter 507 mol = i->mol;
315     comVel = mol->getComVel();
316     pzMovingMols_local += mol->getMass() * comVel[whichDirection];
317 gezelter 246 }
318    
319     std::vector<Molecule*>::iterator j;
320     for ( j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
321 gezelter 507 mol =*j;
322     comVel = mol->getComVel();
323     pzMovingMols_local += mol->getMass() * comVel[whichDirection];
324 gezelter 246 }
325    
326     #ifndef IS_MPI
327     pzMovingMols = pzMovingMols_local;
328     #else
329 tim 963 MPI_Allreduce(&pzMovingMols_local, &pzMovingMols, 1, MPI_REALTYPE,
330 gezelter 507 MPI_SUM, MPI_COMM_WORLD);
331 gezelter 246 #endif
332    
333 tim 963 RealType vzMovingMols = pzMovingMols / (totMassMovingZMols_ + totMassUnconsMols_);
334 gezelter 246
335     //modify the velocities of moving z-constrained molecuels
336     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
337 gezelter 1782
338 gezelter 507 mol = i->mol;
339 gezelter 246
340 gezelter 1782 for(sd = mol->beginIntegrableObject(ii); sd != NULL;
341     sd = mol->nextIntegrableObject(ii)) {
342    
343     vel = sd->getVel();
344 gezelter 507 vel[whichDirection] -= vzMovingMols;
345 gezelter 1782 sd->setVel(vel);
346 gezelter 507 }
347 gezelter 246 }
348    
349     //modify the velocites of unconstrained molecules
350     for ( j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
351 gezelter 1782
352 gezelter 507 mol =*j;
353 gezelter 246
354 gezelter 1782 for(sd = mol->beginIntegrableObject(ii); sd != NULL;
355     sd = mol->nextIntegrableObject(ii)) {
356    
357     vel = sd->getVel();
358 gezelter 507 vel[whichDirection] -= vzMovingMols;
359 gezelter 1782 sd->setVel(vel);
360 gezelter 507 }
361 gezelter 246 }
362    
363 gezelter 507 }
364 gezelter 246
365    
366 gezelter 507 void ZconstraintForceManager::doZconstraintForce(){
367 tim 963 RealType totalFZ;
368     RealType totalFZ_local;
369 gezelter 507 Vector3d com;
370     Vector3d force(0.0);
371 gezelter 246
372 gezelter 507 //constrain the molecules which do not reach the specified positions
373 gezelter 246
374 gezelter 507 //Zero Out the force of z-contrained molecules
375     totalFZ_local = 0;
376 gezelter 246
377    
378     //calculate the total z-contrained force of fixed z-contrained molecules
379     std::list<ZconstraintMol>::iterator i;
380     Molecule* mol;
381 gezelter 1782 StuntDouble* sd;
382 gezelter 246 Molecule::IntegrableObjectIterator ii;
383    
384     for ( i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
385 gezelter 1782
386 gezelter 507 mol = i->mol;
387     i->fz = 0.0;
388 gezelter 246
389 gezelter 1782 for( sd = mol->beginIntegrableObject(ii); sd != NULL;
390     sd = mol->nextIntegrableObject(ii)) {
391    
392     force = sd->getFrc();
393 gezelter 507 i->fz += force[whichDirection];
394     }
395     totalFZ_local += i->fz;
396 gezelter 246 }
397    
398 gezelter 507 //calculate total z-constraint force
399 gezelter 246 #ifdef IS_MPI
400 tim 963 MPI_Allreduce(&totalFZ_local, &totalFZ, 1, MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
401 gezelter 246 #else
402 gezelter 507 totalFZ = totalFZ_local;
403 gezelter 246 #endif
404    
405    
406 gezelter 507 // apply negative to fixed z-constrained molecues;
407 gezelter 246 for ( i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
408 gezelter 1782
409 gezelter 507 mol = i->mol;
410 gezelter 246
411 gezelter 1782 for(sd = mol->beginIntegrableObject(ii); sd != NULL;
412     sd = mol->nextIntegrableObject(ii)) {
413    
414     force[whichDirection] = -getZFOfFixedZMols(mol, sd, i->fz);
415     sd->addFrc(force);
416 gezelter 507 }
417 gezelter 246 }
418    
419 gezelter 507 //modify the forces of moving z-constrained molecules
420 gezelter 246 for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
421 gezelter 1782
422 gezelter 507 mol = i->mol;
423 gezelter 246
424 gezelter 1782 for(sd = mol->beginIntegrableObject(ii); sd != NULL;
425     sd = mol->nextIntegrableObject(ii)) {
426    
427 gezelter 507 force[whichDirection] = -getZFOfMovingMols(mol,totalFZ);
428 gezelter 1782 sd->addFrc(force);
429 gezelter 507 }
430 gezelter 246 }
431    
432 gezelter 507 //modify the forces of unconstrained molecules
433 gezelter 246 std::vector<Molecule*>::iterator j;
434     for ( j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
435 gezelter 1782
436 gezelter 507 mol =*j;
437 gezelter 246
438 gezelter 1782 for(sd = mol->beginIntegrableObject(ii); sd != NULL;
439     sd = mol->nextIntegrableObject(ii)) {
440    
441 gezelter 507 force[whichDirection] = -getZFOfMovingMols(mol, totalFZ);
442 gezelter 1782 sd->addFrc(force);
443 gezelter 507 }
444 gezelter 246 }
445    
446 gezelter 507 }
447 gezelter 246
448    
449 gezelter 507 void ZconstraintForceManager::doHarmonic(){
450 tim 963 RealType totalFZ;
451 gezelter 246 Vector3d force(0.0);
452     Vector3d com;
453 tim 963 RealType totalFZ_local = 0;
454 gezelter 1782 RealType lrPot;
455 gezelter 246 std::list<ZconstraintMol>::iterator i;
456 gezelter 1782 StuntDouble* sd;
457 gezelter 246 Molecule::IntegrableObjectIterator ii;
458     Molecule* mol;
459     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
460 gezelter 507 mol = i->mol;
461     com = mol->getCom();
462 tim 963 RealType resPos = usingSMD_? i->cantPos : i->param.zTargetPos;
463     RealType diff = com[whichDirection] - resPos;
464     RealType harmonicU = 0.5 * i->param.kz * diff * diff;
465 gezelter 1782 lrPot = currSnapshot_->getLongRangePotential();
466     lrPot += harmonicU;
467     currSnapshot_->setLongRangePotential(lrPot);
468 tim 963 RealType harmonicF = -i->param.kz * diff;
469 gezelter 507 totalFZ_local += harmonicF;
470 gezelter 246
471 gezelter 507 //adjust force
472 gezelter 1782 for(sd = mol->beginIntegrableObject(ii); sd != NULL;
473     sd = mol->nextIntegrableObject(ii)) {
474 gezelter 246
475 gezelter 1782 force[whichDirection] = getHFOfFixedZMols(mol, sd, harmonicF);
476     sd->addFrc(force);
477 gezelter 507 }
478 gezelter 246 }
479    
480     #ifndef IS_MPI
481 gezelter 507 totalFZ = totalFZ_local;
482 gezelter 246 #else
483 tim 963 MPI_Allreduce(&totalFZ_local, &totalFZ, 1, MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
484 gezelter 246 #endif
485    
486     //modify the forces of unconstrained molecules
487     std::vector<Molecule*>::iterator j;
488     for ( j = unzconsMols_.begin(); j != unzconsMols_.end(); ++j) {
489 gezelter 1782
490 gezelter 507 mol = *j;
491 gezelter 246
492 gezelter 1782 for(sd = mol->beginIntegrableObject(ii); sd != NULL;
493     sd = mol->nextIntegrableObject(ii)) {
494    
495 gezelter 507 force[whichDirection] = getHFOfUnconsMols(mol, totalFZ);
496 gezelter 1782 sd->addFrc(force);
497 gezelter 507 }
498 gezelter 246 }
499    
500 gezelter 507 }
501 gezelter 246
502 gezelter 507 bool ZconstraintForceManager::checkZConsState(){
503 gezelter 246 Vector3d com;
504 tim 963 RealType diff;
505 gezelter 246 int changed_local = 0;
506    
507     std::list<ZconstraintMol>::iterator i;
508     std::list<ZconstraintMol>::iterator j;
509    
510     std::list<ZconstraintMol> newMovingZMols;
511     for ( i = fixedZMols_.begin(); i != fixedZMols_.end();) {
512 gezelter 507 com = i->mol->getCom();
513     diff = fabs(com[whichDirection] - i->param.zTargetPos);
514     if (diff > zconsTol_) {
515     if (usingZconsGap_) {
516     i->endFixingTime = infiniteTime;
517     }
518     j = i++;
519     newMovingZMols.push_back(*j);
520     fixedZMols_.erase(j);
521 gezelter 246
522 gezelter 507 changed_local = 1;
523     }else {
524     ++i;
525     }
526 gezelter 246 }
527    
528     std::list<ZconstraintMol> newFixedZMols;
529     for ( i = movingZMols_.begin(); i != movingZMols_.end();) {
530 gezelter 507 com = i->mol->getCom();
531     diff = fabs(com[whichDirection] - i->param.zTargetPos);
532     if (diff <= zconsTol_) {
533     if (usingZconsGap_) {
534     i->endFixingTime = currSnapshot_->getTime() + zconsFixingTime_;
535     }
536     //this moving zconstraint molecule is about to fixed
537     //moved this molecule to
538     j = i++;
539     newFixedZMols.push_back(*j);
540     movingZMols_.erase(j);
541     changed_local = 1;
542     }else {
543     ++i;
544     }
545 gezelter 246 }
546    
547     //merge the lists
548     fixedZMols_.insert(fixedZMols_.end(), newFixedZMols.begin(), newFixedZMols.end());
549     movingZMols_.insert(movingZMols_.end(), newMovingZMols.begin(), newMovingZMols.end());
550    
551     int changed;
552     #ifndef IS_MPI
553     changed = changed_local;
554     #else
555     MPI_Allreduce(&changed_local, &changed, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
556     #endif
557    
558     return (changed > 0);
559 gezelter 507 }
560 gezelter 246
561 gezelter 507 bool ZconstraintForceManager::haveFixedZMols(){
562     int havingFixed;
563     int havingFixed_local = fixedZMols_.empty() ? 0 : 1;
564 gezelter 246
565     #ifndef IS_MPI
566 gezelter 507 havingFixed = havingFixed_local;
567 gezelter 246 #else
568 gezelter 507 MPI_Allreduce(&havingFixed_local, &havingFixed, 1, MPI_INT, MPI_SUM,
569     MPI_COMM_WORLD);
570 gezelter 246 #endif
571    
572 gezelter 507 return havingFixed > 0;
573     }
574 gezelter 246
575    
576 gezelter 507 bool ZconstraintForceManager::haveMovingZMols(){
577     int havingMoving_local;
578     int havingMoving;
579 gezelter 246
580 gezelter 507 havingMoving_local = movingZMols_.empty()? 0 : 1;
581 gezelter 246
582     #ifndef IS_MPI
583 gezelter 507 havingMoving = havingMoving_local;
584 gezelter 246 #else
585 gezelter 507 MPI_Allreduce(&havingMoving_local, &havingMoving, 1, MPI_INT, MPI_SUM,
586     MPI_COMM_WORLD);
587 gezelter 246 #endif
588    
589 gezelter 507 return havingMoving > 0;
590     }
591 gezelter 246
592 gezelter 507 void ZconstraintForceManager::calcTotalMassMovingZMols(){
593 gezelter 246
594 tim 963 RealType totMassMovingZMols_local = 0.0;
595 gezelter 246 std::list<ZconstraintMol>::iterator i;
596     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
597 gezelter 507 totMassMovingZMols_local += i->mol->getMass();
598 gezelter 246 }
599    
600     #ifdef IS_MPI
601 tim 963 MPI_Allreduce(&totMassMovingZMols_local, &totMassMovingZMols_, 1, MPI_REALTYPE,
602 gezelter 507 MPI_SUM, MPI_COMM_WORLD);
603 gezelter 246 #else
604     totMassMovingZMols_ = totMassMovingZMols_local;
605     #endif
606    
607 gezelter 507 }
608 gezelter 246
609 tim 963 RealType ZconstraintForceManager::getZFOfFixedZMols(Molecule* mol, StuntDouble* sd, RealType totalForce){
610 gezelter 507 return totalForce * sd->getMass() / mol->getMass();
611     }
612 gezelter 246
613 tim 963 RealType ZconstraintForceManager::getZFOfMovingMols(Molecule* mol, RealType totalForce){
614 gezelter 507 return totalForce * mol->getMass() / (totMassUnconsMols_ + totMassMovingZMols_);
615     }
616 gezelter 246
617 tim 963 RealType ZconstraintForceManager::getHFOfFixedZMols(Molecule* mol, StuntDouble*sd, RealType totalForce){
618 gezelter 507 return totalForce * sd->getMass() / mol->getMass();
619     }
620 gezelter 246
621 tim 963 RealType ZconstraintForceManager::getHFOfUnconsMols(Molecule* mol, RealType totalForce){
622 gezelter 507 return totalForce * mol->getMass() / totMassUnconsMols_;
623     }
624 gezelter 246
625 gezelter 507 void ZconstraintForceManager::updateZPos(){
626 tim 963 RealType curTime = currSnapshot_->getTime();
627 gezelter 246 std::list<ZconstraintMol>::iterator i;
628     for ( i = fixedZMols_.begin(); i != fixedZMols_.end(); ++i) {
629 gezelter 507 i->param.zTargetPos += zconsGap_;
630 gezelter 246 }
631 gezelter 507 }
632 gezelter 246
633 gezelter 507 void ZconstraintForceManager::updateCantPos(){
634 gezelter 246 std::list<ZconstraintMol>::iterator i;
635     for ( i = movingZMols_.begin(); i != movingZMols_.end(); ++i) {
636 gezelter 507 i->cantPos += i->param.cantVel * dt_;
637 gezelter 246 }
638 gezelter 507 }
639 gezelter 246
640 tim 963 RealType ZconstraintForceManager::getZTargetPos(int index){
641     RealType zTargetPos;
642 gezelter 246 #ifndef IS_MPI
643     Molecule* mol = info_->getMoleculeByGlobalIndex(index);
644     assert(mol);
645     Vector3d com = mol->getCom();
646     zTargetPos = com[whichDirection];
647     #else
648     int whicProc = info_->getMolToProc(index);
649 tim 963 MPI_Bcast(&zTargetPos, 1, MPI_REALTYPE, whicProc, MPI_COMM_WORLD);
650 gezelter 246 #endif
651     return zTargetPos;
652 gezelter 507 }
653 gezelter 246
654     }

Properties

Name Value
svn:executable *
svn:keywords Author Id Revision Date