OpenMD 3.1
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
CurrentDensityAutoCorrFunc.cpp
1/*
2 * Copyright (c) 2004-present, The University of Notre Dame. All rights
3 * reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
32 * research, please cite the appropriate papers when you publish your
33 * work. Good starting points are:
34 *
35 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
36 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
37 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
38 * [4] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
39 * [5] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
40 * [6] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
41 * [7] Lamichhane, Newman & Gezelter, J. Chem. Phys. 141, 134110 (2014).
42 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
43 */
44
45#include "applications/dynamicProps/CurrentDensityAutoCorrFunc.hpp"
46
47#include "types/FixedChargeAdapter.hpp"
48#include "types/FluctuatingChargeAdapter.hpp"
49#include "utils/Revision.hpp"
50
51using namespace std;
52namespace OpenMD {
53 CurrentDensityAutoCorrFunc::CurrentDensityAutoCorrFunc(SimInfo* info,
54 const string& filename,
55 const string& sele1,
56 const string& sele2) :
57 SystemACF<RealType>(info, filename, sele1, sele2) {
58 setCorrFuncType("Current Density Auto Correlation Function");
59 setOutputName(getPrefix(dumpFilename_) + ".currentDensityCorr");
60
61 AtomTypeSet osTypes = seleMan1_.getSelectedAtomTypes();
62 std::copy(osTypes.begin(), osTypes.end(), std::back_inserter(outputTypes_));
63
64 Jc_.resize(nFrames_, V3Zero);
65 JcCount_.resize(nFrames_, 0);
66
67 typeJc_.resize(nFrames_);
68 typeCounts_.resize(nFrames_);
69 myHistogram_.resize(nTimeBins_);
70
71 for (int i = 0; i < nFrames_; ++i) {
72 typeJc_[i].resize(outputTypes_.size(), V3Zero);
73 typeCounts_[i].resize(outputTypes_.size(), 0);
74 }
75 for (unsigned int i = 0; i < nTimeBins_; ++i) {
76 myHistogram_[i].resize(outputTypes_.size() + 1, 0.0);
77 }
78 // We'll need thermo to compute the volume:
79 thermo_ = new Thermo(info_);
80 }
81
82 void CurrentDensityAutoCorrFunc::computeProperty1(int frame) {
83 StuntDouble* sd1;
84 AtomType* atype;
85 std::vector<AtomType*>::iterator at;
86 int i;
87
88 for (sd1 = seleMan1_.beginSelected(i); sd1 != NULL;
89 sd1 = seleMan1_.nextSelected(i)) {
90 Vector3d v = sd1->getVel();
91 RealType q = 0.0;
92 int typeIndex(-1);
93
94 if (sd1->isAtom()) {
95 atype = static_cast<Atom*>(sd1)->getAtomType();
97 if (fca.isFixedCharge()) q = fca.getCharge();
99 if (fqa.isFluctuatingCharge()) q += sd1->getFlucQPos();
100
101 typeIndex = -1;
102 at = std::find(outputTypes_.begin(), outputTypes_.end(), atype);
103 if (at != outputTypes_.end()) {
104 typeIndex = std::distance(outputTypes_.begin(), at);
105 }
106 if (typeIndex != -1) {
107 typeCounts_[frame][typeIndex]++;
108 typeJc_[frame][typeIndex] += q * v;
109 }
110 }
111 JcCount_[frame]++;
112 Jc_[frame] += q * v;
113 }
114
115 RealType vol = thermo_->getVolume();
116
117 Jc_[frame] /= (vol * Constants::currentDensityConvert);
118 for (unsigned int j = 0; j < outputTypes_.size(); j++) {
119 typeJc_[frame][j] /= (vol * Constants::currentDensityConvert);
120 }
121 }
122
123 void CurrentDensityAutoCorrFunc::correlateFrames(int frame1, int frame2,
124 int timeBin) {
125 RealType corrVal(0.0);
126 corrVal = dot(Jc_[frame1], Jc_[frame2]);
127 myHistogram_[timeBin][0] += corrVal;
128
129 for (unsigned int j = 0; j < outputTypes_.size(); j++) {
130 corrVal = dot(typeJc_[frame1][j], typeJc_[frame2][j]);
131 myHistogram_[timeBin][j + 1] += corrVal;
132 }
133
134 count_[timeBin]++;
135 }
136
137 void CurrentDensityAutoCorrFunc::postCorrelate() {
138 for (unsigned int i = 0; i < nTimeBins_; ++i) {
139 for (unsigned int j = 0; j < outputTypes_.size() + 1; j++) {
140 if (count_[i] > 0) {
141 myHistogram_[i][j] /= count_[i];
142 } else {
143 myHistogram_[i][j] = 0.0;
144 }
145 }
146 }
147 }
148
149 void CurrentDensityAutoCorrFunc::writeCorrelate() {
150 ofstream ofs(outputFilename_.c_str());
151
152 if (ofs.is_open()) {
153 Revision r;
154
155 ofs << "# " << getCorrFuncType() << "\n";
156 ofs << "# OpenMD " << r.getFullRevision() << "\n";
157 ofs << "# " << r.getBuildDate() << "\n";
158 ofs << "# selection script1: \"" << selectionScript1_;
159 ofs << "\"\tselection script2: \"" << selectionScript2_ << "\"\n";
160 if (!paramString_.empty())
161 ofs << "# parameters: " << paramString_ << "\n";
162 ofs << "# units = Amps^2 m^-4\n";
163 if (!labelString_.empty())
164 ofs << "#time\t" << labelString_ << "\n";
165 else
166 ofs << "#time\tcorrVal\t(";
167
168 for (unsigned int j = 0; j < outputTypes_.size(); j++) {
169 ofs << outputTypes_[j]->getName() << "\t";
170 }
171
172 ofs << ")\n";
173
174 for (unsigned int i = 0; i < nTimeBins_; ++i) {
175 ofs << times_[i] - times_[0] << "\t";
176 for (unsigned int j = 0; j < outputTypes_.size() + 1; j++) {
177 ofs << myHistogram_[i][j] << '\t';
178 }
179 ofs << '\n';
180 }
181
182 } else {
183 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
184 "CurrentDensityAutoCorrFunc::writeCorrelate Error: failed to "
185 "open %s\n",
186 outputFilename_.c_str());
187 painCave.isFatal = 1;
188 simError();
189 }
190
191 ofs.close();
192 }
193} // namespace OpenMD
AtomType is what OpenMD looks to for unchanging data about an atom.
Definition AtomType.hpp:66
StuntDouble * nextSelected(int &i)
Finds the next selected StuntDouble in the selection.
StuntDouble * beginSelected(int &i)
Finds the first selected StuntDouble in the selection.
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:93
"Don't move, or you're dead! Stand up! Captain, we've got them!"
Vector3d getVel()
Returns the current velocity of this stuntDouble.
RealType getFlucQPos()
Returns the current fluctuating charge of this stuntDouble.
bool isAtom()
Tests if this stuntDouble is an atom.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Real dot(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the dot product of two DynamicVectors.
std::string getPrefix(const std::string &str)