1 /*!
2  * \file  mfront/include/MFront/Ansys/AnsysTangentOperator.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_ANSYS_ANSYSTANGENTOPERATOR_HXX
15 #define LIB_MFRONT_ANSYS_ANSYSTANGENTOPERATOR_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/Ansys/Ansys.hxx"
25 #include"MFront/Ansys/AnsysTraits.hxx"
26 #include"MFront/Ansys/AnsysConfig.hxx"
27 
28 namespace ansys
29 {
30 
31   template<AnsysBehaviourType btype,
32 	   typename real,unsigned short N>
33   struct AnsysTangentOperatorType
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 AnsysTangentOperator
45   {
46     /*!
47      * \brief convert to TFEL object
48      * \param[in] D: ansys tangent operatorx
49      */
50     static tfel::math::st2tost2<2u,real>
51     convert2D(const real* const);
52     /*!
53      * \brief convert to TFEL object
54      * \param[in] D: ansys tangent operatorx
55      */
56     static tfel::math::st2tost2<3u,real>
57     convert3D(const real* const);
58     /*!
59      * \brief normalize the tangent operator in 1D
60      * \param[in] Dt : tangent operator
61      */
62     static void
63     normalize(tfel::math::ST2toST2View<1u,real>&);
64     /*!
65      * \brief normalize the tangent operator in 2D
66      * \param[in] Dt : tangent operator
67      */
68     static void
69     normalize(tfel::math::ST2toST2View<2u,real>&);
70     /*!
71      * \brief normalize the tangent operator in 3D
72      * \param[in] Dt : tangent operator
73      */
74     static void
75     normalize(tfel::math::ST2toST2View<3u,real>&);
76     /*!
77      * \brief transpose the tangent operator in 1D
78      * \param[in] Dt : tangent operator
79      */
80     static void
81     transpose(tfel::math::ST2toST2View<1u,real>&);
82     /*!
83      * \brief transpose the tangent operator in 2D
84      * \param[in] Dt : tangent operator
85      */
86     static void
87     transpose(tfel::math::ST2toST2View<2u,real>&);
88     /*!
89      * \brief transpose the tangent operator in 3D
90      * \param[in] Dt : tangent operator
91      */
92     static void
93     transpose(tfel::math::ST2toST2View<3u,real>&);
94   }; // end of struct AnsysTangentOperator
95 
96   /*!
97    * \brief this class extracts and normalise (convert to
98    * ansys/fortran conventions) the tangent operator
99    */
100   template<tfel::material::ModellingHypothesis::Hypothesis H>
101   struct ExtractAndConvertTangentOperator
102   {
103     template<typename Behaviour,typename real>
exeansys::ExtractAndConvertTangentOperator104     static void exe(const Behaviour& b,real *const DDSDDE){
105       using namespace tfel::material;
106       typedef MechanicalBehaviourTraits<Behaviour> Traits;
107       using handler = typename std::conditional<
108 	Traits::isConsistentTangentOperatorSymmetric,
109 	SymmetricConsistentTangentOperatorComputer,
110 	GeneralConsistentTangentOperatorComputer
111 	>::type;
112       handler::exe(b,DDSDDE);
113     }// end of exe
114   private:
115     struct ConsistentTangentOperatorComputer
116     {
117       template<typename Behaviour,typename real>
exeansys::ExtractAndConvertTangentOperator::ConsistentTangentOperatorComputer118       static void exe(const Behaviour& bv,
119 		      real *const DDSDDE)
120       {
121 	using tfel::material::ModellingHypothesisToSpaceDimension;
122 	const unsigned short N = ModellingHypothesisToSpaceDimension<H>::value;
123 	using  TangentOperatorType     = typename AnsysTangentOperatorType<AnsysTraits<Behaviour>::btype,real,N>::type;
124 	using  TangentOperatorViewType = typename AnsysTangentOperatorType<AnsysTraits<Behaviour>::btype,real,N>::view_type;
125 	TangentOperatorViewType Dt{DDSDDE};
126 	Dt = static_cast<const TangentOperatorType&>(bv.getTangentOperator());
127 	AnsysTangentOperator<real>::normalize(Dt);
128       } // end of exe
129     };
130     struct SymmetricConsistentTangentOperatorComputer
131     {
132       template<typename Behaviour,typename real>
exeansys::ExtractAndConvertTangentOperator::SymmetricConsistentTangentOperatorComputer133       static void exe(const Behaviour& bv,
134 		      real *const DDSDDE)
135       {
136 	ConsistentTangentOperatorComputer::exe(bv,DDSDDE);
137       } // end of exe
138     };
139     struct GeneralConsistentTangentOperatorComputer
140     {
141       template<typename Behaviour,typename real>
exeansys::ExtractAndConvertTangentOperator::GeneralConsistentTangentOperatorComputer142       static void exe(const Behaviour& bv,real *const DDSDDE)
143       {
144 	using tfel::material::ModellingHypothesisToSpaceDimension;
145 	const unsigned short N = ModellingHypothesisToSpaceDimension<H>::value;
146 	using TangentOperatorViewType = typename AnsysTangentOperatorType<AnsysTraits<Behaviour>::btype,real,N>::view_type;
147 	ConsistentTangentOperatorComputer::exe(bv,DDSDDE);
148 	// les conventions fortran....
149 	TangentOperatorViewType Dt{DDSDDE};
150 	AnsysTangentOperator<real>::transpose(Dt);
151       } // end of exe
152     };
153   }; // end of struct ExtractAndConvertTangentOperator
154   /*!
155    * \brief partial specialisation of the
156    * ExtractAndConvertTangentOperator for the plane stress modelling
157    * hypothesis
158    */
159   template<>
160   struct ExtractAndConvertTangentOperator<tfel::material::ModellingHypothesis::PLANESTRESS>
161   {
162     template<typename Behaviour,typename real>
exeansys::ExtractAndConvertTangentOperator163     static void exe(const Behaviour& b,real *const DDSDDE){
164       using namespace tfel::material;
165       typedef MechanicalBehaviourTraits<Behaviour> Traits;
166       using handler = typename std::conditional<
167 	Traits::isConsistentTangentOperatorSymmetric,
168 	SymmetricConsistentTangentOperatorComputer,
169 	GeneralConsistentTangentOperatorComputer
170 	>::type;
171       handler::exe(b,DDSDDE);
172     }// end of exe
173   private:
174     struct SymmetricConsistentTangentOperatorComputer
175     {
176       template<typename Behaviour,typename real>
exeansys::ExtractAndConvertTangentOperator::SymmetricConsistentTangentOperatorComputer177       static void exe(const Behaviour& bv,
178 		      real *const DDSDDE)
179       {
180 	using  TangentOperatorType
181 	  = typename AnsysTangentOperatorType<AnsysTraits<Behaviour>::btype,real,2u>::type;
182 	constexpr      const auto cste = tfel::math::Cste<real>::sqrt2;
183 	// constexpr      const auto icste = tfel::math::Cste<real>::isqrt2;
184 	// TFEL_CONSTEXPR const auto one_half = real(1)/real(2);
185 	auto Dt = static_cast<const TangentOperatorType&>(bv.getTangentOperator());
186 	// DDSDDE[0] = Dt(0,0);
187 	// DDSDDE[1] = Dt(1,0);
188 	// DDSDDE[2] = Dt(3,0)*icste;
189 	// DDSDDE[3] = Dt(0,1);
190 	// DDSDDE[4] = Dt(1,1);
191 	// DDSDDE[5] = Dt(3,1)*icste;
192 	// DDSDDE[6] = Dt(0,3)*icste;
193 	// DDSDDE[7] = Dt(1,3)*icste;
194 	// DDSDDE[8] = Dt(3,3)*one_half;
195 	DDSDDE[0] = Dt(0,0);
196 	DDSDDE[1] = Dt(1,0);
197 	DDSDDE[2] = Dt(3,0)*cste;
198 	DDSDDE[3] = Dt(0,1);
199 	DDSDDE[4] = Dt(1,1);
200 	DDSDDE[5] = Dt(3,1)*cste;
201 	DDSDDE[6] = Dt(0,3)*cste;
202 	DDSDDE[7] = Dt(1,3)*cste;
203 	DDSDDE[8] = Dt(3,3);
204       } // end of exe
205     };
206     struct GeneralConsistentTangentOperatorComputer
207     {
208       template<typename Behaviour,typename real>
exeansys::ExtractAndConvertTangentOperator::GeneralConsistentTangentOperatorComputer209       static void exe(const Behaviour& bv,real *const DDSDDE)
210       {
211 	using  TangentOperatorType =
212 	  typename AnsysTangentOperatorType<AnsysTraits<Behaviour>::btype,real,2u>::type;
213 	constexpr const auto cste = tfel::math::Cste<real>::sqrt2;
214 	// constexpr const auto icste = tfel::math::Cste<real>::isqrt2;
215 	// TFEL_CONSTEXPR const auto one_half = real(1)/real(2);
216 	auto Dt = static_cast<const TangentOperatorType&>(bv.getTangentOperator());
217 	// DDSDDE[0] = Dt(0,0);
218 	// DDSDDE[1] = Dt(0,1);
219 	// DDSDDE[2] = Dt(0,3)*icste;
220 	// DDSDDE[3] = Dt(1,0);
221 	// DDSDDE[4] = Dt(1,1);
222 	// DDSDDE[5] = Dt(1,3)*icste;
223 	// DDSDDE[6] = Dt(3,0)*icste;
224 	// DDSDDE[7] = Dt(3,1)*icste;
225 	// DDSDDE[8] = Dt(3,3)*one_half;
226 	DDSDDE[0] = Dt(0,0);
227 	DDSDDE[1] = Dt(0,1);
228 	DDSDDE[2] = Dt(0,3)*cste;
229 	DDSDDE[3] = Dt(1,0);
230 	DDSDDE[4] = Dt(1,1);
231 	DDSDDE[5] = Dt(1,3)*cste;
232 	DDSDDE[6] = Dt(3,0)*cste;
233 	DDSDDE[7] = Dt(3,1)*cste;
234 	DDSDDE[8] = Dt(3,3);
235       } // end of exe
236     };
237   };
238 
239 } // end of namespace ansys
240 
241 #include"MFront/Ansys/AnsysTangentOperator.ixx"
242 
243 #endif /* LIB_MFRONT_ANSYS_ANSYSTANGENTOPERATOR_HXX */
244