1 /*!
2  * \file   tests/Math/t2tot2/ComputeTensorDeterminantSecondDerivativeTest.cxx
3  * \brief
4  * \author Thomas Helfer
5  * \date   14/11/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 #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/tensor.hxx"
22 #include"TFEL/Math/t2tot2.hxx"
23 
24 struct ComputeTensorDeterminantSecondDerivativeTest final
25   : public tfel::tests::TestCase
26 {
ComputeTensorDeterminantSecondDerivativeTestComputeTensorDeterminantSecondDerivativeTest27   ComputeTensorDeterminantSecondDerivativeTest()
28     : tfel::tests::TestCase("TFEL/Math/T2toT2",
29 			    "ComputeTensorDeterminantSecondDerivative")
30   {} // end of ComputeTensorDeterminantSecondDerivativeTest
31 
executeComputeTensorDeterminantSecondDerivativeTest32   tfel::tests::TestResult execute() override
33   {
34     const double Id[9u] = {1.,1.,1.,0.,0.,0.,0.,0.,0.};
35     const double v[9u]  = {1.27453824166446,0.77207083708966,0.24525337568425,
36 			  -1.7790370858361e-4,3.613971630283e-3,-1.7873236537153e-02,
37 			  3.613971630283e-3,-1.7873236537153e-02,-1.7790370858361e-1};
38     const double v2[9u] = {1.02,0.85,1.78,
39 			   0.18,-0.16,0.05,
40 			   -0.08,-0.0243,0.07654};
41     test<1u>(Id);
42     test<2u>(Id);
43     test<3u>(Id);
44     test<1u>(v);
45     test<2u>(v);
46     test<3u>(v);
47     test<1u>(v2);
48     test<2u>(v2);
49     test<3u>(v2);
50     return this->result;
51   } // end of execute
52  private:
53   template<unsigned short N>
testComputeTensorDeterminantSecondDerivativeTest54   void test(const double* values){
55     this->template test2<N>(values);
56     this->template test3<N>(values);
57   }
58   template<unsigned short N>
test2ComputeTensorDeterminantSecondDerivativeTest59   void test2(const double* values){
60     using namespace tfel::math;
61     using Tensor    = tensor<N,double>;
62     using size_type = typename tensor<N,double>::size_type;
63     const double eps  = 1.e-5;
64     const double prec = 1.e-10;
65     const Tensor s(values);
66     const auto dJ2 = computeDeterminantSecondDerivative(s);
67     t2tot2<N,double> ndJ2;
68     for(size_type i=0;i!=s.size();++i){
69       tensor<N> s_e(s);
70       s_e[i] += eps;
71       const tensor<N> dJp = det(s_e)*invert(s_e);
72       s_e[i] -= 2*eps;
73       const tensor<N> dJm = det(s_e)*invert(s_e);
74       for(size_type j=0;j!=s.size();++j){
75     	ndJ2(j,i) = (dJp(j)-dJm(j))/(2*eps);
76       }
77     }
78     for(size_type i=0;i!=s.size();++i){
79       for(size_type j=0;j!=s.size();++j){
80     	TFEL_TESTS_ASSERT(std::abs(ndJ2(i,j)-dJ2(i,j))<prec);
81     	if(std::abs(ndJ2(i,j)-dJ2(i,j))>prec){
82     	  std::cout << "Error " << N << " (" << i << ", " << j << ") "
83     		    << "[" << i*TensorDimeToSize<N>::value+j << "]: "
84     		    << ndJ2(i,j) << " vs " << dJ2(i,j) << " "
85     		    << std::abs(ndJ2(i,j)-dJ2(i,j)) << std::endl;
86     	}
87       }
88     }
89   }
90   template<unsigned short N>
test3ComputeTensorDeterminantSecondDerivativeTest91   void test3(const double* values){
92     using namespace tfel::math;
93     using Tensor  = tensor<N,double>;
94     using Tensor4 = t2tot2<N,double>;
95     using size_type = typename tensor<N,double>::size_type;
96     const double prec = 1.e-10;
97     const tensor<N,double> s(values);
98     const Tensor s2 = s*s;
99     const Tensor s3 = s2*s;
100     const auto i1 = trace(s);
101     const auto i2 = (i1*i1-trace(s*s))/2;
102     const auto i3 = det(s);
103     const Tensor c = s3-i1*s2+i2*s-i3*Tensor::Id();
104     const auto dJ2 = computeDeterminantSecondDerivative(s);
105        const Tensor id = Tensor::Id();
106     const t2tot2<N,double> dJ2_2 =
107       Tensor4::tpld(s)+Tensor4::tprd(s)-(s^id)-i1*Tensor4::Id()
108       +(id^(i1*id-transpose(s)));
109     for(size_type i=0;i!=s.size();++i){
110       TFEL_TESTS_ASSERT(std::abs(c(i))<100*std::numeric_limits<double>::epsilon());
111       for(size_type j=0;j!=s.size();++j){
112       	TFEL_TESTS_ASSERT(std::abs(dJ2_2(i,j)-dJ2(i,j))<prec);
113       	if(std::abs(dJ2_2(i,j)-dJ2(i,j))>prec){
114       	  std::cout << "Error " << N << " (" << i << ", " << j << ") "
115       		    << "[" << i*TensorDimeToSize<N>::value+j << "]: "
116       		    << dJ2_2(i,j) << " vs " << dJ2(i,j) << " "
117       		    << std::abs(dJ2_2(i,j)-dJ2(i,j)) << std::endl;
118       	}
119       }
120     }
121   }
122 }; // end of ComputeTensorDeterminantSecondDerivativeTest
123 
124 TFEL_TESTS_GENERATE_PROXY(ComputeTensorDeterminantSecondDerivativeTest,
125 			  "ComputeTensorDeterminantSecondDerivativeTest");
126 
main()127 int main()
128 {
129   auto& m = tfel::tests::TestManager::getTestManager();
130   m.addTestOutput(std::cout);
131   m.addXMLTestOutput("ComputeTensorDeterminantSecondDerivative.xml");
132   return m.execute().success() ? EXIT_SUCCESS : EXIT_FAILURE;
133 }
134