1#[cfg(test)]
2mod test;
3
4use crate::{
5 fem::block::element::{
6 FRAC_SQRT_3_5, FiniteElement, ParametricCoordinate, ParametricCoordinates,
7 ParametricReference, ShapeFunctions, ShapeFunctionsGradients,
8 quadratic::{M, QuadraticElement, QuadraticFiniteElement},
9 },
10 math::{Scalar, ScalarList},
11};
12
13const G: usize = 18;
14const N: usize = 15;
15const P: usize = N;
16
17pub type Wedge = QuadraticElement<G, N>;
18
19impl FiniteElement<G, M, N, P> for Wedge {
20 fn integration_points() -> ParametricCoordinates<G, M> {
21 const ONE_SIXTH: Scalar = 1.0 / 12.0;
22 const TWO_THIRDS: Scalar = 2.0 / 3.0;
23 [
24 [ONE_SIXTH, ONE_SIXTH, FRAC_SQRT_3_5],
25 [ONE_SIXTH, TWO_THIRDS, FRAC_SQRT_3_5],
26 [TWO_THIRDS, ONE_SIXTH, FRAC_SQRT_3_5],
27 [ONE_SIXTH, ONE_SIXTH, -FRAC_SQRT_3_5],
28 [ONE_SIXTH, TWO_THIRDS, -FRAC_SQRT_3_5],
29 [TWO_THIRDS, ONE_SIXTH, -FRAC_SQRT_3_5],
30 [ONE_SIXTH, ONE_SIXTH, 0.0],
31 [ONE_SIXTH, TWO_THIRDS, 0.0],
32 [TWO_THIRDS, ONE_SIXTH, 0.0],
33 [0.5, 0.5, FRAC_SQRT_3_5],
34 [0.5, 0.0, FRAC_SQRT_3_5],
35 [0.0, 0.5, FRAC_SQRT_3_5],
36 [0.5, 0.5, -FRAC_SQRT_3_5],
37 [0.5, 0.0, -FRAC_SQRT_3_5],
38 [0.0, 0.5, -FRAC_SQRT_3_5],
39 [0.5, 0.5, 0.0],
40 [0.5, 0.0, 0.0],
41 [0.0, 0.5, 0.0],
42 ]
43 .into()
44 }
45 fn integration_weights(&self) -> &ScalarList<G> {
46 &self.integration_weights
47 }
48 fn parametric_reference() -> ParametricReference<M, N> {
49 [
50 [0.0, 0.0, -1.0],
51 [1.0, 0.0, -1.0],
52 [0.0, 1.0, -1.0],
53 [0.0, 0.0, 1.0],
54 [1.0, 0.0, 1.0],
55 [0.0, 1.0, 1.0],
56 [0.5, 0.0, -1.0],
57 [0.5, 0.5, -1.0],
58 [0.0, 0.5, -1.0],
59 [0.0, 0.0, 0.0],
60 [1.0, 0.0, 0.0],
61 [0.0, 1.0, 0.0],
62 [0.5, 0.0, 1.0],
63 [0.5, 0.5, 1.0],
64 [0.0, 0.5, 1.0],
65 ]
66 .into()
67 }
68 fn parametric_weights() -> ScalarList<G> {
69 const ONE_TWELFTH: Scalar = 1.0 / 12.0;
70 const TWO_FIFTEENTHS: Scalar = 2.0 / 15.0;
71 const ONE_ONE_HUNDRED_EIGHTH: Scalar = 1.0 / 108.0;
72 const TWO_ONE_HUNDRED_THIRTY_FIFTHS: Scalar = 2.0 / 135.0;
73 [
74 ONE_TWELFTH,
75 ONE_TWELFTH,
76 ONE_TWELFTH,
77 ONE_TWELFTH,
78 ONE_TWELFTH,
79 ONE_TWELFTH,
80 TWO_FIFTEENTHS,
81 TWO_FIFTEENTHS,
82 TWO_FIFTEENTHS,
83 ONE_ONE_HUNDRED_EIGHTH,
84 ONE_ONE_HUNDRED_EIGHTH,
85 ONE_ONE_HUNDRED_EIGHTH,
86 ONE_ONE_HUNDRED_EIGHTH,
87 ONE_ONE_HUNDRED_EIGHTH,
88 ONE_ONE_HUNDRED_EIGHTH,
89 TWO_ONE_HUNDRED_THIRTY_FIFTHS,
90 TWO_ONE_HUNDRED_THIRTY_FIFTHS,
91 TWO_ONE_HUNDRED_THIRTY_FIFTHS,
92 ]
93 .into()
94 }
95 fn shape_functions(parametric_coordinate: ParametricCoordinate<M>) -> ShapeFunctions<N> {
96 let [xi_1, xi_2, xi_3] = parametric_coordinate.into();
97 let xi_0 = 1.0 - xi_1 - xi_2;
98 [
99 -0.5 * xi_0 * (1.0 - xi_3) * (2.0 * xi_1 + 2.0 * xi_2 + xi_3),
100 0.5 * xi_1 * (1.0 - xi_3) * (2.0 * xi_1 - 2.0 - xi_3),
101 0.5 * xi_2 * (1.0 - xi_3) * (2.0 * xi_2 - 2.0 - xi_3),
102 -0.5 * xi_0 * (1.0 + xi_3) * (2.0 * xi_1 + 2.0 * xi_2 - xi_3),
103 0.5 * xi_1 * (1.0 + xi_3) * (2.0 * xi_1 - 2.0 + xi_3),
104 0.5 * xi_2 * (1.0 + xi_3) * (2.0 * xi_2 - 2.0 + xi_3),
105 2.0 * xi_0 * xi_1 * (1.0 - xi_3),
106 2.0 * xi_1 * xi_2 * (1.0 - xi_3),
107 2.0 * xi_0 * xi_2 * (1.0 - xi_3),
108 xi_0 * (1.0 - xi_3 * xi_3),
109 xi_1 * (1.0 - xi_3 * xi_3),
110 xi_2 * (1.0 - xi_3 * xi_3),
111 2.0 * xi_0 * xi_1 * (1.0 + xi_3),
112 2.0 * xi_1 * xi_2 * (1.0 + xi_3),
113 2.0 * xi_0 * xi_2 * (1.0 + xi_3),
114 ]
115 .into()
116 }
117 fn shape_functions_gradients(
118 parametric_coordinate: ParametricCoordinate<M>,
119 ) -> ShapeFunctionsGradients<M, N> {
120 let [xi_1, xi_2, xi_3] = parametric_coordinate.into();
121 let xi_0 = 1.0 - xi_1 - xi_2;
122 [
123 [
124 0.5 * (1.0 - xi_3) * (4.0 * xi_1 + 4.0 * xi_2 + xi_3 - 2.0),
125 0.5 * (1.0 - xi_3) * (4.0 * xi_1 + 4.0 * xi_2 + xi_3 - 2.0),
126 xi_0 * (xi_1 + xi_2 + xi_3 - 0.5),
127 ],
128 [
129 0.5 * (1.0 - xi_3) * (4.0 * xi_1 - 2.0 - xi_3),
130 0.0,
131 xi_1 * (xi_3 - xi_1 + 0.5),
132 ],
133 [
134 0.0,
135 0.5 * (1.0 - xi_3) * (4.0 * xi_2 - xi_3 - 2.0),
136 xi_2 * (xi_3 - xi_2 + 0.5),
137 ],
138 [
139 0.5 * (1.0 + xi_3) * (4.0 * xi_1 + 4.0 * xi_2 - xi_3 - 2.0),
140 0.5 * (1.0 + xi_3) * (4.0 * xi_1 + 4.0 * xi_2 - xi_3 - 2.0),
141 xi_0 * (-xi_1 - xi_2 + xi_3 + 0.5),
142 ],
143 [
144 0.5 * (1.0 + xi_3) * (4.0 * xi_1 - 2.0 + xi_3),
145 0.0,
146 xi_1 * (xi_3 + xi_1 - 0.5),
147 ],
148 [
149 0.0,
150 0.5 * (1.0 + xi_3) * (4.0 * xi_2 + xi_3 - 2.0),
151 xi_2 * (xi_3 + xi_2 - 0.5),
152 ],
153 [
154 2.0 * (1.0 - xi_3) * (1.0 - 2.0 * xi_1 - xi_2),
155 -2.0 * xi_1 * (1.0 - xi_3),
156 -2.0 * xi_0 * xi_1,
157 ],
158 [
159 2.0 * xi_2 * (1.0 - xi_3),
160 2.0 * xi_1 * (1.0 - xi_3),
161 -2.0 * xi_1 * xi_2,
162 ],
163 [
164 -2.0 * xi_2 * (1.0 - xi_3),
165 2.0 * (1.0 - xi_3) * (xi_0 - xi_2),
166 -2.0 * xi_0 * xi_2,
167 ],
168 [xi_3 * xi_3 - 1.0, xi_3 * xi_3 - 1.0, -2.0 * xi_0 * xi_3],
169 [1.0 - xi_3 * xi_3, 0.0, -2.0 * xi_1 * xi_3],
170 [0.0, 1.0 - xi_3 * xi_3, -2.0 * xi_2 * xi_3],
171 [
172 2.0 * (1.0 + xi_3) * (1.0 - 2.0 * xi_1 - xi_2),
173 -2.0 * xi_1 * (1.0 + xi_3),
174 2.0 * xi_0 * xi_1,
175 ],
176 [
177 2.0 * xi_2 * (1.0 + xi_3),
178 2.0 * xi_1 * (1.0 + xi_3),
179 2.0 * xi_1 * xi_2,
180 ],
181 [
182 -2.0 * xi_2 * (1.0 + xi_3),
183 2.0 * (1.0 + xi_3) * (1.0 - xi_1 - 2.0 * xi_2),
184 2.0 * xi_0 * xi_2,
185 ],
186 ]
187 .into()
188 }
189}
190
191impl QuadraticFiniteElement<G, N> for Wedge {}