Nektar++
Loading...
Searching...
No Matches
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=default
 
CurveSharedPtr GetCurve ()
 
- Public Member Functions inherited from Nektar::SpatialDomains::Geometry
 Geometry ()
 Default constructor.
 
 Geometry (int coordim)
 Constructor when supplied a coordinate dimension.
 
virtual ~Geometry ()=default
 
int GetCoordim () const
 Return the coordinate dimension of this object (i.e. the dimension of the space in which this object is embedded).
 
void SetCoordim (int coordim)
 Sets the coordinate dimension of this object (i.e. the dimension of the space in which this object is embedded).
 
GeomFactorsSharedPtr GetGeomFactors ()
 Get the geometric factors for this object, generating them if required.
 
GeomFactorsSharedPtr GetRefGeomFactors (const Array< OneD, const LibUtilities::BasisSharedPtr > &tbasis)
 
GeomFactorsSharedPtr GetMetricInfo ()
 Get the geometric factors for this object.
 
LibUtilities::ShapeType GetShapeType (void)
 Get the geometric shape type of this object.
 
int GetGlobalID (void) const
 Get the ID of this object.
 
void SetGlobalID (int globalid)
 Set the ID of this object.
 
int GetVid (int i) const
 Returns global id of vertex i of this object.
 
int GetEid (int i) const
 Get the ID of edge i of this object.
 
int GetFid (int i) const
 Get the ID of face i of this object.
 
int GetTid (int i) const
 Get the ID of trace i of this object.
 
PointGeomGetVertex (int i) const
 Returns vertex i of this object.
 
Geometry1DGetEdge (int i) const
 Returns edge i of this object.
 
Geometry2DGetFace (int i) const
 Returns face i of this object.
 
StdRegions::Orientation GetEorient (const int i) const
 Returns the orientation of edge i with respect to the ordering of edges in the standard element.
 
StdRegions::Orientation GetForient (const int i) const
 Returns the orientation of face i with respect to the ordering of faces in the standard element.
 
int GetNumVerts () const
 Get the number of vertices of this object.
 
int GetNumEdges () const
 Get the number of edges of this object.
 
int GetNumFaces () const
 Get the number of faces of this object.
 
int GetShapeDim () const
 Get the object's shape dimension.
 
StdRegions::StdExpansionSharedPtr GetXmap () const
 Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standard element to physical element.
 
const Array< OneD, const NekDouble > & GetCoeffs (const int i) const
 Return the coefficients of the transformation Geometry::m_xmap in coordinate direction i.
 
void FillGeom ()
 Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements.
 
std::array< NekDouble, 6 > GetBoundingBox ()
 Generates the bounding box for the element.
 
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)\).
 
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)\).
 
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)\).
 
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.
 
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.
 
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.
 
bool MinMaxCheck (const Array< OneD, const NekDouble > &gloCoord)
 Check if given global coord is within the BoundingBox of the element.
 
bool ClampLocCoords (Array< OneD, NekDouble > &locCoord, NekDouble tol=std::numeric_limits< NekDouble >::epsilon())
 Clamp local coords to be within standard regions [-1, 1]^dim.
 
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.
 
int GetVertexFaceMap (int i, int j) const
 Returns the standard element face IDs that are connected to a given vertex.
 
int GetEdgeFaceMap (int i, int j) const
 Returns the standard element edge IDs that are connected to a given face.
 
int GetEdgeNormalToFaceVert (int i, int j) const
 Returns the standard lement edge IDs that are normal to a given face vertex.
 
int GetDir (const int i, const int j=0) const
 Returns the element coordinate direction corresponding to a given face coordinate direction.
 
void Reset (CurveMap &curvedEdges, CurveMap &curvedFaces)
 Reset this geometry object: unset the current state, zero Geometry::m_coeffs and remove allocated GeomFactors.
 
