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