64 while (str[len] !=
'\0') { len++; }
74 int len = len1 < len2 ? len1 : len2;
75 bool are_equal =
true;
76 for (
int i = 0; i < len; ++i) {
77 if (str1[i] != str2[i]) {
87static constexpr int K_X = 0;
88static constexpr int K_Y = 1;
89static constexpr int K_Z = 2;
91static constexpr int K_S_XX = 0;
92static constexpr int K_S_YY = 1;
93static constexpr int K_S_ZZ = 2;
94static constexpr int K_S_XY = 3;
95static constexpr int K_S_YZ = 4;
96static constexpr int K_S_ZX = 5;
97static constexpr int K_S_YX = 3;
98static constexpr int K_S_ZY = 4;
99static constexpr int K_S_XZ = 5;
101static constexpr int K_F_XX = 0;
102static constexpr int K_F_YY = 1;
103static constexpr int K_F_ZZ = 2;
104static constexpr int K_F_XY = 3;
105static constexpr int K_F_YZ = 4;
106static constexpr int K_F_ZX = 5;
107static constexpr int K_F_YX = 6;
108static constexpr int K_F_ZY = 7;
109static constexpr int K_F_XZ = 8;
112template <
typename ScalarT>
117 for (
int i = 0; i < vec_length; i++) {
118#ifndef NIMBLE_HAVE_KOKKOS
119 if (!std::isfinite(vec[i])) {
120 NIMBLE_ABORT(
"\n**** Finite value check failed for " + std::string(label) +
"!\n");
123 if (vec[i] != vec[i] || vec[i] > DBL_MAX || vec[i] < -DBL_MAX) {
124 printf(
"\n**** Error, finite value check failed for %s!\n", label);
132template <
typename ScalarT>
136 return x * (1 - 2 * (y < 0));
139template <
typename ScalarT>
143 return x < y ? x : y;
146template <
typename ScalarT>
148if_then(
const bool b,
const ScalarT v1,
const ScalarT v2)
153template <
typename ScalarT>
160template <
typename ScalarT>
164 return b ? v : ScalarT(0.0);
167template <
typename ScalarT>
169Print_Full33(std::string label,
const ScalarT*
const mat,
int precision = 2)
171 std::cout <<
"Full33 " << label << std::endl;
172 std::cout << std::setprecision(precision) <<
" " << mat[K_F_XX] <<
", " << mat[K_F_XY] <<
", " << mat[K_F_XZ]
174 std::cout << std::setprecision(precision) <<
" " << mat[K_F_YX] <<
", " << mat[K_F_YY] <<
", " << mat[K_F_YZ]
176 std::cout << std::setprecision(precision) <<
" " << mat[K_F_ZX] <<
", " << mat[K_F_ZY] <<
", " << mat[K_F_ZZ]
180template <
typename ScalarT>
182Print_Sym33(std::string label,
const ScalarT*
const mat,
int precision = 2)
184 std::cout <<
"Sym33 " << label << std::endl;
185 std::cout << std::setprecision(precision) <<
" " << mat[K_S_XX] <<
", " << mat[K_S_XY] <<
", " << mat[K_S_XZ]
187 std::cout << std::setprecision(precision) <<
" " << mat[K_S_YX] <<
", " << mat[K_S_YY] <<
", " << mat[K_S_YZ]
189 std::cout << std::setprecision(precision) <<
" " << mat[K_S_ZX] <<
", " << mat[K_S_ZY] <<
", " << mat[K_S_ZZ]
194template <
typename ScalarT>
199 result[K_S_XX] = mat[K_F_XX] * mat[K_F_XX] + mat[K_F_YX] * mat[K_F_YX] + mat[K_F_ZX] * mat[K_F_ZX];
200 result[K_S_YY] = mat[K_F_XY] * mat[K_F_XY] + mat[K_F_YY] * mat[K_F_YY] + mat[K_F_ZY] * mat[K_F_ZY];
201 result[K_S_ZZ] = mat[K_F_XZ] * mat[K_F_XZ] + mat[K_F_YZ] * mat[K_F_YZ] + mat[K_F_ZZ] * mat[K_F_ZZ];
202 result[K_S_XY] = mat[K_F_XX] * mat[K_F_XY] + mat[K_F_YX] * mat[K_F_YY] + mat[K_F_ZX] * mat[K_F_ZY];
203 result[K_S_YZ] = mat[K_F_XY] * mat[K_F_XZ] + mat[K_F_YY] * mat[K_F_YZ] + mat[K_F_ZY] * mat[K_F_ZZ];
204 result[K_S_ZX] = mat[K_F_XX] * mat[K_F_XZ] + mat[K_F_YX] * mat[K_F_YZ] + mat[K_F_ZX] * mat[K_F_ZZ];
208template <
typename ScalarT>
212 result[K_F_XX] = a * mat[K_F_XX];
213 result[K_F_XY] = a * mat[K_F_XY];
214 result[K_F_XZ] = a * mat[K_F_XZ];
215 result[K_F_YX] = a * mat[K_F_YX];
216 result[K_F_YY] = a * mat[K_F_YY];
217 result[K_F_YZ] = a * mat[K_F_YZ];
218 result[K_F_ZX] = a * mat[K_F_ZX];
219 result[K_F_ZY] = a * mat[K_F_ZY];
220 result[K_F_ZZ] = a * mat[K_F_ZZ];
224template <
typename ScalarT>
228 result[K_F_XX] = A[K_F_XX] + B[K_F_XX];
229 result[K_F_XY] = A[K_F_XY] + B[K_F_XY];
230 result[K_F_XZ] = A[K_F_XZ] + B[K_F_XZ];
231 result[K_F_YX] = A[K_F_YX] + B[K_F_YX];
232 result[K_F_YY] = A[K_F_YY] + B[K_F_YY];
233 result[K_F_YZ] = A[K_F_YZ] + B[K_F_YZ];
234 result[K_F_ZX] = A[K_F_ZX] + B[K_F_ZX];
235 result[K_F_ZY] = A[K_F_ZY] + B[K_F_ZY];
236 result[K_F_ZZ] = A[K_F_ZZ] + B[K_F_ZZ];
240template <
typename ScalarT>
244 result[K_F_XX] = A[K_S_XX] + B[K_F_XX];
245 result[K_F_XY] = A[K_S_XY] + B[K_F_XY];
246 result[K_F_XZ] = A[K_S_XZ] + B[K_F_XZ];
247 result[K_F_YX] = A[K_S_YX] + B[K_F_YX];
248 result[K_F_YY] = A[K_S_YY] + B[K_F_YY];
249 result[K_F_YZ] = A[K_S_YZ] + B[K_F_YZ];
250 result[K_F_ZX] = A[K_S_ZX] + B[K_F_ZX];
251 result[K_F_ZY] = A[K_S_ZY] + B[K_F_ZY];
252 result[K_F_ZZ] = A[K_S_ZZ] + B[K_F_ZZ];
256template <
typename ScalarT>
262 result[K_F_XX] = A[K_F_XX] * B[K_F_XX] + A[K_F_XY] * B[K_F_YX] + A[K_F_XZ] * B[K_F_ZX];
263 result[K_F_XY] = A[K_F_XX] * B[K_F_XY] + A[K_F_XY] * B[K_F_YY] + A[K_F_XZ] * B[K_F_ZY];
264 result[K_F_XZ] = A[K_F_XX] * B[K_F_XZ] + A[K_F_XY] * B[K_F_YZ] + A[K_F_XZ] * B[K_F_ZZ];
265 result[K_F_YX] = A[K_F_YX] * B[K_F_XX] + A[K_F_YY] * B[K_F_YX] + A[K_F_YZ] * B[K_F_ZX];
266 result[K_F_YY] = A[K_F_YX] * B[K_F_XY] + A[K_F_YY] * B[K_F_YY] + A[K_F_YZ] * B[K_F_ZY];
267 result[K_F_YZ] = A[K_F_YX] * B[K_F_XZ] + A[K_F_YY] * B[K_F_YZ] + A[K_F_YZ] * B[K_F_ZZ];
268 result[K_F_ZX] = A[K_F_ZX] * B[K_F_XX] + A[K_F_ZY] * B[K_F_YX] + A[K_F_ZZ] * B[K_F_ZX];
269 result[K_F_ZY] = A[K_F_ZX] * B[K_F_XY] + A[K_F_ZY] * B[K_F_YY] + A[K_F_ZZ] * B[K_F_ZY];
270 result[K_F_ZZ] = A[K_F_ZX] * B[K_F_XZ] + A[K_F_ZY] * B[K_F_YZ] + A[K_F_ZZ] * B[K_F_ZZ];
274template <
typename ScalarT>
280 result[K_F_XX] = sym[K_S_XX] * full[K_F_XX] + sym[K_S_XY] * full[K_F_YX] + sym[K_S_XZ] * full[K_F_ZX];
281 result[K_F_XY] = sym[K_S_XX] * full[K_F_XY] + sym[K_S_XY] * full[K_F_YY] + sym[K_S_XZ] * full[K_F_ZY];
282 result[K_F_XZ] = sym[K_S_XX] * full[K_F_XZ] + sym[K_S_XY] * full[K_F_YZ] + sym[K_S_XZ] * full[K_F_ZZ];
283 result[K_F_YX] = sym[K_S_YX] * full[K_F_XX] + sym[K_S_YY] * full[K_F_YX] + sym[K_S_YZ] * full[K_F_ZX];
284 result[K_F_YY] = sym[K_S_YX] * full[K_F_XY] + sym[K_S_YY] * full[K_F_YY] + sym[K_S_YZ] * full[K_F_ZY];
285 result[K_F_YZ] = sym[K_S_YX] * full[K_F_XZ] + sym[K_S_YY] * full[K_F_YZ] + sym[K_S_YZ] * full[K_F_ZZ];
286 result[K_F_ZX] = sym[K_S_ZX] * full[K_F_XX] + sym[K_S_ZY] * full[K_F_YX] + sym[K_S_ZZ] * full[K_F_ZX];
287 result[K_F_ZY] = sym[K_S_ZX] * full[K_F_XY] + sym[K_S_ZY] * full[K_F_YY] + sym[K_S_ZZ] * full[K_F_ZY];
288 result[K_F_ZZ] = sym[K_S_ZX] * full[K_F_XZ] + sym[K_S_ZY] * full[K_F_YZ] + sym[K_S_ZZ] * full[K_F_ZZ];
292template <
typename ScalarT>
298 result[K_F_XX] = alpha * (A[K_F_XX] * B[K_F_XX] + A[K_F_XY] * B[K_F_YX] + A[K_F_XZ] * B[K_F_ZX]);
299 result[K_F_XY] = alpha * (A[K_F_XX] * B[K_F_XY] + A[K_F_XY] * B[K_F_YY] + A[K_F_XZ] * B[K_F_ZY]);
300 result[K_F_XZ] = alpha * (A[K_F_XX] * B[K_F_XZ] + A[K_F_XY] * B[K_F_YZ] + A[K_F_XZ] * B[K_F_ZZ]);
301 result[K_F_YX] = alpha * (A[K_F_YX] * B[K_F_XX] + A[K_F_YY] * B[K_F_YX] + A[K_F_YZ] * B[K_F_ZX]);
302 result[K_F_YY] = alpha * (A[K_F_YX] * B[K_F_XY] + A[K_F_YY] * B[K_F_YY] + A[K_F_YZ] * B[K_F_ZY]);
303 result[K_F_YZ] = alpha * (A[K_F_YX] * B[K_F_XZ] + A[K_F_YY] * B[K_F_YZ] + A[K_F_YZ] * B[K_F_ZZ]);
304 result[K_F_ZX] = alpha * (A[K_F_ZX] * B[K_F_XX] + A[K_F_ZY] * B[K_F_YX] + A[K_F_ZZ] * B[K_F_ZX]);
305 result[K_F_ZY] = alpha * (A[K_F_ZX] * B[K_F_XY] + A[K_F_ZY] * B[K_F_YY] + A[K_F_ZZ] * B[K_F_ZY]);
306 result[K_F_ZZ] = alpha * (A[K_F_ZX] * B[K_F_XZ] + A[K_F_ZY] * B[K_F_YZ] + A[K_F_ZZ] * B[K_F_ZZ]);
310template <
typename ScalarT>
315 result[K_S_XX] = mat[K_F_XX] * mat[K_F_XX] + mat[K_F_XY] * mat[K_F_XY] + mat[K_F_XZ] * mat[K_F_XZ];
316 result[K_S_YY] = mat[K_F_YX] * mat[K_F_YX] + mat[K_F_YY] * mat[K_F_YY] + mat[K_F_YZ] * mat[K_F_YZ];
317 result[K_S_ZZ] = mat[K_F_ZX] * mat[K_F_ZX] + mat[K_F_ZY] * mat[K_F_ZY] + mat[K_F_ZZ] * mat[K_F_ZZ];
318 result[K_S_XY] = mat[K_F_XX] * mat[K_F_YX] + mat[K_F_XY] * mat[K_F_YY] + mat[K_F_XZ] * mat[K_F_YZ];
319 result[K_S_YZ] = mat[K_F_YX] * mat[K_F_ZX] + mat[K_F_YY] * mat[K_F_ZY] + mat[K_F_YZ] * mat[K_F_ZZ];
320 result[K_S_ZX] = mat[K_F_ZX] * mat[K_F_XX] + mat[K_F_ZY] * mat[K_F_XY] + mat[K_F_ZZ] * mat[K_F_XZ];
324template <
typename ScalarT>
330 result[K_F_XX] = full[K_F_XX] * sym[K_S_XX] + full[K_F_XY] * sym[K_S_YX] + full[K_F_XZ] * sym[K_S_ZX];
331 result[K_F_YX] = full[K_F_XX] * sym[K_S_XY] + full[K_F_XY] * sym[K_S_YY] + full[K_F_XZ] * sym[K_S_ZY];
332 result[K_F_ZX] = full[K_F_XX] * sym[K_S_XZ] + full[K_F_XY] * sym[K_S_YZ] + full[K_F_XZ] * sym[K_S_ZZ];
333 result[K_F_XY] = full[K_F_YX] * sym[K_S_XX] + full[K_F_YY] * sym[K_S_YX] + full[K_F_YZ] * sym[K_S_ZX];
334 result[K_F_YY] = full[K_F_YX] * sym[K_S_XY] + full[K_F_YY] * sym[K_S_YY] + full[K_F_YZ] * sym[K_S_ZY];
335 result[K_F_ZY] = full[K_F_YX] * sym[K_S_XZ] + full[K_F_YY] * sym[K_S_YZ] + full[K_F_YZ] * sym[K_S_ZZ];
336 result[K_F_XZ] = full[K_F_ZX] * sym[K_S_XX] + full[K_F_ZY] * sym[K_S_YX] + full[K_F_ZZ] * sym[K_S_ZX];
337 result[K_F_YZ] = full[K_F_ZX] * sym[K_S_XY] + full[K_F_ZY] * sym[K_S_YY] + full[K_F_ZZ] * sym[K_S_ZY];
338 result[K_F_ZZ] = full[K_F_ZX] * sym[K_S_XZ] + full[K_F_ZY] * sym[K_S_YZ] + full[K_F_ZZ] * sym[K_S_ZZ];
342template <
typename ScalarT>
349 ScalarT temp_xx = s[K_S_XX] * r[K_F_XX] + s[K_S_XY] * r[K_F_YX] + s[K_S_XZ] * r[K_F_ZX];
350 ScalarT temp_yx = s[K_S_YX] * r[K_F_XX] + s[K_S_YY] * r[K_F_YX] + s[K_S_YZ] * r[K_F_ZX];
351 ScalarT temp_zx = s[K_S_ZX] * r[K_F_XX] + s[K_S_ZY] * r[K_F_YX] + s[K_S_ZZ] * r[K_F_ZX];
352 ScalarT temp_xy = s[K_S_XX] * r[K_F_XY] + s[K_S_XY] * r[K_F_YY] + s[K_S_XZ] * r[K_F_ZY];
353 ScalarT temp_yy = s[K_S_YX] * r[K_F_XY] + s[K_S_YY] * r[K_F_YY] + s[K_S_YZ] * r[K_F_ZY];
354 ScalarT temp_zy = s[K_S_ZX] * r[K_F_XY] + s[K_S_ZY] * r[K_F_YY] + s[K_S_ZZ] * r[K_F_ZY];
355 ScalarT temp_xz = s[K_S_XX] * r[K_F_XZ] + s[K_S_XY] * r[K_F_YZ] + s[K_S_XZ] * r[K_F_ZZ];
356 ScalarT temp_yz = s[K_S_YX] * r[K_F_XZ] + s[K_S_YY] * r[K_F_YZ] + s[K_S_YZ] * r[K_F_ZZ];
357 ScalarT temp_zz = s[K_S_ZX] * r[K_F_XZ] + s[K_S_ZY] * r[K_F_YZ] + s[K_S_ZZ] * r[K_F_ZZ];
359 result[K_S_XX] = r[K_F_XX] * temp_xx + r[K_F_YX] * temp_yx + r[K_F_ZX] * temp_zx;
360 result[K_S_YY] = r[K_F_XY] * temp_xy + r[K_F_YY] * temp_yy + r[K_F_ZY] * temp_zy;
361 result[K_S_ZZ] = r[K_F_XZ] * temp_xz + r[K_F_YZ] * temp_yz + r[K_F_ZZ] * temp_zz;
362 result[K_S_XY] = r[K_F_XX] * temp_xy + r[K_F_YX] * temp_yy + r[K_F_ZX] * temp_zy;
363 result[K_S_YZ] = r[K_F_XY] * temp_xz + r[K_F_YY] * temp_yz + r[K_F_ZY] * temp_zz;
364 result[K_S_ZX] = r[K_F_XZ] * temp_xx + r[K_F_YZ] * temp_yx + r[K_F_ZZ] * temp_zx;
368template <
typename ScalarT>
375 ScalarT temp_xx = s[K_S_XX] * r[K_F_XX] + s[K_S_XY] * r[K_F_XY] + s[K_S_XZ] * r[K_F_XZ];
376 ScalarT temp_yx = s[K_S_YX] * r[K_F_XX] + s[K_S_YY] * r[K_F_XY] + s[K_S_YZ] * r[K_F_XZ];
377 ScalarT temp_zx = s[K_S_ZX] * r[K_F_XX] + s[K_S_ZY] * r[K_F_XY] + s[K_S_ZZ] * r[K_F_XZ];
378 ScalarT temp_xy = s[K_S_XX] * r[K_F_YX] + s[K_S_XY] * r[K_F_YY] + s[K_S_XZ] * r[K_F_YZ];
379 ScalarT temp_yy = s[K_S_YX] * r[K_F_YX] + s[K_S_YY] * r[K_F_YY] + s[K_S_YZ] * r[K_F_YZ];
380 ScalarT temp_zy = s[K_S_ZX] * r[K_F_YX] + s[K_S_ZY] * r[K_F_YY] + s[K_S_ZZ] * r[K_F_YZ];
381 ScalarT temp_xz = s[K_S_XX] * r[K_F_ZX] + s[K_S_XY] * r[K_F_ZY] + s[K_S_XZ] * r[K_F_ZZ];
382 ScalarT temp_yz = s[K_S_YX] * r[K_F_ZX] + s[K_S_YY] * r[K_F_ZY] + s[K_S_YZ] * r[K_F_ZZ];
383 ScalarT temp_zz = s[K_S_ZX] * r[K_F_ZX] + s[K_S_ZY] * r[K_F_ZY] + s[K_S_ZZ] * r[K_F_ZZ];
385 result[K_S_XX] = r[K_F_XX] * temp_xx + r[K_F_XY] * temp_yx + r[K_F_XZ] * temp_zx;
386 result[K_S_YY] = r[K_F_YX] * temp_xy + r[K_F_YY] * temp_yy + r[K_F_YZ] * temp_zy;
387 result[K_S_ZZ] = r[K_F_ZX] * temp_xz + r[K_F_ZY] * temp_yz + r[K_F_ZZ] * temp_zz;
388 result[K_S_XY] = r[K_F_XX] * temp_xy + r[K_F_XY] * temp_yy + r[K_F_XZ] * temp_zy;
389 result[K_S_YZ] = r[K_F_YX] * temp_xz + r[K_F_YY] * temp_yz + r[K_F_YZ] * temp_zz;
390 result[K_S_ZX] = r[K_F_ZX] * temp_xx + r[K_F_ZY] * temp_yx + r[K_F_ZZ] * temp_zx;
393template <
typename ScalarT>
395CrossProduct(
const ScalarT*
const u,
const ScalarT*
const v, ScalarT*
const result)
397 result[0] = u[1] * v[2] - u[2] * v[1];
398 result[1] = u[2] * v[0] - u[0] * v[2];
399 result[2] = u[0] * v[1] - u[1] * v[0];
402template <
typename ScalarT>
406 ScalarT minor0 = mat[K_F_YY] * mat[K_F_ZZ] - mat[K_F_YZ] * mat[K_F_ZY];
407 ScalarT minor1 = mat[K_F_YX] * mat[K_F_ZZ] - mat[K_F_YZ] * mat[K_F_ZX];
408 ScalarT minor2 = mat[K_F_YX] * mat[K_F_ZY] - mat[K_F_YY] * mat[K_F_ZX];
409 ScalarT det = mat[K_F_XX] * minor0 - mat[K_F_XY] * minor1 + mat[K_F_XZ] * minor2;
414template <
typename ScalarT>
419 norm += mat[K_S_XX] * mat[K_S_XX] + mat[K_S_XY] * mat[K_S_XY] + mat[K_S_XZ] * mat[K_S_XZ];
420 norm += mat[K_S_YX] * mat[K_S_YX] + mat[K_S_YY] * mat[K_S_YY] + mat[K_S_YZ] * mat[K_S_YZ];
421 norm += mat[K_S_ZX] * mat[K_S_ZX] + mat[K_S_ZY] * mat[K_S_ZY] + mat[K_S_ZZ] * mat[K_S_ZZ];
423 if (norm > 0.0) { norm = std::sqrt(norm); }
428template <
typename ScalarT>
433 norm += mat[K_F_XX] * mat[K_F_XX] + mat[K_F_XY] * mat[K_F_XY] + mat[K_F_XZ] * mat[K_F_XZ];
434 norm += mat[K_F_YX] * mat[K_F_YX] + mat[K_F_YY] * mat[K_F_YY] + mat[K_F_YZ] * mat[K_F_YZ];
435 norm += mat[K_F_ZX] * mat[K_F_ZX] + mat[K_F_ZY] * mat[K_F_ZY] + mat[K_F_ZZ] * mat[K_F_ZZ];
437 if (norm > 0.0) { norm = std::sqrt(norm); }
442template <
typename ScalarT>
457template <
typename ScalarT>
461 A[K_F_XX] = B[K_F_XX];
462 A[K_F_XY] = B[K_F_XY];
463 A[K_F_XZ] = B[K_F_XZ];
464 A[K_F_YX] = B[K_F_YX];
465 A[K_F_YY] = B[K_F_YY];
466 A[K_F_YZ] = B[K_F_YZ];
467 A[K_F_ZX] = B[K_F_ZX];
468 A[K_F_ZY] = B[K_F_ZY];
469 A[K_F_ZZ] = B[K_F_ZZ];
472template <
typename ScalarT>
476 A[K_S_XX] = B[K_S_XX];
477 A[K_S_YY] = B[K_S_YY];
478 A[K_S_ZZ] = B[K_S_ZZ];
479 A[K_S_XY] = B[K_S_XY];
480 A[K_S_YZ] = B[K_S_YZ];
481 A[K_S_ZX] = B[K_S_ZX];
484template <
typename ScalarT>
488 result[K_S_XX] = mat[K_F_XX];
489 result[K_S_YY] = mat[K_F_YY];
490 result[K_S_ZZ] = mat[K_F_ZZ];
491 result[K_S_XY] = 0.5 * (mat[K_F_XY] + mat[K_F_YX]);
492 result[K_S_YZ] = 0.5 * (mat[K_F_YZ] + mat[K_F_ZY]);
493 result[K_S_ZX] = 0.5 * (mat[K_F_ZX] + mat[K_F_XZ]);
496template <
typename ScalarT>
500 result[K_F_XX] = 0.0;
501 result[K_F_XY] = 0.5 * (mat[K_F_XY] - mat[K_F_YX]);
502 result[K_F_XZ] = 0.5 * (mat[K_F_XZ] - mat[K_F_ZX]);
503 result[K_F_YX] = 0.5 * (mat[K_F_YX] - mat[K_F_XY]);
504 result[K_F_YY] = 0.0;
505 result[K_F_YZ] = 0.5 * (mat[K_F_YZ] - mat[K_F_ZY]);
506 result[K_F_ZX] = 0.5 * (mat[K_F_ZX] - mat[K_F_XZ]);
507 result[K_F_ZY] = 0.5 * (mat[K_F_ZY] - mat[K_F_YZ]);
508 result[K_F_ZZ] = 0.0;
523template <
typename ScalarT>
527 ScalarT minor0 = mat[K_F_YY] * mat[K_F_ZZ] - mat[K_F_YZ] * mat[K_F_ZY];
528 ScalarT minor1 = mat[K_F_YX] * mat[K_F_ZZ] - mat[K_F_YZ] * mat[K_F_ZX];
529 ScalarT minor2 = mat[K_F_YX] * mat[K_F_ZY] - mat[K_F_YY] * mat[K_F_ZX];
530 ScalarT minor3 = mat[K_F_XY] * mat[K_F_ZZ] - mat[K_F_XZ] * mat[K_F_ZY];
531 ScalarT minor4 = mat[K_F_XX] * mat[K_F_ZZ] - mat[K_F_ZX] * mat[K_F_XZ];
532 ScalarT minor5 = mat[K_F_XX] * mat[K_F_ZY] - mat[K_F_XY] * mat[K_F_ZX];
533 ScalarT minor6 = mat[K_F_XY] * mat[K_F_YZ] - mat[K_F_XZ] * mat[K_F_YY];
534 ScalarT minor7 = mat[K_F_XX] * mat[K_F_YZ] - mat[K_F_XZ] * mat[K_F_YX];
535 ScalarT minor8 = mat[K_F_XX] * mat[K_F_YY] - mat[K_F_XY] * mat[K_F_YX];
536 ScalarT det = mat[K_F_XX] * minor0 - mat[K_F_XY] * minor1 + mat[K_F_XZ] * minor2;
538 NIMBLE_ASSERT(det >= 0.0,
"Error in Invert_Full33(), singular matrix");
540 inv[K_F_XX] = minor0 / det;
541 inv[K_F_XY] = -1.0 * minor3 / det;
542 inv[K_F_XZ] = minor6 / det;
543 inv[K_F_YX] = -1.0 * minor1 / det;
544 inv[K_F_YY] = minor4 / det;
545 inv[K_F_YZ] = -1.0 * minor7 / det;
546 inv[K_F_ZX] = minor2 / det;
547 inv[K_F_ZY] = -1.0 * minor5 / det;
548 inv[K_F_ZZ] = minor8 / det;
555template <
typename ScalarT>
557BCH(
const ScalarT*
const x,
const ScalarT*
const y, ScalarT*
const result)
561 ScalarT temp1[9], temp2[9], temp3[9];
627template <
typename ScalarT>
629BCH_Sym33_Full33(
const ScalarT*
const sym,
const ScalarT*
const full, ScalarT*
const result)
632 temp[K_F_XX] = sym[K_S_XX];
633 temp[K_F_XY] = sym[K_S_XY];
634 temp[K_F_XZ] = sym[K_S_XZ];
635 temp[K_F_YX] = sym[K_S_YX];
636 temp[K_F_YY] = sym[K_S_YY];
637 temp[K_F_YZ] = sym[K_S_YZ];
638 temp[K_F_ZX] = sym[K_S_ZX];
639 temp[K_F_ZY] = sym[K_S_ZY];
640 temp[K_F_ZZ] = sym[K_S_ZZ];
641 BCH(temp, full, result);
650template <
typename ScalarT>
656 const ScalarT x2 = x * x;
657 const ScalarT x4 = x2 * x2;
659 return (0.866025403784438713 + 2.12714890259493060 * x +
660 ((1.89202064815951569 + 0.739603278343401613 * x) * x2 +
661 (0.121973926953064794 + x * (0.00655637626263929360 + 0.0000390884982780803443 * x)) * x4)) /
662 (1.0 + 2.26376989330935617 * x +
663 ((1.80461009751278976 + 0.603976798217196003 * x) * x2 +
664 (0.0783255761115461708 + 0.00268525944538021629 * x) * x4));
667template <
typename ScalarT>
670 const ScalarT*
const tensor,
674 ScalarT*
const evec0,
675 ScalarT*
const evec1,
676 ScalarT*
const evec2)
678 ScalarT cxx = tensor[K_S_XX];
679 ScalarT cyy = tensor[K_S_YY];
680 ScalarT czz = tensor[K_S_ZZ];
681 const ScalarT& cxy = tensor[K_S_XY];
682 const ScalarT& cyz = tensor[K_S_YZ];
683 const ScalarT& czx = tensor[K_S_ZX];
685 const ScalarT c1 = (cxx + cyy + czz) / ScalarT(3.0);
691 const ScalarT cxy_cxy = cxy * cxy;
692 const ScalarT cyz_cyz = cyz * cyz;
693 const ScalarT czx_czx = czx * czx;
694 const ScalarT cxx_cyy = cxx * cyy;
696 const ScalarT c2 = cxx_cyy + cyy * czz + czz * cxx - cxy_cxy - cyz_cyz - czx_czx;
698 const ScalarT ThreeOverA = ScalarT(-3.0) / c2;
699 const ScalarT sqrtThreeOverA = std::sqrt(ThreeOverA);
701 const ScalarT c3 = cxx * cyz_cyz + cyy * czx_czx - ScalarT(2.0) * cxy * cyz * czx + czz * (cxy_cxy - cxx_cyy);
703 const ScalarT rr = ScalarT(-0.5) * c3 * ThreeOverA * sqrtThreeOverA;
705 const ScalarT arg =
Minimum(std::abs(rr), ScalarT(1.0));
709 const ScalarT two_cos_thd3 = ScalarT(2.0) *
MultiplySign(cos_thd3, rr);
711 eval2 = two_cos_thd3 / sqrtThreeOverA;
713 ScalarT crow0[3] = {cxx - eval2, cxy, czx};
714 ScalarT crow1[3] = {cxy, cyy - eval2, cyz};
715 ScalarT crow2[3] = {czx, cyz, czz - eval2};
720 const ScalarT k0 = crow0[0] * crow0[0] + cxy_cxy + czx_czx;
721 const ScalarT k1 = cxy_cxy + crow1[1] * crow1[1] + cyz_cyz;
722 const ScalarT k2 = czx_czx + cyz_cyz + crow2[2] * crow2[2];
729 const bool k0gk1 = k1 <= k0;
730 const bool k0gk2 = k2 <= k0;
731 const bool k1gk2 = k2 <= k1;
733 const bool k0_largest = k0gk1 && k0gk2;
734 const bool k1_largest = k1gk2 && !k0gk1;
735 const bool k2_largest = !(k0_largest || k1_largest);
757 const ScalarT ki_dpr1 = ki_ki * (k_row1[0] * row2[0] + k_row1[1] * row2[1] + k_row1[2] * row2[2]);
758 const ScalarT ki_dpr2 = ki_ki * (k_row1[0] * row3[0] + k_row1[1] * row3[1] + k_row1[2] * row3[2]);
760 row2[0] -= ki_dpr1 * k_row1[0];
761 row2[1] -= ki_dpr1 * k_row1[1];
762 row2[2] -= ki_dpr1 * k_row1[2];
764 row3[0] -= ki_dpr2 * k_row1[0];
765 row3[1] -= ki_dpr2 * k_row1[1];
766 row3[2] -= ki_dpr2 * k_row1[2];
768 const ScalarT a0 = row2[0] * row2[0] + row2[1] * row2[1] + row2[2] * row2[2];
769 const ScalarT a1 = row3[0] * row3[0] + row3[1] * row3[1] + row3[2] * row3[2];
773 const bool a0lea1 = a0 <= a1;
778 const ScalarT ai_ai = ScalarT(1.0) /
if_then_else(a0lea1, a1, a0);
780 evec2[K_X] = k_row1[1] * a_row2[2] - k_row1[2] * a_row2[1];
781 evec2[K_Y] = k_row1[2] * a_row2[0] - k_row1[0] * a_row2[2];
782 evec2[K_Z] = k_row1[0] * a_row2[1] - k_row1[1] * a_row2[0];
784 const ScalarT k_atr11 = cxx * k_row1[0] + cxy * k_row1[1] + czx * k_row1[2];
785 const ScalarT k_atr21 = cxy * k_row1[0] + cyy * k_row1[1] + cyz * k_row1[2];
786 const ScalarT k_atr31 = czx * k_row1[0] + cyz * k_row1[1] + czz * k_row1[2];
788 const ScalarT a_atr12 = cxx * a_row2[0] + cxy * a_row2[1] + czx * a_row2[2];
789 const ScalarT a_atr22 = cxy * a_row2[0] + cyy * a_row2[1] + cyz * a_row2[2];
790 const ScalarT a_atr32 = czx * a_row2[0] + cyz * a_row2[1] + czz * a_row2[2];
792 ScalarT rm2xx = (k_row1[0] * k_atr11 + k_row1[1] * k_atr21 + k_row1[2] * k_atr31) * ki_ki;
793 const ScalarT k_a_rm2xy = (k_row1[0] * a_atr12 + k_row1[1] * a_atr22 + k_row1[2] * a_atr32);
794 ScalarT rm2yy = (a_row2[0] * a_atr12 + a_row2[1] * a_atr22 + a_row2[2] * a_atr32) * ai_ai;
795 const ScalarT rm2xy_rm2xy = k_a_rm2xy * k_a_rm2xy * ai_ai * ki_ki;
800 const ScalarT b = ScalarT(0.5) * (rm2xx - rm2yy);
801 const ScalarT sqrtTerm =
MultiplySign(std::sqrt(b * b + rm2xy_rm2xy), b);
802 eval0 = rm2yy + b - sqrtTerm;
804 eval1 = rm2xx + rm2yy - eval0;
809 const ScalarT rm2xx2 = rm2xx * rm2xx;
810 const ScalarT rm2yy2 = rm2yy * rm2yy;
812 const ScalarT fac1 =
if_then_else(rm2xx2 < rm2yy2, k_a_rm2xy * ai_ai, rm2xx);
813 const ScalarT fac2 =
if_then_else(rm2xx2 < rm2yy2, rm2yy, ki_ki * k_a_rm2xy);
815 evec0[0] = fac1 * a_row2[0] - fac2 * k_row1[0];
816 evec0[1] = fac1 * a_row2[1] - fac2 * k_row1[1];
817 evec0[2] = fac1 * a_row2[2] - fac2 * k_row1[2];
819 const bool rm2xx2iszero = rm2xx2 == ScalarT(0.0);
820 const bool rm2xy_rm2xyiszero = rm2xy_rm2xy == ScalarT(0.0);
821 const bool both_zero = rm2xx2iszero && rm2xy_rm2xyiszero;
824 evec0[0] =
if_then_else(both_zero, a_row2[0], evec0[0]);
825 evec0[1] =
if_then_else(both_zero, a_row2[1], evec0[1]);
826 evec0[2] =
if_then_else(both_zero, a_row2[2], evec0[2]);
828 evec1[K_X] = evec2[K_Y] * evec0[K_Z] - evec2[K_Z] * evec0[K_Y];
829 evec1[K_Y] = evec2[K_Z] * evec0[K_X] - evec2[K_X] * evec0[K_Z];
830 evec1[K_Z] = evec2[K_X] * evec0[K_Y] - evec2[K_Y] * evec0[K_X];
836 const ScalarT c2tol = (c1 * c1) * (-1.0e-30);
838 const bool c2lsmall_neg = c2 < c2tol;
844 evec0[0] =
if_then_else(c2lsmall_neg, evec0[0], ScalarT(1.0));
845 evec0[1] =
if_then_else(c2lsmall_neg, evec0[1], ScalarT(0.0));
846 evec0[2] =
if_then_else(c2lsmall_neg, evec0[2], ScalarT(0.0));
848 evec1[0] =
if_then_else(c2lsmall_neg, evec1[0], ScalarT(0.0));
849 evec1[1] =
if_then_else(c2lsmall_neg, evec1[1], ScalarT(1.0));
850 evec1[2] =
if_then_else(c2lsmall_neg, evec1[2], ScalarT(0.0));
852 evec2[0] =
if_then_else(c2lsmall_neg, evec2[0], ScalarT(0.0));
853 evec2[1] =
if_then_else(c2lsmall_neg, evec2[1], ScalarT(0.0));
854 evec2[2] =
if_then_else(c2lsmall_neg, evec2[2], ScalarT(1.0));
859template <
typename ScalarT>
862 const ScalarT*
const mat,
863 ScalarT*
const left_stretch,
864 ScalarT*
const rotation)
870 ScalarT mat_inv_squared[6];
873 ScalarT vec1[3] = {0.0, 0.0, 0.0};
874 ScalarT vec2[3] = {0.0, 0.0, 0.0};
875 ScalarT vec3[3] = {0.0, 0.0, 0.0};
876 ScalarT eval[3] = {0.0, 0.0, 0.0};
880 const ScalarT zero = ScalarT(0.0);
882 eval[0] =
if_then(eval[0] < zero, zero, eval[0]);
883 eval[1] =
if_then(eval[1] < zero, zero, eval[1]);
884 eval[2] =
if_then(eval[2] < zero, zero, eval[2]);
886 const ScalarT len1_sq = vec1[K_X] * vec1[K_X] + vec1[K_Y] * vec1[K_Y] + vec1[K_Z] * vec1[K_Z];
887 const ScalarT len2_sq = vec2[K_X] * vec2[K_X] + vec2[K_Y] * vec2[K_Y] + vec2[K_Z] * vec2[K_Z];
888 const ScalarT len3_sq = vec3[K_X] * vec3[K_X] + vec3[K_Y] * vec3[K_Y] + vec3[K_Z] * vec3[K_Z];
890 const ScalarT xlx = std::sqrt(eval[0]);
891 const ScalarT xly = std::sqrt(eval[1]);
892 const ScalarT xlz = std::sqrt(eval[2]);
894 const ScalarT one = ScalarT(1.0);
896 const ScalarT xlxi = one / (xlx * len1_sq);
897 const ScalarT xlyi = one / (xly * len2_sq);
898 const ScalarT xlzi = one / (xlz * len3_sq);
900 left_stretch[K_S_XX] = xlxi * vec1[K_X] * vec1[K_X] + xlyi * vec2[K_X] * vec2[K_X] + xlzi * vec3[K_X] * vec3[K_X];
901 left_stretch[K_S_YY] = xlxi * vec1[K_Y] * vec1[K_Y] + xlyi * vec2[K_Y] * vec2[K_Y] + xlzi * vec3[K_Y] * vec3[K_Y];
902 left_stretch[K_S_ZZ] = xlxi * vec1[K_Z] * vec1[K_Z] + xlyi * vec2[K_Z] * vec2[K_Z] + xlzi * vec3[K_Z] * vec3[K_Z];
903 left_stretch[K_S_XY] = xlxi * vec1[K_X] * vec1[K_Y] + xlyi * vec2[K_X] * vec2[K_Y] + xlzi * vec3[K_X] * vec3[K_Y];
904 left_stretch[K_S_YZ] = xlxi * vec1[K_Y] * vec1[K_Z] + xlyi * vec2[K_Y] * vec2[K_Z] + xlzi * vec3[K_Y] * vec3[K_Z];
905 left_stretch[K_S_ZX] = xlxi * vec1[K_Z] * vec1[K_X] + xlyi * vec2[K_Z] * vec2[K_X] + xlzi * vec3[K_Z] * vec3[K_X];
910template <
typename ScalarT>
913 const ScalarT*
const def_grad_inc,
914 ScalarT*
const left_stretch_inc,
915 ScalarT*
const rotation_inc,
916 ScalarT*
const log_left_stretch_inc)
926 ScalarT vec1[3] = {0.0, 0.0, 0.0};
927 ScalarT vec2[3] = {0.0, 0.0, 0.0};
928 ScalarT vec3[3] = {0.0, 0.0, 0.0};
929 ScalarT eval[3] = {0.0, 0.0, 0.0};
936 mag = std::sqrt(vec1[0] * vec1[0] + vec1[1] * vec1[1] + vec1[2] * vec1[2]);
940 mag = std::sqrt(vec2[0] * vec2[0] + vec2[1] * vec2[1] + vec2[2] * vec2[2]);
944 mag = std::sqrt(vec3[0] * vec3[0] + vec3[1] * vec3[1] + vec3[2] * vec3[2]);
958 x[0] = std::sqrt(eval[0]);
959 x[1] = std::sqrt(eval[1]);
960 x[2] = std::sqrt(eval[2]);
968 lnx[0] = std::log(x[0]);
969 lnx[1] = std::log(x[1]);
970 lnx[2] = std::log(x[2]);
972 ScalarT vec_transpose[9];
973 vec_transpose[K_F_XX] = vec1[0];
974 vec_transpose[K_F_XY] = vec1[1];
975 vec_transpose[K_F_XZ] = vec1[2];
976 vec_transpose[K_F_YX] = vec2[0];
977 vec_transpose[K_F_YY] = vec2[1];
978 vec_transpose[K_F_YZ] = vec2[2];
979 vec_transpose[K_F_ZX] = vec3[0];
980 vec_transpose[K_F_ZY] = vec3[1];
981 vec_transpose[K_F_ZZ] = vec3[2];
986 temp[K_F_XX] = vec1[0] * x[0];
987 temp[K_F_XY] = vec2[0] * x[1];
988 temp[K_F_XZ] = vec3[0] * x[2];
989 temp[K_F_YX] = vec1[1] * x[0];
990 temp[K_F_YY] = vec2[1] * x[1];
991 temp[K_F_YZ] = vec3[1] * x[2];
992 temp[K_F_ZX] = vec1[2] * x[0];
993 temp[K_F_ZY] = vec2[2] * x[1];
994 temp[K_F_ZZ] = vec3[2] * x[2];
995 left_stretch_inc[K_S_XX] = temp[K_F_XX] * vec_transpose[K_F_XX] + temp[K_F_XY] * vec_transpose[K_F_YX] +
996 temp[K_F_XZ] * vec_transpose[K_F_ZX];
997 left_stretch_inc[K_S_YY] = temp[K_F_YX] * vec_transpose[K_F_XY] + temp[K_F_YY] * vec_transpose[K_F_YY] +
998 temp[K_F_YZ] * vec_transpose[K_F_ZY];
999 left_stretch_inc[K_S_ZZ] = temp[K_F_ZX] * vec_transpose[K_F_XZ] + temp[K_F_ZY] * vec_transpose[K_F_YZ] +
1000 temp[K_F_ZZ] * vec_transpose[K_F_ZZ];
1001 left_stretch_inc[K_S_XY] = temp[K_F_XX] * vec_transpose[K_F_XY] + temp[K_F_XY] * vec_transpose[K_F_YY] +
1002 temp[K_F_XZ] * vec_transpose[K_F_ZY];
1003 left_stretch_inc[K_S_YZ] = temp[K_F_YX] * vec_transpose[K_F_XZ] + temp[K_F_YY] * vec_transpose[K_F_YZ] +
1004 temp[K_F_YZ] * vec_transpose[K_F_ZZ];
1005 left_stretch_inc[K_S_ZX] = temp[K_F_ZX] * vec_transpose[K_F_XX] + temp[K_F_ZY] * vec_transpose[K_F_YX] +
1006 temp[K_F_ZZ] * vec_transpose[K_F_ZX];
1009 temp[K_F_XX] = vec1[0] * xi[0];
1010 temp[K_F_XY] = vec2[0] * xi[1];
1011 temp[K_F_XZ] = vec3[0] * xi[2];
1012 temp[K_F_YX] = vec1[1] * xi[0];
1013 temp[K_F_YY] = vec2[1] * xi[1];
1014 temp[K_F_YZ] = vec3[1] * xi[2];
1015 temp[K_F_ZX] = vec1[2] * xi[0];
1016 temp[K_F_ZY] = vec2[2] * xi[1];
1017 temp[K_F_ZZ] = vec3[2] * xi[2];
1018 ScalarT left_stretch_inc_inverse[9];
1022 temp[K_F_XX] = vec1[0] * lnx[0];
1023 temp[K_F_XY] = vec2[0] * lnx[1];
1024 temp[K_F_XZ] = vec3[0] * lnx[2];
1025 temp[K_F_YX] = vec1[1] * lnx[0];
1026 temp[K_F_YY] = vec2[1] * lnx[1];
1027 temp[K_F_YZ] = vec3[1] * lnx[2];
1028 temp[K_F_ZX] = vec1[2] * lnx[0];
1029 temp[K_F_ZY] = vec2[2] * lnx[1];
1030 temp[K_F_ZZ] = vec3[2] * lnx[2];
1031 log_left_stretch_inc[K_S_XX] = temp[K_F_XX] * vec_transpose[K_F_XX] + temp[K_F_XY] * vec_transpose[K_F_YX] +
1032 temp[K_F_XZ] * vec_transpose[K_F_ZX];
1033 log_left_stretch_inc[K_S_YY] = temp[K_F_YX] * vec_transpose[K_F_XY] + temp[K_F_YY] * vec_transpose[K_F_YY] +
1034 temp[K_F_YZ] * vec_transpose[K_F_ZY];
1035 log_left_stretch_inc[K_S_ZZ] = temp[K_F_ZX] * vec_transpose[K_F_XZ] + temp[K_F_ZY] * vec_transpose[K_F_YZ] +
1036 temp[K_F_ZZ] * vec_transpose[K_F_ZZ];
1037 log_left_stretch_inc[K_S_XY] = temp[K_F_XX] * vec_transpose[K_F_XY] + temp[K_F_XY] * vec_transpose[K_F_YY] +
1038 temp[K_F_XZ] * vec_transpose[K_F_ZY];
1039 log_left_stretch_inc[K_S_YZ] = temp[K_F_YX] * vec_transpose[K_F_XZ] + temp[K_F_YY] * vec_transpose[K_F_YZ] +
1040 temp[K_F_YZ] * vec_transpose[K_F_ZZ];
1041 log_left_stretch_inc[K_S_ZX] = temp[K_F_ZX] * vec_transpose[K_F_XX] + temp[K_F_ZY] * vec_transpose[K_F_YX] +
1042 temp[K_F_ZZ] * vec_transpose[K_F_ZX];
1048template <
typename ScalarT>
1051 const ScalarT*
const mat,
1052 const ScalarT*
const V,
1053 const ScalarT*
const R,
1054 std::string
const& label)
1056 ScalarT norm_tol = 1.0e-12;
1058 ScalarT check[9], should_be_zero[9];
1060 for (
int i = 0; i < 9; i++) { should_be_zero[i] = mat[i] - check[i]; }
1061 ScalarT should_be_zero_norm =
Norm_Full33(should_be_zero);
1062 if (should_be_zero_norm > norm_tol) {
1063 std::cout <<
"\n\nFailure in CheckCorrectnessOfPolarDecomp()!" << std::endl;
1067 std::cout <<
"norm of error = " << should_be_zero_norm <<
"\n" << std::endl;
1073template <
typename ScalarT>
1076 const ScalarT*
const mat,
1077 const ScalarT*
const sym,
1078 const ScalarT*
const skew,
1079 std::string
const& label)
1083 ScalarT should_be_zero[9];
1084 should_be_zero[K_F_XX] = sym[K_S_XX] + skew[K_F_XX] - mat[K_F_XX];
1085 should_be_zero[K_F_XY] = sym[K_S_XY] + skew[K_F_XY] - mat[K_F_XY];
1086 should_be_zero[K_F_XZ] = sym[K_S_XZ] + skew[K_F_XZ] - mat[K_F_XZ];
1087 should_be_zero[K_F_YX] = sym[K_S_YX] + skew[K_F_YX] - mat[K_F_YX];
1088 should_be_zero[K_F_YY] = sym[K_S_YY] + skew[K_F_YY] - mat[K_F_YY];
1089 should_be_zero[K_F_YZ] = sym[K_S_YZ] + skew[K_F_YZ] - mat[K_F_YZ];
1090 should_be_zero[K_F_ZX] = sym[K_S_ZX] + skew[K_F_ZX] - mat[K_F_ZX];
1091 should_be_zero[K_F_ZY] = sym[K_S_ZY] + skew[K_F_ZY] - mat[K_F_ZY];
1092 should_be_zero[K_F_ZZ] = sym[K_S_ZZ] + skew[K_F_ZZ] - mat[K_F_ZZ];
1093 ScalarT should_be_zero_norm =
Norm_Full33(should_be_zero);
1094 if (should_be_zero_norm > norm_tol) {
1095 std::cout <<
"\n\nFailure in CheckCorrectnessOfSymSkew()!" << std::endl;
1099 std::cout <<
"norm of error = " << should_be_zero_norm <<
"\n" << std::endl;
1105template <
typename ScalarT>
1111 ScalarT machine_epsilon = std::numeric_limits<ScalarT>::epsilon();
1114 if (std::abs(rotation[K_F_XX] + rotation[K_F_YY] + rotation[K_F_ZZ] + 1.0) < 10.0 * machine_epsilon) {
1119 B[K_F_XX] = rotation[K_F_XX] - 1.0;
1120 B[K_F_XY] = rotation[K_F_XY];
1121 B[K_F_XZ] = rotation[K_F_XZ];
1122 B[K_F_YX] = rotation[K_F_YX];
1123 B[K_F_YY] = rotation[K_F_YY] - 1.0;
1124 B[K_F_YZ] = rotation[K_F_YZ];
1125 B[K_F_ZX] = rotation[K_F_ZX];
1126 B[K_F_ZY] = rotation[K_F_ZY];
1127 B[K_F_ZZ] = rotation[K_F_ZZ] - 1.0;
1142 ScalarT norm = normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2];
1143 if (norm > 0.0) { norm = std::sqrt(norm); }
1145 if (norm < machine_epsilon) {
1153 norm = normal[0] * normal[0] + normal[1] * normal[1] + normal[2] * normal[2];
1154 if (norm > 0.0) { norm = std::sqrt(norm); }
1156 NIMBLE_ASSERT(norm >= machine_epsilon,
"\n**** Error in Log_Rotation_Pi(), cannot"
1157 " determine rotation vector.");
1164 ScalarT pi = std::acos(-1.0);
1166 log_rotation[K_F_XX] = 0.0;
1167 log_rotation[K_F_XY] = -normal[2] * pi;
1168 log_rotation[K_F_XZ] = normal[1] * pi;
1169 log_rotation[K_F_YX] = normal[2] * pi;
1170 log_rotation[K_F_YY] = 0.0;
1171 log_rotation[K_F_YZ] = -normal[0] * pi;
1172 log_rotation[K_F_ZX] = -normal[1] * pi;
1173 log_rotation[K_F_ZY] = normal[0] * pi;
1174 log_rotation[K_F_ZZ] = 0.0;
1177template <
typename ScalarT>
1184 bool valid_input =
true;
1185 ScalarT machine_epsilon = std::numeric_limits<ScalarT>::epsilon();
1188 temp[K_S_XX] -= 1.0;
1189 temp[K_S_YY] -= 1.0;
1190 temp[K_S_ZZ] -= 1.0;
1192 if (norm > 100.0 * machine_epsilon) { valid_input =
false; }
1194 if (std::abs(det_rotation - 1.0) > 100.0 * machine_epsilon) { valid_input =
false; }
1196 std::stringstream ss;
1197 ss <<
"\n**** Input check failed for Log_Rotation()!";
1198 ss <<
"\n**** norm(R - I) must be less than (100 * machine_epsilon): "
1200 << norm <<
", machine_epsilon = " << machine_epsilon;
1201 ss <<
"\n**** (det(R) - 1) must be less than (100 * machine_epsilon): "
1203 << det_rotation <<
", machine_epsilon = " << machine_epsilon <<
"\n";
1208 ScalarT cosine = 0.5 * (rotation[K_F_XX] + rotation[K_F_YY] + rotation[K_F_ZZ] - 1.0);
1209 if (cosine < -1.0) {
1211 }
else if (cosine > 1.0) {
1214 ScalarT theta = std::acos(cosine);
1218 }
else if (std::abs(cosine + 1.0) < 10.0 * machine_epsilon) {
1222 ScalarT a = theta / std::sin(theta);
1223 ScalarT rotation_skew[9];
1232 double minor0 = mat[1][1] * mat[2][2] - mat[1][2] * mat[2][1];
1233 double minor1 = mat[1][0] * mat[2][2] - mat[1][2] * mat[2][0];
1234 double minor2 = mat[1][0] * mat[2][1] - mat[1][1] * mat[2][0];
1235 double minor3 = mat[0][1] * mat[2][2] - mat[0][2] * mat[2][1];
1236 double minor4 = mat[0][0] * mat[2][2] - mat[2][0] * mat[0][2];
1237 double minor5 = mat[0][0] * mat[2][1] - mat[0][1] * mat[2][0];
1238 double minor6 = mat[0][1] * mat[1][2] - mat[0][2] * mat[1][1];
1239 double minor7 = mat[0][0] * mat[1][2] - mat[0][2] * mat[1][0];
1240 double minor8 = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0];
1241 double det = mat[0][0] * minor0 - mat[0][1] * minor1 + mat[0][2] * minor2;
1244#ifdef NIMBLE_HAVE_KOKKOS
1246 printf(
"\n**** Error in Invert3x3(), singular matrix.\n");
1249 "\n**** Error in HexInvert3x3(), negative determinant "
1253 NIMBLE_ASSERT(det > 0.0,
"\n**** Error in Invert3x3(), singular matrix.\n");
1257 inv[0][0] = minor0 / det;
1258 inv[0][1] = -1.0 * minor3 / det;
1259 inv[0][2] = minor6 / det;
1260 inv[1][0] = -1.0 * minor1 / det;
1261 inv[1][1] = minor4 / det;
1262 inv[1][2] = -1.0 * minor7 / det;
1263 inv[2][0] = minor2 / det;
1264 inv[2][1] = -1.0 * minor5 / det;
1265 inv[2][2] = minor8 / det;
1271template<
class Matrix >
1276 double big, temp, sum;
1277 int n = num_entries;
1278 std::vector<double> vv(n);
1279 double tiny = 1e-40;
1284 for (
int i = 0; i < n; ++i) {
1286 for (
int j = 0; j < n; ++j) {
1287 if (std::fabs(mat(i, j)) > big) big = std::fabs(mat(i, j));
1291 NIMBLE_ABORT(
"Singular matrix in routine LU_Decompose()");
1297 for (
int j = 0; j < n; ++j) {
1298 for (
int i = 0; i < j; ++i) {
1300 for (
int k = 0; k < i; ++k) { sum -= mat(i, k) * mat(k, j); }
1305 for (
int i = j; i < n; ++i) {
1307 for (
int k = 0; k < j; ++k) { sum -= mat(i, k) * mat(k, j); }
1310 if (vv[i] * std::fabs(sum) > big) {
1313 big = vv[i] * std::fabs(sum);
1320 for (
int k = 0; k < n; ++k) {
1321 temp = mat(imax, k);
1322 mat(imax, k) = mat(j, k);
1329 if (std::fabs(mat(j, j)) < tiny) {
1331 NIMBLE_ABORT(
"Singular matrix in routine LU_Decompose()");
1336 temp = 1.0 / (mat(j, j));
1337 for (
int i = j + 1; i < n; ++i) { mat(i, j) *= temp; }
1345template<
class Matrix >
1347LU_Solve(
int num_entries,
const Matrix& mat,
double* vec,
const int* index)
1354 int n = num_entries;
1358 for (
int i = 0; i < n; ++i) {
1359 sum = vec[index[i]];
1360 vec[index[i]] = vec[i];
1361 for (
int j = 0; j < i; ++j) { sum -= mat(i, j) * vec[j]; }
1366 for (
int i = n - 1; i >= 0; --i) {
1368 for (
int j = i + 1; j < n; ++j) { sum -= mat(i, j) * vec[j]; }
1369 vec[i] = sum / mat(i, i);
1376template<
class Matrix >
1380 int* index = scratch;
1386 LU_Solve(num_entries, mat, vec, index);
#define NIMBLE_INLINE_FUNCTION
Definition nimble_defs.h:50
#define NIMBLE_DEBUG_ASSERT(cond)
Definition nimble_macros.h:99
#define NIMBLE_ASSERT(...)
Definition nimble_macros.h:85
#define NIMBLE_ABORT(...)
Definition nimble_macros.h:87
void Print_Full33(std::string label, const ScalarT *const mat, int precision=2)
Definition nimble_utils.h:169
NIMBLE_INLINE_FUNCTION ScalarT Cos_Of_Acos_Divided_By_3(const ScalarT x)
Pade approximation to cos( acos(x)/3 )
Definition nimble_utils.h:652
NIMBLE_INLINE_FUNCTION void Unrotate_Sym33_Using_R_S_Rtranspose(const ScalarT *const s, const ScalarT *const r, ScalarT *const result)
Unrotate a symetric tensor, result = R S R^T.
Definition nimble_utils.h:370
NIMBLE_INLINE_FUNCTION void Log_Rotation(const ScalarT *const rotation, ScalarT *const log_rotation)
Definition nimble_utils.h:1179
NIMBLE_INLINE_FUNCTION ScalarT if_then_else(const bool b, const ScalarT v1, const ScalarT v2)
Definition nimble_utils.h:155
NIMBLE_INLINE_FUNCTION void CheckCorrectnessOfSymSkew(const ScalarT *const mat, const ScalarT *const sym, const ScalarT *const skew, std::string const &label)
Definition nimble_utils.h:1075
NIMBLE_INLINE_FUNCTION ScalarT Determinant_Full33(const ScalarT *const mat)
Definition nimble_utils.h:404
NIMBLE_INLINE_FUNCTION void Square_Full33T_Full33(const ScalarT *const mat, ScalarT *const result)
Compute result = mat^T mat.
Definition nimble_utils.h:196
NIMBLE_INLINE_FUNCTION void Mult_Full33_Sym33_ReturnT(const ScalarT *const full, const ScalarT *const sym, ScalarT *const result)
Multiply a full tensor by a symmetric tensor, return transpose of resultant.
Definition nimble_utils.h:326
void LU_SolveSystem(int num_entries, Matrix &mat, double *vec, int *scratch)
Definition nimble_utils.h:1378
NIMBLE_INLINE_FUNCTION void Sum_Sym33_Full33(const ScalarT *const A, const ScalarT *const B, ScalarT *const result)
Sum of a symmetric tensor and a full tensor.
Definition nimble_utils.h:242
NIMBLE_INLINE_FUNCTION void Zero_Full33(ScalarT *const mat)
Definition nimble_utils.h:444
NIMBLE_INLINE_FUNCTION ScalarT Invert_Full33(const ScalarT *mat, ScalarT *inv)
Function to invert a 3x3 matrix.
Definition nimble_utils.h:525
NIMBLE_INLINE_FUNCTION void CheckCorrectnessOfPolarDecomp(const ScalarT *const mat, const ScalarT *const V, const ScalarT *const R, std::string const &label)
Definition nimble_utils.h:1050
void LU_Decompose(int num_entries, Matrix &mat, int *index)
Definition nimble_utils.h:1273
NIMBLE_INLINE_FUNCTION ScalarT if_then_else_zero(const bool b, const ScalarT v)
Definition nimble_utils.h:162
NIMBLE_INLINE_FUNCTION void Mult_Scalar_Full33(ScalarT a, const ScalarT *const mat, ScalarT *const result)
Multiply a full tensor by a scalar.
Definition nimble_utils.h:210
NIMBLE_INLINE_FUNCTION ScalarT Minimum(const ScalarT x, const ScalarT y)
Definition nimble_utils.h:141
NIMBLE_INLINE_FUNCTION int StringLength(const char *str)
Definition nimble_utils.h:61
NIMBLE_INLINE_FUNCTION bool StringsAreEqual(const char *str1, const char *str2)
Definition nimble_utils.h:70
NIMBLE_INLINE_FUNCTION ScalarT Norm_Full33(const ScalarT *const mat)
Definition nimble_utils.h:430
NIMBLE_INLINE_FUNCTION void Sum_Full33_Full33(const ScalarT *const A, const ScalarT *const B, ScalarT *const result)
Sum of a full tensor and a full tensor.
Definition nimble_utils.h:226
NIMBLE_INLINE_FUNCTION void Log_Rotation_Pi(const ScalarT *const rotation, ScalarT *const log_rotation)
Definition nimble_utils.h:1107
NIMBLE_INLINE_FUNCTION ScalarT MultiplySign(const ScalarT x, const ScalarT y)
Return x times sign of y.
Definition nimble_utils.h:134
NIMBLE_INLINE_FUNCTION void CheckVectorSanity(int vec_length, ScalarT const *const vec, const char *label)
Definition nimble_utils.h:114
NIMBLE_INLINE_FUNCTION void Rotate_Sym33_Using_Rtranspose_S_R(const ScalarT *const s, const ScalarT *const r, ScalarT *const result)
Rotate a symetric tensor, result = R^T S R.
Definition nimble_utils.h:344
NIMBLE_INLINE_FUNCTION void Mult_Scalar_Full33_Full33(ScalarT alpha, const ScalarT *const A, const ScalarT *const B, ScalarT *const result)
Multiply a full tensor by a full tensor and a scalar.
Definition nimble_utils.h:294
NIMBLE_INLINE_FUNCTION void SetEqual_Full33(const ScalarT *const B, ScalarT *const A)
Definition nimble_utils.h:459
NIMBLE_INLINE_FUNCTION void Eigen_Sym33_NonUnit(const ScalarT *const tensor, ScalarT &eval0, ScalarT &eval1, ScalarT &eval2, ScalarT *const evec0, ScalarT *const evec1, ScalarT *const evec2)
Definition nimble_utils.h:669
NIMBLE_INLINE_FUNCTION double Invert3x3(const double mat[][3], double inv[][3])
Definition nimble_utils.h:1230
NIMBLE_INLINE_FUNCTION void SetEqual_Sym33(const ScalarT *const B, ScalarT *const A)
Definition nimble_utils.h:474
void LU_Solve(int num_entries, const Matrix &mat, double *vec, const int *index)
Definition nimble_utils.h:1347
NIMBLE_INLINE_FUNCTION void Polar_Decomp(const ScalarT *const mat, ScalarT *const left_stretch, ScalarT *const rotation)
Definition nimble_utils.h:861
NIMBLE_INLINE_FUNCTION void Square_Full33_Full33T(const ScalarT *const mat, ScalarT *const result)
Compute result = mat mat^T.
Definition nimble_utils.h:312
NIMBLE_INLINE_FUNCTION void Polar_Left_LogV_Lame(const ScalarT *const def_grad_inc, ScalarT *const left_stretch_inc, ScalarT *const rotation_inc, ScalarT *const log_left_stretch_inc)
Definition nimble_utils.h:912
NIMBLE_INLINE_FUNCTION void CrossProduct(const ScalarT *const u, const ScalarT *const v, ScalarT *const result)
Definition nimble_utils.h:395
NIMBLE_INLINE_FUNCTION void BCH(const ScalarT *const x, const ScalarT *const y, ScalarT *const result)
R^N logarithmic map using Baker-Campbell-Hausdorff (BCH) expansion (4 terms)
Definition nimble_utils.h:557
NIMBLE_INLINE_FUNCTION void SymPart_Full33(const ScalarT *const mat, ScalarT *const result)
Definition nimble_utils.h:486
NIMBLE_INLINE_FUNCTION void Mult_Sym33_Full33(const ScalarT *const sym, const ScalarT *const full, ScalarT *const result)
Multiply a symmetric tensor by a full tensor.
Definition nimble_utils.h:276
NIMBLE_INLINE_FUNCTION ScalarT if_then(const bool b, const ScalarT v1, const ScalarT v2)
Definition nimble_utils.h:148
NIMBLE_INLINE_FUNCTION void SkewPart_Full33(const ScalarT *const mat, ScalarT *const result)
Definition nimble_utils.h:498
NIMBLE_INLINE_FUNCTION void Mult_Full33_Full33(const ScalarT *const A, const ScalarT *const B, ScalarT *const result)
Multiply a full tensor by a full tensor.
Definition nimble_utils.h:258
NIMBLE_INLINE_FUNCTION ScalarT Norm_Sym33(const ScalarT *const mat)
Definition nimble_utils.h:416
NIMBLE_INLINE_FUNCTION void BCH_Sym33_Full33(const ScalarT *const sym, const ScalarT *const full, ScalarT *const result)
R^N logarithmic map using Baker-Campbell-Hausdorff (BCH) expansion (4 terms)
Definition nimble_utils.h:629
void Print_Sym33(std::string label, const ScalarT *const mat, int precision=2)
Definition nimble_utils.h:182