Nektar++
Geometry2D.cpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: Geometry2D.cpp
4//
5// For more information, please see: http://www.nektar.info/
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: 2D geometry information
32//
33//
34////////////////////////////////////////////////////////////////////////////////
35
36#include <iomanip>
37
40
41#include <iomanip>
42
43using namespace std;
44
46{
47
49{
50}
51
52Geometry2D::Geometry2D(const int coordim, CurveSharedPtr curve)
53 : Geometry(coordim), m_curve(curve)
54{
56 "Coordinate dimension should be at least 2 for a 2D geometry");
57}
58
60{
61}
62
64{
65 int nc = 1, d0 = m_manifold[0], d1 = m_manifold[1];
66 if (0 == m_edgeNormal.size())
67 {
70 x[0] = Array<OneD, NekDouble>(3);
71 x[1] = Array<OneD, NekDouble>(3);
72 m_verts[m_verts.size() - 1]->GetCoords(x[0]);
73 int i0 = 1, i1 = 0, direction = 1;
74 for (size_t i = 0; i < m_verts.size(); ++i)
75 {
76 i0 ^= 1;
77 i1 ^= 1;
78 m_verts[i]->GetCoords(x[i1]);
79 if (m_edges[i]->GetXmap()->GetBasis(0)->GetNumModes() > 2)
80 {
81 continue;
82 }
84 m_edgeNormal[i][0] = x[i0][d1] - x[i1][d1];
85 m_edgeNormal[i][1] = x[i1][d0] - x[i0][d0];
86 }
87 if (m_coordim == 3)
88 {
89 for (size_t i = 0; i < m_verts.size(); ++i)
90 {
91 if (m_edgeNormal[i].size() == 2)
92 {
93 m_verts[i]->GetCoords(x[0]);
94 m_verts[(i + 2) % m_verts.size()]->GetCoords(x[1]);
95 if (m_edgeNormal[i][0] * (x[1][d0] - x[0][d0]) <
96 m_edgeNormal[i][1] * (x[0][d1] - x[1][d1]))
97 {
98 direction = -1;
99 }
100 break;
101 }
102 }
103 }
104 if (direction == -1)
105 {
106 for (size_t i = 0; i < m_verts.size(); ++i)
107 {
108 if (m_edgeNormal[i].size() == 2)
109 {
110 m_edgeNormal[i][0] = -m_edgeNormal[i][0];
111 m_edgeNormal[i][1] = -m_edgeNormal[i][1];
112 }
113 }
114 }
115 }
116
117 Array<OneD, NekDouble> vertex(3);
118 for (size_t i = 0; i < m_verts.size(); ++i)
119 {
120 m_verts[i]->GetCoords(vertex);
121 if (m_edgeNormal[i].size() == 0)
122 {
123 nc = 0; // not sure
124 continue;
125 }
126 if (m_edgeNormal[i][0] * (gloCoord[d0] - vertex[d0]) <
127 m_edgeNormal[i][1] * (vertex[d1] - gloCoord[d1]))
128 {
129 return -1; // outside
130 }
131 }
132 // 3D manifold needs to check the distance
133 if (m_coordim == 3)
134 {
135 nc = 0;
136 }
137 // nc: 1 (side element), 0 (maybe inside), -1 (outside)
138 return nc;
139}
140
143{
144 int i0 = 0, i1 = 1, j1 = 0, j2 = 1;
145 if (m_straightEdge & 2)
146 {
147 i0 = 1;
148 i1 = 0;
149 }
150 if (m_straightEdge & 4)
151 {
152 j1 = 1;
153 j2 = 0;
154 }
156 NekDouble gamma = m_isoParameter[1][3];
157 NekDouble tty = (coords[i1] - gamma * coords[i0] - m_isoParameter[1][0]) *
158 m_isoParameter[1][1];
159 NekDouble denom = 1. / (m_isoParameter[0][2] + m_isoParameter[0][3] * tty);
160 NekDouble epsilon = -m_isoParameter[0][3] * beta * denom;
161 NekDouble h =
162 (m_isoParameter[0][0] + m_isoParameter[0][1] * tty - coords[i0]) *
163 denom;
164 Lcoords[j2] = -h / (0.5 + sqrt(0.25 - epsilon * h));
165 Lcoords[j1] = -beta * Lcoords[j2] + tty;
166}
167
169 const Array<OneD, const NekDouble> &coords,
172 NekDouble &dist)
173{
174 // Maximum iterations for convergence
175 const int MaxIterations = NekConstants::kNewtonIterations;
176 // |x-xp|^2 < EPSILON error tolerance
177 const NekDouble Tol = 1.e-8;
178 // |r,s| > LcoordDIV stop the search
179 const NekDouble LcoordDiv = 15.0;
180
182 m_geomFactors->GetJac(m_xmap->GetPointsKeys());
183
184 NekDouble ScaledTol =
185 Vmath::Vsum(Jac.size(), Jac, 1) / ((NekDouble)Jac.size());
186 ScaledTol *= Tol;
187
188 NekDouble xmap, ymap, F1, F2;
189 NekDouble derx_1, derx_2, dery_1, dery_2, jac;
190
191 // save intiial guess for later reference if required.
192 NekDouble init0 = Lcoords[0], init1 = Lcoords[1];
193
194 Array<OneD, NekDouble> DxD1(ptsx.size());
195 Array<OneD, NekDouble> DxD2(ptsx.size());
196 Array<OneD, NekDouble> DyD1(ptsx.size());
197 Array<OneD, NekDouble> DyD2(ptsx.size());
198
199 // Ideally this will be stored in m_geomfactors
200 m_xmap->PhysDeriv(ptsx, DxD1, DxD2);
201 m_xmap->PhysDeriv(ptsy, DyD1, DyD2);
202
203 int cnt = 0;
206
207 F1 = F2 = 2000; // Starting value of Function
208 NekDouble resid = sqrt(F1 * F1 + F2 * F2);
209 while (cnt++ < MaxIterations)
210 {
211 // evaluate lagrange interpolant at Lcoords
212 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
213 I[0] = m_xmap->GetBasis(0)->GetI(eta);
214 I[1] = m_xmap->GetBasis(1)->GetI(eta + 1);
215
216 // calculate the global point `corresponding to Lcoords
217 xmap = m_xmap->PhysEvaluate(I, ptsx);
218 ymap = m_xmap->PhysEvaluate(I, ptsy);
219
220 F1 = coords[0] - xmap;
221 F2 = coords[1] - ymap;
222
223 if (F1 * F1 + F2 * F2 < ScaledTol)
224 {
225 resid = sqrt(F1 * F1 + F2 * F2);
226 break;
227 }
228
229 // Interpolate derivative metric at Lcoords
230 derx_1 = m_xmap->PhysEvaluate(I, DxD1);
231 derx_2 = m_xmap->PhysEvaluate(I, DxD2);
232 dery_1 = m_xmap->PhysEvaluate(I, DyD1);
233 dery_2 = m_xmap->PhysEvaluate(I, DyD2);
234
235 jac = dery_2 * derx_1 - dery_1 * derx_2;
236
237 // use analytical inverse of derivitives which are
238 // also similar to those of metric factors.
239 Lcoords[0] =
240 Lcoords[0] +
241 (dery_2 * (coords[0] - xmap) - derx_2 * (coords[1] - ymap)) / jac;
242
243 Lcoords[1] =
244 Lcoords[1] +
245 (-dery_1 * (coords[0] - xmap) + derx_1 * (coords[1] - ymap)) / jac;
246
247 if (!(std::isfinite(Lcoords[0]) && std::isfinite(Lcoords[1])))
248 {
249 dist = 1e16;
250 std::ostringstream ss;
251 ss << "nan or inf found in NewtonIterationForLocCoord in element "
252 << GetGlobalID();
253 WARNINGL1(false, ss.str());
254 return;
255 }
256 if (fabs(Lcoords[0]) > LcoordDiv || fabs(Lcoords[1]) > LcoordDiv)
257 {
258 break; // lcoords have diverged so stop iteration
259 }
260 }
261
262 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
263 if (ClampLocCoords(eta, 0.))
264 {
265 I[0] = m_xmap->GetBasis(0)->GetI(eta);
266 I[1] = m_xmap->GetBasis(1)->GetI(eta + 1);
267 // calculate the global point corresponding to Lcoords
268 xmap = m_xmap->PhysEvaluate(I, ptsx);
269 ymap = m_xmap->PhysEvaluate(I, ptsy);
270 F1 = coords[0] - xmap;
271 F2 = coords[1] - ymap;
272 dist = sqrt(F1 * F1 + F2 * F2);
273 }
274 else
275 {
276 dist = 0.;
277 }
278
279 if (cnt >= MaxIterations)
280 {
281 Array<OneD, NekDouble> collCoords(2);
282 m_xmap->LocCoordToLocCollapsed(Lcoords, collCoords);
283
284 // if coordinate is inside element dump error!
285 if ((collCoords[0] >= -1.0 && collCoords[0] <= 1.0) &&
286 (collCoords[1] >= -1.0 && collCoords[1] <= 1.0))
287 {
288 std::ostringstream ss;
289
290 ss << "Reached MaxIterations (" << MaxIterations
291 << ") in Newton iteration ";
292 ss << "Init value (" << setprecision(4) << init0 << "," << init1
293 << ","
294 << ") ";
295 ss << "Fin value (" << Lcoords[0] << "," << Lcoords[1] << ","
296 << ") ";
297 ss << "Resid = " << resid << " Tolerance = " << sqrt(ScaledTol);
298
299 WARNINGL1(cnt < MaxIterations, ss.str());
300 }
301 }
302}
303
305 Array<OneD, NekDouble> &Lcoords)
306{
307 NekDouble dist = std::numeric_limits<double>::max();
308 Array<OneD, NekDouble> tmpcoords(2);
309 tmpcoords[0] = coords[m_manifold[0]];
310 tmpcoords[1] = coords[m_manifold[1]];
311 if (GetMetricInfo()->GetGtype() == eRegular)
312 {
313 tmpcoords[0] -= m_isoParameter[0][0];
314 tmpcoords[1] -= m_isoParameter[1][0];
315 Lcoords[0] = m_invIsoParam[0][0] * tmpcoords[0] +
316 m_invIsoParam[0][1] * tmpcoords[1];
317 Lcoords[1] = m_invIsoParam[1][0] * tmpcoords[0] +
318 m_invIsoParam[1][1] * tmpcoords[1];
319 }
320 else if (m_straightEdge)
321 {
322 SolveStraightEdgeQuad(tmpcoords, Lcoords);
323 }
324 else if (GetMetricInfo()->GetGtype() == eDeformed)
325 {
326 v_FillGeom();
327 // Determine nearest point of coords to values in m_xmap
328 int npts = m_xmap->GetTotPoints();
329 Array<OneD, NekDouble> ptsx(npts), ptsy(npts);
330 Array<OneD, NekDouble> tmpx(npts), tmpy(npts);
331
332 // Determine 3D manifold orientation
333 m_xmap->BwdTrans(m_coeffs[m_manifold[0]], ptsx);
334 m_xmap->BwdTrans(m_coeffs[m_manifold[1]], ptsy);
335
336 Array<OneD, NekDouble> eta(2, 0.);
337 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
338 ClampLocCoords(eta, 0.);
339
340 m_xmap->LocCollapsedToLocCoord(eta, Lcoords);
341
342 // Perform newton iteration to find local coordinates
343 NewtonIterationForLocCoord(tmpcoords, ptsx, ptsy, Lcoords, dist);
344 }
345 if (m_coordim == 3)
346 {
347 Array<OneD, NekDouble> eta(2, 0.), xi(2, 0.);
348 m_xmap->LocCoordToLocCollapsed(Lcoords, eta);
349 ClampLocCoords(eta, 0.);
350 m_xmap->LocCollapsedToLocCoord(eta, xi);
351 int npts = m_xmap->GetTotPoints();
352 Array<OneD, NekDouble> ptsz(npts);
353 m_xmap->BwdTrans(m_coeffs[m_manifold[2]], ptsz);
354 NekDouble z = m_xmap->PhysEvaluate(xi, ptsz) - coords[m_manifold[2]];
355 if (GetMetricInfo()->GetGtype() == eDeformed)
356 {
357 dist = sqrt(z * z + dist * dist);
358 }
359 else
360 {
361 dist = fabs(z);
362 }
363 }
364 return dist;
365}
366
368{
369 return m_verts.size();
370}
371
373{
374 return m_edges.size();
375}
376
378{
379 ASSERTL2(i >= 0 && i < m_verts.size(), "Index out of range");
380 return m_verts[i];
381}
382
384{
385 ASSERTL2(i >= 0 && i < m_edges.size(), "Index out of range");
386 return m_edges[i];
387}
388
390{
391 ASSERTL2(i >= 0 && i < m_eorient.size(), "Index out of range");
392 return m_eorient[i];
393}
394
396{
397 return 2;
398}
399
402{
403 if (m_geomFactors->GetGtype() == eRegular)
404 {
405 xiOut = Array<OneD, NekDouble>(2, 0.0);
406
407 GetLocCoords(xs, xiOut);
408 ClampLocCoords(xiOut);
409
410 Array<OneD, NekDouble> gloCoord(3);
411 gloCoord[0] = GetCoord(0, xiOut);
412 gloCoord[1] = GetCoord(1, xiOut);
413 gloCoord[2] = GetCoord(2, xiOut);
414
415 return sqrt((xs[0] - gloCoord[0]) * (xs[0] - gloCoord[0]) +
416 (xs[1] - gloCoord[1]) * (xs[1] - gloCoord[1]) +
417 (xs[2] - gloCoord[2]) * (xs[2] - gloCoord[2]));
418 }
419 // If deformed edge then the inverse mapping is non-linear so need to
420 // numerically solve for the local coordinate
421 else if (m_geomFactors->GetGtype() == eDeformed)
422 {
423 // Choose starting based on closest quad
424 Array<OneD, NekDouble> xi(2, 0.0), eta(2, 0.0);
425 m_xmap->LocCollapsedToLocCoord(eta, xi);
426
427 // Armijo constants:
428 // https://en.wikipedia.org/wiki/Backtracking_line_search
429 const NekDouble c1 = 1e-4, c2 = 0.9;
430
431 int nq = m_xmap->GetTotPoints();
432
433 Array<OneD, NekDouble> x(nq), y(nq), z(nq);
434 m_xmap->BwdTrans(m_coeffs[0], x);
435 m_xmap->BwdTrans(m_coeffs[1], y);
436 m_xmap->BwdTrans(m_coeffs[2], z);
437
438 Array<OneD, NekDouble> xderxi1(nq, 0.0), yderxi1(nq, 0.0),
439 zderxi1(nq, 0.0), xderxi2(nq, 0.0), yderxi2(nq, 0.0),
440 zderxi2(nq, 0.0), xderxi1xi1(nq, 0.0), yderxi1xi1(nq, 0.0),
441 zderxi1xi1(nq, 0.0), xderxi1xi2(nq, 0.0), yderxi1xi2(nq, 0.0),
442 zderxi1xi2(nq, 0.0), xderxi2xi1(nq, 0.0), yderxi2xi1(nq, 0.0),
443 zderxi2xi1(nq, 0.0), xderxi2xi2(nq, 0.0), yderxi2xi2(nq, 0.0),
444 zderxi2xi2(nq, 0.0);
445
446 // Get first & second derivatives & partial derivatives of x,y,z values
447 std::array<NekDouble, 3> xc_derxi, yc_derxi, zc_derxi;
448
449 m_xmap->PhysDeriv(x, xderxi1, xderxi2);
450 m_xmap->PhysDeriv(y, yderxi1, yderxi2);
451 m_xmap->PhysDeriv(z, zderxi1, zderxi2);
452
453 m_xmap->PhysDeriv(xderxi1, xderxi1xi1, xderxi1xi2);
454 m_xmap->PhysDeriv(yderxi1, yderxi1xi1, yderxi1xi2);
455 m_xmap->PhysDeriv(zderxi1, zderxi1xi1, zderxi1xi2);
456
457 m_xmap->PhysDeriv(yderxi2, yderxi2xi1, yderxi2xi2);
458 m_xmap->PhysDeriv(xderxi2, xderxi2xi1, xderxi2xi2);
459 m_xmap->PhysDeriv(zderxi2, zderxi2xi1, zderxi2xi2);
460
461 // Minimisation loop (Quasi-newton method)
462 NekDouble fx_prev = std::numeric_limits<NekDouble>::max();
463 for (int i = 0; i < NekConstants::kNewtonIterations; ++i)
464 {
465 // Compute the objective function, f(x_k) and its derivatives
466 NekDouble xc = m_xmap->PhysEvaluate(xi, x, xc_derxi);
467 NekDouble yc = m_xmap->PhysEvaluate(xi, y, yc_derxi);
468 NekDouble zc = m_xmap->PhysEvaluate(xi, z, zc_derxi);
469
470 NekDouble xc_derxi1xi1 = m_xmap->PhysEvaluate(xi, xderxi1xi1);
471 NekDouble yc_derxi1xi1 = m_xmap->PhysEvaluate(xi, yderxi1xi1);
472 NekDouble zc_derxi1xi1 = m_xmap->PhysEvaluate(xi, zderxi1xi1);
473
474 NekDouble xc_derxi1xi2 = m_xmap->PhysEvaluate(xi, xderxi1xi2);
475 NekDouble yc_derxi1xi2 = m_xmap->PhysEvaluate(xi, yderxi1xi2);
476 NekDouble zc_derxi1xi2 = m_xmap->PhysEvaluate(xi, zderxi1xi2);
477
478 NekDouble xc_derxi2xi2 = m_xmap->PhysEvaluate(xi, xderxi2xi2);
479 NekDouble yc_derxi2xi2 = m_xmap->PhysEvaluate(xi, yderxi2xi2);
480 NekDouble zc_derxi2xi2 = m_xmap->PhysEvaluate(xi, zderxi2xi2);
481
482 // Objective function is the distance to the search point
483 NekDouble xdiff = xc - xs[0];
484 NekDouble ydiff = yc - xs[1];
485 NekDouble zdiff = zc - xs[2];
486
487 NekDouble fx = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
488
489 NekDouble fx_derxi1 = 2.0 * xdiff * xc_derxi[0] +
490 2.0 * ydiff * yc_derxi[0] +
491 2.0 * zdiff * zc_derxi[0];
492
493 NekDouble fx_derxi2 = 2.0 * xdiff * xc_derxi[1] +
494 2.0 * ydiff * yc_derxi[1] +
495 2.0 * zdiff * zc_derxi[1];
496
497 NekDouble fx_derxi1xi1 =
498 2.0 * xdiff * xc_derxi1xi1 + 2.0 * xc_derxi[0] * xc_derxi[0] +
499 2.0 * ydiff * yc_derxi1xi1 + 2.0 * yc_derxi[0] * yc_derxi[0] +
500 2.0 * zdiff * zc_derxi1xi1 + 2.0 * zc_derxi[0] * zc_derxi[0];
501
502 NekDouble fx_derxi1xi2 =
503 2.0 * xdiff * xc_derxi1xi2 + 2.0 * xc_derxi[1] * xc_derxi[0] +
504 2.0 * ydiff * yc_derxi1xi2 + 2.0 * yc_derxi[1] * yc_derxi[0] +
505 2.0 * zdiff * zc_derxi1xi2 + 2.0 * zc_derxi[1] * zc_derxi[0];
506
507 NekDouble fx_derxi2xi2 =
508 2.0 * xdiff * xc_derxi2xi2 + 2.0 * xc_derxi[1] * xc_derxi[1] +
509 2.0 * ydiff * yc_derxi2xi2 + 2.0 * yc_derxi[1] * yc_derxi[1] +
510 2.0 * zdiff * zc_derxi2xi2 + 2.0 * zc_derxi[1] * zc_derxi[1];
511
512 // Jacobian
513 NekDouble jac[2];
514 jac[0] = fx_derxi1;
515 jac[1] = fx_derxi2;
516
517 // Inverse of 2x2 hessian
518 NekDouble hessInv[2][2];
519
520 NekDouble det =
521 1 / (fx_derxi1xi1 * fx_derxi2xi2 - fx_derxi1xi2 * fx_derxi1xi2);
522 hessInv[0][0] = det * fx_derxi2xi2;
523 hessInv[0][1] = det * -fx_derxi1xi2;
524 hessInv[1][0] = det * -fx_derxi1xi2;
525 hessInv[1][1] = det * fx_derxi1xi1;
526
527 // Check for convergence
528 if (abs(fx - fx_prev) < 1e-12)
529 {
530 fx_prev = fx;
531 break;
532 }
533 else
534 {
535 fx_prev = fx;
536 }
537
538 NekDouble gamma = 1.0;
539 bool conv = false;
540
541 // Search direction: Newton's method
542 NekDouble pk[2];
543 pk[0] = -(hessInv[0][0] * jac[0] + hessInv[1][0] * jac[1]);
544 pk[1] = -(hessInv[0][1] * jac[0] + hessInv[1][1] * jac[1]);
545
546 // Backtracking line search
547 while (gamma > 1e-10)
548 {
549 Array<OneD, NekDouble> xi_pk(2);
550 xi_pk[0] = xi[0] + pk[0] * gamma;
551 xi_pk[1] = xi[1] + pk[1] * gamma;
552
553 Array<OneD, NekDouble> eta_pk(2, 0.0);
554 m_xmap->LocCoordToLocCollapsed(xi_pk, eta_pk);
555
556 if (eta_pk[0] <
557 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
558 eta_pk[0] >
559 (1 + std::numeric_limits<NekDouble>::epsilon()) ||
560 eta_pk[1] <
561 (-1 - std::numeric_limits<NekDouble>::epsilon()) ||
562 eta_pk[1] > (1 + std::numeric_limits<NekDouble>::epsilon()))
563 {
564 gamma /= 2.0;
565 continue;
566 }
567
568 std::array<NekDouble, 3> xc_pk_derxi, yc_pk_derxi, zc_pk_derxi;
569
570 NekDouble xc_pk = m_xmap->PhysEvaluate(xi_pk, x, xc_pk_derxi);
571 NekDouble yc_pk = m_xmap->PhysEvaluate(xi_pk, y, yc_pk_derxi);
572 NekDouble zc_pk = m_xmap->PhysEvaluate(xi_pk, z, zc_pk_derxi);
573
574 NekDouble xc_pk_diff = xc_pk - xs[0];
575 NekDouble yc_pk_diff = yc_pk - xs[1];
576 NekDouble zc_pk_diff = zc_pk - xs[2];
577
578 NekDouble fx_pk = xc_pk_diff * xc_pk_diff +
579 yc_pk_diff * yc_pk_diff +
580 zc_pk_diff * zc_pk_diff;
581
582 NekDouble fx_pk_derxi1 = 2.0 * xc_pk_diff * xc_pk_derxi[0] +
583 2.0 * yc_pk_diff * yc_pk_derxi[0] +
584 2.0 * zc_pk_diff * zc_pk_derxi[0];
585
586 NekDouble fx_pk_derxi2 = 2.0 * xc_pk_diff * xc_pk_derxi[1] +
587 2.0 * yc_pk_diff * yc_pk_derxi[1] +
588 2.0 * zc_pk_diff * zc_pk_derxi[1];
589
590 // Check Wolfe conditions using Armijo constants
591 // https://en.wikipedia.org/wiki/Wolfe_conditions
592 NekDouble tmp = pk[0] * fx_derxi1 + pk[1] * fx_derxi2;
593 NekDouble tmp2 = pk[0] * fx_pk_derxi1 + pk[1] * fx_pk_derxi2;
594 if ((fx_pk - (fx + c1 * gamma * tmp)) <
595 std::numeric_limits<NekDouble>::epsilon() &&
596 (-tmp2 - (-c2 * tmp)) <
597 std::numeric_limits<NekDouble>::epsilon())
598 {
599 conv = true;
600 break;
601 }
602
603 gamma /= 2.0;
604 }
605
606 if (!conv)
607 {
608 break;
609 }
610
611 xi[0] += gamma * pk[0];
612 xi[1] += gamma * pk[1];
613 }
614
615 xiOut = xi;
616 return sqrt(fx_prev);
617 }
618 else
619 {
620 ASSERTL0(false, "Geometry type unknown")
621 }
622
623 return -1.0;
624}
625
627{
628 NekDouble Jac = m_isoParameter[0][1] * m_isoParameter[1][2] -
629 m_isoParameter[1][1] * m_isoParameter[0][2];
630 Jac = 1. / Jac;
631 // a12, -a02, -a11, a01
635 m_invIsoParam[0][0] = m_isoParameter[1][2] * Jac;
636 m_invIsoParam[0][1] = -m_isoParameter[0][2] * Jac;
637 m_invIsoParam[1][0] = -m_isoParameter[1][1] * Jac;
638 m_invIsoParam[1][1] = m_isoParameter[0][1] * Jac;
639}
640
641} // namespace Nektar::SpatialDomains
#define WARNINGL1(condition, msg)
Definition: ErrorUtil.hpp:243
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:208
#define ASSERTL2(condition, msg)
Assert Level 2 – Debugging which is used FULLDEBUG compilation mode. This level assert is designed to...
Definition: ErrorUtil.hpp:265
int v_GetShapeDim() const override
Get the object's shape dimension.
Definition: Geometry2D.cpp:395
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)
Definition: Geometry2D.cpp:168
Array< OneD, int > m_manifold
Definition: Geometry2D.h:83
Array< OneD, Array< OneD, NekDouble > > m_edgeNormal
Definition: Geometry2D.h:84
void SolveStraightEdgeQuad(const Array< OneD, const NekDouble > &coords, Array< OneD, NekDouble > &Lcoords)
Definition: Geometry2D.cpp:141
PointGeomSharedPtr v_GetVertex(int i) const override
Definition: Geometry2D.cpp:377
Geometry1DSharedPtr v_GetEdge(int i) const override
Returns edge i of this object.
Definition: Geometry2D.cpp:383
std::vector< StdRegions::Orientation > m_eorient
Definition: Geometry2D.h:81
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...
Definition: Geometry2D.cpp:304
int v_AllLeftCheck(const Array< OneD, const NekDouble > &gloCoord) override
Definition: Geometry2D.cpp:63
void v_CalculateInverseIsoParam() override
Definition: Geometry2D.cpp:626
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.
Definition: Geometry2D.cpp:389
NekDouble v_FindDistance(const Array< OneD, const NekDouble > &xs, Array< OneD, NekDouble > &xi) override
Definition: Geometry2D.cpp:400
int v_GetNumEdges() const override
Get the number of edges of this object.
Definition: Geometry2D.cpp:372
int v_GetNumVerts() const override
Get the number of vertices of this object.
Definition: Geometry2D.cpp:367
Base class for shape geometry information.
Definition: Geometry.h:79
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:555
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:545
virtual void v_FillGeom()
Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements.
Definition: Geometry.cpp:386
Array< OneD, Array< OneD, NekDouble > > m_isoParameter
Definition: Geometry.h:210
Array< OneD, Array< OneD, NekDouble > > m_invIsoParam
Definition: Geometry.h:211
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:561
int GetGlobalID(void) const
Get the ID of this object.
Definition: Geometry.h:327
Array< OneD, Array< OneD, NekDouble > > m_coeffs
Array containing expansion coefficients of m_xmap.
Definition: Geometry.h:207
GeomFactorsSharedPtr GetMetricInfo()
Get the geometric factors for this object.
Definition: Geometry.h:311
StdRegions::StdExpansionSharedPtr m_xmap
mapping containing isoparametric transformation.
Definition: Geometry.h:195
StdRegions::StdExpansionSharedPtr GetXmap() const
Return the mapping object Geometry::m_xmap that represents the coordinate transformation from standar...
Definition: Geometry.h:436
GeomFactorsSharedPtr m_geomFactors
Geometric factors.
Definition: Geometry.h:191
int m_coordim
Coordinate dimension of this geometry object.
Definition: Geometry.h:189
@ beta
Gauss Radau pinned at x=-1,.
Definition: PointsType.h:59
static const unsigned int kNewtonIterations
std::shared_ptr< Curve > CurveSharedPtr
Definition: Curve.hpp:58
@ eRegular
Geometry is straight-sided with constant geometric factors.
@ eDeformed
Geometry is curved or has non-constant factors.
std::shared_ptr< PointGeom > PointGeomSharedPtr
Definition: Geometry.h:57
std::shared_ptr< Geometry1D > Geometry1DSharedPtr
Definition: Geometry.h:61
std::vector< double > z(NPUPPER)
double NekDouble
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
Definition: Vmath.hpp:608
STL namespace.
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298
scalarT< T > sqrt(scalarT< T > in)
Definition: scalar.hpp:294