1 /*! 2 * \file mfront/include/MFront/LSDYNA/LSDYNATangentOperator.hxx 3 * \brief 4 * \author Thomas Helfer 5 * \brief 07 févr. 2013 6 * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights 7 * reserved. 8 * This project is publicly released under either the GNU GPL Licence 9 * or the CECILL-A licence. A copy of thoses licences are delivered 10 * with the sources of TFEL. CEA or EDF may also distribute this 11 * project under specific licensing conditions. 12 */ 13 14 #ifndef LIB_MFRONT_LSDYNA_LSDYNATANGENTOPERATOR_HXX 15 #define LIB_MFRONT_LSDYNA_LSDYNATANGENTOPERATOR_HXX 16 17 #include<type_traits> 18 19 #include"TFEL/Math/ST2toST2/ST2toST2View.hxx" 20 #include"TFEL/Math/General/MathConstants.hxx" 21 #include"TFEL/Material/ModellingHypothesis.hxx" 22 #include"TFEL/Material/MechanicalBehaviourTraits.hxx" 23 24 #include"MFront/LSDYNA/LSDYNA.hxx" 25 #include"MFront/LSDYNA/LSDYNATraits.hxx" 26 #include"MFront/LSDYNA/LSDYNAConfig.hxx" 27 28 namespace lsdyna 29 { 30 31 template<LSDYNABehaviourType btype, 32 typename real,unsigned short N> 33 struct LSDYNATangentOperatorType 34 { 35 using type = tfel::math::st2tost2<N,real>; 36 using view_type = tfel::math::ST2toST2View<N,real>; 37 }; 38 39 /*! 40 * \brief an helper structure introduced to normalise the tangent 41 * operator to follow the umat interface 42 */ 43 template<typename real> 44 struct LSDYNATangentOperator 45 { 46 /*! 47 * \brief normalize the tangent operator in 1D 48 * \param[in] Dt : tangent operator 49 */ 50 static void 51 normalize(tfel::math::ST2toST2View<1u,real>&); 52 /*! 53 * \brief normalize the tangent operator in 2D 54 * \param[in] Dt : tangent operator 55 */ 56 static void 57 normalize(tfel::math::ST2toST2View<2u,real>&); 58 /*! 59 * \brief normalize the tangent operator in 3D 60 * \param[in] Dt : tangent operator 61 */ 62 static void 63 normalize(tfel::math::ST2toST2View<3u,real>&); 64 /*! 65 * \brief transpose the tangent operator in 1D 66 * \param[in] Dt : tangent operator 67 */ 68 static void 69 transpose(tfel::math::ST2toST2View<1u,real>&); 70 /*! 71 * \brief transpose the tangent operator in 2D 72 * \param[in] Dt : tangent operator 73 */ 74 static void 75 transpose(tfel::math::ST2toST2View<2u,real>&); 76 /*! 77 * \brief transpose the tangent operator in 3D 78 * \param[in] Dt : tangent operator 79 */ 80 static void 81 transpose(tfel::math::ST2toST2View<3u,real>&); 82 }; // end of struct LSDYNATangentOperator 83 84 /*! 85 * \brief this class extracts and normalise (convert to 86 * lsdyna/fortran conventions) the tangent operator 87 */ 88 template<tfel::material::ModellingHypothesis::Hypothesis H> 89 struct ExtractAndConvertTangentOperator 90 { 91 template<typename Behaviour,typename real> exelsdyna::ExtractAndConvertTangentOperator92 static void exe(const Behaviour& b,real *const DDSDDE){ 93 using namespace tfel::material; 94 typedef MechanicalBehaviourTraits<Behaviour> Traits; 95 using handler = typename std::conditional< 96 Traits::isConsistentTangentOperatorSymmetric, 97 SymmetricConsistentTangentOperatorComputer, 98 GeneralConsistentTangentOperatorComputer 99 >::type; 100 handler::exe(b,DDSDDE); 101 }// end of exe 102 private: 103 struct ConsistentTangentOperatorComputer 104 { 105 template<typename Behaviour,typename real> exelsdyna::ExtractAndConvertTangentOperator::ConsistentTangentOperatorComputer106 static void exe(const Behaviour& bv, 107 real *const DDSDDE) 108 { 109 using tfel::material::ModellingHypothesisToSpaceDimension; 110 const unsigned short N = ModellingHypothesisToSpaceDimension<H>::value; 111 using TangentOperatorType = typename LSDYNATangentOperatorType<LSDYNATraits<Behaviour>::btype,real,N>::type; 112 using TangentOperatorViewType = typename LSDYNATangentOperatorType<LSDYNATraits<Behaviour>::btype,real,N>::view_type; 113 TangentOperatorViewType Dt{DDSDDE}; 114 Dt = static_cast<const TangentOperatorType&>(bv.getTangentOperator()); 115 LSDYNATangentOperator<real>::normalize(Dt); 116 } // end of exe 117 }; 118 struct SymmetricConsistentTangentOperatorComputer 119 { 120 template<typename Behaviour,typename real> exelsdyna::ExtractAndConvertTangentOperator::SymmetricConsistentTangentOperatorComputer121 static void exe(const Behaviour& bv, 122 real *const DDSDDE) 123 { 124 ConsistentTangentOperatorComputer::exe(bv,DDSDDE); 125 } // end of exe 126 }; 127 struct GeneralConsistentTangentOperatorComputer 128 { 129 template<typename Behaviour,typename real> exelsdyna::ExtractAndConvertTangentOperator::GeneralConsistentTangentOperatorComputer130 static void exe(const Behaviour& bv,real *const DDSDDE) 131 { 132 using tfel::material::ModellingHypothesisToSpaceDimension; 133 const unsigned short N = ModellingHypothesisToSpaceDimension<H>::value; 134 using TangentOperatorViewType = typename LSDYNATangentOperatorType<LSDYNATraits<Behaviour>::btype,real,N>::view_type; 135 ConsistentTangentOperatorComputer::exe(bv,DDSDDE); 136 // les conventions fortran.... 137 TangentOperatorViewType Dt{DDSDDE}; 138 LSDYNATangentOperator<real>::transpose(Dt); 139 } // end of exe 140 }; 141 }; // end of struct ExtractAndConvertTangentOperator 142 /*! 143 * \brief partial specialisation of the 144 * ExtractAndConvertTangentOperator for the plane stress modelling 145 * hypothesis 146 */ 147 template<> 148 struct ExtractAndConvertTangentOperator<tfel::material::ModellingHypothesis::PLANESTRESS> 149 { 150 template<typename Behaviour,typename real> exelsdyna::ExtractAndConvertTangentOperator151 static void exe(const Behaviour& b,real *const DDSDDE){ 152 using namespace tfel::material; 153 typedef MechanicalBehaviourTraits<Behaviour> Traits; 154 using handler = typename std::conditional< 155 Traits::isConsistentTangentOperatorSymmetric, 156 SymmetricConsistentTangentOperatorComputer, 157 GeneralConsistentTangentOperatorComputer 158 >::type; 159 handler::exe(b,DDSDDE); 160 }// end of exe 161 private: 162 struct SymmetricConsistentTangentOperatorComputer 163 { 164 template<typename Behaviour,typename real> exelsdyna::ExtractAndConvertTangentOperator::SymmetricConsistentTangentOperatorComputer165 static void exe(const Behaviour& bv, 166 real *const DDSDDE) 167 { 168 using TangentOperatorType 169 = typename LSDYNATangentOperatorType<LSDYNATraits<Behaviour>::btype,real,2u>::type; 170 constexpr const auto icste = tfel::math::Cste<real>::isqrt2; 171 TFEL_CONSTEXPR const auto one_half = real(1)/real(2); 172 auto Dt = static_cast<const TangentOperatorType&>(bv.getTangentOperator()); 173 DDSDDE[0] = Dt(0,0); 174 DDSDDE[1] = Dt(1,0); 175 DDSDDE[2] = Dt(3,0)*icste; 176 DDSDDE[3] = Dt(0,1); 177 DDSDDE[4] = Dt(1,1); 178 DDSDDE[5] = Dt(3,1)*icste; 179 DDSDDE[6] = Dt(0,3)*icste; 180 DDSDDE[7] = Dt(1,3)*icste; 181 DDSDDE[8] = Dt(3,3)*one_half; 182 } // end of exe 183 }; 184 struct GeneralConsistentTangentOperatorComputer 185 { 186 template<typename Behaviour,typename real> exelsdyna::ExtractAndConvertTangentOperator::GeneralConsistentTangentOperatorComputer187 static void exe(const Behaviour& bv,real *const DDSDDE) 188 { 189 using TangentOperatorType = 190 typename LSDYNATangentOperatorType<LSDYNATraits<Behaviour>::btype,real,2u>::type; 191 constexpr const auto icste = tfel::math::Cste<real>::isqrt2; 192 TFEL_CONSTEXPR const auto one_half = real(1)/real(2); 193 auto Dt = static_cast<const TangentOperatorType&>(bv.getTangentOperator()); 194 DDSDDE[0] = Dt(0,0); 195 DDSDDE[1] = Dt(0,1); 196 DDSDDE[2] = Dt(0,3)*icste; 197 DDSDDE[3] = Dt(1,0); 198 DDSDDE[4] = Dt(1,1); 199 DDSDDE[5] = Dt(1,3)*icste; 200 DDSDDE[6] = Dt(3,0)*icste; 201 DDSDDE[7] = Dt(3,1)*icste; 202 DDSDDE[8] = Dt(3,3)*one_half; 203 } // end of exe 204 }; 205 }; 206 207 } // end of namespace lsdyna 208 209 #include"MFront/LSDYNA/LSDYNATangentOperator.ixx" 210 211 #endif /* LIB_MFRONT_LSDYNA_LSDYNATANGENTOPERATOR_HXX */ 212