LCOV - code coverage report
Current view: top level - src/Set - Matrix4_Isotropic.H (source / functions) Coverage Total Hit
Test: coverage_merged.info Lines: 98.5 % 66 65
Test Date: 2026-01-21 04:31:22 Functions: 94.4 % 18 17

            Line data    Source code
       1              : //
       2              : // The isotropic tensor is defined to be
       3              : //
       4              : // .. math::
       5              : // 
       6              : //     C_{ijkl} = \mu(d_{il}d_{jk} + d_{ik}d_{jl}) + \lambda d_{ij} d_{kl}
       7              : // 
       8              : // The inverse ("compliance") tensor is 
       9              : // 
      10              : // .. math::
      11              : //
      12              : //     S_{ijkl} = ((1+\nu)/2E)(d_{il}d_{jl} + d_{ik}d_{jl}) - (\nu/E)d_{ij}d_{kl}
      13              : //
      14              : // Replacing E, nu with Lame constants gives:
      15              : // 
      16              : // .. math::
      17              : //
      18              : //     S_{ijkl} = (1/(4 \mu))(d_{il}d_{jl} + d_{ik}d_{jl}) + (\lambda/(2*\mu*(3\lambda+2\mu))) * d_{ij} * d_{kl}
      19              : //
      20              : // For reference: http://solidmechanics.org/text/Chapter3_2/Chapter3_2.htm
      21              : //                https://en.wikipedia.org/wiki/Lam%C3%A9_parameters
      22              : //
      23              : 
      24              : #ifndef SET_MATRIX4_ISOTROPIC_H
      25              : #define SET_MATRIX4_ISOTROPIC_H
      26              : 
      27              : #include "AMReX_Config.H"
      28              : #include "Util/Util.H"
      29              : #include "Set/Set.H"
      30              : #include "Set/Base.H"
      31              : #include "Matrix3.H"
      32              : #include "Matrix4.H"
      33              : 
      34              : namespace Set
      35              : {
      36              : template<>
      37              : class Matrix4<AMREX_SPACEDIM,Sym::Isotropic>
      38              : {
      39              :     Set::Scalar lambda=NAN, mu=NAN;
      40              : public:
      41     52222959 :     AMREX_GPU_HOST_DEVICE Matrix4() {};
      42        88301 :     AMREX_GPU_HOST_DEVICE Matrix4(Set::Scalar a_lambda, Set::Scalar a_mu) : lambda(a_lambda), mu(a_mu) {};
      43              : 
      44              :     /// Note: for the Isotropic Matrix4 this routine works for **retrieval only**!
      45              :     /// If you try to assign a value using this with, say
      46              :     ///
      47              :     ///     isotropicmatrix4(i,j,k,l) = 8.0
      48              :     ///
      49              :     /// you will get a `lvalue required as left operand of assignment` compile error.
      50              :     /// You should probably consider using a lower symmetry operator.
      51              :     AMREX_FORCE_INLINE
      52              :     Scalar operator () (const int i, const int j, const int k, const int l) const
      53              :     {
      54         3880 :         Set::Scalar ret = 0.0;
      55         3880 :         if (i==k && j==l) ret += mu;
      56         3880 :         if (i==l && j==k) ret += mu;
      57         3880 :         if (i==j && k==l) ret += lambda;
      58         3880 :         return ret;
      59              :     }
      60            2 :     void Randomize()
      61              :     {
      62            2 :         lambda = Util::Random();
      63            2 :         mu = Util::Random();
      64            2 :     }
      65            2 :     static Matrix4<AMREX_SPACEDIM,Sym::Isotropic> Random()
      66              :     {
      67            2 :         Matrix4<AMREX_SPACEDIM,Sym::Isotropic> ret;
      68            2 :         ret.Randomize();
      69            2 :         return ret;
      70              :     }
      71              :     void Print (std::ostream& os )
      72              :     {
      73              :         os << "lambda = " << lambda << " mu = " << mu;
      74              :     }
      75      1071238 :     Set::Scalar Lambda () const
      76              :     {
      77      1071238 :         return lambda;
      78              :     }
      79      1071238 :     Set::Scalar Mu () const
      80              :     {
      81      1071238 :         return mu;
      82              :     }
      83              :     Set::Scalar Youngs() const
      84              :     {
      85              :         return mu * ( 3.0*lambda + 2.0*mu ) / (lambda + mu);
      86              :     }
      87              :     Set::Scalar Nu() const
      88              :     {
      89              :         return 0.5 * lambda / (lambda + mu);
      90              :     }
      91          562 :     static Matrix4<AMREX_SPACEDIM,Sym::Isotropic> Zero()
      92              :     {
      93          562 :         Matrix4<AMREX_SPACEDIM,Sym::Isotropic> zero;
      94          562 :         zero.lambda = 0.0;
      95          562 :         zero.mu = 0.0;
      96          562 :         return zero;
      97              :     }
      98              : 
      99              : 
     100           79 :     Matrix4<AMREX_SPACEDIM,Sym::Isotropic> Inverse() const
     101              :     {
     102           79 :         Matrix4<AMREX_SPACEDIM,Sym::Isotropic> inv;
     103           79 :         inv.mu = 1./4./mu;
     104           79 :         inv.lambda = lambda / (2*mu*(3*lambda + 2*mu));
     105           79 :         return inv;
     106              :     }
     107              :     friend Set::Matrix operator * (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Set::Matrix  &b);
     108              :     friend Set::Vector operator * (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Set::Matrix3 &b);
     109              :     friend Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator - (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &b);
     110              :     friend Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator * (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Set::Scalar &b);
     111              :     friend Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator * (const Set::Scalar &b, const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a);
     112              :     friend Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator / (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Set::Scalar &b);
     113              :     friend Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator * (const Set::Scalar &b, const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a);
     114              :     friend bool operator == (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a,const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &b);
     115              :     friend Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator + (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a,const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &b);
     116              : 
     117              :     //AMREX_GPU_HOST_DEVICE void operator =  (Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a) {lambda =  a.lambda; mu =  a.mu;}
     118       126627 :     AMREX_GPU_HOST_DEVICE void operator += (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a) {lambda += a.lambda; mu += a.mu;}
     119              :     AMREX_GPU_HOST_DEVICE void operator -= (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a) {lambda -= a.lambda; mu -= a.mu;}
     120              :     AMREX_GPU_HOST_DEVICE void operator *= (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a) {lambda *= a.lambda; mu *= a.mu;}
     121              :     AMREX_GPU_HOST_DEVICE void operator /= (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a) {lambda /= a.lambda; mu /= a.mu;}
     122              :     AMREX_GPU_HOST_DEVICE void operator *= (const Set::Scalar &alpha) {lambda *= alpha; mu *= alpha;}
     123              :     AMREX_GPU_HOST_DEVICE void operator /= (const Set::Scalar &alpha) {lambda /= alpha; mu /= alpha;}
     124              :     
     125              :     Set::Scalar Norm()
     126              :     {
     127              :         return std::sqrt(lambda*lambda + mu*mu);
     128              :     }
     129              : 
     130              :     bool contains_nan() const
     131              :     {
     132              :         if (std::isnan(lambda)) return true;
     133              :         if (std::isnan(mu)) return true;
     134              :         return false;
     135              :     }
     136              : };
     137              : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE 
     138              : Set::Matrix operator * (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Set::Matrix &b)
     139              : {
     140     50024085 :     Set::Matrix ret;
     141              :         
     142              :     #if   AMREX_SPACEDIM == 2
     143     35049001 :     ret(0,0) = (a.lambda + 2.*a.mu) * b(0,0) +       a.lambda      *b(1,1);
     144     35049001 :     ret(1,1) =        a.lambda      * b(0,0) + (a.lambda + 2.*a.mu)*b(1,1);
     145     35049001 :     ret(0,1) = a.mu*(b(0,1) + b(1,0)); ret(1,0) = ret(0,1);
     146              :     
     147              :     #elif AMREX_SPACEDIM == 3
     148     14975084 :     ret(0,0) = (a.lambda + 2.*a.mu) * b(0,0) +       a.lambda      *b(1,1) +       a.lambda      *b(2,2);
     149     14975084 :     ret(1,1) =        a.lambda      * b(0,0) + (a.lambda + 2.*a.mu)*b(1,1) +       a.lambda      *b(2,2);
     150     14975084 :     ret(2,2) =        a.lambda      * b(0,0) +       a.lambda      *b(1,1) + (a.lambda + 2.*a.mu)*b(2,2);
     151     14975084 :     ret(1,2) = a.mu*(b(1,2) + b(2,1)); ret(2,1) = ret(1,2);
     152     14975084 :     ret(2,0) = a.mu*(b(2,0) + b(0,2)); ret(0,2) = ret(2,0);
     153     14975084 :     ret(0,1) = a.mu*(b(0,1) + b(1,0)); ret(1,0) = ret(0,1);
     154              :     
     155              :     #endif         
     156     50024085 :     return ret;
     157              : }
     158              : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE 
     159              : Set::Matrix operator * (const Set::Matrix &b, const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a)
     160              : {return a*b;}
     161              : 
     162              : 
     163              : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE 
     164              : Set::Vector operator * (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Set::Matrix3 &b)
     165              : {
     166     11898561 :     Set::Vector ret = Set::Vector::Zero();
     167              :     
     168     37312383 :     for (int i = 0; i < AMREX_SPACEDIM; i++)
     169     81091566 :         for (int j=0; j < AMREX_SPACEDIM; j++)
     170    222710976 :             ret(i) += a.mu*(b(i,j,j) + b(j,i,j)) + a.lambda*b(j,j,i);
     171              : 
     172     11898561 :     return ret;
     173              : }
     174              : 
     175              : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE 
     176              : Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator * (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Set::Scalar &b)
     177              : {
     178     25224168 :     Matrix4<AMREX_SPACEDIM,Sym::Isotropic> ret;// = Set::Vector::Zero();
     179     25224168 :     ret.mu = a.mu * b;
     180     25224168 :     ret.lambda = a.lambda * b;
     181     25224168 :     return ret;
     182              : }
     183              : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE 
     184              : Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator / (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Set::Scalar &b)
     185              : {
     186     25042164 :     Matrix4<AMREX_SPACEDIM,Sym::Isotropic> ret;// = Set::Vector::Zero();
     187     25042164 :     ret.mu = a.mu / b;
     188     25042164 :     ret.lambda = a.lambda / b;
     189     25042164 :     return ret;
     190              : }
     191              : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE 
     192              : Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator * (const Set::Scalar &b, const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a)
     193              : {
     194            0 :     return a*b;
     195              : }
     196              : 
     197              : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE 
     198              : bool operator == (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &b)
     199              : {
     200           20 :     if (a.mu != b.mu) return false;
     201           20 :     if (a.lambda != b.lambda) return false;
     202           20 :     return true;
     203              : }
     204              : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE 
     205              : Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator + (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &b)
     206              : {
     207        70959 :     Matrix4<AMREX_SPACEDIM,Sym::Isotropic> ret;// = Set::Vector::Zero();
     208        70959 :     ret.mu = a.mu + b.mu;
     209        70959 :     ret.lambda = a.lambda + b.lambda;
     210        70959 :     return ret;
     211              : }
     212              : 
     213              : AMREX_FORCE_INLINE AMREX_GPU_HOST_DEVICE 
     214              : Matrix4<AMREX_SPACEDIM,Sym::Isotropic> operator - (const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &a, 
     215              :                                                     const Matrix4<AMREX_SPACEDIM,Sym::Isotropic> &b)
     216              : {
     217     25043326 :     Matrix4<AMREX_SPACEDIM,Sym::Isotropic> ret = a;
     218     25043326 :     ret.mu -= b.mu;
     219     25043326 :     ret.lambda -= b.lambda;
     220     25043326 :     return ret;
     221              : }
     222              : 
     223              : 
     224              : }
     225              : #endif
        

Generated by: LCOV version 2.0-1