ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/nonbonded/LJ.cpp
Revision: 1710
Committed: Fri May 18 21:44:02 2012 UTC (12 years, 11 months ago) by gezelter
File size: 9037 byte(s)
Log Message:
Added an adapter layer between the AtomType and the rest of the code to 
handle the bolt-on capabilities of new types. 

Fixed a long-standing bug in how storageLayout was being set to the maximum
possible value.

Started to add infrastructure for Polarizable and fluc-Q calculations.

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] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 */
42
43 #include <stdio.h>
44 #include <string.h>
45
46 #include <cmath>
47 #include "nonbonded/LJ.hpp"
48 #include "utils/simError.h"
49 #include "types/LennardJonesAdapter.hpp"
50 #include "types/LennardJonesInteractionType.hpp"
51
52 namespace OpenMD {
53
54 LJ::LJ() : name_("LJ"), initialized_(false), forceField_(NULL) {}
55
56 RealType LJ::getSigma(AtomType* atomType1, AtomType* atomType2) {
57
58 LennardJonesAdapter lja1 = LennardJonesAdapter(atomType1);
59 LennardJonesAdapter lja2 = LennardJonesAdapter(atomType2);
60 RealType sigma1 = lja1.getSigma();
61 RealType sigma2 = lja2.getSigma();
62
63 ForceFieldOptions& fopts = forceField_->getForceFieldOptions();
64 string DistanceMix = fopts.getDistanceMixingRule();
65 toUpper(DistanceMix);
66
67 if (DistanceMix == "GEOMETRIC")
68 return sqrt(sigma1 * sigma2);
69 else
70 return 0.5 * (sigma1 + sigma2);
71 }
72
73 RealType LJ::getEpsilon(AtomType* atomType1, AtomType* atomType2) {
74 LennardJonesAdapter lja1 = LennardJonesAdapter(atomType1);
75 LennardJonesAdapter lja2 = LennardJonesAdapter(atomType2);
76
77 RealType epsilon1 = lja1.getEpsilon();
78 RealType epsilon2 = lja2.getEpsilon();
79 return sqrt(epsilon1 * epsilon2);
80 }
81
82 void LJ::initialize() {
83 ForceField::AtomTypeContainer* atomTypes = forceField_->getAtomTypes();
84 ForceField::AtomTypeContainer::MapTypeIterator i;
85 AtomType* at;
86
87 for (at = atomTypes->beginType(i); at != NULL;
88 at = atomTypes->nextType(i)) {
89 LennardJonesAdapter lja = LennardJonesAdapter(at);
90 if (lja.isLennardJones()){
91 addType(at);
92 }
93 }
94 ForceField::NonBondedInteractionTypeContainer* nbiTypes = forceField_->getNonBondedInteractionTypes();
95 ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
96 NonBondedInteractionType* nbt;
97 ForceField::NonBondedInteractionTypeContainer::KeyType keys;
98
99
100 for (nbt = nbiTypes->beginType(j); nbt != NULL;
101 nbt = nbiTypes->nextType(j)) {
102
103 if (nbt->isLennardJones()) {
104 keys = nbiTypes->getKeys(j);
105 AtomType* at1 = forceField_->getAtomType(keys[0]);
106 AtomType* at2 = forceField_->getAtomType(keys[1]);
107
108 LennardJonesInteractionType* ljit = dynamic_cast<LennardJonesInteractionType*>(nbt);
109
110 if (ljit == NULL) {
111 sprintf( painCave.errMsg,
112 "LJ::initialize could not convert NonBondedInteractionType\n"
113 "\tto LennardJonesInteractionType for %s - %s interaction.\n",
114 at1->getName().c_str(),
115 at2->getName().c_str());
116 painCave.severity = OPENMD_ERROR;
117 painCave.isFatal = 1;
118 simError();
119 }
120
121 RealType sigma = ljit->getSigma();
122 RealType epsilon = ljit->getEpsilon();
123 addExplicitInteraction(at1, at2, sigma, epsilon);
124 }
125 }
126 initialized_ = true;
127 }
128
129
130
131 void LJ::addType(AtomType* atomType){
132 LennardJonesAdapter lja1 = LennardJonesAdapter(atomType);
133
134 RealType sigma1 = lja1.getSigma();
135 RealType epsilon1 = lja1.getEpsilon();
136
137 // add it to the map:
138
139 pair<map<int,AtomType*>::iterator,bool> ret;
140 ret = LJMap.insert( pair<int, AtomType*>(atomType->getIdent(), atomType) );
141 if (ret.second == false) {
142 sprintf( painCave.errMsg,
143 "LJ already had a previous entry with ident %d\n",
144 atomType->getIdent());
145 painCave.severity = OPENMD_INFO;
146 painCave.isFatal = 0;
147 simError();
148 }
149
150 // Now, iterate over all known types and add to the mixing map:
151
152 std::map<int, AtomType*>::iterator it;
153 for( it = LJMap.begin(); it != LJMap.end(); ++it) {
154
155 AtomType* atype2 = (*it).second;
156
157 LJInteractionData mixer;
158 mixer.sigma = getSigma(atomType, atype2);
159 mixer.epsilon = getEpsilon(atomType, atype2);
160 mixer.sigmai = 1.0 / mixer.sigma;
161 mixer.explicitlySet = false;
162
163 std::pair<AtomType*, AtomType*> key1, key2;
164 key1 = std::make_pair(atomType, atype2);
165 key2 = std::make_pair(atype2, atomType);
166
167 MixingMap[key1] = mixer;
168 if (key2 != key1) {
169 MixingMap[key2] = mixer;
170 }
171 }
172 }
173
174 void LJ::addExplicitInteraction(AtomType* atype1, AtomType* atype2, RealType sigma, RealType epsilon){
175
176 LJInteractionData mixer;
177 mixer.sigma = sigma;
178 mixer.epsilon = epsilon;
179 mixer.sigmai = 1.0 / mixer.sigma;
180 mixer.explicitlySet = true;
181
182 std::pair<AtomType*, AtomType*> key1, key2;
183 key1 = std::make_pair(atype1, atype2);
184 key2 = std::make_pair(atype2, atype1);
185
186 MixingMap[key1] = mixer;
187 if (key2 != key1) {
188 MixingMap[key2] = mixer;
189 }
190 }
191
192 void LJ::calcForce(InteractionData &idat) {
193 if (!initialized_) initialize();
194 map<pair<AtomType*, AtomType*>, LJInteractionData>::iterator it;
195 it = MixingMap.find( idat.atypes );
196
197 if (it != MixingMap.end()) {
198
199 LJInteractionData mixer = (*it).second;
200
201 RealType sigmai = mixer.sigmai;
202 RealType epsilon = mixer.epsilon;
203
204 RealType ros;
205 RealType rcos;
206 RealType myPot = 0.0;
207 RealType myPotC = 0.0;
208 RealType myDeriv = 0.0;
209 RealType myDerivC = 0.0;
210
211 ros = *(idat.rij) * sigmai;
212
213 getLJfunc(ros, myPot, myDeriv);
214
215 if (idat.shiftedPot) {
216 rcos = *(idat.rcut) * sigmai;
217 getLJfunc(rcos, myPotC, myDerivC);
218 myDerivC = 0.0;
219 } else if (idat.shiftedForce) {
220 rcos = *(idat.rcut) * sigmai;
221 getLJfunc(rcos, myPotC, myDerivC);
222 myPotC = myPotC + myDerivC * (*(idat.rij) - *(idat.rcut)) * sigmai;
223 } else {
224 myPotC = 0.0;
225 myDerivC = 0.0;
226 }
227
228 RealType pot_temp = *(idat.vdwMult) * epsilon * (myPot - myPotC);
229 *(idat.vpair) += pot_temp;
230
231 RealType dudr = *(idat.sw) * *(idat.vdwMult) * epsilon * (myDeriv -
232 myDerivC)*sigmai;
233
234 (*(idat.pot))[VANDERWAALS_FAMILY] += *(idat.sw) * pot_temp;
235 *(idat.f1) += *(idat.d) * dudr / *(idat.rij);
236 }
237 return;
238 }
239
240 void LJ::getLJfunc(RealType r, RealType &pot, RealType &deriv) {
241
242 RealType ri = 1.0 / r;
243 RealType ri2 = ri * ri;
244 RealType ri6 = ri2 * ri2 * ri2;
245 RealType ri7 = ri6 * ri;
246 RealType ri12 = ri6 * ri6;
247 RealType ri13 = ri12 * ri;
248
249 pot = 4.0 * (ri12 - ri6);
250 deriv = 24.0 * (ri7 - 2.0 * ri13);
251
252 return;
253 }
254
255 RealType LJ::getSuggestedCutoffRadius(pair<AtomType*, AtomType*> atypes) {
256 if (!initialized_) initialize();
257 map<pair<AtomType*, AtomType*>, LJInteractionData>::iterator it;
258 it = MixingMap.find(atypes);
259 if (it == MixingMap.end())
260 return 0.0;
261 else {
262 LJInteractionData mixer = (*it).second;
263 return 2.5 * mixer.sigma;
264 }
265 }
266
267 }

Properties

Name Value
svn:eol-style native