3 #include <Caribou/config.h>
4 #include <Caribou/Geometry/BaseTriangle.h>
5 #include <Caribou/Geometry/Segment.h>
9 namespace caribou::geometry {
11 template<UNSIGNED_INTEGER_TYPE _Dimension, UNSIGNED_INTEGER_TYPE _Order = Linear>
14 template<UNSIGNED_INTEGER_TYPE _Dimension>
16 static constexpr UNSIGNED_INTEGER_TYPE CanonicalDimension = 2;
17 static constexpr UNSIGNED_INTEGER_TYPE Dimension = _Dimension;
18 static constexpr INTEGER_TYPE NumberOfNodesAtCompileTime = 3;
19 static constexpr INTEGER_TYPE NumberOfGaussNodesAtCompileTime = 1;
22 static constexpr INTEGER_TYPE NumberOfBoundaryElementsAtCompileTime = 3;
43 template<UNSIGNED_INTEGER_TYPE _Dimension>
47 using LocalCoordinates =
typename Base::LocalCoordinates;
48 using WorldCoordinates =
typename Base::WorldCoordinates;
50 using GaussNode =
typename Base::GaussNode;
52 template <UNSIGNED_INTEGER_TYPE Dim>
53 using Vector =
typename Base::template Vector<Dim>;
55 template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
56 using Matrix =
typename Base::template Matrix<Rows, Cols>;
59 static constexpr
auto CanonicalDimension = Base::CanonicalDimension;
60 static constexpr
auto Dimension = Base::Dimension;
61 static constexpr
auto NumberOfNodesAtCompileTime = Base::NumberOfNodesAtCompileTime;
62 static constexpr
auto NumberOfGaussNodesAtCompileTime = Base::NumberOfGaussNodesAtCompileTime;
67 if constexpr (Dimension == 2) {
68 this->p_nodes.row(0) = WorldCoordinates(0, 0);
69 this->p_nodes.row(1) = WorldCoordinates(1, 0);
70 this->p_nodes.row(2) = WorldCoordinates(0, 1);
72 this->p_nodes.row(0) = WorldCoordinates(0, 0, 0);
73 this->p_nodes.row(1) = WorldCoordinates(1, 0, 0);
74 this->p_nodes.row(2) = WorldCoordinates(0, 1, 0);
83 inline auto get_L(
const LocalCoordinates & xi)
const -> Vector<NumberOfNodesAtCompileTime> {
84 const auto & u = xi[0];
85 const auto & v = xi[1];
87 static_cast<FLOATING_POINT_TYPE
>(1 - u - v),
88 static_cast<FLOATING_POINT_TYPE
>(u),
89 static_cast<FLOATING_POINT_TYPE
>(v)
93 inline auto get_dL(
const LocalCoordinates & )
const {
94 Matrix<NumberOfNodesAtCompileTime, CanonicalDimension> m;
102 inline auto get_gauss_nodes()
const ->
const auto & {
103 using Weight = FLOATING_POINT_TYPE;
104 static const std::vector<GaussNode> gauss_nodes {
105 GaussNode {LocalCoordinates(1/3., 1/3.), Weight(1/2.)}
110 inline auto get_boundary_elements_nodes()
const ->
const auto & {
111 static const std::array<std::array<UNSIGNED_INTEGER_TYPE, 2>, 3> indices = {{
121 template<UNSIGNED_INTEGER_TYPE _Dimension>
123 static constexpr UNSIGNED_INTEGER_TYPE CanonicalDimension = 2;
124 static constexpr UNSIGNED_INTEGER_TYPE Dimension = _Dimension;
125 static constexpr INTEGER_TYPE NumberOfNodesAtCompileTime = 6;
126 static constexpr INTEGER_TYPE NumberOfGaussNodesAtCompileTime = 3;
129 static constexpr INTEGER_TYPE NumberOfBoundaryElementsAtCompileTime = 3;
150 template<UNSIGNED_INTEGER_TYPE _Dimension>
154 using LocalCoordinates =
typename Base::LocalCoordinates;
155 using WorldCoordinates =
typename Base::WorldCoordinates;
157 using GaussNode =
typename Base::GaussNode;
159 template <UNSIGNED_INTEGER_TYPE Dim>
160 using Vector =
typename Base::template Vector<Dim>;
162 template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
163 using Matrix =
typename Base::template Matrix<Rows, Cols>;
166 static constexpr
auto CanonicalDimension = Base::CanonicalDimension;
167 static constexpr
auto Dimension = Base::Dimension;
168 static constexpr
auto NumberOfNodesAtCompileTime = Base::NumberOfNodesAtCompileTime;
169 static constexpr
auto NumberOfGaussNodesAtCompileTime = Base::NumberOfGaussNodesAtCompileTime;
174 if constexpr (Dimension == 2) {
175 this->p_nodes.row(0) = WorldCoordinates(0.0, 0.0);
176 this->p_nodes.row(1) = WorldCoordinates(1.0, 0.0);
177 this->p_nodes.row(2) = WorldCoordinates(0.0, 1.0);
178 this->p_nodes.row(3) = WorldCoordinates(0.5, 0.0);
179 this->p_nodes.row(4) = WorldCoordinates(0.5, 0.5);
180 this->p_nodes.row(5) = WorldCoordinates(0.0, 0.5);
182 this->p_nodes.row(0) = WorldCoordinates(0.0, 0.0, 0.0);
183 this->p_nodes.row(1) = WorldCoordinates(1.0, 0.0, 0.0);
184 this->p_nodes.row(2) = WorldCoordinates(0.0, 1.0, 0.0);
185 this->p_nodes.row(3) = WorldCoordinates(0.5, 0.0, 0.0);
186 this->p_nodes.row(4) = WorldCoordinates(0.5, 0.5, 0.0);
187 this->p_nodes.row(5) = WorldCoordinates(0.0, 0.5, 0.0);
193 this->p_nodes.row(0) = linear_triangle.node(0);
194 this->p_nodes.row(1) = linear_triangle.node(1);
195 this->p_nodes.row(2) = linear_triangle.node(2);
196 this->p_nodes.row(3) = linear_triangle.world_coordinates(LocalCoordinates(0.5, 0.0));
197 this->p_nodes.row(4) = linear_triangle.world_coordinates(LocalCoordinates(0.5, 0.5));
198 this->p_nodes.row(5) = linear_triangle.world_coordinates(LocalCoordinates(0.0, 0.5));
202 Triangle(WorldCoordinates & p0, WorldCoordinates & p1, WorldCoordinates & p2)
206 Triangle(
const WorldCoordinates & p0,
const WorldCoordinates & p1,
const WorldCoordinates & p2)
213 inline auto get_L(
const LocalCoordinates & xi)
const {
214 const auto & u = xi[0];
215 const auto & v = xi[1];
216 const auto l = 1 - u - v;
218 Vector<NumberOfNodesAtCompileTime> m;
229 inline auto get_dL(
const LocalCoordinates & xi)
const {
230 const auto & u = xi[0];
231 const auto & v = xi[1];
232 const auto l = 1 - u - v;
234 Matrix<NumberOfNodesAtCompileTime, CanonicalDimension> m;
236 m << 1 - 4 * l , 1 - 4 * l ,
239 4 * (l - u), -4 * u ,
241 - 4 * v , 4 * (l - v);
245 inline auto get_gauss_nodes() const -> const auto & {
246 using Weight = FLOATING_POINT_TYPE;
247 static const std::vector<GaussNode> gauss_nodes {
248 GaussNode {LocalCoordinates(2/3., 1/6.), Weight(1/6.)},
249 GaussNode {LocalCoordinates(1/6., 2/3.), Weight(1/6.)},
250 GaussNode {LocalCoordinates(1/6., 1/6.), Weight(1/6.)}
255 inline auto get_boundary_elements_nodes() const -> const auto & {
256 static const std::array<std::array<UNSIGNED_INTEGER_TYPE, 3>, 3> indices = {{