Nektar++
Geometry.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: Geometry.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: This file contains the base class implementation for the
32 // Geometry class.
33 //
34 //
35 ////////////////////////////////////////////////////////////////////////////////
36 
37 #include <boost/core/ignore_unused.hpp>
38 
42 
43 namespace Nektar
44 {
45 namespace SpatialDomains
46 {
47 
48 // static class property
50 
51 /**
52  * @brief Default constructor.
53  */
55  : m_coordim(0), m_geomFactorsState(eNotFilled), m_state(eNotFilled), m_setupState(false),
56  m_shapeType(LibUtilities::eNoShapeType), m_globalID(-1)
57 {
58 }
59 
60 /**
61  * @brief Constructor when supplied a coordinate dimension.
62  */
63 Geometry::Geometry(const int coordim)
65  m_shapeType(LibUtilities::eNoShapeType), m_globalID(-1)
66 {
67 }
68 
69 /**
70  * @brief Default destructor.
71  */
73 {
74 }
75 
76 /**
77  * @brief Check to see if a geometric factor has already been created that
78  * contains the same regular information.
79  *
80  * The principle behind this is that many regular (i.e. constant Jacobian)
81  * elements have identicial geometric factors. Memory may therefore be reduced
82  * by storing only the unique factors.
83  *
84  * @param geomFactor The GeomFactor to check.
85  *
86  * @return Either the cached GeomFactor or @p geomFactor.
87  *
88  * @todo Currently this method is disabled since the lookup is very expensive.
89  */
91  GeomFactorsSharedPtr geomFactor)
92 {
93  GeomFactorsSharedPtr returnval = geomFactor;
94 
95 /// \todo should this '#if 0' statement be removed?
96 #if 0
97  bool found = false;
98  if (geomFactor->GetGtype() == eRegular)
99  {
100  for (GeomFactorsVectorIter iter = m_regGeomFactorsManager.begin();
101  iter != m_regGeomFactorsManager.end();
102  ++iter)
103  {
104  if (**iter == *geomFactor)
105  {
106  returnval = *iter;
107  found = true;
108  break;
109  }
110  }
111 
112  if (!found)
113  {
114  m_regGeomFactorsManager.push_back(geomFactor);
115  returnval = geomFactor;
116  }
117  }
118 #endif
119  return returnval;
120 }
121 
122 bool SortByGlobalId(const std::shared_ptr<Geometry> &lhs,
123  const std::shared_ptr<Geometry> &rhs)
124 {
125  return lhs->GetGlobalID() < rhs->GetGlobalID();
126 }
127 
128 bool GlobalIdEquality(const std::shared_ptr<Geometry> &lhs,
129  const std::shared_ptr<Geometry> &rhs)
130 {
131  return lhs->GetGlobalID() == rhs->GetGlobalID();
132 }
133 
134 /**
135  * @brief Get the ID of vertex @p i of this object.
136  */
137 int Geometry::GetVid(int i) const
138 {
139  return GetVertex(i)->GetGlobalID();
140 }
141 
142 /**
143  * @brief Get the ID of edge @p i of this object.
144  */
145 int Geometry::GetEid(int i) const
146 {
147  return GetEdge(i)->GetGlobalID();
148 }
149 
150 /**
151  * @brief Get the ID of face @p i of this object.
152  */
153 int Geometry::GetFid(int i) const
154 {
155  return GetFace(i)->GetGlobalID();
156 }
157 
158 /**
159  * @copydoc Geometry::GetEdge()
160  */
162 {
163  boost::ignore_unused(i);
165  "This function is only valid for shape type geometries");
166  return Geometry1DSharedPtr();
167 }
168 
169 /**
170  * @copydoc Geometry::GetFace()
171  */
173 {
174  boost::ignore_unused(i);
176  "This function is only valid for shape type geometries");
177  return Geometry2DSharedPtr();
178 }
179 
180 /**
181  * @copydoc Geometry::GetNumVerts()
182  */
184 {
186  "This function is only valid for shape type geometries");
187  return 0;
188 }
189 
190 /**
191  * @copydoc Geometry::GetEorient()
192  */
194 {
195  boost::ignore_unused(i);
197  "This function is not valid for this geometry.");
198  return StdRegions::eForwards;
199 }
200 
201 /**
202  * @copydoc Geometry::GetForient()
203  */
205 {
206  boost::ignore_unused(i);
208  "This function is not valid for this geometry.");
209  return StdRegions::eFwd;
210 }
211 
212 /**
213  * @copydoc Geometry::GetNumEdges()
214  */
216 {
218  "This function is only valid for shape type geometries");
219  return 0;
220 }
221 
222 /**
223  * @copydoc Geometry::GetNumFaces()
224  */
226 {
228  "This function is only valid for shape type geometries");
229  return 0;
230 }
231 
232 /**
233  * @copydoc Geometry::GetShapeDim()
234  */
236 {
238  "This function is only valid for shape type geometries");
239  return 0;
240 }
241 
242 /**
243  * @copydoc Geometry::GetXmap()
244  */
246 {
247  return m_xmap;
248 }
249 
250 /**
251  * @copydoc Geometry::ContainsPoint(
252  * const Array<OneD, const NekDouble> &, Array<OneD, NekDouble> &,
253  * NekDouble, NekDouble&)
254  */
256  Array<OneD, NekDouble> &locCoord,
257  NekDouble tol,
258  NekDouble &resid)
259 {
260  boost::ignore_unused(gloCoord, locCoord, tol, resid);
262  "This function has not been defined for this geometry");
263  return false;
264 }
265 
266 /**
267  * @copydoc Geometry::GetVertexEdgeMap()
268  */
269 int Geometry::v_GetVertexEdgeMap(const int i, const int j) const
270 {
271  boost::ignore_unused(i, j);
273  "This function has not been defined for this geometry");
274  return 0;
275 }
276 
277 /**
278  * @copydoc Geometry::GetVertexFaceMap()
279  */
280 int Geometry::v_GetVertexFaceMap(const int i, const int j) const
281 {
282  boost::ignore_unused(i, j);
284  "This function has not been defined for this geometry");
285  return 0;
286 }
287 
288 /**
289  * @copydoc Geometry::GetEdgeFaceMap()
290  */
291 int Geometry::v_GetEdgeFaceMap(const int i, const int j) const
292 {
293  boost::ignore_unused(i, j);
295  "This function has not been defined for this geometry");
296  return 0;
297 }
298 
299 /**
300  * @copydoc Geometry::GetCoord()
301  */
303  const Array<OneD, const NekDouble> &Lcoord)
304 {
305  boost::ignore_unused(i, Lcoord);
307  "This function is only valid for expansion type geometries");
308  return 0.0;
309 }
310 
311 /**
312  * @copydoc Geometry::GetLocCoords()
313  */
315  Array<OneD, NekDouble> &Lcoords)
316 {
317  boost::ignore_unused(coords, Lcoords);
319  "This function is only valid for expansion type geometries");
320  return 0.0;
321 }
322 
323 /**
324  * @copydoc Geometry::FillGeom()
325  */
327 {
329  "This function is only valid for expansion type geometries");
330 }
331 
332 /**
333  * @copydoc Geometry::Reset()
334  */
335 void Geometry::v_Reset(CurveMap &curvedEdges, CurveMap &curvedFaces)
336 {
337  boost::ignore_unused(curvedEdges, curvedFaces);
338 
339  // Reset state
342 
343  // Junk geometric factors
345 }
346 
348 {
350  "This function is only valid for expansion type geometries");
351 }
352 
353 
354 /**
355  * @brief Generates the bounding box for the element.
356  *
357  * For regular elements, the vertices are sufficient to define the extent of
358  * the bounding box. For non-regular elements, the extremes of the quadrature
359  * point coordinates are used. A 10% margin is added around this computed
360  * region to account for convex hull elements where the true extent of the
361  * element may extend slightly beyond the quadrature points.
362  */
363 std::array<NekDouble, 6> Geometry::GetBoundingBox()
364 {
365  //NekDouble minx, miny, minz, maxx, maxy, maxz;
366  Array<OneD, NekDouble> min(3), max(3);
367 
368  // Always get vertexes min/max
370  Array<OneD, NekDouble> x(3, 0.0);
371  p->GetCoords(x[0], x[1], x[2]);
372  for (int j = 0; j < 3; ++j)
373  {
374  min[j] = x[j];
375  max[j] = x[j];
376  }
377  for (int i = 1; i < GetNumVerts(); ++i)
378  {
379  p = GetVertex(i);
380  p->GetCoords(x[0], x[1], x[2]);
381  for (int j = 0; j < 3; ++j)
382  {
383  min[j] = (x[j] < min[j] ? x[j] : min[j]);
384  max[j] = (x[j] > max[j] ? x[j] : max[j]);
385  }
386  }
387  // If element is deformed loop over quadrature points
388  if (GetGeomFactors()->GetGtype() != eRegular)
389  {
390  const int nq = GetXmap()->GetTotPoints();
392  for (int j = 0; j < 3; ++j)
393  {
394  x[j] = Array<OneD, NekDouble>(nq, 0.0);
395  }
396  for (int j = 0; j < GetCoordim(); ++j)
397  {
398  GetXmap()->BwdTrans(m_coeffs[j], x[j]);
399  }
400  for (int j = 0; j < 3; ++j)
401  {
402  for (int i = 0; i < nq; ++i)
403  {
404  min[j] = (x[j][i] < min[j] ? x[j][i] : min[j]);
405  max[j] = (x[j][i] > max[j] ? x[j][i] : max[j]);
406  }
407 
408  // Add 10% margin to bounding box in case elements have
409  // convex boundaries.
410  const NekDouble len = max[j] - min[j];
411  max[j] += 0.1*len;
412  min[j] -= 0.1*len;
413  }
414  }
415  // Add geometric tolerance
416  for (int j = 0; j < 3; ++j)
417  {
418  const NekDouble len = max[j] - min[j];
419  min[j] -= NekConstants::kGeomFactorsTol*len;
420  max[j] += NekConstants::kGeomFactorsTol*len;
421  }
422 
423  // Return bounding box
424  return {{ min[0], min[1], min[2], max[0], max[1], max[2] }};
425 }
426 
427 /**
428  * @brief Check if given global coord is within twice the min/max distance
429  * of the element.
430  *
431  * @param coords Input Cartesian global coordinates
432  *
433  * @return True if within distance or False otherwise.
434  */
436 {
437  // Validation checks
438  ASSERTL1(gloCoord.num_elements() >= m_coordim,
439  "Expects number of global coordinates supplied to be greater than "
440  "or equal to the mesh dimension.");
441 
442  int i;
443  Array<OneD, NekDouble> mincoord(m_coordim), maxcoord(m_coordim);
444  NekDouble diff = 0.0;
445 
446  v_FillGeom();
447 
448  const int npts = m_xmap->GetTotPoints();
449  Array<OneD, NekDouble> pts(npts);
450 
451  for (i = 0; i < m_coordim; ++i)
452  {
453  m_xmap->BwdTrans(m_coeffs[i], pts);
454  mincoord[i] = Vmath::Vmin(pts.num_elements(), pts, 1);
455  maxcoord[i] = Vmath::Vmax(pts.num_elements(), pts, 1);
456 
457  diff = std::max(maxcoord[i] - mincoord[i], diff);
458  }
459 
460  for (i = 0; i < m_coordim; ++i)
461  {
462  if ((gloCoord[i] < mincoord[i] - 0.2 * diff) ||
463  (gloCoord[i] > maxcoord[i] + 0.2 * diff))
464  {
465  return false;
466  }
467  }
468 
469  return true;
470 }
471 
472 
473 /**
474  * @brief Clamp local coords to be within standard regions [-1, 1]^dim.
475  *
476  * @param Lcoords Corresponding local coordinates
477  */
479  NekDouble tol)
480 {
481  // Validation checks
482  ASSERTL1(locCoord.num_elements() == GetShapeDim(),
483  "Expects same number of local coordinates as shape dimension.");
484 
485  // If out of range clamp locCoord to be within [-1,1]^dim
486  // since any larger value will be very oscillatory if
487  // called by 'returnNearestElmt' option in
488  // ExpList::GetExpIndex
489  for (int i = 0; i < GetShapeDim(); ++i)
490  {
491  if (locCoord[i] < -(1 + tol))
492  {
493  locCoord[i] = -(1 + tol);
494  }
495 
496  if (locCoord[i] > (1 + tol))
497  {
498  locCoord[i] = 1 + tol;
499  }
500  }
501 }
502 
503 
504 }
505 }
StdRegions::StdExpansionSharedPtr m_xmap
mapping containing isoparametric transformation.
Definition: Geometry.h:189
virtual Geometry2DSharedPtr v_GetFace(int i) const
Returns face i of this object.
Definition: Geometry.cpp:172
int GetShapeDim() const
Get the object&#39;s shape dimension.
Definition: Geometry.h:412
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mod...
Definition: ErrorUtil.hpp:209
int GetEid(int i) const
Get the ID of edge i of this object.
Definition: Geometry.cpp:145
int GetFid(int i) const
Get the ID of face i of this object.
Definition: Geometry.cpp:153
virtual int v_GetEdgeFaceMap(int i, int j) const
Returns the standard element edge IDs that are connected to a given face.
Definition: Geometry.cpp:291
virtual bool v_ContainsPoint(const Array< OneD, const NekDouble > &gloCoord, Array< OneD, NekDouble > &locCoord, NekDouble tol, NekDouble &resid)
Definition: Geometry.cpp:255
std::shared_ptr< Geometry2D > Geometry2DSharedPtr
Definition: Geometry.h:65
GeomFactorsSharedPtr m_geomFactors
Geometric factors.
Definition: Geometry.h:185
StdRegions::StdExpansionSharedPtr GetXmap() const
Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standar...
Definition: Geometry.h:421
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
Definition: Vmath.cpp:782
Geometry2DSharedPtr GetFace(int i) const
Returns face i of this object.
Definition: Geometry.h:359
std::unordered_map< int, CurveSharedPtr > CurveMap
Definition: Curve.hpp:62
std::shared_ptr< GeomFactors > GeomFactorsSharedPtr
Pointer to a GeomFactors object.
Definition: GeomFactors.h:62
T Vmin(int n, const T *x, const int incx)
Return the minimum element in x - called vmin to avoid conflict with min.
Definition: Vmath.cpp:874
bool MinMaxCheck(const Array< OneD, const NekDouble > &gloCoord)
Check if given global coord is within twice the min/max distance of the element.
Definition: Geometry.cpp:435
static GeomFactorsSharedPtr ValidateRegGeomFactor(GeomFactorsSharedPtr geomFactor)
Check to see if a geometric factor has already been created that contains the same regular informatio...
Definition: Geometry.cpp:90
virtual NekDouble v_GetLocCoords(const Array< OneD, const NekDouble > &coords, Array< OneD, NekDouble > &Lcoords)
Determine the local collapsed coordinates that correspond to a given Cartesian coordinate for this ge...
Definition: Geometry.cpp:314
GeomFactorsSharedPtr GetGeomFactors()
Get the geometric factors for this object, generating them if required.
Definition: Geometry.h:289
virtual void v_Reset(CurveMap &curvedEdges, CurveMap &curvedFaces)
Reset this geometry object: unset the current state, zero Geometry::m_coeffs and remove allocated Geo...
Definition: Geometry.cpp:335
void ClampLocCoords(Array< OneD, NekDouble > &locCoord, NekDouble tol)
Clamp local coords to be within standard regions [-1, 1]^dim.
Definition: Geometry.cpp:478
static GeomFactorsVector m_regGeomFactorsManager
Definition: Geometry.h:180
virtual StdRegions::Orientation v_GetEorient(const int i) const
Returns the orientation of edge i with respect to the ordering of edges in the standard element...
Definition: Geometry.cpp:193
GeomState m_geomFactorsState
State of the geometric factors.
Definition: Geometry.h:187
StandardMatrixTag & lhs
virtual int v_GetNumFaces() const
Get the number of faces of this object.
Definition: Geometry.cpp:225
virtual int v_GetShapeDim() const
Get the object&#39;s shape dimension.
Definition: Geometry.cpp:235
std::shared_ptr< StdExpansion > StdExpansionSharedPtr
int GetCoordim() const
Return the coordinate dimension of this object (i.e. the dimension of the space in which this object ...
Definition: Geometry.h:271
Geometric information has not been generated.
std::vector< GeomFactorsSharedPtr > GeomFactorsVector
A vector of GeomFactor pointers.
Definition: GeomFactors.h:64
virtual StdRegions::StdExpansionSharedPtr v_GetXmap() const
Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standar...
Definition: Geometry.cpp:245
double NekDouble
bool GlobalIdEquality(const std::shared_ptr< Geometry > &lhs, const std::shared_ptr< Geometry > &rhs)
Definition: Geometry.cpp:128
std::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:59
bool m_setupState
Wether or not the setup routines have been run.
Definition: Geometry.h:193
int GetVid(int i) const
Get the ID of vertex i of this object.
Definition: Geometry.cpp:137
int GetNumVerts() const
Get the number of vertices of this object.
Definition: Geometry.h:385
Array< OneD, Array< OneD, NekDouble > > m_coeffs
Array containing expansion coefficients of m_xmap.
Definition: Geometry.h:201
virtual int v_GetNumVerts() const
Get the number of vertices of this object.
Definition: Geometry.cpp:183
Geometry is straight-sided with constant geometric factors.
static const NekDouble kGeomFactorsTol
virtual StdRegions::Orientation v_GetForient(const int i) const
Returns the orientation of face i with respect to the ordering of faces in the standard element...
Definition: Geometry.cpp:204
Geometry1DSharedPtr GetEdge(int i) const
Returns edge i of this object.
Definition: Geometry.h:351
LibUtilities::ShapeType m_shapeType
Type of shape.
Definition: Geometry.h:197
std::shared_ptr< Geometry1D > Geometry1DSharedPtr
Definition: Geometry.h:63
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs
virtual int v_GetNumEdges() const
Get the number of edges of this object.
Definition: Geometry.cpp:215
GeomState m_state
Enumeration to dictate whether coefficients are filled.
Definition: Geometry.h:191
virtual NekDouble v_GetCoord(const int i, const Array< OneD, const NekDouble > &Lcoord)
Given local collapsed coordinate Lcoord, return the value of physical coordinate in direction i...
Definition: Geometry.cpp:302
virtual int v_GetVertexFaceMap(int i, int j) const
Returns the standard element face IDs that are connected to a given vertex.
Definition: Geometry.cpp:280
virtual ~Geometry()
Default destructor.
Definition: Geometry.cpp:72
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode...
Definition: ErrorUtil.hpp:250
virtual void v_FillGeom()
Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements...
Definition: Geometry.cpp:326
virtual int v_GetVertexEdgeMap(int i, int j) const
Returns the standard element edge IDs that are connected to a given vertex.
Definition: Geometry.cpp:269
bool SortByGlobalId(const std::shared_ptr< Geometry > &lhs, const std::shared_ptr< Geometry > &rhs)
Less than operator to sort Geometry objects by global id when sorting STL containers.
Definition: Geometry.cpp:122
virtual Geometry1DSharedPtr v_GetEdge(int i) const
Returns edge i of this object.
Definition: Geometry.cpp:161
PointGeomSharedPtr GetVertex(int i) const
Returns vertex i of this object.
Definition: Geometry.h:343
int m_coordim
Coordinate dimension of this geometry object.
Definition: Geometry.h:183
Geometry()
Default constructor.
Definition: Geometry.cpp:54
std::array< NekDouble, 6 > GetBoundingBox()
Generates the bounding box for the element.
Definition: Geometry.cpp:363