Nektar++
Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | List of all members
Nektar::SpatialDomains::Geometry2D Class Reference

2D geometry information More...

#include <Geometry2D.h>

Inheritance diagram for Nektar::SpatialDomains::Geometry2D:
[legend]

Public Member Functions

 Geometry2D ()
 
 Geometry2D (const int coordim, CurveSharedPtr curve)
 
 ~Geometry2D () override
 
CurveSharedPtr GetCurve ()
 
- Public Member Functions inherited from Nektar::SpatialDomains::Geometry
 Geometry ()
 Default constructor. More...
 
 Geometry (int coordim)
 Constructor when supplied a coordinate dimension. More...
 
virtual ~Geometry ()
 Default destructor. More...
 
int GetCoordim () const
 Return the coordinate dimension of this object (i.e. the dimension of the space in which this object is embedded). More...
 
void SetCoordim (int coordim)
 Sets the coordinate dimension of this object (i.e. the dimension of the space in which this object is embedded). More...
 
GeomFactorsSharedPtr GetGeomFactors ()
 Get the geometric factors for this object, generating them if required. More...
 
GeomFactorsSharedPtr GetRefGeomFactors (const Array< OneD, const LibUtilities::BasisSharedPtr > &tbasis)
 
GeomFactorsSharedPtr GetMetricInfo ()
 Get the geometric factors for this object. More...
 
LibUtilities::ShapeType GetShapeType (void)
 Get the geometric shape type of this object. More...
 
int GetGlobalID (void) const
 Get the ID of this object. More...
 
void SetGlobalID (int globalid)
 Set the ID of this object. More...
 
int GetVid (int i) const
 Get the ID of vertex i of this object. More...
 
int GetEid (int i) const
 Get the ID of edge i of this object. More...
 
int GetFid (int i) const
 Get the ID of face i of this object. More...
 
int GetTid (int i) const
 Get the ID of trace i of this object. More...
 
PointGeomSharedPtr GetVertex (int i) const
 Returns vertex i of this object. More...
 
Geometry1DSharedPtr GetEdge (int i) const
 Returns edge i of this object. More...
 
Geometry2DSharedPtr GetFace (int i) const
 Returns face i of this object. More...
 
StdRegions::Orientation GetEorient (const int i) const
 Returns the orientation of edge i with respect to the ordering of edges in the standard element. More...
 
StdRegions::Orientation GetForient (const int i) const
 Returns the orientation of face i with respect to the ordering of faces in the standard element. More...
 
int GetNumVerts () const
 Get the number of vertices of this object. More...
 
int GetNumEdges () const
 Get the number of edges of this object. More...
 
int GetNumFaces () const
 Get the number of faces of this object. More...
 
int GetShapeDim () const
 Get the object's shape dimension. More...
 
StdRegions::StdExpansionSharedPtr GetXmap () const
 Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standard element to physical element. More...
 
const Array< OneD, const NekDouble > & GetCoeffs (const int i) const
 Return the coefficients of the transformation Geometry::m_xmap in coordinate direction i. More...
 
void FillGeom ()
 Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements. More...
 
std::array< NekDouble, 6 > GetBoundingBox ()
 Generates the bounding box for the element. More...
 
void ClearBoundingBox ()
 
bool ContainsPoint (const Array< OneD, const NekDouble > &gloCoord, NekDouble tol=0.0)
 Determine whether an element contains a particular Cartesian coordinate \((x,y,z)\). More...
 
bool ContainsPoint (const Array< OneD, const NekDouble > &gloCoord, Array< OneD, NekDouble > &locCoord, NekDouble tol)
 Determine whether an element contains a particular Cartesian coordinate \((x,y,z)\). More...
 
bool ContainsPoint (const Array< OneD, const NekDouble > &gloCoord, Array< OneD, NekDouble > &locCoord, NekDouble tol, NekDouble &dist)
 Determine whether an element contains a particular Cartesian coordinate \(\vec{x} = (x,y,z)\). More...
 
NekDouble 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 geometry object. More...
 
NekDouble GetCoord (const int i, const Array< OneD, const NekDouble > &Lcoord)
 Given local collapsed coordinate Lcoord, return the value of physical coordinate in direction i. More...
 
int PreliminaryCheck (const Array< OneD, const NekDouble > &gloCoord)
 A fast and robust check if a given global coord is outside of a deformed element. For regular elements, this check is unnecessary. More...
 
bool MinMaxCheck (const Array< OneD, const NekDouble > &gloCoord)
 Check if given global coord is within the BoundingBox of the element. More...
 
bool ClampLocCoords (Array< OneD, NekDouble > &locCoord, NekDouble tol=std::numeric_limits< NekDouble >::epsilon())
 Clamp local coords to be within standard regions [-1, 1]^dim. More...
 
NekDouble FindDistance (const Array< OneD, const NekDouble > &xs, Array< OneD, NekDouble > &xi)
 
int GetVertexEdgeMap (int i, int j) const
 Returns the standard element edge IDs that are connected to a given vertex. More...
 
int GetVertexFaceMap (int i, int j) const
 Returns the standard element face IDs that are connected to a given vertex. More...
 
int GetEdgeFaceMap (int i, int j) const
 Returns the standard element edge IDs that are connected to a given face. More...
 
int GetEdgeNormalToFaceVert (int i, int j) const
 Returns the standard lement edge IDs that are normal to a given face vertex. More...
 
int GetDir (const int i, const int j=0) const
 Returns the element coordinate direction corresponding to a given face coordinate direction. More...
 
void Reset (CurveMap &curvedEdges, CurveMap &curvedFaces)
 Reset this geometry object: unset the current state, zero Geometry::m_coeffs and remove allocated GeomFactors. More...
 
void Setup ()
 

Static Public Attributes

static const int kDim = 2
 

Protected Member Functions

