ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/nonbonded/Morse.cpp
Revision: 2032
Committed: Fri Oct 31 18:57:19 2014 UTC (10 years, 8 months ago) by jmichalk
File size: 8106 byte(s)
Log Message:
Forgot to svn add the files. Additionally, examined the files where changes were committed that I didn't realize were going to be changed. Primary one to examine SimplePreprocessor, bufferSize=8192 instead of 1024... everything else was commented cerr/cout or line spacing issues

File Contents

# User Rev Content
1 gezelter 1501 /*
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 gezelter 1879 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
39 gezelter 1665 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40     * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 gezelter 1501 */
42    
43     #include <stdio.h>
44     #include <string.h>
45    
46     #include <cmath>
47     #include "nonbonded/Morse.hpp"
48     #include "utils/simError.h"
49 gezelter 1664 #include "types/MorseInteractionType.hpp"
50 gezelter 1501
51     using namespace std;
52    
53     namespace OpenMD {
54    
55 gezelter 1583 Morse::Morse() : name_("Morse"), initialized_(false), forceField_(NULL) {}
56 gezelter 1501
57     void Morse::initialize() {
58    
59 gezelter 1895 Mtypes.clear();
60     Mtids.clear();
61     MixingMap.clear();
62     Mtids.resize( forceField_->getNAtomType(), -1);
63    
64 gezelter 1501 ForceField::NonBondedInteractionTypeContainer* nbiTypes = forceField_->getNonBondedInteractionTypes();
65     ForceField::NonBondedInteractionTypeContainer::MapTypeIterator j;
66 gezelter 1895 ForceField::NonBondedInteractionTypeContainer::KeyType keys;
67 gezelter 1501 NonBondedInteractionType* nbt;
68 gezelter 1895 int mtid1, mtid2;
69 gezelter 1501
70     for (nbt = nbiTypes->beginType(j); nbt != NULL;
71     nbt = nbiTypes->nextType(j)) {
72    
73     if (nbt->isMorse()) {
74 gezelter 1664 keys = nbiTypes->getKeys(j);
75     AtomType* at1 = forceField_->getAtomType(keys[0]);
76     AtomType* at2 = forceField_->getAtomType(keys[1]);
77 gezelter 1501
78 gezelter 1895 int atid1 = at1->getIdent();
79     if (Mtids[atid1] == -1) {
80     mtid1 = Mtypes.size();
81     Mtypes.insert(atid1);
82     Mtids[atid1] = mtid1;
83     }
84     int atid2 = at2->getIdent();
85     if (Mtids[atid2] == -1) {
86     mtid2 = Mtypes.size();
87     Mtypes.insert(atid2);
88     Mtids[atid2] = mtid2;
89     }
90    
91 gezelter 1664 MorseInteractionType* mit = dynamic_cast<MorseInteractionType*>(nbt);
92 gezelter 1501
93 gezelter 1664 if (mit == NULL) {
94 gezelter 1501 sprintf( painCave.errMsg,
95 gezelter 1664 "Morse::initialize could not convert NonBondedInteractionType\n"
96     "\tto MorseInteractionType for %s - %s interaction.\n",
97     at1->getName().c_str(),
98     at2->getName().c_str());
99 gezelter 1501 painCave.severity = OPENMD_ERROR;
100     painCave.isFatal = 1;
101     simError();
102     }
103 gezelter 1664
104     RealType De = mit->getD();
105     RealType Re = mit->getR();
106     RealType beta = mit->getBeta();
107    
108     MorseType variant = mit->getInteractionType();
109     addExplicitInteraction(at1, at2, De, Re, beta, variant );
110 gezelter 1501 }
111     }
112     initialized_ = true;
113     }
114    
115     void Morse::addExplicitInteraction(AtomType* atype1, AtomType* atype2,
116     RealType De, RealType Re, RealType beta,
117 gezelter 1664 MorseType mt) {
118 gezelter 1501
119     MorseInteractionData mixer;
120     mixer.De = De;
121     mixer.Re = Re;
122     mixer.beta = beta;
123 gezelter 1664 mixer.variant = mt;
124 gezelter 1501
125 gezelter 1895 int mtid1 = Mtids[atype1->getIdent()];
126     int mtid2 = Mtids[atype2->getIdent()];
127     int nM = Mtypes.size();
128    
129     MixingMap.resize(nM);
130     MixingMap[mtid1].resize(nM);
131 gezelter 1501
132 gezelter 1895 MixingMap[mtid1][mtid2] = mixer;
133     if (mtid2 != mtid1) {
134     MixingMap[mtid2].resize(nM);
135     MixingMap[mtid2][mtid1] = mixer;
136 gezelter 1501 }
137     }
138    
139 gezelter 1536 void Morse::calcForce(InteractionData &idat) {
140 gezelter 1501
141     if (!initialized_) initialize();
142 jmichalk 2031
143    
144 gezelter 1895 MorseInteractionData &mixer = MixingMap[Mtids[idat.atid1]][Mtids[idat.atid2]];
145    
146     RealType myPot = 0.0;
147     RealType myPotC = 0.0;
148     RealType myDeriv = 0.0;
149     RealType myDerivC = 0.0;
150    
151     RealType De = mixer.De;
152     RealType Re = mixer.Re;
153     RealType beta = mixer.beta;
154     MorseType variant = mixer.variant;
155    
156     // V(r) = D_e exp(-a(r-re)(exp(-a(r-re))-2)
157    
158     RealType expt = -beta*( *(idat.rij) - Re);
159     RealType expfnc = exp(expt);
160     RealType expfnc2 = expfnc*expfnc;
161    
162     RealType exptC = 0.0;
163     RealType expfncC = 0.0;
164     RealType expfnc2C = 0.0;
165    
166     if (idat.shiftedPot || idat.shiftedForce) {
167     exptC = -beta*( *(idat.rcut) - Re);
168     expfncC = exp(exptC);
169     expfnc2C = expfncC*expfncC;
170     }
171    
172    
173     switch(variant) {
174     case mtShifted : {
175     myPot = De * (expfnc2 - 2.0 * expfnc);
176     myDeriv = 2.0 * De * beta * (expfnc - expfnc2);
177 gezelter 1505
178 gezelter 1895 if (idat.shiftedPot) {
179     myPotC = De * (expfnc2C - 2.0 * expfncC);
180     myDerivC = 0.0;
181     } else if (idat.shiftedForce) {
182     myPotC = De * (expfnc2C - 2.0 * expfncC);
183     myDerivC = 2.0 * De * beta * (expfncC - expfnc2C);
184     myPotC += myDerivC * ( *(idat.rij) - *(idat.rcut) );
185     } else {
186     myPotC = 0.0;
187     myDerivC = 0.0;
188 gezelter 1501 }
189 gezelter 1505
190 gezelter 1895 break;
191     }
192     case mtRepulsive : {
193     myPot = De * expfnc2;
194     myDeriv = -2.0 * De * beta * expfnc2;
195 gezelter 1505
196 gezelter 1895 if (idat.shiftedPot) {
197     myPotC = De * expfnc2C;
198     myDerivC = 0.0;
199     } else if (idat.shiftedForce) {
200     myPotC = De * expfnc2C;
201     myDerivC = -2.0 * De * beta * expfnc2C;
202     myPotC += myDerivC * ( *(idat.rij) - *(idat.rcut));
203     } else {
204     myPotC = 0.0;
205     myDerivC = 0.0;
206 gezelter 1501 }
207 gezelter 1505
208 gezelter 1895 break;
209 gezelter 1501 }
210 gezelter 1895 case mtUnknown: {
211     // don't know what to do so don't do anything
212     break;
213     }
214     }
215 gezelter 1501
216 gezelter 2017
217 gezelter 1895 RealType pot_temp = *(idat.vdwMult) * (myPot - myPotC);
218     *(idat.vpair) += pot_temp;
219    
220     RealType dudr = *(idat.sw) * *(idat.vdwMult) * (myDeriv - myDerivC);
221 gezelter 2017
222 gezelter 1895
223     (*(idat.pot))[VANDERWAALS_FAMILY] += *(idat.sw) * pot_temp;
224     *(idat.f1) = *(idat.d) * dudr / *(idat.rij);
225 jmichalk 2031
226 gezelter 1895 return;
227 gezelter 1505 }
228 gezelter 1895
229 gezelter 1545 RealType Morse::getSuggestedCutoffRadius(pair<AtomType*, AtomType*> atypes) {
230 gezelter 1505 if (!initialized_) initialize();
231 gezelter 1895
232     int atid1 = atypes.first->getIdent();
233     int atid2 = atypes.second->getIdent();
234     int mtid1 = Mtids[atid1];
235     int mtid2 = Mtids[atid2];
236    
237     if ( mtid1 == -1 || mtid2 == -1) return 0.0;
238     else {
239     MorseInteractionData mixer = MixingMap[mtid1][mtid2];
240 gezelter 1505 RealType Re = mixer.Re;
241     RealType beta = mixer.beta;
242     // This value of the r corresponds to an energy about 1.48% of
243     // the energy at the bottom of the Morse well. For comparison, the
244     // Lennard-Jones function is about 1.63% of it's minimum value at
245     // a distance of 2.5 sigma.
246     return (4.9 + beta * Re) / beta;
247     }
248 gezelter 1501 }
249     }
250    

Properties

Name Value
svn:eol-style native