ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/brains/ForceManager.cpp
Revision: 1480
Committed: Mon Jul 26 19:50:53 2010 UTC (14 years, 10 months ago) by gezelter
File size: 12885 byte(s)
Log Message:
no longer segfaults

File Contents

# Content
1 /*
2 * 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 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * 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 *
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 * [4] Vardeman & Gezelter, in progress (2009).
40 */
41
42 /**
43 * @file ForceManager.cpp
44 * @author tlin
45 * @date 11/09/2004
46 * @time 10:39am
47 * @version 1.0
48 */
49
50 #include "brains/ForceManager.hpp"
51 #include "primitives/Molecule.hpp"
52 #include "UseTheForce/doForces_interface.h"
53 #define __OPENMD_C
54 #include "UseTheForce/DarkSide/fInteractionMap.h"
55 #include "utils/simError.h"
56 #include "primitives/Bond.hpp"
57 #include "primitives/Bend.hpp"
58 #include "primitives/Torsion.hpp"
59 #include "primitives/Inversion.hpp"
60
61 namespace OpenMD {
62
63 ForceManager::ForceManager(SimInfo * info) : info_(info),
64 NBforcesInitialized_(false) {
65 lj_ = LJ::Instance();
66 lj_->setForceField(info_->getForceField());
67
68 eam_ = EAM::Instance();
69 eam_->setForceField(info_->getForceField());
70 }
71
72 void ForceManager::calcForces() {
73
74 if (!info_->isFortranInitialized()) {
75 info_->update();
76 }
77
78 preCalculation();
79
80 calcShortRangeInteraction();
81
82 calcLongRangeInteraction();
83
84 postCalculation();
85
86 }
87
88 void ForceManager::preCalculation() {
89 SimInfo::MoleculeIterator mi;
90 Molecule* mol;
91 Molecule::AtomIterator ai;
92 Atom* atom;
93 Molecule::RigidBodyIterator rbIter;
94 RigidBody* rb;
95
96 // forces are zeroed here, before any are accumulated.
97 // NOTE: do not rezero the forces in Fortran.
98
99 for (mol = info_->beginMolecule(mi); mol != NULL;
100 mol = info_->nextMolecule(mi)) {
101 for(atom = mol->beginAtom(ai); atom != NULL; atom = mol->nextAtom(ai)) {
102 atom->zeroForcesAndTorques();
103 }
104
105 //change the positions of atoms which belong to the rigidbodies
106 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
107 rb = mol->nextRigidBody(rbIter)) {
108 rb->zeroForcesAndTorques();
109 }
110
111 }
112
113 // Zero out the stress tensor
114 tau *= 0.0;
115
116 }
117
118 void ForceManager::calcShortRangeInteraction() {
119 Molecule* mol;
120 RigidBody* rb;
121 Bond* bond;
122 Bend* bend;
123 Torsion* torsion;
124 Inversion* inversion;
125 SimInfo::MoleculeIterator mi;
126 Molecule::RigidBodyIterator rbIter;
127 Molecule::BondIterator bondIter;;
128 Molecule::BendIterator bendIter;
129 Molecule::TorsionIterator torsionIter;
130 Molecule::InversionIterator inversionIter;
131 RealType bondPotential = 0.0;
132 RealType bendPotential = 0.0;
133 RealType torsionPotential = 0.0;
134 RealType inversionPotential = 0.0;
135
136 //calculate short range interactions
137 for (mol = info_->beginMolecule(mi); mol != NULL;
138 mol = info_->nextMolecule(mi)) {
139
140 //change the positions of atoms which belong to the rigidbodies
141 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
142 rb = mol->nextRigidBody(rbIter)) {
143 rb->updateAtoms();
144 }
145
146 for (bond = mol->beginBond(bondIter); bond != NULL;
147 bond = mol->nextBond(bondIter)) {
148 bond->calcForce();
149 bondPotential += bond->getPotential();
150 }
151
152 for (bend = mol->beginBend(bendIter); bend != NULL;
153 bend = mol->nextBend(bendIter)) {
154
155 RealType angle;
156 bend->calcForce(angle);
157 RealType currBendPot = bend->getPotential();
158
159 bendPotential += bend->getPotential();
160 std::map<Bend*, BendDataSet>::iterator i = bendDataSets.find(bend);
161 if (i == bendDataSets.end()) {
162 BendDataSet dataSet;
163 dataSet.prev.angle = dataSet.curr.angle = angle;
164 dataSet.prev.potential = dataSet.curr.potential = currBendPot;
165 dataSet.deltaV = 0.0;
166 bendDataSets.insert(std::map<Bend*, BendDataSet>::value_type(bend, dataSet));
167 }else {
168 i->second.prev.angle = i->second.curr.angle;
169 i->second.prev.potential = i->second.curr.potential;
170 i->second.curr.angle = angle;
171 i->second.curr.potential = currBendPot;
172 i->second.deltaV = fabs(i->second.curr.potential -
173 i->second.prev.potential);
174 }
175 }
176
177 for (torsion = mol->beginTorsion(torsionIter); torsion != NULL;
178 torsion = mol->nextTorsion(torsionIter)) {
179 RealType angle;
180 torsion->calcForce(angle);
181 RealType currTorsionPot = torsion->getPotential();
182 torsionPotential += torsion->getPotential();
183 std::map<Torsion*, TorsionDataSet>::iterator i = torsionDataSets.find(torsion);
184 if (i == torsionDataSets.end()) {
185 TorsionDataSet dataSet;
186 dataSet.prev.angle = dataSet.curr.angle = angle;
187 dataSet.prev.potential = dataSet.curr.potential = currTorsionPot;
188 dataSet.deltaV = 0.0;
189 torsionDataSets.insert(std::map<Torsion*, TorsionDataSet>::value_type(torsion, dataSet));
190 }else {
191 i->second.prev.angle = i->second.curr.angle;
192 i->second.prev.potential = i->second.curr.potential;
193 i->second.curr.angle = angle;
194 i->second.curr.potential = currTorsionPot;
195 i->second.deltaV = fabs(i->second.curr.potential -
196 i->second.prev.potential);
197 }
198 }
199
200 for (inversion = mol->beginInversion(inversionIter);
201 inversion != NULL;
202 inversion = mol->nextInversion(inversionIter)) {
203 RealType angle;
204 inversion->calcForce(angle);
205 RealType currInversionPot = inversion->getPotential();
206 inversionPotential += inversion->getPotential();
207 std::map<Inversion*, InversionDataSet>::iterator i = inversionDataSets.find(inversion);
208 if (i == inversionDataSets.end()) {
209 InversionDataSet dataSet;
210 dataSet.prev.angle = dataSet.curr.angle = angle;
211 dataSet.prev.potential = dataSet.curr.potential = currInversionPot;
212 dataSet.deltaV = 0.0;
213 inversionDataSets.insert(std::map<Inversion*, InversionDataSet>::value_type(inversion, dataSet));
214 }else {
215 i->second.prev.angle = i->second.curr.angle;
216 i->second.prev.potential = i->second.curr.potential;
217 i->second.curr.angle = angle;
218 i->second.curr.potential = currInversionPot;
219 i->second.deltaV = fabs(i->second.curr.potential -
220 i->second.prev.potential);
221 }
222 }
223 }
224
225 RealType shortRangePotential = bondPotential + bendPotential +
226 torsionPotential + inversionPotential;
227 Snapshot* curSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
228 curSnapshot->statData[Stats::SHORT_RANGE_POTENTIAL] = shortRangePotential;
229 curSnapshot->statData[Stats::BOND_POTENTIAL] = bondPotential;
230 curSnapshot->statData[Stats::BEND_POTENTIAL] = bendPotential;
231 curSnapshot->statData[Stats::DIHEDRAL_POTENTIAL] = torsionPotential;
232 curSnapshot->statData[Stats::INVERSION_POTENTIAL] = inversionPotential;
233
234 }
235
236 void ForceManager::calcLongRangeInteraction() {
237 Snapshot* curSnapshot;
238 DataStorage* config;
239 RealType* frc;
240 RealType* pos;
241 RealType* trq;
242 RealType* A;
243 RealType* electroFrame;
244 RealType* rc;
245 RealType* particlePot;
246
247 //get current snapshot from SimInfo
248 curSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
249
250 //get array pointers
251 config = &(curSnapshot->atomData);
252 frc = config->getArrayPointer(DataStorage::dslForce);
253 pos = config->getArrayPointer(DataStorage::dslPosition);
254 trq = config->getArrayPointer(DataStorage::dslTorque);
255 A = config->getArrayPointer(DataStorage::dslAmat);
256 electroFrame = config->getArrayPointer(DataStorage::dslElectroFrame);
257 particlePot = config->getArrayPointer(DataStorage::dslParticlePot);
258
259 //calculate the center of mass of cutoff group
260 SimInfo::MoleculeIterator mi;
261 Molecule* mol;
262 Molecule::CutoffGroupIterator ci;
263 CutoffGroup* cg;
264 Vector3d com;
265 std::vector<Vector3d> rcGroup;
266
267 if(info_->getNCutoffGroups() > 0){
268
269 for (mol = info_->beginMolecule(mi); mol != NULL;
270 mol = info_->nextMolecule(mi)) {
271 for(cg = mol->beginCutoffGroup(ci); cg != NULL;
272 cg = mol->nextCutoffGroup(ci)) {
273 cg->getCOM(com);
274 rcGroup.push_back(com);
275 }
276 }// end for (mol)
277
278 rc = rcGroup[0].getArrayPointer();
279 } else {
280 // center of mass of the group is the same as position of the atom
281 // if cutoff group does not exist
282 rc = pos;
283 }
284
285 //initialize data before passing to fortran
286 RealType longRangePotential[LR_POT_TYPES];
287 RealType lrPot = 0.0;
288 Vector3d totalDipole;
289 int isError = 0;
290
291 for (int i=0; i<LR_POT_TYPES;i++){
292 longRangePotential[i]=0.0; //Initialize array
293 }
294
295 doForceLoop(pos,
296 rc,
297 A,
298 electroFrame,
299 frc,
300 trq,
301 tau.getArrayPointer(),
302 longRangePotential,
303 particlePot,
304 &isError );
305
306 if( isError ){
307 sprintf( painCave.errMsg,
308 "Error returned from the fortran force calculation.\n" );
309 painCave.isFatal = 1;
310 simError();
311 }
312 for (int i=0; i<LR_POT_TYPES;i++){
313 lrPot += longRangePotential[i]; //Quick hack
314 }
315
316 // grab the simulation box dipole moment if specified
317 if (info_->getCalcBoxDipole()){
318 getAccumulatedBoxDipole(totalDipole.getArrayPointer());
319
320 curSnapshot->statData[Stats::BOX_DIPOLE_X] = totalDipole(0);
321 curSnapshot->statData[Stats::BOX_DIPOLE_Y] = totalDipole(1);
322 curSnapshot->statData[Stats::BOX_DIPOLE_Z] = totalDipole(2);
323 }
324
325 //store the tau and long range potential
326 curSnapshot->statData[Stats::LONG_RANGE_POTENTIAL] = lrPot;
327 curSnapshot->statData[Stats::VANDERWAALS_POTENTIAL] = longRangePotential[VDW_POT];
328 curSnapshot->statData[Stats::ELECTROSTATIC_POTENTIAL] = longRangePotential[ELECTROSTATIC_POT];
329 }
330
331
332 void ForceManager::postCalculation() {
333 SimInfo::MoleculeIterator mi;
334 Molecule* mol;
335 Molecule::RigidBodyIterator rbIter;
336 RigidBody* rb;
337 Snapshot* curSnapshot = info_->getSnapshotManager()->getCurrentSnapshot();
338
339 // collect the atomic forces onto rigid bodies
340
341 for (mol = info_->beginMolecule(mi); mol != NULL;
342 mol = info_->nextMolecule(mi)) {
343 for (rb = mol->beginRigidBody(rbIter); rb != NULL;
344 rb = mol->nextRigidBody(rbIter)) {
345 Mat3x3d rbTau = rb->calcForcesAndTorquesAndVirial();
346 tau += rbTau;
347 }
348 }
349
350 #ifdef IS_MPI
351 Mat3x3d tmpTau(tau);
352 MPI_Allreduce(tmpTau.getArrayPointer(), tau.getArrayPointer(),
353 9, MPI_REALTYPE, MPI_SUM, MPI_COMM_WORLD);
354 #endif
355 curSnapshot->statData.setTau(tau);
356 }
357
358 } //end namespace OpenMD

Properties

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