NekDouble v_GetLocCoords (const Array< OneD, const NekDouble > &coords, Array< OneD, NekDouble > &Lcoords) override
 Determine the local collapsed coordinates that correspond to a given Cartesian coordinate for this geometry object. More...
 
void NewtonIterationForLocCoord (const Array< OneD, const NekDouble > &coords, const Array< OneD, const NekDouble > &ptsx, const Array< OneD, const NekDouble > &ptsy, Array< OneD, NekDouble > &Lcoords, NekDouble &dist)
 
void SolveStraightEdgeQuad (const Array< OneD, const NekDouble > &coords, Array< OneD, NekDouble > &Lcoords)
 
void v_CalculateInverseIsoParam () override
 
int v_AllLeftCheck (const Array< OneD, const NekDouble > &gloCoord) override
 
int v_GetShapeDim () const override
 Get the object's shape dimension. More...
 
PointGeomSharedPtr v_GetVertex (int i) const override
 
Geometry1DSharedPtr v_GetEdge (int i) const override
 Returns edge i of this object. More...
 
int v_GetNumVerts () const override
 Get the number of vertices of this object. More...
 
int v_GetNumEdges () const override
 Get the number of edges of this object. More...
 
StdRegions::Orientation v_GetEorient (const int i) const override
 Returns the orientation of edge i with respect to the ordering of edges in the standard element. More...
 
NekDouble v_FindDistance (const Array< OneD, const NekDouble > &xs, Array< OneD, NekDouble > &xi) override
 
- Protected Member Functions inherited from Nektar::SpatialDomains::Geometry
void GenGeomFactors ()
 Handles generation of geometry factors. More...
 
virtual PointGeomSharedPtr v_GetVertex (int i) const =0
 
virtual Geometry1DSharedPtr v_GetEdge (int i) const
 Returns edge i of this object. More...
 
virtual Geometry2DSharedPtr v_GetFace (int i) const
 Returns face i of this object. More...
 
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. More...
 
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. More...
 
virtual int v_GetNumVerts () const
 Get the number of vertices of this object. More...
 
virtual int v_GetNumEdges () const
 Get the number of edges of this object. More...
 
virtual int v_GetNumFaces () const
 Get the number of faces of this object. More...
 
virtual int v_GetShapeDim () const
 Get the object's shape dimension. More...
 
virtual StdRegions::StdExpansionSharedPtr v_GetXmap () const
 Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standard element to physical element. More...
 
virtual void v_FillGeom ()
 Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements. More...
 
virtual bool v_ContainsPoint (const Array< OneD, const NekDouble > &gloCoord, Array< OneD, NekDouble > &locCoord, NekDouble tol, NekDouble &dist)
 Determine whether an element contains a particular Cartesian coordinate \(\vec{x} = (x,y,z)\). More...
 
virtual int v_AllLeftCheck (const Array< OneD, const NekDouble > &gloCoord)
 
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. More...
 
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 geometry object. More...
 
virtual NekDouble v_FindDistance (const Array< OneD, const NekDouble > &xs, Array< OneD, NekDouble > &xi)
 
virtual int v_GetVertexEdgeMap (int i, int j) const
 Returns the standard element edge IDs that are connected to a given vertex. More...
 
virtual int v_GetVertexFaceMap (int i, int j) const
 Returns the standard element face IDs that are connected to a given vertex. More...
 
virtual int v_GetEdgeFaceMap (int i, int j) const
 Returns the standard element edge IDs that are connected to a given face. More...
 
virtual int v_GetEdgeNormalToFaceVert (const int i, const int j) const
 Returns the standard lement edge IDs that are normal to a given face vertex. More...
 
virtual int v_GetDir (const int faceidx, const int facedir) const
 Returns the element coordinate direction corresponding to a given face coordinate direction. More...
 
virtual void v_Reset (CurveMap &curvedEdges, CurveMap &curvedFaces)
 Reset this geometry object: unset the current state, zero Geometry::m_coeffs and remove allocated GeomFactors. More...
 
virtual void v_Setup ()
 
virtual void v_GenGeomFactors ()=0
 
void SetUpCoeffs (const int nCoeffs)
 Initialise the Geometry::m_coeffs array. More...
 
virtual void v_CalculateInverseIsoParam ()
 

Protected Attributes

PointGeomVector m_verts
 
SegGeomVector m_edges
 
std::vector< StdRegions::Orientationm_eorient
 
CurveSharedPtr m_curve
 
Array< OneD, int > m_manifold
 
Array< OneD, Array< OneD, NekDouble > > m_edgeNormal
 
- Protected Attributes inherited from Nektar::SpatialDomains::Geometry
int m_coordim
 Coordinate dimension of this geometry object. More...
 
GeomFactorsSharedPtr m_geomFactors
 Geometric factors. More...
 
GeomState m_geomFactorsState
 State of the geometric factors. More...
 
StdRegions::StdExpansionSharedPtr m_xmap
 \(\chi\) mapping containing isoparametric transformation. More...
 
GeomState m_state
 Enumeration to dictate whether coefficients are filled. More...
 
bool m_setupState
 Wether or not the setup routines have been run. More...
 
GeomType m_geomType
 Type of geometry. More...
 
LibUtilities::ShapeType m_shapeType
 Type of shape. More...
 
int m_globalID
 Global ID. More...
 
Array< OneD, Array< OneD, NekDouble > > m_coeffs
 Array containing expansion coefficients of m_xmap. More...
 
Array< OneD, NekDoublem_boundingBox
 Array containing bounding box. More...
 
Array< OneD, Array< OneD, NekDouble > > m_isoParameter
 
Array< OneD, Array< OneD, NekDouble > > m_invIsoParam
 
int m_straightEdge
 

Additional Inherited Members

- Static Protected Member Functions inherited from Nektar::SpatialDomains::Geometry
static GeomFactorsSharedPtr ValidateRegGeomFactor (GeomFactorsSharedPtr geomFactor)
 Check to see if a geometric factor has already been created that contains the same regular information. More...
 
