OGS
KelvinVector.cpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#include "KelvinVector.h"
5
6#include "BaseLib/Error.h"
7
8namespace MathLib
9{
10namespace KelvinVector
11{
12template <>
13double Invariants<6>::determinant(Eigen::Matrix<double, 6, 1> const& v)
14{
15 return v(0) * v(1) * v(2) + v(3) * v(4) * v(5) / std::sqrt(2.) -
16 v(3) * v(3) * v(2) / 2. - v(4) * v(4) * v(0) / 2. -
17 v(5) * v(5) * v(1) / 2.;
18}
19
20template <>
21double Invariants<4>::determinant(Eigen::Matrix<double, 4, 1> const& v)
22{
23 return v(2) * (v(0) * v(1) - v(3) * v(3) / 2.);
24}
25
26template <>
27Eigen::Matrix<double, 4, 1, Eigen::ColMajor, 4, 1> inverse(
28 Eigen::Matrix<double, 4, 1, Eigen::ColMajor, 4, 1> const& v)
29{
30 assert(Invariants<4>::determinant(v) != 0);
31
32 Eigen::Matrix<double, 4, 1, Eigen::ColMajor, 4, 1> inv;
33 inv(0) = v(1) * v(2);
34 inv(1) = v(0) * v(2);
35 inv(2) = v(0) * v(1) - v(3) * v(3) / 2.;
36 inv(3) = -v(3) * v(2);
37 return inv / Invariants<4>::determinant(v);
38}
39
40template <>
41Eigen::Matrix<double, 6, 1, Eigen::ColMajor, 6, 1> inverse(
42 Eigen::Matrix<double, 6, 1, Eigen::ColMajor, 6, 1> const& v)
43{
44 assert(Invariants<6>::determinant(v) != 0);
45
46 Eigen::Matrix<double, 6, 1, Eigen::ColMajor, 6, 1> inv;
47 inv(0) = v(1) * v(2) - v(4) * v(4) / 2.;
48 inv(1) = v(0) * v(2) - v(5) * v(5) / 2.;
49 inv(2) = v(0) * v(1) - v(3) * v(3) / 2.;
50 inv(3) = v(4) * v(5) / std::sqrt(2.) - v(3) * v(2);
51 inv(4) = v(3) * v(5) / std::sqrt(2.) - v(4) * v(0);
52 inv(5) = v(4) * v(3) / std::sqrt(2.) - v(1) * v(5);
53 return inv / Invariants<6>::determinant(v);
54}
55
56template <>
57Eigen::Matrix<double, 3, 3> kelvinVectorToTensor(
58 Eigen::Matrix<double, 4, 1, Eigen::ColMajor, 4, 1> const& v)
59{
60 Eigen::Matrix<double, 3, 3> m;
61 m << v[0], v[3] / std::sqrt(2.), 0, v[3] / std::sqrt(2.), v[1], 0, 0, 0,
62 v[2];
63 return m;
64}
65
66template <>
67Eigen::Matrix<double, 3, 3> kelvinVectorToTensor(
68 Eigen::Matrix<double, 6, 1, Eigen::ColMajor, 6, 1> const& v)
69{
70 Eigen::Matrix<double, 3, 3> m;
71 m << v[0], v[3] / std::sqrt(2.), v[5] / std::sqrt(2.), v[3] / std::sqrt(2.),
72 v[1], v[4] / std::sqrt(2.), v[5] / std::sqrt(2.), v[4] / std::sqrt(2.),
73 v[2];
74 return m;
75}
76
77template <>
78Eigen::Matrix<double, 3, 3> kelvinVectorToTensor(Eigen::Matrix<double,
79 Eigen::Dynamic,
80 1,
81 Eigen::ColMajor,
82 Eigen::Dynamic,
83 1> const& v)
84{
85 if (v.size() == 4)
86 {
87 Eigen::Matrix<double, 4, 1, Eigen::ColMajor, 4, 1> v4;
88 v4 << v[0], v[1], v[2], v[3];
89 return kelvinVectorToTensor(v4);
90 }
91 if (v.size() == 6)
92 {
93 Eigen::Matrix<double, 6, 1, Eigen::ColMajor, 6, 1> v6;
94 v6 << v[0], v[1], v[2], v[3], v[4], v[5];
95 return kelvinVectorToTensor(v6);
96 }
98 "Conversion of dynamic Kelvin vector of size {:d} to a tensor is not "
99 "possible. Kelvin vector must be of size 4 or 6.",
100 v.size());
101}
102
103template <>
104KelvinVectorType<2> tensorToKelvin<2>(Eigen::Matrix<double, 3, 3> const& m)
105{
106 assert(std::abs(m(0, 1) - m(1, 0)) <
107 std::numeric_limits<double>::epsilon());
108 assert(m(0, 2) == 0);
109 assert(m(1, 2) == 0);
110 assert(m(2, 0) == 0);
111 assert(m(2, 1) == 0);
112
114 v << m(0, 0), m(1, 1), m(2, 2), m(0, 1) * std::sqrt(2.);
115 return v;
116}
117
118template <>
119KelvinVectorType<3> tensorToKelvin<3>(Eigen::Matrix<double, 3, 3> const& m)
120{
121 assert(std::abs(m(0, 1) - m(1, 0)) <
122 std::numeric_limits<double>::epsilon());
123 assert(std::abs(m(1, 2) - m(2, 1)) <
124 std::numeric_limits<double>::epsilon());
125 assert(std::abs(m(0, 2) - m(2, 0)) <
126 std::numeric_limits<double>::epsilon());
127
129 v << m(0, 0), m(1, 1), m(2, 2), m(0, 1) * std::sqrt(2.),
130 m(1, 2) * std::sqrt(2.), m(0, 2) * std::sqrt(2.);
131 return v;
132}
133
134template <>
135Eigen::Matrix<double, 4, 1> kelvinVectorToSymmetricTensor(
136 Eigen::Matrix<double, 4, 1, Eigen::ColMajor, 4, 1> const& v)
137{
138 Eigen::Matrix<double, 4, 1> m;
139 m << v[0], v[1], v[2], v[3] / std::sqrt(2.);
140 return m;
141}
142
143template <>
144Eigen::Matrix<double, 6, 1> kelvinVectorToSymmetricTensor(
145 Eigen::Matrix<double, 6, 1, Eigen::ColMajor, 6, 1> const& v)
146{
147 Eigen::Matrix<double, 6, 1> m;
148 m << v[0], v[1], v[2], v[3] / std::sqrt(2.), v[4] / std::sqrt(2.),
149 v[5] / std::sqrt(2.);
150 return m;
151}
152
153template <>
154Eigen::Matrix<double, Eigen::Dynamic, 1, Eigen::ColMajor, Eigen::Dynamic, 1>
155kelvinVectorToSymmetricTensor(Eigen::Matrix<double,
156 Eigen::Dynamic,
157 1,
158 Eigen::ColMajor,
159 Eigen::Dynamic,
160 1> const& v)
161{
162 if (v.size() == 4)
163 {
165 }
166 if (v.size() == 6)
167 {
169 }
170 OGS_FATAL(
171 "Kelvin vector to tensor conversion expected an input vector of size 4 "
172 "or 6, but a vector of size {:d} was given.",
173 v.size());
174}
175
176template <>
177Eigen::Matrix<double, 2, 4> liftVectorToKelvin<2>(
178 Eigen::Matrix<double, 2, 1> const& v)
179{
180 Eigen::Matrix<double, 2, 4> m;
181 m << v[0], 0, 0, v[1] / std::sqrt(2.), 0, v[1], 0, v[0] / std::sqrt(2.);
182 return m;
183}
184
185template <>
186Eigen::Matrix<double, 3, 6> liftVectorToKelvin<3>(
187 Eigen::Matrix<double, 3, 1> const& v)
188{
189 Eigen::Matrix<double, 3, 6> m;
190 m << v[0], 0, 0, v[1] / std::sqrt(2.), 0, v[2] / std::sqrt(2.), 0, v[1], 0,
191 v[0] / std::sqrt(2.), v[2] / std::sqrt(2.), 0, 0, 0, v[2], 0,
192 v[1] / std::sqrt(2.), v[0] / std::sqrt(2.);
193 return m;
194}
195
196template <>
197Eigen::Matrix<double, 2, 1> reduceKelvinToVector<2>(
198 Eigen::Matrix<double, 2, 4> const& m)
199{
200 assert(m(0, 1) == 0);
201 assert(m(0, 2) == 0);
202 assert(m(1, 0) == 0);
203 assert(m(1, 2) == 0);
204 Eigen::Matrix<double, 2, 1> v;
205 v << m(0, 0), m(1, 1);
206 return v;
207}
208
209template <>
210Eigen::Matrix<double, 3, 1> reduceKelvinToVector<3>(
211 Eigen::Matrix<double, 3, 6> const& m)
212{
213 assert(m(0, 1) == 0);
214 assert(m(0, 2) == 0);
215 assert(m(0, 4) == 0);
216 assert(m(1, 0) == 0);
217 assert(m(1, 2) == 0);
218 assert(m(1, 5) == 0);
219 assert(m(2, 0) == 0);
220 assert(m(2, 1) == 0);
221 assert(m(2, 3) == 0);
222 assert(std::abs(m(0, 3) - m(2, 4)) <
223 std::numeric_limits<double>::epsilon());
224 assert(std::abs(m(0, 5) - m(1, 4)) <
225 std::numeric_limits<double>::epsilon());
226 assert(std::abs(m(1, 3) - m(2, 5)) <
227 std::numeric_limits<double>::epsilon());
228 Eigen::Matrix<double, 3, 1> v;
229 v << m(0, 0), m(1, 1), m(2, 2);
230 return v;
231}
232
233template <>
235 Eigen::Matrix<double, 2, 2, Eigen::ColMajor, 2, 2> const& transformation)
236{
237 // 1-based index access for convenience.
238 auto Q = [&](int const i, int const j)
239 { return transformation(i - 1, j - 1); };
240
242 R << Q(1, 1) * Q(1, 1), Q(1, 2) * Q(1, 2), 0,
243 std::sqrt(2) * Q(1, 1) * Q(1, 2), Q(2, 1) * Q(2, 1), Q(2, 2) * Q(2, 2),
244 0, std::sqrt(2) * Q(2, 1) * Q(2, 2), 0, 0, 1, 0,
245 std::sqrt(2) * Q(1, 1) * Q(2, 1), std::sqrt(2) * Q(1, 2) * Q(2, 2), 0,
246 Q(1, 1) * Q(2, 2) + Q(1, 2) * Q(2, 1);
247 return R;
248}
249
250template <>
252 Eigen::Matrix<double, 3, 3, Eigen::ColMajor, 3, 3> const& transformation)
253{
254 // 1-based index access for convenience.
255 auto Q = [&](int const i, int const j)
256 { return transformation(i - 1, j - 1); };
257
259 R << Q(1, 1) * Q(1, 1), Q(1, 2) * Q(1, 2), Q(1, 3) * Q(1, 3),
260 std::sqrt(2) * Q(1, 1) * Q(1, 2), std::sqrt(2) * Q(1, 2) * Q(1, 3),
261 std::sqrt(2) * Q(1, 1) * Q(1, 3), Q(2, 1) * Q(2, 1), Q(2, 2) * Q(2, 2),
262 Q(2, 3) * Q(2, 3), std::sqrt(2) * Q(2, 1) * Q(2, 2),
263 std::sqrt(2) * Q(2, 2) * Q(2, 3), std::sqrt(2) * Q(2, 1) * Q(2, 3),
264 Q(3, 1) * Q(3, 1), Q(3, 2) * Q(3, 2), Q(3, 3) * Q(3, 3),
265 std::sqrt(2) * Q(3, 1) * Q(3, 2), std::sqrt(2) * Q(3, 2) * Q(3, 3),
266 std::sqrt(2) * Q(3, 1) * Q(3, 3), std::sqrt(2) * Q(1, 1) * Q(2, 1),
267 std::sqrt(2) * Q(1, 2) * Q(2, 2), std::sqrt(2) * Q(1, 3) * Q(2, 3),
268 Q(1, 1) * Q(2, 2) + Q(1, 2) * Q(2, 1),
269 Q(1, 2) * Q(2, 3) + Q(1, 3) * Q(2, 2),
270 Q(1, 1) * Q(2, 3) + Q(1, 3) * Q(2, 1), std::sqrt(2) * Q(2, 1) * Q(3, 1),
271 std::sqrt(2) * Q(2, 2) * Q(3, 2), std::sqrt(2) * Q(2, 3) * Q(3, 3),
272 Q(2, 1) * Q(3, 2) + Q(2, 2) * Q(3, 1),
273 Q(2, 2) * Q(3, 3) + Q(2, 3) * Q(3, 2),
274 Q(2, 1) * Q(3, 3) + Q(2, 3) * Q(3, 1), std::sqrt(2) * Q(1, 1) * Q(3, 1),
275 std::sqrt(2) * Q(1, 2) * Q(3, 2), std::sqrt(2) * Q(1, 3) * Q(3, 3),
276 Q(1, 1) * Q(3, 2) + Q(1, 2) * Q(3, 1),
277 Q(1, 2) * Q(3, 3) + Q(1, 3) * Q(3, 2),
278 Q(1, 1) * Q(3, 3) + Q(1, 3) * Q(3, 1);
279 return R;
280}
281} // namespace KelvinVector
282} // namespace MathLib
#define OGS_FATAL(...)
Definition Error.h:19
KelvinMatrixType< 3 > fourthOrderRotationMatrix< 3 >(Eigen::Matrix< double, 3, 3, Eigen::ColMajor, 3, 3 > const &transformation)
Eigen::Matrix< double, 4, 1 > kelvinVectorToSymmetricTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
KelvinVectorType< 2 > tensorToKelvin< 2 >(Eigen::Matrix< double, 3, 3 > const &m)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), 1, Eigen::ColMajor > KelvinVectorType
Eigen::Matrix< double, 2, 4 > liftVectorToKelvin< 2 >(Eigen::Matrix< double, 2, 1 > const &v)
Eigen::Matrix< double, 2, 1 > reduceKelvinToVector< 2 >(Eigen::Matrix< double, 2, 4 > const &m)
Eigen::Matrix< double, 3, 3 > kelvinVectorToTensor(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
Eigen::Matrix< double, 3, 6 > liftVectorToKelvin< 3 >(Eigen::Matrix< double, 3, 1 > const &v)
KelvinMatrixType< 2 > fourthOrderRotationMatrix< 2 >(Eigen::Matrix< double, 2, 2, Eigen::ColMajor, 2, 2 > const &transformation)
Eigen::Matrix< double, kelvin_vector_dimensions(DisplacementDim), kelvin_vector_dimensions(DisplacementDim), Eigen::RowMajor > KelvinMatrixType
KelvinVectorType< 3 > tensorToKelvin< 3 >(Eigen::Matrix< double, 3, 3 > const &m)
Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > inverse(Eigen::Matrix< double, 4, 1, Eigen::ColMajor, 4, 1 > const &v)
Eigen::Matrix< double, 3, 1 > reduceKelvinToVector< 3 >(Eigen::Matrix< double, 3, 6 > const &m)
static const double v
static double determinant(Eigen::Matrix< double, KelvinVectorSize, 1 > const &v)
Determinant of a matrix in Kelvin vector representation.