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