- Static Protected Attributes inherited from Nektar::SpatialDomains::Geometry
static GeomFactorsVector m_regGeomFactorsManager
 

Detailed Description

2D geometry information

Definition at line 65 of file Geometry2D.h.

Constructor & Destructor Documentation

◆ Geometry2D() [1/2]

Nektar::SpatialDomains::Geometry2D::Geometry2D ( )

Definition at line 48 of file Geometry2D.cpp.

49{
50}

◆ Geometry2D() [2/2]

Nektar::SpatialDomains::Geometry2D::Geometry2D ( const int  coordim,
CurveSharedPtr  curve 
)

Definition at line 52 of file Geometry2D.cpp.

53 : Geometry(coordim), m_curve(curve)
54{
56 "Coordinate dimension should be at least 2 for a 2D geometry");
57}
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
Geometry()
Default constructor.
Definition: Geometry.cpp:50
int m_coordim
Coordinate dimension of this geometry object.
Definition: Geometry.h:183

References ASSERTL0, and Nektar::SpatialDomains::Geometry::m_coordim.

◆ ~Geometry2D()

Nektar::SpatialDomains::Geometry2D::~Geometry2D ( )
override

Definition at line 59 of file Geometry2D.cpp.

60{
61}

Member Function Documentation

◆ GetCurve()

CurveSharedPtr Nektar::SpatialDomains::Geometry2D::GetCurve ( )
inline

Definition at line 73 of file Geometry2D.h.

74 {
75 return m_curve;
76 }

References m_curve.

◆ NewtonIterationForLocCoord()

void Nektar::SpatialDomains::Geometry2D::NewtonIterationForLocCoord ( const Array< OneD, const NekDouble > &  coords,
const Array< OneD, const NekDouble > &  ptsx,
const Array< OneD, const NekDouble > &  ptsy,
Array< OneD, NekDouble > &  Lcoords,
NekDouble dist 
)
protected

Definition at line 136 of file Geometry2D.cpp.

141{
142 // Maximum iterations for convergence
143 const int MaxIterations = NekConstants::kNewtonIterations;
144 // |x-xp|^2 < EPSILON error tolerance
145 const NekDouble Tol = 1.e-8;
146 // |r,s| > LcoordDIV stop the search
147 const NekDouble LcoordDiv = 15.0;
148
149 Array<OneD, const NekDouble> Jac =
150 m_geomFactors->GetJac(m_xmap->GetPointsKeys());
151
152 NekDouble ScaledTol =
153 Vmath::Vsum(Jac.size(), Jac, 1) / ((NekDouble)Jac.size());
154 ScaledTol *= Tol;
155
156 NekDouble xmap, ymap, F1, F2;
157 NekDouble derx_1, derx_2, dery_1, dery_2, jac;
158
159 // save intiial guess for later reference if required.
160 NekDouble init0 = Lcoords[0], init1 = Lcoords[1];
161
162 Array<OneD, NekDouble> DxD1(ptsx.size());
163 Array<OneD, NekDouble> DxD2(ptsx.size());
164 Array<OneD, NekDouble> DyD1(ptsx.size());
165 Array<OneD, NekDouble> DyD2(ptsx.size());
166
167 // Ideally this will be stored in m_geomfactors
168 m_xmap->PhysDeriv(ptsx, DxD1, DxD2);
169 m_xmap->PhysDeriv(ptsy, DyD1, DyD2);
170
171 int cnt = 0;
172 Array<OneD, DNekMatSharedPtr> I(2);
173 Array<OneD, NekDouble> eta(2);
174
175 F1 = F2 = 2000; // Starting value of Function
176 NekDouble resid = sqrt(F1 * F1 + F2 * F2);
177 while (cnt++ < MaxIterations)
178 {
179 // evaluate lagrange interpolant at Lcoords
180 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
181 I[0] = m_xmap->GetBasis(0)->GetI(eta);
182 I[1] = m_xmap->GetBasis(1)->GetI(eta + 1);
183
184 // calculate the global point `corresponding to Lcoords
185 xmap = m_xmap->PhysEvaluate(I, ptsx);
186 ymap = m_xmap->PhysEvaluate(I, ptsy);
187
188 F1 = coords[0] - xmap;
189 F2 = coords[1] - ymap;
190
191 if (F1 * F1 + F2 * F2 < ScaledTol)
192 {
193 resid = sqrt(F1 * F1 + F2 * F2);
194 break;
195 }
196
197 // Interpolate derivative metric at Lcoords
198 derx_1 = m_xmap->PhysEvaluate(I, DxD1);
199 derx_2 = m_xmap->PhysEvaluate(I, DxD2);
200 dery_1 = m_xmap->PhysEvaluate(I, DyD1);
201 dery_2 = m_xmap->PhysEvaluate(I, DyD2);
202
203 jac = dery_2 * derx_1 - dery_1 * derx_2;
204
205 // use analytical inverse of derivitives which are
206 // also similar to those of metric factors.
207 Lcoords[0] =
208 Lcoords[0] +
209 (dery_2 * (coords[0] - xmap) - derx_2 * (coords[1] - ymap)) / jac;
210
211 Lcoords[1] =
212 Lcoords[1] +
213 (-dery_1 * (coords[0] - xmap) + derx_1 * (coords[1] - ymap)) / jac;
214
215 if (!(std::isfinite(Lcoords[0]) && std::isfinite(Lcoords[1])))
216 {
217 dist = 1e16;
218 std::ostringstream ss;
219 ss << "nan or inf found in NewtonIterationForLocCoord in element "
220 << GetGlobalID();
221 WARNINGL1(false, ss.str());
222 return;
223 }
224 if (fabs(Lcoords[0]) > LcoordDiv || fabs(Lcoords[1]) > LcoordDiv)
225 {
226 break; // lcoords have diverged so stop iteration
227 }
228 }
229
230 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
231 if (ClampLocCoords(eta, 0.))
232 {
233 I[0] = m_xmap->GetBasis(0)->GetI(eta);
234 I[1] = m_xmap->GetBasis(1)->GetI(eta + 1);
235 // calculate the global point corresponding to Lcoords
236 xmap = m_xmap->PhysEvaluate(I, ptsx);
237 ymap = m_xmap->PhysEvaluate(I, ptsy);
238 F1 = coords[0] - xmap;
239 F2 = coords[1] - ymap;
240 dist = sqrt(F1 * F1 + F2 * F2);
241 }
242 else
243 {
244 dist = 0.;
245 }
246
247 if (cnt >= MaxIterations)
248 {
249 Array<OneD, NekDouble> collCoords(2);
250 m_xmap->LocCoordToLocCollapsed(Lcoords, collCoords);
251
252 // if coordinate is inside element dump error!
253 if ((collCoords[0] >= -1.0 && collCoords[0] <= 1.0) &&
254 (collCoords[1] >= -1.0 && collCoords[1] <= 1.0))
255 {
256 std::ostringstream ss;
257
258 ss << "Reached MaxIterations (" << MaxIterations
259 << ") in Newton iteration ";
260 ss << "Init value (" << setprecision(4) << init0 << "," << init1
261 << ","
262 << ") ";
263 ss << "Fin value (" << Lcoords[0] << "," << Lcoords[1] << ","
264 << ") ";
265 ss << "Resid = " << resid << " Tolerance = " << sqrt(ScaledTol);
266
267 WARNINGL1(cnt < MaxIterations, ss.str());
268 }
269 }
270}
#define WARNINGL1(condition, msg)
Definition: ErrorUtil.hpp:243
bool ClampLocCoords(Array< OneD, NekDouble > &locCoord, NekDouble tol=std::numeric_limits< NekDouble >::epsilon())
Clamp local coords to be within standard regions [-1, 1]^dim.
Definition: Geometry.cpp:550
int GetGlobalID(void) const
Get the ID of this object.
Definition: Geometry.h:324
StdRegions::StdExpansionSharedPtr m_xmap
mapping containing isoparametric transformation.
Definition: Geometry.h:189
GeomFactorsSharedPtr m_geomFactors
Geometric factors.
Definition: Geometry.h:185
static const unsigned int kNewtonIterations
double NekDouble
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
Definition: Vmath.hpp:608
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294

