Skip to main content

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

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