void ResetNonRecursive (CurveMap &curvedEdges, CurveMap &curvedFaces)
 Reset this geometry object non-recursively: unset the current state, zero Geometry::m_coeffs and remove allocated GeomFactors.
 
void Setup ()
 
void GenGeomFactors ()
 Handles generation of geometry factors.
 

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.
 
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_GetShapeDim () const override
 Get the object's shape dimension.
 
NekDouble v_FindDistance (const Array< OneD, const NekDouble > &xs, Array< OneD, NekDouble > &xi) override
 
- Protected Member Functions inherited from Nektar::SpatialDomains::Geometry
virtual int v_GetVid (int i) const
 Get the ID of vertex i of this object.
 
virtual PointGeomv_GetVertex (int i) const
 Returns vertex i of this object.
 
virtual Geometry1Dv_GetEdge (int i) const
 Returns edge i of this object.
 
virtual Geometry2Dv_GetFace (int i) const
 Returns face i of this object.
 
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.
 
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.
 
virtual int v_GetNumVerts () const
 Get the number of vertices of this object.
 
virtual int v_GetNumEdges () const
 Get the number of edges of this object.
 
virtual int v_GetNumFaces () const
 Get the number of faces of this object.
 
virtual StdRegions::StdExpansionSharedPtr v_GetXmap () const
 Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standard element to physical element.
 
virtual void v_FillGeom ()
 Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements.
 
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)\).
 
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.
 
virtual int v_GetVertexEdgeMap (int i, int j) const
 Returns the standard element edge IDs that are connected to a given vertex.
 
virtual int v_GetVertexFaceMap (int i, int j) const
 Returns the standard element face IDs that are connected to a given vertex.
 
virtual int v_GetEdgeFaceMap (int i, int j) const
 Returns the standard element edge IDs that are connected to a given face.
 
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.
 
virtual int v_GetDir (const int faceidx, const int facedir) const
 Returns the element coordinate direction corresponding to a given face coordinate direction.
 
virtual void v_Reset (CurveMap &curvedEdges, CurveMap &curvedFaces)
 Reset this geometry object: unset the current state, zero Geometry::m_coeffs and remove allocated GeomFactors.
 
virtual void v_Setup ()
 
virtual void v_GenGeomFactors ()=0
 
void SetUpCoeffs (const int nCoeffs)
 Initialise the Geometry::m_coeffs array.
 

Protected Attributes

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.
 
GeomFactorsSharedPtr m_geomFactors
 Geometric factors.
 
GeomState m_geomFactorsState
 State of the geometric factors.
 
StdRegions::StdExpansionSharedPtr m_xmap
 \(\chi\) mapping containing isoparametric transformation.
 
GeomState m_state
 Enumeration to dictate whether coefficients are filled.
 
bool m_setupState
 Wether or not the setup routines have been run.
 
GeomType m_geomType
 Type of geometry.
 
LibUtilities::ShapeType m_shapeType
 Type of shape.
 
int m_globalID
 Global ID.
 
Array< OneD, Array< OneD, NekDouble > > m_coeffs
 Array containing expansion coefficients of m_xmap.
 
Array< OneD, NekDoublem_boundingBox
 Array containing bounding box.
 
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.
 
- Static Protected Attributes inherited from Nektar::SpatialDomains::Geometry
static GeomFactorsVector m_regGeomFactorsManager
 

Detailed Description

2D geometry information

Definition at line 49 of file Geometry2D.h.

Constructor & Destructor Documentation

◆ Geometry2D() [1/2]

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

Definition at line 46 of file Geometry2D.cpp.

47{
48}

◆ Geometry2D() [2/2]

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

Definition at line 50 of file Geometry2D.cpp.

51 : Geometry(coordim), m_curve(curve)
52{
54 "Coordinate dimension should be at least 2 for a 2D geometry");
55}
#define ASSERTL0(condition, msg)
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 ( )
overridedefault

Member Function Documentation

