Nektar++
Loading...
Searching...
No Matches
SegGeom.cpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: SegGeom.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:
32//
33//
34////////////////////////////////////////////////////////////////////////////////
35
39
40#include <LibUtilities/Foundations/ManagerAccess.h> // for PointsManager, etc
43
44namespace Nektar
45{
46// Forward declarations for allocation pools that are defined within
47// MeshGraph.cpp compilation unit.
48template <>
49PoolAllocator<SpatialDomains::PointGeom>
51template <>
54} // namespace Nektar
55
57{
58
68
69SegGeom::SegGeom(int id, int coordim, std::array<PointGeom *, kNverts> vertex,
70 const CurveSharedPtr curve)
71 : Geometry1D(coordim)
72{
74 m_globalID = id;
76 m_curve = curve;
77 m_verts = vertex;
78}
79
81{
82 // From Geometry class
84
85 // info from EdgeComponent class
87 m_xmap = in.m_xmap;
88 SetUpCoeffs(m_xmap->GetNcoeffs());
89
90 // info from SegGeom class
92 m_verts[0] = in.m_verts[0];
93 m_verts[1] = in.m_verts[1];
94
95 m_state = in.m_state;
96}
97
116
117/**
118 * \brief Generate a one dimensional space segment geometry where the vert[0]
119 * has the same x value and vert[1] is set to vert[0] plus the length of the
120 * original segment
121 **/
123{
125
126 // info about numbering
127 returnval->m_globalID = m_globalID;
128
129 // geometric information.
130 returnval->m_coordim = 1;
131 NekDouble x0 = (*m_verts[0])[0];
133 1, m_verts[0]->GetGlobalID(), x0, 0.0, 0.0);
134 vert0->SetGlobalID(vert0->GetGlobalID());
135 returnval->m_verts[0] = vert0.get();
136 holder.m_pointVec.push_back(std::move(vert0));
137
138 // Get information to calculate length.
140 m_xmap->GetBase();
142 v.push_back(base[0]->GetPointsKey());
144
145 const Array<OneD, const NekDouble> jac = m_geomFactors->GetJac(v);
146
147 NekDouble len = 0.0;
148 if (jac.size() == 1)
149 {
150 len = jac[0] * 2.0;
151 }
152 else
153 {
154 Array<OneD, const NekDouble> w0 = base[0]->GetW();
155 len = 0.0;
156
157 for (int i = 0; i < jac.size(); ++i)
158 {
159 len += jac[i] * w0[i];
160 }
161 }
162 // Set up second vertex.
164 1, m_verts[1]->GetGlobalID(), x0 + len, 0.0, 0.0);
165 vert1->SetGlobalID(vert1->GetGlobalID());
166
167 returnval->m_verts[1] = vert1.get();
168 holder.m_pointVec.push_back(std::move(vert1));
169
170 // at present just use previous m_xmap[0];
171 returnval->m_xmap = m_xmap;
172 returnval->SetUpCoeffs(m_xmap->GetNcoeffs());
173 returnval->m_state = eNotFilled;
174
175 return returnval;
176}
177
182
184 const Array<OneD, const NekDouble> &Lcoord)
185{
186 ASSERTL1(m_state == ePtsFilled, "Geometry is not in physical space");
187
188 Array<OneD, NekDouble> tmp(m_xmap->GetTotPoints());
189 m_xmap->BwdTrans(m_coeffs[i], tmp);
190
191 return m_xmap->PhysEvaluate(Lcoord, tmp);
192}
193
194/**
195 * @brief Get the orientation of @p edge1.
196 *
197 * If @p edge1 is connected to @p edge2 in the same direction as the points
198 * comprising @p edge1 then it is forward, otherwise it is backward.
199 *
200 * For example, assume @p edge1 is comprised of points 1 and 2, and @p edge2 is
201 * comprised of points 2 and 3, then @p edge1 is forward.
202 *
203 * If @p edge1 is comprised of points 2 and 1 and @p edge2 is comprised of
204 * points 3 and 2, then @p edge1 is backward.
205 *
206 * Since both edges are passed, it does not need any information from the
207 * EdgeComponent instance.
208 */
210 const SegGeom &edge2)
211{
213
214 if ((*edge1.GetVertex(0) == *edge2.GetVertex(0)) ||
215 (*edge1.GetVertex(0) == *edge2.GetVertex(1)))
216 {
217 // Backward direction. Vertex 0 is connected to edge 2.
218 returnval = StdRegions::eBackwards;
219 }
220 else if ((*edge1.GetVertex(1) != *edge2.GetVertex(0)) &&
221 (*edge1.GetVertex(1) != *edge2.GetVertex(1)))
222 {
223 // Not forward either, then we have a problem.
224 std::ostringstream errstrm;
225 errstrm << "Connected edges do not share a vertex. Edges ";
226 errstrm << edge1.GetGlobalID() << ", " << edge2.GetGlobalID();
227 ASSERTL0(false, errstrm.str());
228 }
229
230 return returnval;
231}
232
234{
235 if (!m_setupState)
236 {
238 }
239
241 {
244
245 if (m_xmap->GetBasisNumModes(0) != 2)
246 {
247 gType = eDeformed;
248 }
249
251 gType, m_coordim, m_xmap, m_coeffs);
253 }
254}
255
257{
258 if (m_state != ePtsFilled)
259 {
260 int i;
261
262 if (m_coordim > 0 && m_curve)
263 {
264 int npts = m_curve->m_points.size();
265 LibUtilities::PointsKey pkey(npts + 1,
267 Array<OneD, NekDouble> tmp(npts);
268
269 if (m_verts[0]->dist(*(m_curve->m_points[0])) >
271 {
272 std::string err =
273 "Vertex 0 is separated from first point by more than ";
274 std::stringstream strstrm;
275 strstrm << NekConstants::kVertexTheSameDouble << " in edge "
276 << m_globalID;
277 err += strstrm.str();
278 NEKERROR(ErrorUtil::ewarning, err.c_str());
279 }
280
281 if (m_verts[1]->dist(*(m_curve->m_points[npts - 1])) >
283 {
284 std::string err =
285 "Vertex 1 is separated from last point by more than ";
286 std::stringstream strstrm;
287 strstrm << NekConstants::kVertexTheSameDouble << " in edge "
288 << m_globalID;
289 err += strstrm.str();
290 NEKERROR(ErrorUtil::ewarning, err.c_str());
291 }
292
293 LibUtilities::PointsKey fkey(npts, m_curve->m_ptype);
295 LibUtilities::PointsManager()[fkey]->GetI(pkey);
296 NekVector<NekDouble> out(npts + 1);
297
298 for (int i = 0; i < m_coordim; ++i)
299 {
300 // Load up coordinate values into tmp
301 for (int j = 0; j < npts; ++j)
302 {
303 tmp[j] = (m_curve->m_points[j]->GetPtr())[i];
304 }
305
306 // Interpolate to GLL points
307 NekVector<NekDouble> in(npts, tmp, eWrapper);
308 out = (*I0) * in;
309
310 m_xmap->FwdTrans(out.GetPtr(), m_coeffs[i]);
311 }
312 }
313
314 for (i = 0; i < m_coordim; ++i)
315 {
316 m_coeffs[i][0] = (*m_verts[0])[i];
317 m_coeffs[i][1] = (*m_verts[1])[i];
318 }
319
321 }
322}
323
324void SegGeom::v_Reset(CurveMap &curvedEdges, CurveMap &curvedFaces)
325{
326 Geometry::v_Reset(curvedEdges, curvedFaces);
327 CurveMap::iterator it = curvedEdges.find(m_globalID);
328
329 if (it != curvedEdges.end())
330 {
331 m_curve = it->second;
332 }
333
334 SetUpXmap();
335 SetUpCoeffs(m_xmap->GetNcoeffs());
336}
337
339{
340 if (!m_setupState)
341 {
342 SetUpXmap();
343 SetUpCoeffs(m_xmap->GetNcoeffs());
344 m_setupState = true;
345 }
346}
347
349{
350 PointGeom *returnval = nullptr;
351
352 if (i >= 0 && i < kNverts)
353 {
354 returnval = m_verts[i];
355 }
356
357 return returnval;
358}
359
361{
362 return kNverts;
363}
364
367{
368 if (m_geomFactors->GetGtype() == eRegular)
369 {
370 xiOut = Array<OneD, NekDouble>(1, 0.0);
371
372 GetLocCoords(xs, xiOut);
373 ClampLocCoords(xiOut);
374
376 NekDouble tmp = 0;
377 for (int i = 0; i < m_coordim; ++i)
378 {
379 gloCoord[i] = GetCoord(i, xiOut);
380 tmp += (xs[i] - gloCoord[i]) * (xs[i] - gloCoord[i]);
381 }
382
383 return sqrt(tmp);
384 }
385 // If deformed edge then the inverse mapping is non-linear so need to
386 // numerically solve for the local coordinate
387 else if (m_geomFactors->GetGtype() == eDeformed)
388 {
389 Array<OneD, NekDouble> xi(1, 0.0);
390
391 // Armijo constants:
392 // https://en.wikipedia.org/wiki/Backtracking_line_search
393 const NekDouble c1 = 1e-4, c2 = 0.9;
394
395 int dim = GetCoordim();
396 int nq = m_xmap->GetTotPoints();
397
398 Array<OneD, Array<OneD, NekDouble>> x(dim), xder(dim), xder2(dim);
399 // Get x,y,z phys values from coefficients
400 for (int i = 0; i < dim; ++i)
401 {
402 x[i] = Array<OneD, NekDouble>(nq);
403 xder[i] = Array<OneD, NekDouble>(nq);
404 xder2[i] = Array<OneD, NekDouble>(nq);
405
406 m_xmap->BwdTrans(m_coeffs[i], x[i]);
407 }
408
409 NekDouble fx_prev = std::numeric_limits<NekDouble>::max();
410
411 // Minimisation loop (Quasi-newton method)
412 for (int i = 0; i < NekConstants::kNewtonIterations; ++i)
413 {
414 // Compute the objective function, f(x_k) and its derivatives
418 NekDouble fx = 0, fxp = 0, fxp2 = 0, xcDiff = 0;
419 for (int j = 0; j < dim; ++j)
420 {
421 xc[j] = m_xmap->PhysEvaluate(xi, x[j], xc_der[j], xc_der2[j]);
422
423 xcDiff = xc[j] - xs[j];
424 // Objective function is the distance to the search point
425 fx += xcDiff * xcDiff;
426 fxp += xc_der[j][0] * xcDiff;
427 fxp2 += xc_der2[j][0] * xcDiff + xc_der[j][0] * xc_der[j][0];
428 }
429
430 fxp *= 2;
431 fxp2 *= 2;
432
433 // Check for convergence
434 if (std::abs(fx - fx_prev) < 1e-12)
435 {
436 fx_prev = fx;
437 break;
438 }
439 else
440 {
441 fx_prev = fx;
442 }
443
444 NekDouble gamma = 1.0;
445 bool conv = false;
446
447 // Search direction: Newton's method
448 NekDouble pk = -fxp / fxp2;
449
450 // Perform backtracking line search
451 while (gamma > 1e-10)
452 {
453 Array<OneD, NekDouble> xi_pk(1);
454 xi_pk[0] = xi[0] + pk * gamma;
455
456 if (xi_pk[0] < -1.0 || xi_pk[0] > 1.0)
457 {
458 gamma /= 2.0;
459 continue;
460 }
461
462 Array<OneD, NekDouble> xc_pk(dim);
464 NekDouble fx_pk = 0, fxp_pk = 0, xc_pkDiff = 0;
465 for (int j = 0; j < dim; ++j)
466 {
467 xc_pk[j] = m_xmap->PhysEvaluate(xi_pk, x[j], xc_der_pk[j]);
468
469 xc_pkDiff = xc_pk[j] - xs[j];
470 fx_pk += xc_pkDiff * xc_pkDiff;
471 fxp_pk += xc_der_pk[j][0] * xc_pkDiff;
472 }
473
474 fxp_pk *= 2;
475
476 // Check Wolfe conditions using Armijo constants
477 // https://en.wikipedia.org/wiki/Wolfe_conditions
478 if ((fx_pk - (fx + c1 * gamma * pk * fxp)) <
479 std::numeric_limits<NekDouble>::epsilon() &&
480 (-pk * fxp_pk + c2 * pk * fxp) <
481 std::numeric_limits<NekDouble>::epsilon())
482 {
483 conv = true;
484 break;
485 }
486
487 gamma /= 2.0;
488 }
489
490 if (!conv)
491 {
492 break;
493 }
494
495 xi[0] += gamma * pk;
496 }
497
498 xiOut = xi;
499 return sqrt(fx_prev);
500 }
501 else
502 {
503 ASSERTL0(false, "Geometry type unknown")
504 }
505
506 return -1.0;
507}
508
509} // namespace Nektar::SpatialDomains
#define ASSERTL0(condition, msg)
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Describes the specification for a Basis.
Definition Basis.h:45
Defines a specification for a set of points.
Definition Points.h:50
static std::shared_ptr< DataType > AllocateSharedPtr(const Args &...args)
Allocate a shared pointer from the memory pool.
Array< OneD, DataType > & GetPtr()
Generic object pool allocator/deallocator.
static std::unique_ptr< DataType, UniquePtrDeleter > AllocateUniquePtr(const Args &...args)
std::vector< PointGeomUniquePtr > m_pointVec
Definition SegGeom.h:55
1D geometry information
Definition Geometry1D.h:49
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:558
bool m_setupState
Wether or not the setup routines have been run.
Definition Geometry.h:193
GeomState m_state
Enumeration to dictate whether coefficients are filled.
Definition Geometry.h:191
void SetUpCoeffs(const int nCoeffs)
Initialise the Geometry::m_coeffs array.
Definition Geometry.h:704
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:548
virtual void v_Reset(CurveMap &curvedEdges, CurveMap &curvedFaces)
Reset this geometry object: unset the current state, zero Geometry::m_coeffs and remove allocated Geo...
Definition Geometry.cpp:372
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:536
int GetGlobalID(void) const
Get the ID of this object.
Definition Geometry.h:322
PointGeom * GetVertex(int i) const
Returns vertex i of this object.
Definition Geometry.h:361
int GetCoordim() const
Return the coordinate dimension of this object (i.e. the dimension of the space in which this object ...
Definition Geometry.h:279
LibUtilities::ShapeType m_shapeType
Type of shape.
Definition Geometry.h:197
Array< OneD, Array< OneD, NekDouble > > m_coeffs
Array containing expansion coefficients of m_xmap.
Definition Geometry.h:201
GeomState m_geomFactorsState
State of the geometric factors.
Definition Geometry.h:187
StdRegions::StdExpansionSharedPtr m_xmap
mapping containing isoparametric transformation.
Definition Geometry.h:189
GeomFactorsSharedPtr m_geomFactors
Geometric factors.
Definition Geometry.h:185
int m_coordim
Coordinate dimension of this geometry object.
Definition Geometry.h:183
PointGeom * v_GetVertex(const int i) const override
Returns vertex i of this object.
Definition SegGeom.cpp:348
std::array< SpatialDomains::PointGeom *, kNverts > m_verts
Definition SegGeom.h:86
int v_GetNumVerts() const override
Get the number of vertices of this object.
Definition SegGeom.cpp:360
virtual LibUtilities::ShapeType v_GetShapeType() const
Definition SegGeom.cpp:178
void v_FillGeom() override
Populate the coordinate mapping Geometry::m_coeffs information from any children geometry elements.
Definition SegGeom.cpp:256
CurveSharedPtr m_curve
Boolean indicating whether object owns the data.
Definition SegGeom.h:103
void v_GenGeomFactors() override
Definition SegGeom.cpp:233
static StdRegions::Orientation GetEdgeOrientation(const SegGeom &edge1, const SegGeom &edge2)
Get the orientation of edge1.
Definition SegGeom.cpp:209
NekDouble v_FindDistance(const Array< OneD, const NekDouble > &xs, Array< OneD, NekDouble > &xi) override
Definition SegGeom.cpp:365
static const int kNverts
Definition SegGeom.h:62
NekDouble v_GetCoord(const int i, const Array< OneD, const NekDouble > &Lcoord) override
Given local collapsed coordinate Lcoord, return the value of physical coordinate in direction i.
Definition SegGeom.cpp:183
SegGeomUniquePtr GenerateOneSpaceDimGeom(EntityHolder1D &holder)
Generate a one dimensional space segment geometry where the vert[0] has the same x value and vert[1] ...
Definition SegGeom.cpp:122
void v_Reset(CurveMap &curvedEdges, CurveMap &curvedFaces) override
Reset this geometry object: unset the current state, zero Geometry::m_coeffs and remove allocated Geo...
Definition SegGeom.cpp:324
A simple factory for Xmap objects that is based on the element type, the basis and quadrature selecti...
PointsManagerT & PointsManager(void)
std::vector< PointsKey > PointsKeyVector
Definition Points.h:231
@ eGaussLobattoLegendre
1D Gauss-Lobatto-Legendre quadrature points
Definition PointsType.h:51
@ eModified_A
Principle Modified Functions .
Definition BasisType.h:48
static const NekDouble kVertexTheSameDouble
static const unsigned int kNewtonIterations
XmapFactory< StdRegions::StdSegExp, 1 > & GetStdSegFactory()
Definition SegGeom.cpp:59
std::shared_ptr< Curve > CurveSharedPtr
Definition Curve.hpp:60
std::unordered_map< int, CurveSharedPtr > CurveMap
Definition Curve.hpp:61
GeomType
Indicates the type of element geometry.
@ eRegular
Geometry is straight-sided with constant geometric factors.
@ eDeformed
Geometry is curved or has non-constant factors.
@ eNotFilled
Geometric information has not been generated.
@ ePtsFilled
Geometric information has been generated.
unique_ptr_objpool< SegGeom > SegGeomUniquePtr
Definition MeshGraph.h:98
unique_ptr_objpool< PointGeom > PointGeomUniquePtr
Definition MeshGraph.h:93
boost::fast_pool_allocator< DataType, boost::default_user_allocator_new_delete, boost::details::pool::null_mutex > PoolAllocator
std::shared_ptr< DNekMat > DNekMatSharedPtr
scalarT< T > sqrt(scalarT< T > in)
Definition scalar.hpp:290