A point-cloud container with type-bound procedures to (1) locate each
physical point inside a SEMQuad/SEMHex element-of-elements and recover its
reference (computational) coordinates via a Newton inverse-map, and (2)
sample MappedScalar2D / MappedScalar3D fields at the located points.
The point-location uses a uniform-grid spatial hash built from per-element
axis-aligned bounding boxes of the discrete control-grid (geometry%x). For
each candidate element, a Newton iteration on
is driven to convergence using the high-order Jacobian dX/dxi (interpolated
covariant-basis tensor dxds). Points that fall outside every element this
rank owns are marked with the sentinel elements(p) = 0 and their evaluated
field values are returned as zero.
Nodes of different colours represent the following:
Solid arrows point from a submodule to the (sub)module which it is
descended from. Dashed arrows point from a module or program unit to
modules which it uses. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Nodes of different colours represent the following:
Solid arrows point from a submodule to the (sub)module which it is
descended from. Dashed arrows point from a module or program unit to
modules which it uses. Where possible, edges connecting nodes are given different colours to make them easier to distinguish in large graphs.
Reference coordinates (s,t[,u]) in [-1,1]^nDim, shape (1:nPoints, 1:nDim).
Defined only where elements(p) > 0.
integer,
public,
pointer
::
elements(:)
=>
null()
Element id (rank-local) containing each point; 0 = not found.
real(kind=prec),
public,
pointer
::
lS_cache(:,:)
=>
null()
Lagrange basis at coordinates(p,1), shape (0:nCached, 1:nPoints).
Filled by LocatePoints for points with elements(p) > 0.
real(kind=prec),
public,
pointer
::
lT_cache(:,:)
=>
null()
Lagrange basis at coordinates(p,2), shape (0:nCached, 1:nPoints).
real(kind=prec),
public,
pointer
::
lU_cache(:,:)
=>
null()
Lagrange basis at coordinates(p,3), shape (0:nCached, 1:nPoints).
Allocated only for nDim = 3.
integer,
public
::
nCached
=
0
Polynomial degree at which the per-point Lagrange basis cache is
valid. Zero means no cache. The cache is filled by LocatePoints and
consumed by EvaluateScalar when the field's interpolant degree
matches.
integer,
public
::
nDim
=
0
integer,
public
::
nPoints
=
0
real(kind=prec),
public,
allocatable
::
x(:,:)
Physical coordinates, shape (1:nPoints, 1:nDim). User input.
Type-Bound Procedures
generic, public :: DiracDelta => DiracDelta_2D_Points_t, DiracDelta_3D_Points_t
Axis-aligned bounding box of each element. The box is taken over the
element's boundary nodes (geometry%x%boundary), which are evaluated at
the element edges (reference coordinate = +/-1) and therefore reach the
true element boundary and corners. Using the interior nodes alone is not
sufficient: for Gauss quadrature the interior nodes are strictly inside
[-1,1], so a box built from them under-covers the element by a fixed
fraction of its size and rejects points lying on element edges/corners.
The boundary nodes give the correct extent for both Gauss and
Gauss-Lobatto node sets.
Axis-aligned bounding box of each element, taken over the boundary nodes
(geometry%x%boundary) which are evaluated on the element faces (reference
coordinate = +/-1) and so reach the true element boundary, edges and
corners. See BuildElementBBoxes_2D for why the interior nodes alone are
insufficient (Gauss interior nodes under-cover the element).
Scatter a discrete Dirac delta of unit strength (S = 1) onto a 2D
MappedScalar, one variable per stored point. Variable p of scalar
receives the delta associated with point p.
Scatter a discrete Dirac delta of unit strength (S = 1) onto a 3D
MappedScalar, one variable per stored point. See DiracDelta_2D_Points_t
for the full specification; this is the direct 3D analogue.
Evaluate a 2D MappedScalar at all located points by tensor-product
Lagrange interpolation at the stored reference coordinates. Points with
elements(p) == 0 receive a value of zero. When LocatePoints has cached
the per-point basis at the matching polynomial degree, this routine
reuses it and skips Lagrange-polynomial evaluation altogether.
Evaluate a 3D MappedScalar at all located points by tensor-product
Lagrange interpolation. Points with elements(p) == 0 receive zero.
When LocatePoints has cached the basis at the matching degree, this
routine reuses it.
Locate each stored physical point inside the 2D SEMQuad geometry. On
exit, elements(p) holds the (rank-local) element id and coordinates(p,:)
holds the (s,t) reference coordinates, both for points that resolve.
Points that resolve to no element are marked with elements(p) = 0.
Locate each stored physical point inside the 3D SEMHex geometry. On
exit, elements(p) and coordinates(p,1:3) hold the located element id
and reference (s,t,u) for points that resolve; elements(p) = 0
otherwise.
public subroutine NewtonInverse_2D(geometry, iEl, N, xTarget, xi, converged)
Newton inverse-map for the 2D SEM element iEl: solve X(xi) = xTarget for
the reference coordinate xi in R^2, where X is the high-order
interpolant. The Jacobian dX/dxi is taken from geometry%dxds (the
covariant basis tensor), interpolated to xi via Lagrange basis.