◆ GetCurve()

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

Definition at line 58 of file Geometry2D.h.

59 {
60 return m_curve;
61 }

References m_curve.

Referenced by export_GeomElements(), and Nektar::SpatialDomains::ZoneBase::ZoneBase().

◆ 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 84 of file Geometry2D.cpp.

89{
90 // Maximum iterations for convergence
91 const int MaxIterations = NekConstants::kNewtonIterations;
92 // |x-xp|^2 < EPSILON error tolerance
93 const NekDouble Tol = 1.e-8;
94 // |r,s| > LcoordDIV stop the search
95 const NekDouble LcoordDiv = 15.0;
96
97 Array<OneD, const NekDouble> Jac =
98 m_geomFactors->GetJac(m_xmap->GetPointsKeys());
99
100 NekDouble ScaledTol =
101 Vmath::Vsum(Jac.size(), Jac, 1) / ((NekDouble)Jac.size());
102 ScaledTol *= Tol;
103
104 NekDouble xmap, ymap, F1, F2;
105 NekDouble derx_1, derx_2, dery_1, dery_2, jac;
106
107 // save intiial guess for later reference if required.
108 NekDouble init0 = Lcoords[0], init1 = Lcoords[1];
109
110 Array<OneD, NekDouble> DxD1(ptsx.size());
111 Array<OneD, NekDouble> DxD2(ptsx.size());
112 Array<OneD, NekDouble> DyD1(ptsx.size());
113 Array<OneD, NekDouble> DyD2(ptsx.size());
114
115 // Ideally this will be stored in m_geomfactors
116 m_xmap->PhysDeriv(ptsx, DxD1, DxD2);
117 m_xmap->PhysDeriv(ptsy, DyD1, DyD2);
118
119 int cnt = 0;
120 Array<OneD, DNekMatSharedPtr> I(2);
121 Array<OneD, NekDouble> eta(2);
122
123 F1 = F2 = 2000; // Starting value of Function
124 NekDouble resid = sqrt(F1 * F1 + F2 * F2);
125 while (cnt++ < MaxIterations)
126 {
127 // evaluate lagrange interpolant at Lcoords
128 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
129 I[0] = m_xmap->GetBasis(0)->GetI(eta);
130 I[1] = m_xmap->GetBasis(1)->GetI(eta + 1);
131
132 // calculate the global point `corresponding to Lcoords
133 xmap = m_xmap->PhysEvaluate(I, ptsx);
134 ymap = m_xmap->PhysEvaluate(I, ptsy);
135
136 F1 = coords[0] - xmap;
137 F2 = coords[1] - ymap;
138
139 if (F1 * F1 + F2 * F2 < ScaledTol)
140 {
141 resid = sqrt(F1 * F1 + F2 * F2);
142 break;
143 }
144
145 // Interpolate derivative metric at Lcoords
146 derx_1 = m_xmap->PhysEvaluate(I, DxD1);
147 derx_2 = m_xmap->PhysEvaluate(I, DxD2);
148 dery_1 = m_xmap->PhysEvaluate(I, DyD1);
149 dery_2 = m_xmap->PhysEvaluate(I, DyD2);
150
151 jac = dery_2 * derx_1 - dery_1 * derx_2;
152
153 // use analytical inverse of derivitives which are
154 // also similar to those of metric factors.
155 Lcoords[0] =
156 Lcoords[0] +
157 (dery_2 * (coords[0] - xmap) - derx_2 * (coords[1] - ymap)) / jac;
158
159 Lcoords[1] =
160 Lcoords[1] +
161 (-dery_1 * (coords[0] - xmap) + derx_1 * (coords[1] - ymap)) / jac;
162
163 if (!(std::isfinite(Lcoords[0]) && std::isfinite(Lcoords[1])))
164 {
165 dist = 1e16;
166 std::ostringstream ss;
167 ss << "nan or inf found in NewtonIterationForLocCoord in element "
168 << GetGlobalID();
169 WARNINGL1(false, ss.str());
170 return;
171 }
172 if (fabs(Lcoords[0]) > LcoordDiv || fabs(Lcoords[1]) > LcoordDiv)
173 {
174 break; // lcoords have diverged so stop iteration
175 }
176 }
177
178 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
179 if (ClampLocCoords(eta, 0.))
180 {
181 I[0] = m_xmap->GetBasis(0)->GetI(eta);
182 I[1] = m_xmap->GetBasis(1)->GetI(eta + 1);
183 // calculate the global point corresponding to Lcoords
184 xmap = m_xmap->PhysEvaluate(I, ptsx);
185 ymap = m_xmap->PhysEvaluate(I, ptsy);
186 F1 = coords[0] - xmap;
187 F2 = coords[1] - ymap;
188 dist = sqrt(F1 * F1 + F2 * F2);
189 }
190 else
191 {
192 dist = 0.;
193 }
194
195 if (cnt >= MaxIterations)
196 {
197 Array<OneD, NekDouble> collCoords(2);
198 m_xmap->LocCoordToLocCollapsed(Lcoords, collCoords);
199
200 // if coordinate is inside element dump error!
201 if ((collCoords[0] >= -1.0 && collCoords[0] <= 1.0) &&
202 (collCoords[1] >= -1.0 && collCoords[1] <= 1.0))
203 {
204 std::ostringstream ss;
205
206 ss << "Reached MaxIterations (" << MaxIterations
207 << ") in Newton iteration ";
208 ss << "Init value (" << std::setprecision(4) << init0 << ","
209 << init1 << ","
210 << ") ";
211 ss << "Fin value (" << Lcoords[0] << "," << Lcoords[1] << ","
212 << ") ";
213 ss << "Resid = " << resid
214 << " Tolerance = " << std::sqrt(ScaledTol);
215
216 WARNINGL1(cnt < MaxIterations, ss.str());
217 }
218 }
219}
#define WARNINGL1(condition, msg)
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:536
int GetGlobalID(void) const
Get the ID of this object.
Definition Geometry.h:322
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
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:290

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 57 of file Geometry2D.cpp.

