OpenMD 3.1
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
MomentumCorrFunc.cpp
1/*
2 * Copyright (c) 2005 The University of Notre Dame. All Rights Reserved.
3 *
4 * The University of Notre Dame grants you ("Licensee") a
5 * non-exclusive, royalty free, license to use, modify and
6 * redistribute this software in source and binary code form, provided
7 * that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the
15 * distribution.
16 *
17 * This software is provided "AS IS," without a warranty of any
18 * kind. All express or implied conditions, representations and
19 * warranties, including any implied warranty of merchantability,
20 * fitness for a particular purpose or non-infringement, are hereby
21 * excluded. The University of Notre Dame and its licensors shall not
22 * be liable for any damages suffered by licensee as a result of
23 * using, modifying or distributing the software or its
24 * derivatives. In no event will the University of Notre Dame or its
25 * licensors be liable for any lost revenue, profit or data, or for
26 * direct, indirect, special, consequential, incidental or punitive
27 * damages, however caused and regardless of the theory of liability,
28 * arising out of the use of or inability to use software, even if the
29 * University of Notre Dame has been advised of the possibility of
30 * such damages.
31 *
32 * SUPPORT OPEN SCIENCE! If you use OpenMD or its source code in your
33 * research, please cite the appropriate papers when you publish your
34 * work. Good starting points are:
35 *
36 * [1] Meineke, et al., J. Comp. Chem. 26, 252-271 (2005).
37 * [2] Fennell & Gezelter, J. Chem. Phys. 124, 234104 (2006).
38 * [3] Sun, Lin & Gezelter, J. Chem. Phys. 128, 234107 (2008).
39 * [4] Kuang & Gezelter, J. Chem. Phys. 133, 164101 (2010).
40 * [5] Vardeman, Stocker & Gezelter, J. Chem. Theory Comput. 7, 834 (2011).
41 */
42
43 /* Uses the Helfand-moment method for calculating thermal
44 * conductivity using the relation kappa = (N,V)lim(t)->inf 1/(2*k_B*T^2*V*t) <[G_K(t)-G_K(0)]^2>
45 * where G_K is the Helfand moment for thermal conductivity definded as
46 * G_K(t) = sum_{a=1}{^N} x_a(E_a-<E_a>) and E_a is defined to be
47 * E_a = p_2^2/(2*m)+1/2 sum_{b.ne.a} u(r_ab) where p is momentum and u is pot energy for the
48 * particle pair a-b. This routine calculates E_a, <E_a> and does the correlation
49 * <[G_K(t)-G_K(0)]^2>.
50 * See Viscardy et al. JCP 126, 184513 (2007)
51 */
52
53#include "applications/dynamicProps/MomentumCorrFunc.hpp"
54#include "utils/Revision.hpp"
56
57namespace OpenMD {
58
59 // We need all of the positions, velocities, etc. so that we can
60 // recalculate pressures and actions on the fly:
61 MomentumCorrFunc::MomentumCorrFunc(SimInfo* info, const std::string& filename,
62 const std::string& sele1,
63 const std::string& sele2)
64 : FrameTimeCorrFunc<Mat3x3d>(info, filename, sele1, sele2,
65 DataStorage::dslPosition |
66 DataStorage::dslVelocity){
67
68 setCorrFuncType("MomentumCorrFunc");
69 setOutputName(getPrefix(dumpFilename_) + ".momcorr");
70 }
71
72 void MomentumCorrFunc::correlateFrames(int frame1, int frame2) {
73 SimInfo::MoleculeIterator mi1;
74 SimInfo::MoleculeIterator mi2;
75 Molecule* mol1;
76 Molecule* mol2;
77 Molecule::AtomIterator ai1;
78 Molecule::AtomIterator ai2;
79 Atom* atom1;
80 Atom* atom2;
81
82 std::vector<Vector3d> atomPositions1;
83 std::vector<Vector3d> atomPositions2;
84 std::vector<Vector3d> atomVelocity1;
85 std::vector<Vector3d> atomVelocity2;
86 int thisAtom1, thisAtom2;
87
88 Snapshot* snapshot1 = bsMan_->getSnapshot(frame1);
89 Snapshot* snapshot2 = bsMan_->getSnapshot(frame2);
90
91 assert(snapshot1 && snapshot2);
92
93 RealType time1 = snapshot1->getTime();
94 RealType time2 = snapshot2->getTime();
95
96 int timeBin = int ((time2 - time1) /deltaTime_ + 0.5);
97
98 atomPositions1.clear();
99 for (mol1 = info_->beginMolecule(mi1); mol1 != NULL;
100 mol1 = info_->nextMolecule(mi1)) {
101 for(atom1 = mol1->beginAtom(ai1); atom1 != NULL;
102 atom1 = mol1->nextAtom(ai1)) {
103 atomPositions1.push_back(atom1->getPos(frame1));
104 atomVelocity1.push_back(atom1->getVel(frame1));
105 }
106 }
107
108 atomPositions2.clear();
109 for (mol2 = info_->beginMolecule(mi2); mol2 != NULL;
110 mol2 = info_->nextMolecule(mi2)) {
111 for(atom2 = mol2->beginAtom(ai2); atom2 != NULL;
112 atom2 = mol2->nextAtom(ai2)) {
113 atomPositions2.push_back(atom2->getPos(frame2));
114 atomVelocity2.push_back(atom2->getVel(frame2));
115 }
116 }
117
118 thisAtom1 = 0;
119
120 for (mol1 = info_->beginMolecule(mi1); mol1 != NULL;
121 mol1 = info_->nextMolecule(mi1)) {
122 for(atom1 = mol1->beginAtom(ai1); atom1 != NULL;
123 atom1 = mol1->nextAtom(ai1)) {
124
125 Vector3d r1 = atomPositions1[thisAtom1];
126 Vector3d p1 = atom1->getMass() * atomVelocity1[thisAtom1];
127
128 thisAtom2 = 0;
129
130 for (mol2 = info_->beginMolecule(mi2); mol2 != NULL;
131 mol2 = info_->nextMolecule(mi2)) {
132 for(atom2 = mol2->beginAtom(ai2); atom2 != NULL;
133 atom2 = mol2->nextAtom(ai2)) {
134
135 Vector3d r2 = atomPositions2[thisAtom2];
136 Vector3d p2 = atom2->getMass() * atomVelocity1[thisAtom1];
137
138 Vector3d deltaPos = (r2-r1);
139 Vector3d dp2( deltaPos.x() * deltaPos.x(),
140 deltaPos.y() * deltaPos.y(),
141 deltaPos.z() * deltaPos.z());
142 Vector3d pprod( p1.x() * p2.x(),
143 p1.y() * p2.y(),
144 p1.z() * p2.z());
145
146 histogram_[timeBin] += outProduct(dp2, pprod);
147
148 thisAtom2++;
149 }
150 }
151 thisAtom1++;
152 }
153 }
154 count_[timeBin]++;
155 }
156
157 void MomentumCorrFunc::postCorrelate() {
158 for (unsigned int i =0 ; i < nTimeBins_; ++i) {
159 if (count_[i] > 0) {
160 histogram_[i] /= count_[i];
161 }
162 }
163 }
164
165 void MomentumCorrFunc::preCorrelate() {
166 // Fill the histogram with empty 3x3 matrices:
167 std::fill(histogram_.begin(), histogram_.end(), Mat3x3d(0.0));
168 // count array set to zero
169 std::fill(count_.begin(), count_.end(), 0);
170 }
171
172 void MomentumCorrFunc::writeCorrelate() {
173 std::ofstream ofs(getOutputFileName().c_str());
174
175 if (ofs.is_open()) {
176 Revision r;
177
178 ofs << "# " << getCorrFuncType() << "\n";
179 ofs << "# OpenMD " << r.getFullRevision() << "\n";
180 ofs << "# " << r.getBuildDate() << "\n";
181 ofs << "# selection script1: \"" << selectionScript1_ ;
182 ofs << "\"\tselection script2: \"" << selectionScript2_ << "\"\n";
183 if (!paramString_.empty())
184 ofs << "# parameters: " << paramString_ << "\n";
185
186 ofs << "#time\tcorrTensor\txx\txy\txz\tyx\tyy\tyz\tzx\tzy\tzz\n";
187
188 for (unsigned int i = 0; i < nTimeBins_; ++i) {
189 ofs << time_[i] << "\t" <<
190 histogram_[i](0,0) << "\t" <<
191 histogram_[i](0,1) << "\t" <<
192 histogram_[i](0,2) << "\t" <<
193 histogram_[i](1,0) << "\t" <<
194 histogram_[i](1,1) << "\t" <<
195 histogram_[i](1,2) << "\t" <<
196 histogram_[i](2,0) << "\t" <<
197 histogram_[i](2,1) << "\t" <<
198 histogram_[i](2,2) << "\t" << "\n";
199 }
200
201 } else {
202 snprintf(painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
203 "MomentumCorrFunc::writeCorrelate Error: fail to open %s\n",
204 getOutputFileName().c_str());
205 painCave.isFatal = 1;
206 simError();
207 }
208 ofs.close();
209 }
210}
211
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
std::string getPrefix(const std::string &str)