include/pops/mesh/geometry/geometry.hpp Source FileΒΆ

adc_cpp: include/pops/mesh/geometry/geometry.hpp Source File
adc_cpp 0.3.0
Model-free C++23 core for coupled hyperbolic-elliptic systems on adaptive (AMR) meshes, with MPI and GPU (Kokkos) backends
geometry.hpp
Go to the documentation of this file.
1
10
11#pragma once
12
15
16namespace pops {
17
20struct Geometry {
22 Real xlo = 0, xhi = 1, ylo = 0, yhi = 1;
23
24 // POPS_HD accessors: pure arithmetic, capturable by value and callable FROM A device KERNEL.
25 // Without POPS_HD, geom.x_cell(i) inside a Kokkos::Cuda kernel is a __host__ call from
26 // __device__: nvcc returns a GARBAGE value (often 0) on device, WITHOUT a compile or
27 // runtime error. An init kernel that sets x = geom.x_cell(i) then sees x = 0 on GPU (sin(pi*0) = 0)
28 // -> field silently zero (defect observed on test_condensed_schur). Geometry is a trivial
29 // POD: the annotation is free and keeps the host path bit-identical.
31 POPS_HD Real dx() const { return (xhi - xlo) / domain.nx(); }
33 POPS_HD Real dy() const { return (yhi - ylo) / domain.ny(); }
35 POPS_HD Real x_cell(int i) const { return xlo + (i + Real(0.5)) * dx(); }
37 POPS_HD Real y_cell(int j) const { return ylo + (j + Real(0.5)) * dy(); }
38
40 Geometry refine(int r) const { return Geometry{domain.refine(r), xlo, xhi, ylo, yhi}; }
41};
42
43// PolarGeometry: SIBLING of Geometry for a GLOBAL ANNULAR domain (r, theta).
44// "Annular polar grid" effort, Phase 1 (TRANSPORT only, opt-in via pops.PolarMesh).
45// The Phase-0 proto (test_polar_ring_advection) quantified that the Cartesian grid diffuses
46// the RADIAL gradient of a ring in azimuthal rotation (~18%/5 turns) where the polar grid
47// preserves it (ratio 73): carrying the radial direction onto a grid AXIS lifts this lock.
48//
49// AXIS CONVENTION (fixed):
50// - index direction 0 = RADIAL (i runs over r, from r_min to r_max)
51// - index direction 1 = AZIMUTHAL (j runs over theta, from 0 to 2pi)
52// The domain is r in [r_min, r_max] (PHYSICAL BC at r_min/r_max) x theta in [0, 2pi)
53// (PERIODIC in theta). This is a global ring, NOT a local Cartesian<->polar patch
54// (the hybrid interface + interpolation + boundary conservation = Phase 2, out of scope here).
55//
56// The cell size (dr, dtheta) is uniform in INDEX; the PHYSICAL cell size in theta is r*dtheta
57// and thus grows with r (hence the 1/r metric of the divergence: cf. assemble_rhs_polar). The
58// centers and faces are defined for every index (ghosts included, i negative or >= nr).
61 Real r_min = 0, r_max = 1;
62 // theta covers [0, 2pi) (periodic): we store no bounds, dtheta = 2pi/ntheta.
63
64 // Local pi (no global pops::kPi constant: it would collide with the local kPi from
65 // 'using namespace pops;' in several tests). Constexpr -> no overhead.
66 static constexpr Real kTwoPi = Real(2) * Real(3.14159265358979323846);
67
68 // POPS_HD accessors (same pattern as Geometry): device-callable from a kernel without returning
69 // garbage under nvcc. Pure arithmetic, host bit-identical.
70 POPS_HD Real dr() const { return (r_max - r_min) / domain.nx(); }
71 POPS_HD Real dtheta() const { return kTwoPi / domain.ny(); }
73 POPS_HD Real r_cell(int i) const { return r_min + (i + Real(0.5)) * dr(); }
75 POPS_HD Real r_face(int i) const { return r_min + i * dr(); }
77 POPS_HD Real theta_cell(int j) const { return (j + Real(0.5)) * dtheta(); }
79 POPS_HD Real theta_face(int j) const { return j * dtheta(); }
80
81 // Same annular physical extent, refined index domain (counterpart of Geometry::refine).
82 PolarGeometry refine(int r) const { return PolarGeometry{domain.refine(r), r_min, r_max}; }
83};
84
85} // namespace pops
Box2D: the integer index space of a 2D cell-centered Cartesian grid.
Definition amr_hierarchy.hpp:29
double Real
Definition types.hpp:30
2D integer index space, cell-centered.
Definition box2d.hpp:37
POPS_HD int nx() const
Width (direction 0). POPS_HD (called from Geometry::dx() in a device kernel).
Definition box2d.hpp:50
POPS_HD int ny() const
Height (direction 1). POPS_HD (called from Geometry::dy() in a device kernel).
Definition box2d.hpp:52
Box2D refine(int r) const
Refines by a ratio r: each cell becomes an r x r block ([lo, hi] -> [lo*r, hi*r + r-1]).
Definition box2d.hpp:86
Cartesian geometry of a level: index domain + physical bounds [xlo, xhi] x [ylo, yhi].
Definition geometry.hpp:20
Real xhi
Definition geometry.hpp:22
POPS_HD Real x_cell(int i) const
Abscissa at the CENTER of cell index i (i = 0 -> xlo + dx/2; defined for negative i)....
Definition geometry.hpp:35
POPS_HD Real dy() const
Grid spacing in y (= (yhi - ylo) / domain.ny()). POPS_HD.
Definition geometry.hpp:33
POPS_HD Real dx() const
Grid spacing in x (= (xhi - xlo) / domain.nx()). POPS_HD.
Definition geometry.hpp:31
Real yhi
Definition geometry.hpp:22
Geometry refine(int r) const
Geometry refined by ratio r: SAME physical extent, refined index domain (dx -> dx/r).
Definition geometry.hpp:40
POPS_HD Real y_cell(int j) const
Ordinate at the CENTER of cell index j. POPS_HD.
Definition geometry.hpp:37
Real xlo
Definition geometry.hpp:22
Real ylo
Definition geometry.hpp:22
Box2D domain
Definition geometry.hpp:21
Definition geometry.hpp:59
PolarGeometry refine(int r) const
Definition geometry.hpp:82
POPS_HD Real theta_face(int j) const
Angle at azimuthal FACE j (face between cells j-1 and j).
Definition geometry.hpp:79
static constexpr Real kTwoPi
Definition geometry.hpp:66
POPS_HD Real r_face(int i) const
Radius at radial FACE i (face between cells i-1 and i; i = 0 -> r_min, i = nr -> r_max).
Definition geometry.hpp:75
POPS_HD Real r_cell(int i) const
Radius at the CENTER of radial cell i (i = 0 -> r_min + dr/2).
Definition geometry.hpp:73
POPS_HD Real dr() const
Definition geometry.hpp:70
Real r_min
Definition geometry.hpp:61
Box2D domain
nx() = nr (radial cells), ny() = ntheta (azimuthal cells)
Definition geometry.hpp:60
POPS_HD Real theta_cell(int j) const
Angle at the CENTER of azimuthal cell j (j = 0 -> dtheta/2).
Definition geometry.hpp:77
Real r_max
physical radial bounds of the ring
Definition geometry.hpp:61
POPS_HD Real dtheta() const
Definition geometry.hpp:71
Base scalar types and the POPS_HD macro (host+device portability).
#define POPS_HD
Definition types.hpp:25