59{
60 int i0 = 0, i1 = 1, j1 = 0, j2 = 1;
61 if (m_straightEdge & 2)
62 {
63 i0 = 1;
64 i1 = 0;
65 }
66 if (m_straightEdge & 4)
67 {
68 j1 = 1;
69 j2 = 0;
70 }
72 NekDouble gamma = m_isoParameter[1][3];
73 NekDouble tty = (coords[i1] - gamma * coords[i0] - m_isoParameter[1][0]) *
74 m_isoParameter[1][1];
75 NekDouble denom = 1. / (m_isoParameter[0][2] + m_isoParameter[0][3] * tty);
76 NekDouble epsilon = -m_isoParameter[0][3] * beta * denom;
77 NekDouble h =
78 (m_isoParameter[0][0] + m_isoParameter[0][1] * tty - coords[i0]) *
79 denom;
80 Lcoords[j2] = -h / (0.5 + sqrt(0.25 - epsilon * h));
81 Lcoords[j1] = -beta * Lcoords[j2] + tty;
82}
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_CalculateInverseIsoParam()

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

Reimplemented from Nektar::SpatialDomains::Geometry.

Definition at line 515 of file Geometry2D.cpp.

516{
517 NekDouble Jac = m_isoParameter[0][1] * m_isoParameter[1][2] -
518 m_isoParameter[1][1] * m_isoParameter[0][2];
519 Jac = 1. / Jac;
520 // a12, -a02, -a11, a01
521 m_invIsoParam = Array<OneD, Array<OneD, NekDouble>>(2);
522 m_invIsoParam[0] = Array<OneD, NekDouble>(2);
523 m_invIsoParam[1] = Array<OneD, NekDouble>(2);
524 m_invIsoParam[0][0] = m_isoParameter[1][2] * Jac;
525 m_invIsoParam[0][1] = -m_isoParameter[0][2] * Jac;
526 m_invIsoParam[1][0] = -m_isoParameter[1][1] * Jac;
527 m_invIsoParam[1][1] = m_isoParameter[0][1] * Jac;
528}
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 289 of file Geometry2D.cpp.

