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

Generated by: LCOV version 2.0-1