1 /*!
2  * \file   tests/Material/HosfordSecondDerivativeTest.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \date   15/11/2017
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/StensorConceptIO.hxx"
22 #include"TFEL/Math/ST2toST2/ST2toST2ConceptIO.hxx"
23 #include"TFEL/Material/Hosford1972YieldCriterion.hxx"
24 
25 struct HosfordSecondDerivativeTest final
26   : public tfel::tests::TestCase
27 {
HosfordSecondDerivativeTestHosfordSecondDerivativeTest28   HosfordSecondDerivativeTest()
29     : tfel::tests::TestCase("TFEL/Math","HosfordSecondDerivative")
30   {} // end of HosfordSecondDerivativeTest
31 
executeHosfordSecondDerivativeTest32   tfel::tests::TestResult execute() override
33   {
34     // stresses in "MPa" :)
35     const double Id[6] = {1.,1.,1.,0.,0.,0.};
36     const double v1[6]  = {1.27453824166446,0.77207083708966,0.24525337568425,
37 			  -1.7790370858361e-4,3.613971630283e-3,-1.7873236537153e-2};
38     const double v2[6] = {1.27453824166446,1.27453824166446,0.24525337568425,
39 			  0,0,0};
40     const double v3[6] = {0.24525337568425,0.24525337568425,1.27453824166446,
41 			  0,0,0};
42     const double v4[6] = {-0.24525337568425,-0.24525337568425,1.27453824166446,
43 			  0,0,0};
44     for(const auto v : {Id,v1,v2,v3,v4}){
45       test1<1u>(v);
46       test1<2u>(v);
47       test1<3u>(v);
48     }
49     for(const auto v : {Id,v1,v2,v3,v4}){
50       test2<1u>(v);
51       test2<2u>(v);
52       test2<3u>(v);
53     }
54     for(const auto v : {v1,v2,v3,v4}){
55       test3<1u>(v);
56       test3<2u>(v);
57       test3<3u>(v);
58     }
59     return this->result;
60   } // end of execute
61  private:
62 
63   // This tests compares the Hosford stress and its first and second
64   // derivatives for an Hosford exponent egal to 2 to the Von Mises
65   // stress and its first and second derivatives
66   template<unsigned short N>
test1HosfordSecondDerivativeTest67   void test1(const double* values){
68     using tfel::math::stensor;
69     using tfel::math::st2tost2;
70     using tfel::material::computeHosfordStressSecondDerivative;
71     using size_type = typename stensor<N,double>::size_type;
72     const auto seps = 1.e-10;
73     const auto eps1 = 1.e-8;
74     const auto eps2 = 1.e-8;
75     const auto s    = stensor<N,double>{values};
76     const auto seq  = sigmaeq(s);
77     const auto n    = (seq<seps ?
78 		       stensor<N,double>(double(0)) :
79 		       eval(3*deviator(s)/(2*seq)));
80     const auto dn   = (seq<seps ?
81 		       st2tost2<N,double>(double(0)) :
82 		       eval((st2tost2<N,double>::M()-(n^n))/seq));
83     // no structured binding yet
84     double hseq;
85     tfel::math::stensor<N,double> hn;
86     tfel::math::st2tost2<N,double> dhn;
87     std::tie(hseq,hn,dhn) = computeHosfordStressSecondDerivative(s,2,seps);
88     TFEL_TESTS_ASSERT(std::abs(seq-hseq)<seps);
89     for(size_type i=0;i!=s.size();++i){
90       const auto en = std::abs(n[i]-hn[i]);
91       if(en>eps1){
92 	std::cout << i <<  " " << n(i)
93 		  << " " << hn(i) << " " << en << std::endl;
94       }
95       TFEL_TESTS_ASSERT(en<eps1);
96       for(size_type j=0;j!=s.size();++j){
97 	const auto edn = std::abs(dhn(i,j)-dn(i,j));
98 	if(edn>=eps2){
99 	  std::cout << i   << " " << j << " " << dn(i,j)
100 		    << " " << dhn(i,j) << " " << edn << std::endl;
101 	}
102 	TFEL_TESTS_ASSERT(std::abs(edn)<eps2);
103       }
104     }
105   }
106   // This tests compares the first derivative of the Hosford stress
107   // for an Hosford exponent egal to 8 to a numerical approximation
108   template<unsigned short N>
test2HosfordSecondDerivativeTest109   void test2(const double* values){
110     using tfel::math::stensor;
111     using tfel::math::st2tost2;
112     using tfel::material::computeHosfordStress;
113     using tfel::material::computeHosfordStressNormal;
114     using size_type = typename stensor<N,double>::size_type;
115     const auto seps = 1.e-10;
116     const auto eps1 = 3.e-8;
117     const auto ds   = 1.e-5;
118     const auto s    = stensor<N,double>{values};
119     double seq;
120     tfel::math::stensor<N,double> n;
121     std::tie(seq,n) = computeHosfordStressNormal(s,8,seps);
122     tfel::math::stensor<N,double> dn;
123     for(size_type i=0;i!=s.size();++i){
124       auto sb = s;
125       sb[i] += ds;
126       const auto seq_p = computeHosfordStress(sb,8,seps);
127       sb[i] -= 2*ds;
128       const auto seq_m = computeHosfordStress(sb,8,seps);
129       dn[i] = (seq_p-seq_m)/(2*ds);
130     }
131     for(size_type i=0;i!=s.size();++i){
132       const auto en = std::abs(dn[i]-n[i]);
133       if(en>eps1){
134 	std::cout << i <<  " " << n(i)
135 		  << " " << dn(i) << " " << en << std::endl;
136       }
137       TFEL_TESTS_ASSERT(en<eps1);
138     }
139   }
140   // This tests compares the first derivative of the Hosford stress
141   // for an Hosford exponent egal to 8 to a numerical approximation
142   template<unsigned short N>
test3HosfordSecondDerivativeTest143   void test3(const double* values){
144     using tfel::math::stensor;
145     using tfel::math::st2tost2;
146     using tfel::material::computeHosfordStressNormal;
147     using tfel::material::computeHosfordStressSecondDerivative;
148     constexpr const auto a  = double(8);
149     using size_type = typename stensor<N,double>::size_type;
150     const auto seps = 1.e-10;
151     const auto eps1 = 2.e-6;
152     const auto eps2 = 2.e-4;
153     const auto ds   = 1.e-6;
154     const auto s    = stensor<N,double>{values};
155     double seq;
156     stensor<N,double> n;
157     st2tost2<N,double> dn;
158     std::tie(seq,n,dn) = computeHosfordStressSecondDerivative(s,a,seps);
159     tfel::math::st2tost2<N,double> dnn;
160     for(size_type i=0;i!=s.size();++i){
161       auto sb = s;
162       sb[i] += ds;
163       double seq_p,seq_m;
164       stensor<N,double> n_p,n_m;
165       std::tie(seq_p,n_p) = computeHosfordStressNormal(sb,a,seps);
166       sb[i] -= 2*ds;
167       std::tie(seq_m,n_m) = computeHosfordStressNormal(sb,a,seps);
168       for(size_type j=0;j!=s.size();++j){
169 	dnn(j,i)=(n_p(j)-n_m(j))/(2*ds);
170       }
171     }
172     for(size_type i=0;i!=s.size();++i){
173       for(size_type j=0;j!=s.size();++j){
174 	const auto en = std::abs(dnn(i,j)-dn(i,j));
175 	const auto e  = std::max(std::abs(dnn(i,j))*eps2,
176 				 eps1);
177 	if(en>e){
178 	  std::cout << i <<  " " << j
179 		    << " " << dnn(i,j)
180 		    << " " << dn(i,j)
181 		    << " " << en
182 		    << " " << e  << std::endl;
183 	}
184 	TFEL_TESTS_ASSERT(en<e);
185       }
186     }
187   }
188 }; // end of HosfordSecondDerivativeTest
189 
190 TFEL_TESTS_GENERATE_PROXY(HosfordSecondDerivativeTest,
191 			  "HosfordSecondDerivativeTest");
192 
main()193 int main()
194 {
195   auto& m = tfel::tests::TestManager::getTestManager();
196   m.addTestOutput(std::cout);
197   m.addXMLTestOutput("HosfordSecondDerivative.xml");
198   return m.execute().success() ? EXIT_SUCCESS : EXIT_FAILURE;
199 }
200