Caribou
RectangularHexahedron.h
1 #pragma once
2 
3 #include <Caribou/config.h>
4 #include <Caribou/Geometry/BaseRectangularHexahedron.h>
5 #include <Caribou/Geometry/Hexahedron.h>
6 #include <Caribou/Geometry/RectangularQuad.h>
7 #include <Eigen/Core>
8 
9 namespace caribou::geometry {
10 
11 template<UNSIGNED_INTEGER_TYPE Order = Linear>
13 
14 template<>
15 struct traits<RectangularHexahedron <Linear>> {
16  static constexpr UNSIGNED_INTEGER_TYPE CanonicalDimension = 3;
17  static constexpr UNSIGNED_INTEGER_TYPE Dimension = 3;
18  static constexpr INTEGER_TYPE NumberOfNodesAtCompileTime = 8;
19  static constexpr INTEGER_TYPE NumberOfGaussNodesAtCompileTime = 8;
20 
22  static constexpr INTEGER_TYPE NumberOfBoundaryElementsAtCompileTime = 6;
23 };
24 
44 template<>
45 struct RectangularHexahedron <Linear> : public BaseRectangularHexahedron<RectangularHexahedron <Linear>> {
46  // Types
48  using LocalCoordinates = typename Base::LocalCoordinates;
49  using WorldCoordinates = typename Base::WorldCoordinates;
50 
51  using GaussNode = typename Base::GaussNode;
52 
53  template <UNSIGNED_INTEGER_TYPE Dim>
54  using Vector = typename Base::template Vector<Dim>;
55 
56  template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
57  using Matrix = typename Base::template Matrix<Rows, Cols>;
58 
59  // Constants
60  static constexpr auto CanonicalDimension = Base::CanonicalDimension;
61  static constexpr auto Dimension = Base::Dimension;
62  static constexpr auto NumberOfNodesAtCompileTime = Base::NumberOfNodesAtCompileTime;
63  static constexpr auto NumberOfGaussNodesAtCompileTime = Base::NumberOfGaussNodesAtCompileTime;
64 
65  static constexpr auto canonical_nodes = Hexahedron<Linear>::canonical_nodes;
66 
67  // Constructors
68  using Base::Base;
69 
70  // Constructor from a regular Hexahedron
71  explicit RectangularHexahedron(const Hexahedron<Linear> & hexa) {
72  this->p_center = hexa.center();
73  this->p_H = Size((hexa.node(1)-hexa.node(0)).norm(), (hexa.node(3)-hexa.node(0)).norm(), (hexa.node(4)-hexa.node(0)).norm());
74  this->p_R = hexa.frame({0, 0, 0});
75  };
76 
78  template<typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == NumberOfNodesAtCompileTime)>
79  explicit RectangularHexahedron(Eigen::EigenBase<EigenType> & nodes)
80  : RectangularHexahedron(Hexahedron<Linear>(nodes)) {}
81 
83  template<typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == NumberOfNodesAtCompileTime)>
84  explicit RectangularHexahedron(const Eigen::EigenBase<EigenType> & nodes)
85  : RectangularHexahedron(Hexahedron<Linear>(nodes)) {}
86 
87  // Public methods
92  inline auto edges() const {
93  static const std::array<std::array<UNSIGNED_INTEGER_TYPE, 2>, 12> indices = {{
94  {0, 1}, // Edge 0
95  {1, 2}, // Edge 1
96  {2, 3}, // Edge 2
97  {3, 0}, // Edge 3
98  {4, 5}, // Edge 4
99  {5, 6}, // Edge 5
100  {6, 7}, // Edge 6
101  {7, 4}, // Edge 7
102  {0, 4}, // Edge 8
103  {1, 5}, // Edge 9
104  {2, 6}, // Edge 10
105  {3, 7} // Edge 11
106  }};
107  return indices;
108  }
109 
110 private:
111  // Implementations
112  friend struct Element<RectangularHexahedron <Linear>>;
113  friend struct BaseRectangularHexahedron<RectangularHexahedron <Linear>>;
114  inline auto get_L(const LocalCoordinates & xi) const {
115  const auto & u = xi[0];
116  const auto & v = xi[1];
117  const auto & w = xi[2];
118 
119  Vector<NumberOfNodesAtCompileTime> m;
120  m << (1/8.) * (1 - u) * (1 - v) * (1 - w),
121  (1/8.) * (1 + u) * (1 - v) * (1 - w),
122  (1/8.) * (1 + u) * (1 + v) * (1 - w),
123  (1/8.) * (1 - u) * (1 + v) * (1 - w),
124  (1/8.) * (1 - u) * (1 - v) * (1 + w),
125  (1/8.) * (1 + u) * (1 - v) * (1 + w),
126  (1/8.) * (1 + u) * (1 + v) * (1 + w),
127  (1/8.) * (1 - u) * (1 + v) * (1 + w);
128  return m;
129  };
130 
131  inline auto get_dL(const LocalCoordinates & xi) const {
132  const auto & u = xi[0];
133  const auto & v = xi[1];
134  const auto & w = xi[2];
135 
136  Matrix<NumberOfNodesAtCompileTime, CanonicalDimension> m;
137  // dL/du dL/dv dL/dw
138  m << -1/8. * (1 - v) * (1 - w), -1/8. * (1 - u) * (1 - w), -1/8. * (1 - u) * (1 - v), // Node 0
139  +1/8. * (1 - v) * (1 - w), -1/8. * (1 + u) * (1 - w), -1/8. * (1 + u) * (1 - v), // Node 1
140  +1/8. * (1 + v) * (1 - w), +1/8. * (1 + u) * (1 - w), -1/8. * (1 + u) * (1 + v), // Node 2
141  -1/8. * (1 + v) * (1 - w), +1/8. * (1 - u) * (1 - w), -1/8. * (1 - u) * (1 + v), // Node 3
142  -1/8. * (1 - v) * (1 + w), -1/8. * (1 - u) * (1 + w), +1/8. * (1 - u) * (1 - v), // Node 4
143  +1/8. * (1 - v) * (1 + w), -1/8. * (1 + u) * (1 + w), +1/8. * (1 + u) * (1 - v), // Node 5
144  +1/8. * (1 + v) * (1 + w), +1/8. * (1 + u) * (1 + w), +1/8. * (1 + u) * (1 + v), // Node 6
145  -1/8. * (1 + v) * (1 + w), +1/8. * (1 - u) * (1 + w), +1/8. * (1 - u) * (1 + v); // Node 7
146  return m;
147  };
148 
149  inline auto get_node(const UNSIGNED_INTEGER_TYPE & index) const -> WorldCoordinates {
150  caribou_assert(index < NumberOfNodesAtCompileTime and "Trying to get a node from an invalid node index.");
151  return this->world_coordinates(LocalCoordinates(canonical_nodes[index][0], canonical_nodes[index][1], canonical_nodes[index][2]));
152  }
153 
154  inline auto get_nodes() const {
155  Matrix<NumberOfNodesAtCompileTime, Dimension> nodes;
156  for (UNSIGNED_INTEGER_TYPE node_id = 0; node_id < NumberOfNodesAtCompileTime; ++node_id) {
157  nodes.row(node_id) = get_node(node_id);
158  }
159  return nodes;
160  }
161 
162  inline auto get_gauss_nodes() const -> const auto & {
163  using Weight = FLOATING_POINT_TYPE;
164  static const std::vector<GaussNode> gauss_nodes {
165  GaussNode {LocalCoordinates(-1/sqrt(3), -1/sqrt(3), -1/sqrt(3)), Weight(1)}, // Node 0
166  GaussNode {LocalCoordinates(+1/sqrt(3), -1/sqrt(3), -1/sqrt(3)), Weight(1)}, // Node 1
167  GaussNode {LocalCoordinates(-1/sqrt(3), +1/sqrt(3), -1/sqrt(3)), Weight(1)}, // Node 2
168  GaussNode {LocalCoordinates(+1/sqrt(3), +1/sqrt(3), -1/sqrt(3)), Weight(1)}, // Node 3
169  GaussNode {LocalCoordinates(-1/sqrt(3), -1/sqrt(3), +1/sqrt(3)), Weight(1)}, // Node 4
170  GaussNode {LocalCoordinates(+1/sqrt(3), -1/sqrt(3), +1/sqrt(3)), Weight(1)}, // Node 5
171  GaussNode {LocalCoordinates(-1/sqrt(3), +1/sqrt(3), +1/sqrt(3)), Weight(1)}, // Node 6
172  GaussNode {LocalCoordinates(+1/sqrt(3), +1/sqrt(3), +1/sqrt(3)), Weight(1)} // Node 7
173  };
174  return gauss_nodes;
175  }
176 
177  inline auto get_boundary_elements_nodes() const -> const auto & {
178  static const std::array<std::array<UNSIGNED_INTEGER_TYPE, 4>, 6> indices = {{
179  {0, 3, 2, 1}, // Face 0
180  {0, 4, 7, 3}, // Face 1
181  {1, 2, 6, 5}, // Face 2
182  {0, 1, 5, 4}, // Face 3
183  {2, 3, 7, 6}, // Face 4
184  {4, 5, 6, 7} // Face 5
185  }};
186  return indices;
187  }
188 };
189 
190 
191 template<>
192 struct traits<RectangularHexahedron <Quadratic>> {
193  static constexpr UNSIGNED_INTEGER_TYPE CanonicalDimension = 3;
194  static constexpr UNSIGNED_INTEGER_TYPE Dimension = 3;
195  static constexpr INTEGER_TYPE NumberOfNodesAtCompileTime = 20;
196  static constexpr INTEGER_TYPE NumberOfGaussNodesAtCompileTime = 4;
197 
199  static constexpr INTEGER_TYPE NumberOfBoundaryElementsAtCompileTime = 6;
200 };
201 
223 template<>
224 struct RectangularHexahedron <Quadratic> : public BaseRectangularHexahedron<RectangularHexahedron <Quadratic>> {
225  // Types
227  using LocalCoordinates = typename Base::LocalCoordinates;
228  using WorldCoordinates = typename Base::WorldCoordinates;
229 
230  using GaussNode = typename Base::GaussNode;
231 
232  template <UNSIGNED_INTEGER_TYPE Dim>
233  using Vector = typename Base::template Vector<Dim>;
234 
235  template <UNSIGNED_INTEGER_TYPE Rows, UNSIGNED_INTEGER_TYPE Cols>
236  using Matrix = typename Base::template Matrix<Rows, Cols>;
237 
238  // Constants
239  static constexpr auto CanonicalDimension = Base::CanonicalDimension;
240  static constexpr auto Dimension = Base::Dimension;
241  static constexpr auto NumberOfNodesAtCompileTime = Base::NumberOfNodesAtCompileTime;
242  static constexpr auto NumberOfGaussNodesAtCompileTime = Base::NumberOfGaussNodesAtCompileTime;
243 
244  static constexpr auto canonical_nodes = Hexahedron<Quadratic>::canonical_nodes;
245 
246  // Constructors
247  using Base::Base;
248 
249  // Constructor from a regular Hexahedron
250  template<UNSIGNED_INTEGER_TYPE Order>
251  explicit RectangularHexahedron(const Hexahedron<Order> & hexa) {
252  this->p_center = hexa.center();
253  this->p_H = Size((hexa.node(1)-hexa.node(0)).norm(), (hexa.node(3)-hexa.node(0)).norm(), (hexa.node(4)-hexa.node(0)).norm());
254  this->p_R = hexa.frame({0, 0, 0});
255  }
256 
258  template<typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == NumberOfNodesAtCompileTime)>
259  explicit RectangularHexahedron(Eigen::EigenBase<EigenType> & nodes)
260  : RectangularHexahedron(Hexahedron<Quadratic>(nodes)) {}
261 
263  template<typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == NumberOfNodesAtCompileTime)>
264  explicit RectangularHexahedron(const Eigen::EigenBase<EigenType> & nodes)
265  : RectangularHexahedron(Hexahedron<Quadratic>(nodes)) {}
266 
268  template<typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == 8)>
269  explicit RectangularHexahedron(Eigen::EigenBase<EigenType> & nodes)
270  : RectangularHexahedron(Hexahedron<Linear>(nodes)) {}
271 
273  template<typename EigenType, REQUIRES(EigenType::RowsAtCompileTime == 8)>
274  explicit RectangularHexahedron(const Eigen::EigenBase<EigenType> & nodes)
275  : RectangularHexahedron(Hexahedron<Linear>(nodes)) {}
276 
277  // Public methods
282  inline auto edges() const {
283  static const std::array<std::array<UNSIGNED_INTEGER_TYPE, 3>, 12> indices = {{
284  {0, 1, 8}, // Edge 0
285  {1, 2, 9}, // Edge 1
286  {2, 3, 10}, // Edge 2
287  {3, 0, 11}, // Edge 3
288  {4, 5, 12}, // Edge 4
289  {5, 6, 13}, // Edge 5
290  {6, 7, 14}, // Edge 6
291  {7, 4, 15}, // Edge 7
292  {0, 4, 16}, // Edge 8
293  {1, 5, 17}, // Edge 9
294  {2, 6, 18}, // Edge 10
295  {3, 7, 19} // Edge 11
296  }};
297  return indices;
298  }
299 
300 private:
301  // Implementations
302  friend struct Element<RectangularHexahedron <Quadratic>>;
303  friend struct BaseRectangularHexahedron<RectangularHexahedron <Quadratic>>;
304  inline auto get_L(const LocalCoordinates & xi) const {
305  const auto & u = xi[0];
306  const auto & v = xi[1];
307  const auto & w = xi[2];
308 
309  Vector<NumberOfNodesAtCompileTime> m;
310  m[ 8] = 1/4.*(1 - u*u)*(1 - v)*(1 - w);
311  m[ 9] = 1/4.*(1 - v*v)*(1 + u)*(1 - w);
312  m[10] = 1/4.*(1 - u*u)*(1 + v)*(1 - w);
313  m[11] = 1/4.*(1 - v*v)*(1 - u)*(1 - w);
314  m[12] = 1/4.*(1 - u*u)*(1 - v)*(1 + w);
315  m[13] = 1/4.*(1 - v*v)*(1 + u)*(1 + w);
316  m[14] = 1/4.*(1 - u*u)*(1 + v)*(1 + w);
317  m[15] = 1/4.*(1 - v*v)*(1 - u)*(1 + w);
318  m[16] = 1/4.*(1 - w*w)*(1 - u)*(1 - v);
319  m[17] = 1/4.*(1 - w*w)*(1 + u)*(1 - v);
320  m[18] = 1/4.*(1 - w*w)*(1 + u)*(1 + v);
321  m[19] = 1/4.*(1 - w*w)*(1 - u)*(1 + v);
322 
323  m[0] = 1/8.*(1 - u)*(1 - v)*(1 - w) - 1/2.*(m[ 8] + m[11] + m[16]);
324  m[1] = 1/8.*(1 + u)*(1 - v)*(1 - w) - 1/2.*(m[ 8] + m[ 9] + m[17]);
325  m[2] = 1/8.*(1 + u)*(1 + v)*(1 - w) - 1/2.*(m[ 9] + m[10] + m[18]);
326  m[3] = 1/8.*(1 - u)*(1 + v)*(1 - w) - 1/2.*(m[10] + m[11] + m[19]);
327  m[4] = 1/8.*(1 - u)*(1 - v)*(1 + w) - 1/2.*(m[12] + m[15] + m[16]);
328  m[5] = 1/8.*(1 + u)*(1 - v)*(1 + w) - 1/2.*(m[12] + m[13] + m[17]);
329  m[6] = 1/8.*(1 + u)*(1 + v)*(1 + w) - 1/2.*(m[13] + m[14] + m[18]);
330  m[7] = 1/8.*(1 - u)*(1 + v)*(1 + w) - 1/2.*(m[14] + m[15] + m[19]);
331  return m;
332  };
333 
334  inline auto get_dL(const LocalCoordinates & xi) const {
335  using ShapeDerivative = Vector<3>;
336  const auto & u = xi[0];
337  const auto & v = xi[1];
338  const auto & w = xi[2];
339 
340  Matrix<NumberOfNodesAtCompileTime, CanonicalDimension> m;
341 
342  // dL/du dL/dv dL/dw
343  m.row( 8) = ShapeDerivative({-1/2.*u*(1 - v)*(1 - w), -1/4.*(1 - u*u)*(1 - w), -1/4.*(1 - u*u)*(1 - v)});
344  m.row( 9) = ShapeDerivative({ 1/4.*(1 - v*v)*(1 - w), -1/2.*v*(1 + u)*(1 - w), -1/4.*(1 - v*v)*(1 + u)});
345  m.row(10) = ShapeDerivative({-1/2.*u*(1 + v)*(1 - w), 1/4.*(1 - u*u)*(1 - w), -1/4.*(1 - u*u)*(1 + v)});
346  m.row(11) = ShapeDerivative({-1/4.*(1 - v*v)*(1 - w), -1/2.*v*(1 - u)*(1 - w), -1/4.*(1 - v*v)*(1 - u)});
347  m.row(12) = ShapeDerivative({-1/2.*u*(1 - v)*(1 + w), -1/4.*(1 - u*u)*(1 + w), 1/4.*(1 - u*u)*(1 - v)});
348  m.row(13) = ShapeDerivative({ 1/4.*(1 - v*v)*(1 + w), -1/2.*v*(1 + u)*(1 + w), 1/4.*(1 - v*v)*(1 + u)});
349  m.row(14) = ShapeDerivative({-1/2.*u*(1 + v)*(1 + w), 1/4.*(1 - u*u)*(1 + w), 1/4.*(1 - u*u)*(1 + v)});
350  m.row(15) = ShapeDerivative({-1/4.*(1 - v*v)*(1 + w), -1/2.*v*(1 - u)*(1 + w), 1/4.*(1 - v*v)*(1 - u)});
351  m.row(16) = ShapeDerivative({-1/4.*(1 - w*w)*(1 - v), -1/4.*(1 - w*w)*(1 - u), -1/2.*w*(1 - u)*(1 - v)});
352  m.row(17) = ShapeDerivative({ 1/4.*(1 - w*w)*(1 - v), -1/4.*(1 - w*w)*(1 + u), -1/2.*w*(1 + u)*(1 - v)});
353  m.row(18) = ShapeDerivative({ 1/4.*(1 - w*w)*(1 + v), 1/4.*(1 - w*w)*(1 + u), -1/2.*w*(1 + u)*(1 + v)});
354  m.row(19) = ShapeDerivative({-1/4.*(1 - w*w)*(1 + v), 1/4.*(1 - w*w)*(1 - u), -1/2.*w*(1 - u)*(1 + v)});
355 
356  const auto du = m.col(0); // dL/du
357  const auto dv = m.col(1); // dL/dv
358  const auto dw = m.col(2); // dL/dw
359  // dL/du dL/dv dL/dw
360  m.row(0) = ShapeDerivative({-1/8.*(1 - v)*(1 - w) - 1/2.*(du[8 ] + du[11] + du[16]), -1/8.*(1 - u)*(1 - w) - 1/2.*(dv[ 8] + dv[11] + dv[16]), -1/8.*(1 - u)*(1 - v) - 1/2.*(dw[ 8] + dw[11] + dw[16])});
361  m.row(1) = ShapeDerivative({ 1/8.*(1 - v)*(1 - w) - 1/2.*(du[8 ] + du[ 9] + du[17]), -1/8.*(1 + u)*(1 - w) - 1/2.*(dv[ 8] + dv[ 9] + dv[17]), -1/8.*(1 + u)*(1 - v) - 1/2.*(dw[ 8] + dw[ 9] + dw[17])});
362  m.row(2) = ShapeDerivative({ 1/8.*(1 + v)*(1 - w) - 1/2.*(du[9 ] + du[10] + du[18]), 1/8.*(1 + u)*(1 - w) - 1/2.*(dv[ 9] + dv[10] + dv[18]), -1/8.*(1 + u)*(1 + v) - 1/2.*(dw[ 9] + dw[10] + dw[18])});
363  m.row(3) = ShapeDerivative({-1/8.*(1 + v)*(1 - w) - 1/2.*(du[10] + du[11] + du[19]), 1/8.*(1 - u)*(1 - w) - 1/2.*(dv[10] + dv[11] + dv[19]), -1/8.*(1 - u)*(1 + v) - 1/2.*(dw[10] + dw[11] + dw[19])});
364  m.row(4) = ShapeDerivative({-1/8.*(1 - v)*(1 + w) - 1/2.*(du[12] + du[15] + du[16]), -1/8.*(1 - u)*(1 + w) - 1/2.*(dv[12] + dv[15] + dv[16]), 1/8.*(1 - u)*(1 - v) - 1/2.*(dw[12] + dw[15] + dw[16])});
365  m.row(5) = ShapeDerivative({ 1/8.*(1 - v)*(1 + w) - 1/2.*(du[12] + du[13] + du[17]), -1/8.*(1 + u)*(1 + w) - 1/2.*(dv[12] + dv[13] + dv[17]), 1/8.*(1 + u)*(1 - v) - 1/2.*(dw[12] + dw[13] + dw[17])});
366  m.row(6) = ShapeDerivative({ 1/8.*(1 + v)*(1 + w) - 1/2.*(du[13] + du[14] + du[18]), 1/8.*(1 + u)*(1 + w) - 1/2.*(dv[13] + dv[14] + dv[18]), 1/8.*(1 + u)*(1 + v) - 1/2.*(dw[13] + dw[14] + dw[18])});
367  m.row(7) = ShapeDerivative({-1/8.*(1 + v)*(1 + w) - 1/2.*(du[14] + du[15] + du[19]), 1/8.*(1 - u)*(1 + w) - 1/2.*(dv[14] + dv[15] + dv[19]), 1/8.*(1 - u)*(1 + v) - 1/2.*(dw[14] + dw[15] + dw[19])});
368 
369 
370  return m;
371  };
372 
373  inline auto get_node(const UNSIGNED_INTEGER_TYPE & index) const -> WorldCoordinates {
374  caribou_assert(index < NumberOfNodesAtCompileTime and "Trying to get a node from an invalid node index.");
375  return this->world_coordinates(LocalCoordinates(canonical_nodes[index][0], canonical_nodes[index][1], canonical_nodes[index][2]));
376  }
377 
378  inline auto get_nodes() const {
379  Matrix<NumberOfNodesAtCompileTime, Dimension> nodes;
380  for (UNSIGNED_INTEGER_TYPE node_id = 0; node_id < NumberOfNodesAtCompileTime; ++node_id) {
381  nodes.row(node_id) = get_node(node_id);
382  }
383  return nodes;
384  }
385 
386  inline auto get_gauss_nodes() const -> const auto & {
387  using Weight = FLOATING_POINT_TYPE;
388  static const std::vector<GaussNode> gauss_nodes {
389  GaussNode {LocalCoordinates(-1/sqrt(3), -1/sqrt(3), -1/sqrt(3)), Weight(1)}, // Node 0
390  GaussNode {LocalCoordinates(+1/sqrt(3), -1/sqrt(3), -1/sqrt(3)), Weight(1)}, // Node 1
391  GaussNode {LocalCoordinates(-1/sqrt(3), +1/sqrt(3), -1/sqrt(3)), Weight(1)}, // Node 2
392  GaussNode {LocalCoordinates(+1/sqrt(3), +1/sqrt(3), -1/sqrt(3)), Weight(1)}, // Node 3
393  GaussNode {LocalCoordinates(-1/sqrt(3), -1/sqrt(3), +1/sqrt(3)), Weight(1)}, // Node 4
394  GaussNode {LocalCoordinates(+1/sqrt(3), -1/sqrt(3), +1/sqrt(3)), Weight(1)}, // Node 5
395  GaussNode {LocalCoordinates(-1/sqrt(3), +1/sqrt(3), +1/sqrt(3)), Weight(1)}, // Node 6
396  GaussNode {LocalCoordinates(+1/sqrt(3), +1/sqrt(3), +1/sqrt(3)), Weight(1)} // Node 7
397  };
398  return gauss_nodes;
399  }
400 
401  inline auto get_boundary_elements_nodes() const -> const auto & {
402  static const std::array<std::array<UNSIGNED_INTEGER_TYPE, 8>, 6> indices = {{
403  {0, 3, 2, 1, 9, 13, 11, 8}, // Face 0
404  {0, 4, 7, 3, 10, 17, 15, 9}, // Face 1
405  {1, 2, 6, 5, 11, 14, 18, 12}, // Face 2
406  {0, 1, 5, 4, 8, 12, 16, 10}, // Face 3
407  {2, 3, 7, 6, 13, 15, 19, 14}, // Face 4
408  {4, 5, 6, 7, 16, 18, 19, 17} // Face 5
409  }};
410  return indices;
411  }
412 };
413 
414 }
caribou::geometry::BaseRectangularHexahedron
Base class for rectangular hexahedral elements.
Definition: BaseRectangularHexahedron.h:18
caribou::geometry::Hexahedron
Definition: Hexahedron.h:11
caribou::geometry::BaseHexahedron::frame
auto frame() const -> Matrix< 3, 3 >
Extract the orthogonal frame of the element by computing the cross product of the unit vectors from t...
Definition: BaseHexahedron.h:80
caribou::geometry::Element< Derived >
caribou::geometry::RectangularHexahedron< Linear >::RectangularHexahedron
RectangularHexahedron(const Eigen::EigenBase< EigenType > &nodes)
Constructor from an Eigen matrix containing the positions of the hexa's nodes.
Definition: RectangularHexahedron.h:84
caribou::geometry::RectangularHexahedron< Quadratic >::edges
auto edges() const
Get the list of node indices of the edges.
Definition: RectangularHexahedron.h:282
caribou::geometry::RectangularQuad
Definition: RectangularQuad.h:13
caribou::geometry::traits
Definition: Element.h:14
caribou::geometry::Element::node
auto node(const UNSIGNED_INTEGER_TYPE &index) const
Get the Node at given index.
Definition: Element.h:64
caribou::geometry::RectangularHexahedron< Linear >::edges
auto edges() const
Get the list of node indices of the edges.
Definition: RectangularHexahedron.h:92
caribou::geometry::RectangularHexahedron< Quadratic >::RectangularHexahedron
RectangularHexahedron(Eigen::EigenBase< EigenType > &nodes)
Constructor from an Eigen matrix containing the positions of an quadratic hexa nodes.
Definition: RectangularHexahedron.h:259
caribou::geometry::RectangularHexahedron< Linear >::RectangularHexahedron
RectangularHexahedron(Eigen::EigenBase< EigenType > &nodes)
Constructor from an Eigen matrix containing the positions of the hexa's nodes.
Definition: RectangularHexahedron.h:79
caribou::geometry::Element::center
auto center() const -> WorldCoordinates
Get the position at the center of the element.
Definition: Element.h:154
caribou::geometry::RectangularHexahedron< Quadratic >::RectangularHexahedron
RectangularHexahedron(const Eigen::EigenBase< EigenType > &nodes)
Constructor from an Eigen matrix containing the positions of an quadratic hexa nodes.
Definition: RectangularHexahedron.h:264
caribou::geometry::Hexahedron< Linear >
Linear Hexahedron.
Definition: Hexahedron.h:44
caribou::geometry::RectangularHexahedron
Definition: RectangularHexahedron.h:12