OpenMD 3.1
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
ChargeZ.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/*
46 * Computes the charge density distribution along preferred axis for the
47 * selected atom Created by Cody R. Drisko on 06/14/14.
48 */
49
50#include "applications/staticProps/ChargeZ.hpp"
51
52#include <algorithm>
53#include <fstream>
54
55#include "brains/Thermo.hpp"
56#include "io/DumpReader.hpp"
58#include "types/FixedChargeAdapter.hpp"
59#include "types/FluctuatingChargeAdapter.hpp"
60#include "utils/simError.h"
61
62namespace OpenMD {
63
64 ChargeZ::ChargeZ(SimInfo* info, const std::string& filename,
65 const std::string& sele, int nzbins, int axis) :
66 StaticAnalyser(info, filename, nzbins),
67 selectionScript_(sele), evaluator_(info), seleMan_(info), thermo_(info),
68 axis_(axis) {
69 evaluator_.loadScriptString(sele);
70 if (!evaluator_.isDynamic()) {
71 seleMan_.setSelectionSet(evaluator_.evaluate());
72 }
73
74 // fixed number of bins
75
76 sliceSDLists_.resize(nBins_);
77 sliceSDCount_.resize(nBins_);
78 std::fill(sliceSDCount_.begin(), sliceSDCount_.end(), 0);
79
80 chargeZ_.resize(nBins_);
81
82 switch (axis_) {
83 case 0:
84 axisLabel_ = "x";
85 break;
86 case 1:
87 axisLabel_ = "y";
88 break;
89 case 2:
90 default:
91 axisLabel_ = "z";
92 break;
93 }
94
95 setOutputName(getPrefix(filename) + ".ChargeZ");
96 }
97
98 void ChargeZ::process() {
99 StuntDouble* sd;
100 int ii;
101
102 bool usePeriodicBoundaryConditions_ =
103 info_->getSimParams()->getUsePeriodicBoundaryConditions();
104
105 DumpReader reader(info_, dumpFilename_);
106 int nFrames = reader.getNFrames();
107 nProcessed_ = nFrames / step_;
108
109 for (int istep = 0; istep < nFrames; istep += step_) {
110 reader.readFrame(istep);
111 currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
112
113 for (unsigned int i = 0; i < nBins_; i++) {
114 sliceSDLists_[i].clear();
115 }
116
117 Mat3x3d hmat = currentSnapshot_->getHmat();
118 zBox_.push_back(hmat(axis_, axis_));
119
120 RealType halfBoxZ_ = hmat(axis_, axis_) / 2.0;
121 RealType area = 0.0;
122 switch (axis_) {
123 case 0:
124 area = currentSnapshot_->getYZarea();
125 break;
126 case 1:
127 area = currentSnapshot_->getXZarea();
128 break;
129 case 2:
130 default:
131 area = currentSnapshot_->getXYarea();
132 break;
133 }
134
135 areas_.push_back(area);
136
137 if (evaluator_.isDynamic()) {
138 seleMan_.setSelectionSet(evaluator_.evaluate());
139 }
140
141 // wrap the stuntdoubles into a cell
142 for (sd = seleMan_.beginSelected(ii); sd != NULL;
143 sd = seleMan_.nextSelected(ii)) {
144 Vector3d pos = sd->getPos();
145 if (usePeriodicBoundaryConditions_) currentSnapshot_->wrapVector(pos);
146 sd->setPos(pos);
147 }
148
149 // determine which atom belongs to which slice
150 for (sd = seleMan_.beginSelected(ii); sd != NULL;
151 sd = seleMan_.nextSelected(ii)) {
152 Vector3d pos = sd->getPos();
153 // shift molecules by half a box to have bins start at 0
154 int binNo = int(nBins_ * (halfBoxZ_ + pos[axis_]) / hmat(axis_, axis_));
155 sliceSDLists_[binNo].push_back(sd);
156 sliceSDCount_[binNo]++;
157 }
158
159 // loop over the slices to calculate the charge
160 for (unsigned int i = 0; i < nBins_; i++) {
161 RealType binC = 0;
162 for (unsigned int k = 0; k < sliceSDLists_[i].size(); ++k) {
163 RealType q = 0.0;
164 Atom* atom = static_cast<Atom*>(sliceSDLists_[i][k]);
165
166 AtomType* atomType = atom->getAtomType();
167
168 if (sliceSDLists_[i][k]->isAtom()) {
170 if (fca.isFixedCharge()) { q += fca.getCharge(); }
171
173 if (fqa.isFluctuatingCharge()) { q += atom->getFlucQPos(); }
174 }
175
176 binC += q;
177 }
178 chargeZ_[i] += binC;
179 // Units of (e / Ang^2 / fs)
180 }
181 }
182
183 writeChargeZ();
184 }
185
186 void ChargeZ::writeChargeZ() {
187 // compute average box length:
188 std::vector<RealType>::iterator j;
189 RealType zSum = 0.0;
190 for (j = zBox_.begin(); j != zBox_.end(); ++j) {
191 zSum += *j;
192 }
193 RealType zAve = zSum / zBox_.size();
194
195 RealType areaSum = 0.0;
196 for (j = areas_.begin(); j != areas_.end(); ++j) {
197 areaSum += *j;
198 }
199 RealType areaAve = areaSum / areas_.size();
200
201 std::ofstream rdfStream(outputFilename_.c_str());
202 if (rdfStream.is_open()) {
203 rdfStream << "#ChargeZ "
204 << "\n";
205 rdfStream << "#selection: (" << selectionScript_ << ")\n";
206 rdfStream << "#" << axisLabel_ << "\tcharge\n";
207 RealType binCharge;
208 for (unsigned int i = 0; i < chargeZ_.size(); ++i) {
209 RealType z = zAve * (i + 0.5) / chargeZ_.size();
210
211 RealType volSlice = areaAve * zAve / zBox_.size();
212
213 binCharge = chargeZ_[i] / (volSlice * nProcessed_);
214
215 rdfStream << z << "\t" << binCharge << "\n";
216 }
217
218 } else {
219 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
220 "ChargeZ: unable to open %s\n", outputFilename_.c_str());
221 painCave.isFatal = 1;
222 simError();
223 }
224
225 rdfStream.close();
226 }
227} // namespace OpenMD
AtomType * getAtomType()
Returns the AtomType of this Atom.
Definition A.hpp:93
AtomType is what OpenMD looks to for unchanging data about an atom.
Definition AtomType.hpp:66
bool isDynamic()
Tests if the result from evaluation of script is dynamic.
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
SnapshotManager * getSnapshotManager()
Returns the snapshot manager.
Definition SimInfo.hpp:248
Mat3x3d getHmat()
Returns the H-Matrix.
Definition Snapshot.cpp:214
void wrapVector(Vector3d &v)
Wrapping the vector according to periodic boundary condition.
Definition Snapshot.cpp:337
Snapshot * getCurrentSnapshot()
Returns the pointer of current snapshot.
"Don't move, or you're dead! Stand up! Captain, we've got them!"
Vector3d getPos()
Returns the current position of this stuntDouble.
RealType getFlucQPos()
Returns the current fluctuating charge of this stuntDouble.
void setPos(const Vector3d &pos)
Sets the current position of this stuntDouble.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)