Line data Source code
1 : // 2 : // This model implements an isotropic linear elastic material. 3 : // See `this link <https://en.wikipedia.org/wiki/Linear_elasticity#(An)isotropic_(in)homogeneous_media>`_ 4 : // for more information about the theory. 5 : // 6 : // Free energy for a linear material is defined as 7 : // 8 : // .. math:: 9 : // 10 : // W(\nabla\mathbf{u}) = 11 : // \frac{1}{2}\nabla\mathbf{u}\cdot\mathbb{C}\,\nabla\mathbf{u} 12 : // 13 : // For an isotropic material, stress and strain are related through 14 : // 15 : // .. math:: 16 : // 17 : // \mathbb{C}_{ijkl} = \lambda \delta_{ij}\varepsilon_{kk} + 2\mu\varepsilon_{ij} 18 : // 19 : // where :math:`\lambda` and :math:`\mu` are the Lame constant and shear modulus, respectively. 20 : // Users can specify these either through (:code:`lame` and :code:`shear`) 21 : // OR (:code:`lambda` and :code:`mu`) OR (:code:`E` and :code:`nu`). 22 : // 23 : // Class methods: 24 : // 25 : // #. :code:`Isotropic()`: 26 : // Basic constructor. Does nothing, and leaves all values initiated as NAN. 27 : // #. :code:`Isotropic(Solid<Set::Sym::Isotropic> base)` 28 : // Basic constructor. Does nothing gut allows for inheritance. 29 : // #. :code:`Isotropic(Set::Scalar a_mu, Set::Scalar a_lambda)` 30 : // BAD old-fashioned constructor. Do not use! 31 : // #. :code:`~Isotropic()` 32 : // Simple destructor. Don't need to change it. 33 : // #. :code:`void Define(Set::Scalar a_mu, Set::Scalar a_lambda)` 34 : // BAD old-fashioned way of doing things. Use :code:`Parse` instead. 35 : // #. :code:`Set::Scalar W(const Set::Matrix & gradu) const override` 36 : // Returns elastic free energy density 37 : // #. :code:`Set::Matrix DW(const Set::Matrix & gradu) const override` 38 : // Returns first derivative of free energy, the stress tensor 39 : // #. :code:`Set::Matrix4<...> DDW(const Set::Matrix & ) const override` 40 : // Returns second derivative of free energy, the modulus tensor 41 : // #. :code:`virtual void Print(std::ostream &out) const override` 42 : // Prints the modulus tensor object to output stream (usually the terminal) 43 : // #. :code:`static Isotropic Random()` 44 : // Static method that generates a random yet acceptable model. 45 : // #. :code:`static Isotropic Zero()` 46 : // Static method that generates a "zero" element (so that there is no effect under addition) 47 : // #. :code:`static void Parse(Isotropic & value, IO::ParmParse & pp)` 48 : // Parser where all the IO occurs 49 : // 50 : // 51 : 52 : #ifndef MODEL_SOLID_LINEAR_ISOTROPIC_H_ 53 : #define MODEL_SOLID_LINEAR_ISOTROPIC_H_ 54 : 55 : #include "Model/Solid/Solid.H" 56 : #include "IO/ParmParse.H" 57 : 58 : namespace Model 59 : { 60 : namespace Solid 61 : { 62 : namespace Linear 63 : { 64 : class Isotropic : public Solid<Set::Sym::Isotropic> 65 : { 66 : public: 67 : 68 230163 : Isotropic() {}; 69 : Isotropic(Solid<Set::Sym::Isotropic> base) : Solid<Set::Sym::Isotropic>(base) {}; 70 0 : Isotropic(Set::Scalar a_mu, Set::Scalar a_lambda) 71 0 : { 72 0 : Define(a_mu,a_lambda); 73 0 : }; 74 320406 : virtual ~Isotropic() {}; 75 : 76 49906 : void Define(Set::Scalar a_mu, Set::Scalar a_lambda) 77 : { 78 49906 : ddw = Set::Matrix4<AMREX_SPACEDIM,Set::Sym::Isotropic>(a_lambda,a_mu); 79 49906 : } 80 : 81 260 : Set::Scalar W(const Set::Matrix & gradu) const override 82 : { 83 520 : return ( 0.5 * gradu.transpose() * (ddw*gradu) ).trace(); 84 : } 85 134932 : Set::Matrix DW(const Set::Matrix & gradu) const override 86 : { 87 269864 : return ddw*gradu; 88 : } 89 66506 : Set::Matrix4<AMREX_SPACEDIM,Set::Sym::Isotropic> DDW(const Set::Matrix & /*gradu*/) const override 90 : { 91 66506 : return ddw; 92 : } 93 7 : virtual void Print(std::ostream &out) const override 94 : { 95 7 : out << ddw; 96 7 : } 97 : 98 : public: 99 : Set::Matrix4<AMREX_SPACEDIM,Set::Sym::Isotropic> ddw; 100 : static const KinematicVariable kinvar = KinematicVariable::gradu; 101 : 102 : public: 103 44 : static Isotropic Random() 104 : { 105 44 : Isotropic ret; 106 44 : ret.Define(Util::Random(),Util::Random()); 107 44 : return ret; 108 : } 109 49855 : static Isotropic Zero() 110 : { 111 49855 : Isotropic ret; 112 49855 : ret.Define(0.,0.); 113 49855 : return ret; 114 : } 115 7 : static void Parse(Isotropic & value, IO::ParmParse & pp) 116 : { 117 : Set::Scalar mu, lambda; 118 7 : bool planestress = false; 119 : 120 : // Whether or not to use the 121 : // `plane stress <https://en.wikipedia.org/wiki/Plane_stress>`_ 122 : // approximation. 123 7 : pp_query("planestress",planestress); 124 7 : if (pp.contains("lame") && pp.contains("shear")) 125 : { 126 0 : pp_query("lame",lambda); // Lame parameter 127 0 : pp_query("shear",mu); // Shear modulus (redundant with "mu") 128 : } 129 7 : if (pp.contains("lambda") && pp.contains("mu")) 130 : { 131 0 : pp_query("lambda",lambda); // Lame parameter 132 0 : pp_query("mu",mu); // Shear modulus (redundant with "shear") 133 : } 134 7 : else if (pp.contains("E") && pp.contains("nu")) 135 : { 136 : Set::Scalar E, nu; 137 7 : pp_query("E",E); // Elastic modulus 138 7 : pp_query("nu",nu); // Poisson's ratio 139 7 : lambda = E * nu / (1.0 + nu) / (1.0 - 2.0*nu); 140 7 : mu = E / 2.0 / (1.0 + nu); 141 : } 142 0 : else Util::Abort(INFO,"Invalid elastic constants specified"); 143 : 144 6 : if (AMREX_SPACEDIM==2 && planestress) 145 5 : value.Define(mu,lambda*(1.0 - lambda/(2.*mu + lambda))); 146 : else 147 2 : value.Define(mu,lambda); 148 7 : Util::Message(INFO,value); 149 7 : } 150 : 151 : #define OP_CLASS Isotropic 152 : #define OP_VARS X(ddw) 153 : #include "Model/Solid/InClassOperators.H" 154 : }; 155 : #include "Model/Solid/ExtClassOperators.H" 156 : 157 : 158 : 159 : } 160 : } 161 : } 162 : 163 : #endif