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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
#[cfg(test)]
mod test;

use super::*;
use crate::math::{
    tensor_rank_1, tensor_rank_1_list, tensor_rank_1_list_2d, tensor_rank_1_zero, tensor_rank_2,
    tensor_rank_2_list,
};

const G: usize = 4;
const M: usize = 3;
const N: usize = 10;
const P: usize = 12;
const Q: usize = 4;

pub type Tetrahedron<C> = Element<C, G, N>;

impl<'a, C> FiniteElement<'a, C, G, N> for Tetrahedron<C>
where
    C: Constitutive<'a>,
{
    fn new(
        constitutive_model_parameters: Parameters<'a>,
        reference_nodal_coordinates: ReferenceNodalCoordinates<N>,
    ) -> Self {
        Self {
            constitutive_models: from_fn(|_| <C>::new(constitutive_model_parameters)),
            gradient_vectors: Self::projected_gradient_vectors(&reference_nodal_coordinates),
            integration_weights: Self::reference_jacobians(&reference_nodal_coordinates)
                * Self::integration_weight(),
        }
    }
}

impl<'a, C> Tetrahedron<C>
where
    C: Constitutive<'a>,
{
    const fn integration_weight() -> Scalar {
        1.0 / 24.0
    }
    const fn inverse_normalized_projection_matrix() -> NormalizedProjectionMatrix<Q> {
        const DIAG: Scalar = 4.0 / 640.0;
        const OFF: Scalar = -1.0 / 640.0;
        tensor_rank_2([
            tensor_rank_1([DIAG, OFF, OFF, OFF]),
            tensor_rank_1([OFF, DIAG, OFF, OFF]),
            tensor_rank_1([OFF, OFF, DIAG, OFF]),
            tensor_rank_1([OFF, OFF, OFF, DIAG]),
        ])
    }
    fn inverse_projection_matrix(
        reference_jacobians_subelements: &Scalars<P>,
    ) -> NormalizedProjectionMatrix<Q> {
        Self::shape_function_integrals_products()
            .iter()
            .zip(reference_jacobians_subelements.iter())
            .map(
                |(shape_function_integrals_products, reference_jacobian_subelement)| {
                    shape_function_integrals_products * reference_jacobian_subelement
                },
            )
            .sum::<ProjectionMatrix<Q>>()
            .inverse()
    }
    fn projected_gradient_vectors(
        reference_nodal_coordinates: &ReferenceNodalCoordinates<N>,
    ) -> GradientVectors<G, N> {
        let parametric_gradient_operators = Self::standard_gradient_operators()
            .iter()
            .map(|standard_gradient_operator| {
                reference_nodal_coordinates * standard_gradient_operator
            })
            .collect::<ParametricGradientOperators<P>>();
        let reference_jacobians_subelements =
            Self::reference_jacobians_subelements(reference_nodal_coordinates);
        let inverse_projection_matrix =
            Self::inverse_projection_matrix(&reference_jacobians_subelements);
        Self::shape_functions_at_integration_points()
            .iter()
            .map(|shape_functions_at_integration_point| {
                Self::standard_gradient_operators_transposed()
                    .iter()
                    .map(|standard_gradient_operators_a| {
                        Self::shape_function_integrals()
                            .iter()
                            .zip(
                                standard_gradient_operators_a.iter().zip(
                                    parametric_gradient_operators
                                        .iter()
                                        .zip(reference_jacobians_subelements.iter()),
                                ),
                            )
                            .map(
                                |(
                                    shape_function_integral,
                                    (
                                        standard_gradient_operator,
                                        (
                                            parametric_gradient_operator,
                                            reference_jacobian_subelement,
                                        ),
                                    ),
                                )| {
                                    (parametric_gradient_operator.inverse_transpose()
                                        * standard_gradient_operator)
                                        * reference_jacobian_subelement
                                        * (shape_functions_at_integration_point
                                            * (&inverse_projection_matrix
                                                * shape_function_integral))
                                },
                            )
                            .sum()
                    })
                    .collect()
            })
            .collect()
    }
    fn reference_jacobians(
        reference_nodal_coordinates: &ReferenceNodalCoordinates<N>,
    ) -> Scalars<G> {
        let vector = Self::inverse_normalized_projection_matrix()
            * Self::shape_function_integrals()
                .iter()
                .zip(Self::reference_jacobians_subelements(reference_nodal_coordinates).iter())
                .map(|(shape_function_integral, reference_jacobian_subelement)| {
                    shape_function_integral * reference_jacobian_subelement
                })
                .sum::<TensorRank1<Q, 9>>();
        Self::shape_functions_at_integration_points()
            .iter()
            .map(|shape_functions_at_integration_point| {
                shape_functions_at_integration_point * &vector
            })
            .collect()
    }
    fn reference_jacobians_subelements(
        reference_nodal_coordinates: &ReferenceNodalCoordinates<N>,
    ) -> Scalars<P> {
        Self::standard_gradient_operators()
            .iter()
            .map(|standard_gradient_operator| {
                reference_nodal_coordinates * standard_gradient_operator
            })
            .collect::<ParametricGradientOperators<P>>()
            .iter()
            .map(|parametric_gradient_operator| parametric_gradient_operator.determinant())
            .collect()
    }
    const fn shape_functions_at_integration_points() -> ShapeFunctionsAtIntegrationPoints<G, Q> {
        const DIAG: Scalar = 0.585_410_196_624_968_5;
        const OFF: Scalar = 0.138_196_601_125_010_5;
        tensor_rank_1_list([
            tensor_rank_1([DIAG, OFF, OFF, OFF]),
            tensor_rank_1([OFF, DIAG, OFF, OFF]),
            tensor_rank_1([OFF, OFF, DIAG, OFF]),
            tensor_rank_1([OFF, OFF, OFF, DIAG]),
        ])
    }
    const fn shape_function_integrals() -> ShapeFunctionIntegrals<P, Q> {
        tensor_rank_1_list([
            tensor_rank_1([200.0, 40.0, 40.0, 40.0]),
            tensor_rank_1([40.0, 200.0, 40.0, 40.0]),
            tensor_rank_1([40.0, 40.0, 200.0, 40.0]),
            tensor_rank_1([40.0, 40.0, 40.0, 200.0]),
            tensor_rank_1([30.0, 70.0, 30.0, 30.0]),
            tensor_rank_1([10.0, 50.0, 50.0, 50.0]),
            tensor_rank_1([30.0, 30.0, 30.0, 70.0]),
            tensor_rank_1([50.0, 50.0, 10.0, 50.0]),
            tensor_rank_1([50.0, 50.0, 50.0, 10.0]),
            tensor_rank_1([30.0, 30.0, 70.0, 30.0]),
            tensor_rank_1([50.0, 10.0, 50.0, 50.0]),
            tensor_rank_1([70.0, 30.0, 30.0, 30.0]),
        ])
    }
    const fn shape_function_integrals_products() -> ShapeFunctionIntegralsProducts<P, Q> {
        tensor_rank_2_list([
            tensor_rank_2([
                tensor_rank_1([128.0, 24.0, 24.0, 24.0]),
                tensor_rank_1([24.0, 8.0, 4.0, 4.0]),
                tensor_rank_1([24.0, 4.0, 8.0, 4.0]),
                tensor_rank_1([24.0, 4.0, 4.0, 8.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([8.0, 24.0, 4.0, 4.0]),
                tensor_rank_1([24.0, 128.0, 24.0, 24.0]),
                tensor_rank_1([4.0, 24.0, 8.0, 4.0]),
                tensor_rank_1([4.0, 24.0, 4.0, 8.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([8.0, 4.0, 24.0, 4.0]),
                tensor_rank_1([4.0, 8.0, 24.0, 4.0]),
                tensor_rank_1([24.0, 24.0, 128.0, 24.0]),
                tensor_rank_1([4.0, 4.0, 24.0, 8.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([8.0, 4.0, 4.0, 24.0]),
                tensor_rank_1([4.0, 8.0, 4.0, 24.0]),
                tensor_rank_1([4.0, 4.0, 8.0, 24.0]),
                tensor_rank_1([24.0, 24.0, 24.0, 128.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([7.0, 13.0, 5.0, 5.0]),
                tensor_rank_1([13.0, 31.0, 13.0, 13.0]),
                tensor_rank_1([5.0, 13.0, 7.0, 5.0]),
                tensor_rank_1([5.0, 13.0, 5.0, 7.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([1.0, 3.0, 3.0, 3.0]),
                tensor_rank_1([3.0, 17.0, 15.0, 15.0]),
                tensor_rank_1([3.0, 15.0, 17.0, 15.0]),
                tensor_rank_1([3.0, 15.0, 15.0, 17.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([7.0, 5.0, 5.0, 13.0]),
                tensor_rank_1([5.0, 7.0, 5.0, 13.0]),
                tensor_rank_1([5.0, 5.0, 7.0, 13.0]),
                tensor_rank_1([13.0, 13.0, 13.0, 31.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([17.0, 15.0, 3.0, 15.0]),
                tensor_rank_1([15.0, 17.0, 3.0, 15.0]),
                tensor_rank_1([3.0, 3.0, 1.0, 3.0]),
                tensor_rank_1([15.0, 15.0, 3.0, 17.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([17.0, 15.0, 15.0, 3.0]),
                tensor_rank_1([15.0, 17.0, 15.0, 3.0]),
                tensor_rank_1([15.0, 15.0, 17.0, 3.0]),
                tensor_rank_1([3.0, 3.0, 3.0, 1.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([7.0, 5.0, 13.0, 5.0]),
                tensor_rank_1([5.0, 7.0, 13.0, 5.0]),
                tensor_rank_1([13.0, 13.0, 31.0, 13.0]),
                tensor_rank_1([5.0, 5.0, 13.0, 7.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([17.0, 3.0, 15.0, 15.0]),
                tensor_rank_1([3.0, 1.0, 3.0, 3.0]),
                tensor_rank_1([15.0, 3.0, 17.0, 15.0]),
                tensor_rank_1([15.0, 3.0, 15.0, 17.0]),
            ]),
            tensor_rank_2([
                tensor_rank_1([31.0, 13.0, 13.0, 13.0]),
                tensor_rank_1([13.0, 7.0, 5.0, 5.0]),
                tensor_rank_1([13.0, 5.0, 7.0, 5.0]),
                tensor_rank_1([13.0, 5.0, 5.0, 7.0]),
            ]),
        ])
    }
    const fn standard_gradient_operators() -> StandardGradientOperators<M, N, P> {
        const TWO_THIRDS: Scalar = 2.0 / 3.0;
        const FOUR_THIRDS: Scalar = 4.0 / 3.0;
        tensor_rank_1_list_2d([
            tensor_rank_1_list([
                tensor_rank_1([-2.0, -2.0, -2.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([2.0, 0.0, 0.0]),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 2.0, 0.0]),
                tensor_rank_1([0.0, 0.0, 2.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1([2.0, 0.0, 0.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([-2.0, -2.0, -2.0]),
                tensor_rank_1([0.0, 2.0, 0.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 0.0, 2.0]),
                tensor_rank_1_zero(),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 2.0, 0.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([2.0, 0.0, 0.0]),
                tensor_rank_1([-2.0, -2.0, -2.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 0.0, 2.0]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 0.0, 2.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([-2.0, -2.0, -2.0]),
                tensor_rank_1([2.0, 0.0, 0.0]),
                tensor_rank_1([0.0, 2.0, 0.0]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([-TWO_THIRDS, -2.0, -2.0]),
                tensor_rank_1([FOUR_THIRDS, 2.0, 0.0]),
                tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([FOUR_THIRDS, 0.0, 2.0]),
                tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
                tensor_rank_1([FOUR_THIRDS, FOUR_THIRDS, -TWO_THIRDS]),
                tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
                tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
                tensor_rank_1([FOUR_THIRDS, -TWO_THIRDS, FOUR_THIRDS]),
                tensor_rank_1([-TWO_THIRDS, FOUR_THIRDS, FOUR_THIRDS]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
                tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
                tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
                tensor_rank_1([-2.0, -2.0, -TWO_THIRDS]),
                tensor_rank_1([2.0, 0.0, FOUR_THIRDS]),
                tensor_rank_1([0.0, 2.0, FOUR_THIRDS]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, -FOUR_THIRDS, -2.0]),
                tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
                tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
                tensor_rank_1([-2.0, -FOUR_THIRDS, 0.0]),
                tensor_rank_1([2.0, TWO_THIRDS, 2.0]),
                tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, -2.0, -FOUR_THIRDS]),
                tensor_rank_1([2.0, 2.0, TWO_THIRDS]),
                tensor_rank_1([-2.0, 0.0, -FOUR_THIRDS]),
                tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
                tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
                tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
                tensor_rank_1([2.0, FOUR_THIRDS, 0.0]),
                tensor_rank_1([-2.0, -TWO_THIRDS, -2.0]),
                tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
                tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
                tensor_rank_1([0.0, FOUR_THIRDS, 2.0]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([-FOUR_THIRDS, 0.0, -2.0]),
                tensor_rank_1([-FOUR_THIRDS, -2.0, 0.0]),
                tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([TWO_THIRDS, 2.0, 2.0]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([TWO_THIRDS, -FOUR_THIRDS, -FOUR_THIRDS]),
                tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
                tensor_rank_1([-FOUR_THIRDS, TWO_THIRDS, -FOUR_THIRDS]),
                tensor_rank_1([-FOUR_THIRDS, -FOUR_THIRDS, TWO_THIRDS]),
                tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
                tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
            ]),
        ])
    }
    const fn standard_gradient_operators_transposed() -> StandardGradientOperatorsTransposed<M, N, P>
    {
        const TWO_THIRDS: Scalar = 2.0 / 3.0;
        const FOUR_THIRDS: Scalar = 4.0 / 3.0;
        tensor_rank_1_list_2d([
            tensor_rank_1_list([
                tensor_rank_1([-2.0, -2.0, -2.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1([2.0, 0.0, 0.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 2.0, 0.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 0.0, 2.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
            ]),
            tensor_rank_1_list([
                tensor_rank_1([2.0, 0.0, 0.0]),
                tensor_rank_1([-2.0, -2.0, -2.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([-TWO_THIRDS, -2.0, -2.0]),
                tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
                tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
                tensor_rank_1([0.0, -FOUR_THIRDS, -2.0]),
                tensor_rank_1([0.0, -2.0, -FOUR_THIRDS]),
                tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
                tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([TWO_THIRDS, -FOUR_THIRDS, -FOUR_THIRDS]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 2.0, 0.0]),
                tensor_rank_1([2.0, 0.0, 0.0]),
                tensor_rank_1_zero(),
                tensor_rank_1([FOUR_THIRDS, 2.0, 0.0]),
                tensor_rank_1([FOUR_THIRDS, FOUR_THIRDS, -TWO_THIRDS]),
                tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
                tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
                tensor_rank_1([2.0, 2.0, TWO_THIRDS]),
                tensor_rank_1([2.0, FOUR_THIRDS, 0.0]),
                tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1([0.0, 2.0, 0.0]),
                tensor_rank_1_zero(),
                tensor_rank_1([-2.0, -2.0, -2.0]),
                tensor_rank_1_zero(),
                tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
                tensor_rank_1([0.0, 0.0, -TWO_THIRDS]),
                tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
                tensor_rank_1([-2.0, 0.0, -FOUR_THIRDS]),
                tensor_rank_1([-2.0, -TWO_THIRDS, -2.0]),
                tensor_rank_1([-FOUR_THIRDS, 0.0, -2.0]),
                tensor_rank_1([-FOUR_THIRDS, TWO_THIRDS, -FOUR_THIRDS]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1([0.0, 0.0, 2.0]),
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([-2.0, -2.0, -2.0]),
                tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([-TWO_THIRDS, -TWO_THIRDS, -TWO_THIRDS]),
                tensor_rank_1([-2.0, -2.0, -TWO_THIRDS]),
                tensor_rank_1([-2.0, -FOUR_THIRDS, 0.0]),
                tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
                tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
                tensor_rank_1([-FOUR_THIRDS, -2.0, 0.0]),
                tensor_rank_1([-FOUR_THIRDS, -FOUR_THIRDS, TWO_THIRDS]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 0.0, 2.0]),
                tensor_rank_1_zero(),
                tensor_rank_1([2.0, 0.0, 0.0]),
                tensor_rank_1([FOUR_THIRDS, 0.0, 2.0]),
                tensor_rank_1([FOUR_THIRDS, -TWO_THIRDS, FOUR_THIRDS]),
                tensor_rank_1([2.0, 0.0, FOUR_THIRDS]),
                tensor_rank_1([2.0, TWO_THIRDS, 2.0]),
                tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
                tensor_rank_1([0.0, -TWO_THIRDS, 0.0]),
                tensor_rank_1([TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
            ]),
            tensor_rank_1_list([
                tensor_rank_1_zero(),
                tensor_rank_1_zero(),
                tensor_rank_1([0.0, 0.0, 2.0]),
                tensor_rank_1([0.0, 2.0, 0.0]),
                tensor_rank_1([-TWO_THIRDS, 0.0, 0.0]),
                tensor_rank_1([-TWO_THIRDS, FOUR_THIRDS, FOUR_THIRDS]),
                tensor_rank_1([0.0, 2.0, FOUR_THIRDS]),
                tensor_rank_1([0.0, TWO_THIRDS, 0.0]),
                tensor_rank_1([0.0, 0.0, TWO_THIRDS]),
                tensor_rank_1([0.0, FOUR_THIRDS, 2.0]),
                tensor_rank_1([TWO_THIRDS, 2.0, 2.0]),
                tensor_rank_1([TWO_THIRDS, TWO_THIRDS, TWO_THIRDS]),
            ]),
        ])
    }
}