OpenMD 3.0
Molecular Dynamics in the Open
Loading...
Searching...
No Matches
HydroProp.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#include "hydrodynamics/HydroProp.hpp"
46
47#include "math/CholeskyDecomposition.hpp"
49#include "utils/simError.h"
50
51namespace OpenMD {
52
53 HydroProp::HydroProp() : hasCOR_(false), hasXi_(false), hasS_(false) {}
54
55 HydroProp::HydroProp(Vector3d cor, Mat6x6d Xi) :
56 cor_(cor), Xi_(Xi), hasCOR_(true), hasXi_(true), hasS_(false) {}
57
58 void HydroProp::complete() {
59 if (hasXi_) {
60 CholeskyDecomposition(Xi_, S_);
61 hasS_ = true;
62 } else {
63 snprintf(
64 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
65 "HydroProp was asked to complete without a Resistance Tensor.\n");
66 painCave.severity = OPENMD_ERROR;
67 painCave.isFatal = 1;
68 simError();
69 }
70 }
71
72 Mat6x6d HydroProp::getS() {
73 if (!hasS_) { complete(); }
74 return S_;
75 }
76
77 Mat3x3d HydroProp::getXitt() {
78 Mat3x3d Xitt;
79 Xi_.getSubMatrix(0, 0, Xitt);
80 return Xitt;
81 }
82 Mat3x3d HydroProp::getXirt() {
83 Mat3x3d Xirt;
84 Xi_.getSubMatrix(0, 3, Xirt);
85 return Xirt;
86 }
87 Mat3x3d HydroProp::getXitr() {
88 Mat3x3d Xitr;
89 Xi_.getSubMatrix(3, 0, Xitr);
90 return Xitr;
91 }
92 Mat3x3d HydroProp::getXirr() {
93 Mat3x3d Xirr;
94 Xi_.getSubMatrix(3, 3, Xirr);
95 return Xirr;
96 }
97
98 Mat6x6d HydroProp::getDiffusionTensor(RealType temperature) {
99 Mat6x6d XiCopy = Xi_;
100 Mat6x6d D;
101 invertMatrix(XiCopy, D);
102 RealType kt = Constants::kb * temperature; // in kcal mol^-1
103 D *= kt; // now in angstroms^2 fs^-1 (at least for Trans-trans)
104 return D;
105 }
106
107 Mat6x6d HydroProp::getResistanceTensorAtPos(Vector3d pos) {
108 // Vector from reference point to center of resistance = cor_
109 // Vector from reference point to new location = pos
110 // Vector from center of resistance to new location = pos - cor_
111 Vector3d cp = pos - cor_;
112 Mat3x3d U;
113 U.setupSkewMat(cp);
114
115 Mat3x3d Xitt = getXitt();
116 Mat3x3d Xitr = getXitr();
117 Mat3x3d Xirr = getXirr();
118
119 Mat3x3d Xipostt;
120 Mat3x3d Xiposrr;
121 Mat3x3d Xipostr;
122
123 // Resistance tensors at the new location
124 Xipostt = Xitt;
125 Xipostr = (Xitr - U * Xitt);
126 Xiposrr = Xirr - U * Xitt * U + Xitr * U - U * Xitr.transpose();
127
128 Mat6x6d Xipos;
129 Xipos.setSubMatrix(0, 0, Xipostt);
130 Xipos.setSubMatrix(0, 3, Xipostr.transpose());
131 Xipos.setSubMatrix(3, 0, Xipostr);
132 Xipos.setSubMatrix(3, 3, Xiposrr);
133 return Xipos;
134 }
135
136 Mat6x6d HydroProp::getDiffusionTensorAtPos(Vector3d pos,
137 RealType temperature) {
138 // Vector from reference point to center of resistance = cor_
139 // Vector from reference point to new location = pos
140 // Vector from center of resistance to new location = pos - cor_
141
142 Vector3d cp = pos - cor_;
143 Mat3x3d U;
144 U.setupSkewMat(cp);
145
146 Mat6x6d D = getDiffusionTensor(temperature);
147
148 Mat3x3d Dtt;
149 Mat3x3d Dtr;
150 Mat3x3d Drr;
151
152 D.getSubMatrix(0, 0, Dtt);
153 D.getSubMatrix(3, 0, Dtr);
154 D.getSubMatrix(3, 3, Drr);
155
156 // calculate Diffusion Tensor at new location
157 Mat3x3d Dpostt; // translational diffusion tensor at new location
158 Mat3x3d Dpostr; // rotational diffusion tensor at new location
159 Mat3x3d Dposrr; // translation-rotation coupling diffusion tensor
160 // at new location
161
162 Dpostt = Dtt - U * Drr * U + Dtr.transpose() * U - U * Dtr;
163 Dposrr = Drr;
164 Dpostr = Dtr + Drr * U;
165
166 Mat6x6d Dpos;
167 Dpos.setSubMatrix(0, 0, Dpostt);
168 Dpos.setSubMatrix(0, 3, Dpostr.transpose());
169 Dpos.setSubMatrix(3, 0, Dpostr);
170 Dpos.setSubMatrix(3, 3, Dposrr);
171 return Dpos;
172 }
173
174 Vector3d HydroProp::getCenterOfDiffusion(RealType temperature) {
175 // First get the Diffusion tensor at the origin of the coordinate system:
176
177 Vector3d origin(0.0);
178 Mat6x6d Do = getDiffusionTensorAtPos(origin, temperature);
179
180 Mat3x3d Dotr;
181 Mat3x3d Dorr;
182
183 Do.getSubMatrix(3, 0, Dotr);
184 Do.getSubMatrix(3, 3, Dorr);
185
186 Mat3x3d tmp;
187 Mat3x3d tmpInv;
188 Vector3d tmpVec;
189
190 // Find center of diffusion
191 tmp(0, 0) = Dorr(1, 1) + Dorr(2, 2);
192 tmp(0, 1) = -Dorr(0, 1);
193 tmp(0, 2) = -Dorr(0, 2);
194 tmp(1, 0) = -Dorr(0, 1);
195 tmp(1, 1) = Dorr(0, 0) + Dorr(2, 2);
196 tmp(1, 2) = -Dorr(1, 2);
197 tmp(2, 0) = -Dorr(0, 2);
198 tmp(2, 1) = -Dorr(1, 2);
199 tmp(2, 2) = Dorr(1, 1) + Dorr(0, 0);
200
201 // Vector3d tmpVec;
202 tmpVec[0] = Dotr(1, 2) - Dotr(2, 1);
203 tmpVec[1] = Dotr(2, 0) - Dotr(0, 2);
204 tmpVec[2] = Dotr(0, 1) - Dotr(1, 0);
205
206 // invert tmp Matrix
207 invertMatrix(tmp, tmpInv);
208
209 // center of difussion
210 Vector3d cod = tmpInv * tmpVec;
211 return cod;
212 }
213
214 Mat3x3d HydroProp::getPitchMatrix() {
215 Mat3x3d P;
216 P = -getXitt().inverse() * getXirt();
217 return P;
218 }
219
220 RealType HydroProp::getScalarPitch() {
221 Mat3x3d P = getPitchMatrix();
222 Vector3d evals;
223 Mat3x3d evects;
224 Mat3x3d::diagonalize(P, evals, evects);
225 RealType pScalar(0.0);
226
227 for (int i = 0; i < 3; i++) {
228 pScalar += pow(evals[i], 2);
229 }
230 pScalar /= 3.0;
231
232 return sqrt(pScalar);
233 }
234
235 void HydroProp::pitchAxes(Mat3x3d& pitchAxes, Vector3d& pitches,
236 RealType& pitchScalar) {
237 Mat3x3d P = getPitchMatrix();
238
239 Mat3x3d::diagonalize(P, pitches, pitchAxes);
240
241 pitchScalar = 0.0;
242 for (int i = 0; i < 3; i++) {
243 pitchScalar += pow(pitches[i], 2);
244 }
245 pitchScalar /= 3.0;
246
247 pitchScalar = sqrt(pitchScalar);
248 }
249
250 Vector3d HydroProp::getCenterOfPitch() {
251 Mat3x3d P = getPitchMatrix();
252 Vector3d cop;
253 cop[0] = 0.5 * (P(1, 2) - P(2, 1));
254 cop[1] = 0.5 * (P(2, 0) - P(0, 2));
255 cop[2] = 0.5 * (P(0, 1) - P(1, 0));
256 // Assume Xi_ was stored at center of resistance, so center of
257 // pitch is returned relative to origin if center of resistance is
258 // not the origin:
259 return (cor_ + cop);
260 }
261
262} // namespace OpenMD
SquareMatrix3< Real > inverse() const
Sets the value of this matrix to the inverse of itself.
This basic Periodic Table class was originally taken from the data.cpp file in OpenBabel.
bool invertMatrix(MatrixType &A, MatrixType &AI)
Invert input square matrix A into matrix AI.
Definition LU.hpp:98