1 /*!
2  * \file   ConvertToTangentModuliTest.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \date   15 déc. 2015
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 #include<cstdlib>
15 #include<iostream>
16 
17 #include"TFEL/Tests/Test.hxx"
18 #include"TFEL/Tests/TestCase.hxx"
19 #include"TFEL/Tests/TestProxy.hxx"
20 #include"TFEL/Tests/TestManager.hxx"
21 #include"TFEL/Math/stensor.hxx"
22 #include"TFEL/Math/st2tost2.hxx"
23 #include"TFEL/Math/t2tost2.hxx"
24 #include"TFEL/Math/tensor.hxx"
25 #include"TFEL/Material/Lame.hxx"
26 #include"TFEL/Math/ST2toST2/ConvertToTangentModuli.hxx"
27 
28 struct ConvertToTangentModuliTest
29   : public tfel::tests::TestCase
30 {
31 
ConvertToTangentModuliTestConvertToTangentModuliTest32   ConvertToTangentModuliTest()
33     : tfel::tests::TestCase("TFEL/Math","ConvertToTangentModuli")
34   {} // end of ConvertToTangentModuli
35 
executeConvertToTangentModuliTest36   tfel::tests::TestResult execute() override
37   {
38     this->test<1>();
39     this->test<2>();
40     this->test<3>();
41     return this->result;
42   } // end of execute
43 
44 private:
45   // simple alias
46   using size_type = tfel::math::t2tost2<1u,double>::size_type;
47   /*!
48    */
49   template<unsigned short N>
testConvertToTangentModuliTest50   void test(){
51     using namespace tfel::math;
52     const double eps = 1.e-14;
53     const double E  = 150e9;
54     const double nu = 0.33;
55     const double lambda = tfel::material::computeLambda(E,nu);
56     const double mu     = tfel::material::computeMu(E,nu);
57     const st2tost2<N,double> D = lambda*st2tost2<N,double>::IxI()+2*mu*st2tost2<N,double>::Id();
58     tensor<N,double> F;
59     for(size_type i=0;i!=F.size();++i){
60       if(i<3){
61 	F[i] = 1+0.1*i*i;
62       } else {
63 	F[i] = 0.03*(i-2);
64       }
65     }
66     const auto CG   = computeRightCauchyGreenTensor(F);
67     const auto e_gl = 0.5*(CG-stensor<N,double>::Id());
68     const auto S  = eval(D*e_gl);
69     const auto dC = t2tost2<N,double>::dCdF(F);
70     const auto dS = 0.5*D*dC;
71     t2tost2<N,double> K;
72     computePushForwardDerivative(K,dS,S,F);
73     // real work begin here
74     t2tot2<N,double>   C1;
75     st2tost2<N,double> C2;
76     for(size_type i=0;i!=3u;++i){
77       for(size_type j=0;j!=3u;++j){
78 	const auto rij  = index(i,j,N);
79 	const auto rij2 = index2(i,j,N);
80 	if(rij==-1){
81 	  continue;
82 	}
83 	for(size_type k=0;k!=3u;++k){
84 	  for(size_type l=0;l!=3u;++l){
85 	    const auto rkl = index(k,l,N);
86 	    if(rkl==-1){
87 	      continue;
88 	    }
89 	    C1(rij,rkl)=double{0};
90 	    for(size_type m=0;m!=3u;++m){
91 	      const auto rkm = index(k,m,N);
92 	      const auto rlm = index(l,m,N);
93 	      if(rkm==-1){
94 		continue;
95 	      }
96 	      if(rlm==-1){
97 		continue;
98 	      }
99 	      C1(rij,rkl)+=K(rij2,rkm)*F(rlm);
100 	    }
101 	    if(i!=j){
102 	      C1(rij,rkl) /= std::sqrt(2);
103 	    }
104 	  }
105 	}
106       }
107     }
108     for(size_type i=0;i!=3u;++i){
109       for(size_type j=0;j!=3u;++j){
110 	const auto rij  = index2(i,j,N);
111 	if(rij==-1){
112 	  continue;
113 	}
114 	const auto rij1 = index(i,j,N);
115 	const auto rij2 = index(j,i,N);
116 	for(size_type k=0;k!=3u;++k){
117 	  for(size_type l=0;l!=3u;++l){
118 	    const auto rkl  = index2(k,l,N);
119 	    if(rkl==-1){
120 	      continue;
121 	    }
122 	    const auto rkl1 = index(k,l,N);
123 	    const auto rkl2 = index(l,k,N);
124 	    C2(rij,rkl)=(C1(rij1,rkl1)+C1(rij1,rkl2)+
125 			 C1(rij2,rkl1)+C1(rij2,rkl2))/4;
126 	  }
127 	}
128       }
129     }
130     for(size_type i=3;i!=StensorDimeToSize<N>::value;++i){
131       for(size_type j=0;j!=StensorDimeToSize<N>::value;++j){
132 	C2(i,j)*=std::sqrt(2);
133       }
134     }
135     for(size_type i=0;i!=StensorDimeToSize<N>::value;++i){
136       for(size_type j=3;j!=StensorDimeToSize<N>::value;++j){
137 	C2(i,j)/=std::sqrt(2);
138       }
139     }
140     const auto C = convertToTangentModuli(K,F);
141     for(size_type i=0;i!=StensorDimeToSize<N>::value;++i){
142       for(size_type j=0;j!=StensorDimeToSize<N>::value;++j){
143 	TFEL_TESTS_ASSERT(std::abs(C(i,j)-C2(i,j))<E*eps);
144       }
145     }
146   }
indexConvertToTangentModuliTest147   static int index(const size_type i,const size_type j,
148 		   const size_type N){
149     if(i==j){
150       return i;
151     }
152     if(N==1){
153       return -1;
154     }
155     if((i==0)&&(j==1)){
156       return 3;
157     }
158     if((i==1)&&(j==0)){
159       return 4;
160     }
161     if((i==0)&&(j==2)&&(N==3u)){
162       return 5;
163     }
164     if((i==2)&&(j==0)&&(N==3u)){
165       return 6;
166     }
167     if((i==1)&&(j==2)&&(N==3u)){
168       return 7;
169     }
170     if((i==2)&&(j==1)&&(N==3u)){
171       return 8;
172     }
173     return -1;
174   }
index2ConvertToTangentModuliTest175   static int index2(const size_type i,const size_type j,
176 		    const size_type N){
177     if(i==j){
178       return i;
179     }
180     if(N==1){
181       return -1;
182     }
183     if(((i==0)&&(j==1))||
184        ((i==1)&&(j==0))){
185       return 3;
186     }
187     if((((i==0)&&(j==2))||
188 	((i==2)&&(j==0)))&&(N==3u)){
189       return 4;
190     }
191     if((((i==1)&&(j==2))||
192 	((i==2)&&(j==1)))&&(N==3u)){
193       return 5;
194     }
195     return -1;
196   }
197 }; // end of ConvertToTangentModuliTest
198 
199 TFEL_TESTS_GENERATE_PROXY(ConvertToTangentModuliTest,
200 			  "ConvertToTangentModuliTest");
201 
main()202 int main()
203 {
204   auto& manager = tfel::tests::TestManager::getTestManager();
205   manager.addTestOutput(std::cout);
206   manager.addXMLTestOutput("ConvertToTangentModuli.xml");
207   const auto r = manager.execute();
208   return r.success() ? EXIT_SUCCESS : EXIT_FAILURE;
209 }
210 
211