ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/brains/ForceManager.cpp
Revision: 2067
Committed: Thu Mar 5 15:35:37 2015 UTC (10 years, 1 month ago) by gezelter
File size: 36892 byte(s)
Log Message:
Trying to eliminate some g++ warnings

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 gezelter 1879 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (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 gezelter 507 /**
44     * @file ForceManager.cpp
45     * @author tlin
46     * @date 11/09/2004
47     * @version 1.0
48     */
49 gezelter 246
50 gezelter 1782
51 gezelter 246 #include "brains/ForceManager.hpp"
52     #include "primitives/Molecule.hpp"
53 gezelter 1390 #define __OPENMD_C
54 gezelter 246 #include "utils/simError.h"
55 xsun 1215 #include "primitives/Bond.hpp"
56 tim 749 #include "primitives/Bend.hpp"
57 cli2 1275 #include "primitives/Torsion.hpp"
58     #include "primitives/Inversion.hpp"
59 gezelter 1782 #include "nonbonded/NonBondedInteraction.hpp"
60 gezelter 2020 #include "perturbations/UniformField.hpp"
61 gezelter 2047 #include "perturbations/UniformGradient.hpp"
62 gezelter 1782 #include "parallel/ForceMatrixDecomposition.hpp"
63    
64     #include <cstdio>
65     #include <iostream>
66     #include <iomanip>
67    
68     using namespace std;
69 gezelter 1390 namespace OpenMD {
70 gezelter 1782
71 gezelter 2067 ForceManager::ForceManager(SimInfo * info) : initialized_(false), info_(info),
72 gezelter 2066 switcher_(NULL) {
73 gezelter 1782 forceField_ = info_->getForceField();
74     interactionMan_ = new InteractionManager();
75     fDecomp_ = new ForceMatrixDecomposition(info_, interactionMan_);
76 gezelter 1879 thermo = new Thermo(info_);
77 gezelter 1782 }
78 gezelter 246
79 gezelter 1879 ForceManager::~ForceManager() {
80     perturbations_.clear();
81    
82     delete switcher_;
83     delete interactionMan_;
84     delete fDecomp_;
85     delete thermo;
86     }
87    
88 gezelter 1782 /**
89     * setupCutoffs
90     *
91 gezelter 2057 * Sets the values of cutoffRadius, switchingRadius, and cutoffMethod
92 gezelter 1782 *
93     * cutoffRadius : realType
94     * If the cutoffRadius was explicitly set, use that value.
95     * If the cutoffRadius was not explicitly set:
96     * Are there electrostatic atoms? Use 12.0 Angstroms.
97     * No electrostatic atoms? Poll the atom types present in the
98     * simulation for suggested cutoff values (e.g. 2.5 * sigma).
99     * Use the maximum suggested value that was found.
100     *
101 gezelter 1879 * cutoffMethod : (one of HARD, SWITCHED, SHIFTED_FORCE, TAYLOR_SHIFTED,
102 gezelter 1915 * SHIFTED_POTENTIAL, or EWALD_FULL)
103 gezelter 1782 * If cutoffMethod was explicitly set, use that choice.
104     * If cutoffMethod was not explicitly set, use SHIFTED_FORCE
105     *
106     * switchingRadius : realType
107     * If the cutoffMethod was set to SWITCHED:
108     * If the switchingRadius was explicitly set, use that value
109     * (but do a sanity check first).
110     * If the switchingRadius was not explicitly set: use 0.85 *
111     * cutoffRadius_
112     * If the cutoffMethod was not set to SWITCHED:
113     * Set switchingRadius equal to cutoffRadius for safety.
114     */
115     void ForceManager::setupCutoffs() {
116 gezelter 1126
117 gezelter 1782 Globals* simParams_ = info_->getSimParams();
118     int mdFileVersion;
119     rCut_ = 0.0; //Needs a value for a later max() call;
120    
121     if (simParams_->haveMDfileVersion())
122     mdFileVersion = simParams_->getMDfileVersion();
123     else
124     mdFileVersion = 0;
125    
126 gezelter 1879 // We need the list of simulated atom types to figure out cutoffs
127     // as well as long range corrections.
128    
129     set<AtomType*>::iterator i;
130     set<AtomType*> atomTypes_;
131     atomTypes_ = info_->getSimulatedAtomTypes();
132    
133 gezelter 1782 if (simParams_->haveCutoffRadius()) {
134     rCut_ = simParams_->getCutoffRadius();
135     } else {
136     if (info_->usesElectrostaticAtoms()) {
137     sprintf(painCave.errMsg,
138     "ForceManager::setupCutoffs: No value was set for the cutoffRadius.\n"
139     "\tOpenMD will use a default value of 12.0 angstroms"
140     "\tfor the cutoffRadius.\n");
141     painCave.isFatal = 0;
142     painCave.severity = OPENMD_INFO;
143     simError();
144     rCut_ = 12.0;
145     } else {
146     RealType thisCut;
147 gezelter 1879 for (i = atomTypes_.begin(); i != atomTypes_.end(); ++i) {
148 gezelter 1782 thisCut = interactionMan_->getSuggestedCutoffRadius((*i));
149     rCut_ = max(thisCut, rCut_);
150     }
151     sprintf(painCave.errMsg,
152     "ForceManager::setupCutoffs: No value was set for the cutoffRadius.\n"
153     "\tOpenMD will use %lf angstroms.\n",
154     rCut_);
155     painCave.isFatal = 0;
156     painCave.severity = OPENMD_INFO;
157     simError();
158     }
159     }
160    
161 gezelter 2057 fDecomp_->setCutoffRadius(rCut_);
162 gezelter 1782 interactionMan_->setCutoffRadius(rCut_);
163 gezelter 2057 rCutSq_ = rCut_ * rCut_;
164 gezelter 1782
165     map<string, CutoffMethod> stringToCutoffMethod;
166     stringToCutoffMethod["HARD"] = HARD;
167     stringToCutoffMethod["SWITCHED"] = SWITCHED;
168     stringToCutoffMethod["SHIFTED_POTENTIAL"] = SHIFTED_POTENTIAL;
169     stringToCutoffMethod["SHIFTED_FORCE"] = SHIFTED_FORCE;
170 gezelter 1879 stringToCutoffMethod["TAYLOR_SHIFTED"] = TAYLOR_SHIFTED;
171 gezelter 1915 stringToCutoffMethod["EWALD_FULL"] = EWALD_FULL;
172 gezelter 1782
173     if (simParams_->haveCutoffMethod()) {
174     string cutMeth = toUpperCopy(simParams_->getCutoffMethod());
175     map<string, CutoffMethod>::iterator i;
176     i = stringToCutoffMethod.find(cutMeth);
177     if (i == stringToCutoffMethod.end()) {
178     sprintf(painCave.errMsg,
179     "ForceManager::setupCutoffs: Could not find chosen cutoffMethod %s\n"
180     "\tShould be one of: "
181 gezelter 1879 "HARD, SWITCHED, SHIFTED_POTENTIAL, TAYLOR_SHIFTED,\n"
182 gezelter 1915 "\tSHIFTED_FORCE, or EWALD_FULL\n",
183 gezelter 1782 cutMeth.c_str());
184     painCave.isFatal = 1;
185     painCave.severity = OPENMD_ERROR;
186     simError();
187     } else {
188     cutoffMethod_ = i->second;
189     }
190     } else {
191     if (mdFileVersion > 1) {
192     sprintf(painCave.errMsg,
193     "ForceManager::setupCutoffs: No value was set for the cutoffMethod.\n"
194     "\tOpenMD will use SHIFTED_FORCE.\n");
195     painCave.isFatal = 0;
196     painCave.severity = OPENMD_INFO;
197     simError();
198     cutoffMethod_ = SHIFTED_FORCE;
199     } else {
200     // handle the case where the old file version was in play
201     // (there should be no cutoffMethod, so we have to deduce it
202     // from other data).
203    
204     sprintf(painCave.errMsg,
205     "ForceManager::setupCutoffs : DEPRECATED FILE FORMAT!\n"
206     "\tOpenMD found a file which does not set a cutoffMethod.\n"
207     "\tOpenMD will attempt to deduce a cutoffMethod using the\n"
208     "\tbehavior of the older (version 1) code. To remove this\n"
209     "\twarning, add an explicit cutoffMethod and change the top\n"
210     "\tof the file so that it begins with <OpenMD version=2>\n");
211     painCave.isFatal = 0;
212     painCave.severity = OPENMD_WARNING;
213     simError();
214    
215     // The old file version tethered the shifting behavior to the
216     // electrostaticSummationMethod keyword.
217    
218     if (simParams_->haveElectrostaticSummationMethod()) {
219     string myMethod = simParams_->getElectrostaticSummationMethod();
220     toUpper(myMethod);
221    
222     if (myMethod == "SHIFTED_POTENTIAL") {
223     cutoffMethod_ = SHIFTED_POTENTIAL;
224     } else if (myMethod == "SHIFTED_FORCE") {
225     cutoffMethod_ = SHIFTED_FORCE;
226 gezelter 1879 } else if (myMethod == "TAYLOR_SHIFTED") {
227     cutoffMethod_ = TAYLOR_SHIFTED;
228 gezelter 1915 } else if (myMethod == "EWALD_FULL") {
229     cutoffMethod_ = EWALD_FULL;
230 gezelter 1782 }
231    
232     if (simParams_->haveSwitchingRadius())
233     rSwitch_ = simParams_->getSwitchingRadius();
234    
235 gezelter 1879 if (myMethod == "SHIFTED_POTENTIAL" || myMethod == "SHIFTED_FORCE" ||
236 gezelter 1915 myMethod == "TAYLOR_SHIFTED" || myMethod == "EWALD_FULL") {
237 gezelter 1782 if (simParams_->haveSwitchingRadius()){
238     sprintf(painCave.errMsg,
239     "ForceManager::setupCutoffs : DEPRECATED ERROR MESSAGE\n"
240     "\tA value was set for the switchingRadius\n"
241     "\teven though the electrostaticSummationMethod was\n"
242     "\tset to %s\n", myMethod.c_str());
243     painCave.severity = OPENMD_WARNING;
244     painCave.isFatal = 1;
245     simError();
246     }
247     }
248     if (abs(rCut_ - rSwitch_) < 0.0001) {
249     if (cutoffMethod_ == SHIFTED_FORCE) {
250     sprintf(painCave.errMsg,
251     "ForceManager::setupCutoffs : DEPRECATED BEHAVIOR\n"
252     "\tcutoffRadius and switchingRadius are set to the\n"
253     "\tsame value. OpenMD will use shifted force\n"
254     "\tpotentials instead of switching functions.\n");
255     painCave.isFatal = 0;
256     painCave.severity = OPENMD_WARNING;
257     simError();
258     } else {
259     cutoffMethod_ = SHIFTED_POTENTIAL;
260     sprintf(painCave.errMsg,
261     "ForceManager::setupCutoffs : DEPRECATED BEHAVIOR\n"
262     "\tcutoffRadius and switchingRadius are set to the\n"
263     "\tsame value. OpenMD will use shifted potentials\n"
264     "\tinstead of switching functions.\n");
265     painCave.isFatal = 0;
266     painCave.severity = OPENMD_WARNING;
267     simError();
268     }
269     }
270     }
271     }
272     }
273    
274     // create the switching function object:
275    
276     switcher_ = new SwitchingFunction();
277    
278     if (cutoffMethod_ == SWITCHED) {
279     if (simParams_->haveSwitchingRadius()) {
280     rSwitch_ = simParams_->getSwitchingRadius();
281     if (rSwitch_ > rCut_) {
282     sprintf(painCave.errMsg,
283     "ForceManager::setupCutoffs: switchingRadius (%f) is larger "
284     "than the cutoffRadius(%f)\n", rSwitch_, rCut_);
285     painCave.isFatal = 1;
286     painCave.severity = OPENMD_ERROR;
287     simError();
288     }
289     } else {
290     rSwitch_ = 0.85 * rCut_;
291     sprintf(painCave.errMsg,
292     "ForceManager::setupCutoffs: No value was set for the switchingRadius.\n"
293     "\tOpenMD will use a default value of 85 percent of the cutoffRadius.\n"
294     "\tswitchingRadius = %f. for this simulation\n", rSwitch_);
295     painCave.isFatal = 0;
296     painCave.severity = OPENMD_WARNING;
297     simError();
298     }
299     } else {
300     if (mdFileVersion > 1) {
301     // throw an error if we define a switching radius and don't need one.
302     // older file versions should not do this.
303     if (simParams_->haveSwitchingRadius()) {
304     map<string, CutoffMethod>::const_iterator it;
305     string theMeth;
306     for (it = stringToCutoffMethod.begin();
307     it != stringToCutoffMethod.end(); ++it) {
308     if (it->second == cutoffMethod_) {
309     theMeth = it->first;
310     break;
311     }
312     }
313     sprintf(painCave.errMsg,
314     "ForceManager::setupCutoffs: the cutoffMethod (%s)\n"
315     "\tis not set to SWITCHED, so switchingRadius value\n"
316     "\twill be ignored for this simulation\n", theMeth.c_str());
317     painCave.isFatal = 0;
318     painCave.severity = OPENMD_WARNING;
319     simError();
320     }
321     }
322     rSwitch_ = rCut_;
323     }
324    
325     // Default to cubic switching function.
326     sft_ = cubic;
327     if (simParams_->haveSwitchingFunctionType()) {
328     string funcType = simParams_->getSwitchingFunctionType();
329     toUpper(funcType);
330     if (funcType == "CUBIC") {
331     sft_ = cubic;
332     } else {
333     if (funcType == "FIFTH_ORDER_POLYNOMIAL") {
334     sft_ = fifth_order_poly;
335     } else {
336     // throw error
337     sprintf( painCave.errMsg,
338     "ForceManager::setupSwitching : Unknown switchingFunctionType. (Input file specified %s .)\n"
339     "\tswitchingFunctionType must be one of: "
340     "\"cubic\" or \"fifth_order_polynomial\".",
341     funcType.c_str() );
342     painCave.isFatal = 1;
343     painCave.severity = OPENMD_ERROR;
344     simError();
345     }
346     }
347     }
348     switcher_->setSwitchType(sft_);
349     switcher_->setSwitch(rSwitch_, rCut_);
350     }
351    
352     void ForceManager::initialize() {
353    
354     if (!info_->isTopologyDone()) {
355    
356 gezelter 507 info_->update();
357 gezelter 1782 interactionMan_->setSimInfo(info_);
358     interactionMan_->initialize();
359    
360 gezelter 2020 //! We want to delay the cutoffs until after the interaction
361     //! manager has set up the atom-atom interactions so that we can
362     //! query them for suggested cutoff values
363 gezelter 1782 setupCutoffs();
364    
365     info_->prepareTopology();
366    
367     doParticlePot_ = info_->getSimParams()->getOutputParticlePotential();
368     doHeatFlux_ = info_->getSimParams()->getPrintHeatFlux();
369     if (doHeatFlux_) doParticlePot_ = true;
370 gezelter 1879
371     doElectricField_ = info_->getSimParams()->getOutputElectricField();
372 gezelter 1993 doSitePotential_ = info_->getSimParams()->getOutputSitePotential();
373 gezelter 1782
374 gezelter 246 }
375 gezelter 1782
376     ForceFieldOptions& fopts = forceField_->getForceFieldOptions();
377 gezelter 1126
378 gezelter 2020 //! Force fields can set options on how to scale van der Waals and
379     //! electrostatic interactions for atoms connected via bonds, bends
380     //! and torsions in this case the topological distance between
381     //! atoms is:
382     //! 0 = topologically unconnected
383     //! 1 = bonded together
384     //! 2 = connected via a bend
385     //! 3 = connected via a torsion
386 gezelter 246
387 gezelter 1782 vdwScale_.reserve(4);
388     fill(vdwScale_.begin(), vdwScale_.end(), 0.0);
389 gezelter 246
390 gezelter 1782 electrostaticScale_.reserve(4);
391     fill(electrostaticScale_.begin(), electrostaticScale_.end(), 0.0);
392 gezelter 246
393 gezelter 1782 vdwScale_[0] = 1.0;
394     vdwScale_[1] = fopts.getvdw12scale();
395     vdwScale_[2] = fopts.getvdw13scale();
396     vdwScale_[3] = fopts.getvdw14scale();
397 tim 749
398 gezelter 1782 electrostaticScale_[0] = 1.0;
399     electrostaticScale_[1] = fopts.getelectrostatic12scale();
400     electrostaticScale_[2] = fopts.getelectrostatic13scale();
401     electrostaticScale_[3] = fopts.getelectrostatic14scale();
402    
403 gezelter 2020 if (info_->getSimParams()->haveUniformField()) {
404     UniformField* eField = new UniformField(info_);
405 gezelter 1782 perturbations_.push_back(eField);
406     }
407 gezelter 2047 if (info_->getSimParams()->haveUniformGradientStrength() ||
408     info_->getSimParams()->haveUniformGradientDirection1() ||
409     info_->getSimParams()->haveUniformGradientDirection2() ) {
410     UniformGradient* eGrad = new UniformGradient(info_);
411     perturbations_.push_back(eGrad);
412     }
413    
414 gezelter 1879 usePeriodicBoundaryConditions_ = info_->getSimParams()->getUsePeriodicBoundaryConditions();
415    
416 gezelter 1782 fDecomp_->distributeInitialData();
417 gezelter 1879
418 gezelter 1782 initialized_ = true;
419 gezelter 1879
420 gezelter 507 }
421 gezelter 1879
422 gezelter 1782 void ForceManager::calcForces() {
423    
424     if (!initialized_) initialize();
425 gezelter 1879
426 gezelter 1782 preCalculation();
427     shortRangeInteractions();
428     longRangeInteractions();
429     postCalculation();
430     }
431 gezelter 1126
432 gezelter 507 void ForceManager::preCalculation() {
433 gezelter 246 SimInfo::MoleculeIterator mi;
434     Molecule* mol;
435     Molecule::AtomIterator ai;
436     Atom* atom;
437     Molecule::RigidBodyIterator rbIter;
438     RigidBody* rb;
439 gezelter 1782 Molecule::CutoffGroupIterator ci;
440     CutoffGroup* cg;
441 gezelter 246
442 gezelter 1782 // forces and potentials are zeroed here, before any are
443     // accumulated.
444 chuckv 1245
445 gezelter 1782 Snapshot* snap = info_->getSnapshotManager()->getCurrentSnapshot();
446    
447     snap->setBondPotential(0.0);
448     snap->setBendPotential(0.0);
449     snap->setTorsionPotential(0.0);
450     snap->setInversionPotential(0.0);
451    
452     potVec zeroPot(0.0);
453     snap->setLongRangePotential(zeroPot);
454     snap->setExcludedPotentials(zeroPot);
455    
456     snap->setRestraintPotential(0.0);
457     snap->setRawPotential(0.0);
458    
459 gezelter 1126 for (mol = info_->beginMolecule(mi); mol != NULL;
460     mol = info_->nextMolecule(mi)) {
461 gezelter 1782 for(atom = mol->beginAtom(ai); atom != NULL;
462     atom = mol->nextAtom(ai)) {
463 gezelter 507 atom->zeroForcesAndTorques();
464     }
465 gezelter 1782
466 gezelter 507 //change the positions of atoms which belong to the rigidbodies
467 gezelter 1126 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
468     rb = mol->nextRigidBody(rbIter)) {
469 gezelter 507 rb->zeroForcesAndTorques();
470     }
471 gezelter 1782
472     if(info_->getNGlobalCutoffGroups() != info_->getNGlobalAtoms()){
473     for(cg = mol->beginCutoffGroup(ci); cg != NULL;
474     cg = mol->nextCutoffGroup(ci)) {
475     //calculate the center of mass of cutoff group
476     cg->updateCOM();
477     }
478     }
479 gezelter 246 }
480    
481 gezelter 1126 // Zero out the stress tensor
482 gezelter 1782 stressTensor *= 0.0;
483     // Zero out the heatFlux
484     fDecomp_->setHeatFlux( Vector3d(0.0) );
485 gezelter 507 }
486 gezelter 1126
487 gezelter 1782 void ForceManager::shortRangeInteractions() {
488 gezelter 246 Molecule* mol;
489     RigidBody* rb;
490     Bond* bond;
491     Bend* bend;
492     Torsion* torsion;
493 cli2 1275 Inversion* inversion;
494 gezelter 246 SimInfo::MoleculeIterator mi;
495     Molecule::RigidBodyIterator rbIter;
496     Molecule::BondIterator bondIter;;
497     Molecule::BendIterator bendIter;
498     Molecule::TorsionIterator torsionIter;
499 cli2 1275 Molecule::InversionIterator inversionIter;
500 tim 963 RealType bondPotential = 0.0;
501     RealType bendPotential = 0.0;
502     RealType torsionPotential = 0.0;
503 cli2 1275 RealType inversionPotential = 0.0;
504 gezelter 246
505     //calculate short range interactions
506 gezelter 1126 for (mol = info_->beginMolecule(mi); mol != NULL;
507     mol = info_->nextMolecule(mi)) {
508 gezelter 246
509 gezelter 507 //change the positions of atoms which belong to the rigidbodies
510 gezelter 1126 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
511     rb = mol->nextRigidBody(rbIter)) {
512     rb->updateAtoms();
513 gezelter 507 }
514 gezelter 246
515 gezelter 1126 for (bond = mol->beginBond(bondIter); bond != NULL;
516     bond = mol->nextBond(bondIter)) {
517 gezelter 1782 bond->calcForce(doParticlePot_);
518 tim 749 bondPotential += bond->getPotential();
519 gezelter 507 }
520 gezelter 246
521 gezelter 1126 for (bend = mol->beginBend(bendIter); bend != NULL;
522     bend = mol->nextBend(bendIter)) {
523    
524     RealType angle;
525 gezelter 1782 bend->calcForce(angle, doParticlePot_);
526 gezelter 1126 RealType currBendPot = bend->getPotential();
527 gezelter 1448
528 gezelter 1126 bendPotential += bend->getPotential();
529 gezelter 1782 map<Bend*, BendDataSet>::iterator i = bendDataSets.find(bend);
530 gezelter 1126 if (i == bendDataSets.end()) {
531     BendDataSet dataSet;
532     dataSet.prev.angle = dataSet.curr.angle = angle;
533     dataSet.prev.potential = dataSet.curr.potential = currBendPot;
534     dataSet.deltaV = 0.0;
535 gezelter 1782 bendDataSets.insert(map<Bend*, BendDataSet>::value_type(bend,
536     dataSet));
537 gezelter 1126 }else {
538     i->second.prev.angle = i->second.curr.angle;
539     i->second.prev.potential = i->second.curr.potential;
540     i->second.curr.angle = angle;
541     i->second.curr.potential = currBendPot;
542     i->second.deltaV = fabs(i->second.curr.potential -
543     i->second.prev.potential);
544     }
545 gezelter 507 }
546 gezelter 1126
547     for (torsion = mol->beginTorsion(torsionIter); torsion != NULL;
548     torsion = mol->nextTorsion(torsionIter)) {
549 tim 963 RealType angle;
550 gezelter 1782 torsion->calcForce(angle, doParticlePot_);
551 tim 963 RealType currTorsionPot = torsion->getPotential();
552 gezelter 1126 torsionPotential += torsion->getPotential();
553 gezelter 1782 map<Torsion*, TorsionDataSet>::iterator i = torsionDataSets.find(torsion);
554 gezelter 1126 if (i == torsionDataSets.end()) {
555     TorsionDataSet dataSet;
556     dataSet.prev.angle = dataSet.curr.angle = angle;
557     dataSet.prev.potential = dataSet.curr.potential = currTorsionPot;
558     dataSet.deltaV = 0.0;
559 gezelter 1782 torsionDataSets.insert(map<Torsion*, TorsionDataSet>::value_type(torsion, dataSet));
560 gezelter 1126 }else {
561     i->second.prev.angle = i->second.curr.angle;
562     i->second.prev.potential = i->second.curr.potential;
563     i->second.curr.angle = angle;
564     i->second.curr.potential = currTorsionPot;
565     i->second.deltaV = fabs(i->second.curr.potential -
566     i->second.prev.potential);
567     }
568     }
569 gezelter 1782
570 cli2 1275 for (inversion = mol->beginInversion(inversionIter);
571     inversion != NULL;
572     inversion = mol->nextInversion(inversionIter)) {
573     RealType angle;
574 gezelter 1782 inversion->calcForce(angle, doParticlePot_);
575 cli2 1275 RealType currInversionPot = inversion->getPotential();
576     inversionPotential += inversion->getPotential();
577 gezelter 1782 map<Inversion*, InversionDataSet>::iterator i = inversionDataSets.find(inversion);
578 cli2 1275 if (i == inversionDataSets.end()) {
579     InversionDataSet dataSet;
580     dataSet.prev.angle = dataSet.curr.angle = angle;
581     dataSet.prev.potential = dataSet.curr.potential = currInversionPot;
582     dataSet.deltaV = 0.0;
583 gezelter 1782 inversionDataSets.insert(map<Inversion*, InversionDataSet>::value_type(inversion, dataSet));
584 cli2 1275 }else {
585     i->second.prev.angle = i->second.curr.angle;
586     i->second.prev.potential = i->second.curr.potential;
587     i->second.curr.angle = angle;
588     i->second.curr.potential = currInversionPot;
589     i->second.deltaV = fabs(i->second.curr.potential -
590     i->second.prev.potential);
591     }
592     }
593 gezelter 246 }
594 gezelter 1782
595     #ifdef IS_MPI
596     // Collect from all nodes. This should eventually be moved into a
597     // SystemDecomposition, but this is a better place than in
598     // Thermo to do the collection.
599 gezelter 1969
600     MPI_Allreduce(MPI_IN_PLACE, &bondPotential, 1, MPI_REALTYPE,
601     MPI_SUM, MPI_COMM_WORLD);
602     MPI_Allreduce(MPI_IN_PLACE, &bendPotential, 1, MPI_REALTYPE,
603     MPI_SUM, MPI_COMM_WORLD);
604     MPI_Allreduce(MPI_IN_PLACE, &torsionPotential, 1,
605     MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
606     MPI_Allreduce(MPI_IN_PLACE, &inversionPotential, 1,
607     MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
608 gezelter 1782 #endif
609    
610 gezelter 246 Snapshot* curSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
611 gezelter 1782
612     curSnapshot->setBondPotential(bondPotential);
613     curSnapshot->setBendPotential(bendPotential);
614     curSnapshot->setTorsionPotential(torsionPotential);
615     curSnapshot->setInversionPotential(inversionPotential);
616 tim 665
617 gezelter 1782 // RealType shortRangePotential = bondPotential + bendPotential +
618     // torsionPotential + inversionPotential;
619    
620     // curSnapshot->setShortRangePotential(shortRangePotential);
621 gezelter 507 }
622 gezelter 1126
623 gezelter 1782 void ForceManager::longRangeInteractions() {
624 gezelter 246
625 gezelter 1782 Snapshot* curSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
626     DataStorage* config = &(curSnapshot->atomData);
627     DataStorage* cgConfig = &(curSnapshot->cgData);
628    
629 gezelter 246 //calculate the center of mass of cutoff group
630 gezelter 1782
631 gezelter 246 SimInfo::MoleculeIterator mi;
632     Molecule* mol;
633     Molecule::CutoffGroupIterator ci;
634     CutoffGroup* cg;
635 gezelter 2057
636     if(info_->getNCutoffGroups() != info_->getNAtoms()){
637 gezelter 1126 for (mol = info_->beginMolecule(mi); mol != NULL;
638     mol = info_->nextMolecule(mi)) {
639     for(cg = mol->beginCutoffGroup(ci); cg != NULL;
640     cg = mol->nextCutoffGroup(ci)) {
641 gezelter 1782 cg->updateCOM();
642 gezelter 246 }
643 gezelter 1782 }
644 gezelter 246 } else {
645 gezelter 1126 // center of mass of the group is the same as position of the atom
646     // if cutoff group does not exist
647 gezelter 1782 cgConfig->position = config->position;
648     cgConfig->velocity = config->velocity;
649 gezelter 246 }
650 gezelter 1782
651     fDecomp_->zeroWorkArrays();
652     fDecomp_->distributeData();
653 gezelter 1126
654 gezelter 1782 int cg1, cg2, atom1, atom2, topoDist;
655     Vector3d d_grp, dag, d, gvel2, vel2;
656     RealType rgrpsq, rgrp, r2, r;
657     RealType electroMult, vdwMult;
658     RealType vij;
659     Vector3d fij, fg, f1;
660     bool in_switching_region;
661     RealType sw, dswdr, swderiv;
662 gezelter 1879 vector<int> atomListColumn, atomListRow;
663 gezelter 1782 InteractionData idat;
664     SelfData sdat;
665     RealType mf;
666     RealType vpair;
667     RealType dVdFQ1(0.0);
668     RealType dVdFQ2(0.0);
669     potVec longRangePotential(0.0);
670 gezelter 1925 RealType reciprocalPotential(0.0);
671 gezelter 1782 potVec workPot(0.0);
672     potVec exPot(0.0);
673 gezelter 1880 Vector3d eField1(0.0);
674     Vector3d eField2(0.0);
675 gezelter 1993 RealType sPot1(0.0);
676     RealType sPot2(0.0);
677 gezelter 2057 bool newAtom1;
678 gezelter 1993
679 gezelter 1782 vector<int>::iterator ia, jb;
680 gezelter 246
681 gezelter 1782 int loopStart, loopEnd;
682 gezelter 1895
683 gezelter 2057 idat.rcut = &rCut_;
684 gezelter 1782 idat.vdwMult = &vdwMult;
685     idat.electroMult = &electroMult;
686     idat.pot = &workPot;
687     idat.excludedPot = &exPot;
688     sdat.pot = fDecomp_->getEmbeddingPotential();
689     sdat.excludedPot = fDecomp_->getExcludedSelfPotential();
690     idat.vpair = &vpair;
691     idat.dVdFQ1 = &dVdFQ1;
692     idat.dVdFQ2 = &dVdFQ2;
693 gezelter 1788 idat.eField1 = &eField1;
694 gezelter 1993 idat.eField2 = &eField2;
695     idat.sPot1 = &sPot1;
696     idat.sPot2 = &sPot2;
697 gezelter 1782 idat.f1 = &f1;
698     idat.sw = &sw;
699     idat.shiftedPot = (cutoffMethod_ == SHIFTED_POTENTIAL) ? true : false;
700 gezelter 2033 idat.shiftedForce = (cutoffMethod_ == SHIFTED_FORCE ||
701     cutoffMethod_ == TAYLOR_SHIFTED) ? true : false;
702 gezelter 1782 idat.doParticlePot = doParticlePot_;
703 gezelter 1879 idat.doElectricField = doElectricField_;
704 gezelter 1993 idat.doSitePotential = doSitePotential_;
705 gezelter 1782 sdat.doParticlePot = doParticlePot_;
706    
707     loopEnd = PAIR_LOOP;
708     if (info_->requiresPrepair() ) {
709     loopStart = PREPAIR_LOOP;
710     } else {
711     loopStart = PAIR_LOOP;
712 chuckv 664 }
713 gezelter 1782 for (int iLoop = loopStart; iLoop <= loopEnd; iLoop++) {
714 gezelter 1126
715 gezelter 1782 if (iLoop == loopStart) {
716     bool update_nlist = fDecomp_->checkNeighborList();
717 gezelter 1879 if (update_nlist) {
718     if (!usePeriodicBoundaryConditions_)
719     Mat3x3d bbox = thermo->getBoundingBox();
720 gezelter 2057 fDecomp_->buildNeighborList(neighborList_, point_);
721 gezelter 1879 }
722     }
723 gezelter 1782
724 gezelter 2067 for (cg1 = 0; cg1 < int(point_.size()) - 1; cg1++) {
725 gezelter 1782
726 gezelter 2057 atomListRow = fDecomp_->getAtomsInGroupRow(cg1);
727     newAtom1 = true;
728    
729     for (int m2 = point_[cg1]; m2 < point_[cg1+1]; m2++) {
730 gezelter 1782
731 gezelter 2057 cg2 = neighborList_[m2];
732 gezelter 1782
733 gezelter 2057 d_grp = fDecomp_->getIntergroupVector(cg1, cg2);
734    
735     // already wrapped in the getIntergroupVector call:
736     // curSnapshot->wrapVector(d_grp);
737     rgrpsq = d_grp.lengthSquare();
738    
739     if (rgrpsq < rCutSq_) {
740     if (iLoop == PAIR_LOOP) {
741     vij = 0.0;
742     fij.zero();
743     eField1.zero();
744     eField2.zero();
745     sPot1 = 0.0;
746     sPot2 = 0.0;
747     }
748    
749     in_switching_region = switcher_->getSwitch(rgrpsq, sw, dswdr,
750     rgrp);
751    
752     atomListColumn = fDecomp_->getAtomsInGroupColumn(cg2);
753    
754     if (doHeatFlux_)
755     gvel2 = fDecomp_->getGroupVelocityColumn(cg2);
756    
757     for (ia = atomListRow.begin();
758     ia != atomListRow.end(); ++ia) {
759     atom1 = (*ia);
760    
761     for (jb = atomListColumn.begin();
762     jb != atomListColumn.end(); ++jb) {
763     atom2 = (*jb);
764    
765     if (!fDecomp_->skipAtomPair(atom1, atom2, cg1, cg2)) {
766    
767     vpair = 0.0;
768     workPot = 0.0;
769     exPot = 0.0;
770     f1.zero();
771     dVdFQ1 = 0.0;
772     dVdFQ2 = 0.0;
773    
774     fDecomp_->fillInteractionData(idat, atom1, atom2, newAtom1);
775    
776     topoDist = fDecomp_->getTopologicalDistance(atom1, atom2);
777     vdwMult = vdwScale_[topoDist];
778     electroMult = electrostaticScale_[topoDist];
779    
780     if (atomListRow.size() == 1 && atomListColumn.size() == 1) {
781     idat.d = &d_grp;
782     idat.r2 = &rgrpsq;
783     if (doHeatFlux_)
784     vel2 = gvel2;
785     } else {
786     d = fDecomp_->getInteratomicVector(atom1, atom2);
787     curSnapshot->wrapVector( d );
788     r2 = d.lengthSquare();
789     idat.d = &d;
790     idat.r2 = &r2;
791     if (doHeatFlux_)
792     vel2 = fDecomp_->getAtomVelocityColumn(atom2);
793     }
794    
795     r = sqrt( *(idat.r2) );
796     idat.rij = &r;
797    
798     if (iLoop == PREPAIR_LOOP) {
799     interactionMan_->doPrePair(idat);
800     } else {
801     interactionMan_->doPair(idat);
802     fDecomp_->unpackInteractionData(idat, atom1, atom2);
803     vij += vpair;
804     fij += f1;
805     stressTensor -= outProduct( *(idat.d), f1);
806     if (doHeatFlux_)
807     fDecomp_->addToHeatFlux(*(idat.d) * dot(f1, vel2));
808     }
809 gezelter 1782 }
810     }
811     }
812 gezelter 2057
813     if (iLoop == PAIR_LOOP) {
814     if (in_switching_region) {
815     swderiv = vij * dswdr / rgrp;
816     fg = swderiv * d_grp;
817     fij += fg;
818    
819     if (atomListRow.size() == 1 && atomListColumn.size() == 1) {
820     if (!fDecomp_->skipAtomPair(atomListRow[0],
821     atomListColumn[0],
822     cg1, cg2)) {
823 gezelter 1809 stressTensor -= outProduct( *(idat.d), fg);
824     if (doHeatFlux_)
825     fDecomp_->addToHeatFlux(*(idat.d) * dot(fg, vel2));
826 gezelter 2057 }
827     }
828    
829     for (ia = atomListRow.begin();
830     ia != atomListRow.end(); ++ia) {
831     atom1 = (*ia);
832     mf = fDecomp_->getMassFactorRow(atom1);
833     // fg is the force on atom ia due to cutoff group's
834     // presence in switching region
835     fg = swderiv * d_grp * mf;
836     fDecomp_->addForceToAtomRow(atom1, fg);
837     if (atomListRow.size() > 1) {
838     if (info_->usesAtomicVirial()) {
839     // find the distance between the atom
840     // and the center of the cutoff group:
841     dag = fDecomp_->getAtomToGroupVectorRow(atom1, cg1);
842     stressTensor -= outProduct(dag, fg);
843     if (doHeatFlux_)
844     fDecomp_->addToHeatFlux( dag * dot(fg, vel2));
845     }
846 gezelter 1782 }
847     }
848 gezelter 2057 for (jb = atomListColumn.begin();
849     jb != atomListColumn.end(); ++jb) {
850     atom2 = (*jb);
851     mf = fDecomp_->getMassFactorColumn(atom2);
852     // fg is the force on atom jb due to cutoff group's
853     // presence in switching region
854     fg = -swderiv * d_grp * mf;
855     fDecomp_->addForceToAtomColumn(atom2, fg);
856    
857     if (atomListColumn.size() > 1) {
858     if (info_->usesAtomicVirial()) {
859     // find the distance between the atom
860     // and the center of the cutoff group:
861     dag = fDecomp_->getAtomToGroupVectorColumn(atom2, cg2);
862     stressTensor -= outProduct(dag, fg);
863     if (doHeatFlux_)
864     fDecomp_->addToHeatFlux( dag * dot(fg, vel2));
865     }
866 gezelter 1782 }
867     }
868     }
869 gezelter 2057 //if (!info_->usesAtomicVirial()) {
870     // stressTensor -= outProduct(d_grp, fij);
871     // if (doHeatFlux_)
872     // fDecomp_->addToHeatFlux( d_grp * dot(fij, vel2));
873     //}
874 gezelter 1782 }
875     }
876     }
877 gezelter 2057 newAtom1 = false;
878 gezelter 1782 }
879 gezelter 2057
880 gezelter 1782 if (iLoop == PREPAIR_LOOP) {
881     if (info_->requiresPrepair()) {
882 gezelter 2057
883 gezelter 1782 fDecomp_->collectIntermediateData();
884 gezelter 2057
885 gezelter 1782 for (unsigned int atom1 = 0; atom1 < info_->getNAtoms(); atom1++) {
886     fDecomp_->fillSelfData(sdat, atom1);
887     interactionMan_->doPreForce(sdat);
888     }
889 gezelter 2057
890 gezelter 1782 fDecomp_->distributeIntermediateData();
891 gezelter 2057
892 gezelter 1782 }
893     }
894 gezelter 246 }
895 gezelter 1880
896 gezelter 1782 // collects pairwise information
897     fDecomp_->collectData();
898 gezelter 1915 if (cutoffMethod_ == EWALD_FULL) {
899 gezelter 1923 interactionMan_->doReciprocalSpaceSum(reciprocalPotential);
900 gezelter 1925
901     curSnapshot->setReciprocalPotential(reciprocalPotential);
902 gezelter 1915 }
903 gezelter 1782
904     if (info_->requiresSelfCorrection()) {
905     for (unsigned int atom1 = 0; atom1 < info_->getNAtoms(); atom1++) {
906     fDecomp_->fillSelfData(sdat, atom1);
907     interactionMan_->doSelfCorrection(sdat);
908     }
909 chrisfen 998 }
910 gezelter 1782
911     // collects single-atom information
912     fDecomp_->collectSelfData();
913    
914     longRangePotential = *(fDecomp_->getEmbeddingPotential()) +
915 gezelter 1925 *(fDecomp_->getPairwisePotential());
916 gezelter 1782
917     curSnapshot->setLongRangePotential(longRangePotential);
918 gezelter 1126
919 gezelter 1782 curSnapshot->setExcludedPotentials(*(fDecomp_->getExcludedSelfPotential()) +
920 gezelter 2033 *(fDecomp_->getExcludedPotential()));
921 gezelter 1782
922 gezelter 507 }
923 gezelter 246
924 gezelter 1464 void ForceManager::postCalculation() {
925 gezelter 1782
926     vector<Perturbation*>::iterator pi;
927     for (pi = perturbations_.begin(); pi != perturbations_.end(); ++pi) {
928     (*pi)->applyPerturbation();
929     }
930    
931 gezelter 246 SimInfo::MoleculeIterator mi;
932     Molecule* mol;
933     Molecule::RigidBodyIterator rbIter;
934     RigidBody* rb;
935 gezelter 1126 Snapshot* curSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
936 gezelter 1782
937 gezelter 246 // collect the atomic forces onto rigid bodies
938 gezelter 1126
939     for (mol = info_->beginMolecule(mi); mol != NULL;
940     mol = info_->nextMolecule(mi)) {
941     for (rb = mol->beginRigidBody(rbIter); rb != NULL;
942     rb = mol->nextRigidBody(rbIter)) {
943 gezelter 1464 Mat3x3d rbTau = rb->calcForcesAndTorquesAndVirial();
944 gezelter 1782 stressTensor += rbTau;
945 gezelter 507 }
946 gezelter 1126 }
947 gezelter 1464
948 gezelter 1126 #ifdef IS_MPI
949 gezelter 1969 MPI_Allreduce(MPI_IN_PLACE, stressTensor.getArrayPointer(), 9,
950 gezelter 1987 MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
951 gezelter 1126 #endif
952 gezelter 1782 curSnapshot->setStressTensor(stressTensor);
953    
954 gezelter 1879 if (info_->getSimParams()->getUseLongRangeCorrections()) {
955     /*
956 gezelter 2033 RealType vol = curSnapshot->getVolume();
957     RealType Elrc(0.0);
958     RealType Wlrc(0.0);
959 gezelter 1879
960 gezelter 2033 set<AtomType*>::iterator i;
961     set<AtomType*>::iterator j;
962 gezelter 1879
963 gezelter 2033 RealType n_i, n_j;
964     RealType rho_i, rho_j;
965     pair<RealType, RealType> LRI;
966 gezelter 1879
967 gezelter 2033 for (i = atomTypes_.begin(); i != atomTypes_.end(); ++i) {
968 gezelter 1879 n_i = RealType(info_->getGlobalCountOfType(*i));
969     rho_i = n_i / vol;
970     for (j = atomTypes_.begin(); j != atomTypes_.end(); ++j) {
971 gezelter 2033 n_j = RealType(info_->getGlobalCountOfType(*j));
972     rho_j = n_j / vol;
973 gezelter 1879
974 gezelter 2033 LRI = interactionMan_->getLongRangeIntegrals( (*i), (*j) );
975 gezelter 1879
976 gezelter 2033 Elrc += n_i * rho_j * LRI.first;
977     Wlrc -= rho_i * rho_j * LRI.second;
978 gezelter 1879 }
979 gezelter 2033 }
980     Elrc *= 2.0 * NumericConstant::PI;
981     Wlrc *= 2.0 * NumericConstant::PI;
982 gezelter 1879
983 gezelter 2033 RealType lrp = curSnapshot->getLongRangePotential();
984     curSnapshot->setLongRangePotential(lrp + Elrc);
985     stressTensor += Wlrc * SquareMatrix3<RealType>::identity();
986     curSnapshot->setStressTensor(stressTensor);
987 gezelter 1879 */
988    
989     }
990 gezelter 507 }
991 gezelter 1879 }

Properties

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