OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
RCorrFunc.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 following paper when you publish your work:
33 *
34 * [1] Drisko et al., J. Open Source Softw. 9, 7004 (2024).
35 *
36 * Good starting points for code and simulation methodology are:
37 *
38 * [2] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
39 * [3] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
40 * [4] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
41 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
42 * [6] Kuang & Gezelter, Mol. Phys., 110, 691-701 (2012).
43 * [7] Lamichhane, Gezelter & Newman, J. Chem. Phys. 141, 134109 (2014).
44 * [8] Bhattarai, Newman & Gezelter, Phys. Rev. B 99, 094106 (2019).
45 * [9] Drisko & Gezelter, J. Chem. Theory Comput. 20, 4986-4997 (2024).
46 */
47
48#include "applications/dynamicProps/RCorrFunc.hpp"
49
50#include <sstream>
51
52#include "utils/Revision.hpp"
53
54namespace OpenMD {
55 RCorrFunc::RCorrFunc(SimInfo* info, const std::string& filename,
56 const std::string& sele1, const std::string& sele2) :
57 ObjectACF<RealType>(info, filename, sele1, sele2) {
58 setCorrFuncType("Mean Square Displacement");
59 setOutputName(getPrefix(dumpFilename_) + ".rcorr");
60
61 positions_.resize(nFrames_);
62 }
63
64 RCorrFuncZ::RCorrFuncZ(SimInfo* info, const std::string& filename,
65 const std::string& sele1, const std::string& sele2,
66 int nZbins, int axis) :
67 ObjectACF<RealType>(info, filename, sele1, sele2),
68 axis_(axis) {
69 setCorrFuncType("Mean Square Displacement binned by Z");
70 setOutputName(getPrefix(dumpFilename_) + ".rcorrZ");
71
72 positions_.resize(nFrames_);
73 zBins_.resize(nFrames_);
74 nZBins_ = nZbins;
75
76 switch (axis_) {
77 case 0:
78 axisLabel_ = "x";
79 break;
80 case 1:
81 axisLabel_ = "y";
82 break;
83 case 2:
84 default:
85 axisLabel_ = "z";
86 break;
87 }
88
89 std::stringstream params;
90 params << " nzbins = " << nZBins_;
91 const std::string paramString = params.str();
92 setParameterString(paramString);
93
94 histograms_.resize(nTimeBins_);
95 counts_.resize(nTimeBins_);
96
97 idimHistograms_.resize(3);
98 for (unsigned i = 0; i < idimHistograms_.size(); i++) {
99 idimHistograms_[i].resize(nTimeBins_);
100 }
101 for (unsigned int i = 0; i < nTimeBins_; i++) {
102 histograms_[i].resize(nZBins_);
103 counts_[i].resize(nZBins_);
104
105 std::fill(histograms_[i].begin(), histograms_[i].end(), 0.0);
106 std::fill(counts_[i].begin(), counts_[i].end(), 0);
107
108 for (unsigned j = 0; j < 3; j++) {
109 idimHistograms_[j][i].resize(nZBins_);
110 std::fill(idimHistograms_[j][i].begin(), idimHistograms_[j][i].end(),
111 0.0);
112 }
113 }
114 }
115
116 RCorrFuncR::RCorrFuncR(SimInfo* info, const std::string& filename,
117 const std::string& sele1, const std::string& sele2) :
118 ObjectACF<RealType>(info, filename, sele1, sele2) {
119 // Turn on COM calculation in reader:
120 bool ncp = true;
121 reader_->setNeedCOMprops(ncp);
122 setCorrFuncType("MSD (radial projection)");
123 setOutputName(getPrefix(dumpFilename_) + ".r_rcorr");
124 positions_.resize(nFrames_);
125 }
126
127 int RCorrFunc::computeProperty1(int frame, StuntDouble* sd) {
128 positions_[frame].push_back(sd->getPos());
129 return positions_[frame].size() - 1;
130 }
131
132 RealType RCorrFunc::calcCorrVal(int frame1, int frame2, int id1, int id2) {
133 Vector3d diff = positions_[frame2][id2] - positions_[frame1][id1];
134 return diff.lengthSquare();
135 }
136
137 void RCorrFuncZ::computeFrame(int istep) {
138 hmat_ = currentSnapshot_->getHmat();
139 halfBoxZ_ = hmat_(axis_, axis_) / 2.0;
140
141 StuntDouble* sd;
142
143 int isd1, isd2;
144 unsigned int index;
145
146 if (evaluator1_.isDynamic()) {
147 seleMan1_.setSelectionSet(evaluator1_.evaluate());
148 }
149
150 if (uniqueSelections_ && evaluator2_.isDynamic()) {
151 seleMan2_.setSelectionSet(evaluator2_.evaluate());
152 }
153
154 for (sd = seleMan1_.beginSelected(isd1); sd != NULL;
155 sd = seleMan1_.nextSelected(isd1)) {
156 index = computeProperty1(istep, sd);
157 if (index == sele1ToIndex_[istep].size()) {
158 sele1ToIndex_[istep].push_back(sd->getGlobalIndex());
159 } else {
160 sele1ToIndex_[istep].resize(index + 1);
161 sele1ToIndex_[istep][index] = sd->getGlobalIndex();
162 }
163 }
164
165 if (uniqueSelections_) {
166 for (sd = seleMan2_.beginSelected(isd2); sd != NULL;
167 sd = seleMan2_.nextSelected(isd2)) {
168 index = computeProperty1(istep, sd);
169
170 if (index == sele2ToIndex_[istep].size()) {
171 sele2ToIndex_[istep].push_back(sd->getGlobalIndex());
172 } else {
173 sele2ToIndex_[istep].resize(index + 1);
174 sele2ToIndex_[istep][index] = sd->getGlobalIndex();
175 }
176 }
177 }
178 }
179
180 int RCorrFuncZ::computeProperty1(int frame, StuntDouble* sd) {
181 Vector3d pos = sd->getPos();
182 // we need the raw (not wrapped) positions for RMSD:
183 positions_[frame].push_back(sd->getPos());
184
185 if (info_->getSimParams()->getUsePeriodicBoundaryConditions()) {
186 currentSnapshot_->wrapVector(pos);
187 }
188 int zBin = int(nZBins_ * (halfBoxZ_ + pos[axis_]) / hmat_(axis_, axis_));
189 zBins_[frame].push_back(zBin);
190
191 return positions_[frame].size() - 1;
192 }
193
194 void RCorrFuncZ::correlateFrames(int frame1, int frame2, int timeBin) {
195 std::vector<int> s1;
196 std::vector<int> s2;
197
198 std::vector<int>::iterator i1;
199 std::vector<int>::iterator i2;
200
201 s1 = sele1ToIndex_[frame1];
202
203 if (uniqueSelections_)
204 s2 = sele2ToIndex_[frame2];
205 else
206 s2 = sele1ToIndex_[frame2];
207
208 for (i1 = s1.begin(), i2 = s2.begin(); i1 != s1.end() && i2 != s2.end();
209 ++i1, ++i2) {
210 // If the selections are dynamic, they might not have the
211 // same objects in both frames, so we need to roll either of
212 // the selections until we have the same object to
213 // correlate.
214
215 while (i1 != s1.end() && *i1 < *i2) {
216 ++i1;
217 }
218
219 while (i2 != s2.end() && *i2 < *i1) {
220 ++i2;
221 }
222
223 if (i1 == s1.end() || i2 == s2.end()) break;
224
225 calcCorrValImpl(frame1, frame2, i1 - s1.begin(), i2 - s2.begin(),
226 timeBin);
227 }
228 }
229
230 RealType RCorrFuncZ::calcCorrValImpl(int frame1, int frame2, int id1, int id2,
231 int timeBin) {
232 int zBin1 = zBins_[frame1][id1];
233 int zBin2 = zBins_[frame2][id2];
234
235 if (zBin1 == zBin2) {
236 Vector3d diff = positions_[frame2][id2] - positions_[frame1][id1];
237 histograms_[timeBin][zBin1] += diff.lengthSquare();
238
239 for (unsigned i = 0; i < 3; i++) {
240 RealType iDiff =
241 positions_[frame2][id2][i] - positions_[frame1][id1][i];
242 idimHistograms_[i][timeBin][zBin1] += (iDiff * iDiff);
243 }
244
245 counts_[timeBin][zBin1]++;
246 }
247 return 0.0;
248 }
249
250 void RCorrFuncZ::postCorrelate() {
251 for (unsigned int i = 0; i < nTimeBins_; ++i) {
252 for (unsigned int j = 0; j < nZBins_; ++j) {
253 if (counts_[i][j] > 0) {
254 histograms_[i][j] /= counts_[i][j];
255 for (unsigned int k = 0; k < 3; k++) {
256 idimHistograms_[k][i][j] /= counts_[i][j];
257 }
258 } else {
259 histograms_[i][j] = 0;
260 for (unsigned int k = 0; k < 3; k++) {
261 idimHistograms_[k][i][j] = 0;
262 }
263 }
264 }
265 }
266 }
267 void RCorrFuncZ::writeCorrelate() {
268 std::ofstream ofs(getOutputFileName().c_str());
269
270 if (ofs.is_open()) {
271 Revision r;
272
273 ofs << "# " << getCorrFuncType() << "\n";
274 ofs << "# OpenMD " << r.getFullRevision() << "\n";
275 ofs << "# " << r.getBuildDate() << "\n";
276 ofs << "# selection script1: \"" << selectionScript1_;
277 ofs << "\"\tselection script2: \"" << selectionScript2_ << "\"\n";
278 ofs << "# privilegedAxis computed as " << axisLabel_ << " axis \n";
279 if (!paramString_.empty())
280 ofs << "# parameters: " << paramString_ << "\n";
281
282 ofs << "#time\tcorrVal\n";
283
284 for (unsigned int i = 0; i < nTimeBins_; ++i) {
285 ofs << times_[i] - times_[0];
286
287 for (unsigned int j = 0; j < nZBins_; ++j) {
288 ofs << "\t" << histograms_[i][j];
289 }
290 ofs << "\n";
291 }
292
293 ofs << "&\n#time\tcorrValXZ\n";
294
295 for (unsigned int i = 0; i < nTimeBins_; ++i) {
296 ofs << times_[i] - times_[0];
297
298 for (unsigned int j = 0; j < nZBins_; ++j) {
299 ofs << "\t" << idimHistograms_[0][i][j];
300 }
301 ofs << "\n";
302 }
303
304 ofs << "&\n#time\tcorrValYZ\n";
305
306 for (unsigned int i = 0; i < nTimeBins_; ++i) {
307 ofs << times_[i] - times_[0];
308
309 for (unsigned int j = 0; j < nZBins_; ++j) {
310 ofs << "\t" << idimHistograms_[1][i][j];
311 }
312 ofs << "\n";
313 }
314
315 ofs << "&\n#time\tcorrValZZ\n";
316
317 for (unsigned int i = 0; i < nTimeBins_; ++i) {
318 ofs << times_[i] - times_[0];
319
320 for (unsigned int j = 0; j < nZBins_; ++j) {
321 ofs << "\t" << idimHistograms_[2][i][j];
322 }
323 ofs << "\n";
324 }
325
326 } else {
327 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
328 "RCorrFuncZ::writeCorrelate Error: fail to open %s\n",
329 getOutputFileName().c_str());
330 painCave.isFatal = 1;
331 simError();
332 }
333 ofs.close();
334 }
335
336 int RCorrFuncR::computeProperty1(int frame, StuntDouble* sd) {
337 // get the radial vector from the frame's center of mass:
338 Vector3d coord_t = sd->getPos() - sd->getCOM();
339
340 positions_[frame].push_back(coord_t.length());
341 return positions_[frame].size() - 1;
342 }
343
344 RealType RCorrFuncR::calcCorrVal(int frame1, int frame2, int id1, int id2) {
345 RealType dr;
346 dr = positions_[frame2][id2] - positions_[frame1][id1];
347 return dr * dr;
348 }
349} // namespace OpenMD
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:96
Real lengthSquare() const
Returns the squared length of this vector.
Definition Vector.hpp:403
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)