LCOV - code coverage report
Current view: top level - src/Model/Solid/Affine - Isotropic.H (source / functions) Coverage Total Hit
Test: coverage_merged.info Lines: 82.7 % 110 91
Test Date: 2026-01-21 04:31:22 Functions: 100.0 % 16 16

            Line data    Source code
       1              : #ifndef MODEL_SOLID_AFFINE_ISOTROPIC_H_
       2              : #define MODEL_SOLID_AFFINE_ISOTROPIC_H_
       3              : 
       4              : #include "AMReX.H"
       5              : #include "IO/ParmParse.H"
       6              : #include "Model/Solid/Affine/Affine.H"
       7              : 
       8              : namespace Model
       9              : {
      10              : namespace Solid
      11              : {
      12              : namespace Affine
      13              : {
      14              : class Isotropic : public Affine<Set::Sym::Isotropic>
      15              : {
      16              : public:
      17              : 
      18       222061 :     Isotropic()  = default;
      19              :     ~Isotropic() = default;
      20              :     
      21              :     Isotropic(Affine<Set::Sym::Isotropic> base) : Affine<Set::Sym::Isotropic>(base) {};
      22              :     Isotropic(Set::Scalar a_mu, Set::Scalar a_lambda, Set::Matrix a_F0 = Set::Matrix::Zero())
      23              :     {
      24              :         Define(a_mu, a_lambda, a_F0);
      25              :     };
      26              : 
      27        38397 :     void Define(Set::Scalar a_mu, Set::Scalar a_lambda, Set::Matrix a_F0)
      28              :     {
      29        38397 :         F0 = a_F0;
      30        38397 :         ddw = Set::Matrix4<AMREX_SPACEDIM, Set::Sym::Isotropic>(a_lambda, a_mu);
      31        38397 :     }
      32              : 
      33              :     void Define(Set::Scalar a_mu, Set::Scalar a_lambda)
      34              :     {
      35              :         ddw = Set::Matrix4<AMREX_SPACEDIM, Set::Sym::Isotropic>(a_lambda, a_mu);
      36              :     }
      37              : 
      38          260 :     Set::Scalar W(const Set::Matrix& F) const 
      39              :     {
      40          520 :         return 0.5 * ((F - F0).transpose() * (ddw * ((F - F0)))).trace();
      41              :     }
      42       111902 :     Set::Matrix DW(const Set::Matrix& F) const 
      43              :     {
      44       223804 :         return ddw * (F - F0);
      45              :     }
      46        51294 :     Set::Matrix4<AMREX_SPACEDIM, Set::Sym::Isotropic> DDW(const Set::Matrix& /*F*/) const 
      47              :     {
      48        51294 :         return ddw;
      49              :     }
      50              :     void Print(std::ostream& out) const 
      51              :     {
      52              :         out << "lambda=" << ddw.Lambda() << ", mu=" << ddw.Mu() << ", F0=\n" << F0;
      53              :     }
      54              :     bool ContainsNan() 
      55              :     {
      56              :         if (F0.hasNaN()) return true;
      57              :         if (ddw.contains_nan()) return true;
      58              :         else return false;
      59              :     }
      60              : public:
      61        38349 :     static Isotropic Zero()
      62              :     {
      63        38349 :         Isotropic ret;
      64        38349 :         Set::Scalar mu = 0.0;
      65        38349 :         Set::Scalar lambda = 0.0;
      66        38349 :         Set::Matrix F0 = Set::Matrix::Zero();
      67        38349 :         ret.Define(mu, lambda, F0);
      68        76698 :         return ret;
      69              :     }
      70           42 :     static Isotropic Random()
      71              :     {
      72           42 :         Isotropic ret;
      73           42 :         Set::Scalar mu = Util::Random();
      74           42 :         Set::Scalar lambda = Util::Random();
      75           42 :         Set::Matrix F0 = Set::Matrix::Random();
      76           42 :         ret.Define(mu, lambda, F0);
      77           84 :         return ret;
      78              :     }
      79            6 :     static void Parse(Isotropic& value, IO::ParmParse& pp)
      80              :     {
      81            6 :         Set::Scalar mu = NAN, lambda = NAN;
      82            6 :         Set::Matrix F0 = Set::Matrix::Zero();
      83              : 
      84           30 :         std::pair<std::string, Set::Scalar> moduli[2];
      85              : 
      86           24 :         pp.forbid("lame","Use 'lambda' instead for lame constant");
      87           24 :         pp.forbid("shear","Use 'mu' instead for shear modulus");
      88           18 :         pp.forbid("bulk","Use 'kappa' instead for bulk modulus");
      89              : 
      90              :         // Specify exactly two of: lame constant \(\lambda\),
      91              :         // shear modulus \(\mu\), Young's modulus \(E\), Poisson's ratio \(\nu\),
      92              :         // bulk modulus \(\kappa\).
      93              :         // \(\mu\) and \(\lambda\) are how the final values are stored.
      94           18 :         pp.query_exactly<2>({"lambda","mu","E","nu","kappa"}, moduli);
      95              : 
      96            6 :         if      (moduli[0].first == "lambda" && moduli[1].first == "mu")
      97              :         {
      98            0 :             lambda = moduli[0].second;
      99            0 :             mu = moduli[1].second;
     100              :         }
     101            6 :         else if (moduli[0].first == "lambda" && moduli[1].first == "E")
     102              :         {
     103            0 :             lambda = moduli[0].second;
     104            0 :             Set::Scalar E = moduli[1].second;
     105            0 :             mu = (E - 3.0 * lambda + sqrt(E * E + 9.0 * lambda * lambda + 2.0 * E * lambda)) / 4.0;
     106              :         }
     107            6 :         else if (moduli[0].first == "lambda" && moduli[1].first == "nu")
     108              :         {
     109            0 :             lambda = moduli[0].second;
     110            0 :             Set::Scalar nu = moduli[1].second;
     111            0 :             mu = lambda * (1.0 - 2.0 * nu) / 2.0 / nu;
     112              :         }
     113            6 :         else if (moduli[0].first == "mu" && moduli[1].first == "E")
     114              :         {
     115            0 :             mu = moduli[0].second;
     116            0 :             Set::Scalar E = moduli[1].second;
     117            0 :             lambda = mu * (E - 2.0 * mu) / (3.0 * mu - E);
     118              :         }
     119            6 :         else if (moduli[0].first == "mu" && moduli[1].first == "nu")
     120              :         {
     121            0 :             mu = moduli[0].second;
     122            0 :             Set::Scalar nu = moduli[1].second;
     123            0 :             lambda = 2.0 * mu * nu / (1.0 - 2.0 * nu);
     124              :         }
     125            6 :         else if (moduli[0].first == "mu" && moduli[1].first == "K")
     126              :         {
     127            0 :             mu = moduli[0].second;
     128            0 :             Set::Scalar K = moduli[1].second;
     129            0 :             lambda = K - (2.0 * mu / 3.0);
     130              :         }
     131            6 :         else if (moduli[0].first == "E" && moduli[1].first == "nu")
     132              :         {
     133            6 :             Set::Scalar E = moduli[0].second, nu = moduli[1].second;
     134            6 :             lambda = E * nu / (1.0 + nu) / (1.0 - 2.0 * nu);
     135            6 :             mu = E / 2.0 / (1.0 + nu);
     136              :         }
     137              :         else
     138              :         {
     139            0 :             Util::Exception(INFO,"Haven't implemented ",moduli[0].first," and ",moduli[1].first," (sorry!)");
     140              :         }
     141              : 
     142           12 :         if (pp.contains("F0"))
     143              :         {
     144           15 :             pp_queryarr("F0", F0); // Eigendeformation gradient
     145              :         }
     146            6 :         value.Define(mu, lambda, F0);
     147           24 :     }
     148              : #define OP_CLASS Isotropic
     149              : #define OP_VARS  X(ddw) X(F0)
     150              : #include "Model/Solid/InClassOperators.H"
     151              : };
     152              : #include "Model/Solid/ExtClassOperators.H"
     153              : }
     154              : }
     155              : }
     156              : 
     157              : template<>
     158              : ALAMO_SINGLE_DEFINITION
     159          226 : int Set::Field<Model::Solid::Affine::Isotropic>::NComp() const
     160              : {
     161          226 :     return AMREX_SPACEDIM * AMREX_SPACEDIM + 2;
     162              : }
     163              : template<>
     164              : ALAMO_SINGLE_DEFINITION
     165          145 : std::string Set::Field<Model::Solid::Affine::Isotropic>::Name(int i) const
     166              : {
     167          145 :     if (i == 0) return name + "_lambda";
     168          130 :     if (i == 1) return name + "_mu";
     169              : #if AMREX_SPACEDIM==2
     170           16 :     if (i == 2) return name + "_F0_xx";
     171           12 :     if (i == 3) return name + "_F0_xy";
     172            8 :     if (i == 4) return name + "_F0_yx";
     173            4 :     if (i == 5) return name + "_F0_yy";
     174              : #elif AMREX_SPACEDIM==3
     175           99 :     if (i == 2) return name + "_F0_xx";
     176           88 :     if (i == 3) return name + "_F0_xy";
     177           77 :     if (i == 4) return name + "_F0_xy";
     178           66 :     if (i == 5) return name + "_F0_yx";
     179           55 :     if (i == 6) return name + "_F0_yy";
     180           44 :     if (i == 7) return name + "_F0_yz";
     181           33 :     if (i == 8) return name + "_F0_zy";
     182           22 :     if (i == 9) return name + "_F0_zx";
     183           11 :     if (i == 10) return name + "_F0_zz";
     184              : #endif
     185            0 :     return name;
     186              : }
     187              : template<>
     188              : ALAMO_SINGLE_DEFINITION
     189           51 : void Set::Field<Model::Solid::Affine::Isotropic>::Copy(int a_lev, amrex::MultiFab& a_dst, int a_dstcomp, int a_nghost) const
     190              : {
     191          334 :     for (amrex::MFIter mfi(a_dst, amrex::TilingIfNotGPU()); mfi.isValid(); ++mfi)
     192              :     {
     193          283 :         const amrex::Box& bx = mfi.growntilebox(amrex::IntVect(a_nghost));
     194          283 :         if (bx.ok())
     195              :         {
     196          283 :             amrex::Array4<const Model::Solid::Affine::Isotropic> const& src = ((*this)[a_lev])->array(mfi);
     197          283 :             amrex::Array4<Set::Scalar> const& dst = a_dst.array(mfi);
     198         1470 :             for (int n = 0; n < AMREX_SPACEDIM * AMREX_SPACEDIM; n++)
     199              :             {
     200         1187 :                 amrex::ParallelFor(bx, [=] AMREX_GPU_DEVICE(int i, int j, int k) {
     201       901422 :                     dst(i, j, k, a_dstcomp + 0) = src(i, j, k).ddw.Lambda();
     202       901422 :                     dst(i, j, k, a_dstcomp + 1) = src(i, j, k).ddw.Mu();
     203              : #if AMREX_SPACEDIM==2
     204       876672 :                     dst(i, j, k, a_dstcomp + 2) = src(i, j, k).F0(0, 0);
     205       876672 :                     dst(i, j, k, a_dstcomp + 3) = src(i, j, k).F0(0, 1);
     206       876672 :                     dst(i, j, k, a_dstcomp + 4) = src(i, j, k).F0(1, 0);
     207       876672 :                     dst(i, j, k, a_dstcomp + 5) = src(i, j, k).F0(1, 1);
     208              : #elif AMREX_SPACEDIM==3
     209        24750 :                     dst(i, j, k, a_dstcomp + 2) = src(i, j, k).F0(0, 0);
     210        24750 :                     dst(i, j, k, a_dstcomp + 3) = src(i, j, k).F0(0, 1);
     211        24750 :                     dst(i, j, k, a_dstcomp + 4) = src(i, j, k).F0(0, 2);
     212        24750 :                     dst(i, j, k, a_dstcomp + 5) = src(i, j, k).F0(1, 0);
     213        24750 :                     dst(i, j, k, a_dstcomp + 6) = src(i, j, k).F0(1, 1);
     214        24750 :                     dst(i, j, k, a_dstcomp + 7) = src(i, j, k).F0(1, 2);
     215        24750 :                     dst(i, j, k, a_dstcomp + 8) = src(i, j, k).F0(2, 0);
     216        24750 :                     dst(i, j, k, a_dstcomp + 9) = src(i, j, k).F0(2, 1);
     217        24750 :                     dst(i, j, k, a_dstcomp + 10) = src(i, j, k).F0(2, 2);
     218              : #endif
     219       450711 :                 });
     220              :             }
     221              :         }
     222           51 :     }
     223           51 : }
     224              : 
     225              : 
     226              : 
     227              : 
     228              : #endif
        

Generated by: LCOV version 2.0-1