LCOV - code coverage report
Current view: top level - src/Model/Solid/Finite - NeoHookean.H (source / functions) Coverage Total Hit
Test: coverage_merged.info Lines: 89.7 % 97 87
Test Date: 2026-06-09 22:55:57 Functions: 100.0 % 10 10

            Line data    Source code
       1              : #ifndef MODEL_SOLID_FINITE_NEOHOOKEAN_H_
       2              : #define MODEL_SOLID_FINITE_NEOHOOKEAN_H_
       3              : 
       4              : #include "IO/ParmParse.H"
       5              : #include "Model/Solid/Solid.H"
       6              : #include "Unit/Unit.H"
       7              : 
       8              : namespace Model
       9              : {
      10              : namespace Solid
      11              : {
      12              : namespace Finite
      13              : {
      14              : class NeoHookean : public Solid<Set::Sym::Major>
      15              : {
      16              : public:
      17        13460 :     NeoHookean() = default;
      18              :     NeoHookean(Solid<Set::Sym::Major> base) : Solid<Set::Sym::Major>(base) {};
      19              :     ~NeoHookean() = default;
      20              : 
      21          960 :     Set::Scalar W(const Set::Matrix& a_F) const 
      22              :     {
      23              : #if AMREX_SPACEDIM==2
      24          380 :         Eigen::Matrix3d F = Eigen::Matrix3d::Identity();
      25          380 :         F(0, 0) = a_F(0, 0);
      26          380 :         F(0, 1) = a_F(0, 1);
      27          380 :         F(1, 0) = a_F(1, 0);
      28          380 :         F(1, 1) = a_F(1, 1);
      29              : #elif AMREX_SPACEDIM==3
      30          580 :         Eigen::Matrix3d F = a_F;
      31              : #endif
      32              : 
      33          960 :         Set::Scalar J = F.determinant();
      34          960 :         Set::Scalar J23 = std::pow(fabs(J), 2. / 3.);
      35          960 :         Set::Scalar w = 0.0;
      36          960 :         w += 0.5 * mu * ((F * F.transpose()).trace() / J23 - 3.);
      37          960 :         w += 0.5 * kappa * (J - 1.0) * (J - 1.0);
      38          960 :         return w;
      39              :     }
      40       123488 :     Set::Matrix DW(const Set::Matrix& a_F) const 
      41              :     {
      42              : #if AMREX_SPACEDIM==2
      43       120228 :         Eigen::Matrix3d F = Eigen::Matrix3d::Identity();
      44       120228 :         F(0, 0) = a_F(0, 0);
      45       120228 :         F(0, 1) = a_F(0, 1);
      46       120228 :         F(1, 0) = a_F(1, 0);
      47       120228 :         F(1, 1) = a_F(1, 1);
      48              : #elif AMREX_SPACEDIM==3
      49         3260 :         Eigen::Matrix3d F = a_F;
      50              : #endif
      51              : 
      52       123488 :         Set::Scalar J = F.determinant();
      53       123488 :         Set::Scalar J23 = std::pow(fabs(J), 2. / 3.);
      54       123488 :         Eigen::Matrix3d FinvT = F.inverse().transpose();
      55              : 
      56       123488 :         Eigen::Matrix3d dw = Eigen::Matrix3d::Zero();
      57              : 
      58       123488 :         dw += mu * (F / J23 - (F * F.transpose()).trace() * FinvT / (3. * J23));
      59       123488 :         dw += kappa * (J - 1) * J * FinvT;
      60              : 
      61              : #if AMREX_SPACEDIM==2
      62       120228 :         Set::Matrix r_dw;
      63       120228 :         r_dw(0, 0) = dw(0, 0);
      64       120228 :         r_dw(0, 1) = dw(0, 1);
      65       120228 :         r_dw(1, 0) = dw(1, 0);
      66       120228 :         r_dw(1, 1) = dw(1, 1);
      67       240456 :         return r_dw;
      68              : #elif AMREX_SPACEDIM==3
      69         6520 :         return dw;
      70              : #endif
      71              :     }
      72        71074 :     Set::Matrix4<AMREX_SPACEDIM, Set::Sym::Major> DDW(const Set::Matrix& a_F) const 
      73              :     {
      74              : #if AMREX_SPACEDIM==2
      75        71054 :         Eigen::Matrix3d F = Eigen::Matrix3d::Identity();
      76        71054 :         F(0, 0) = a_F(0, 0);
      77        71054 :         F(0, 1) = a_F(0, 1);
      78        71054 :         F(1, 0) = a_F(1, 0);
      79        71054 :         F(1, 1) = a_F(1, 1);
      80              : #elif AMREX_SPACEDIM==3
      81           20 :         Eigen::Matrix3d F = a_F;
      82              : #endif
      83              : 
      84        71074 :         Set::Matrix4<3, Set::Sym::Major> ddw;
      85        71074 :         Set::Scalar J = F.determinant();
      86        71074 :         Set::Scalar J23 = std::pow(fabs(J), 2. / 3.);
      87        71074 :         Eigen::Matrix3d FinvT = F.inverse().transpose();
      88       284296 :         for (int i = 0; i < 3; i++)
      89       852888 :             for (int j = 0; j < 3; j++)
      90      2558664 :                 for (int k = 0; k < 3; k++)
      91      7675992 :                     for (int l = 0; l < 3; l++)
      92              :                     {
      93      5756994 :                         ddw(i, j, k, l) = 0.0;
      94              : 
      95      5756994 :                         Set::Scalar t1 = 0.0, t2 = 0.0;
      96              : 
      97      5756994 :                         if (i == k && j == l) t1 += 1.0;
      98      5756994 :                         t1 -= (2. / 3.) * F(i, j) * FinvT(k, l);
      99      5756994 :                         t1 -= (2. / 3.) * FinvT(i, j) * F(k, l);
     100      5756994 :                         t1 += (2. / 9.) * (F * F.transpose()).trace() * FinvT(i, j) * FinvT(k, l);
     101      5756994 :                         t1 += (1. / 3.) * (F * F.transpose()).trace() * FinvT(i, l) * FinvT(k, j);
     102              : 
     103      5756994 :                         t2 += (2. * J - 1.) * FinvT(i, j) * FinvT(k, l);
     104      5756994 :                         t2 += (1. - J) * FinvT(i, l) * FinvT(k, j);
     105              : 
     106     11513988 :                         ddw(i, j, k, l) = (mu / J23) * t1 + kappa * J * t2;
     107              :                     }
     108              : #if AMREX_SPACEDIM==2
     109        71054 :         Set::Matrix4<2, Set::Sym::Major> r_ddw;
     110       213162 :         for (int i = 0; i < 2; i++)
     111       426324 :             for (int j = 0; j < 2; j++)
     112       852648 :                 for (int k = 0; k < 2; k++)
     113      1705296 :                     for (int l = 0; l < 2; l++)
     114      2273728 :                         r_ddw(i, j, k, l) = ddw(i, j, k, l);
     115       142108 :         return r_ddw;
     116              : #elif AMREX_SPACEDIM==3
     117           40 :         return ddw;
     118              : #endif
     119              :     }
     120              :     void Print(std::ostream& out) const 
     121              :     {
     122              :         out << "mu = " << mu << " kappa = " << kappa;
     123              :     }
     124              : 
     125              : public:
     126              :     Set::Scalar mu = NAN, kappa = NAN;
     127              :     static constexpr KinematicVariable kinvar = KinematicVariable::F;
     128              : 
     129              : public:
     130         8747 :     static NeoHookean Zero()
     131              :     {
     132         8747 :         NeoHookean ret;
     133         8747 :         ret.mu = 0.0;
     134         8747 :         ret.kappa = 0.0;
     135         8747 :         return ret;
     136              :     }
     137          124 :     static NeoHookean Random()
     138              :     {
     139          124 :         NeoHookean ret;
     140          124 :         ret.mu = Util::Random();
     141          124 :         ret.kappa = Util::Random();
     142          124 :         return ret;
     143              :     }
     144            4 :     static void Parse(NeoHookean& value, IO::ParmParse& pp)
     145              :     {
     146              : 
     147           24 :         std::pair<std::string, Set::Scalar> moduli[2];
     148              : 
     149           16 :         pp.forbid("lame","Use 'lambda' instead for lame constant");
     150           16 :         pp.forbid("shear","Use 'mu' instead for shear modulus");
     151           12 :         pp.forbid("bulk","Use 'K' instead for bulk modulus");
     152              : 
     153              :         // Lame constant \(\lambda\),
     154              :         // shear modulus \(\mu\), Young's modulus \(E\), Poisson's ratio \(\nu\),
     155              :         // bulk modulus \(K\).
     156              :         // You can currently specify (mu and kappa), (lambda and mu), or (E and nu).
     157              :         // std::vector{Unit::Pressure, Unit::Pressure, Unit::Pressure, Unit::Less, Unit::Pressure};
     158           16 :         pp.query_exactly<2>({"lambda","mu","E","nu","kappa"}, moduli, std::vector<Unit>{Unit::Pressure(), Unit::Pressure(), Unit::Pressure(), Unit::Less(), Unit::Pressure()});
     159              : 
     160              : 
     161            4 :         if (moduli[0].first == "mu" && moduli[1].first == "kappa")
     162              :         {
     163            4 :             value.mu = moduli[0].second;
     164            4 :             value.kappa =  moduli[1].second;
     165              :         }
     166            0 :         else if (moduli[0].first == "lambda" && moduli[1].first == "mu")
     167              :         {
     168            0 :             Set::Scalar lambda = moduli[0].second;
     169            0 :             value.mu = moduli[1].second;
     170            0 :             value.kappa = lambda + (2.0 * value.mu) / 3.0;
     171              :         }
     172            0 :         else if (pp.contains("E") && pp.contains("nu")) {
     173            0 :             Set::Scalar E = moduli[0].second;
     174            0 :             Set::Scalar nu = moduli[1].second;
     175            0 :             value.kappa = E / (3.0 - 6.0 * nu);
     176            0 :             value.mu = E / (2.0 + 2.0 * nu);
     177              :         }
     178              :         else
     179              :         {
     180            0 :             Util::Exception(INFO,"Haven't implemented",moduli[0].first," and ",moduli[1].first," yet (sorry!)");
     181              :         }
     182           16 :     }
     183              : 
     184              : #define OP_CLASS NeoHookean
     185              : #define OP_VARS X(kappa) X(mu)
     186              : #include "Model/Solid/InClassOperators.H"
     187              : };
     188              : #include "Model/Solid/ExtClassOperators.H"
     189              : 
     190              : }
     191              : }
     192              : }
     193              : 
     194              : #endif
        

Generated by: LCOV version 2.0-1