105 NekDouble derx_1, derx_2, dery_1, dery_2, jac;
108 NekDouble init0 = Lcoords[0], init1 = Lcoords[1];
116 m_xmap->PhysDeriv(ptsx, DxD1, DxD2);
117 m_xmap->PhysDeriv(ptsy, DyD1, DyD2);
125 while (cnt++ < MaxIterations)
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);
133 xmap =
m_xmap->PhysEvaluate(I, ptsx);
134 ymap =
m_xmap->PhysEvaluate(I, ptsy);
136 F1 = coords[0] - xmap;
137 F2 = coords[1] - ymap;
139 if (F1 * F1 + F2 * F2 < ScaledTol)
141 resid =
sqrt(F1 * F1 + F2 * F2);
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);
151 jac = dery_2 * derx_1 - dery_1 * derx_2;
157 (dery_2 * (coords[0] - xmap) - derx_2 * (coords[1] - ymap)) / jac;
161 (-dery_1 * (coords[0] - xmap) + derx_1 * (coords[1] - ymap)) / jac;
163 if (!(std::isfinite(Lcoords[0]) && std::isfinite(Lcoords[1])))
166 std::ostringstream ss;
167 ss <<
"nan or inf found in NewtonIterationForLocCoord in element "
172 if (fabs(Lcoords[0]) > LcoordDiv || fabs(Lcoords[1]) > LcoordDiv)
178 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
181 I[0] =
m_xmap->GetBasis(0)->GetI(eta);
182 I[1] =
m_xmap->GetBasis(1)->GetI(eta + 1);
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);
195 if (cnt >= MaxIterations)
198 m_xmap->LocCoordToLocCollapsed(Lcoords, collCoords);
201 if ((collCoords[0] >= -1.0 && collCoords[0] <= 1.0) &&
202 (collCoords[1] >= -1.0 && collCoords[1] <= 1.0))
204 std::ostringstream ss;
206 ss <<
"Reached MaxIterations (" << MaxIterations
207 <<
") in Newton iteration ";
208 ss <<
"Init value (" << std::setprecision(4) << init0 <<
","
211 ss <<
"Fin value (" << Lcoords[0] <<
"," << Lcoords[1] <<
","
213 ss <<
"Resid = " << resid
214 <<
" Tolerance = " << std::sqrt(ScaledTol);
216 WARNINGL1(cnt < MaxIterations, ss.str());
306 return sqrt((xs[0] - gloCoord[0]) * (xs[0] - gloCoord[0]) +
307 (xs[1] - gloCoord[1]) * (xs[1] - gloCoord[1]) +
308 (xs[2] - gloCoord[2]) * (xs[2] - gloCoord[2]));
316 m_xmap->LocCollapsedToLocCoord(eta, xi);
322 int nq =
m_xmap->GetTotPoints();
330 zderxi1(nq, 0.0), xderxi2(nq, 0.0), yderxi2(nq, 0.0),
331 zderxi2(nq, 0.0), xderxi1xi1(nq, 0.0), yderxi1xi1(nq, 0.0),
332 zderxi1xi1(nq, 0.0), xderxi1xi2(nq, 0.0), yderxi1xi2(nq, 0.0),
333 zderxi1xi2(nq, 0.0), xderxi2xi1(nq, 0.0), yderxi2xi1(nq, 0.0),
334 zderxi2xi1(nq, 0.0), xderxi2xi2(nq, 0.0), yderxi2xi2(nq, 0.0),
338 std::array<NekDouble, 3> xc_derxi, yc_derxi, zc_derxi;
340 m_xmap->PhysDeriv(x, xderxi1, xderxi2);
341 m_xmap->PhysDeriv(y, yderxi1, yderxi2);
342 m_xmap->PhysDeriv(z, zderxi1, zderxi2);
344 m_xmap->PhysDeriv(xderxi1, xderxi1xi1, xderxi1xi2);
345 m_xmap->PhysDeriv(yderxi1, yderxi1xi1, yderxi1xi2);
346 m_xmap->PhysDeriv(zderxi1, zderxi1xi1, zderxi1xi2);
348 m_xmap->PhysDeriv(yderxi2, yderxi2xi1, yderxi2xi2);
349 m_xmap->PhysDeriv(xderxi2, xderxi2xi1, xderxi2xi2);
350 m_xmap->PhysDeriv(zderxi2, zderxi2xi1, zderxi2xi2);
353 NekDouble fx_prev = std::numeric_limits<NekDouble>::max();
378 NekDouble fx = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
380 NekDouble fx_derxi1 = 2.0 * xdiff * xc_derxi[0] +
381 2.0 * ydiff * yc_derxi[0] +
382 2.0 * zdiff * zc_derxi[0];
384 NekDouble fx_derxi2 = 2.0 * xdiff * xc_derxi[1] +
385 2.0 * ydiff * yc_derxi[1] +
386 2.0 * zdiff * zc_derxi[1];
389 2.0 * xdiff * xc_derxi1xi1 + 2.0 * xc_derxi[0] * xc_derxi[0] +
390 2.0 * ydiff * yc_derxi1xi1 + 2.0 * yc_derxi[0] * yc_derxi[0] +
391 2.0 * zdiff * zc_derxi1xi1 + 2.0 * zc_derxi[0] * zc_derxi[0];
394 2.0 * xdiff * xc_derxi1xi2 + 2.0 * xc_derxi[1] * xc_derxi[0] +
395 2.0 * ydiff * yc_derxi1xi2 + 2.0 * yc_derxi[1] * yc_derxi[0] +
396 2.0 * zdiff * zc_derxi1xi2 + 2.0 * zc_derxi[1] * zc_derxi[0];
399 2.0 * xdiff * xc_derxi2xi2 + 2.0 * xc_derxi[1] * xc_derxi[1] +
400 2.0 * ydiff * yc_derxi2xi2 + 2.0 * yc_derxi[1] * yc_derxi[1] +
401 2.0 * zdiff * zc_derxi2xi2 + 2.0 * zc_derxi[1] * zc_derxi[1];
412 1 / (fx_derxi1xi1 * fx_derxi2xi2 - fx_derxi1xi2 * fx_derxi1xi2);
413 hessInv[0][0] = det * fx_derxi2xi2;
414 hessInv[0][1] = det * -fx_derxi1xi2;
415 hessInv[1][0] = det * -fx_derxi1xi2;
416 hessInv[1][1] = det * fx_derxi1xi1;
419 if (
abs(fx - fx_prev) < 1e-12)
434 pk[0] = -(hessInv[0][0] * jac[0] + hessInv[1][0] * jac[1]);
435 pk[1] = -(hessInv[0][1] * jac[0] + hessInv[1][1] * jac[1]);
438 while (gamma > 1e-10)
441 xi_pk[0] = xi[0] + pk[0] * gamma;
442 xi_pk[1] = xi[1] + pk[1] * gamma;
445 m_xmap->LocCoordToLocCollapsed(xi_pk, eta_pk);
448 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
450 (1 + std::numeric_limits<NekDouble>::epsilon()) ||
452 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
453 eta_pk[1] > (1 + std::numeric_limits<NekDouble>::epsilon()))
459 std::array<NekDouble, 3> xc_pk_derxi, yc_pk_derxi, zc_pk_derxi;
469 NekDouble fx_pk = xc_pk_diff * xc_pk_diff +
470 yc_pk_diff * yc_pk_diff +
471 zc_pk_diff * zc_pk_diff;
473 NekDouble fx_pk_derxi1 = 2.0 * xc_pk_diff * xc_pk_derxi[0] +
474 2.0 * yc_pk_diff * yc_pk_derxi[0] +
475 2.0 * zc_pk_diff * zc_pk_derxi[0];
477 NekDouble fx_pk_derxi2 = 2.0 * xc_pk_diff * xc_pk_derxi[1] +
478 2.0 * yc_pk_diff * yc_pk_derxi[1] +
479 2.0 * zc_pk_diff * zc_pk_derxi[1];
483 NekDouble tmp = pk[0] * fx_derxi1 + pk[1] * fx_derxi2;
484 NekDouble tmp2 = pk[0] * fx_pk_derxi1 + pk[1] * fx_pk_derxi2;
485 if ((fx_pk - (fx + c1 * gamma * tmp)) <
486 std::numeric_limits<NekDouble>::epsilon() &&
487 (-tmp2 - (-c2 * tmp)) <
488 std::numeric_limits<NekDouble>::epsilon())
502 xi[0] += gamma * pk[0];
503 xi[1] += gamma * pk[1];
507 return sqrt(fx_prev);
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)
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...
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...
bool ClampLocCoords(Array< OneD, NekDouble > &locCoord, NekDouble tol=std::numeric_limits< NekDouble >::epsilon())
Clamp local coords to be within standard regions [-1, 1]^dim.