25#ifndef __B2ELEMENT_CONTINUUM_UTIL_H__
26#define __B2ELEMENT_CONTINUUM_UTIL_H__
32#include "elements/properties/b2solid_mechanics.H"
33#include "model/b2element.H"
35#include "utils/b2linear_algebra.H"
45typedef b2linalg::Vector<double, b2linalg::Vdense> VD;
46typedef b2linalg::Vector<double, b2linalg::Vdense_ref> VR;
47typedef b2linalg::Vector<double, b2linalg::Vdense_constref> VDC;
48typedef b2linalg::Matrix<double, b2linalg::Mrectangle> ME;
49typedef b2linalg::Matrix<double, b2linalg::Mrectangle_constref> MEC;
50typedef b2linalg::Matrix<double, b2linalg::Mpacked> MP;
51typedef b2linalg::Matrix<double, b2linalg::Mupper_packed> MUP;
52typedef b2linalg::Matrix<double, b2linalg::Mupper_packed_constref> MUPC;
53typedef b2linalg::Matrix<double, b2linalg::Mlower_packed> MLP;
54typedef b2linalg::Matrix<double, b2linalg::Mlower_packed_constref> MLPC;
63inline void sc_eq_va_mul_vb(
double& c,
const double A[SIZE],
const double B[SIZE]) {
65 for (
int i = 0; i != SIZE; ++i) { c += A[i] * B[i]; }
68template <
int SIZE_BC,
int SIZE_AB>
69inline void vc_eq_va_mul_mb(
70 double C[SIZE_BC],
const double A[SIZE_AB],
const double B[SIZE_AB][SIZE_BC]) {
71 for (
int i = 0; i != SIZE_BC; ++i) {
73 for (
int j = 0; j != SIZE_AB; ++j) { s += A[j] * B[j][i]; }
78template <
int SIZE_BC,
int SIZE_AB>
79inline void vc_eq_va_mul_mbt(
80 double C[SIZE_BC],
const double A[SIZE_AB],
const double B[SIZE_BC][SIZE_AB]) {
81 for (
int i = 0; i != SIZE_BC; ++i) {
83 for (
int j = 0; j != SIZE_AB; ++j) { s += A[j] * B[i][j]; }
88template <
int SIZE_CR,
int SIZE_CC>
89inline void mb_eq_mat(
double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CC][SIZE_CR]) {
90 for (
int i = 0; i != SIZE_CR; ++i) {
91 for (
int j = 0; j != SIZE_CC; ++j) { C[i][j] = A[j][i]; }
95template <
int SIZE_CR,
int SIZE_CC>
96inline void mb_eq_add_mat(
double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CC][SIZE_CR]) {
97 for (
int i = 0; i != SIZE_CR; ++i) {
98 for (
int j = 0; j != SIZE_CC; ++j) { C[i][j] += A[j][i]; }
102template <
int SIZE_CR,
int SIZE_CC>
103inline void mc_eq_ma_mul_sb(
104 double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CR][SIZE_CC],
const double sb) {
105 for (
int j = 0; j != SIZE_CR; ++j) {
106 for (
int i = 0; i != SIZE_CC; ++i) { C[j][i] = sb * A[j][i]; }
110template <
int SIZE_CR,
int SIZE_CC>
111inline void mc_eq_add_ma_mul_sb(
112 double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CR][SIZE_CC],
const double sb) {
114 const double* Ap = A[0];
115 for (
int i = 0; i != SIZE_CR * SIZE_CC; ++i) { Cp[i] += sb * Ap[i]; }
118template <
int SIZE_CR,
int SIZE_CC>
119inline void mc_eq_ma_plus_mb(
120 double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CR][SIZE_CC],
121 const double B[SIZE_CR][SIZE_CC]) {
123 const double* Ap = A[0];
124 const double* Bp = B[0];
125 for (
int i = 0; i != SIZE_CR * SIZE_CC; ++i) { Cp[i] = Ap[i] + Bp[i]; }
128template <
int SIZE_CR,
int SIZE_CC>
129inline void mc_eq_add_ma_plus_mb(
130 double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CR][SIZE_CC],
131 const double B[SIZE_CR][SIZE_CC]) {
133 const double* Ap = A[0];
134 const double* Bp = B[0];
135 for (
int i = 0; i != SIZE_CR * SIZE_CC; ++i) { Cp[i] += Ap[i] + Bp[i]; }
138template <
int SIZE_CR,
int SIZE_CC>
139inline void mc_eq_ma_minus_mb(
140 double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CR][SIZE_CC],
141 const double B[SIZE_CR][SIZE_CC]) {
143 const double* Ap = A[0];
144 const double* Bp = B[0];
145 for (
int i = 0; i != SIZE_CR * SIZE_CC; ++i) { Cp[i] = Ap[i] - Bp[i]; }
148template <
int SIZE_CR,
int SIZE_CC>
149inline void mc_eq_add_ma_minus_mb(
150 double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CR][SIZE_CC],
151 const double B[SIZE_CR][SIZE_CC]) {
153 const double* Ap = A[0];
154 const double* Bp = B[0];
155 for (
int i = 0; i != SIZE_CR * SIZE_CC; ++i) { Cp[i] += Ap[i] - Bp[i]; }
158template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
159inline void mc_eq_ma_mul_mb(
160 double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CR][SIZE_AB],
161 const double B[SIZE_AB][SIZE_CC]) {
162 for (
int i = 0; i != SIZE_CR; ++i) {
163 for (
int j = 0; j != SIZE_CC; ++j) {
165 for (
int k = 0; k != SIZE_AB; ++k) { s += A[i][k] * B[k][j]; }
171template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
172inline void mc_eq_add_ma_mul_mb(
173 double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CR][SIZE_AB],
174 const double B[SIZE_AB][SIZE_CC]) {
175 for (
int i = 0; i != SIZE_CR; ++i) {
176 for (
int j = 0; j != SIZE_CC; ++j) {
178 for (
int k = 0; k != SIZE_AB; ++k) { s += A[i][k] * B[k][j]; }
184template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
185inline void mc_eq_mat_mul_mb(
186 double C[SIZE_CR][SIZE_CC],
const double AT[SIZE_AB][SIZE_CR],
187 const double B[SIZE_AB][SIZE_CC]) {
188 for (
int i = 0; i != SIZE_CR; ++i) {
189 for (
int j = 0; j != SIZE_CC; ++j) {
191 for (
int k = 0; k != SIZE_AB; ++k) { s += AT[k][i] * B[k][j]; }
197template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
198inline void mc_eq_add_mat_mul_mb(
199 double C[SIZE_CR][SIZE_CC],
const double AT[SIZE_AB][SIZE_CR],
200 const double B[SIZE_AB][SIZE_CC]) {
201 for (
int i = 0; i != SIZE_CR; ++i) {
202 for (
int j = 0; j != SIZE_CC; ++j) {
204 for (
int k = 0; k != SIZE_AB; ++k) { s += AT[k][i] * B[k][j]; }
210template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
211inline void mc_eq_ma_mul_mbt(
212 double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CR][SIZE_AB],
213 const double BT[SIZE_CC][SIZE_AB]) {
214 for (
int i = 0; i != SIZE_CR; ++i) {
215 for (
int j = 0; j != SIZE_CC; ++j) {
217 for (
int k = 0; k != SIZE_AB; ++k) { s += A[i][k] * BT[j][k]; }
223template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
224inline void mc_eq_add_ma_mul_mbt(
225 double C[SIZE_CR][SIZE_CC],
const double A[SIZE_CR][SIZE_AB],
226 const double BT[SIZE_CC][SIZE_AB]) {
227 for (
int i = 0; i != SIZE_CR; ++i) {
228 for (
int j = 0; j != SIZE_CC; ++j) {
230 for (
int k = 0; k != SIZE_AB; ++k) { s += A[i][k] * BT[j][k]; }
236template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
237inline void mc_eq_mat_mul_mbt(
238 double C[SIZE_CR][SIZE_CC],
const double AT[SIZE_AB][SIZE_CR],
239 const double BT[SIZE_CC][SIZE_AB]) {
240 for (
int i = 0; i != SIZE_CR; ++i) {
241 for (
int j = 0; j != SIZE_CC; ++j) {
243 for (
int k = 0; k != SIZE_AB; ++k) { s += AT[k][i] * BT[j][k]; }
249template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
250inline void mc_eq_add_mat_mul_mbt(
251 double C[SIZE_CR][SIZE_CC],
const double AT[SIZE_AB][SIZE_CR],
252 const double BT[SIZE_CC][SIZE_AB]) {
253 for (
int i = 0; i != SIZE_CR; ++i) {
254 for (
int j = 0; j != SIZE_CC; ++j) {
256 for (
int k = 0; k != SIZE_AB; ++k) { s += AT[k][i] * BT[j][k]; }
262template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
263inline void mct_eq_ma_mul_mb(
264 double CT[SIZE_CR][SIZE_CC],
const double A[SIZE_CC][SIZE_AB],
265 const double B[SIZE_AB][SIZE_CR]) {
266 for (
int j = 0; j != SIZE_CR; ++j) {
267 for (
int i = 0; i != SIZE_CC; ++i) {
269 for (
int k = 0; k != SIZE_AB; ++k) { s += A[i][k] * B[k][j]; }
275template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
276inline void mct_eq_add_ma_mul_mb(
277 double CT[SIZE_CR][SIZE_CC],
const double A[SIZE_CC][SIZE_AB],
278 const double B[SIZE_AB][SIZE_CR]) {
279 for (
int j = 0; j != SIZE_CR; ++j) {
280 for (
int i = 0; i != SIZE_CC; ++i) {
282 for (
int k = 0; k != SIZE_AB; ++k) { s += A[i][k] * B[k][j]; }
288template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
289inline void mct_eq_mat_mul_mb(
290 double CT[SIZE_CR][SIZE_CC],
const double AT[SIZE_AB][SIZE_CC],
291 const double B[SIZE_AB][SIZE_CR]) {
292 for (
int j = 0; j != SIZE_CR; ++j) {
293 for (
int i = 0; i != SIZE_CC; ++i) {
295 for (
int k = 0; k != SIZE_AB; ++k) { s += AT[k][i] * B[k][j]; }
301template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
302inline void mct_eq_add_mat_mul_mb(
303 double CT[SIZE_CR][SIZE_CC],
const double AT[SIZE_AB][SIZE_CC],
304 const double B[SIZE_AB][SIZE_CR]) {
305 for (
int j = 0; j != SIZE_CR; ++j) {
306 for (
int i = 0; i != SIZE_CC; ++i) {
308 for (
int k = 0; k != SIZE_AB; ++k) { s += AT[k][i] * B[k][j]; }
314template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
315inline void mct_eq_ma_mul_mbt(
316 double CT[SIZE_CR][SIZE_CC],
const double A[SIZE_CC][SIZE_AB],
317 const double BT[SIZE_CR][SIZE_AB]) {
318 for (
int j = 0; j != SIZE_CR; ++j) {
319 for (
int i = 0; i != SIZE_CC; ++i) {
321 for (
int k = 0; k != SIZE_AB; ++k) { s += A[i][k] * BT[j][k]; }
327template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
328inline void mct_eq_add_ma_mul_mbt(
329 double CT[SIZE_CR][SIZE_CC],
const double A[SIZE_CC][SIZE_AB],
330 const double BT[SIZE_CR][SIZE_AB]) {
331 for (
int j = 0; j != SIZE_CR; ++j) {
332 for (
int i = 0; i != SIZE_CC; ++i) {
334 for (
int k = 0; k != SIZE_AB; ++k) { s += A[i][k] * BT[j][k]; }
340template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
341inline void mct_eq_mat_mul_mbt(
342 double CT[SIZE_CR][SIZE_CC],
const double AT[SIZE_AB][SIZE_CC],
343 const double BT[SIZE_CR][SIZE_AB]) {
344 for (
int j = 0; j != SIZE_CR; ++j) {
345 for (
int i = 0; i != SIZE_CC; ++i) {
347 for (
int k = 0; k != SIZE_AB; ++k) { s += AT[k][i] * BT[j][k]; }
353template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
354inline void mct_eq_add_mat_mul_mbt(
355 double CT[SIZE_CR][SIZE_CC],
const double AT[SIZE_AB][SIZE_CC],
356 const double BT[SIZE_CR][SIZE_AB]) {
357 for (
int j = 0; j != SIZE_CR; ++j) {
358 for (
int i = 0; i != SIZE_CC; ++i) {
360 for (
int k = 0; k != SIZE_AB; ++k) { s += AT[k][i] * BT[j][k]; }
371inline void sc_eq_va_mul_vb(
double& c,
const VDC& A,
const VDC& B) {
373 for (
int i = 0; i < SIZE; ++i) { c += A[i] * B[i]; }
376template <
int SIZE_CR,
int SIZE_CC>
377inline void mc_eq_ma_mul_sb(ME& C,
const MEC& A,
const double sb) {
378 for (
int i = 0; i < SIZE_CR; ++i) {
379 for (
int j = 0; j < SIZE_CC; ++j) { C(i, j) = sb * A(i, j); }
383template <
int SIZE_CR,
int SIZE_CC>
384inline void mc_eq_ma_plus_mb(ME& C,
const MEC& A,
const MEC& B) {
385 for (
int i = 0; i < SIZE_CR; ++i) {
386 for (
int j = 0; j < SIZE_CC; ++j) { C(i, j) = A(i, j) + B(i, j); }
390template <
int SIZE_CR,
int SIZE_CC>
391inline void mc_eq_ma_minus_mb(ME& C,
const MEC& A,
const MEC& B) {
392 for (
int i = 0; i < SIZE_CR; ++i) {
393 for (
int j = 0; j < SIZE_CC; ++j) { C(i, j) = A(i, j) - B(i, j); }
397template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
398inline void mc_eq_ma_mul_mb(ME& C,
const MEC& A,
const MEC& B) {
399 for (
int i = 0; i < SIZE_CR; ++i) {
400 for (
int j = 0; j < SIZE_CC; ++j) {
402 for (
int k = 0; k < SIZE_AB; ++k) { s += A(i, k) * B(k, j); }
408template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
409inline void mc_eq_mat_mul_mb(ME& C,
const MEC& A,
const MEC& B) {
410 for (
int i = 0; i < SIZE_CR; ++i) {
411 for (
int j = 0; j < SIZE_CC; ++j) {
413 for (
int k = 0; k < SIZE_AB; ++k) { s += A(k, i) * B(k, j); }
419template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
420inline void mc_eq_ma_mul_mbt(ME& C,
const MEC& A,
const MEC& B) {
421 for (
int i = 0; i < SIZE_CR; ++i) {
422 for (
int j = 0; j < SIZE_CC; ++j) {
424 for (
int k = 0; k < SIZE_AB; ++k) { s += A(i, k) * B(j, k); }
430template <
int SIZE_CR,
int SIZE_CC,
int SIZE_AB>
431inline void mc_eq_mat_mul_mbt(ME& C,
const MEC& A,
const MEC& B) {
432 for (
int i = 0; i < SIZE_CR; ++i) {
433 for (
int j = 0; j < SIZE_CC; ++j) {
435 for (
int k = 0; k < SIZE_AB; ++k) { s += A(k, i) * B(j, k); }
454inline double eval_determinant_2x2(
const ME& a) {
456 double det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
474inline double eval_determinant_and_adjoint_2x2(
const ME& a, ME& adj) {
476 double det = eval_determinant_2x2(a);
479 adj[0][0] = +a[1][1];
480 adj[0][1] = -a[0][1];
481 adj[1][0] = -a[1][0];
482 adj[1][1] = +a[0][0];
498inline double eval_determinant_3x3(
const ME& a) {
500 double det = a[0][0] * a[1][1] * a[2][2] + a[0][1] * a[1][2] * a[2][0]
501 + a[0][2] * a[1][0] * a[2][1] - a[0][0] * a[1][2] * a[2][1]
502 - a[0][1] * a[1][0] * a[2][2] - a[0][2] * a[1][1] * a[2][0];
524inline double eval_determinant_and_adjoint_3x3(
const ME& a, ME& adj) {
525 double a00 = a[0][0];
526 double a01 = a[0][1];
527 double a02 = a[0][2];
528 double a10 = a[1][0];
529 double a11 = a[1][1];
530 double a12 = a[1][2];
531 double a20 = a[2][0];
532 double a21 = a[2][1];
533 double a22 = a[2][2];
536 adj[0][0] = a11 * a22 - a12 * a21;
537 adj[0][1] = a02 * a21 - a01 * a22;
538 adj[0][2] = a01 * a12 - a02 * a11;
539 adj[1][0] = a12 * a20 - a10 * a22;
540 adj[1][1] = a00 * a22 - a02 * a20;
541 adj[1][2] = a02 * a10 - a00 * a12;
542 adj[2][0] = a10 * a21 - a11 * a20;
543 adj[2][1] = a01 * a20 - a00 * a21;
544 adj[2][2] = a00 * a11 - a01 * a10;
548 a00 * a11 * a22 + a01 * a12 * a20 + a02 * a10 * a21 - a00 * a12 * a21 - a01 * a10 * a22
568inline void eval_linear_strain_3(
const ME& F,
double* E) {
569 const double f00 = F(0, 0);
570 const double f01 = F(0, 1);
571 const double f02 = F(0, 2);
572 const double f10 = F(1, 0);
573 const double f11 = F(1, 1);
574 const double f12 = F(1, 2);
575 const double f20 = F(2, 0);
576 const double f21 = F(2, 1);
577 const double f22 = F(2, 2);
587inline void eval_linear_strain_3(
const double F[3][3],
double E[6]) {
588 const double f00 = F[0][0];
589 const double f01 = F[0][1];
590 const double f02 = F[0][2];
591 const double f10 = F[1][0];
592 const double f11 = F[1][1];
593 const double f12 = F[1][2];
594 const double f20 = F[2][0];
595 const double f21 = F[2][1];
596 const double f22 = F[2][2];
622inline void eval_green_lagrange_strain_3(
const ME& F,
double* E) {
623 const double f00 = F(0, 0);
624 const double f01 = F(0, 1);
625 const double f02 = F(0, 2);
626 const double f10 = F(1, 0);
627 const double f11 = F(1, 1);
628 const double f12 = F(1, 2);
629 const double f20 = F(2, 0);
630 const double f21 = F(2, 1);
631 const double f22 = F(2, 2);
633 E[0] = 0.5 * (f00 * f00 + f10 * f10 + f20 * f20 - 1.0);
634 E[1] = 0.5 * (f01 * f01 + f11 * f11 + f21 * f21 - 1.0);
635 E[2] = 0.5 * (f02 * f02 + f12 * f12 + f22 * f22 - 1.0);
636 E[3] = f00 * f01 + f10 * f11 + f20 * f21;
637 E[4] = f01 * f02 + f11 * f12 + f21 * f22;
638 E[5] = f00 * f02 + f10 * f12 + f20 * f22;
641inline void eval_green_lagrange_strain_3t(
const double FT[3][3],
double E[6]) {
642 const double f00 = FT[0][0];
643 const double f01 = FT[1][0];
644 const double f02 = FT[2][0];
645 const double f10 = FT[0][1];
646 const double f11 = FT[1][1];
647 const double f12 = FT[2][1];
648 const double f20 = FT[0][2];
649 const double f21 = FT[1][2];
650 const double f22 = FT[2][2];
652 E[0] = 0.5 * (f00 * f00 + f10 * f10 + f20 * f20 - 1.0);
653 E[1] = 0.5 * (f01 * f01 + f11 * f11 + f21 * f21 - 1.0);
654 E[2] = 0.5 * (f02 * f02 + f12 * f12 + f22 * f22 - 1.0);
655 E[3] = f00 * f01 + f10 * f11 + f20 * f21;
656 E[4] = f01 * f02 + f11 * f12 + f21 * f22;
657 E[5] = f00 * f02 + f10 * f12 + f20 * f22;
676inline void eval_linear_strain_2(
const ME& F,
double* E) {
677 const double f00 = F(0, 0);
678 const double f01 = F(0, 1);
679 const double f10 = F(1, 0);
680 const double f11 = F(1, 1);
687inline void eval_linear_strain_2(
const double F[2][2],
double E[3]) {
688 const double f00 = F[0][0];
689 const double f01 = F[0][1];
690 const double f10 = F[1][0];
691 const double f11 = F[1][1];
714inline void eval_green_lagrange_strain_2(
const ME& F,
double* E) {
715 const double f00 = F(0, 0);
716 const double f01 = F(0, 1);
717 const double f10 = F(1, 0);
718 const double f11 = F(1, 1);
720 E[0] = 0.5 * (f00 * f00 + f10 * f10 - 1.0);
721 E[1] = 0.5 * (f01 * f01 + f11 * f11 - 1.0);
722 E[2] = f00 * f01 + f10 * f11;
725inline void eval_green_lagrange_strain_2t(
const double FT[2][2],
double E[3]) {
726 const double f00 = FT[0][0];
727 const double f01 = FT[1][0];
728 const double f10 = FT[0][1];
729 const double f11 = FT[1][1];
731 E[0] = 0.5 * (f00 * f00 + f10 * f10 - 1.0);
732 E[1] = 0.5 * (f01 * f01 + f11 * f11 - 1.0);
733 E[2] = f00 * f01 + f10 * f11;
741const int tensor_3x3_to_6_conversion_table[3][3] = {{0, 3, 5}, {3, 1, 4}, {5, 4, 2}};
743void tensor_strain_3x3_to_6(
const ME& a,
double* b);
745void tensor_stress_6_to_3x3(
const double* a, ME& b);
747void tensor_stress_3x3_to_6(
const ME& a,
double* b);
749void tensor_strain_2x2_to_3(
const ME& a,
double* b);
751void tensor_stress_3_to_2x2(
const double* a, ME& b);
753void make_director_3x3(ME& m);
755double get_surface(ME& m);
760void get_surface_directors(
const ME& J, ME& d_coor_d_lcoor,
double& surface);
768 inline Natural_Coor() {
774 inline Natural_Coor(
double r_,
double s_,
double t_) {
780 inline Natural_Coor(
const double* rst_) {
786 inline const double& operator[](
int index)
const {
787 assert(index >= 0 && index < 3);
791 inline double& operator[](
int index) {
792 assert(index >= 0 && index < 3);
796 inline const double*
data()
const {
return rst; }
798 inline double*
data() {
return rst; }
800 inline bool operator<(
const Natural_Coor& n)
const {
801 if (rst[2] != n.rst[2]) {
return rst[2] < n.rst[2]; }
802 if (rst[1] != n.rst[1]) {
return rst[1] < n.rst[1]; }
803 return rst[0] < n.rst[0];
817 Shape_Value(
int num_nodes) : h(num_nodes), h_derived(3, num_nodes) { ; }
832template <
typename SE>
833class Shape_Value_Map :
public std::map<Natural_Coor, Shape_Value> {
836 virtual ~Shape_Value_Map(){};
838 iterator insert(
const key_type& natural_coor) {
839 iterator i = find(natural_coor);
845 Shape_Value shape_value(SE::num_nodes);
846 SE::eval_h(natural_coor.data(), shape_value.h);
847 SE::eval_h_derived(natural_coor.data(), shape_value.h_derived);
848 std::pair<iterator, bool> result = std::map<Natural_Coor, Shape_Value>::insert(
849 value_type(natural_coor, shape_value));
856typedef std::map<Natural_Coor, Shape_Value>::const_iterator svm_const_iterator_t;
869class IP_ID :
public Natural_Coor {
871 inline IP_ID() : f_layer_id(0) {}
873 inline IP_ID(
double r_,
double s_,
double t_,
int layer_id_)
874 : Natural_Coor(r_, s_, t_), f_layer_id(layer_id_) {
878 inline IP_ID(
const double* rst_,
int layer_id_) : Natural_Coor(rst_), f_layer_id(layer_id_) {
882 inline IP_ID(
const Natural_Coor& n,
int layer_id_) : Natural_Coor(n), f_layer_id(layer_id_) {
886 inline int layer_id()
const {
return f_layer_id; }
888 inline int& layer_id() {
return f_layer_id; }
890 inline bool operator<(
const IP_ID& i)
const {
891 if (f_layer_id != i.f_layer_id) {
return f_layer_id < i.f_layer_id; }
892 if ((*
this)[2] != i[2]) {
return (*
this)[2] < i[2]; }
893 if ((*
this)[1] != i[1]) {
return (*
this)[1] < i[1]; }
894 return (*
this)[0] < i[0];
924inline void add_w1_to_second_3d(
930 assert(B.size1() == 6);
931 assert(d_value_d_dof.size1() == B.size2());
932 const size_t NDOF = B.size2();
937 b2linalg::Matrix<double, b2linalg::Mlower_packed_constref> CC(6, C);
940 ME BTBC = transposed(B) * CB;
941 test = BTBC * volume;
942 ME KK(d_value_d_dof);
947 for (
size_t j = 0; j != NDOF; ++j) {
951 t[0] = Bj[0] * C[0] + Bj[1] * C[1] + Bj[2] * C[2] + Bj[3] * C[3] + Bj[4] * C[4]
954 t[1] = Bj[0] * C[1] + Bj[1] * C[6] + Bj[2] * C[7] + Bj[3] * C[8] + Bj[4] * C[9]
957 t[2] = Bj[0] * C[2] + Bj[1] * C[7] + Bj[2] * C[11] + Bj[3] * C[12] + Bj[4] * C[13]
960 t[3] = Bj[0] * C[3] + Bj[1] * C[8] + Bj[2] * C[12] + Bj[3] * C[15] + Bj[4] * C[16]
963 t[4] = Bj[0] * C[4] + Bj[1] * C[9] + Bj[2] * C[13] + Bj[3] * C[16] + Bj[4] * C[18]
966 t[5] = Bj[0] * C[5] + Bj[1] * C[10] + Bj[2] * C[14] + Bj[3] * C[17] + Bj[4] * C[19]
976 for (
size_t i = 0; i <= j; ++i) {
978 const double s = Bi[0] * t[0] + Bi[1] * t[1] + Bi[2] * t[2] + Bi[3] * t[3]
979 + Bi[4] * t[4] + Bi[5] * t[5];
980 d_value_d_dof(i, j) += s;
987 for (
size_t j = 0; j != NDOF; ++j) {
988 for (
size_t i = 0; i <= j; ++i) { sd += std::abs(test(i, j) - d_value_d_dof(i, j)); }
991 std::cerr <<
"Error in add_w1_to_second: sd=" << sd << std::endl;
992 for (
size_t j = 0; j != NDOF; ++j) {
993 for (
size_t i = 0; i <= j; ++i) {
994 const double diff = std::abs(test(i, j) - d_value_d_dof(i, j));
996 std::cerr << std::setprecision(17) <<
" K[" << i <<
"," << j
997 <<
"]=" << d_value_d_dof(i, j) <<
" T=" << test(i, j)
998 <<
" diff=" << diff << std::endl;
1033inline void add_w1_to_second_3d(
1034 const double BT[NDOF][6],
const double C[21],
const double volume,
1044 assert(d_value_d_dof.is_upper());
1045 second_0_0 = &d_value_d_dof(0, 0);
1047 for (
int j = 0; j != NDOF; ++j) {
1049 t[0] = b_j[0] * C[0] + b_j[1] * C[1] + b_j[2] * C[2] + b_j[3] * C[3] + b_j[4] * C[4]
1052 t[1] = b_j[0] * C[1] + b_j[1] * C[6] + b_j[2] * C[7] + b_j[3] * C[8] + b_j[4] * C[9]
1055 t[2] = b_j[0] * C[2] + b_j[1] * C[7] + b_j[2] * C[11] + b_j[3] * C[12] + b_j[4] * C[13]
1058 t[3] = b_j[0] * C[3] + b_j[1] * C[8] + b_j[2] * C[12] + b_j[3] * C[15] + b_j[4] * C[16]
1061 t[4] = b_j[0] * C[4] + b_j[1] * C[9] + b_j[2] * C[13] + b_j[3] * C[16] + b_j[4] * C[18]
1064 t[5] = b_j[0] * C[5] + b_j[1] * C[10] + b_j[2] * C[14] + b_j[3] * C[17] + b_j[4] * C[19]
1074 second_0_j = second_0_0 + (j * (j + 1) / 2);
1076 for (
int i = 0; i <= j; ++i) {
1078 s = b_i[0] * t[0] + b_i[1] * t[1] + b_i[2] * t[2] + b_i[3] * t[3] + b_i[4] * t[4]
1129inline void add_w2_to_second_3d(
1132 const double volume,
1138 double* second_0_j0;
1139 double* second_0_j1;
1140 double* second_0_j2;
1149 assert(d_value_d_dof.is_upper());
1150 const int NNEL = NDOF / 3;
1153 MP test(NDOF,
true);
1159 for (
int k = 0; k < NNEL; k++) {
1164 BNL(0, k0) = D(0, k);
1165 BNL(1, k0) = D(1, k);
1166 BNL(2, k0) = D(2, k);
1167 BNL(3, k1) = D(0, k);
1168 BNL(4, k1) = D(1, k);
1169 BNL(5, k1) = D(2, k);
1170 BNL(6, k2) = D(0, k);
1171 BNL(7, k2) = D(1, k);
1172 BNL(8, k2) = D(2, k);
1177 for (
int i = 0; i < 3; i++) {
1179 SM(j + 0, j + 0) = S[0];
1180 SM(j + 0, j + 1) = S[3];
1181 SM(j + 0, j + 2) = S[5];
1182 SM(j + 1, j + 0) = S[3];
1183 SM(j + 1, j + 1) = S[1];
1184 SM(j + 1, j + 2) = S[4];
1185 SM(j + 2, j + 0) = S[5];
1186 SM(j + 2, j + 1) = S[4];
1187 SM(j + 2, j + 2) = S[2];
1191 W2 = volume * transposed(BNL) * SMBNL;
1194 for (
int j = 0; j < NDOF; j++) {
1195 for (
int i = 0; i <= j; i++) { test(i, j) = W2(i, j); }
1197 test += d_value_d_dof;
1201 second_0_0 = &d_value_d_dof(0, 0);
1202 for (
int j = 0; j < NNEL; j++) {
1209 b[0] = S[0] * d_j[0] + S[3] * d_j[1] + S[5] * d_j[2];
1210 b[1] = S[3] * d_j[0] + S[1] * d_j[1] + S[4] * d_j[2];
1211 b[2] = S[5] * d_j[0] + S[4] * d_j[1] + S[2] * d_j[2];
1213 second_0_j0 = second_0_0 + (j0 * (j0 + 1) / 2);
1214 second_0_j1 = second_0_0 + (j1 * (j1 + 1) / 2);
1215 second_0_j2 = second_0_0 + (j2 * (j2 + 1) / 2);
1217 for (
int i = 0; i <= j; i++) {
1220 double s = d_i[0] * b[0] + d_i[1] * b[1] + d_i[2] * b[2];
1227 second_0_j0[i0] += s;
1228 second_0_j1[i1] += s;
1229 second_0_j2[i2] += s;
1235 for (
int j = 0; j < NDOF; j++) {
1236 for (
int i = 0; i < NDOF; i++) {
1237 double diff = test(i, j) - d_value_d_dof(i, j);
1242 std::cerr <<
"Error in add_w2_to_second: sd=" << sd << std::endl;
1270inline void add_to_mass_matrix_3d(
1272 const double density,
1273 const double volume,
1274 MP& d_value_d_dofdotdot
1276 const int NNEL = H.size();
1277 const int NDOF = NNEL * 3;
1282 for (
int i = 0; i < 3; i++) {
1283 for (
int j = 0; j < NNEL; j++) { HS(i, i + 3 * j) = H[j]; }
1286 MP test(NDOF,
true);
1287 for (
int kl = 0; kl < NDOF; kl++) {
1288 for (
int mn = 0; mn <= kl; mn++) { test(kl, mn) = HS[kl] * HS[mn] * volume * density; }
1290 test += d_value_d_dofdotdot;
1293 const double dv = density * volume;
1295 for (
int kl = 0; kl < NDOF; kl++) {
1298 const double a = H[k] * dv;
1299 for (
int m = 0; m <= k; ++m) {
1301 d_value_d_dofdotdot(kl, mn) += a * H[m];
1308 for (
int j = 0; j < NDOF; j++) {
1309 for (
int i = 0; i < NDOF; i++) {
1310 avg += test(i, j) * test(i, j);
1311 double diff = test(i, j) - d_value_d_dofdotdot(i, j);
1315 avg /= (NDOF * (NDOF + 1));
1317 if (sd > 1e-10 * avg) {
1318 std::cerr <<
"Error in add_to_mass_matrix_3d: sd=" << sd << std::endl;
1348inline void add_to_mass_matrix_3d(
1349 const double H[NNEL],
1350 const double density,
1351 const double volume,
1352 MP& d_value_d_dofdotdot
1354 assert(d_value_d_dofdotdot.is_upper());
1355 const int NDOF = NNEL * 3;
1360 for (
int i = 0; i < 3; i++) {
1361 for (
int j = 0; j < NNEL; j++) { HS(i, i + 3 * j) = H[j]; }
1364 MP test(NDOF,
true);
1365 for (
int kl = 0; kl < NDOF; kl++) {
1366 for (
int mn = 0; mn <= kl; mn++) { test(kl, mn) = HS[kl] * HS[mn] * volume * density; }
1368 test += d_value_d_dofdotdot;
1371 const double dv = density * volume;
1373 double* mass_0_0 = &d_value_d_dofdotdot(0, 0);
1374 for (
int kl = 0; kl != NDOF; ++kl) {
1375 const int k = kl / 3;
1376 const int l = kl % 3;
1377 const double a = H[k] * dv;
1378 double* mass_0_kl = mass_0_0 + (kl * (kl + 1) / 2);
1379 for (
int m = 0; m <= k; ++m) {
1381 mass_0_kl[mn] += a * H[m];
1388 for (
int j = 0; j < NDOF; j++) {
1389 for (
int i = 0; i < NDOF; i++) {
1390 avg += test(i, j) * test(i, j);
1391 double diff = test(i, j) - d_value_d_dofdotdot(i, j);
1395 avg /= (NDOF * (NDOF + 1));
1397 if (sd > 1e-10 * avg) {
1398 std::cerr <<
"Error in add_to_mass_matrix_3d: sd=" << sd << std::endl;
1407inline void write_ip_coor_disp_3d(
1413 const double area, GradientContainer* gradient_container) {
1414 if (gradient_container ==
nullptr) {
return; }
1417 const GradientContainer::InternalElementPosition ip = {xi[0], xi[1], xi[2], layer_id};
1418 gradient_container->set_current_position(ip, area);
1419 static const GradientContainer::FieldDescription coor_descr = {
1422 "Physical coordinate of the point "
1423 "in the reference configuration",
1430 if (gradient_container->compute_field_value(coor_descr.name)) {
1433 gradient_container->set_field_value(coor_descr, &pcoor[0]);
1438 static const GradientContainer::FieldDescription disp_descr = {
1439 "DISP_IP",
"dx.dy.dz",
"Physical displacement at the point", 3, 3, 1, 3,
1440 false,
typeid(double)};
1441 if (gradient_container->compute_field_value(disp_descr.name)) {
1444 gradient_container->set_field_value(disp_descr, &pdisp[0]);
1452inline void write_ip_coor_disp_3d(
1455 const double H[NNEL],
1456 const double X[NNEL][3],
1457 const double U[NNEL][3],
1458 const double area, GradientContainer* gradient_container) {
1459 if (gradient_container ==
nullptr) {
return; }
1462 const GradientContainer::InternalElementPosition ip = {xi[0], xi[1], xi[2], layer_id};
1463 gradient_container->set_current_position(ip, area);
1464 static const GradientContainer::FieldDescription coor_descr = {
1467 "Physical coordinate of the point "
1468 "in the reference configuration",
1475 if (gradient_container->compute_field_value(coor_descr.name)) {
1477 ffmv::vc_eq_va_mul_mb<3, NNEL>(pcoor, H, X);
1478 gradient_container->set_field_value(coor_descr, &pcoor[0]);
1483 static const GradientContainer::FieldDescription disp_descr = {
1484 "DISP_IP",
"dx.dy.dz",
"Physical displacement at the point", 3, 3, 1, 3,
1485 false,
typeid(double)};
1486 if (gradient_container->compute_field_value(disp_descr.name)) {
1488 ffmv::vc_eq_va_mul_mb<3, NNEL>(pdisp, H, U);
1489 gradient_container->set_field_value(disp_descr, &pdisp[0]);
1497inline void write_ip_coor_disp_2d(
1500 const double H[NNEL],
1501 const double X[NNEL][2],
1502 const double U[NNEL][2],
1503 const double area, GradientContainer* gradient_container) {
1504 if (gradient_container ==
nullptr) {
return; }
1507 const GradientContainer::InternalElementPosition ip = {xi[0], xi[1], xi[2], layer_id};
1508 gradient_container->set_current_position(ip, area);
1509 static const GradientContainer::FieldDescription coor_descr = {
1512 "Physical coordinate of the point "
1513 "in the reference configuration",
1520 if (gradient_container->compute_field_value(coor_descr.name)) {
1521 double pcoor[3] = {};
1522 ffmv::vc_eq_va_mul_mb<2, NNEL>(pcoor, H, X);
1523 gradient_container->set_field_value(coor_descr, &pcoor[0]);
1528 static const GradientContainer::FieldDescription disp_descr = {
1529 "DISP_IP",
"dx.dy.dz",
"Physical displacement at the point", 3, 3, 1, 3,
1530 false,
typeid(double)};
1531 if (gradient_container->compute_field_value(disp_descr.name)) {
1532 double pdisp[3] = {};
1533 ffmv::vc_eq_va_mul_mb<2, NNEL>(pdisp, H, U);
1534 gradient_container->set_field_value(disp_descr, &pdisp[0]);
1555inline void add_w1_to_second_2d(
1556 const double BT[NDOF][3],
const double C[6],
const double volume,
1566 assert(d_value_d_dof.is_upper());
1567 second_0_0 = &d_value_d_dof(0, 0);
1569 for (
int j = 0; j != NDOF; ++j) {
1571 t[0] = b_j[0] * C[0] + b_j[1] * C[1] + b_j[2] * C[2];
1572 t[1] = b_j[0] * C[1] + b_j[1] * C[3] + b_j[2] * C[4];
1573 t[2] = b_j[0] * C[2] + b_j[1] * C[4] + b_j[2] * C[5];
1579 second_0_j = second_0_0 + (j * (j + 1) / 2);
1581 for (
int i = 0; i <= j; ++i) {
1583 s = b_i[0] * t[0] + b_i[1] * t[1] + b_i[2] * t[2];
1590inline void add_w1_to_second_2d(
1605 MP test(NDOF,
true);
1606 test = area * transposed(B) * C * B;
1607 test += d_value_d_dof;
1610 second_0_0 = &d_value_d_dof(0, 0);
1613 for (
int j = 0; j < NDOF; j++) {
1615 t[0] = b_j[0] * c[0] + b_j[1] * c[1] + b_j[2] * c[2];
1616 t[1] = b_j[0] * c[1] + b_j[1] * c[3] + b_j[2] * c[4];
1617 t[2] = b_j[0] * c[2] + b_j[1] * c[4] + b_j[2] * c[5];
1623 second_0_j = second_0_0 + (j * (j + 1) / 2);
1625 for (
int i = 0; i <= j; i++) {
1627 s = b_i[0] * t[0] + b_i[1] * t[1] + b_i[2] * t[2];
1634 for (
int j = 0; j < NDOF; j++) {
1635 for (
int i = 0; i < NDOF; i++) {
1636 double diff = test(i, j) - d_value_d_dof(i, j);
1641 std::cerr <<
"Error in add_w1_to_second: sd=" << sd << std::endl;
1678inline void add_w2_to_second_2d(
1687 double* second_0_j0;
1688 double* second_0_j1;
1695 const int NNEL = NDOF / 2;
1698 MP test(NDOF,
true);
1704 for (
int k = 0; k < NNEL; k++) {
1708 BNL(0, k0) = DC(0, k);
1709 BNL(1, k0) = DC(1, k);
1710 BNL(3, k1) = DC(0, k);
1711 BNL(4, k1) = DC(1, k);
1716 for (
int i = 0; i < 2; i++) {
1718 SM(j + 0, j + 0) = S[0];
1719 SM(j + 0, j + 1) = S[2];
1720 SM(j + 1, j + 0) = S[2];
1721 SM(j + 1, j + 1) = S[1];
1725 W2 = area * transposed(BNL) * SMBNL;
1728 for (
int j = 0; j < NDOF; j++) {
1729 for (
int i = 0; i <= j; i++) { test(i, j) = W2(i, j); }
1731 test += d_value_d_dof;
1735 second_0_0 = &d_value_d_dof(0, 0);
1736 for (
int j = 0; j < NNEL; j++) {
1742 b[0] = S[0] * dc_j[0] + S[2] * dc_j[1];
1743 b[1] = S[2] * dc_j[0] + S[1] * dc_j[1];
1745 second_0_j0 = second_0_0 + (j0 * (j0 + 1) / 2);
1746 second_0_j1 = second_0_0 + (j1 * (j1 + 1) / 2);
1748 for (
int i = 0; i <= j; i++) {
1751 double s = dc_i[0] * b[0] + dc_i[1] * b[1];
1757 second_0_j0[i0] += s;
1758 second_0_j1[i1] += s;
1764 for (
int j = 0; j < NDOF; j++) {
1765 for (
int i = 0; i < NDOF; i++) {
1766 double diff = test(i, j) - d_value_d_dof(i, j);
1771 std::cerr <<
"Error in add_w2_to_second: sd=" << sd << std::endl;
1793void add_to_mass_matrix_2d(
1795 const double density,
1797 MP& d_value_d_dofdotdot
1799 const int NNEL = NDOF / 2;
1802 for (
int i = 0; i < 2; i++) {
1803 for (
int j = 0; j < NNEL; j++) { HS(i, i + 2 * j) = H[j]; }
1807 MP test(NDOF,
true);
1808 for (
int kl = 0; kl < NDOF; kl++) {
1809 for (
int mn = 0; mn <= kl; mn++) { test(kl, mn) = HS[kl] * HS[mn] * area * density; }
1811 test += d_value_d_dofdotdot;
1814 const double dv = density * area;
1816 double* mass_0_0 = &d_value_d_dofdotdot(0, 0);
1817 for (
int kl = 0; kl < NDOF; kl++) {
1818 double* mass_0_kl = mass_0_0 + (kl * (kl + 1) / 2);
1819 for (
int mn = 0; mn <= kl; mn++) { mass_0_kl[mn] += HS[kl] * HS[mn] * dv; }
1825 for (
int j = 0; j < NDOF; j++) {
1826 for (
int i = 0; i < NDOF; i++) {
1827 avg += test(i, j) * test(i, j);
1828 double diff = test(i, j) - d_value_d_dofdotdot(i, j);
1832 avg /= (NDOF * (NDOF + 1));
1834 if (sd > 1e-10 * avg) {
1835 std::cerr <<
"Error in add_to_mass_matrix: sd=" << sd << std::endl;
1857void add_to_mass_matrix_2d(
1858 const double H[NNEL],
1859 const double density,
1860 const double volume,
1861 MP& d_value_d_dofdotdot
1863 assert(d_value_d_dofdotdot.is_upper());
1864 const int NDOF = NNEL * 2;
1866 const double dv = density * volume;
1868 double* mass_0_0 = &d_value_d_dofdotdot(0, 0);
1869 for (
int kl = 0; kl != NDOF; ++kl) {
1870 const int k = kl / 2;
1871 const int l = kl % 2;
1872 const double a = H[k] * dv;
1873 double* mass_0_kl = mass_0_0 + (kl * (kl + 1) / 2);
1874 for (
int m = 0; m <= k; ++m) {
1876 mass_0_kl[mn] += a * H[m];
1884inline void write_ip_coor_disp_2d(
1890 const double area, GradientContainer* gradient_container) {
1891 if (gradient_container ==
nullptr) {
return; }
1894 const GradientContainer::InternalElementPosition ip = {xi[0], xi[1], xi[2], layer_id};
1895 gradient_container->set_current_position(ip, area);
1896 static const GradientContainer::FieldDescription coor_descr = {
1899 "Physical coordinate of the point "
1900 "in the reference configuration",
1907 if (gradient_container->compute_field_value(coor_descr.name)) {
1911 pcoor_3d[0] = pcoor[0];
1912 pcoor_3d[1] = pcoor[1];
1914 gradient_container->set_field_value(coor_descr, &pcoor_3d[0]);
1919 static const GradientContainer::FieldDescription disp_descr = {
1920 "DISP_IP",
"dx.dy.dz",
"Physical displacement at the point", 3, 3, 1, 3,
1921 false,
typeid(double)};
1922 if (gradient_container->compute_field_value(disp_descr.name)) {
1926 pdisp_3d[0] = pdisp[0];
1927 pdisp_3d[1] = pdisp[1];
1929 gradient_container->set_field_value(disp_descr, &pdisp_3d[0]);
bool operator<(const csda< T1 > &a, const csda< T2 > &b)
Comparison of two csda numbers is performed on the real part only.
Definition b2csda.H:262
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32