ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/flucq/FluctuatingChargeNVT.cpp
Revision: 1735
Committed: Tue Jun 5 17:50:53 2012 UTC (12 years, 11 months ago) by jmichalk
File size: 9203 byte(s)
Log Message:
Moved FluctuatingChargeNVT to the flucq directory

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    
141     for (mol = info_->beginMolecule(i); mol != NULL;
142     mol = info_->nextMolecule(i)) {
143     for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
144     atom = mol->nextFluctuatingCharge(j)) {
145    
146     cvel = atom->getFlucQVel();
147     cpos = atom->getFlucQPos();
148     cfrc = atom->getFlucQFrc();
149     cmass = atom->getChargeMass();
150    
151 jmichalk 1735 cerr << atom->getType() << "\n";
152     cerr << "Before\n";
153     cerr << "cvel: " << cvel << "\tcpos: " << cpos << "\tcfrc: " << cfrc << "\tcmass: " << cmass << "\n";
154    
155     // velocity half step
156     cvel += dt2_ * cfrc / cmass - dt2_*chi*cvel;
157 gezelter 1716 // position whole step
158     cpos += dt_ * cvel;
159 jmichalk 1735
160     cerr << "After\n";
161     cerr << "cvel: " << cvel << "\tcpos: " << cpos << "\n\n";
162    
163 gezelter 1716 atom->setFlucQVel(cvel);
164     atom->setFlucQPos(cpos);
165     }
166     }
167    
168     chi += dt2_ * (instTemp / targetTemp_ - 1.0) /
169     (tauThermostat_ * tauThermostat_);
170    
171     integralOfChidt += chi * dt2_;
172 jmichalk 1735 cerr << "Move A instTemp: " << instTemp << "\n";
173 gezelter 1716 currentSnapshot_->setChiElectronic(chi);
174     currentSnapshot_->setIntegralOfChiElectronicDt(integralOfChidt);
175    
176     }
177    
178     void FluctuatingChargeNVT::updateSizes() {
179     if (!hasFlucQ_) return;
180     oldVel_.resize(info_->getNFluctuatingCharges());
181     }
182    
183     void FluctuatingChargeNVT::moveB() {
184     if (!hasFlucQ_) return;
185     SimInfo::MoleculeIterator i;
186     Molecule::FluctuatingChargeIterator j;
187     Molecule* mol;
188     Atom* atom;
189     RealType instTemp;
190     RealType chi = currentSnapshot_->getChiElectronic();
191     RealType oldChi = chi;
192     RealType prevChi;
193     RealType integralOfChidt = currentSnapshot_->getIntegralOfChiElectronicDt();
194     int index;
195     RealType cfrc, cvel, cmass;
196    
197     index = 0;
198     for (mol = info_->beginMolecule(i); mol != NULL;
199     mol = info_->nextMolecule(i)) {
200     for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
201     atom = mol->nextFluctuatingCharge(j)) {
202    
203     oldVel_[index] = atom->getFlucQVel();
204     ++index;
205     }
206     }
207    
208     // do the iteration:
209    
210     for(int k = 0; k < maxIterNum_; k++) {
211     index = 0;
212     instTemp = thermo.getElectronicTemperature();
213 jmichalk 1735 cerr << "MoveB instTemp: " << instTemp << "\n";
214 gezelter 1716 // evolve chi another half step using the temperature at t + dt/2
215     prevChi = chi;
216     chi = oldChi + dt2_ * (instTemp / targetTemp_ - 1.0) /
217     (tauThermostat_ * tauThermostat_);
218    
219     for (mol = info_->beginMolecule(i); mol != NULL;
220     mol = info_->nextMolecule(i)) {
221     for (atom = mol->beginFluctuatingCharge(j); atom != NULL;
222     atom = mol->nextFluctuatingCharge(j)) {
223    
224     cfrc = atom->getFlucQFrc();
225     cvel =atom->getFlucQVel();
226     cmass = atom->getChargeMass();
227    
228     // velocity half step
229 jmichalk 1735 cvel = oldVel_[index] + dt2_ * cfrc / cmass - dt2_*chi*oldVel_[index];
230 gezelter 1716
231     atom->setFlucQVel(cvel);
232     ++index;
233     }
234     }
235     if (fabs(prevChi - chi) <= chiTolerance_)
236     break;
237     }
238     integralOfChidt += dt2_ * chi;
239     currentSnapshot_->setChiElectronic(chi);
240     currentSnapshot_->setIntegralOfChiElectronicDt(integralOfChidt);
241     }
242    
243     void FluctuatingChargeNVT::resetPropagator() {
244     if (!hasFlucQ_) return;
245     currentSnapshot_->setChiElectronic(0.0);
246     currentSnapshot_->setIntegralOfChiElectronicDt(0.0);
247     }
248    
249     RealType FluctuatingChargeNVT::calcConservedQuantity() {
250     if (!hasFlucQ_) return 0.0;
251     RealType chi = currentSnapshot_->getChiElectronic();
252     RealType integralOfChidt = currentSnapshot_->getIntegralOfChiElectronicDt();
253     RealType fkBT = info_->getNFluctuatingCharges() *
254     PhysicalConstants::kB *targetTemp_;
255    
256     RealType thermostat_kinetic = fkBT * tauThermostat_ * tauThermostat_ *
257     chi * chi / (2.0 * PhysicalConstants::energyConvert);
258    
259     RealType thermostat_potential = fkBT * integralOfChidt /
260     PhysicalConstants::energyConvert;
261    
262     return thermostat_kinetic + thermostat_potential;
263     }
264     }

Properties

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