45#include "hydrodynamics/HydroProp.hpp"
47#include "math/CholeskyDecomposition.hpp"
49#include "utils/simError.h"
53 HydroProp::HydroProp() : hasCOR_(false), hasXi_(false), hasS_(false) {}
55 HydroProp::HydroProp(Vector3d cor, Mat6x6d Xi) :
56 cor_(cor), Xi_(Xi), hasCOR_(true), hasXi_(true), hasS_(false) {}
58 void HydroProp::complete() {
60 CholeskyDecomposition(Xi_, S_);
64 painCave.errMsg, MAX_SIM_ERROR_MSG_LENGTH,
65 "HydroProp was asked to complete without a Resistance Tensor.\n");
66 painCave.severity = OPENMD_ERROR;
72 Mat6x6d HydroProp::getS() {
73 if (!hasS_) { complete(); }
77 Mat3x3d HydroProp::getXitt() {
79 Xi_.getSubMatrix(0, 0, Xitt);
82 Mat3x3d HydroProp::getXirt() {
84 Xi_.getSubMatrix(0, 3, Xirt);
87 Mat3x3d HydroProp::getXitr() {
89 Xi_.getSubMatrix(3, 0, Xitr);
92 Mat3x3d HydroProp::getXirr() {
94 Xi_.getSubMatrix(3, 3, Xirr);
98 Mat6x6d HydroProp::getDiffusionTensor(RealType temperature) {
102 RealType kt = Constants::kb * temperature;
107 Mat6x6d HydroProp::getResistanceTensorAtPos(Vector3d pos) {
111 Vector3d cp = pos - cor_;
115 Mat3x3d Xitt = getXitt();
116 Mat3x3d Xitr = getXitr();
117 Mat3x3d Xirr = getXirr();
125 Xipostr = (Xitr - U * Xitt);
126 Xiposrr = Xirr - U * Xitt * U + Xitr * U - U * Xitr.transpose();
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);
136 Mat6x6d HydroProp::getDiffusionTensorAtPos(Vector3d pos,
137 RealType temperature) {
142 Vector3d cp = pos - cor_;
146 Mat6x6d D = getDiffusionTensor(temperature);
152 D.getSubMatrix(0, 0, Dtt);
153 D.getSubMatrix(3, 0, Dtr);
154 D.getSubMatrix(3, 3, Drr);
162 Dpostt = Dtt - U * Drr * U + Dtr.transpose() * U - U * Dtr;
164 Dpostr = Dtr + Drr * U;
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);
174 Vector3d HydroProp::getCenterOfDiffusion(RealType temperature) {
177 Vector3d origin(0.0);
178 Mat6x6d Do = getDiffusionTensorAtPos(origin, temperature);
183 Do.getSubMatrix(3, 0, Dotr);
184 Do.getSubMatrix(3, 3, Dorr);
190 tmp(0, 0) = Dorr(1, 1) + Dorr(2, 2);
191 tmp(0, 1) = -Dorr(0, 1);
192 tmp(0, 2) = -Dorr(0, 2);
193 tmp(1, 0) = -Dorr(0, 1);
194 tmp(1, 1) = Dorr(0, 0) + Dorr(2, 2);
195 tmp(1, 2) = -Dorr(1, 2);
196 tmp(2, 0) = -Dorr(0, 2);
197 tmp(2, 1) = -Dorr(1, 2);
198 tmp(2, 2) = Dorr(1, 1) + Dorr(0, 0);
201 tmpVec[0] = Dotr(1, 2) - Dotr(2, 1);
202 tmpVec[1] = Dotr(2, 0) - Dotr(0, 2);
203 tmpVec[2] = Dotr(0, 1) - Dotr(1, 0);
206 Vector3d cod = tmp.inverse() * tmpVec;
210 Mat3x3d HydroProp::getPitchMatrix() {
212 P = -getXitt().
inverse() * getXirt();
216 RealType HydroProp::getScalarPitch() {
217 Mat3x3d P = getPitchMatrix();
220 Mat3x3d::diagonalize(P, evals, evects);
221 RealType pScalar(0.0);
223 for (
int i = 0; i < 3; i++) {
224 pScalar += pow(evals[i], 2);
228 return sqrt(pScalar);
231 void HydroProp::pitchAxes(Mat3x3d& pitchAxes, Vector3d& pitches,
232 RealType& pitchScalar) {
233 Mat3x3d P = getPitchMatrix();
235 Mat3x3d::diagonalize(P, pitches, pitchAxes);
238 for (
int i = 0; i < 3; i++) {
239 pitchScalar += pow(pitches[i], 2);
243 pitchScalar = sqrt(pitchScalar);
246 Vector3d HydroProp::getCenterOfPitch() {
247 Mat3x3d P = getPitchMatrix();
249 cop[0] = 0.5 * (P(1, 2) - P(2, 1));
250 cop[1] = 0.5 * (P(2, 0) - P(0, 2));
251 cop[2] = 0.5 * (P(0, 1) - P(1, 0));
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.