291{
292 if (m_geomFactors->GetGtype() == eRegular)
293 {
294 xiOut = Array<OneD, NekDouble>(2, 0.0);
295
296 GetLocCoords(xs, xiOut);
297 ClampLocCoords(xiOut);
298
299 Array<OneD, NekDouble> gloCoord(3);
300 gloCoord[0] = GetCoord(0, xiOut);
301 gloCoord[1] = GetCoord(1, xiOut);
302 gloCoord[2] = GetCoord(2, xiOut);
303
304 return sqrt((xs[0] - gloCoord[0]) * (xs[0] - gloCoord[0]) +
305 (xs[1] - gloCoord[1]) * (xs[1] - gloCoord[1]) +
306 (xs[2] - gloCoord[2]) * (xs[2] - gloCoord[2]));
307 }
308 // If deformed edge then the inverse mapping is non-linear so need to
309 // numerically solve for the local coordinate
310 else if (m_geomFactors->GetGtype() == eDeformed)
311 {
312 // Choose starting based on closest quad
313 Array<OneD, NekDouble> xi(2, 0.0), eta(2, 0.0);
314 m_xmap->LocCollapsedToLocCoord(eta, xi);
315
316 // Armijo constants:
317 // https://en.wikipedia.org/wiki/Backtracking_line_search
318 const NekDouble c1 = 1e-4, c2 = 0.9;
319
320 int nq = m_xmap->GetTotPoints();
321
322 Array<OneD, NekDouble> x(nq), y(nq), z(nq);
323 m_xmap->BwdTrans(m_coeffs[0], x);
324 m_xmap->BwdTrans(m_coeffs[1], y);
325 m_xmap->BwdTrans(m_coeffs[2], z);
326
327 Array<OneD, NekDouble> xderxi1(nq, 0.0), yderxi1(nq, 0.0),
328 zderxi1(nq, 0.0), xderxi2(nq, 0.0), yderxi2(nq, 0.0),
329 zderxi2(nq, 0.0), xderxi1xi1(nq, 0.0), yderxi1xi1(nq, 0.0),
330 zderxi1xi1(nq, 0.0), xderxi1xi2(nq, 0.0), yderxi1xi2(nq, 0.0),
331 zderxi1xi2(nq, 0.0), xderxi2xi1(nq, 0.0), yderxi2xi1(nq, 0.0),
332 zderxi2xi1(nq, 0.0), xderxi2xi2(nq, 0.0), yderxi2xi2(nq, 0.0),
333 zderxi2xi2(nq, 0.0);
334
335 // Get first & second derivatives & partial derivatives of x,y,z values
336 std::array<NekDouble, 3> xc_derxi, yc_derxi, zc_derxi;
337
338 m_xmap->PhysDeriv(x, xderxi1, xderxi2);
339 m_xmap->PhysDeriv(y, yderxi1, yderxi2);
340 m_xmap->PhysDeriv(z, zderxi1, zderxi2);
341
342 m_xmap->PhysDeriv(xderxi1, xderxi1xi1, xderxi1xi2);
343 m_xmap->PhysDeriv(yderxi1, yderxi1xi1, yderxi1xi2);
344 m_xmap->PhysDeriv(zderxi1, zderxi1xi1, zderxi1xi2);
345
346 m_xmap->PhysDeriv(yderxi2, yderxi2xi1, yderxi2xi2);
347 m_xmap->PhysDeriv(xderxi2, xderxi2xi1, xderxi2xi2);
348 m_xmap->PhysDeriv(zderxi2, zderxi2xi1, zderxi2xi2);
349
350 // Minimisation loop (Quasi-newton method)
351 NekDouble fx_prev = std::numeric_limits<NekDouble>::max();
352 for (int i = 0; i < NekConstants::kNewtonIterations; ++i)
353 {
354 // Compute the objective function, f(x_k) and its derivatives
355 NekDouble xc = m_xmap->PhysEvaluate(xi, x, xc_derxi);
356 NekDouble yc = m_xmap->PhysEvaluate(xi, y, yc_derxi);
357 NekDouble zc = m_xmap->PhysEvaluate(xi, z, zc_derxi);
358
359 NekDouble xc_derxi1xi1 = m_xmap->PhysEvaluate(xi, xderxi1xi1);
360 NekDouble yc_derxi1xi1 = m_xmap->PhysEvaluate(xi, yderxi1xi1);
361 NekDouble zc_derxi1xi1 = m_xmap->PhysEvaluate(xi, zderxi1xi1);
362
363 NekDouble xc_derxi1xi2 = m_xmap->PhysEvaluate(xi, xderxi1xi2);
364 NekDouble yc_derxi1xi2 = m_xmap->PhysEvaluate(xi, yderxi1xi2);
365 NekDouble zc_derxi1xi2 = m_xmap->PhysEvaluate(xi, zderxi1xi2);
366
367 NekDouble xc_derxi2xi2 = m_xmap->PhysEvaluate(xi, xderxi2xi2);
368 NekDouble yc_derxi2xi2 = m_xmap->PhysEvaluate(xi, yderxi2xi2);
369 NekDouble zc_derxi2xi2 = m_xmap->PhysEvaluate(xi, zderxi2xi2);
370
371 // Objective function is the distance to the search point
372 NekDouble xdiff = xc - xs[0];
373 NekDouble ydiff = yc - xs[1];
374 NekDouble zdiff = zc - xs[2];
375
376 NekDouble fx = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
377
378 NekDouble fx_derxi1 = 2.0 * xdiff * xc_derxi[0] +
379 2.0 * ydiff * yc_derxi[0] +
380 2.0 * zdiff * zc_derxi[0];
381
382 NekDouble fx_derxi2 = 2.0 * xdiff * xc_derxi[1] +
383 2.0 * ydiff * yc_derxi[1] +
384 2.0 * zdiff * zc_derxi[1];
385
386 NekDouble fx_derxi1xi1 =
387 2.0 * xdiff * xc_derxi1xi1 + 2.0 * xc_derxi[0] * xc_derxi[0] +
388 2.0 * ydiff * yc_derxi1xi1 + 2.0 * yc_derxi[0] * yc_derxi[0] +
389 2.0 * zdiff * zc_derxi1xi1 + 2.0 * zc_derxi[0] * zc_derxi[0];
390
391 NekDouble fx_derxi1xi2 =
392 2.0 * xdiff * xc_derxi1xi2 + 2.0 * xc_derxi[1] * xc_derxi[0] +
393 2.0 * ydiff * yc_derxi1xi2 + 2.0 * yc_derxi[1] * yc_derxi[0] +
394 2.0 * zdiff * zc_derxi1xi2 + 2.0 * zc_derxi[1] * zc_derxi[0];
395
396 NekDouble fx_derxi2xi2 =
397 2.0 * xdiff * xc_derxi2xi2 + 2.0 * xc_derxi[1] * xc_derxi[1] +
398 2.0 * ydiff * yc_derxi2xi2 + 2.0 * yc_derxi[1] * yc_derxi[1] +
399 2.0 * zdiff * zc_derxi2xi2 + 2.0 * zc_derxi[1] * zc_derxi[1];
400
401 // Jacobian
402 NekDouble jac[2];
403 jac[0] = fx_derxi1;
404 jac[1] = fx_derxi2;
405
406 // Inverse of 2x2 hessian
407 NekDouble hessInv[2][2];
408
409 NekDouble det =
410 1 / (fx_derxi1xi1 * fx_derxi2xi2 - fx_derxi1xi2 * fx_derxi1xi2);
411 hessInv[0][0] = det * fx_derxi2xi2;
412 hessInv[0][1] = det * -fx_derxi1xi2;
413 hessInv[1][0] = det * -fx_derxi1xi2;
414 hessInv[1][1] = det * fx_derxi1xi1;
415
416 // Check for convergence
417 if (abs(fx - fx_prev) < 1e-12)
418 {
419 fx_prev = fx;
420 break;
421 }
422 else
423 {
424 fx_prev = fx;
425 }
426
427 NekDouble gamma = 1.0;
428 bool conv = false;
429
430 // Search direction: Newton's method
431 NekDouble pk[2];
432 pk[0] = -(hessInv[0][0] * jac[0] + hessInv[1][0] * jac[1]);
433 pk[1] = -(hessInv[0][1] * jac[0] + hessInv[1][1] * jac[1]);
434
435 // Backtracking line search
436 while (gamma > 1e-10)
437 {
438 Array<OneD, NekDouble> xi_pk(2);
439 xi_pk[0] = xi[0] + pk[0] * gamma;
440 xi_pk[1] = xi[1] + pk[1] * gamma;
441
442 Array<OneD, NekDouble> eta_pk(2, 0.0);
443 m_xmap->LocCoordToLocCollapsed(xi_pk, eta_pk);
444
445 if (eta_pk[0] <
446 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
447 eta_pk[0] >
448 (1 + std::numeric_limits<NekDouble>::epsilon()) ||
449 eta_pk[1] <
450 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
451 eta_pk[1] > (1 + std::numeric_limits<NekDouble>::epsilon()))
452 {
453 gamma /= 2.0;
454 continue;
455 }
456
457 std::array<NekDouble, 3> xc_pk_derxi, yc_pk_derxi, zc_pk_derxi;
458
459 NekDouble xc_pk = m_xmap->PhysEvaluate(xi_pk, x, xc_pk_derxi);
460 NekDouble yc_pk = m_xmap->PhysEvaluate(xi_pk, y, yc_pk_derxi);
461 NekDouble zc_pk = m_xmap->PhysEvaluate(xi_pk, z, zc_pk_derxi);
462
463 NekDouble xc_pk_diff = xc_pk - xs[0];
464 NekDouble yc_pk_diff = yc_pk - xs[1];
465 NekDouble zc_pk_diff = zc_pk - xs[2];
466
467 NekDouble fx_pk = xc_pk_diff * xc_pk_diff +
468 yc_pk_diff * yc_pk_diff +
469 zc_pk_diff * zc_pk_diff;
470
471 NekDouble fx_pk_derxi1 = 2.0 * xc_pk_diff * xc_pk_derxi[0] +
472 2.0 * yc_pk_diff * yc_pk_derxi[0] +
473 2.0 * zc_pk_diff * zc_pk_derxi[0];
474
475 NekDouble fx_pk_derxi2 = 2.0 * xc_pk_diff * xc_pk_derxi[1] +
476 2.0 * yc_pk_diff * yc_pk_derxi[1] +
477 2.0 * zc_pk_diff * zc_pk_derxi[1];
478
479 // Check Wolfe conditions using Armijo constants
480 // https://en.wikipedia.org/wiki/Wolfe_conditions
481 NekDouble tmp = pk[0] * fx_derxi1 + pk[1] * fx_derxi2;
482 NekDouble tmp2 = pk[0] * fx_pk_derxi1 + pk[1] * fx_pk_derxi2;
483 if ((fx_pk - (fx + c1 * gamma * tmp)) <
484 std::numeric_limits<NekDouble>::epsilon() &&
485 (-tmp2 - (-c2 * tmp)) <
486 std::numeric_limits<NekDouble>::epsilon())
487 {
488 conv = true;
489 break;
490 }
491
492 gamma /= 2.0;
493 }
494
495 if (!conv)
496 {
497 break;
498 }
499
500 xi[0] += gamma * pk[0];
501 xi[1] += gamma * pk[1];
502 }
503
504 xiOut = xi;
505 return sqrt(fx_prev);
506 }
507 else
508 {
509 ASSERTL0(false, "Geometry type unknown")
510 }
511
512 return -1.0;
513}
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:558
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:548
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:295

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, and tinysimd::sqrt().

