conspire/fem/block/element/composite/tetrahedron/
mod.rs

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}