Caribou
Segment.h
1 #pragma once
2 
3 #include <Caribou/config.h>
4 #include <Caribou/Geometry/BaseSegment.h>
5 #include <Eigen/Core>
6 
7 namespace caribou::geometry {
8 
9 template<UNSIGNED_INTEGER_TYPE _Dimension, UNSIGNED_INTEGER_TYPE _Order = Linear>
10 struct Segment;
11 
12 template<UNSIGNED_INTEGER_TYPE _Dimension>
13  struct traits<Segment <_Dimension, Linear>> {
14  static constexpr UNSIGNED_INTEGER_TYPE CanonicalDimension = 1;
15  static constexpr UNSIGNED_INTEGER_TYPE Dimension = _Dimension;
16  static constexpr INTEGER_TYPE NumberOfNodesAtCompileTime = 2;
17  static constexpr INTEGER_TYPE NumberOfGaussNodesAtCompileTime = 1;
18  };
19 
29 template<UNSIGNED_INTEGER_TYPE _Dimension>
30 struct Segment <_Dimension, Linear> : public BaseSegment<Segment <_Dimension, Linear>> {
31  // Types
33  using LocalCoordinates = typename Base::LocalCoordinates;
34  using WorldCoordinates = typename Base::WorldCoordinates;
35 
36  using GaussNode = typename Base::GaussNode;
37 
38  template <UNSIGNED_INTEGER_TYPE Dim>
39  using Vector = typename Base::template Vector<Dim>;
40 
41  template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
42  using Matrix = typename Base::template Matrix<Rows, Cols>;
43 
44  // Constants
45  static constexpr auto CanonicalDimension = Base::CanonicalDimension;
46  static constexpr auto Dimension = Base::Dimension;
47  static constexpr auto NumberOfNodesAtCompileTime = Base::NumberOfNodesAtCompileTime;
48  static constexpr auto NumberOfGaussNodesAtCompileTime = Base::NumberOfGaussNodesAtCompileTime;
49 
50  // Constructors
51  using Base::Base;
52  Segment() : Base() {
53  if constexpr (Dimension == 1) {
54  this->p_nodes[0] = -1;
55  this->p_nodes[1] = +1;
56  } else if constexpr (Dimension == 2) {
57  this->p_nodes.row(0) = WorldCoordinates(-1, 0);
58  this->p_nodes.row(1) = WorldCoordinates(+1, 0);
59  } else {
60  this->p_nodes.row(0) = WorldCoordinates(-1, 0, 0);
61  this->p_nodes.row(1) = WorldCoordinates(+1, 0, 0);
62  }
63  };
64 
65 
66 private:
67  // Implementations
68  friend struct Element<Segment <_Dimension, Linear>>;
69  friend struct BaseSegment<Segment <_Dimension, Linear>>;
70  inline auto get_L(const LocalCoordinates & xi) const -> Vector<NumberOfNodesAtCompileTime> {
71  const auto & u = xi[0];
72  return {
73  static_cast<FLOATING_POINT_TYPE>(1/2. * (1 - u)),
74  static_cast<FLOATING_POINT_TYPE>(1/2. * (1 + u))
75  };
76  };
77 
78  inline auto get_dL(const LocalCoordinates & /*xi*/) const -> Matrix<NumberOfNodesAtCompileTime, CanonicalDimension> {
79  return {
80  static_cast<FLOATING_POINT_TYPE>(-1/2.),
81  static_cast<FLOATING_POINT_TYPE>(+1/2.)
82  };
83  };
84 
85  inline auto get_gauss_nodes() const -> const auto & {
86  static std::vector<GaussNode> gauss_nodes {
87  GaussNode {LocalCoordinates(0), 2} // Node 0
88  };
89  return gauss_nodes;
90  }
91 };
92 
93 
94 template<UNSIGNED_INTEGER_TYPE _Dimension>
95 struct traits<Segment <_Dimension, Quadratic>> {
96  static constexpr UNSIGNED_INTEGER_TYPE CanonicalDimension = 1;
97  static constexpr UNSIGNED_INTEGER_TYPE Dimension = _Dimension;
98  static constexpr INTEGER_TYPE NumberOfNodesAtCompileTime = 3;
99  static constexpr INTEGER_TYPE NumberOfGaussNodesAtCompileTime = 2;
100 };
101 
111 template<UNSIGNED_INTEGER_TYPE _Dimension>
112 struct Segment <_Dimension, Quadratic> : public BaseSegment<Segment <_Dimension, Quadratic>> {
113 // Types
115  using LocalCoordinates = typename Base::LocalCoordinates;
116  using WorldCoordinates = typename Base::WorldCoordinates;
117 
118  using GaussNode = typename Base::GaussNode;
119 
120  template <UNSIGNED_INTEGER_TYPE Dim>
121  using Vector = typename Base::template Vector<Dim>;
122 
123  template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
124  using Matrix = typename Base::template Matrix<Rows, Cols>;
125 
126  // Constants
127  static constexpr auto CanonicalDimension = Base::CanonicalDimension;
128  static constexpr auto Dimension = Base::Dimension;
129  static constexpr auto NumberOfNodesAtCompileTime = Base::NumberOfNodesAtCompileTime;
130 
131  // Constructors
132  using Base::Base;
133  Segment() : Base() {
134  if constexpr (Dimension == 1) {
135  this->p_nodes[0] = -1;
136  this->p_nodes[1] = +1;
137  this->p_nodes[2] = 0;
138  } else if constexpr (Dimension == 2) {
139  this->p_nodes.row(0) = WorldCoordinates(-1, 0);
140  this->p_nodes.row(1) = WorldCoordinates(+1, 0);
141  this->p_nodes.row(2) = WorldCoordinates( 0, 0);
142  } else {
143  this->p_nodes.row(0) = WorldCoordinates(-1, 0, 0);
144  this->p_nodes.row(1) = WorldCoordinates(+1, 0, 0);
145  this->p_nodes.row(2) = WorldCoordinates( 0, 0, 0);
146  }
147  };
148 
149 
150 private:
151  // Implementations
152  friend struct Element<Segment <_Dimension, Quadratic>>;
153  friend struct BaseSegment<Segment <_Dimension, Quadratic>>;
154  inline auto get_L(const LocalCoordinates & xi) const -> Vector<NumberOfNodesAtCompileTime> {
155  const auto & u = xi[0];
156  return {
157  static_cast<FLOATING_POINT_TYPE>(1/2. * u * (u - 1)),
158  static_cast<FLOATING_POINT_TYPE>(1/2. * u * (u + 1)),
159  static_cast<FLOATING_POINT_TYPE>(1 - (u * u))
160  };
161  };
162 
163  inline auto get_dL(const LocalCoordinates & xi) const -> Matrix<NumberOfNodesAtCompileTime, CanonicalDimension> {
164  const auto & u = xi[0];
165  return {
166  static_cast<FLOATING_POINT_TYPE>(u - 1/2.),
167  static_cast<FLOATING_POINT_TYPE>(u + 1/2.),
168  static_cast<FLOATING_POINT_TYPE>( -2 * u )
169  };
170  };
171 
172  inline auto get_gauss_nodes() const -> const auto & {
173  static std::vector<GaussNode> gauss_nodes {
174  GaussNode {LocalCoordinates(-1/sqrt(3)), 1}, // Node 0
175  GaussNode {LocalCoordinates(+1/sqrt(3)), 1} // Node 1
176  };
177  return gauss_nodes;
178  }
179 };
180 
181 }
caribou::geometry::Element< Derived >
caribou::geometry::traits
Definition: Element.h:14
caribou::geometry::BaseSegment
Definition: BaseSegment.h:11
caribou::geometry::Segment
Definition: Segment.h:10