Caribou
BaseQuad.h
1 #pragma once
2 
3 #include <Caribou/config.h>
4 #include <Caribou/constants.h>
5 #include <Caribou/Geometry/Element.h>
6 #include <Eigen/Core>
7 
8 namespace caribou::geometry {
9 
10 template<typename Derived>
11 struct BaseQuad : public Element<Derived> {
12  // Types
13  using Base = Element<Derived>;
14 
15  using LocalCoordinates = typename Base::LocalCoordinates;
16  using WorldCoordinates = typename Base::WorldCoordinates;
17 
18  using GaussNode = typename Base::GaussNode;
19 
20  template <UNSIGNED_INTEGER_TYPE Dim>
21  using Vector = typename Base::template Vector<Dim>;
22 
23  template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
24  using Matrix = typename Base::template Matrix<Rows, Cols>;
25 
26  // Constants
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;
31 
32  static_assert(Dimension == 2 or Dimension == 3, "Quads can only be of dimension 2 or 3.");
33 
35  BaseQuad() = default;
36 
38  template<typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == NumberOfNodesAtCompileTime)>
39  explicit BaseQuad(Eigen::EigenBase<EigenType> & nodes) :p_nodes(nodes.derived().template cast<typename Base::Scalar>()) {}
40 
42  template<typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == NumberOfNodesAtCompileTime)>
43  explicit BaseQuad(const Eigen::EigenBase<EigenType> & nodes) :p_nodes(nodes.derived().template cast<typename Base::Scalar>()) {}
44 
46  template <
47  typename ...Nodes,
48  REQUIRES(NumberOfNodesAtCompileTime == sizeof...(Nodes)+1)
49  >
50  explicit BaseQuad(const WorldCoordinates & first_node, Nodes&&...remaining_nodes)
51  {
52  construct_from_nodes<0>(first_node, std::forward<Nodes>(remaining_nodes)...);
53  }
54 
55  // Public methods common to all quad types
56 
61  inline auto edges() const {
62  return self().get_boundary_elements_nodes();
63  }
64 
75  inline auto frame() const -> Matrix<Dimension, Dimension>
76  {
77  return frame(LocalCoordinates::Zero());
78  }
79 
101  inline
102  auto
103  frame(const LocalCoordinates & local_point) const -> Matrix<Dimension, Dimension>
104  {
105  // Position of the point inside the quad where the frame should be computed
106  const auto p = this->world_coordinates( local_point );
107 
108  // Project of the point on the edge facing the u axis
109  const auto projected_on_u = this->world_coordinates({1,local_point[1]});
110 
111  // Project of the point on the edge facing the v axis
112  const auto projected_on_v = this->world_coordinates({local_point[0], 1});
113 
114  // Vector from the point to its projection on the edge facing the u axis
115  const auto point_to_u = projected_on_u - p;
116 
117  // Vector from the point to its projection on the edge facing the v axis
118  const auto point_to_v = projected_on_v - p;
119 
120  // The u-axis of the computed frame
121  const auto u = point_to_u.normalized();
122 
123  // The v-axis of the computed frame
124  auto v = point_to_v.normalized();
125 
126  Matrix<Dimension, Dimension> m {};
127  if constexpr (Dimension == 3) {
128  // The w-axis of the computed frame
129  const WorldCoordinates w = u.cross(v).normalized();
130  m << u, v, w;
131  } else {
132  m << u, v;
133  }
134 
135  return m;
136  }
137 
138 private:
139  // Implementations
140  friend struct Element<Derived>;
141  [[nodiscard]]
142  inline auto get_number_of_nodes() const {return NumberOfNodesAtCompileTime;}
143  inline auto get_number_of_gauss_nodes() const {return NumberOfGaussNodesAtCompileTime;}
144  inline auto get_node(const UNSIGNED_INTEGER_TYPE & index) const {return WorldCoordinates(p_nodes.row(index));};
145  inline auto get_nodes() const -> const auto & {return p_nodes;};
146  inline auto get_center() const {return Base::world_coordinates(LocalCoordinates({0, 0}));};
147  inline auto get_number_of_boundary_elements() const -> UNSIGNED_INTEGER_TYPE {return 4;};
148  inline auto get_contains_local(const LocalCoordinates & xi, const FLOATING_POINT_TYPE & eps) const -> bool {
149  const auto & u = xi[0];
150  const auto & v = xi[1];
151  return IN_CLOSED_INTERVAL(-1-eps, u, 1+eps) and
152  IN_CLOSED_INTERVAL(-1-eps, v, 1+eps);
153  }
154 
155  auto self() -> Derived& { return *static_cast<Derived*>(this); }
156  auto self() const -> const Derived& { return *static_cast<const Derived*>(this); }
157 
158  template <size_t index, typename ...Nodes, REQUIRES(sizeof...(Nodes) >= 1)>
159  inline
160  void construct_from_nodes(const WorldCoordinates & first_node, Nodes&&...remaining_nodes) {
161  p_nodes.row(index) = first_node;
162  construct_from_nodes<index+1>(std::forward<Nodes>(remaining_nodes)...);
163  }
164 
165  template <size_t index>
166  inline
167  void construct_from_nodes(const WorldCoordinates & last_node) {
168  p_nodes.row(index) = last_node;
169  }
170 protected:
171  Matrix<NumberOfNodesAtCompileTime, Dimension> p_nodes;
172 };
173 
174 }
caribou::geometry::BaseQuad::BaseQuad
BaseQuad(Eigen::EigenBase< EigenType > &nodes)
Constructor from an Eigen matrix containing the positions of the quad's nodes.
Definition: BaseQuad.h:39
caribou::geometry::BaseQuad::frame
auto frame() const -> Matrix< Dimension, Dimension >
Extract the orthogonal frame of the element by computing the cross product of the unit vectors from t...
Definition: BaseQuad.h:75
caribou::geometry::BaseQuad::BaseQuad
BaseQuad(const WorldCoordinates &first_node, Nodes &&...remaining_nodes)
Constructor from a serie of nodes.
Definition: BaseQuad.h:50
caribou::geometry::Element< Derived >::world_coordinates
auto world_coordinates(const LocalCoordinates &coordinates) const -> WorldCoordinates
Get the world coordinates of a point from its local coordinates.
Definition: Element.h:157
caribou::geometry::BaseQuad::BaseQuad
BaseQuad()=default
Default empty constructor.
caribou::geometry::Element
Definition: Element.h:28
caribou::geometry::BaseQuad
Definition: BaseQuad.h:11
caribou::geometry::BaseQuad::edges
auto edges() const
Get the list of node indices of the edges.
Definition: BaseQuad.h:61
caribou::geometry::Element< Derived >::nodes
auto nodes() const
Get the set of nodes.
Definition: Element.h:67
caribou::geometry::BaseQuad::BaseQuad
BaseQuad(const Eigen::EigenBase< EigenType > &nodes)
Constructor from an Eigen matrix containing the positions of the quad's nodes.
Definition: BaseQuad.h:43
caribou::geometry::BaseQuad::frame
auto frame(const LocalCoordinates &local_point) const -> Matrix< Dimension, Dimension >
Extract the frame positioned at the given position (in local coordinates) on the quad by computing th...
Definition: BaseQuad.h:103