References Nektar::SpatialDomains::Geometry::ClampLocCoords(), Nektar::SpatialDomains::Geometry::GetGlobalID(), Nektar::NekConstants::kNewtonIterations, Nektar::SpatialDomains::Geometry::m_geomFactors, Nektar::SpatialDomains::Geometry::m_xmap, tinysimd::sqrt(), Vmath::Vsum(), and WARNINGL1.

Referenced by v_GetLocCoords().

◆ SolveStraightEdgeQuad()

void Nektar::SpatialDomains::Geometry2D::SolveStraightEdgeQuad ( const Array< OneD, const NekDouble > &  coords,
Array< OneD, NekDouble > &  Lcoords 
)
protected

Definition at line 109 of file Geometry2D.cpp.

111{
112 int i0 = 0, i1 = 1, j1 = 0, j2 = 1;
113 if (m_straightEdge & 2)
114 {
115 i0 = 1;
116 i1 = 0;
117 }
118 if (m_straightEdge & 4)
119 {
120 j1 = 1;
121 j2 = 0;
122 }
124 NekDouble gamma = m_isoParameter[1][3];
125 NekDouble tty = (coords[i1] - gamma * coords[i0] - m_isoParameter[1][0]) *
126 m_isoParameter[1][1];
127 NekDouble denom = 1. / (m_isoParameter[0][2] + m_isoParameter[0][3] * tty);
128 NekDouble epsilon = -m_isoParameter[0][3] * beta * denom;
129 NekDouble h =
130 (m_isoParameter[0][0] + m_isoParameter[0][1] * tty - coords[i0]) *
131 denom;
132 Lcoords[j2] = -h / (0.5 + sqrt(0.25 - epsilon * h));
133 Lcoords[j1] = -beta * Lcoords[j2] + tty;
134}
Array< OneD, Array< OneD, NekDouble > > m_isoParameter
Definition: Geometry.h:204
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:59

References Nektar::LibUtilities::beta, Nektar::SpatialDomains::Geometry::m_isoParameter, Nektar::SpatialDomains::Geometry::m_straightEdge, and tinysimd::sqrt().

Referenced by v_GetLocCoords().

◆ v_AllLeftCheck()

int Nektar::SpatialDomains::Geometry2D::v_AllLeftCheck ( const Array< OneD, const NekDouble > &  gloCoord)
overrideprotectedvirtual

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 63 of file Geometry2D.cpp.

