ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/devel_omp/src/nonbonded/LJ.cpp
Revision: 1614
Committed: Tue Aug 23 20:55:51 2011 UTC (13 years, 9 months ago) by mciznick
File size: 10671 byte(s)
Log Message:
Updated scalability of OpenMP threads.

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 #include <stdio.h>
43 #include <string.h>
44
45 #include <cmath>
46 #include "nonbonded/LJ.hpp"
47 #include "utils/simError.h"
48
49 namespace OpenMD {
50
51 LJ::LJ() : name_("LJ"), initialized_(false), forceField_(NULL) {}
52
53 LJParam LJ::getLJParam(AtomType* atomType) {
54
55 // Do sanity checking on the AtomType we were passed before
56 // building any data structures:
57 if (!atomType->isLennardJones()) {
58 sprintf( painCave.errMsg,
59 "LJ::getLJParam was passed an atomType (%s) that does not\n"
60 "\tappear to be a Lennard-Jones atom.\n",
61 atomType->getName().c_str());
62 painCave.severity = OPENMD_ERROR;
63 painCave.isFatal = 1;
64 simError();
65 }
66
67 GenericData* data = atomType->getPropertyByName("LennardJones");
68 if (data == NULL) {
69 sprintf( painCave.errMsg, "LJ::getLJParam could not find Lennard-Jones\n"
70 "\tparameters for atomType %s.\n", atomType->getName().c_str());
71 painCave.severity = OPENMD_ERROR;
72 painCave.isFatal = 1;
73 simError();
74 }
75
76 LJParamGenericData* ljData = dynamic_cast<LJParamGenericData*>(data);
77 if (ljData == NULL) {
78 sprintf( painCave.errMsg,
79 "LJ::getLJParam could not convert GenericData to LJParam for\n"
80 "\tatom type %s\n", atomType->getName().c_str());
81 painCave.severity = OPENMD_ERROR;
82 painCave.isFatal = 1;
83 simError();
84 }
85
86 return ljData->getData();
87 }
88
89 RealType LJ::getSigma(AtomType* atomType) {
90 LJParam ljParam = getLJParam(atomType);
91 return ljParam.sigma;
92 }
93
94 RealType LJ::getSigma(AtomType* atomType1, AtomType* atomType2) {
95 RealType sigma1 = getSigma(atomType1);
96 RealType sigma2 = getSigma(atomType2);
97
98 ForceFieldOptions& fopts = forceField_->getForceFieldOptions();
99 string DistanceMix = fopts.getDistanceMixingRule();
100 toUpper(DistanceMix);
101
102 if (DistanceMix == "GEOMETRIC")
103 return sqrt(sigma1 * sigma2);
104 else
105 return 0.5 * (sigma1 + sigma2);
106 }
107
108 RealType LJ::getEpsilon(AtomType* atomType) {
109 LJParam ljParam = getLJParam(atomType);
110 return ljParam.epsilon;
111 }
112
113 RealType LJ::getEpsilon(AtomType* atomType1, AtomType* atomType2) {
114 RealType epsilon1 = getEpsilon(atomType1);
115 RealType epsilon2 = getEpsilon(atomType2);
116 return sqrt(epsilon1 * epsilon2);
117 }
118
119 void LJ::initialize() {
120 ForceField::AtomTypeContainer* atomTypes = forceField_->getAtomTypes();
121 ForceField::AtomTypeContainer::MapTypeIterator i;
122 AtomType* at;
123
124 for (at = atomTypes->beginType(i); at != NULL;
125 at = atomTypes->nextType(i)) {
126
127 if (at->isLennardJones())
128 addType(at);
129 }
130
131 ForceField::NonBondedInteractionTypeContainer* nbiTypes = forceField_->getNonBondedInteractionTypes();
132 ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
133 NonBondedInteractionType* nbt;
134
135 for (nbt = nbiTypes->beginType(j); nbt != NULL;
136 nbt = nbiTypes->nextType(j)) {
137
138 if (nbt->isLennardJones()) {
139
140 pair<AtomType*, AtomType*> atypes = nbt->getAtomTypes();
141
142 GenericData* data = nbt->getPropertyByName("LennardJones");
143 if (data == NULL) {
144 sprintf( painCave.errMsg, "LJ::rebuildMixingMap could not find\n"
145 "\tLennard-Jones parameters for %s - %s interaction.\n",
146 atypes.first->getName().c_str(),
147 atypes.second->getName().c_str());
148 painCave.severity = OPENMD_ERROR;
149 painCave.isFatal = 1;
150 simError();
151 }
152
153 LJParamGenericData* ljData = dynamic_cast<LJParamGenericData*>(data);
154 if (ljData == NULL) {
155 sprintf( painCave.errMsg,
156 "LJ::rebuildMixingMap could not convert GenericData to\n"
157 "\tLJParam for %s - %s interaction.\n",
158 atypes.first->getName().c_str(),
159 atypes.second->getName().c_str());
160 painCave.severity = OPENMD_ERROR;
161 painCave.isFatal = 1;
162 simError();
163 }
164
165 LJParam ljParam = ljData->getData();
166
167 RealType sigma = ljParam.sigma;
168 RealType epsilon = ljParam.epsilon;
169
170 addExplicitInteraction(atypes.first, atypes.second, sigma, epsilon);
171 }
172 }
173 initialized_ = true;
174 }
175
176
177
178 void LJ::addType(AtomType* atomType){
179 RealType sigma1 = getSigma(atomType);
180 RealType epsilon1 = getEpsilon(atomType);
181
182 // add it to the map:
183 AtomTypeProperties atp = atomType->getATP();
184
185 pair<map<int,AtomType*>::iterator,bool> ret;
186 ret = LJMap.insert( pair<int, AtomType*>(atp.ident, atomType) );
187 if (ret.second == false) {
188 sprintf( painCave.errMsg,
189 "LJ already had a previous entry with ident %d\n",
190 atp.ident);
191 painCave.severity = OPENMD_INFO;
192 painCave.isFatal = 0;
193 simError();
194 }
195
196 // Now, iterate over all known types and add to the mixing map:
197
198 std::map<int, AtomType*>::iterator it;
199 for( it = LJMap.begin(); it != LJMap.end(); ++it) {
200
201 AtomType* atype2 = (*it).second;
202
203 LJInteractionData mixer;
204 mixer.sigma = getSigma(atomType, atype2);
205 mixer.epsilon = getEpsilon(atomType, atype2);
206 mixer.sigmai = 1.0 / mixer.sigma;
207 mixer.explicitlySet = false;
208
209 std::pair<AtomType*, AtomType*> key1, key2;
210 key1 = std::make_pair(atomType, atype2);
211 key2 = std::make_pair(atype2, atomType);
212
213 MixingMap[key1] = mixer;
214 if (key2 != key1) {
215 MixingMap[key2] = mixer;
216 }
217 }
218 }
219
220 void LJ::addExplicitInteraction(AtomType* atype1, AtomType* atype2, RealType sigma, RealType epsilon){
221
222 // in case these weren't already in the map
223 addType(atype1);
224 addType(atype2);
225
226 LJInteractionData mixer;
227 mixer.sigma = sigma;
228 mixer.epsilon = epsilon;
229 mixer.sigmai = 1.0 / mixer.sigma;
230 mixer.explicitlySet = true;
231
232 std::pair<AtomType*, AtomType*> key1, key2;
233 key1 = std::make_pair(atype1, atype2);
234 key2 = std::make_pair(atype2, atype1);
235
236 MixingMap[key1] = mixer;
237 if (key2 != key1) {
238 MixingMap[key2] = mixer;
239 }
240 }
241
242 void LJ::initForce() {
243 if (!initialized_) initialize();
244 }
245
246 void LJ::calcForce(InteractionData &idat) {
247 // #pragma omp critical (LJLck)
248 {
249 // if (!initialized_) initialize();
250 }
251
252 map<pair<AtomType*, AtomType*>, LJInteractionData>::iterator it;
253 it = MixingMap.find( idat.atypes );
254
255 if (it != MixingMap.end()) {
256
257 LJInteractionData mixer = (*it).second;
258
259 RealType sigmai = mixer.sigmai;
260 RealType epsilon = mixer.epsilon;
261
262 RealType ros;
263 RealType rcos;
264 RealType myPot = 0.0;
265 RealType myPotC = 0.0;
266 RealType myDeriv = 0.0;
267 RealType myDerivC = 0.0;
268
269 ros = *(idat.rij) * sigmai;
270
271 getLJfunc(ros, myPot, myDeriv);
272
273 if (idat.shiftedPot) {
274 rcos = *(idat.rcut) * sigmai;
275 getLJfunc(rcos, myPotC, myDerivC);
276 myDerivC = 0.0;
277 } else if (idat.shiftedForce) {
278 rcos = *(idat.rcut) * sigmai;
279 getLJfunc(rcos, myPotC, myDerivC);
280 myPotC = myPotC + myDerivC * (*(idat.rij) - *(idat.rcut)) * sigmai;
281 } else {
282 myPotC = 0.0;
283 myDerivC = 0.0;
284 }
285
286 RealType pot_temp = *(idat.vdwMult) * epsilon * (myPot - myPotC);
287 *(idat.vpair) += pot_temp;
288
289 RealType dudr = *(idat.sw) * *(idat.vdwMult) * epsilon * (myDeriv -
290 myDerivC)*sigmai;
291
292 (*(idat.pot))[VANDERWAALS_FAMILY] += *(idat.sw) * pot_temp;
293 *(idat.f1) = *(idat.d) * dudr / *(idat.rij);
294 }
295 return;
296 }
297
298 void LJ::getLJfunc(RealType r, RealType &pot, RealType &deriv) {
299
300 RealType ri = 1.0 / r;
301 RealType ri2 = ri * ri;
302 RealType ri6 = ri2 * ri2 * ri2;
303 RealType ri7 = ri6 * ri;
304 RealType ri12 = ri6 * ri6;
305 RealType ri13 = ri12 * ri;
306
307 pot = 4.0 * (ri12 - ri6);
308 deriv = 24.0 * (ri7 - 2.0 * ri13);
309
310 return;
311 }
312
313 RealType LJ::getSuggestedCutoffRadius(pair<AtomType*, AtomType*> atypes) {
314 if (!initialized_) initialize();
315 map<pair<AtomType*, AtomType*>, LJInteractionData>::iterator it;
316 it = MixingMap.find(atypes);
317 if (it == MixingMap.end())
318 return 0.0;
319 else {
320 LJInteractionData mixer = (*it).second;
321 return 2.5 * mixer.sigma;
322 }
323 }
324
325 }

Properties

Name Value
svn:eol-style native