47 namespace SpatialDomains
50 Geometry2D::Geometry2D()
58 "Coordinate dimension should be at least 2 for a 2D geometry");
86 NekDouble derx_1, derx_2, dery_1, dery_2, jac;
89 NekDouble init0 = Lcoords[0], init1 = Lcoords[1];
97 m_xmap->PhysDeriv(ptsx, DxD1, DxD2);
98 m_xmap->PhysDeriv(ptsy, DyD1, DyD2);
106 while (cnt++ < MaxIterations)
109 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
110 I[0] =
m_xmap->GetBasis(0)->GetI(eta);
111 I[1] =
m_xmap->GetBasis(1)->GetI(eta + 1);
114 xmap =
m_xmap->PhysEvaluate(I, ptsx);
115 ymap =
m_xmap->PhysEvaluate(I, ptsy);
117 F1 = coords[0] - xmap;
118 F2 = coords[1] - ymap;
120 if (F1 * F1 + F2 * F2 < ScaledTol)
122 resid =
sqrt(F1 * F1 + F2 * F2);
127 derx_1 =
m_xmap->PhysEvaluate(I, DxD1);
128 derx_2 =
m_xmap->PhysEvaluate(I, DxD2);
129 dery_1 =
m_xmap->PhysEvaluate(I, DyD1);
130 dery_2 =
m_xmap->PhysEvaluate(I, DyD2);
132 jac = dery_2 * derx_1 - dery_1 * derx_2;
138 (dery_2 * (coords[0] - xmap) - derx_2 * (coords[1] - ymap)) / jac;
142 (-dery_1 * (coords[0] - xmap) + derx_1 * (coords[1] - ymap)) / jac;
144 if (!(std::isfinite(Lcoords[0]) && std::isfinite(Lcoords[1])))
147 std::ostringstream ss;
148 ss <<
"nan or inf found in NewtonIterationForLocCoord in element "
153 if (fabs(Lcoords[0]) > LcoordDiv || fabs(Lcoords[1]) > LcoordDiv)
159 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
162 I[0] =
m_xmap->GetBasis(0)->GetI(eta);
163 I[1] =
m_xmap->GetBasis(1)->GetI(eta + 1);
165 xmap =
m_xmap->PhysEvaluate(I, ptsx);
166 ymap =
m_xmap->PhysEvaluate(I, ptsy);
167 F1 = coords[0] - xmap;
168 F2 = coords[1] - ymap;
169 dist =
sqrt(F1 * F1 + F2 * F2);
176 if (cnt >= MaxIterations)
179 m_xmap->LocCoordToLocCollapsed(Lcoords, collCoords);
182 if ((collCoords[0] >= -1.0 && collCoords[0] <= 1.0) &&
183 (collCoords[1] >= -1.0 && collCoords[1] <= 1.0))
185 std::ostringstream ss;
187 ss <<
"Reached MaxIterations (" << MaxIterations
188 <<
") in Newton iteration ";
189 ss <<
"Init value (" << setprecision(4) << init0 <<
"," << init1
192 ss <<
"Fin value (" << Lcoords[0] <<
"," << Lcoords[1] <<
","
194 ss <<
"Resid = " << resid <<
" Tolerance = " <<
sqrt(ScaledTol);
196 WARNINGL1(cnt < MaxIterations, ss.str());
219 ASSERTL0(
false,
"unrecognized 2D element type");
235 orth1.
Mult(norm, e10);
236 orth2.
Mult(norm, e20);
240 Lcoords[0] = er0.
dot(orth2) / e10.
dot(orth2);
241 Lcoords[0] = 2. * Lcoords[0] - 1.;
242 Lcoords[1] = er0.
dot(orth1) / e20.
dot(orth1);
243 Lcoords[1] = 2. * Lcoords[1] - 1.;
247 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
251 m_xmap->LocCollapsedToLocCoord(eta, xi);
252 xi[0] = (xi[0] + 1.) * 0.5;
253 xi[1] = (xi[1] + 1.) * 0.5;
256 NekDouble tmp = xi[0] * e10[i] + xi[1] * e20[i] - er0[i];
266 int npts =
m_xmap->GetTotPoints();
271 int idx = 0, idy = 1;
279 double tmp = std::fabs(norm[0]);
280 if (tmp < fabs(norm[1]))
285 if (tmp < fabs(norm[2]))
289 idx = (tmpi + 1) % 3;
290 idy = (tmpi + 2) % 3;
293 tmpcoords[0] = coords[idx];
294 tmpcoords[1] = coords[idy];
303 Vmath::Sadd(npts, -tmpcoords[0], ptsx, 1, tmpx, 1);
304 Vmath::Sadd(npts, -tmpcoords[1], ptsy, 1, tmpy, 1);
311 eta[0] = za[min_i % za.size()];
312 eta[1] = zb[min_i / za.size()];
313 m_xmap->LocCollapsedToLocCoord(eta, Lcoords);
369 return sqrt((xs[0] - gloCoord[0]) * (xs[0] - gloCoord[0]) +
370 (xs[1] - gloCoord[1]) * (xs[1] - gloCoord[1]) +
371 (xs[2] - gloCoord[2]) * (xs[2] - gloCoord[2]));
379 m_xmap->LocCollapsedToLocCoord(eta, xi);
385 int nq =
m_xmap->GetTotPoints();
393 zderxi1(nq, 0.0), xderxi2(nq, 0.0), yderxi2(nq, 0.0),
394 zderxi2(nq, 0.0), xderxi1xi1(nq, 0.0), yderxi1xi1(nq, 0.0),
395 zderxi1xi1(nq, 0.0), xderxi1xi2(nq, 0.0), yderxi1xi2(nq, 0.0),
396 zderxi1xi2(nq, 0.0), xderxi2xi1(nq, 0.0), yderxi2xi1(nq, 0.0),
397 zderxi2xi1(nq, 0.0), xderxi2xi2(nq, 0.0), yderxi2xi2(nq, 0.0),
401 std::array<NekDouble, 3> xc_derxi, yc_derxi, zc_derxi;
403 m_xmap->PhysDeriv(x, xderxi1, xderxi2);
404 m_xmap->PhysDeriv(y, yderxi1, yderxi2);
405 m_xmap->PhysDeriv(z, zderxi1, zderxi2);
407 m_xmap->PhysDeriv(xderxi1, xderxi1xi1, xderxi1xi2);
408 m_xmap->PhysDeriv(yderxi1, yderxi1xi1, yderxi1xi2);
409 m_xmap->PhysDeriv(zderxi1, zderxi1xi1, zderxi1xi2);
411 m_xmap->PhysDeriv(yderxi2, yderxi2xi1, yderxi2xi2);
412 m_xmap->PhysDeriv(xderxi2, xderxi2xi1, xderxi2xi2);
413 m_xmap->PhysDeriv(zderxi2, zderxi2xi1, zderxi2xi2);
416 NekDouble fx_prev = std::numeric_limits<NekDouble>::max();
441 NekDouble fx = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
443 NekDouble fx_derxi1 = 2.0 * xdiff * xc_derxi[0] +
444 2.0 * ydiff * yc_derxi[0] +
445 2.0 * zdiff * zc_derxi[0];
447 NekDouble fx_derxi2 = 2.0 * xdiff * xc_derxi[1] +
448 2.0 * ydiff * yc_derxi[1] +
449 2.0 * zdiff * zc_derxi[1];
452 2.0 * xdiff * xc_derxi1xi1 + 2.0 * xc_derxi[0] * xc_derxi[0] +
453 2.0 * ydiff * yc_derxi1xi1 + 2.0 * yc_derxi[0] * yc_derxi[0] +
454 2.0 * zdiff * zc_derxi1xi1 + 2.0 * zc_derxi[0] * zc_derxi[0];
457 2.0 * xdiff * xc_derxi1xi2 + 2.0 * xc_derxi[1] * xc_derxi[0] +
458 2.0 * ydiff * yc_derxi1xi2 + 2.0 * yc_derxi[1] * yc_derxi[0] +
459 2.0 * zdiff * zc_derxi1xi2 + 2.0 * zc_derxi[1] * zc_derxi[0];
462 2.0 * xdiff * xc_derxi2xi2 + 2.0 * xc_derxi[1] * xc_derxi[1] +
463 2.0 * ydiff * yc_derxi2xi2 + 2.0 * yc_derxi[1] * yc_derxi[1] +
464 2.0 * zdiff * zc_derxi2xi2 + 2.0 * zc_derxi[1] * zc_derxi[1];
475 1 / (fx_derxi1xi1 * fx_derxi2xi2 - fx_derxi1xi2 * fx_derxi1xi2);
476 hessInv[0][0] = det * fx_derxi2xi2;
477 hessInv[0][1] = det * -fx_derxi1xi2;
478 hessInv[1][0] = det * -fx_derxi1xi2;
479 hessInv[1][1] = det * fx_derxi1xi1;
482 if (
abs(fx - fx_prev) < 1e-12)
497 pk[0] = -(hessInv[0][0] * jac[0] + hessInv[1][0] * jac[1]);
498 pk[1] = -(hessInv[0][1] * jac[0] + hessInv[1][1] * jac[1]);
501 while (gamma > 1e-10)
504 xi_pk[0] = xi[0] + pk[0] * gamma;
505 xi_pk[1] = xi[1] + pk[1] * gamma;
508 m_xmap->LocCoordToLocCollapsed(xi_pk, eta_pk);
511 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
513 (1 + std::numeric_limits<NekDouble>::epsilon()) ||
515 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
516 eta_pk[1] > (1 + std::numeric_limits<NekDouble>::epsilon()))
522 std::array<NekDouble, 3> xc_pk_derxi, yc_pk_derxi, zc_pk_derxi;
532 NekDouble fx_pk = xc_pk_diff * xc_pk_diff +
533 yc_pk_diff * yc_pk_diff +
534 zc_pk_diff * zc_pk_diff;
536 NekDouble fx_pk_derxi1 = 2.0 * xc_pk_diff * xc_pk_derxi[0] +
537 2.0 * yc_pk_diff * yc_pk_derxi[0] +
538 2.0 * zc_pk_diff * zc_pk_derxi[0];
540 NekDouble fx_pk_derxi2 = 2.0 * xc_pk_diff * xc_pk_derxi[1] +
541 2.0 * yc_pk_diff * yc_pk_derxi[1] +
542 2.0 * zc_pk_diff * zc_pk_derxi[1];
546 NekDouble tmp = pk[0] * fx_derxi1 + pk[1] * fx_derxi2;
547 NekDouble tmp2 = pk[0] * fx_pk_derxi1 + pk[1] * fx_pk_derxi2;
548 if ((fx_pk - (fx + c1 * gamma * tmp)) <
549 std::numeric_limits<NekDouble>::epsilon() &&
550 (-tmp2 - (-c2 * tmp)) <
551 std::numeric_limits<NekDouble>::epsilon())
565 xi[0] += gamma * pk[0];
566 xi[1] += gamma * pk[1];
570 return sqrt(fx_prev);
574 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)
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 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.
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.
LibUtilities::ShapeType m_shapeType
Type of shape.
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.
GeomFactorsSharedPtr m_geomFactors
Geometric factors.
int m_coordim
Coordinate dimension of this geometry object.
void Sub(PointGeom &a, PointGeom &b)
void Mult(PointGeom &a, PointGeom &b)
_this = a x b
NekDouble dot(PointGeom &a)
retun the dot product between this and input a
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
The above copyright notice and this permission notice shall be included.
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
int Imin(int n, const T *x, const int incx)
Return the index of the minimum element in x.
void Sadd(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Add scalar y = alpha + x.
scalarT< T > abs(scalarT< T > in)
scalarT< T > sqrt(scalarT< T > in)