3 #include <Caribou/config.h>
4 #include <Caribou/constants.h>
5 #include <Caribou/Geometry/Element.h>
8 namespace caribou::geometry {
10 template<
typename Derived>
15 using LocalCoordinates =
typename Base::LocalCoordinates;
16 using WorldCoordinates =
typename Base::WorldCoordinates;
18 using GaussNode =
typename Base::GaussNode;
20 template <UNSIGNED_INTEGER_TYPE Dim>
21 using Vector =
typename Base::template Vector<Dim>;
23 template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
24 using Matrix =
typename Base::template Matrix<Rows, Cols>;
27 static constexpr
auto CanonicalDimension = Base::CanonicalDimension;
28 static constexpr
auto Dimension = Base::Dimension;
29 static constexpr
auto NumberOfNodesAtCompileTime = Base::NumberOfNodesAtCompileTime;
30 static constexpr
auto NumberOfGaussNodesAtCompileTime = Base::NumberOfGaussNodesAtCompileTime;
32 static_assert(Dimension == 2 or Dimension == 3,
"Triangles can only be of dimension 2 or 3.");
38 template<
typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == NumberOfNodesAtCompileTime)>
42 template<
typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == NumberOfNodesAtCompileTime)>
48 REQUIRES(NumberOfNodesAtCompileTime ==
sizeof...(Nodes)+1)
50 explicit BaseTriangle(
const WorldCoordinates & first_node, Nodes&&...remaining_nodes)
52 construct_from_nodes<0>(first_node, std::forward<Nodes>(remaining_nodes)...);
62 inline auto normal() const noexcept -> WorldCoordinates {
63 static_assert(Dimension == 3,
"Can only get the normal of a triangle in a 3D world");
64 const WorldCoordinates v1 =
self().
node(1) -
self().
node(0);
65 const WorldCoordinates v2 =
self().
node(2) -
self().
node(0);
67 return v1.cross(v2).normalized();
75 return self().get_boundary_elements_nodes();
82 inline auto get_number_of_nodes()
const {
return NumberOfNodesAtCompileTime;}
83 inline auto get_number_of_gauss_nodes()
const {
return NumberOfGaussNodesAtCompileTime;}
84 inline auto get_node(
const UNSIGNED_INTEGER_TYPE & index)
const {
return WorldCoordinates(p_nodes.row(index));};
85 inline auto get_nodes() const -> const auto & {
return p_nodes;};
87 inline auto get_number_of_boundary_elements() const -> UNSIGNED_INTEGER_TYPE {
return 3;};
88 inline auto get_contains_local(
const LocalCoordinates & xi,
const FLOATING_POINT_TYPE & eps)
const ->
bool {
89 const auto & u = xi[0];
90 const auto & v = xi[1];
91 return (u > -eps) and (v > -eps) and (1 - u - v > -eps);
94 auto self() -> Derived& {
return *
static_cast<Derived*
>(
this); }
95 auto self()
const ->
const Derived& {
return *
static_cast<const Derived*
>(
this); }
97 template <
size_t index,
typename ...Nodes, REQUIRES(
sizeof...(Nodes) >= 1)>
99 void construct_from_nodes(
const WorldCoordinates & first_node, Nodes&&...remaining_nodes) {
100 p_nodes.row(index) = first_node;
101 construct_from_nodes<index+1>(std::forward<Nodes>(remaining_nodes)...);
104 template <
size_t index>
106 void construct_from_nodes(
const WorldCoordinates & last_node) {
107 p_nodes.row(index) = last_node;
110 Matrix<NumberOfNodesAtCompileTime, Dimension> p_nodes;