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());
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]));
314 m_xmap->LocCollapsedToLocCoord(eta, xi);
320 int nq =
m_xmap->GetTotPoints();
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),
336 std::array<NekDouble, 3> xc_derxi, yc_derxi, zc_derxi;
338 m_xmap->PhysDeriv(x, xderxi1, xderxi2);
339 m_xmap->PhysDeriv(y, yderxi1, yderxi2);
340 m_xmap->PhysDeriv(z, zderxi1, zderxi2);
342 m_xmap->PhysDeriv(xderxi1, xderxi1xi1, xderxi1xi2);
343 m_xmap->PhysDeriv(yderxi1, yderxi1xi1, yderxi1xi2);
344 m_xmap->PhysDeriv(zderxi1, zderxi1xi1, zderxi1xi2);
346 m_xmap->PhysDeriv(yderxi2, yderxi2xi1, yderxi2xi2);
347 m_xmap->PhysDeriv(xderxi2, xderxi2xi1, xderxi2xi2);
348 m_xmap->PhysDeriv(zderxi2, zderxi2xi1, zderxi2xi2);
351 NekDouble fx_prev = std::numeric_limits<NekDouble>::max();
376 NekDouble fx = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
378 NekDouble fx_derxi1 = 2.0 * xdiff * xc_derxi[0] +
379 2.0 * ydiff * yc_derxi[0] +
380 2.0 * zdiff * zc_derxi[0];
382 NekDouble fx_derxi2 = 2.0 * xdiff * xc_derxi[1] +
383 2.0 * ydiff * yc_derxi[1] +
384 2.0 * zdiff * zc_derxi[1];
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];
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];
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];
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;
417 if (
abs(fx - fx_prev) < 1e-12)
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]);
436 while (gamma > 1e-10)
439 xi_pk[0] = xi[0] + pk[0] * gamma;
440 xi_pk[1] = xi[1] + pk[1] * gamma;
443 m_xmap->LocCoordToLocCollapsed(xi_pk, eta_pk);
446 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
448 (1 + std::numeric_limits<NekDouble>::epsilon()) ||
450 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
451 eta_pk[1] > (1 + std::numeric_limits<NekDouble>::epsilon()))
457 std::array<NekDouble, 3> xc_pk_derxi, yc_pk_derxi, zc_pk_derxi;
467 NekDouble fx_pk = xc_pk_diff * xc_pk_diff +
468 yc_pk_diff * yc_pk_diff +
469 zc_pk_diff * zc_pk_diff;
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];
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];
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())
500 xi[0] += gamma * pk[0];
501 xi[1] += gamma * pk[1];
505 return sqrt(fx_prev);
509 ASSERTL0(
false,
"Geometry type unknown")
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.