3 #include <Caribou/config.h>
4 #include <Caribou/Geometry/BaseTetrahedron.h>
5 #include <Caribou/Geometry/Triangle.h>
9 namespace caribou::geometry {
11 template<UNSIGNED_INTEGER_TYPE _Order = Linear>
16 static constexpr UNSIGNED_INTEGER_TYPE CanonicalDimension = 3;
17 static constexpr UNSIGNED_INTEGER_TYPE Dimension = 3;
18 static constexpr INTEGER_TYPE NumberOfNodesAtCompileTime = 4;
19 static constexpr INTEGER_TYPE NumberOfGaussNodesAtCompileTime = 1;
22 static constexpr INTEGER_TYPE NumberOfBoundaryElementsAtCompileTime = 4;
54 using LocalCoordinates =
typename Base::LocalCoordinates;
55 using WorldCoordinates =
typename Base::WorldCoordinates;
57 using GaussNode =
typename Base::GaussNode;
59 template <UNSIGNED_INTEGER_TYPE Dim>
60 using Vector =
typename Base::template Vector<Dim>;
62 template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
63 using Matrix =
typename Base::template Matrix<Rows, Cols>;
66 static constexpr
auto CanonicalDimension = Base::CanonicalDimension;
67 static constexpr
auto Dimension = Base::Dimension;
68 static constexpr
auto NumberOfNodesAtCompileTime = Base::NumberOfNodesAtCompileTime;
69 static constexpr
auto NumberOfGaussNodesAtCompileTime = Base::NumberOfGaussNodesAtCompileTime;
74 this->p_nodes.row(0) = WorldCoordinates(0, 0, 0);
75 this->p_nodes.row(1) = WorldCoordinates(1, 0, 0);
76 this->p_nodes.row(2) = WorldCoordinates(0, 1, 0);
77 this->p_nodes.row(3) = WorldCoordinates(0, 0, 1);
86 static const std::array<std::array<UNSIGNED_INTEGER_TYPE, 2>, 6> indices = {{
102 inline auto get_L(
const LocalCoordinates & xi)
const -> Vector<NumberOfNodesAtCompileTime> {
103 const auto & u = xi[0];
104 const auto & v = xi[1];
105 const auto & w = xi[2];
107 static_cast<FLOATING_POINT_TYPE
>(1 - u - v - w),
108 static_cast<FLOATING_POINT_TYPE
>(u),
109 static_cast<FLOATING_POINT_TYPE
>(v),
110 static_cast<FLOATING_POINT_TYPE
>(w)
114 inline auto get_dL(
const LocalCoordinates & )
const {
115 Matrix<NumberOfNodesAtCompileTime, CanonicalDimension> m;
124 inline auto get_gauss_nodes() const -> const auto & {
125 using Weight = FLOATING_POINT_TYPE;
126 static const std::vector<GaussNode> gauss_nodes {
127 GaussNode {LocalCoordinates(1/4., 1/4., 1/4.), Weight(1/6.)}
132 inline auto get_boundary_elements_nodes() const -> const auto & {
133 static const std::array<std::array<UNSIGNED_INTEGER_TYPE, 3>, 4> indices = {{
146 static constexpr UNSIGNED_INTEGER_TYPE CanonicalDimension = 3;
147 static constexpr UNSIGNED_INTEGER_TYPE Dimension = 3;
148 static constexpr INTEGER_TYPE NumberOfNodesAtCompileTime = 10;
149 static constexpr INTEGER_TYPE NumberOfGaussNodesAtCompileTime = 4;
152 static constexpr INTEGER_TYPE NumberOfBoundaryElementsAtCompileTime = 4;
184 using LocalCoordinates =
typename Base::LocalCoordinates;
185 using WorldCoordinates =
typename Base::WorldCoordinates;
187 using GaussNode =
typename Base::GaussNode;
189 template <UNSIGNED_INTEGER_TYPE Dim>
190 using Vector =
typename Base::template Vector<Dim>;
192 template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
193 using Matrix =
typename Base::template Matrix<Rows, Cols>;
196 static constexpr
auto CanonicalDimension = Base::CanonicalDimension;
197 static constexpr
auto Dimension = Base::Dimension;
198 static constexpr
auto NumberOfNodesAtCompileTime = Base::NumberOfNodesAtCompileTime;
199 static constexpr
auto NumberOfGaussNodesAtCompileTime = Base::NumberOfGaussNodesAtCompileTime;
204 this->p_nodes.row(0) = WorldCoordinates(0.0, 0.0, 0.0);
205 this->p_nodes.row(1) = WorldCoordinates(1.0, 0.0, 0.0);
206 this->p_nodes.row(2) = WorldCoordinates(0.0, 1.0, 0.0);
207 this->p_nodes.row(3) = WorldCoordinates(0.0, 0.0, 1.0);
208 this->p_nodes.row(4) = WorldCoordinates(0.5, 0.0, 0.0);
209 this->p_nodes.row(5) = WorldCoordinates(0.5, 0.5, 0.0);
210 this->p_nodes.row(6) = WorldCoordinates(0.0, 0.5, 0.0);
211 this->p_nodes.row(7) = WorldCoordinates(0.0, 0.0, 0.5);
212 this->p_nodes.row(8) = WorldCoordinates(0.5, 0.0, 0.5);
213 this->p_nodes.row(9) = WorldCoordinates(0.0, 0.5, 0.5);
218 this->p_nodes.row(0) = linear_Tetrahedron.
node(0);
219 this->p_nodes.row(1) = linear_Tetrahedron.
node(1);
220 this->p_nodes.row(2) = linear_Tetrahedron.
node(2);
221 this->p_nodes.row(3) = linear_Tetrahedron.
node(3);
222 this->p_nodes.row(4) = linear_Tetrahedron.
world_coordinates(LocalCoordinates(0.5, 0.0, 0.0));
223 this->p_nodes.row(5) = linear_Tetrahedron.
world_coordinates(LocalCoordinates(0.5, 0.5, 0.0));
224 this->p_nodes.row(6) = linear_Tetrahedron.
world_coordinates(LocalCoordinates(0.0, 0.5, 0.0));
225 this->p_nodes.row(7) = linear_Tetrahedron.
world_coordinates(LocalCoordinates(0.0, 0.0, 0.5));
226 this->p_nodes.row(8) = linear_Tetrahedron.
world_coordinates(LocalCoordinates(0.5, 0.0, 0.5));
227 this->p_nodes.row(9) = linear_Tetrahedron.
world_coordinates(LocalCoordinates(0.0, 0.5, 0.5));
231 Tetrahedron(WorldCoordinates & p0, WorldCoordinates & p1, WorldCoordinates & p2, WorldCoordinates & p3)
235 Tetrahedron(
const WorldCoordinates & p0,
const WorldCoordinates & p1,
const WorldCoordinates & p2,
const WorldCoordinates & p3)
244 static const std::array<std::array<UNSIGNED_INTEGER_TYPE, 3>, 6> indices = {{
259 inline auto get_L(
const LocalCoordinates & xi)
const {
260 const auto & u = xi[0];
261 const auto & v = xi[1];
262 const auto & w = xi[2];
263 const auto l = 1 - u - v - w;
265 Vector<NumberOfNodesAtCompileTime> m;
280 inline auto get_dL(
const LocalCoordinates & xi)
const {
281 const auto & u = xi[0];
282 const auto & v = xi[1];
283 const auto & w = xi[2];
284 const auto l = 1 - u - v - w;
286 Matrix<NumberOfNodesAtCompileTime, CanonicalDimension> m;
288 m << 1 - (4 * l), 1 - (4 * l), 1 - (4 * l),
289 (4 * u) - 1 , 0 , 0 ,
290 0 , (4 * v) - 1 , 0 ,
291 0 , 0 , (4 * w) - 1 ,
292 4 * (l - u), -4 * u , -4 * u ,
294 -4 * v , 4 * (l - v), -4 * v ,
295 -4 * w , -4 * w , 4 * (l - w),
301 inline auto get_gauss_nodes() const -> const auto & {
302 using Weight = FLOATING_POINT_TYPE;
303 static const std::vector<GaussNode> gauss_nodes {
304 GaussNode {LocalCoordinates(0.1381966011250105, 0.1381966011250105, 0.1381966011250105), Weight(1/24.)},
305 GaussNode {LocalCoordinates(0.1381966011250105, 0.1381966011250105, 0.5854101966249685), Weight(1/24.)},
306 GaussNode {LocalCoordinates(0.1381966011250105, 0.5854101966249685, 0.1381966011250105), Weight(1/24.)},
307 GaussNode {LocalCoordinates(0.5854101966249685, 0.1381966011250105, 0.1381966011250105), Weight(1/24.)}
312 inline auto get_boundary_elements_nodes() const -> const auto & {
313 static const std::array<std::array<UNSIGNED_INTEGER_TYPE, 6>, 4> indices = {{