ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/flucq/FluctuatingChargeNVT.cpp
Revision: 1731
Committed: Thu May 31 12:25:30 2012 UTC (13 years ago) by gezelter
File size: 8951 byte(s)
Log Message:
Reorganized source directories, added RNEMD and flucQ blocks for
options parsing.

File Contents

# User Rev Content
1 gezelter 1716 /*
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 "FluctuatingChargeNVT.hpp"
44     #include "primitives/Molecule.hpp"
45     #include "utils/simError.h"
46     #include "utils/PhysicalConstants.hpp"
47    
48     namespace OpenMD {
49    
50     FluctuatingChargeNVT::FluctuatingChargeNVT(SimInfo* info) :
51     FluctuatingChargePropagator(info), chiTolerance_ (1e-6), maxIterNum_(4),
52     thermo(info),
53     currentSnapshot_(info->getSnapshotManager()->getCurrentSnapshot()) {
54    
55 gezelter 1731
56 gezelter 1716 if (info_->usesFluctuatingCharges()) {
57     if (info_->getNFluctuatingCharges() > 0) {
58    
59     hasFlucQ_ = true;
60     Globals* simParams = info_->getSimParams();
61 gezelter 1731 FluctuatingChargeParameters* fqParams = simParams->getFluctuatingChargeParameters();
62 gezelter 1716
63     if (simParams->haveDt()) {
64     dt_ = simParams->getDt();
65     dt2_ = dt_ * 0.5;
66     } else {
67     sprintf(painCave.errMsg,
68     "FluctuatingChargeNVT Error: dt is not set\n");
69     painCave.isFatal = 1;
70     simError();
71     }
72    
73     if (!simParams->getUseIntialExtendedSystemState()) {
74     currentSnapshot_->setChiElectronic(0.0);
75     currentSnapshot_->setIntegralOfChiElectronicDt(0.0);
76     }
77    
78 gezelter 1731 if (!fqParams->haveTargetTemp()) {
79 gezelter 1716 sprintf(painCave.errMsg, "You can't use the FluctuatingChargeNVT "
80     "propagator without a flucQ.targetTemp!\n");
81     painCave.isFatal = 1;
82     painCave.severity = OPENMD_ERROR;
83     simError();
84     } else {
85 gezelter 1731 targetTemp_ = fqParams->getTargetTemp();
86 gezelter 1716 }
87    
88     // We must set tauThermostat.
89    
90 gezelter 1731 if (!fqParams->haveTauThermostat()) {
91 gezelter 1716 sprintf(painCave.errMsg, "If you use the FluctuatingChargeNVT\n"
92     "\tpropagator, you must set flucQ.tauThermostat .\n");
93    
94     painCave.severity = OPENMD_ERROR;
95     painCave.isFatal = 1;
96     simError();
97     } else {
98 gezelter 1731 tauThermostat_ = fqParams->getTauThermostat();
99 gezelter 1716 }
100     updateSizes();
101     }
102     }
103     }
104    
105     void FluctuatingChargeNVT::initialize() {
106    
107     if (!hasFlucQ_) return;
108    
109     SimInfo::MoleculeIterator i;
110     Molecule::FluctuatingChargeIterator j;
111     Molecule* mol;
112     Atom* atom;
113    
114     for (mol = info_->beginMolecule(i); mol != NULL;
115     mol = info_->nextMolecule(i)) {
116     for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
117     atom = mol->nextFluctuatingCharge(j)) {
118     atom->setFlucQPos(0.0);
119     atom->setFlucQVel(0.0);
120     }
121     }
122    
123     cerr << "Yeah, you should probably implement this\n";
124     }
125    
126     void FluctuatingChargeNVT::moveA() {
127    
128     if (!hasFlucQ_) return;
129    
130     SimInfo::MoleculeIterator i;
131     Molecule::FluctuatingChargeIterator j;
132     Molecule* mol;
133     Atom* atom;
134     RealType cvel, cpos, cfrc, cmass;
135    
136     RealType chi = currentSnapshot_->getChiElectronic();
137     RealType integralOfChidt = currentSnapshot_->getIntegralOfChiElectronicDt();
138     RealType instTemp = thermo.getElectronicTemperature();
139    
140     cerr << "why are we here?\n";
141    
142     for (mol = info_->beginMolecule(i); mol != NULL;
143     mol = info_->nextMolecule(i)) {
144     for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
145     atom = mol->nextFluctuatingCharge(j)) {
146    
147     cvel = atom->getFlucQVel();
148     cpos = atom->getFlucQPos();
149     cfrc = atom->getFlucQFrc();
150     cmass = atom->getChargeMass();
151    
152     // velocity half step
153     cvel += dt2_ *PhysicalConstants::energyConvert/cmass*cfrc - dt2_*chi*cvel;
154     // position whole step
155     cpos += dt_ * cvel;
156    
157     atom->setFlucQVel(cvel);
158     atom->setFlucQPos(cpos);
159     }
160     }
161    
162     chi += dt2_ * (instTemp / targetTemp_ - 1.0) /
163     (tauThermostat_ * tauThermostat_);
164    
165     integralOfChidt += chi * dt2_;
166     currentSnapshot_->setChiElectronic(chi);
167     currentSnapshot_->setIntegralOfChiElectronicDt(integralOfChidt);
168    
169     }
170    
171     void FluctuatingChargeNVT::updateSizes() {
172     if (!hasFlucQ_) return;
173     oldVel_.resize(info_->getNFluctuatingCharges());
174     }
175    
176     void FluctuatingChargeNVT::moveB() {
177     if (!hasFlucQ_) return;
178     SimInfo::MoleculeIterator i;
179     Molecule::FluctuatingChargeIterator j;
180     Molecule* mol;
181     Atom* atom;
182     RealType instTemp;
183     RealType chi = currentSnapshot_->getChiElectronic();
184     RealType oldChi = chi;
185     RealType prevChi;
186     RealType integralOfChidt = currentSnapshot_->getIntegralOfChiElectronicDt();
187     int index;
188     RealType cfrc, cvel, cmass;
189    
190     index = 0;
191     for (mol = info_->beginMolecule(i); mol != NULL;
192     mol = info_->nextMolecule(i)) {
193     for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
194     atom = mol->nextFluctuatingCharge(j)) {
195    
196     oldVel_[index] = atom->getFlucQVel();
197     ++index;
198     }
199     }
200    
201     // do the iteration:
202    
203     for(int k = 0; k < maxIterNum_; k++) {
204     index = 0;
205     instTemp = thermo.getElectronicTemperature();
206    
207     // evolve chi another half step using the temperature at t + dt/2
208     prevChi = chi;
209     chi = oldChi + dt2_ * (instTemp / targetTemp_ - 1.0) /
210     (tauThermostat_ * tauThermostat_);
211    
212     for (mol = info_->beginMolecule(i); mol != NULL;
213     mol = info_->nextMolecule(i)) {
214     for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
215     atom = mol->nextFluctuatingCharge(j)) {
216    
217     cfrc = atom->getFlucQFrc();
218     cvel =atom->getFlucQVel();
219     cmass = atom->getChargeMass();
220    
221     // velocity half step
222     cvel = oldVel_[index] + dt2_/cmass*PhysicalConstants::energyConvert * cfrc - dt2_*chi*oldVel_[index];
223    
224     atom->setFlucQVel(cvel);
225     ++index;
226     }
227     }
228     if (fabs(prevChi - chi) <= chiTolerance_)
229     break;
230     }
231     integralOfChidt += dt2_ * chi;
232     currentSnapshot_->setChiElectronic(chi);
233     currentSnapshot_->setIntegralOfChiElectronicDt(integralOfChidt);
234     }
235    
236     void FluctuatingChargeNVT::resetPropagator() {
237     if (!hasFlucQ_) return;
238     currentSnapshot_->setChiElectronic(0.0);
239     currentSnapshot_->setIntegralOfChiElectronicDt(0.0);
240     }
241    
242     RealType FluctuatingChargeNVT::calcConservedQuantity() {
243     if (!hasFlucQ_) return 0.0;
244     RealType chi = currentSnapshot_->getChiElectronic();
245     RealType integralOfChidt = currentSnapshot_->getIntegralOfChiElectronicDt();
246     RealType fkBT = info_->getNFluctuatingCharges() *
247     PhysicalConstants::kB *targetTemp_;
248    
249     RealType thermostat_kinetic = fkBT * tauThermostat_ * tauThermostat_ *
250     chi * chi / (2.0 * PhysicalConstants::energyConvert);
251    
252     RealType thermostat_potential = fkBT * integralOfChidt /
253     PhysicalConstants::energyConvert;
254    
255     return thermostat_kinetic + thermostat_potential;
256     }
257     }

Properties

Name Value
svn:eol-style native
svn:executable *