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

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