64{
65 int nc = 1, d0 = m_manifold[0], d1 = m_manifold[1];
66 if (0 == m_edgeNormal.size())
67 {
68 m_edgeNormal = Array<OneD, Array<OneD, NekDouble>>(m_verts.size());
69 Array<OneD, Array<OneD, NekDouble>> x(2);
70 x[0] = Array<OneD, NekDouble>(3);
71 x[1] = Array<OneD, NekDouble>(3);
72 m_verts[m_verts.size() - 1]->GetCoords(x[0]);
73 int i0 = 1, i1 = 0;
74 for (size_t i = 0; i < m_verts.size(); ++i)
75 {
76 i0 ^= 1;
77 i1 ^= 1;
78 m_verts[i]->GetCoords(x[i1]);
79 if (m_edges[i]->GetXmap()->GetBasis(0)->GetNumModes() > 2)
80 {
81 continue;
82 }
83 m_edgeNormal[i] = Array<OneD, NekDouble>(2);
84 m_edgeNormal[i][0] = x[i0][d1] - x[i1][d1];
85 m_edgeNormal[i][1] = x[i1][d0] - x[i0][d0];
86 }
87 }
88
89 Array<OneD, NekDouble> vertex(3);
90 for (size_t i = 0; i < m_verts.size(); ++i)
91 {
92 m_verts[i]->GetCoords(vertex);
93 if (m_edgeNormal[i].size() == 0)
94 {
95 nc = 0; // not sure
96 continue;
97 }
98 NekDouble value = m_edgeNormal[i][0] * (gloCoord[d0] - vertex[d0]) +
99 m_edgeNormal[i][1] * (gloCoord[d1] - vertex[d1]);
100 if (value < 0)
101 {
102 return -1; // outside
103 }
104 }
105 // nc: 1 (side element), 0 (maybe inside), -1 (outside)
106 return nc;
107}
Array< OneD, int > m_manifold
Definition: Geometry2D.h:83
Array< OneD, Array< OneD, NekDouble > > m_edgeNormal
Definition: Geometry2D.h:84
StdRegions::StdExpansionSharedPtr GetXmap() const
Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standar...
Definition: Geometry.h:433

References Nektar::SpatialDomains::Geometry::GetXmap(), m_edgeNormal, m_edges, m_manifold, and m_verts.

◆ v_CalculateInverseIsoParam()

void Nektar::SpatialDomains::Geometry2D::v_CalculateInverseIsoParam ( )
overrideprotectedvirtual

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 575 of file Geometry2D.cpp.

576{
577 NekDouble Jac = m_isoParameter[0][1] * m_isoParameter[1][2] -
578 m_isoParameter[1][1] * m_isoParameter[0][2];
579 Jac = 1. / Jac;
580 // a12, -a02, -a11, a01
581 m_invIsoParam = Array<OneD, Array<OneD, NekDouble>>(2);
582 m_invIsoParam[0] = Array<OneD, NekDouble>(2);
583 m_invIsoParam[1] = Array<OneD, NekDouble>(2);
584 m_invIsoParam[0][0] = m_isoParameter[1][2] * Jac;
585 m_invIsoParam[0][1] = -m_isoParameter[0][2] * Jac;
586 m_invIsoParam[1][0] = -m_isoParameter[1][1] * Jac;
587 m_invIsoParam[1][1] = m_isoParameter[0][1] * Jac;
588}
Array< OneD, Array< OneD, NekDouble > > m_invIsoParam
Definition: Geometry.h:205

References Nektar::SpatialDomains::Geometry::m_invIsoParam, and Nektar::SpatialDomains::Geometry::m_isoParameter.

Referenced by Nektar::SpatialDomains::QuadGeom::v_GenGeomFactors(), and Nektar::SpatialDomains::TriGeom::v_GenGeomFactors().

◆ v_FindDistance()

NekDouble Nektar::SpatialDomains::Geometry2D::v_FindDistance ( const Array< OneD, const NekDouble > &  xs,
Array< OneD, NekDouble > &  xi 
)
overrideprotectedvirtual

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 349 of file Geometry2D.cpp.

