1#[cfg(test)]
2mod test;
3
4use super::*;
5use crate::math::{TensorRank1List, tensor_rank_1, tensor_rank_1_zero, tensor_rank_2};
6
7const G: usize = 4;
8const M: usize = 3;
9const N: usize = 10;
10const P: usize = 12;
11const Q: usize = 4;
12
13pub type Tetrahedron<'a, C> = Element<'a, C, G, N>;
14
15impl<'a, C> FiniteElement<'a, C, G, N> for Tetrahedron<'a, C> {
16 fn new(
17 constitutive_model: &'a C,
18 reference_nodal_coordinates: ReferenceNodalCoordinates<N>,
19 ) -> Self {
20 let (gradient_vectors, integration_weights) = Self::initialize(reference_nodal_coordinates);
21 Self {
22 constitutive_model,
23 gradient_vectors,
24 integration_weights,
25 }
26 }
27 fn reference() -> ReferenceNodalCoordinates<N> {
28 ReferenceNodalCoordinates::const_from([
29 tensor_rank_1([0.0, 0.0, 0.0]),
30 tensor_rank_1([1.0, 0.0, 0.0]),
31 tensor_rank_1([0.0, 1.0, 0.0]),
32 tensor_rank_1([0.0, 0.0, 1.0]),
33 tensor_rank_1([0.25, 0.25, 0.0]),
34 tensor_rank_1([0.25, 0.0, 0.25]),
35 tensor_rank_1([0.0, 0.25, 0.25]),
36 tensor_rank_1([0.5, 0.5, 0.0]),
37 tensor_rank_1([0.5, 0.0, 0.5]),
38 tensor_rank_1([0.0, 0.5, 0.5]),
39 ])
40 }
41 fn reset(&mut self) {
42 let (gradient_vectors, integration_weights) = Self::initialize(Self::reference());
43 self.gradient_vectors = gradient_vectors;
44 self.integration_weights = integration_weights;
45 }
46}
47
48impl<'a, C> Tetrahedron<'a, C> {
49 fn initialize(
50 reference_nodal_coordinates: ReferenceNodalCoordinates<N>,
51 ) -> (GradientVectors<G, N>, Scalars<G>) {
52 let gradient_vectors = Self::projected_gradient_vectors(&reference_nodal_coordinates);
53 let integration_weights =
54 Self::reference_jacobians(&reference_nodal_coordinates) * Self::integration_weight();
55 (gradient_vectors, integration_weights)
56 }
57 const fn integration_weight() -> Scalar {
58 1.0 / 24.0
59 }
60 const fn inverse_normalized_projection_matrix() -> NormalizedProjectionMatrix<Q> {
61 const DIAG: Scalar = 4.0 / 640.0;
62 const OFF: Scalar = -1.0 / 640.0;
63 tensor_rank_2([
64 tensor_rank_1([DIAG, OFF, OFF, OFF]),
65 tensor_rank_1([OFF, DIAG, OFF, OFF]),
66 tensor_rank_1([OFF, OFF, DIAG, OFF]),
67 tensor_rank_1([OFF, OFF, OFF, DIAG]),
68 ])
69 }
70 fn inverse_projection_matrix(
71 reference_jacobians_subelements: &Scalars<P>,
72 ) -> NormalizedProjectionMatrix<Q> {
73 Self::shape_function_integrals_products()
74 .iter()
75 .zip(reference_jacobians_subelements.iter())
76 .map(
77 |(shape_function_integrals_products, reference_jacobian_subelement)| {
78 shape_function_integrals_products * reference_jacobian_subelement
79 },
80 )
81 .sum::<ProjectionMatrix<Q>>()
82 .inverse()
83 }
84 fn projected_gradient_vectors(
85 reference_nodal_coordinates: &ReferenceNodalCoordinates<N>,
86 ) -> GradientVectors<G, N> {
87 let parametric_gradient_operators = Self::standard_gradient_operators()
88 .iter()
89 .map(|standard_gradient_operator| {
90 reference_nodal_coordinates * standard_gradient_operator
91 })
92 .collect::<ParametricGradientOperators<P>>();
93 let reference_jacobians_subelements =
94 Self::reference_jacobians_subelements(reference_nodal_coordinates);
95 let inverse_projection_matrix =
96 Self::inverse_projection_matrix(&reference_jacobians_subelements);
97 Self::shape_functions_at_integration_points()
98 .iter()
99 .map(|shape_functions_at_integration_point| {
100 Self::standard_gradient_operators_transposed()
101 .iter()
102 .map(|standard_gradient_operators_a| {
103 Self::shape_function_integrals()
104 .iter()
105 .zip(
106 standard_gradient_operators_a.iter().zip(
107 parametric_gradient_operators
108 .iter()
109 .zip(reference_jacobians_subelements.iter()),
110 ),
111 )
112 .map(
113 |(
114 shape_function_integral,
115 (
116 standard_gradient_operator,
117 (
118 parametric_gradient_operator,
119 reference_jacobian_subelement,
120 ),
121 ),
122 )| {
123 (parametric_gradient_operator.inverse_transpose()
124 * standard_gradient_operator)
125 * reference_jacobian_subelement
126 * (shape_functions_at_integration_point
127 * (&inverse_projection_matrix
128 * shape_function_integral))
129 },
130 )
131 .sum()
132 })
133 .collect()
134 })
135 .collect()
136 }
137 fn reference_jacobians(
138 reference_nodal_coordinates: &ReferenceNodalCoordinates<N>,
139 ) -> Scalars<G> {
140 let vector = Self::inverse_normalized_projection_matrix()
141 * Self::shape_function_integrals()
142 .iter()
143 .zip(Self::reference_jacobians_subelements(reference_nodal_coordinates).iter())
144 .map(|(shape_function_integral, reference_jacobian_subelement)| {
145 shape_function_integral * reference_jacobian_subelement
146 })
147 .sum::<TensorRank1<Q, 9>>();
148 Self::shape_functions_at_integration_points()
149 .iter()
150 .map(|shape_functions_at_integration_point| {
151 shape_functions_at_integration_point * &vector
152 })
153 .collect()
154 }
155 fn reference_jacobians_subelements(
156 reference_nodal_coordinates: &ReferenceNodalCoordinates<N>,
157 ) -> Scalars<P> {
158 Self::standard_gradient_operators()
159 .iter()
160 .map(|standard_gradient_operator| {
161 reference_nodal_coordinates * standard_gradient_operator
162 })
163 .collect::<ParametricGradientOperators<P>>()
164 .iter()
165 .map(|parametric_gradient_operator| parametric_gradient_operator.determinant())
166 .collect()
167 }
168 const fn shape_functions_at_integration_points() -> ShapeFunctionsAtIntegrationPoints<G, Q> {
169 const DIAG: Scalar = 0.585_410_196_624_968_5;
170 const OFF: Scalar = 0.138_196_601_125_010_5;
171 ShapeFunctionsAtIntegrationPoints::const_from([
172 tensor_rank_1([DIAG, OFF, OFF, OFF]),
173 tensor_rank_1([OFF, DIAG, OFF, OFF]),
174 tensor_rank_1([OFF, OFF, DIAG, OFF]),
175 tensor_rank_1([OFF, OFF, OFF, DIAG]),
176 ])
177 }
178 const fn shape_function_integrals() -> ShapeFunctionIntegrals<P, Q> {
179 ShapeFunctionIntegrals::const_from([
180 tensor_rank_1([200.0, 40.0, 40.0, 40.0]),
181 tensor_rank_1([40.0, 200.0, 40.0, 40.0]),
182 tensor_rank_1([40.0, 40.0, 200.0, 40.0]),
183 tensor_rank_1([40.0, 40.0, 40.0, 200.0]),
184 tensor_rank_1([30.0, 70.0, 30.0, 30.0]),
185 tensor_rank_1([10.0, 50.0, 50.0, 50.0]),
186 tensor_rank_1([30.0, 30.0, 30.0, 70.0]),
187 tensor_rank_1([50.0, 50.0, 10.0, 50.0]),
188 tensor_rank_1([50.0, 50.0, 50.0, 10.0]),
189 tensor_rank_1([30.0, 30.0, 70.0, 30.0]),
190 tensor_rank_1([50.0, 10.0, 50.0, 50.0]),
191 tensor_rank_1([70.0, 30.0, 30.0, 30.0]),
192 ])
193 }
194 const fn shape_function_integrals_products() -> ShapeFunctionIntegralsProducts<P, Q> {
195 ShapeFunctionIntegralsProducts::const_from([
196 tensor_rank_2([
197 tensor_rank_1([128.0, 24.0, 24.0, 24.0]),
198 tensor_rank_1([24.0, 8.0, 4.0, 4.0]),
199 tensor_rank_1([24.0, 4.0, 8.0, 4.0]),
200 tensor_rank_1([24.0, 4.0, 4.0, 8.0]),
201 ]),
202 tensor_rank_2([
203 tensor_rank_1([8.0, 24.0, 4.0, 4.0]),
204 tensor_rank_1([24.0, 128.0, 24.0, 24.0]),
205 tensor_rank_1([4.0, 24.0, 8.0, 4.0]),
206 tensor_rank_1([4.0, 24.0, 4.0, 8.0]),
207 ]),
208 tensor_rank_2([
209 tensor_rank_1([8.0, 4.0, 24.0, 4.0]),
210 tensor_rank_1([4.0, 8.0, 24.0, 4.0]),
211 tensor_rank_1([24.0, 24.0, 128.0, 24.0]),
212 tensor_rank_1([4.0, 4.0, 24.0, 8.0]),
213 ]),
214 tensor_rank_2([
215 tensor_rank_1([8.0, 4.0, 4.0, 24.0]),
216 tensor_rank_1([4.0, 8.0, 4.0, 24.0]),
217 tensor_rank_1([4.0, 4.0, 8.0, 24.0]),
218 tensor_rank_1([24.0, 24.0, 24.0, 128.0]),
219 ]),
220 tensor_rank_2([
221 tensor_rank_1([7.0, 13.0, 5.0, 5.0]),
222 tensor_rank_1([13.0, 31.0, 13.0, 13.0]),
223 tensor_rank_1([5.0, 13.0, 7.0, 5.0]),
224 tensor_rank_1([5.0, 13.0, 5.0, 7.0]),
225 ]),
226 tensor_rank_2([
227 tensor_rank_1([1.0, 3.0, 3.0, 3.0]),
228 tensor_rank_1([3.0, 17.0, 15.0, 15.0]),
229 tensor_rank_1([3.0, 15.0, 17.0, 15.0]),
230 tensor_rank_1([3.0, 15.0, 15.0, 17.0]),
231 ]),
232 tensor_rank_2([
233 tensor_rank_1([7.0, 5.0, 5.0, 13.0]),
234 tensor_rank_1([5.0, 7.0, 5.0, 13.0]),
235 tensor_rank_1([5.0, 5.0, 7.0, 13.0]),
236 tensor_rank_1([13.0, 13.0, 13.0, 31.0]),
237 ]),
238 tensor_rank_2([
239 tensor_rank_1([17.0, 15.0, 3.0, 15.0]),
240 tensor_rank_1([15.0, 17.0, 3.0, 15.0]),
241 tensor_rank_1([3.0, 3.0, 1.0, 3.0]),
242 tensor_rank_1([15.0, 15.0, 3.0, 17.0]),
243 ]),
244 tensor_rank_2([
245 tensor_rank_1([17.0, 15.0, 15.0, 3.0]),
246 tensor_rank_1([15.0, 17.0, 15.0, 3.0]),
247 tensor_rank_1([15.0, 15.0, 17.0, 3.0]),
248 tensor_rank_1([3.0, 3.0, 3.0, 1.0]),
249 ]),
250 tensor_rank_2([
251 tensor_rank_1([7.0, 5.0, 13.0, 5.0]),
252 tensor_rank_1([5.0, 7.0, 13.0, 5.0]),
253 tensor_rank_1([13.0, 13.0, 31.0, 13.0]),
254 tensor_rank_1([5.0, 5.0, 13.0, 7.0]),
255 ]),
256 tensor_rank_2([
257 tensor_rank_1([17.0, 3.0, 15.0, 15.0]),
258 tensor_rank_1([3.0, 1.0, 3.0, 3.0]),
259 tensor_rank_1([15.0, 3.0, 17.0, 15.0]),
260 tensor_rank_1([15.0, 3.0, 15.0, 17.0]),
261 ]),
262 tensor_rank_2([
263 tensor_rank_1([31.0, 13.0, 13.0, 13.0]),
264 tensor_rank_1([13.0, 7.0, 5.0, 5.0]),
265 tensor_rank_1([13.0, 5.0, 7.0, 5.0]),
266 tensor_rank_1([13.0, 5.0, 5.0, 7.0]),
267 ]),
268 ])
269 }
270 const fn standard_gradient_operators() -> StandardGradientOperators<M, N, P> {
271 const TWO_THIRDS: Scalar = 2.0 / 3.0;
272 const FOUR_THIRDS: Scalar = 4.0 / 3.0;
273 StandardGradientOperators::const_from([
274 TensorRank1List::const_from([
275 tensor_rank_1([-2.0, -2.0, -2.0]),
276 tensor_rank_1_zero(),
277 tensor_rank_1_zero(),
278 tensor_rank_1_zero(),
279 tensor_rank_1([2.0, 0.0, 0.0]),
280 tensor_rank_1_zero(),
281 tensor_rank_1([0.0, 2.0, 0.0]),
282 tensor_rank_1([0.0, 0.0, 2.0]),
283 tensor_rank_1_zero(),
284 tensor_rank_1_zero(),
285 ]),
286 TensorRank1List::const_from([
287 tensor_rank_1_zero(),
288 tensor_rank_1([2.0, 0.0, 0.0]),
289 tensor_rank_1_zero(),
290 tensor_rank_1_zero(),
291 tensor_rank_1([-2.0, -2.0, -2.0]),
292 tensor_rank_1([0.0, 2.0, 0.0]),
293 tensor_rank_1_zero(),
294 tensor_rank_1_zero(),
295 tensor_rank_1([0.0, 0.0, 2.0]),
296 tensor_rank_1_zero(),
297 ]),
298 TensorRank1List::const_from([
299 tensor_rank_1_zero(),
300 tensor_rank_1_zero(),
301 tensor_rank_1([0.0, 2.0, 0.0]),
302 tensor_rank_1_zero(),
303 tensor_rank_1_zero(),
304 tensor_rank_1([2.0, 0.0, 0.0]),
305 tensor_rank_1([-2.0, -2.0, -2.0]),
306 tensor_rank_1_zero(),
307 tensor_rank_1_zero(),
308 tensor_rank_1([0.0, 0.0, 2.0]),
309 ]),
310 TensorRank1List::const_from([
311 tensor_rank_1_zero(),
312 tensor_rank_1_zero(),
313 tensor_rank_1_zero(),
314 tensor_rank_1([0.0, 0.0, 2.0]),
315 tensor_rank_1_zero(),
316 tensor_rank_1_zero(),
317 tensor_rank_1_zero(),
318 tensor_rank_1([-2.0, -2.0, -2.0]),
319 tensor_rank_1([2.0, 0.0, 0.0]),
320 tensor_rank_1([0.0, 2.0, 0.0]),
321 ]),
322 TensorRank1List::const_from([
323 tensor_rank_1_zero(),
324 tensor_rank_1_zero(),
325 tensor_rank_1_zero(),
326 tensor_rank_1_zero(),
327 tensor_rank_1([-TWO_THIRDS, -2.0, -2.0]),
328 tensor_rank_1([FOUR_THIRDS, 2.0, 0.0]),
329 tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
330 tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
331 tensor_rank_1([FOUR_THIRDS, 0.0, 2.0]),
332 tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
333 ]),
334 TensorRank1List::const_from([
335 tensor_rank_1_zero(),
336 tensor_rank_1_zero(),
337 tensor_rank_1_zero(),
338 tensor_rank_1_zero(),
339 tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
340 tensor_rank_1([FOUR_THIRDS, FOUR_THIRDS, -TWO_THIRDS]),
341 tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
342 tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
343 tensor_rank_1([FOUR_THIRDS, -TWO_THIRDS, FOUR_THIRDS]),
344 tensor_rank_1([-TWO_THIRDS, FOUR_THIRDS, FOUR_THIRDS]),
345 ]),
346 TensorRank1List::const_from([
347 tensor_rank_1_zero(),
348 tensor_rank_1_zero(),
349 tensor_rank_1_zero(),
350 tensor_rank_1_zero(),
351 tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
352 tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
353 tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
354 tensor_rank_1([-2.0, -2.0, -TWO_THIRDS]),
355 tensor_rank_1([2.0, 0.0, FOUR_THIRDS]),
356 tensor_rank_1([0.0, 2.0, FOUR_THIRDS]),
357 ]),
358 TensorRank1List::const_from([
359 tensor_rank_1_zero(),
360 tensor_rank_1_zero(),
361 tensor_rank_1_zero(),
362 tensor_rank_1_zero(),
363 tensor_rank_1([0.0, -FOUR_THIRDS, -2.0]),
364 tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
365 tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
366 tensor_rank_1([-2.0, -FOUR_THIRDS, 0.0]),
367 tensor_rank_1([2.0, TWO_THIRDS, 2.0]),
368 tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
369 ]),
370 TensorRank1List::const_from([
371 tensor_rank_1_zero(),
372 tensor_rank_1_zero(),
373 tensor_rank_1_zero(),
374 tensor_rank_1_zero(),
375 tensor_rank_1([0.0, -2.0, -FOUR_THIRDS]),
376 tensor_rank_1([2.0, 2.0, TWO_THIRDS]),
377 tensor_rank_1([-2.0, 0.0, -FOUR_THIRDS]),
378 tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
379 tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
380 tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
381 ]),
382 TensorRank1List::const_from([
383 tensor_rank_1_zero(),
384 tensor_rank_1_zero(),
385 tensor_rank_1_zero(),
386 tensor_rank_1_zero(),
387 tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
388 tensor_rank_1([2.0, FOUR_THIRDS, 0.0]),
389 tensor_rank_1([-2.0, -TWO_THIRDS, -2.0]),
390 tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
391 tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
392 tensor_rank_1([0.0, FOUR_THIRDS, 2.0]),
393 ]),
394 TensorRank1List::const_from([
395 tensor_rank_1_zero(),
396 tensor_rank_1_zero(),
397 tensor_rank_1_zero(),
398 tensor_rank_1_zero(),
399 tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
400 tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
401 tensor_rank_1([-FOUR_THIRDS, 0.0, -2.0]),
402 tensor_rank_1([-FOUR_THIRDS, -2.0, 0.0]),
403 tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
404 tensor_rank_1([TWO_THIRDS, 2.0, 2.0]),
405 ]),
406 TensorRank1List::const_from([
407 tensor_rank_1_zero(),
408 tensor_rank_1_zero(),
409 tensor_rank_1_zero(),
410 tensor_rank_1_zero(),
411 tensor_rank_1([TWO_THIRDS, -FOUR_THIRDS, -FOUR_THIRDS]),
412 tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
413 tensor_rank_1([-FOUR_THIRDS, TWO_THIRDS, -FOUR_THIRDS]),
414 tensor_rank_1([-FOUR_THIRDS, -FOUR_THIRDS, TWO_THIRDS]),
415 tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
416 tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
417 ]),
418 ])
419 }
420 const fn standard_gradient_operators_transposed() -> StandardGradientOperatorsTransposed<M, N, P>
421 {
422 const TWO_THIRDS: Scalar = 2.0 / 3.0;
423 const FOUR_THIRDS: Scalar = 4.0 / 3.0;
424 StandardGradientOperators::const_from([
425 TensorRank1List::const_from([
426 tensor_rank_1([-2.0, -2.0, -2.0]),
427 tensor_rank_1_zero(),
428 tensor_rank_1_zero(),
429 tensor_rank_1_zero(),
430 tensor_rank_1_zero(),
431 tensor_rank_1_zero(),
432 tensor_rank_1_zero(),
433 tensor_rank_1_zero(),
434 tensor_rank_1_zero(),
435 tensor_rank_1_zero(),
436 tensor_rank_1_zero(),
437 tensor_rank_1_zero(),
438 ]),
439 TensorRank1List::const_from([
440 tensor_rank_1_zero(),
441 tensor_rank_1([2.0, 0.0, 0.0]),
442 tensor_rank_1_zero(),
443 tensor_rank_1_zero(),
444 tensor_rank_1_zero(),
445 tensor_rank_1_zero(),
446 tensor_rank_1_zero(),
447 tensor_rank_1_zero(),
448 tensor_rank_1_zero(),
449 tensor_rank_1_zero(),
450 tensor_rank_1_zero(),
451 tensor_rank_1_zero(),
452 ]),
453 TensorRank1List::const_from([
454 tensor_rank_1_zero(),
455 tensor_rank_1_zero(),
456 tensor_rank_1([0.0, 2.0, 0.0]),
457 tensor_rank_1_zero(),
458 tensor_rank_1_zero(),
459 tensor_rank_1_zero(),
460 tensor_rank_1_zero(),
461 tensor_rank_1_zero(),
462 tensor_rank_1_zero(),
463 tensor_rank_1_zero(),
464 tensor_rank_1_zero(),
465 tensor_rank_1_zero(),
466 ]),
467 TensorRank1List::const_from([
468 tensor_rank_1_zero(),
469 tensor_rank_1_zero(),
470 tensor_rank_1_zero(),
471 tensor_rank_1([0.0, 0.0, 2.0]),
472 tensor_rank_1_zero(),
473 tensor_rank_1_zero(),
474 tensor_rank_1_zero(),
475 tensor_rank_1_zero(),
476 tensor_rank_1_zero(),
477 tensor_rank_1_zero(),
478 tensor_rank_1_zero(),
479 tensor_rank_1_zero(),
480 ]),
481 TensorRank1List::const_from([
482 tensor_rank_1([2.0, 0.0, 0.0]),
483 tensor_rank_1([-2.0, -2.0, -2.0]),
484 tensor_rank_1_zero(),
485 tensor_rank_1_zero(),
486 tensor_rank_1([-TWO_THIRDS, -2.0, -2.0]),
487 tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
488 tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
489 tensor_rank_1([0.0, -FOUR_THIRDS, -2.0]),
490 tensor_rank_1([0.0, -2.0, -FOUR_THIRDS]),
491 tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
492 tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
493 tensor_rank_1([TWO_THIRDS, -FOUR_THIRDS, -FOUR_THIRDS]),
494 ]),
495 TensorRank1List::const_from([
496 tensor_rank_1_zero(),
497 tensor_rank_1([0.0, 2.0, 0.0]),
498 tensor_rank_1([2.0, 0.0, 0.0]),
499 tensor_rank_1_zero(),
500 tensor_rank_1([FOUR_THIRDS, 2.0, 0.0]),
501 tensor_rank_1([FOUR_THIRDS, FOUR_THIRDS, -TWO_THIRDS]),
502 tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
503 tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
504 tensor_rank_1([2.0, 2.0, TWO_THIRDS]),
505 tensor_rank_1([2.0, FOUR_THIRDS, 0.0]),
506 tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
507 tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
508 ]),
509 TensorRank1List::const_from([
510 tensor_rank_1([0.0, 2.0, 0.0]),
511 tensor_rank_1_zero(),
512 tensor_rank_1([-2.0, -2.0, -2.0]),
513 tensor_rank_1_zero(),
514 tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
515 tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
516 tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
517 tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
518 tensor_rank_1([-2.0, 0.0, -FOUR_THIRDS]),
519 tensor_rank_1([-2.0, -TWO_THIRDS, -2.0]),
520 tensor_rank_1([-FOUR_THIRDS, 0.0, -2.0]),
521 tensor_rank_1([-FOUR_THIRDS, TWO_THIRDS, -FOUR_THIRDS]),
522 ]),
523 TensorRank1List::const_from([
524 tensor_rank_1([0.0, 0.0, 2.0]),
525 tensor_rank_1_zero(),
526 tensor_rank_1_zero(),
527 tensor_rank_1([-2.0, -2.0, -2.0]),
528 tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
529 tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
530 tensor_rank_1([-2.0, -2.0, -TWO_THIRDS]),
531 tensor_rank_1([-2.0, -FOUR_THIRDS, 0.0]),
532 tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
533 tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
534 tensor_rank_1([-FOUR_THIRDS, -2.0, 0.0]),
535 tensor_rank_1([-FOUR_THIRDS, -FOUR_THIRDS, TWO_THIRDS]),
536 ]),
537 TensorRank1List::const_from([
538 tensor_rank_1_zero(),
539 tensor_rank_1([0.0, 0.0, 2.0]),
540 tensor_rank_1_zero(),
541 tensor_rank_1([2.0, 0.0, 0.0]),
542 tensor_rank_1([FOUR_THIRDS, 0.0, 2.0]),
543 tensor_rank_1([FOUR_THIRDS, -TWO_THIRDS, FOUR_THIRDS]),
544 tensor_rank_1([2.0, 0.0, FOUR_THIRDS]),
545 tensor_rank_1([2.0, TWO_THIRDS, 2.0]),
546 tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
547 tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
548 tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
549 tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
550 ]),
551 TensorRank1List::const_from([
552 tensor_rank_1_zero(),
553 tensor_rank_1_zero(),
554 tensor_rank_1([0.0, 0.0, 2.0]),
555 tensor_rank_1([0.0, 2.0, 0.0]),
556 tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
557 tensor_rank_1([-TWO_THIRDS, FOUR_THIRDS, FOUR_THIRDS]),
558 tensor_rank_1([0.0, 2.0, FOUR_THIRDS]),
559 tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
560 tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
561 tensor_rank_1([0.0, FOUR_THIRDS, 2.0]),
562 tensor_rank_1([TWO_THIRDS, 2.0, 2.0]),
563 tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
564 ]),
565 ])
566 }
567}