1 /*!
2  * \file  include/TFEL/Math/T2toT2/TensorProductRightDerivativeExpr.hxx
3  * \brief
4  * \author Thomas Helfer
5  * \brief 04 juin 2014
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 #ifndef LIB_TFEL_MATH_TENSORPRODUCTRIGHTDERIVATIVEEXPR_HXX
15 #define LIB_TFEL_MATH_TENSORPRODUCTRIGHTDERIVATIVEEXPR_HXX
16 
17 #include"TFEL/Math/General/EmptyRunTimeProperties.hxx"
18 #include"TFEL/Metaprogramming/StaticAssert.hxx"
19 #include"TFEL/Math/T2toT2/T2toT2Concept.hxx"
20 
21 namespace tfel{
22 
23   namespace math{
24 
25     /*!
26      * Empty structure allowing partial specialisation
27      */
28     template<unsigned short N>
29     struct TensorProductRightDerivativeExpr
30     {}; // end of struct TensorProductRightDerivativeExpr
31 
32     /*!
33      * Partial specialisation for 1D tensor
34      */
35     template<typename T2toT2ResultType>
36     struct Expr<T2toT2ResultType,TensorProductRightDerivativeExpr<1u> >
37       : public T2toT2Concept<Expr<T2toT2ResultType,TensorProductRightDerivativeExpr<1u> > >,
38 	public fsarray<9u,typename T2toT2Traits<T2toT2ResultType>::NumType>
39     {
40       //! a simple check
41       TFEL_STATIC_ASSERT(T2toT2Traits<T2toT2ResultType>::dime==1u);
42       //! a simple alias
43       typedef typename T2toT2Traits<T2toT2ResultType>::NumType value_type;
44       //! a simple alias
45       typedef EmptyRunTimeProperties RunTimeProperties;
46       /*!
47        * \param[in] A : second tensor of the product
48        */
49       template<typename TensorType>
Exprtfel::math::Expr50       Expr(const TensorType& A)
51       {
52 	//! a simple check
53 	TFEL_STATIC_ASSERT((tfel::meta::Implements<TensorType,TensorConcept>::cond));
54 	//! a simple check
55 	TFEL_STATIC_ASSERT((T2toT2Traits<T2toT2ResultType>::dime==TensorTraits<TensorType>::dime));
56 	//! a simple check
57 	TFEL_STATIC_ASSERT((tfel::typetraits::IsAssignableTo<typename TensorTraits<TensorType>::NumType,
58 							     typename T2toT2Traits<T2toT2ResultType>::NumType>::cond));
59 	this->v[0] = A[0];
60 	this->v[4] = A[1];
61 	this->v[8] = A[2];
62 	this->v[1] = this->v[2] = value_type(0);
63 	this->v[3] = this->v[5] = value_type(0);
64 	this->v[6] = this->v[7] = value_type(0);
65       } // end of Expr
66       /*!
67        * \param[in] A : first tensor of the product
68        * \param[in] C : derivative of the second tensor
69        */
70       template<typename TensorType,
71 	       typename T2toT2Type>
Exprtfel::math::Expr72       Expr(const TensorType& A,
73 		 const T2toT2Type& C)
74       {
75 	//! a simple check
76 	TFEL_STATIC_ASSERT((tfel::meta::Implements<TensorType,TensorConcept>::cond));
77 	//! a simple check
78 	TFEL_STATIC_ASSERT((tfel::meta::Implements<T2toT2Type,tfel::math::T2toT2Concept>::cond));
79 	//! a simple check
80 	TFEL_STATIC_ASSERT((T2toT2Traits<T2toT2ResultType>::dime==TensorTraits<TensorType>::dime));
81 	//! a simple check
82 	TFEL_STATIC_ASSERT((T2toT2Traits<T2toT2Type>::dime==TensorTraits<TensorType>::dime));
83 	//! a simple check
84 	TFEL_STATIC_ASSERT((tfel::typetraits::IsAssignableTo<typename ComputeBinaryResult<typename TensorTraits<TensorType>::NumType,
85 											  typename T2toT2Traits<T2toT2Type>::NumType,
86 											  OpMult>::Result,
87 							     typename T2toT2Traits<T2toT2ResultType>::NumType>::cond));
88 	this->v[0]=C(0,0)*A[0];
89 	this->v[1]=C(0,1)*A[0];
90 	this->v[2]=C(0,2)*A[0];
91 	this->v[3]=C(1,0)*A[1];
92 	this->v[4]=C(1,1)*A[1];
93 	this->v[5]=C(1,2)*A[1];
94 	this->v[6]=C(2,0)*A[2];
95 	this->v[7]=C(2,1)*A[2];
96 	this->v[8]=C(2,2)*A[2];
97       } // end of Expr
98       /*!
99        * \brief access operator
100        * \param[in] i : line   index
101        * \param[in] j : column index
102        */
103       const value_type&
operator ()tfel::math::Expr104       operator()(const unsigned short i,
105 		 const unsigned short j) const
106       {
107 	return this->v[i*3+j];
108       } // end of operator()
109       /*!
110        * \return the runtime properties of this object
111        * In this case, the number of lines and columns
112        * are deduced from the template parameter
113        */
114       RunTimeProperties
getRunTimePropertiestfel::math::Expr115       getRunTimeProperties() const
116       {
117 	return RunTimeProperties();
118       }
119     }; // end of struct Expr<T2toT2ResultType,TensorProductRightDerivativeExpr<1u> >
120 
121     /*!
122      * Partial specialisation for 2D tensor
123      */
124     template<typename T2toT2ResultType>
125     struct Expr<T2toT2ResultType,TensorProductRightDerivativeExpr<2u> >
126       : public T2toT2Concept<Expr<T2toT2ResultType,TensorProductRightDerivativeExpr<2u> > >,
127 	public fsarray<25u,typename T2toT2Traits<T2toT2ResultType>::NumType>
128     {
129       //! a simple check
130       TFEL_STATIC_ASSERT(T2toT2Traits<T2toT2ResultType>::dime==2u);
131       //! a simple alias
132       typedef typename T2toT2Traits<T2toT2ResultType>::NumType value_type;
133       //! a simple alias
134       typedef EmptyRunTimeProperties RunTimeProperties;
135       /*!
136        * \param[in] A : second tensor of the product
137        */
138       template<typename TensorType>
Exprtfel::math::Expr139       Expr(const TensorType& A)
140       {
141 	//! a simple check
142 	TFEL_STATIC_ASSERT((tfel::meta::Implements<TensorType,TensorConcept>::cond));
143 	//! a simple check
144 	TFEL_STATIC_ASSERT((T2toT2Traits<T2toT2ResultType>::dime==TensorTraits<TensorType>::dime));
145 	//! a simple check
146 	TFEL_STATIC_ASSERT((tfel::typetraits::IsAssignableTo<typename TensorTraits<TensorType>::NumType,
147 							     typename T2toT2Traits<T2toT2ResultType>::NumType>::cond));
148 	this->v[0]  = A[0]; this->v[4]  = A[3];
149 	this->v[1]  = this->v[2]  = this->v[3]  = value_type(0);
150 	this->v[6]  = A[1]; this->v[8]  = A[4];
151 	this->v[5]  = this->v[7]  = this->v[9]  = value_type(0);
152 	this->v[12] = A[2];
153 	this->v[10] = this->v[11] = this->v[13] = this->v[14] = value_type(0);
154 	this->v[16] = A[3]; this->v[18]  = A[0];
155 	this->v[15] = this->v[17] = this->v[19]  = value_type(0);
156 	this->v[20] = A[4]; this->v[24]  = A[1];
157 	this->v[21] = this->v[22] = this->v[23]  = value_type(0);
158       } // end of Expr
159       /*!
160        * \param[in] A : first tensor of the product
161        * \param[in] C : derivative of the second tensor
162        */
163       template<typename TensorType,
164 	       typename T2toT2Type>
Exprtfel::math::Expr165       Expr(const TensorType& A,
166 	   const T2toT2Type& C)
167       {
168 	//! a simple check
169 	TFEL_STATIC_ASSERT((tfel::meta::Implements<TensorType,TensorConcept>::cond));
170 	//! a simple check
171 	TFEL_STATIC_ASSERT((tfel::meta::Implements<T2toT2Type,tfel::math::T2toT2Concept>::cond));
172 	//! a simple check
173 	TFEL_STATIC_ASSERT((T2toT2Traits<T2toT2ResultType>::dime==TensorTraits<TensorType>::dime));
174 	//! a simple check
175 	TFEL_STATIC_ASSERT((T2toT2Traits<T2toT2Type>::dime==TensorTraits<TensorType>::dime));
176 	//! a simple check
177 	TFEL_STATIC_ASSERT((tfel::typetraits::IsAssignableTo<typename ComputeBinaryResult<typename TensorTraits<TensorType>::NumType,
178 											  typename T2toT2Traits<T2toT2Type>::NumType,
179 											  OpMult>::Result,
180 							     typename T2toT2Traits<T2toT2ResultType>::NumType>::cond));
181 	this->v[0]=C(4,0)*A[3]+C(0,0)*A[0];
182 	this->v[1]=C(4,1)*A[3]+C(0,1)*A[0];
183 	this->v[2]=C(4,2)*A[3]+C(0,2)*A[0];
184 	this->v[3]=C(4,3)*A[3]+C(0,3)*A[0];
185 	this->v[4]=C(4,4)*A[3]+C(0,4)*A[0];
186 	this->v[5]=C(3,0)*A[4]+C(1,0)*A[1];
187 	this->v[6]=C(3,1)*A[4]+C(1,1)*A[1];
188 	this->v[7]=C(3,2)*A[4]+C(1,2)*A[1];
189 	this->v[8]=C(3,3)*A[4]+C(1,3)*A[1];
190 	this->v[9]=C(3,4)*A[4]+C(1,4)*A[1];
191 	this->v[10]=C(2,0)*A[2];
192 	this->v[11]=C(2,1)*A[2];
193 	this->v[12]=C(2,2)*A[2];
194 	this->v[13]=C(2,3)*A[2];
195 	this->v[14]=C(2,4)*A[2];
196 	this->v[15]=C(1,0)*A[3]+C(3,0)*A[0];
197 	this->v[16]=C(1,1)*A[3]+C(3,1)*A[0];
198 	this->v[17]=C(1,2)*A[3]+C(3,2)*A[0];
199 	this->v[18]=C(1,3)*A[3]+C(3,3)*A[0];
200 	this->v[19]=C(1,4)*A[3]+C(3,4)*A[0];
201 	this->v[20]=C(0,0)*A[4]+C(4,0)*A[1];
202 	this->v[21]=C(0,1)*A[4]+C(4,1)*A[1];
203 	this->v[22]=C(0,2)*A[4]+C(4,2)*A[1];
204 	this->v[23]=C(0,3)*A[4]+C(4,3)*A[1];
205 	this->v[24]=C(0,4)*A[4]+C(4,4)*A[1];
206       } // end of Expr
207       /*!
208        * \brief access operator
209        * \param[in] i : line   index
210        * \param[in] j : column index
211        */
212       const value_type&
operator ()tfel::math::Expr213       operator()(const unsigned short i,
214 		 const unsigned short j) const
215       {
216 	return this->v[i*5+j];
217       } // end of operator()
218       /*!
219        * \return the runtime properties of this object
220        * In this case, the number of lines and columns
221        * are deduced from the template parameter
222        */
223       RunTimeProperties
getRunTimePropertiestfel::math::Expr224       getRunTimeProperties() const
225       {
226 	return RunTimeProperties();
227       }
228     }; // end of struct Expr<T2toT2ResultType,TensorProductRightDerivativeExpr<1u> >
229 
230     /*!
231      * Partial specialisation for 3D tensor
232      */
233     template<typename T2toT2ResultType>
234     struct Expr<T2toT2ResultType,TensorProductRightDerivativeExpr<3u> >
235       : public T2toT2Concept<Expr<T2toT2ResultType,TensorProductRightDerivativeExpr<3u> > >,
236 	public fsarray<81u,typename T2toT2Traits<T2toT2ResultType>::NumType>
237     {
238       //! a simple check
239       TFEL_STATIC_ASSERT(T2toT2Traits<T2toT2ResultType>::dime==3u);
240       //! a simple alias
241       typedef typename T2toT2Traits<T2toT2ResultType>::NumType value_type;
242       //! a simple alias
243       typedef EmptyRunTimeProperties RunTimeProperties;
244       /*!
245        * \param[in] A : second tensor of the product
246        */
247       template<typename TensorType>
Exprtfel::math::Expr248       Expr(const TensorType& A)
249       {
250 	//! a simple check
251 	TFEL_STATIC_ASSERT((tfel::meta::Implements<TensorType,TensorConcept>::cond));
252 	//! a simple check
253 	TFEL_STATIC_ASSERT((T2toT2Traits<T2toT2ResultType>::dime==TensorTraits<TensorType>::dime));
254 	//! a simple check
255 	TFEL_STATIC_ASSERT((tfel::typetraits::IsAssignableTo<typename TensorTraits<TensorType>::NumType,
256 							     typename T2toT2Traits<T2toT2ResultType>::NumType>::cond));
257 	this->v[0]  = A[0]; this->v[4]  = A[3]; this->v[6] = A[5];
258 	this->v[1]  = this->v[2] = this->v[3] = this->v[5] = this->v[7] = this->v[8] =value_type(0);
259 	this->v[10] = A[1]; this->v[12] = A[4]; this->v[17] = A[7];
260 	this->v[9]  = this->v[11] = this->v[13] = this->v[14] = this->v[15] = this->v[16] = value_type(0);
261 	this->v[20] = A[2]; this->v[23] = A[6]; this->v[25]=A[8];
262 	this->v[18] = this->v[19] = this->v[21] = this->v[22] = this->v[24] = this->v[26] = value_type(0);
263 	this->v[28] = A[3]; this->v[30] = A[0]; this->v[35]=A[5];
264 	this->v[27] = this->v[29] = this->v[31] = this->v[32] = this->v[33] = this->v[34] = value_type(0);
265 	this->v[36] = A[4]; this->v[40] = A[1]; this->v[42]=A[7];
266 	this->v[37] = this->v[38] = this->v[39] = this->v[41] = this->v[43] = this->v[44] = value_type(0);
267 	this->v[47] = A[5]; this->v[50] = A[0]; this->v[52]=A[3];
268 	this->v[45] = this->v[46] = this->v[48] = this->v[49] = this->v[51] = this->v[53] = value_type(0);
269 	this->v[54] = A[6]; this->v[58] = A[8]; this->v[60]=A[2];
270 	this->v[55] = this->v[56] = this->v[57] = this->v[59] = this->v[61] = this->v[62] = value_type(0);
271 	this->v[65] = A[7]; this->v[68] = A[4]; this->v[70]=A[1];
272 	this->v[63] = this->v[64] = this->v[66] = this->v[67] = this->v[69] = this->v[71] = value_type(0);
273 	this->v[73] = A[8]; this->v[75] = A[6]; this->v[80]=A[2];
274 	this->v[72] = this->v[74] = this->v[76] = this->v[77] = this->v[78] = this->v[79] = value_type(0);
275       } // end of Expr
276       /*!
277        * \param[in] A : first tensor of the product
278        * \param[in] C : derivative of the second tensor
279        */
280       template<typename TensorType,
281 	       typename T2toT2Type>
Exprtfel::math::Expr282       Expr(const TensorType& A,
283 		 const T2toT2Type& C)
284       {
285 	//! a simple check
286 	TFEL_STATIC_ASSERT((tfel::meta::Implements<TensorType,TensorConcept>::cond));
287 	//! a simple check
288 	TFEL_STATIC_ASSERT((tfel::meta::Implements<T2toT2Type,tfel::math::T2toT2Concept>::cond));
289 	//! a simple check
290 	TFEL_STATIC_ASSERT((T2toT2Traits<T2toT2ResultType>::dime==TensorTraits<TensorType>::dime));
291 	//! a simple check
292 	TFEL_STATIC_ASSERT((T2toT2Traits<T2toT2Type>::dime==TensorTraits<TensorType>::dime));
293 	//! a simple check
294 	TFEL_STATIC_ASSERT((tfel::typetraits::IsAssignableTo<typename ComputeBinaryResult<typename TensorTraits<TensorType>::NumType,
295 											  typename T2toT2Traits<T2toT2Type>::NumType,
296 											  OpMult>::Result,
297 							     typename T2toT2Traits<T2toT2ResultType>::NumType>::cond));
298 	this->v[0] =C(6,0)*A[5]+C(4,0)*A[3]+C(0,0)*A[0];
299 	this->v[1] =C(6,1)*A[5]+C(4,1)*A[3]+C(0,1)*A[0];
300 	this->v[2] =C(6,2)*A[5]+C(4,2)*A[3]+C(0,2)*A[0];
301 	this->v[3] =C(6,3)*A[5]+C(4,3)*A[3]+C(0,3)*A[0];
302 	this->v[4] =C(6,4)*A[5]+C(4,4)*A[3]+C(0,4)*A[0];
303 	this->v[5] =C(6,5)*A[5]+C(4,5)*A[3]+C(0,5)*A[0];
304 	this->v[6] =C(6,6)*A[5]+C(4,6)*A[3]+C(0,6)*A[0];
305 	this->v[7] =C(6,7)*A[5]+C(4,7)*A[3]+C(0,7)*A[0];
306 	this->v[8] =C(6,8)*A[5]+C(4,8)*A[3]+C(0,8)*A[0];
307 	this->v[9] =C(8,0)*A[7]+C(3,0)*A[4]+C(1,0)*A[1];
308 	this->v[10]=C(8,1)*A[7]+C(3,1)*A[4]+C(1,1)*A[1];
309 	this->v[11]=C(8,2)*A[7]+C(3,2)*A[4]+C(1,2)*A[1];
310 	this->v[12]=C(8,3)*A[7]+C(3,3)*A[4]+C(1,3)*A[1];
311 	this->v[13]=C(8,4)*A[7]+C(3,4)*A[4]+C(1,4)*A[1];
312 	this->v[14]=C(8,5)*A[7]+C(3,5)*A[4]+C(1,5)*A[1];
313 	this->v[15]=C(8,6)*A[7]+C(3,6)*A[4]+C(1,6)*A[1];
314 	this->v[16]=C(8,7)*A[7]+C(3,7)*A[4]+C(1,7)*A[1];
315 	this->v[17]=C(8,8)*A[7]+C(3,8)*A[4]+C(1,8)*A[1];
316 	this->v[18]=C(7,0)*A[8]+C(5,0)*A[6]+C(2,0)*A[2];
317 	this->v[19]=C(7,1)*A[8]+C(5,1)*A[6]+C(2,1)*A[2];
318 	this->v[20]=C(7,2)*A[8]+C(5,2)*A[6]+C(2,2)*A[2];
319 	this->v[21]=C(7,3)*A[8]+C(5,3)*A[6]+C(2,3)*A[2];
320 	this->v[22]=C(7,4)*A[8]+C(5,4)*A[6]+C(2,4)*A[2];
321 	this->v[23]=C(7,5)*A[8]+C(5,5)*A[6]+C(2,5)*A[2];
322 	this->v[24]=C(7,6)*A[8]+C(5,6)*A[6]+C(2,6)*A[2];
323 	this->v[25]=C(7,7)*A[8]+C(5,7)*A[6]+C(2,7)*A[2];
324 	this->v[26]=C(7,8)*A[8]+C(5,8)*A[6]+C(2,8)*A[2];
325 	this->v[27]=C(8,0)*A[5]+C(1,0)*A[3]+C(3,0)*A[0];
326 	this->v[28]=C(8,1)*A[5]+C(1,1)*A[3]+C(3,1)*A[0];
327 	this->v[29]=C(8,2)*A[5]+C(1,2)*A[3]+C(3,2)*A[0];
328 	this->v[30]=C(8,3)*A[5]+C(1,3)*A[3]+C(3,3)*A[0];
329 	this->v[31]=C(8,4)*A[5]+C(1,4)*A[3]+C(3,4)*A[0];
330 	this->v[32]=C(8,5)*A[5]+C(1,5)*A[3]+C(3,5)*A[0];
331 	this->v[33]=C(8,6)*A[5]+C(1,6)*A[3]+C(3,6)*A[0];
332 	this->v[34]=C(8,7)*A[5]+C(1,7)*A[3]+C(3,7)*A[0];
333 	this->v[35]=C(8,8)*A[5]+C(1,8)*A[3]+C(3,8)*A[0];
334 	this->v[36]=C(6,0)*A[7]+C(0,0)*A[4]+C(4,0)*A[1];
335 	this->v[37]=C(6,1)*A[7]+C(0,1)*A[4]+C(4,1)*A[1];
336 	this->v[38]=C(6,2)*A[7]+C(0,2)*A[4]+C(4,2)*A[1];
337 	this->v[39]=C(6,3)*A[7]+C(0,3)*A[4]+C(4,3)*A[1];
338 	this->v[40]=C(6,4)*A[7]+C(0,4)*A[4]+C(4,4)*A[1];
339 	this->v[41]=C(6,5)*A[7]+C(0,5)*A[4]+C(4,5)*A[1];
340 	this->v[42]=C(6,6)*A[7]+C(0,6)*A[4]+C(4,6)*A[1];
341 	this->v[43]=C(6,7)*A[7]+C(0,7)*A[4]+C(4,7)*A[1];
342 	this->v[44]=C(6,8)*A[7]+C(0,8)*A[4]+C(4,8)*A[1];
343 	this->v[45]=C(2,0)*A[5]+C(7,0)*A[3]+C(5,0)*A[0];
344 	this->v[46]=C(2,1)*A[5]+C(7,1)*A[3]+C(5,1)*A[0];
345 	this->v[47]=C(2,2)*A[5]+C(7,2)*A[3]+C(5,2)*A[0];
346 	this->v[48]=C(2,3)*A[5]+C(7,3)*A[3]+C(5,3)*A[0];
347 	this->v[49]=C(2,4)*A[5]+C(7,4)*A[3]+C(5,4)*A[0];
348 	this->v[50]=C(2,5)*A[5]+C(7,5)*A[3]+C(5,5)*A[0];
349 	this->v[51]=C(2,6)*A[5]+C(7,6)*A[3]+C(5,6)*A[0];
350 	this->v[52]=C(2,7)*A[5]+C(7,7)*A[3]+C(5,7)*A[0];
351 	this->v[53]=C(2,8)*A[5]+C(7,8)*A[3]+C(5,8)*A[0];
352 	this->v[54]=C(4,0)*A[8]+C(0,0)*A[6]+C(6,0)*A[2];
353 	this->v[55]=C(4,1)*A[8]+C(0,1)*A[6]+C(6,1)*A[2];
354 	this->v[56]=C(4,2)*A[8]+C(0,2)*A[6]+C(6,2)*A[2];
355 	this->v[57]=C(4,3)*A[8]+C(0,3)*A[6]+C(6,3)*A[2];
356 	this->v[58]=C(4,4)*A[8]+C(0,4)*A[6]+C(6,4)*A[2];
357 	this->v[59]=C(4,5)*A[8]+C(0,5)*A[6]+C(6,5)*A[2];
358 	this->v[60]=C(4,6)*A[8]+C(0,6)*A[6]+C(6,6)*A[2];
359 	this->v[61]=C(4,7)*A[8]+C(0,7)*A[6]+C(6,7)*A[2];
360 	this->v[62]=C(4,8)*A[8]+C(0,8)*A[6]+C(6,8)*A[2];
361 	this->v[63]=C(2,0)*A[7]+C(5,0)*A[4]+C(7,0)*A[1];
362 	this->v[64]=C(2,1)*A[7]+C(5,1)*A[4]+C(7,1)*A[1];
363 	this->v[65]=C(2,2)*A[7]+C(5,2)*A[4]+C(7,2)*A[1];
364 	this->v[66]=C(2,3)*A[7]+C(5,3)*A[4]+C(7,3)*A[1];
365 	this->v[67]=C(2,4)*A[7]+C(5,4)*A[4]+C(7,4)*A[1];
366 	this->v[68]=C(2,5)*A[7]+C(5,5)*A[4]+C(7,5)*A[1];
367 	this->v[69]=C(2,6)*A[7]+C(5,6)*A[4]+C(7,6)*A[1];
368 	this->v[70]=C(2,7)*A[7]+C(5,7)*A[4]+C(7,7)*A[1];
369 	this->v[71]=C(2,8)*A[7]+C(5,8)*A[4]+C(7,8)*A[1];
370 	this->v[72]=C(1,0)*A[8]+C(3,0)*A[6]+C(8,0)*A[2];
371 	this->v[73]=C(1,1)*A[8]+C(3,1)*A[6]+C(8,1)*A[2];
372 	this->v[74]=C(1,2)*A[8]+C(3,2)*A[6]+C(8,2)*A[2];
373 	this->v[75]=C(1,3)*A[8]+C(3,3)*A[6]+C(8,3)*A[2];
374 	this->v[76]=C(1,4)*A[8]+C(3,4)*A[6]+C(8,4)*A[2];
375 	this->v[77]=C(1,5)*A[8]+C(3,5)*A[6]+C(8,5)*A[2];
376 	this->v[78]=C(1,6)*A[8]+C(3,6)*A[6]+C(8,6)*A[2];
377 	this->v[79]=C(1,7)*A[8]+C(3,7)*A[6]+C(8,7)*A[2];
378 	this->v[80]=C(1,8)*A[8]+C(3,8)*A[6]+C(8,8)*A[2];
379       } // end of Expr
380       /*!
381        * \brief access operator
382        * \param[in] i : line   index
383        * \param[in] j : column index
384        */
385       const value_type&
operator ()tfel::math::Expr386       operator()(const unsigned short i,
387 		 const unsigned short j) const
388       {
389 	return this->v[i*9+j];
390       } // end of operator()
391       /*!
392        * \return the runtime properties of this object
393        * In this case, the number of lines and columns
394        * are deduced from the template parameter
395        */
396       RunTimeProperties
getRunTimePropertiestfel::math::Expr397       getRunTimeProperties() const
398       {
399 	return RunTimeProperties();
400       }
401     }; // end of struct Expr<T2toT2ResultType,TensorProductRightDerivativeExpr<1u> >
402 
403   } // end of namespace tfel
404 
405 } // end of namespace math
406 
407 #endif /* LIB_TFEL_MATH_TENSORPRODUCTRIGHTDERIVATIVEEXPR_HXX */
408 
409