OGS
NaturalCoordinatesMapping.cpp
Go to the documentation of this file.
1 
12 
13 #include <cassert>
14 #ifndef NDEBUG
15 #include <iostream>
16 #endif // NDEBUG
17 
18 #include "BaseLib/Error.h"
54 #include "ShapeMatrices.h"
55 
56 namespace NumLib
57 {
58 namespace detail
59 {
60 template <ShapeMatrixType FIELD_TYPE>
61 struct FieldType
62 {
63 };
64 
65 template <class T_MESH_ELEMENT, class T_SHAPE_FUNC, class T_SHAPE_MATRICES>
67  const T_MESH_ELEMENT& /*ele*/,
68  const double* natural_pt,
69  const MeshLib::ElementCoordinatesMappingLocal& /*ele_local_coord*/,
70  T_SHAPE_MATRICES& shapemat,
72 {
73  T_SHAPE_FUNC::computeShapeFunction(natural_pt, shapemat.N);
74 }
75 
76 template <class T_MESH_ELEMENT, class T_SHAPE_FUNC, class T_SHAPE_MATRICES>
78  const T_MESH_ELEMENT& /*ele*/,
79  [[maybe_unused]] const double* natural_pt,
80  const MeshLib::ElementCoordinatesMappingLocal& /*ele_local_coord*/,
81  [[maybe_unused]] T_SHAPE_MATRICES& shapemat,
83 {
84  if constexpr (T_SHAPE_FUNC::DIM != 0)
85  {
86  double* const dNdr = shapemat.dNdr.data();
87  T_SHAPE_FUNC::computeGradShapeFunction(natural_pt, dNdr);
88  }
89 }
90 
91 static void checkJacobianDeterminant(const double detJ,
92  MeshLib::Element const& element)
93 {
94  if (detJ > 0)
95  { // The usual case
96  return;
97  }
98 
99  if (detJ < 0)
100  {
101  ERR("det J = {:g} is negative for element {:d}.",
102  detJ,
103  element.getID());
104 #ifndef NDEBUG
105  std::cerr << element << "\n";
106 #endif // NDEBUG
107  OGS_FATAL(
108  "Please check whether the node numbering of the element is correct,"
109  "or additional elements (like boundary elements) are still present "
110  "in the mesh.");
111  }
112 
113  if (detJ == 0)
114  {
115  ERR("det J is zero for element {:d}.", element.getID());
116 #ifndef NDEBUG
117  std::cerr << element << "\n";
118 #endif // NDEBUG
119  OGS_FATAL(
120  "Please check whether:\n"
121  "\t the element nodes may have the same coordinates,\n"
122  "\t or the coordinates of all nodes are not given on the x-axis "
123  "for a 1D problem or in the xy-plane in the 2D case.\n"
124  "The first case can occur, if not all boundary elements"
125  "were removed from the bulk mesh.");
126  }
127 }
128 
129 template <class T_MESH_ELEMENT, class T_SHAPE_FUNC, class T_SHAPE_MATRICES>
131  const T_MESH_ELEMENT& ele,
132  [[maybe_unused]] const double* natural_pt,
133  const MeshLib::ElementCoordinatesMappingLocal& ele_local_coord,
134  T_SHAPE_MATRICES& shapemat,
136 {
137  if constexpr (T_SHAPE_FUNC::DIM != 0)
138  {
139  computeMappingMatrices<T_MESH_ELEMENT, T_SHAPE_FUNC, T_SHAPE_MATRICES>(
140  ele,
141  natural_pt,
142  ele_local_coord,
143  shapemat,
145 
146  auto const dim = T_MESH_ELEMENT::dimension;
147  auto const nnodes = T_MESH_ELEMENT::n_all_nodes;
148 
149  // jacobian: J=[dx/dr dy/dr // dx/ds dy/ds]
150  for (auto k = decltype(nnodes){0}; k < nnodes; k++)
151  {
152  const MathLib::Point3d& mapped_pt =
153  ele_local_coord.getMappedCoordinates(k);
154  // outer product of dNdr and mapped_pt for a particular node
155  for (auto i_r = decltype(dim){0}; i_r < dim; i_r++)
156  {
157  for (auto j_x = decltype(dim){0}; j_x < dim; j_x++)
158  {
159  shapemat.J(i_r, j_x) +=
160  shapemat.dNdr(i_r, k) * mapped_pt[j_x];
161  }
162  }
163  }
164 
165  shapemat.detJ = shapemat.J.determinant();
166  checkJacobianDeterminant(shapemat.detJ, ele);
167  }
168  else
169  {
170  shapemat.detJ = 1.0;
171  }
172 }
173 
174 template <class T_MESH_ELEMENT, class T_SHAPE_FUNC, class T_SHAPE_MATRICES>
176  const T_MESH_ELEMENT& ele,
177  const double* natural_pt,
178  const MeshLib::ElementCoordinatesMappingLocal& ele_local_coord,
179  T_SHAPE_MATRICES& shapemat,
181 {
182  computeMappingMatrices<T_MESH_ELEMENT, T_SHAPE_FUNC, T_SHAPE_MATRICES>(
183  ele,
184  natural_pt,
185  ele_local_coord,
186  shapemat,
188  computeMappingMatrices<T_MESH_ELEMENT, T_SHAPE_FUNC, T_SHAPE_MATRICES>(
189  ele,
190  natural_pt,
191  ele_local_coord,
192  shapemat,
194 }
195 
196 template <class T_MESH_ELEMENT, class T_SHAPE_FUNC, class T_SHAPE_MATRICES>
198  const T_MESH_ELEMENT& ele,
199  const double* natural_pt,
200  const MeshLib::ElementCoordinatesMappingLocal& ele_local_coord,
201  T_SHAPE_MATRICES& shapemat,
203 {
204  computeMappingMatrices<T_MESH_ELEMENT, T_SHAPE_FUNC, T_SHAPE_MATRICES>(
205  ele,
206  natural_pt,
207  ele_local_coord,
208  shapemat,
210  if constexpr (T_SHAPE_FUNC::DIM != 0)
211  {
212  checkJacobianDeterminant(shapemat.detJ, ele);
213 
214  // J^-1, dshape/dx
215  shapemat.invJ.noalias() = shapemat.J.inverse();
216 
217  assert(shapemat.dNdr.rows() == ele.getDimension());
218  shapemat.dNdx
219  .template topLeftCorner<T_SHAPE_FUNC::DIM, T_SHAPE_FUNC::NPOINTS>()
220  .noalias() = shapemat.invJ * shapemat.dNdr;
221  }
222 }
223 
224 template <class T_MESH_ELEMENT, class T_SHAPE_FUNC, class T_SHAPE_MATRICES>
226  const T_MESH_ELEMENT& ele,
227  const double* natural_pt,
228  const MeshLib::ElementCoordinatesMappingLocal& ele_local_coord,
229  T_SHAPE_MATRICES& shapemat,
231 {
232  computeMappingMatrices<T_MESH_ELEMENT, T_SHAPE_FUNC, T_SHAPE_MATRICES>(
233  ele,
234  natural_pt,
235  ele_local_coord,
236  shapemat,
238  computeMappingMatrices<T_MESH_ELEMENT, T_SHAPE_FUNC, T_SHAPE_MATRICES>(
239  ele,
240  natural_pt,
241  ele_local_coord,
242  shapemat,
244 }
245 
246 template <class T_MESH_ELEMENT,
247  class T_SHAPE_FUNC,
248  class T_SHAPE_MATRICES,
249  ShapeMatrixType T_SHAPE_MATRIX_TYPE>
250 void naturalCoordinatesMappingComputeShapeMatrices(const T_MESH_ELEMENT& ele,
251  const double* natural_pt,
252  T_SHAPE_MATRICES& shapemat,
253  const unsigned global_dim)
254 {
255  const MeshLib::ElementCoordinatesMappingLocal ele_local_coord(ele,
256  global_dim);
257 
258  detail::
259  computeMappingMatrices<T_MESH_ELEMENT, T_SHAPE_FUNC, T_SHAPE_MATRICES>(
260  ele,
261  natural_pt,
262  ele_local_coord,
263  shapemat,
265 }
266 
267 #define OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
268  RULE, SHAPE, DIM, WHICHPART, SHAPEMATRIXPOLICY) \
269  template void naturalCoordinatesMappingComputeShapeMatrices< \
270  MeshLib::TemplateElement<MeshLib::RULE>, \
271  NumLib::SHAPE, \
272  SHAPEMATRIXPOLICY<NumLib::SHAPE, DIM>::ShapeMatrices, \
273  ShapeMatrixType::WHICHPART>( \
274  MeshLib::TemplateElement<MeshLib::RULE> const&, \
275  double const*, \
276  SHAPEMATRIXPOLICY<NumLib::SHAPE, DIM>::ShapeMatrices&, \
277  const unsigned global_dim)
278 
279 #define OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_DYN(RULE, SHAPE) \
280  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
281  RULE, SHAPE, 0, ALL, EigenDynamicShapeMatrixPolicy); \
282  /* Those instantiations are needed in unit tests only */ \
283  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
284  RULE, SHAPE, 0, N, EigenDynamicShapeMatrixPolicy); \
285  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
286  RULE, SHAPE, 0, DNDR, EigenDynamicShapeMatrixPolicy); \
287  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
288  RULE, SHAPE, 0, N_J, EigenDynamicShapeMatrixPolicy); \
289  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
290  RULE, SHAPE, 0, DNDR_J, EigenDynamicShapeMatrixPolicy); \
291  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
292  RULE, SHAPE, 0, DNDX, EigenDynamicShapeMatrixPolicy)
293 
294 #define OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_FIX(RULE, SHAPE, DIM) \
295  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
296  RULE, SHAPE, DIM, ALL, EigenFixedShapeMatrixPolicy); \
297  /* Those instantiations are needed in unit tests only */ \
298  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
299  RULE, SHAPE, DIM, N, EigenFixedShapeMatrixPolicy); \
300  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
301  RULE, SHAPE, DIM, DNDR, EigenFixedShapeMatrixPolicy); \
302  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
303  RULE, SHAPE, DIM, N_J, EigenFixedShapeMatrixPolicy); \
304  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
305  RULE, SHAPE, DIM, DNDR_J, EigenFixedShapeMatrixPolicy); \
306  OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_PART( \
307  RULE, SHAPE, DIM, DNDX, EigenFixedShapeMatrixPolicy)
308 
325 
342 
359 
376 
377 } // namespace detail
378 
379 } // namespace NumLib
#define OGS_FATAL(...)
Definition: Error.h:26
void ERR(char const *fmt, Args const &... args)
Definition: Logging.h:42
MathLib::Point3d const & getMappedCoordinates(std::size_t node_id) const
return mapped coordinates of the node
virtual std::size_t getID() const final
Returns the ID of the element.
Definition: Element.h:82
Shape function for a point element in natural coordinates.
Definition: ShapePoint1.h:19
void naturalCoordinatesMappingComputeShapeMatrices(const T_MESH_ELEMENT &ele, const double *natural_pt, T_SHAPE_MATRICES &shapemat, const unsigned global_dim)
Used to explicitly instantiate the NaturalCoordinatesMapping class template.
void computeMappingMatrices(const T_MESH_ELEMENT &, const double *natural_pt, const MeshLib::ElementCoordinatesMappingLocal &, T_SHAPE_MATRICES &shapemat, FieldType< ShapeMatrixType::N >)
static void checkJacobianDeterminant(const double detJ, MeshLib::Element const &element)
OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_FIX(HexRule20, ShapeHex20, 1)
OGS_INSTANTIATE_NATURAL_COORDINATES_MAPPING_DYN(HexRule20, ShapeHex20)
ShapeMatrixType
Shape matrix type to be calculated.
Definition: ShapeMatrices.h:24