3 #include <Caribou/config.h>
4 #include <Caribou/constants.h>
5 #include <Caribou/Geometry/Element.h>
9 namespace caribou::geometry {
15 template<
typename Derived>
20 using LocalCoordinates =
typename Base::LocalCoordinates;
21 using WorldCoordinates =
typename Base::WorldCoordinates;
23 using GaussNode =
typename Base::GaussNode;
25 template <UNSIGNED_INTEGER_TYPE Dim>
26 using Vector =
typename Base::template Vector<Dim>;
28 template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
29 using Matrix =
typename Base::template Matrix<Rows, Cols>;
32 static constexpr
auto CanonicalDimension = Base::CanonicalDimension;
33 static constexpr
auto Dimension = Base::Dimension;
34 static constexpr
auto NumberOfNodesAtCompileTime = Base::NumberOfNodesAtCompileTime;
35 static constexpr
auto NumberOfGaussNodesAtCompileTime = Base::NumberOfGaussNodesAtCompileTime;
37 static_assert(Dimension == 3,
"Hexahedrons can only be of dimension 3.");
43 template<
typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == NumberOfNodesAtCompileTime)>
47 template<
typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == NumberOfNodesAtCompileTime)>
53 REQUIRES(NumberOfNodesAtCompileTime ==
sizeof...(Nodes)+1)
55 explicit BaseHexahedron(
const WorldCoordinates & first_node, Nodes&&...remaining_nodes)
57 construct_from_nodes<0>(first_node, std::forward<Nodes>(remaining_nodes)...);
67 return self().get_boundary_elements_nodes();
80 inline auto frame() const -> Matrix<3, 3>
82 return frame(LocalCoordinates::Zeros());
103 inline auto frame(
const LocalCoordinates & local_point)
const -> Matrix<3, 3>
109 const auto projected_on_u = this->
world_coordinates({1, local_point[1],local_point[2]});
112 const auto projected_on_v = this->
world_coordinates({local_point[0], 1,local_point[2]});
118 const auto point_to_u = projected_on_u - p;
121 const auto point_to_v = projected_on_v - p;
124 const auto u = point_to_u.normalized();
127 auto v = point_to_v.normalized();
130 const WorldCoordinates w = u.cross(v).normalized();
133 v = w.cross(u).normalized();
143 friend struct Element<Derived>;
145 inline auto get_number_of_nodes()
const {
return NumberOfNodesAtCompileTime;}
146 inline auto get_number_of_gauss_nodes()
const {
return NumberOfGaussNodesAtCompileTime;}
147 inline auto get_node(
const UNSIGNED_INTEGER_TYPE & index)
const {
return WorldCoordinates(p_nodes.row(index));};
148 inline auto get_nodes() const -> const auto & {
return p_nodes;};
150 inline auto get_number_of_boundary_elements() const -> UNSIGNED_INTEGER_TYPE {
return 6;};
151 inline auto get_contains_local(
const LocalCoordinates & xi,
const FLOATING_POINT_TYPE & eps)
const ->
bool {
152 const auto & u = xi[0];
153 const auto & v = xi[1];
154 const auto & w = xi[2];
155 return IN_CLOSED_INTERVAL(-1-eps, u, 1+eps) and
156 IN_CLOSED_INTERVAL(-1-eps, v, 1+eps) and
157 IN_CLOSED_INTERVAL(-1-eps, w, 1+eps);
160 auto self() -> Derived& {
return *
static_cast<Derived*
>(
this); }
161 auto self()
const ->
const Derived& {
return *
static_cast<const Derived*
>(
this); }
163 template <
size_t index,
typename ...Nodes, REQUIRES(
sizeof...(Nodes) >= 1)>
165 void construct_from_nodes(
const WorldCoordinates & first_node, Nodes&&...remaining_nodes) {
166 p_nodes.row(index) = first_node;
167 construct_from_nodes<index+1>(std::forward<Nodes>(remaining_nodes)...);
170 template <
size_t index>
172 void construct_from_nodes(
const WorldCoordinates & last_node) {
173 p_nodes.row(index) = last_node;
176 Matrix<NumberOfNodesAtCompileTime, Dimension> p_nodes;