OpenMD
3.2
Molecular Dynamics in the Open
Toggle main menu visibility
Loading...
Searching...
No Matches
PotDiff.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/PotDiff.hpp
"
49
50
#include <algorithm>
51
#include <functional>
52
53
#include "
brains/ForceManager.hpp
"
54
#include "
brains/SimSnapshotManager.hpp
"
55
#include "
io/DumpReader.hpp
"
56
#include "
primitives/Molecule.hpp
"
57
#include "types/FixedChargeAdapter.hpp"
58
#include "types/FluctuatingChargeAdapter.hpp"
59
#include "utils/simError.h"
60
61
namespace
OpenMD
{
62
63
PotDiff::PotDiff
(
SimInfo
* info,
const
std::string& filename,
64
const
std::string& sele) :
65
StaticAnalyser(info, filename, 1),
66
selectionScript_(sele), seleMan_(info), evaluator_(info) {
67
StuntDouble
* sd;
68
int
i;
69
70
setOutputName(
getPrefix
(filename) +
".potDiff"
);
71
72
// The PotDiff is computed by negating the charge on the atom type
73
// using fluctuating charge values. If we don't have any
74
// fluctuating charges in the simulation, we need to expand
75
// storage to hold them.
76
int
atomStorageLayout = info_->getAtomStorageLayout();
77
int
rigidBodyStorageLayout = info->getRigidBodyStorageLayout();
78
int
cutoffGroupStorageLayout = info->getCutoffGroupStorageLayout();
79
80
atomStorageLayout |= DataStorage::dslFlucQPosition;
81
atomStorageLayout |= DataStorage::dslFlucQVelocity;
82
atomStorageLayout |= DataStorage::dslFlucQForce;
83
84
info_->setAtomStorageLayout(atomStorageLayout);
85
info_->setSnapshotManager(
new
SimSnapshotManager
(info_, atomStorageLayout,
86
rigidBodyStorageLayout,
87
cutoffGroupStorageLayout));
88
89
// now we have to figure out which AtomTypes to convert to fluctuating
90
// charges
91
evaluator_.loadScriptString(sele);
92
seleMan_.setSelectionSet(evaluator_.evaluate());
93
for
(sd = seleMan_.beginSelected(i); sd != NULL;
94
sd = seleMan_.nextSelected(i)) {
95
AtomType
* at =
static_cast<
Atom
*
>
(sd)->getAtomType();
96
FluctuatingChargeAdapter
fqa =
FluctuatingChargeAdapter
(at);
97
if
(fqa.isFluctuatingCharge()) {
98
selectionWasFlucQ_.push_back(
true
);
99
}
else
{
100
selectionWasFlucQ_.push_back(
false
);
101
// make a fictitious fluctuating charge with an unphysical
102
// charge mass and slaterN, but we need to zero out the
103
// electronegativity and hardness to remove the self
104
// contribution:
105
fqa.makeFluctuatingCharge(1.0e9, 0.0, 0.0, 1);
106
sd->
setFlucQPos
(0.0);
107
}
108
}
109
info_->getSnapshotManager()->advance();
110
}
111
112
void
PotDiff::process
() {
113
StuntDouble
* sd;
114
int
j;
115
116
diff_.clear();
117
DumpReader
reader(info_, dumpFilename_);
118
int
nFrames = reader.
getNFrames
();
119
120
// We'll need the force manager to compute the potential
121
ForceManager
* forceMan =
new
ForceManager
(info_);
122
123
// We'll need thermo to report the potential
124
Thermo
* thermo =
new
Thermo
(info_);
125
126
for
(
int
i = 0; i < nFrames; i += step_) {
127
reader.readFrame(i);
128
currentSnapshot_ = info_->getSnapshotManager()->getCurrentSnapshot();
129
130
for
(sd = seleMan_.beginSelected(j); sd != NULL;
131
sd = seleMan_.nextSelected(j)) {
132
if
(!selectionWasFlucQ_[j]) { sd->
setFlucQPos
(0.0); }
133
}
134
135
forceMan->calcForces();
136
RealType pot1 = thermo->getPotential();
137
138
if
(evaluator_.isDynamic()) {
139
seleMan_.setSelectionSet(evaluator_.evaluate());
140
}
141
142
for
(sd = seleMan_.beginSelected(j); sd != NULL;
143
sd = seleMan_.nextSelected(j)) {
144
AtomType
* at =
static_cast<
Atom
*
>
(sd)->getAtomType();
145
146
FixedChargeAdapter
fca =
FixedChargeAdapter
(at);
147
FluctuatingChargeAdapter
fqa =
FluctuatingChargeAdapter
(at);
148
149
RealType charge = 0.0;
150
151
if
(fca.isFixedCharge()) charge += fca.getCharge();
152
if
(fqa.isFluctuatingCharge()) charge += sd->
getFlucQPos
();
153
154
sd->
setFlucQPos
(-charge);
155
}
156
157
currentSnapshot_->clearDerivedProperties();
158
forceMan->calcForces();
159
RealType pot2 = thermo->getPotential();
160
RealType diff = pot2 - pot1;
161
162
data_.add(diff);
163
diff_.push_back(diff);
164
times_.push_back(currentSnapshot_->getTime());
165
166
info_->getSnapshotManager()->advance();
167
}
168
169
writeDiff();
170
}
171
172
void
PotDiff::writeDiff() {
173
std::ofstream ofs(outputFilename_.c_str(), std::ios::binary);
174
if
(ofs.is_open()) {
175
RealType mu = data_.getAverage();
176
RealType sigma = data_.getStdDev();
177
RealType m95 = data_.get95percentConfidenceInterval();
178
179
ofs <<
"#potDiff\n"
;
180
ofs <<
"#selection: ("
<< selectionScript_ <<
")\n"
;
181
ofs <<
"# <diff> = "
<< mu <<
"\n"
;
182
ofs <<
"# StdDev = "
<< sigma <<
"\n"
;
183
ofs <<
"# 95% confidence interval = "
<< m95 <<
"\n"
;
184
ofs <<
"# t\tdiff[t]\n"
;
185
for
(
unsigned
int
i = 0; i < diff_.size(); ++i) {
186
ofs << times_[i] <<
"\t"
<< diff_[i] <<
"\n"
;
187
}
188
189
}
else
{
190
snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
191
"PotDiff: unable to open %s\n"
, outputFilename_.c_str());
192
painCave.isFatal = 1;
193
simError();
194
}
195
ofs.close();
196
}
197
198
}
// namespace OpenMD
DumpReader.hpp
ForceManager.hpp
Molecule.hpp
PotDiff.hpp
StaticAnalyser for Potential Energy changes with charges turned off.
SimSnapshotManager.hpp
OpenMD::Atom
Definition
Atom.hpp:62
OpenMD::AtomType
AtomType is what OpenMD looks to for unchanging data about an atom.
Definition
AtomType.hpp:69
OpenMD::DumpReader
Definition
DumpReader.hpp:70
OpenMD::DumpReader::getNFrames
int getNFrames()
Returns the number of frames in the dump file.
Definition
DumpReader.cpp:103
OpenMD::FixedChargeAdapter
Definition
FixedChargeAdapter.hpp:64
OpenMD::FluctuatingChargeAdapter
Definition
FluctuatingChargeAdapter.hpp:74
OpenMD::ForceManager
ForceManager is responsible for calculating both the short range (bonded) interactions and long range...
Definition
ForceManager.hpp:83
OpenMD::PotDiff::process
virtual void process()
Process the data.
Definition
PotDiff.cpp:112
OpenMD::PotDiff::PotDiff
PotDiff(SimInfo *info, const std::string &filename, const std::string &sele)
Default constructor.
Definition
PotDiff.cpp:63
OpenMD::SimInfo
One of the heavy-weight classes of OpenMD, SimInfo maintains objects and variables relating to the cu...
Definition
SimInfo.hpp:96
OpenMD::SimSnapshotManager
"brains/SimSnapshotManager.hpp"
Definition
SimSnapshotManager.hpp:72
OpenMD::StuntDouble
"Don't move, or you're dead! Stand up! Captain, we've got them!"
Definition
StuntDouble.hpp:94
OpenMD::StuntDouble::setFlucQPos
void setFlucQPos(RealType charge)
Sets the current fluctuating charge of this stuntDouble.
Definition
StuntDouble.hpp:962
OpenMD::StuntDouble::getFlucQPos
RealType getFlucQPos()
Returns the current fluctuating charge of this stuntDouble.
Definition
StuntDouble.hpp:933
OpenMD::Thermo
Definition
Thermo.hpp:57
OpenMD
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
Definition
ActionCorrFunc.cpp:63
OpenMD::getPrefix
std::string getPrefix(const std::string &str)
Definition
StringUtils.cpp:207
applications
staticProps
PotDiff.cpp
Generated on
for OpenMD by
1.17.0