47namespace SpatialDomains
58 "Coordinate dimension should be at least 2 for a 2D geometry");
76 for (
size_t i = 0; i <
m_verts.size(); ++i)
92 for (
size_t i = 0; i <
m_verts.size(); ++i)
115 const int MaxIterations = 51;
123 ScaledTol *= Tol * Tol;
126 NekDouble derx_1, derx_2, dery_1, dery_2, jac;
130 while (cnt++ < MaxIterations)
139 F1 = coords[0] - xmap;
140 F2 = coords[1] - ymap;
142 res = F1 * F1 + F2 * F2;
154 jac = 1. / (dery_2 * derx_1 - dery_1 * derx_2);
158 Lcoords[0] += (dery_2 * F1 - derx_2 * F2) * jac;
160 Lcoords[1] += (-dery_1 * F1 + derx_1 * F2) * jac;
162 if (!(std::isfinite(Lcoords[0]) && std::isfinite(Lcoords[1])) ||
163 fabs(Lcoords[0]) > LcoordDiv || fabs(Lcoords[1]) > LcoordDiv)
165 std::ostringstream ss;
166 ss <<
"Iteration has diverged in NewtonIterationForLocCoord in "
174 if (cnt >= MaxIterations)
176 std::ostringstream ss;
178 ss <<
"Reached MaxIterations (" << MaxIterations
179 <<
") in Newton iteration ";
181 WARNINGL1(cnt < MaxIterations, ss.str());
206 NekDouble derx_1, derx_2, dery_1, dery_2, jac;
209 NekDouble init0 = Lcoords[0], init1 = Lcoords[1];
217 m_xmap->PhysDeriv(ptsx, DxD1, DxD2);
218 m_xmap->PhysDeriv(ptsy, DyD1, DyD2);
226 while (cnt++ < MaxIterations)
229 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
230 I[0] =
m_xmap->GetBasis(0)->GetI(eta);
231 I[1] =
m_xmap->GetBasis(1)->GetI(eta + 1);
234 xmap =
m_xmap->PhysEvaluate(I, ptsx);
235 ymap =
m_xmap->PhysEvaluate(I, ptsy);
237 F1 = coords[0] - xmap;
238 F2 = coords[1] - ymap;
240 if (F1 * F1 + F2 * F2 < ScaledTol)
242 resid =
sqrt(F1 * F1 + F2 * F2);
247 derx_1 =
m_xmap->PhysEvaluate(I, DxD1);
248 derx_2 =
m_xmap->PhysEvaluate(I, DxD2);
249 dery_1 =
m_xmap->PhysEvaluate(I, DyD1);
250 dery_2 =
m_xmap->PhysEvaluate(I, DyD2);
252 jac = dery_2 * derx_1 - dery_1 * derx_2;
258 (dery_2 * (coords[0] - xmap) - derx_2 * (coords[1] - ymap)) / jac;
262 (-dery_1 * (coords[0] - xmap) + derx_1 * (coords[1] - ymap)) / jac;
264 if (!(std::isfinite(Lcoords[0]) && std::isfinite(Lcoords[1])))
267 std::ostringstream ss;
268 ss <<
"nan or inf found in NewtonIterationForLocCoord in element "
273 if (fabs(Lcoords[0]) > LcoordDiv || fabs(Lcoords[1]) > LcoordDiv)
279 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
282 I[0] =
m_xmap->GetBasis(0)->GetI(eta);
283 I[1] =
m_xmap->GetBasis(1)->GetI(eta + 1);
285 xmap =
m_xmap->PhysEvaluate(I, ptsx);
286 ymap =
m_xmap->PhysEvaluate(I, ptsy);
287 F1 = coords[0] - xmap;
288 F2 = coords[1] - ymap;
289 dist =
sqrt(F1 * F1 + F2 * F2);
296 if (cnt >= MaxIterations)
299 m_xmap->LocCoordToLocCollapsed(Lcoords, collCoords);
302 if ((collCoords[0] >= -1.0 && collCoords[0] <= 1.0) &&
303 (collCoords[1] >= -1.0 && collCoords[1] <= 1.0))
305 std::ostringstream ss;
307 ss <<
"Reached MaxIterations (" << MaxIterations
308 <<
") in Newton iteration ";
309 ss <<
"Init value (" << setprecision(4) << init0 <<
"," << init1
312 ss <<
"Fin value (" << Lcoords[0] <<
"," << Lcoords[1] <<
","
314 ss <<
"Resid = " << resid <<
" Tolerance = " <<
sqrt(ScaledTol);
316 WARNINGL1(cnt < MaxIterations, ss.str());
324 NekDouble dist = std::numeric_limits<double>::max();
346 int npts =
m_xmap->GetTotPoints();
355 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
358 m_xmap->LocCollapsedToLocCoord(eta, Lcoords);
414 return sqrt((xs[0] - gloCoord[0]) * (xs[0] - gloCoord[0]) +
415 (xs[1] - gloCoord[1]) * (xs[1] - gloCoord[1]) +
416 (xs[2] - gloCoord[2]) * (xs[2] - gloCoord[2]));
424 m_xmap->LocCollapsedToLocCoord(eta, xi);
430 int nq =
m_xmap->GetTotPoints();
438 zderxi1(nq, 0.0), xderxi2(nq, 0.0), yderxi2(nq, 0.0),
439 zderxi2(nq, 0.0), xderxi1xi1(nq, 0.0), yderxi1xi1(nq, 0.0),
440 zderxi1xi1(nq, 0.0), xderxi1xi2(nq, 0.0), yderxi1xi2(nq, 0.0),
441 zderxi1xi2(nq, 0.0), xderxi2xi1(nq, 0.0), yderxi2xi1(nq, 0.0),
442 zderxi2xi1(nq, 0.0), xderxi2xi2(nq, 0.0), yderxi2xi2(nq, 0.0),
446 std::array<NekDouble, 3> xc_derxi, yc_derxi, zc_derxi;
448 m_xmap->PhysDeriv(x, xderxi1, xderxi2);
449 m_xmap->PhysDeriv(y, yderxi1, yderxi2);
450 m_xmap->PhysDeriv(
z, zderxi1, zderxi2);
452 m_xmap->PhysDeriv(xderxi1, xderxi1xi1, xderxi1xi2);
453 m_xmap->PhysDeriv(yderxi1, yderxi1xi1, yderxi1xi2);
454 m_xmap->PhysDeriv(zderxi1, zderxi1xi1, zderxi1xi2);
456 m_xmap->PhysDeriv(yderxi2, yderxi2xi1, yderxi2xi2);
457 m_xmap->PhysDeriv(xderxi2, xderxi2xi1, xderxi2xi2);
458 m_xmap->PhysDeriv(zderxi2, zderxi2xi1, zderxi2xi2);
461 NekDouble fx_prev = std::numeric_limits<NekDouble>::max();
486 NekDouble fx = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
488 NekDouble fx_derxi1 = 2.0 * xdiff * xc_derxi[0] +
489 2.0 * ydiff * yc_derxi[0] +
490 2.0 * zdiff * zc_derxi[0];
492 NekDouble fx_derxi2 = 2.0 * xdiff * xc_derxi[1] +
493 2.0 * ydiff * yc_derxi[1] +
494 2.0 * zdiff * zc_derxi[1];
497 2.0 * xdiff * xc_derxi1xi1 + 2.0 * xc_derxi[0] * xc_derxi[0] +
498 2.0 * ydiff * yc_derxi1xi1 + 2.0 * yc_derxi[0] * yc_derxi[0] +
499 2.0 * zdiff * zc_derxi1xi1 + 2.0 * zc_derxi[0] * zc_derxi[0];
502 2.0 * xdiff * xc_derxi1xi2 + 2.0 * xc_derxi[1] * xc_derxi[0] +
503 2.0 * ydiff * yc_derxi1xi2 + 2.0 * yc_derxi[1] * yc_derxi[0] +
504 2.0 * zdiff * zc_derxi1xi2 + 2.0 * zc_derxi[1] * zc_derxi[0];
507 2.0 * xdiff * xc_derxi2xi2 + 2.0 * xc_derxi[1] * xc_derxi[1] +
508 2.0 * ydiff * yc_derxi2xi2 + 2.0 * yc_derxi[1] * yc_derxi[1] +
509 2.0 * zdiff * zc_derxi2xi2 + 2.0 * zc_derxi[1] * zc_derxi[1];
520 1 / (fx_derxi1xi1 * fx_derxi2xi2 - fx_derxi1xi2 * fx_derxi1xi2);
521 hessInv[0][0] = det * fx_derxi2xi2;
522 hessInv[0][1] = det * -fx_derxi1xi2;
523 hessInv[1][0] = det * -fx_derxi1xi2;
524 hessInv[1][1] = det * fx_derxi1xi1;
527 if (
abs(fx - fx_prev) < 1e-12)
542 pk[0] = -(hessInv[0][0] * jac[0] + hessInv[1][0] * jac[1]);
543 pk[1] = -(hessInv[0][1] * jac[0] + hessInv[1][1] * jac[1]);
546 while (gamma > 1e-10)
549 xi_pk[0] = xi[0] + pk[0] * gamma;
550 xi_pk[1] = xi[1] + pk[1] * gamma;
553 m_xmap->LocCoordToLocCollapsed(xi_pk, eta_pk);
556 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
558 (1 + std::numeric_limits<NekDouble>::epsilon()) ||
560 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
561 eta_pk[1] > (1 + std::numeric_limits<NekDouble>::epsilon()))
567 std::array<NekDouble, 3> xc_pk_derxi, yc_pk_derxi, zc_pk_derxi;
577 NekDouble fx_pk = xc_pk_diff * xc_pk_diff +
578 yc_pk_diff * yc_pk_diff +
579 zc_pk_diff * zc_pk_diff;
581 NekDouble fx_pk_derxi1 = 2.0 * xc_pk_diff * xc_pk_derxi[0] +
582 2.0 * yc_pk_diff * yc_pk_derxi[0] +
583 2.0 * zc_pk_diff * zc_pk_derxi[0];
585 NekDouble fx_pk_derxi2 = 2.0 * xc_pk_diff * xc_pk_derxi[1] +
586 2.0 * yc_pk_diff * yc_pk_derxi[1] +
587 2.0 * zc_pk_diff * zc_pk_derxi[1];
591 NekDouble tmp = pk[0] * fx_derxi1 + pk[1] * fx_derxi2;
592 NekDouble tmp2 = pk[0] * fx_pk_derxi1 + pk[1] * fx_pk_derxi2;
593 if ((fx_pk - (fx + c1 * gamma * tmp)) <
594 std::numeric_limits<NekDouble>::epsilon() &&
595 (-tmp2 - (-c2 * tmp)) <
596 std::numeric_limits<NekDouble>::epsilon())
610 xi[0] += gamma * pk[0];
611 xi[1] += gamma * pk[1];
615 return sqrt(fx_prev);
619 ASSERTL0(
false,
"Geometry type unknown")
#define WARNINGL1(condition, msg)
#define ASSERTL0(condition, msg)
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
virtual int v_GetShapeDim() const override
Get the object's shape dimension.
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)
Array< OneD, int > m_manifold
Array< OneD, Array< OneD, NekDouble > > m_edgeNormal
virtual PointGeomSharedPtr v_GetVertex(int i) const override
virtual Geometry1DSharedPtr v_GetEdge(int i) const override
Returns edge i of this object.
std::vector< StdRegions::Orientation > m_eorient
virtual 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 ge...
virtual int v_AllLeftCheck(const Array< OneD, const NekDouble > &gloCoord) override
virtual void v_CalculateInverseIsoParam() override
virtual 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.
virtual NekDouble v_FindDistance(const Array< OneD, const NekDouble > &xs, Array< OneD, NekDouble > &xi) override
virtual int v_GetNumEdges() const override
Get the number of edges of this object.
virtual int v_GetNumVerts() const override
Get the number of vertices of this object.
Base class for shape geometry information.
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.
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...
virtual void v_FillGeom()
Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements.
Array< OneD, Array< OneD, NekDouble > > m_isoParameter
Array< OneD, Array< OneD, NekDouble > > m_invIsoParam
bool ClampLocCoords(Array< OneD, NekDouble > &locCoord, NekDouble tol=std::numeric_limits< NekDouble >::epsilon())
Clamp local coords to be within standard regions [-1, 1]^dim.
int GetGlobalID(void) const
Get the ID of this object.
Array< OneD, Array< OneD, NekDouble > > m_coeffs
Array containing expansion coefficients of m_xmap.
GeomFactorsSharedPtr GetMetricInfo()
Get the geometric factors for this object.
StdRegions::StdExpansionSharedPtr m_xmap
mapping containing isoparametric transformation.
StdRegions::StdExpansionSharedPtr GetXmap() const
Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standar...
GeomFactorsSharedPtr m_geomFactors
Geometric factors.
int m_coordim
Coordinate dimension of this geometry object.
static const unsigned int kNewtonIterations
std::shared_ptr< Curve > CurveSharedPtr
@ eRegular
Geometry is straight-sided with constant geometric factors.
@ eDeformed
Geometry is curved or has non-constant factors.
std::shared_ptr< PointGeom > PointGeomSharedPtr
std::shared_ptr< Geometry1D > Geometry1DSharedPtr
std::vector< double > z(NPUPPER)
The above copyright notice and this permission notice shall be included.
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
scalarT< T > abs(scalarT< T > in)
scalarT< T > sqrt(scalarT< T > in)