351{
352 if (m_geomFactors->GetGtype() == eRegular)
353 {
354 xiOut = Array<OneD, NekDouble>(2, 0.0);
355
356 GetLocCoords(xs, xiOut);
357 ClampLocCoords(xiOut);
358
359 Array<OneD, NekDouble> gloCoord(3);
360 gloCoord[0] = GetCoord(0, xiOut);
361 gloCoord[1] = GetCoord(1, xiOut);
362 gloCoord[2] = GetCoord(2, xiOut);
363
364 return sqrt((xs[0] - gloCoord[0]) * (xs[0] - gloCoord[0]) +
365 (xs[1] - gloCoord[1]) * (xs[1] - gloCoord[1]) +
366 (xs[2] - gloCoord[2]) * (xs[2] - gloCoord[2]));
367 }
368 // If deformed edge then the inverse mapping is non-linear so need to
369 // numerically solve for the local coordinate
370 else if (m_geomFactors->GetGtype() == eDeformed)
371 {
372 // Choose starting based on closest quad
373 Array<OneD, NekDouble> xi(2, 0.0), eta(2, 0.0);
374 m_xmap->LocCollapsedToLocCoord(eta, xi);
375
376 // Armijo constants:
377 // https://en.wikipedia.org/wiki/Backtracking_line_search
378 const NekDouble c1 = 1e-4, c2 = 0.9;
379
380 int nq = m_xmap->GetTotPoints();
381
382 Array<OneD, NekDouble> x(nq), y(nq), z(nq);
383 m_xmap->BwdTrans(m_coeffs[0], x);
384 m_xmap->BwdTrans(m_coeffs[1], y);
385 m_xmap->BwdTrans(m_coeffs[2], z);
386
387 Array<OneD, NekDouble> xderxi1(nq, 0.0), yderxi1(nq, 0.0),
388 zderxi1(nq, 0.0), xderxi2(nq, 0.0), yderxi2(nq, 0.0),
389 zderxi2(nq, 0.0), xderxi1xi1(nq, 0.0), yderxi1xi1(nq, 0.0),
390 zderxi1xi1(nq, 0.0), xderxi1xi2(nq, 0.0), yderxi1xi2(nq, 0.0),
391 zderxi1xi2(nq, 0.0), xderxi2xi1(nq, 0.0), yderxi2xi1(nq, 0.0),
392 zderxi2xi1(nq, 0.0), xderxi2xi2(nq, 0.0), yderxi2xi2(nq, 0.0),
393 zderxi2xi2(nq, 0.0);
394
395 // Get first & second derivatives & partial derivatives of x,y,z values
396 std::array<NekDouble, 3> xc_derxi, yc_derxi, zc_derxi;
397
398 m_xmap->PhysDeriv(x, xderxi1, xderxi2);
399 m_xmap->PhysDeriv(y, yderxi1, yderxi2);
400 m_xmap->PhysDeriv(z, zderxi1, zderxi2);
401
402 m_xmap->PhysDeriv(xderxi1, xderxi1xi1, xderxi1xi2);
403 m_xmap->PhysDeriv(yderxi1, yderxi1xi1, yderxi1xi2);
404 m_xmap->PhysDeriv(zderxi1, zderxi1xi1, zderxi1xi2);
405
406 m_xmap->PhysDeriv(yderxi2, yderxi2xi1, yderxi2xi2);
407 m_xmap->PhysDeriv(xderxi2, xderxi2xi1, xderxi2xi2);
408 m_xmap->PhysDeriv(zderxi2, zderxi2xi1, zderxi2xi2);
409
410 // Minimisation loop (Quasi-newton method)
411 NekDouble fx_prev = std::numeric_limits<NekDouble>::max();
412 for (int i = 0; i < NekConstants::kNewtonIterations; ++i)
413 {
414 // Compute the objective function, f(x_k) and its derivatives
415 NekDouble xc = m_xmap->PhysEvaluate(xi, x, xc_derxi);
416 NekDouble yc = m_xmap->PhysEvaluate(xi, y, yc_derxi);
417 NekDouble zc = m_xmap->PhysEvaluate(xi, z, zc_derxi);
418
419 NekDouble xc_derxi1xi1 = m_xmap->PhysEvaluate(xi, xderxi1xi1);
420 NekDouble yc_derxi1xi1 = m_xmap->PhysEvaluate(xi, yderxi1xi1);
421 NekDouble zc_derxi1xi1 = m_xmap->PhysEvaluate(xi, zderxi1xi1);
422
423 NekDouble xc_derxi1xi2 = m_xmap->PhysEvaluate(xi, xderxi1xi2);
424 NekDouble yc_derxi1xi2 = m_xmap->PhysEvaluate(xi, yderxi1xi2);
425 NekDouble zc_derxi1xi2 = m_xmap->PhysEvaluate(xi, zderxi1xi2);
426
427 NekDouble xc_derxi2xi2 = m_xmap->PhysEvaluate(xi, xderxi2xi2);
428 NekDouble yc_derxi2xi2 = m_xmap->PhysEvaluate(xi, yderxi2xi2);
429 NekDouble zc_derxi2xi2 = m_xmap->PhysEvaluate(xi, zderxi2xi2);
430
431 // Objective function is the distance to the search point
432 NekDouble xdiff = xc - xs[0];
433 NekDouble ydiff = yc - xs[1];
434 NekDouble zdiff = zc - xs[2];
435
436 NekDouble fx = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
437
438 NekDouble fx_derxi1 = 2.0 * xdiff * xc_derxi[0] +
439 2.0 * ydiff * yc_derxi[0] +
440 2.0 * zdiff * zc_derxi[0];
441
442 NekDouble fx_derxi2 = 2.0 * xdiff * xc_derxi[1] +
443 2.0 * ydiff * yc_derxi[1] +
444 2.0 * zdiff * zc_derxi[1];
445
446 NekDouble fx_derxi1xi1 =
447 2.0 * xdiff * xc_derxi1xi1 + 2.0 * xc_derxi[0] * xc_derxi[0] +
448 2.0 * ydiff * yc_derxi1xi1 + 2.0 * yc_derxi[0] * yc_derxi[0] +
449 2.0 * zdiff * zc_derxi1xi1 + 2.0 * zc_derxi[0] * zc_derxi[0];
450
451 NekDouble fx_derxi1xi2 =
452 2.0 * xdiff * xc_derxi1xi2 + 2.0 * xc_derxi[1] * xc_derxi[0] +
453 2.0 * ydiff * yc_derxi1xi2 + 2.0 * yc_derxi[1] * yc_derxi[0] +
454 2.0 * zdiff * zc_derxi1xi2 + 2.0 * zc_derxi[1] * zc_derxi[0];
455
456 NekDouble fx_derxi2xi2 =
457 2.0 * xdiff * xc_derxi2xi2 + 2.0 * xc_derxi[1] * xc_derxi[1] +
458 2.0 * ydiff * yc_derxi2xi2 + 2.0 * yc_derxi[1] * yc_derxi[1] +
459 2.0 * zdiff * zc_derxi2xi2 + 2.0 * zc_derxi[1] * zc_derxi[1];
460
461 // Jacobian
462 NekDouble jac[2];
463 jac[0] = fx_derxi1;
464 jac[1] = fx_derxi2;
465
466 // Inverse of 2x2 hessian
467 NekDouble hessInv[2][2];
468
469 NekDouble det =
470 1 / (fx_derxi1xi1 * fx_derxi2xi2 - fx_derxi1xi2 * fx_derxi1xi2);
471 hessInv[0][0] = det * fx_derxi2xi2;
472 hessInv[0][1] = det * -fx_derxi1xi2;
473 hessInv[1][0] = det * -fx_derxi1xi2;
474 hessInv[1][1] = det * fx_derxi1xi1;
475
476 // Check for convergence
477 if (abs(fx - fx_prev) < 1e-12)
478 {
479 fx_prev = fx;
480 break;
481 }
482 else
483 {
484 fx_prev = fx;
485 }
486
487 NekDouble gamma = 1.0;
488 bool conv = false;
489
490 // Search direction: Newton's method
491 NekDouble pk[2];
492 pk[0] = -(hessInv[0][0] * jac[0] + hessInv[1][0] * jac[1]);
493 pk[1] = -(hessInv[0][1] * jac[0] + hessInv[1][1] * jac[1]);
494
495 // Backtracking line search
496 while (gamma > 1e-10)
497 {
498 Array<OneD, NekDouble> xi_pk(2);
499 xi_pk[0] = xi[0] + pk[0] * gamma;
500 xi_pk[1] = xi[1] + pk[1] * gamma;
501
502 Array<OneD, NekDouble> eta_pk(2, 0.0);
503 m_xmap->LocCoordToLocCollapsed(xi_pk, eta_pk);
504
505 if (eta_pk[0] <
506 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
507 eta_pk[0] >
508 (1 + std::numeric_limits<NekDouble>::epsilon()) ||
509 eta_pk[1] <
510 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
511 eta_pk[1] > (1 + std::numeric_limits<NekDouble>::epsilon()))
512 {
513 gamma /= 2.0;
514 continue;
515 }
516
517 std::array<NekDouble, 3> xc_pk_derxi, yc_pk_derxi, zc_pk_derxi;
518
519 NekDouble xc_pk = m_xmap->PhysEvaluate(xi_pk, x, xc_pk_derxi);
520 NekDouble yc_pk = m_xmap->PhysEvaluate(xi_pk, y, yc_pk_derxi);
521 NekDouble zc_pk = m_xmap->PhysEvaluate(xi_pk, z, zc_pk_derxi);
522
523 NekDouble xc_pk_diff = xc_pk - xs[0];
524 NekDouble yc_pk_diff = yc_pk - xs[1];
525 NekDouble zc_pk_diff = zc_pk - xs[2];
526
527 NekDouble fx_pk = xc_pk_diff * xc_pk_diff +
528 yc_pk_diff * yc_pk_diff +
529 zc_pk_diff * zc_pk_diff;
530
531 NekDouble fx_pk_derxi1 = 2.0 * xc_pk_diff * xc_pk_derxi[0] +
532 2.0 * yc_pk_diff * yc_pk_derxi[0] +
533 2.0 * zc_pk_diff * zc_pk_derxi[0];
534
535 NekDouble fx_pk_derxi2 = 2.0 * xc_pk_diff * xc_pk_derxi[1] +
536 2.0 * yc_pk_diff * yc_pk_derxi[1] +
537 2.0 * zc_pk_diff * zc_pk_derxi[1];
538
539 // Check Wolfe conditions using Armijo constants
540 // https://en.wikipedia.org/wiki/Wolfe_conditions
541 NekDouble tmp = pk[0] * fx_derxi1 + pk[1] * fx_derxi2;
542 NekDouble tmp2 = pk[0] * fx_pk_derxi1 + pk[1] * fx_pk_derxi2;
543 if ((fx_pk - (fx + c1 * gamma * tmp)) <
544 std::numeric_limits<NekDouble>::epsilon() &&
545 (-tmp2 - (-c2 * tmp)) <
546 std::numeric_limits<NekDouble>::epsilon())
547 {
548 conv = true;
549 break;
550 }
551
552 gamma /= 2.0;
553 }
554
555 if (!conv)
556 {
557 break;
558 }
559
560 xi[0] += gamma * pk[0];
561 xi[1] += gamma * pk[1];
562 }
563
564 xiOut = xi;
565 return sqrt(fx_prev);
566 }
567 else
568 {
569 ASSERTL0(false, "Geometry type unknown")
570 }
571
572 return -1.0;
573}
NekDouble 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.h:552
NekDouble 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.h:542
Array< OneD, Array< OneD, NekDouble > > m_coeffs
Array containing expansion coefficients of m_xmap.
Definition: Geometry.h:201
@ eRegular
Geometry is straight-sided with constant geometric factors.
@ eDeformed
Geometry is curved or has non-constant factors.
std::vector< double > z(NPUPPER)
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298

