ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/nonbonded/Morse.cpp
Revision: 2031
Committed: Fri Oct 31 18:40:40 2014 UTC (10 years, 9 months ago) by jmichalk
File size: 8840 byte(s)
Log Message:
Added a surface diffusion analyser to staticProps

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     //cerr << "In Morse::calcForce\n";
144    
145 gezelter 1895 MorseInteractionData &mixer = MixingMap[Mtids[idat.atid1]][Mtids[idat.atid2]];
146    
147     RealType myPot = 0.0;
148     RealType myPotC = 0.0;
149     RealType myDeriv = 0.0;
150     RealType myDerivC = 0.0;
151    
152     RealType De = mixer.De;
153     RealType Re = mixer.Re;
154     RealType beta = mixer.beta;
155     MorseType variant = mixer.variant;
156    
157     // V(r) = D_e exp(-a(r-re)(exp(-a(r-re))-2)
158    
159     RealType expt = -beta*( *(idat.rij) - Re);
160     RealType expfnc = exp(expt);
161     RealType expfnc2 = expfnc*expfnc;
162    
163     RealType exptC = 0.0;
164     RealType expfncC = 0.0;
165     RealType expfnc2C = 0.0;
166    
167     if (idat.shiftedPot || idat.shiftedForce) {
168     exptC = -beta*( *(idat.rcut) - Re);
169     expfncC = exp(exptC);
170     expfnc2C = expfncC*expfncC;
171     }
172    
173    
174     switch(variant) {
175     case mtShifted : {
176 jmichalk 2031 //cerr << "Morse Type Shifted\n";
177 gezelter 1895 myPot = De * (expfnc2 - 2.0 * expfnc);
178     myDeriv = 2.0 * De * beta * (expfnc - expfnc2);
179 gezelter 1505
180 gezelter 1895 if (idat.shiftedPot) {
181     myPotC = De * (expfnc2C - 2.0 * expfncC);
182     myDerivC = 0.0;
183     } else if (idat.shiftedForce) {
184     myPotC = De * (expfnc2C - 2.0 * expfncC);
185     myDerivC = 2.0 * De * beta * (expfncC - expfnc2C);
186     myPotC += myDerivC * ( *(idat.rij) - *(idat.rcut) );
187     } else {
188     myPotC = 0.0;
189     myDerivC = 0.0;
190 gezelter 1501 }
191 gezelter 1505
192 gezelter 1895 break;
193     }
194     case mtRepulsive : {
195 jmichalk 2031 //cerr << "Morse Type Repulsive\n";
196 gezelter 1895 myPot = De * expfnc2;
197     myDeriv = -2.0 * De * beta * expfnc2;
198 gezelter 1505
199 gezelter 1895 if (idat.shiftedPot) {
200 jmichalk 2031 //cerr << "shifted potentional\n";
201 gezelter 1895 myPotC = De * expfnc2C;
202     myDerivC = 0.0;
203     } else if (idat.shiftedForce) {
204 jmichalk 2031 //cerr << "shifted force\n";
205 gezelter 1895 myPotC = De * expfnc2C;
206 jmichalk 2031 //cerr << "myPotC initial: " << myPotC << "\n";
207 gezelter 1895 myDerivC = -2.0 * De * beta * expfnc2C;
208     myPotC += myDerivC * ( *(idat.rij) - *(idat.rcut));
209     } else {
210 jmichalk 2031 //cerr << "nothing\n";
211 gezelter 1895 myPotC = 0.0;
212     myDerivC = 0.0;
213 gezelter 1501 }
214 gezelter 1505
215 gezelter 1895 break;
216 gezelter 1501 }
217 gezelter 1895 case mtUnknown: {
218 jmichalk 2031 //cerr << "Morse Type Unknown\n";
219 gezelter 1895 // don't know what to do so don't do anything
220     break;
221     }
222     }
223 gezelter 1501
224 gezelter 2017
225 gezelter 1895 RealType pot_temp = *(idat.vdwMult) * (myPot - myPotC);
226     *(idat.vpair) += pot_temp;
227    
228     RealType dudr = *(idat.sw) * *(idat.vdwMult) * (myDeriv - myDerivC);
229 gezelter 2017
230 gezelter 1895
231     (*(idat.pot))[VANDERWAALS_FAMILY] += *(idat.sw) * pot_temp;
232 jmichalk 2031 //cerr << "Before force assigned: " << *(idat.f1) << "\n";
233 gezelter 1895 *(idat.f1) = *(idat.d) * dudr / *(idat.rij);
234 jmichalk 2031
235     /*
236     cerr << "myPot: " << myPot << "\n";
237     cerr << "myDeriv: " << myDeriv << "\n";
238     cerr << "myPotC: " << myPotC << "\n";
239     cerr << "myDerivC: " << myDerivC << "\n";
240     cerr << "idat.rij: " << *(idat.rij) << "\n";
241     cerr << "idat.d: " << *(idat.d) << "\n";
242     cerr << "dudr: " << dudr << "\n";
243     cerr << "After force: " << *(idat.f1) << "\n\n";
244     */
245 gezelter 1895 return;
246 gezelter 1505 }
247 gezelter 1895
248 gezelter 1545 RealType Morse::getSuggestedCutoffRadius(pair<AtomType*, AtomType*> atypes) {
249 gezelter 1505 if (!initialized_) initialize();
250 gezelter 1895
251     int atid1 = atypes.first->getIdent();
252     int atid2 = atypes.second->getIdent();
253     int mtid1 = Mtids[atid1];
254     int mtid2 = Mtids[atid2];
255    
256     if ( mtid1 == -1 || mtid2 == -1) return 0.0;
257     else {
258     MorseInteractionData mixer = MixingMap[mtid1][mtid2];
259 gezelter 1505 RealType Re = mixer.Re;
260     RealType beta = mixer.beta;
261     // This value of the r corresponds to an energy about 1.48% of
262     // the energy at the bottom of the Morse well. For comparison, the
263     // Lennard-Jones function is about 1.63% of it's minimum value at
264     // a distance of 2.5 sigma.
265     return (4.9 + beta * Re) / beta;
266     }
267 gezelter 1501 }
268     }
269    

Properties

Name Value
svn:eol-style native