pub struct Grid { /* private fields */ }Expand description
A validated rectilinear mesh, Cartesian (metres) or cylindrical
(ρ, z in metres, α in radians).
Per-axis arrays such as nodes are indexed by
Axis::index ([x, y, z], or [ρ, α, z]). The grid has n[a] node
lines along axis a (at least 2) and therefore n[a] − 1 cells.
Implementations§
Source§impl Grid
impl Grid
Sourcepub fn new(lines: [Vec<f64>; 3]) -> Result<Self>
pub fn new(lines: [Vec<f64>; 3]) -> Result<Self>
Builds a grid from the node coordinates (metres) of each axis.
Every axis needs at least two lines; the coordinates must be finite
and strictly increasing. The total node count must fit in usize.
Sourcepub fn cylindrical(lines: [Vec<f64>; 3]) -> Result<Self>
pub fn cylindrical(lines: [Vec<f64>; 3]) -> Result<Self>
Builds a cylindrical grid from the lines [ρ, α, z]: ρ and z in
metres, α in radians.
Besides the checks of new, ρ must be non-negative
and the azimuth span α_max − α_min at most 2π. A first ρ line at
0 is the axis (has_axis); an azimuth span of 2π
(to a relative 1e-6) closes the circle
(is_closed): the first and last α lines are
then the same half-plane, and the engine treats the α faces as
periodic.
use ems::engine::Grid;
use std::f64::consts::TAU;
let g = Grid::cylindrical([
vec![0.0, 1e-3, 2e-3],
(0..=8).map(|j| j as f64 * TAU / 8.0).collect(),
vec![0.0, 1e-3],
])?;
assert!(g.has_axis() && g.is_closed());Sourcepub fn coordinates(&self) -> Coordinates
pub fn coordinates(&self) -> Coordinates
The coordinate system.
Sourcepub fn is_cylindrical(&self) -> bool
pub fn is_cylindrical(&self) -> bool
Whether the grid is cylindrical.
Sourcepub fn has_axis(&self) -> bool
pub fn has_axis(&self) -> bool
Whether the grid is cylindrical with its first ρ line at 0 (the
z axis lies on the ρ_min face, see design §5.15).
Sourcepub fn is_closed(&self) -> bool
pub fn is_closed(&self) -> bool
Whether the grid is cylindrical and spans the full circle in α.
Sourcepub fn with_multigrid(self, rings: &[usize]) -> Result<Self>
pub fn with_multigrid(self, rings: &[usize]) -> Result<Self>
Enables azimuthal multigrid on a cylindrical grid (design §5.15.1):
each entry of rings is the index of a ρ line; inside each of
them (cells i < ring) the α resolution is halved once more, so
inside the innermost of L rings only every 2^L-th α line is
kept. The rings may be given in any order; an empty list switches
multigrid off.
§Errors
Error::Invalid if the grid is not cylindrical, a ring index is
repeated or not in 1..=nρ−2 (each zone boundary needs a cell on
both sides), the number of α cells is not a multiple of 2^L, or a
closed grid would keep fewer than 3 α cells in its coarsest zone.
use ems::engine::Grid;
use std::f64::consts::TAU;
let g = Grid::cylindrical([
(0..=8).map(|i| i as f64 * 1e-3).collect(),
(0..=32).map(|j| j as f64 * TAU / 32.0).collect(),
vec![0.0, 1e-3],
])?
.with_multigrid(&[4, 2])?;
assert_eq!(g.alpha_factor(0), 4); // cells 0, 1: every 4th α line
assert_eq!(g.alpha_factor(3), 2); // cells 2, 3: every 2nd
assert_eq!(g.alpha_factor(4), 1);Sourcepub fn multigrid(&self) -> &[usize]
pub fn multigrid(&self) -> &[usize]
The multigrid zone boundaries (ρ line indices, outermost first);
empty without multigrid (see with_multigrid).
Sourcepub fn has_multigrid(&self) -> bool
pub fn has_multigrid(&self) -> bool
Whether azimuthal multigrid is enabled.
Sourcepub fn alpha_factor(&self, i: usize) -> usize
pub fn alpha_factor(&self, i: usize) -> usize
The azimuthal coarsening factor of radial cell i (between ρ_i
and ρ_{i+1}): 1 without multigrid or outside every zone, 2^ℓ
inside ℓ zone boundaries. Indices past the last cell use the last
cell.
Sourcepub fn edge_length(&self, axis: Axis, node: [usize; 3]) -> f64
pub fn edge_length(&self, axis: Axis, node: [usize; 3]) -> f64
Physical length [m] of the primary edge along axis starting at
node: delta, or ρ_i·Δα_j for an α edge of a
cylindrical grid (0 on the axis).
Sourcepub fn dual_edge_length(&self, axis: Axis, node: [usize; 3]) -> f64
pub fn dual_edge_length(&self, axis: Axis, node: [usize; 3]) -> f64
Physical length [m] of the (in-domain part of the) dual edge along
axis through node: dual_delta, or
ρ_{i+½}·Δα*_j for an α dual edge of a cylindrical grid.
Sourcepub fn dual_face_area(&self, axis: Axis, node: [usize; 3]) -> f64
pub fn dual_face_area(&self, axis: Axis, node: [usize; 3]) -> f64
Area [m²] of the (in-domain part of the) dual face pierced by the
primary edge along axis starting at node: the product of the two
transverse dual_deltas in Cartesian
coordinates; in cylindrical coordinates ρ_{i+½}·Δα*·Δz* (ρ edge),
Δρ*·Δz* (α edge) and the annular sector Δα*·(ρ_hi² − ρ_lo²)/2
(z edge, ρ_lo, ρ_hi the dual lines around node i, clamped to
the domain).
Sourcepub fn face_area(&self, axis: Axis, node: [usize; 3]) -> f64
pub fn face_area(&self, axis: Axis, node: [usize; 3]) -> f64
Area [m²] of the primary face normal to axis whose lowest corner
is node: the product of the two transverse
deltas in Cartesian coordinates; in cylindrical
coordinates ρ_i·Δα·Δz (ρ face, 0 on the axis), Δρ·Δz (α face)
and the annular sector Δα·(ρ_{i+1}² − ρ_i²)/2 (z face).
Sourcepub fn uniform(cells: [usize; 3], cell_size: [f64; 3]) -> Result<Self>
pub fn uniform(cells: [usize; 3], cell_size: [f64; 3]) -> Result<Self>
Uniform grid with cells[a] cells of size cell_size[a] (metres)
along each axis, starting at the origin.
Sourcepub fn num_nodes(&self) -> usize
pub fn num_nodes(&self) -> usize
Total number of nodes nx·ny·nz (the length of every field array).
Sourcepub fn index(&self, [i, j, k]: [usize; 3]) -> usize
pub fn index(&self, [i, j, k]: [usize; 3]) -> usize
Linear node index (i·ny + j)·nz + k (z contiguous).
Sourcepub fn delta(&self, axis: Axis, i: usize) -> f64
pub fn delta(&self, axis: Axis, i: usize) -> f64
Primary edge length Δ_a(i) = line[i+1] − line[i] along axis,
for i < n[axis] − 1 (also the size of cell i along that axis).
Sourcepub fn deltas(&self, axis: Axis) -> Vec<f64>
pub fn deltas(&self, axis: Axis) -> Vec<f64>
All primary edge lengths of axis (n[axis] − 1 values).
Sourcepub fn dual_line(&self, axis: Axis, i: usize) -> f64
pub fn dual_line(&self, axis: Axis, i: usize) -> f64
Dual node position along axis: midpoint of cell i
(i < n[axis] − 1).
Sourcepub fn dual_lines(&self, axis: Axis) -> Vec<f64>
pub fn dual_lines(&self, axis: Axis) -> Vec<f64>
All dual node positions of axis (n[axis] − 1 values).
Sourcepub fn dual_delta(&self, axis: Axis, i: usize) -> f64
pub fn dual_delta(&self, axis: Axis, i: usize) -> f64
Dual edge length through primary node i along axis: from the
midpoint of cell i − 1 to the midpoint of cell i, i.e.
(Δ(i−1) + Δ(i)) / 2. At the outer nodes (i = 0, i = n − 1) the
dual cell is a half cell and the length is Δ/2 of the single
adjacent cell.
Sourcepub fn min_deltas(&self) -> [f64; 3]
pub fn min_deltas(&self) -> [f64; 3]
Smallest cell size per axis.