ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/brains/ForceManager.cpp
Revision: 1469
Committed: Mon Jul 19 14:07:59 2010 UTC (14 years, 9 months ago) by gezelter
File size: 12938 byte(s)
Log Message:
attempts at c++->fortran linkage.  Still busticated.

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

Properties

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