1 /*!
2  * \file  tests/Material/FiniteStrainBehaviourTangentOperator4.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \brief 18 août 2016
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 #ifdef NDEBUG
15 #undef NDEBUG
16 #endif /* NDEBUG */
17 
18 #include<cstdlib>
19 #include<iostream>
20 
21 #include"TFEL/Tests/TestCase.hxx"
22 #include"TFEL/Tests/TestProxy.hxx"
23 #include"TFEL/Tests/TestManager.hxx"
24 
25 #include"TFEL/Math/stensor.hxx"
26 #include"TFEL/Math/tensor.hxx"
27 #include"TFEL/Math/st2tost2.hxx"
28 #include"TFEL/Math/t2tost2.hxx"
29 #include"TFEL/Math/st2tot2.hxx"
30 #include"TFEL/Math/t2tot2.hxx"
31 #include"TFEL/Math/T2toT2/T2toT2ConceptIO.hxx"
32 #include"TFEL/Math/T2toST2/T2toST2ConceptIO.hxx"
33 #include"TFEL/Math/ST2toST2/ConvertSpatialModuliToKirchhoffJaumanRateModuli.hxx"
34 #include"TFEL/Math/T2toST2/ConvertKirchhoffStressJaumanRateModuliToKirchhoffStressDerivative.hxx"
35 
36 struct FiniteStrainBehaviourTangentOperator4 final
37   : public tfel::tests::TestCase
38 {
FiniteStrainBehaviourTangentOperator4FiniteStrainBehaviourTangentOperator439   FiniteStrainBehaviourTangentOperator4()
40     : tfel::tests::TestCase("TFEL/Material",
41 			    "FiniteStrainBehaviourTangentOperator4")
42   {} // end of FiniteStrainBehaviourTangentOperator4
executeFiniteStrainBehaviourTangentOperator443   tfel::tests::TestResult execute() override
44   {
45     this->check<1u>();
46     this->check<2u>();
47     this->check<3u>();
48     return this->result;
49   } // end of execute
50  private:
51   template<unsigned short N>
checkFiniteStrainBehaviourTangentOperator452   void check(){
53     using real = double;
54     using stensor  = tfel::math::stensor<N,real>;
55     using tensor   = tfel::math::tensor<N,real>;
56     using t2tost2  = tfel::math::t2tost2<N,real>;
57     using st2tost2 = tfel::math::st2tost2<N,real>;
58     const real l0  = 1.09465e+11;
59     const real m0  = 5.6391e+10;
60     const real eps = 5.e-10*m0;
61     auto nhb = [&l0,&m0](const tfel::math::tensor<N,real>& F) -> stensor{
62       const auto J  = tfel::math::det(F);
63       const auto B  = tfel::math::computeLeftCauchyGreenTensor(F);
64       const auto Id = stensor::Id();
65       return (l0*std::log(J)*Id+m0*(B-Id))/J;
66     };
67     // spatial moduli
68     const auto Cs = [&l0,&m0](const tfel::math::tensor<N,real>& F)
69       -> st2tost2
70     {
71       const auto J = tfel::math::det(F);
72       const auto m = m0-l0*std::log(J);
73       return l0*st2tost2::IxI()+2*m*st2tost2::Id();
74     };
75     const auto D =  [&Cs,&nhb](const tfel::math::tensor<N,real>& F) -> t2tost2{
76       const auto J = det(F);
77       const auto s = nhb(F);
78       const auto t = s*J;
79       const auto CtJ = tfel::math::convertSpatialModuliToKirchhoffJaumanRateModuli(Cs(F),t);
80       const auto Dt  = tfel::math::ConvertKirchhoffStressJaumanRateModuliToKirchhoffStressDerivative<N,double>::exe(CtJ,F,t);
81       const auto dJ  = tfel::math::computeDeterminantDerivative(F);
82       return (Dt-(s^dJ))/J;
83     };
84     for(const tensor& F : {tensor::Id(),tensor{1.03,0.98,1.09,0.03,-0.012,0.04,-0.028,-0.015,0.005}}){
85       const t2tost2 nD = this->getNumericalApproximation(nhb,F,1.e-5);
86       const t2tost2 aD = D(F);
87       for(unsigned short i=0;i!=tfel::math::StensorDimeToSize<N>::value;++i){
88       	for(unsigned short j=0;j!=tfel::math::TensorDimeToSize<N>::value;++j){
89       	  if(std::abs(aD(i,j)-nD(i,j))>eps){
90       	    std::cout << i << " " << j << " "
91       		      << aD(i,j) << " " << nD(i,j) << " " << aD(i,j)-nD(i,j) << " " << eps << std::endl;
92       	  }
93       	  TFEL_TESTS_ASSERT(std::abs(aD(i,j)-nD(i,j))<eps);
94       	}
95       }
96     }
97   }
98   template<unsigned short N,typename Behaviour,typename real>
getNumericalApproximationFiniteStrainBehaviourTangentOperator499   tfel::math::t2tost2<N,real> getNumericalApproximation(const Behaviour& b,
100 							const tfel::math::tensor<N,real>& F,
101 							const real e){
102     tfel::math::t2tost2<N,real> r;
103     for(unsigned short j=0;j!=tfel::math::TensorDimeToSize<N>::value;++j){
104       tfel::math::tensor<N,real> Fp = F;
105       tfel::math::tensor<N,real> Fm = F;
106       Fp(j)+=e;
107       Fm(j)-=e;
108       const tfel::math::stensor<N,real> sp = b(Fp);
109       const tfel::math::stensor<N,real> sm = b(Fm);
110       const tfel::math::stensor<N,real> ds = (sp-sm)/(2*e);
111       for(unsigned short i=0;i!=tfel::math::StensorDimeToSize<N>::value;++i){
112 	r(i,j)=ds(i);
113       }
114     }
115     return r;
116   }
117 };
118 
119 TFEL_TESTS_GENERATE_PROXY(FiniteStrainBehaviourTangentOperator4,
120 			  "FiniteStrainBehaviourTangentOperator4");
121 
122 /* coverity [UNCAUGHT_EXCEPT]*/
main()123 int main()
124 {
125   auto& m = tfel::tests::TestManager::getTestManager();
126   m.addTestOutput(std::cout);
127   m.addXMLTestOutput("FiniteStrainBehaviourTangentOperator4.xml");
128   return m.execute().success() ? EXIT_SUCCESS : EXIT_FAILURE;
129 } // end of main
130