References tinysimd::abs(), ASSERTL0, Nektar::SpatialDomains::Geometry::ClampLocCoords(), Nektar::SpatialDomains::eDeformed, Nektar::SpatialDomains::eRegular, Nektar::SpatialDomains::Geometry::GetCoord(), Nektar::SpatialDomains::Geometry::GetLocCoords(), Nektar::NekConstants::kNewtonIterations, Nektar::SpatialDomains::Geometry::m_coeffs, Nektar::SpatialDomains::Geometry::m_geomFactors, Nektar::SpatialDomains::Geometry::m_xmap, tinysimd::sqrt(), and Nektar::UnitTests::z().

◆ v_GetEdge()

Geometry1DSharedPtr Nektar::SpatialDomains::Geometry2D::v_GetEdge ( int  i) const
overrideprotectedvirtual

Returns edge i of this object.

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 332 of file Geometry2D.cpp.

333{
334 ASSERTL2(i >= 0 && i < m_edges.size(), "Index out of range");
335 return m_edges[i];
336}
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Definition: ErrorUtil.hpp:265

References ASSERTL2, and m_edges.

◆ v_GetEorient()

StdRegions::Orientation Nektar::SpatialDomains::Geometry2D::v_GetEorient ( const int  i) const
overrideprotectedvirtual

Returns the orientation of edge i with respect to the ordering of edges in the standard element.

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 338 of file Geometry2D.cpp.

339{
340 ASSERTL2(i >= 0 && i < m_eorient.size(), "Index out of range");
341 return m_eorient[i];
342}
std::vector< StdRegions::Orientation > m_eorient
Definition: Geometry2D.h:81

References ASSERTL2, and m_eorient.

◆ v_GetLocCoords()

NekDouble Nektar::SpatialDomains::Geometry2D::v_GetLocCoords ( const Array< OneD, const NekDouble > &  coords,
Array< OneD, NekDouble > &  Lcoords 
)
overrideprotectedvirtual

Determine the local collapsed coordinates that correspond to a given Cartesian coordinate for this geometry object.

For curvilinear and non-affine elements (i.e. where the Jacobian varies as a function of the standard element coordinates), this is a non-linear optimisation problem that requires the use of a Newton iteration. Note therefore that this can be an expensive operation.

Note that, clearly, the provided Cartesian coordinate lie outside the element. The function therefore returns the minimum distance from some position in the element to . Lcoords will also be constrained to fit within the range \([-1,1]^d\) where \( d \) is the dimension of the element.

