Kinetic grid and momentum regions

src/grids/kinetic.jl

Public

Runes2P.KineticGrid — Type
KineticGrid{T}

Phase-space grid (p, ξ, r) with a momentum grid per radius, and the phase-space Jacobian 𝒱' (DREAM Vp) at cell centres and at the faces in each direction.

Callers use the accessors, not the fields: momentum_grid, phase_space_jacobian and its face variants, the cell counts, and has_shared_momentum_grid. When all radii have the same cell counts (has_same_cell_counts), a distribution can be stored as a 3D array f[i, j, ir] with p fastest, and size(grid) and the cell counts without a radius argument are available. momentum_grid(grid) needs one momentum grid shared by all radii. They throw an ArgumentError otherwise.

A radial face lies between two radii, whose pitch grids may differ. Its pitch cells are the overlap cells of the two grids (radial_face_overlap, PitchOverlap), and quantities on the face are given per overlap cell. The radial-face Jacobian exists when the p faces are the same at all radii (has_same_p_faces).

In cylindrical geometry 𝒱' = 2π p² V', so that the density is n(r) = (1/V') Σ_ij 𝒱'_ij Δp_i Δξ_j f_ij.

source
Runes2P.current_density — Method
current_density(grid, f; pitch_rule=:linear, region=nothing, t=0)

Current density j(r) = e c (1/V') Σ_ij 𝒱'_ij Δp_i (p_i/γ_i) w_j f_ij in A/m² carried by the distribution f (3D array, the same cell counts at all radii), with the pitch weights w_j of pitch_moment_weights; :cell_center is DREAM's j_hot moment. Sign as in DREAM: positive when the electrons move towards ξ = 1, the direction in which add_electric_field! accelerates them for E > 0, so j and E share their sign and the electron charge is folded into that convention. 𝒱' and p/γ are taken at the cell centre; a pitch-dependent Jacobian (toroidal geometry) would enter the pitch weights. With region, a MomentumRegion, the moment covers that part of the momentum grid, with the limit of the region at the time t [s] (DREAM's j_hot of the fully kinetic mode is the current above 7 thermal momenta).

source
Runes2P.cylindrical_grid — Method
cylindrical_grid(momentum_grid, radial_grid)
cylindrical_grid(momentum_grids::AbstractVector, radial_grid)

Kinetic grid with a homogeneous magnetic field (no trapping, no bounce averaging), with one momentum grid for all radii or one per radius. Per-radius grids with identical faces count as shared.

source
Runes2P.density — Method
density(grid, f; region=nothing, t=0)

Density moment n(r) = (1/V') ∫ 𝒱' f dp dξ [m⁻³] at each radius, for f [m⁻³] stored as a 3D array (the same cell counts at all radii). With region, a MomentumRegion, the moment covers that part of the momentum grid, with the limit of the region at the time t [s].

source
Runes2P.has_same_cell_counts — Method
has_same_cell_counts(grid)

Whether all radii have the same momentum and pitch cell counts, so that a distribution fits a 3D array. The faces may differ between radii (per-radius pitch grids).

source
Runes2P.momentum_envelope — Function
momentum_envelope(region, grid::KineticGrid, ir, t=0)

Envelope of the region on the momentum cells of the radius index ir at the time t [s].

source
Runes2P.momentum_grid — Method
momentum_grid(grid, ir)
momentum_grid(grid)

Momentum grid at radius index ir; without ir, the grid shared by all radii.

source
Runes2P.phase_space_jacobian_r_faces — Method
phase_space_jacobian_r_faces(grid)

Phase-space Jacobian [m] on the radial faces, (p cells, face pitch cells, radii + 1), with the pitch cells of a face those of radial_face_overlap (the pitch cells of the grid when the radii share their pitch grid) and zeros beyond the count of a face. Defined when the p faces are the same at all radii.

source
Runes2P.pitch_moment_weights — Method
pitch_moment_weights(momentum_grid; pitch_rule=:linear)

Weights w_j with ∫ ξ f dξ ≈ Σ_j w_j f_j for a distribution given by its values f_j at the pitch cell centres of one momentum grid. The density moment (weight 1) is the same for both rules; the rules differ for a weight that varies across the cell.

  • :cell_center: w_j = ξ_j Δξ_j, the midpoint rule, DREAM's moment (CurrentDensityFromDistributionFunction). Exact for f constant in ξ; for f linear in ξ it underestimates ∫ ξ² dξ by the relative amount Δξ²/4 on a uniform grid (25% at 2 pitch cells, 0.1% at 32).
  • :linear: f reconstructed in each cell as f_j + s_j (ξ − ξ_j), with s_j the slope at ξ_j of the parabola through the three nearest centres (the central difference on a uniform grid, one-sided at the ends; the two-point slope with two cells, zero with one). The reconstruction keeps the density of every cell (∫ (ξ − ξ_j) dξ = 0) and adds s_j Δξ_j³/12 to its ξ moment. Exact for f linear in ξ on any grid, which removes the Δξ²/4 term; the remaining error is second order and proportional to the curvature of f, so it vanishes for the Spitzer-like f₁ ∝ ξ of the conductivity.
source
Runes2P.radial_face_overlap — Method
radial_face_overlap(grid, face)

PitchOverlap of the pitch grids on the two sides of radial face face (between the radii face - 1, the left grid, and face, the right grid). Its overlap cells are the pitch cells of the face. On the first and the last face both sides are the grid of the boundary radius.

source
Runes2P.radial_face_pitch_cell_count — Method
radial_face_pitch_cell_count(grid, face)
radial_face_pitch_cell_count(grid)

Number of pitch cells of radial face face (the overlap cells of the two neighbouring pitch grids); without face, the largest count over the faces, which is the second dimension of the arrays on the radial faces.

source
Runes2P.radial_neighbour_pitch_cells — Method
radial_neighbour_pitch_cells(grid, ir, j, direction)

Pitch cells at the radius ir + direction (direction is -1 or 1) that overlap pitch cell j of radius ir, as a range; empty beyond the first and the last radius. These are the cells a radial flux couples cell j to.

source
Runes2P.runaway_grid — Method
runaway_grid(hot_tail_grid, p_faces_above, xi_faces=biuniform_theta_xi_faces(20, 12, 0.9))

Cylindrical kinetic grid of the runaway electrons above hot_tail_grid, on the same radii: at every radius its first p face is the last p face of the hot-tail grid there, followed by p_faces_above in units of mₑc (increasing, all above that face, the last one the p_max of the runaway grid), e.g. uniform_p_faces(n, p, p_max)[2:end] with p the hot-tail p_max. Taking the first face from the hot-tail grid keeps the two grids on one face to the bit, which the MomentumInterfaceTerm between them requires.

The default pitch grid is uniform in θ in two regions, 12 cells for θ ∈ [0, 0.9 rad] and 8 cells up to π (a choice of this package; see the docs page Choices of this package). The pitch grid is the same at all radii and independent of the pitch grid of the hot-tail grid.

source
Runes2P.total_particles — Method
total_particles(grid, f)

Total particle content Σ 𝒱' Δp Δξ Δr f [m⁻¹], conserved by a flux-form discretization, for f [m⁻³] stored as a 3D array (the same cell counts at all radii). With the spatial Jacobian V' = r of a cylinder in 𝒱', it is the number of electrons per metre of the cylinder divided by 2π.

source

Methods of other modules

Base.size — Method
size(grid::KineticGrid)

(p cells, ξ cells, radii) of a grid with the same cell counts at all radii, the shape of a distribution stored as a 3D array.

source

src/grids/momentum_region.jl

Public

Runes2P.MomentumRegion — Type
MomentumRegion(limit; side=:above, envelope=:interpolated, smooth_width=2)

Part of the momentum grid that a moment of a distribution covers (DensityMomentTerm, CurrentMomentTerm, density, current_density): the momenta above limit (side = :above) or below it (:below). limit is a momentum in units of mₑc: one number, one number per radius, or a function of time that returns either, e.g. a ThermalMomentum.

A moment with a region multiplies the contribution of the momentum cell i by the envelope of the region (momentum_envelope), 1 inside the region and 0 outside. envelope selects its values in the cells at the limit, for side = :above:

  • :interpolated: the part of the cell that holds the limit p₀ counts with the integrand at the midpoint of that part, interpolated linearly between the centre of the cell and the next one (DREAM's P_THRESHOLD_MODE_MIN_THERMAL, EvaluateMinThermalInterpolationEnvelope). In the last cell of the grid the integrand is taken to fall to zero at p_max. The moment is continuous in p₀ with a continuous derivative inside a cell.
  • :cell_fraction: the fraction of the cell above the limit, with the integrand of the cell centre (DREAM's P_THRESHOLD_MODE_MIN_MC).
  • :smooth: (1 + tanh((p − p₀) / (smooth_width Δp))) / 2 at the cell centres, with Δp the width of the first cell whose centre lies above p₀, or of the last cell when no centre does (DREAM's P_THRESHOLD_MODE_MIN_THERMAL_SMOOTH, width 2, which takes p₀ minus the last centre there).

The envelope of side = :below is one minus that of :above, so the two regions of one limit add up to the whole grid (DREAM's MAX modes for the cell fraction and the smooth step).

source
Runes2P.ThermalMomentum — Type
ThermalMomentum(temperature; factor=7)

Momentum limit that follows the cold-electron temperature: factor thermal momenta, p₀ = factor √(2 T / mₑc²) in units of mₑc at each radius (DREAM's hot region, pThreshold = 7 in thermal units by default in its Python interface). temperature is the temperature in eV at each radius, or a function of time that returns the temperatures or a PlasmaState. limit(t) gives the momenta at the time t [s].

temperature may also be the name of the radial unknown of the temperature. The limit then follows the state, and the moments over the region hold the column of the temperature in their Jacobian: the derivative of the envelope with respect to the limit, piecewise in the cells as DREAM's (MomentQuantity.cpp).

source
Runes2P.momentum_envelope! — Method
momentum_envelope!(values, region, momentum_grid, limit)
momentum_envelope(region, momentum_grid, limit)

Envelope of the region on the momentum cells of one momentum grid, for the limit limit in units of mₑc: the factor of the contribution of each momentum cell to a moment (MomentumRegion).

source
Runes2P.momentum_limit — Function
momentum_limit(region, ir, t=0; radii=nothing)

Limit of the region in units of mₑc at the radius index ir and the time t [s]. With radii, the number of radii of the grid, the length of a limit per radius is checked.

source

Internal

Runes2P.region_temperature — Method
region_temperature(region)

The name of the temperature unknown that the limit of a region follows, as a tuple of one name, or an empty tuple (also for nothing).

source