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