OpenMD 3.2
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
TranslationalOrderParamZ.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/staticProps/TranslationalOrderParamZ.hpp"
49
50#include <algorithm>
51#include <fstream>
52#include <vector>
53
54#include "io/DumpReader.hpp"
56#include "utils/simError.h"
57
58using namespace std;
59namespace OpenMD {
60 TranslationalOrderParamZ::TranslationalOrderParamZ(
61 SimInfo* info, const std::string& filename, const std::string& sele1,
62 const std::string& sele2, double rCut, int nrbins, int nzbins,
63 RealType len, RealType zlen, int axis) :
64 RadialDistrFunc(info, filename, sele1, sele2, nrbins),
65 rCut_(rCut), nZBins_(nzbins), len_(len), zLen_(zlen), axis_(axis) {
66 setOutputName(getPrefix(filename) + ".Tz");
67
68 deltaR_ = len_ / (double)nBins_;
69 deltaZ_ = zLen_ / (double)nZBins_;
70
71 histogram_.resize(nBins_);
72 avgGofr_.resize(nBins_);
73 for (unsigned int i = 0; i < nBins_; ++i) {
74 histogram_[i].resize(nZBins_);
75 avgGofr_[i].resize(nZBins_);
76 }
77 Tz_.resize(nZBins_);
78
79 // Set up cutoff radius:
80 rCut_ = rCut;
81
82 // Compute complementary axes to the privileged axis
83 xaxis_ = (axis_ + 1) % 3;
84 yaxis_ = (axis_ + 2) % 3;
85
86 // Set the axis label for the privileged axis
87 switch (axis_) {
88 case 0:
89 axisLabel_ = "x";
90 break;
91 case 1:
92 axisLabel_ = "y";
93 break;
94 case 2:
95 default:
96 axisLabel_ = "z";
97 break;
98 }
99 }
100
101 void TranslationalOrderParamZ::preProcess() {
102 for (unsigned int i = 0; i < avgGofr_.size(); ++i) {
103 std::fill(avgGofr_[i].begin(), avgGofr_[i].end(), 0);
104 }
105 std::fill(Tz_.begin(), Tz_.end(), 0);
106 }
107
108 void TranslationalOrderParamZ::initializeHistogram() {
109 for (unsigned int i = 0; i < histogram_.size(); ++i) {
110 std::fill(histogram_[i].begin(), histogram_[i].end(), 0);
111 }
112 Mat3x3d hmat = currentSnapshot_->getHmat();
113 zBox_.push_back(hmat(axis_, axis_));
114 }
115
116 void TranslationalOrderParamZ::collectHistogram(StuntDouble* sd1,
117 StuntDouble* sd2) {
118 if (sd1 == sd2) { return; }
119
120 bool usePeriodicBoundaryConditions_ =
121 info_->getSimParams()->getUsePeriodicBoundaryConditions();
122 RealType boxZ = zBox_.back();
123
124 Vector3d pos1 = sd1->getPos();
125 Vector3d pos2 = sd2->getPos();
126 Vector3d r12 = pos2 - pos1;
127 if (usePeriodicBoundaryConditions_) {
128 currentSnapshot_->wrapVector(r12);
129 currentSnapshot_->wrapVector(pos1);
130 currentSnapshot_->wrapVector(pos2);
131 }
132
133 RealType distance = r12.length();
134
135 if (distance < len_) {
136 int whichBin = int(distance / deltaR_);
137 int zBin1 = int(nZBins_ * (0.5 * boxZ + pos1[axis_]) / boxZ);
138 int zBin2 = int(nZBins_ * (0.5 * boxZ + pos2[axis_]) / boxZ);
139
140 histogram_[whichBin][zBin1] += 1;
141 histogram_[whichBin][zBin2] += 1;
142 }
143 }
144
145 void TranslationalOrderParamZ::processHistogram() {
146 int nPairs = getNPairs();
147 RealType volume =
148 info_->getSnapshotManager()->getCurrentSnapshot()->getVolume();
149 RealType pairDensity = 2 * nPairs / volume;
150
151 for (unsigned int i = 0; i < histogram_.size(); ++i) {
152 RealType rLower = i * deltaR_;
153 RealType rUpper = rLower + deltaR_;
154 RealType volSlice =
155 4.0 * Constants::PI * (pow(rUpper, 3) - pow(rLower, 3)) / 3.0;
156 RealType nIdeal = volSlice * pairDensity / nZBins_;
157
158 for (unsigned int j = 0; j < histogram_[i].size(); ++j) {
159 avgGofr_[i][j] += histogram_[i][j] / nIdeal;
160 }
161 }
162 }
163
164 void TranslationalOrderParamZ::postProcess() {
165 for (unsigned int i = 0; i < avgGofr_.size(); ++i) {
166 for (unsigned int j = 0; j < avgGofr_[i].size(); ++j) {
167 avgGofr_[i][j] /= nProcessed_;
168 }
169 }
170
171 for (unsigned int i = 0; i < avgGofr_.size(); ++i) {
172 RealType rLower = i * deltaR_;
173 RealType rUpper = rLower + deltaR_;
174
175 for (unsigned int j = 0; j < avgGofr_[i].size(); ++j) {
176 if (rUpper < rCut_) Tz_[j] += std::fabs(avgGofr_[i][j] - 1.0) * deltaR_;
177 }
178 }
179
180 // normalize by cutoff radius
181 for (unsigned int j = 0; j < Tz_.size(); ++j) {
182 Tz_[j] /= rCut_;
183 }
184 }
185
186 void TranslationalOrderParamZ::writeRdf() {
187 // compute average box length:
188
189 RealType zSum = 0.0;
190 for (std::vector<RealType>::iterator j = zBox_.begin(); j != zBox_.end();
191 ++j) {
192 zSum += *j;
193 }
194 RealType zAve = zSum / zBox_.size();
195
196 std::ofstream tZstream(outputFilename_.c_str());
197 if (tZstream.is_open()) {
198 tZstream << "#Translational Order Parameters (" << axisLabel_ << ")\n";
199
200 tZstream << "#nFrames:\t" << zBox_.size() << "\n";
201 tZstream << "#selection 1: (" << selectionScript1_ << ")\n";
202 tZstream << "#selection 2: (" << selectionScript2_ << ")\n";
203 tZstream << "#" << axisLabel_ << "\tT\n";
204
205 // for (unsigned int i = 0; i < avgGofr_.size(); ++i) {
206 // RealType r = i * deltaR_;
207 // tZstream << r << "\t" ;
208 // for (unsigned int j = 0; j < avgGofr_[i].size(); ++j) {
209 // tZstream << "\t" << avgGofr_[i][j];
210 // }
211 // tZstream << "\n";
212 // }
213
214 for (unsigned int i = 0; i < Tz_.size(); ++i) {
215 RealType z = zAve * (i + 0.5) / Tz_.size();
216 tZstream << z << "\t" << Tz_[i] << "\n";
217 }
218
219 } else {
220 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
221 "TranslationalOrderParamZ: unable to open %s\n",
222 outputFilename_.c_str());
223 painCave.isFatal = 1;
224 simError();
225 }
226 tZstream.close();
227 }
228} // namespace OpenMD
Radial Distribution Function.
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition SimInfo.hpp:96
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)
Real distance(const DynamicVector< Real > &v1, const DynamicVector< Real > &v2)
Returns the distance between two DynamicVectors.