Parameters
coordsInput Cartesian global coordinates
LcoordsCorresponding local coordinates
Returns
Distance between obtained coordinates and provided ones.

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 272 of file Geometry2D.cpp.

274{
275 NekDouble dist = std::numeric_limits<double>::max();
276 Array<OneD, NekDouble> tmpcoords(2);
277 tmpcoords[0] = coords[m_manifold[0]];
278 tmpcoords[1] = coords[m_manifold[1]];
279 if (GetMetricInfo()->GetGtype() == eRegular)
280 {
281 tmpcoords[0] -= m_isoParameter[0][0];
282 tmpcoords[1] -= m_isoParameter[1][0];
283 Lcoords[0] = m_invIsoParam[0][0] * tmpcoords[0] +
284 m_invIsoParam[0][1] * tmpcoords[1];
285 Lcoords[1] = m_invIsoParam[1][0] * tmpcoords[0] +
286 m_invIsoParam[1][1] * tmpcoords[1];
287 }
288 else if (m_straightEdge)
289 {
290 SolveStraightEdgeQuad(tmpcoords, Lcoords);
291 }
292 else if (GetMetricInfo()->GetGtype() == eDeformed)
293 {
294 v_FillGeom();
295 // Determine nearest point of coords to values in m_xmap
296 int npts = m_xmap->GetTotPoints();
297 Array<OneD, NekDouble> ptsx(npts), ptsy(npts);
298 Array<OneD, NekDouble> tmpx(npts), tmpy(npts);
299
300 // Determine 3D manifold orientation
301 m_xmap->BwdTrans(m_coeffs[m_manifold[0]], ptsx);
302 m_xmap->BwdTrans(m_coeffs[m_manifold[1]], ptsy);
303
304 Array<OneD, NekDouble> eta(2, 0.);
305 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
306 ClampLocCoords(eta, 0.);
307
308 m_xmap->LocCollapsedToLocCoord(eta, Lcoords);
309
310 // Perform newton iteration to find local coordinates
311 NewtonIterationForLocCoord(tmpcoords, ptsx, ptsy, Lcoords, dist);
312 }
313 return dist;
314}
void NewtonIterationForLocCoord(const Array< OneD, const NekDouble > &coords, const Array< OneD, const NekDouble > &ptsx, const Array< OneD, const NekDouble > &ptsy, Array< OneD, NekDouble > &Lcoords, NekDouble &dist)
Definition: Geometry2D.cpp:136
void SolveStraightEdgeQuad(const Array< OneD, const NekDouble > &coords, Array< OneD, NekDouble > &Lcoords)
Definition: Geometry2D.cpp:109
virtual void v_FillGeom()
Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements.
Definition: Geometry.cpp:375
GeomFactorsSharedPtr GetMetricInfo()
Get the geometric factors for this object.
Definition: Geometry.h:308

References Nektar::SpatialDomains::Geometry::ClampLocCoords(), Nektar::SpatialDomains::eDeformed, Nektar::SpatialDomains::eRegular, Nektar::SpatialDomains::Geometry::GetMetricInfo(), Nektar::SpatialDomains::Geometry::m_coeffs, Nektar::SpatialDomains::Geometry::m_invIsoParam, Nektar::SpatialDomains::Geometry::m_isoParameter, m_manifold, Nektar::SpatialDomains::Geometry::m_straightEdge, Nektar::SpatialDomains::Geometry::m_xmap, NewtonIterationForLocCoord(), SolveStraightEdgeQuad(), and Nektar::SpatialDomains::Geometry::v_FillGeom().

◆ v_GetNumEdges()

int Nektar::SpatialDomains::Geometry2D::v_GetNumEdges ( ) const
overrideprotectedvirtual

Get the number of edges of this object.

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 321 of file Geometry2D.cpp.

322{
323 return m_edges.size();
324}

References m_edges.

◆ v_GetNumVerts()

int Nektar::SpatialDomains::Geometry2D::v_GetNumVerts ( ) const
overrideprotectedvirtual

Get the number of vertices of this object.

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 316 of file Geometry2D.cpp.

317{
318 return m_verts.size();
319}

References m_verts.

◆ v_GetShapeDim()

int Nektar::SpatialDomains::Geometry2D::v_GetShapeDim ( ) const
overrideprotectedvirtual

Get the object's shape dimension.

For example, a segment is one dimensional and quadrilateral is two dimensional.

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 344 of file Geometry2D.cpp.

345{
346 return 2;
347}

◆ v_GetVertex()

PointGeomSharedPtr Nektar::SpatialDomains::Geometry2D::v_GetVertex ( int  i) const
overrideprotectedvirtual

Implements Nektar::SpatialDomains::Geometry.

Definition at line 326 of file Geometry2D.cpp.

327{
328 ASSERTL2(i >= 0 && i < m_verts.size(), "Index out of range");
329 return m_verts[i];
330}

References ASSERTL2, and m_verts.

Member Data Documentation

◆ kDim

const int Nektar::SpatialDomains::Geometry2D::kDim = 2
static

Definition at line 72 of file Geometry2D.h.

◆ m_curve

CurveSharedPtr Nektar::SpatialDomains::Geometry2D::m_curve
protected

◆ m_edgeNormal

Array<OneD, Array<OneD, NekDouble> > Nektar::SpatialDomains::Geometry2D::m_edgeNormal
protected

Definition at line 84 of file Geometry2D.h.

Referenced by v_AllLeftCheck().

◆ m_edges

SegGeomVector Nektar::SpatialDomains::Geometry2D::m_edges
protected

◆ m_eorient

std::vector<StdRegions::Orientation> Nektar::SpatialDomains::Geometry2D::m_eorient
protected

◆ m_manifold

Array<OneD, int> Nektar::SpatialDomains::Geometry2D::m_manifold
protected

◆ m_verts

PointGeomVector Nektar::SpatialDomains::Geometry2D::m_verts
protected