◆ 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 221 of file Geometry2D.cpp.

223{
224 NekDouble dist = std::numeric_limits<double>::max();
225 Array<OneD, NekDouble> tmpcoords(2);
226 tmpcoords[0] = coords[m_manifold[0]];
227 tmpcoords[1] = coords[m_manifold[1]];
228 if (GetMetricInfo()->GetGtype() == eRegular)
229 {
230 tmpcoords[0] -= m_isoParameter[0][0];
231 tmpcoords[1] -= m_isoParameter[1][0];
232 Lcoords[0] = m_invIsoParam[0][0] * tmpcoords[0] +
233 m_invIsoParam[0][1] * tmpcoords[1];
234 Lcoords[1] = m_invIsoParam[1][0] * tmpcoords[0] +
235 m_invIsoParam[1][1] * tmpcoords[1];
236 }
237 else if (m_straightEdge)
238 {
239 SolveStraightEdgeQuad(tmpcoords, Lcoords);
240 }
241 else if (GetMetricInfo()->GetGtype() == eDeformed)
242 {
243 v_FillGeom();
244 // Determine nearest point of coords to values in m_xmap
245 int npts = m_xmap->GetTotPoints();
246 Array<OneD, NekDouble> ptsx(npts), ptsy(npts);
247 Array<OneD, NekDouble> tmpx(npts), tmpy(npts);
248
249 // Determine 3D manifold orientation
250 m_xmap->BwdTrans(m_coeffs[m_manifold[0]], ptsx);
251 m_xmap->BwdTrans(m_coeffs[m_manifold[1]], ptsy);
252
253 Array<OneD, NekDouble> eta(2, 0.);
254 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
255 ClampLocCoords(eta, 0.);
256
257 m_xmap->LocCollapsedToLocCoord(eta, Lcoords);
258
259 // Perform newton iteration to find local coordinates
260 NewtonIterationForLocCoord(tmpcoords, ptsx, ptsy, Lcoords, dist);
261 }
262 if (m_coordim == 3)
263 {
264 Array<OneD, NekDouble> eta(2, 0.), xi(2, 0.);
265 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
266 ClampLocCoords(eta, 0.);
267 m_xmap->LocCollapsedToLocCoord(eta, xi);
268 int npts = m_xmap->GetTotPoints();
269 Array<OneD, NekDouble> ptsz(npts);
270 m_xmap->BwdTrans(m_coeffs[m_manifold[2]], ptsz);
271 NekDouble z = m_xmap->PhysEvaluate(xi, ptsz) - coords[m_manifold[2]];
272 if (GetMetricInfo()->GetGtype() == eDeformed)
273 {
274 dist = sqrt(z * z + dist * dist);
275 }
276 else
277 {
278 dist = fabs(z);
279 }
280 }
281 return dist;
282}
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)
virtual void v_FillGeom()
Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements.
Definition Geometry.cpp:363
GeomFactorsSharedPtr GetMetricInfo()
Get the geometric factors for this object.
Definition Geometry.h:306

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

◆ 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 284 of file Geometry2D.cpp.

285{
286 return 2;
287}

Member Data Documentation

◆ kDim

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

Definition at line 56 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

◆ m_manifold

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