Fokker–Planck coefficients
src/operators/kinetic_terms.jl
Public
Runes2P.add_electric_field! — Method
add_electric_field!(op, plasma)Acceleration by the parallel electric field: Aᵖ = (eE/mc) ξ, Aᵠ = (eE/mc)(1 - ξ²)/p. A positive field accelerates electrons towards ξ = +1.
Runes2P.add_energy_diffusion! — Method
add_energy_diffusion!(op, collisions)Energy diffusion Dᵖᵖ = ν_∥(p) on the p faces (zero unless mode = :full).
Runes2P.add_pitch_scattering! — Method
add_pitch_scattering!(op, collisions)Pitch-angle scattering Dᵠᵠ = ν_D(p)(1 - ξ²)/2 on the ξ faces. A model with the faces of the grid of op (CollisionModel(plasma, settings; faces)) gives ν_D from its tables at the cell centres, the values of deflection_frequency.
Runes2P.add_slowing_down! — Method
add_slowing_down!(op, collisions)Collisional friction Aᵖ = -p ν_s(p) on the p faces, and the particle flux through p = 0 from lim p³ν_s, which the operator applies under p_zero_boundary = :outflow (AdvectionDiffusion).
Runes2P.add_synchrotron! — Method
add_synchrotron!(op, plasma)Synchrotron radiation reaction in a homogeneous field B: Aᵖ = -C B² p γ (1 - ξ²), Aᵠ = C B² ξ (1 - ξ²)/γ, C = e⁴/(6π ε₀ mₑ³ c³).
Runes2P.fokker_planck_operator — Function
fokker_planck_operator(grid, plasma, settings; synchrotron=true,
scheme=:exponential_fitting, p_scheme=scheme, xi_scheme=scheme,
p_lower_boundary=:zero_flux, p_upper_boundary=:f_zero,
p_zero_boundary=:outflow, r_boundary=:zero_flux,
field_in_coefficients=true)Kinetic operator for the hot electrons: electric field, slowing down, pitch-angle scattering, energy diffusion (:full mode) and synchrotron losses. The default boundary at p_max, p_upper_boundary = :f_zero, is an outflow into a ghost cell with f = 0, DREAM's BC_F_0 (a choice of this package; see the docs page Choices of this package); DREAM's default for the hot-tail grid is BC_PHI_CONST, p_upper_boundary = :constant_flux here (AdvectionDiffusion). The synchrotron loss (add_synchrotron!) is on by default (a choice of this package; see the docs page Choices of this package), and synchrotron = false leaves it out, as DREAM does by default. scheme is one of the schemes of AdvectionDiffusion. The default, exponential fitting, is a choice of this package (see the docs page Choices of this package). It is first order where a smooth tail is driven by the field, such as the slide-away loss through p_max or the hot-tail seed of a fast quench: such tails need more momentum cells than with a limiter, the error roughly halving per doubling. :van_albada (Runes2P) and DREAM's limiters stay available; scheme = :central is DREAM's default (centred interpolation) and the setting of the DREAM comparisons. p_scheme and xi_scheme set the directions separately (DREAM's adv_interp/p1 and p2), e.g. p_scheme = :tcdf for DREAM's TCDF limiter.
A hot-tail grid with a runaway grid above it takes p_upper_boundary = :interface, and the operator of the runaway grid p_lower_boundary = :interface (a grid with p_min > 0, runaway_grid). The flux between the two is the MomentumInterfaceTerm of the equation system.
On a grid from p = 0 the friction carries electrons out through p = 0 by default (p_zero_boundary = :outflow, p3_slowing_down_frequency_at_zero), as on DREAM's hot-tail grid. p_zero_boundary = :zero_flux takes no flux there, as on DREAM's runaway grid, whose f_re keeps the Dirichlet lower condition of its advection in p (src/Settings/Equations/f_re.cpp:87, fvm/Equation/AdvectionTerm.cpp:36); the conditions are those of AdvectionDiffusion. p_zero_boundary applies to a grid from p = 0 only, p_lower_boundary to a grid with p_min > 0 only.
field_in_coefficients = false leaves the field of the plasma out of the coefficients, for a field that is an unknown of the system: the operator holds the collisions and the coefficients of a unit field, and the term passes the field (FokkerPlanckTerm(...; electric_field = :electric_field)).
The operator declares no radial transport and no cross diffusion (radial_transport = false, cross_diffusion = false of AdvectionDiffusion), since none of these terms writes them: its stencil couples neither the radii nor the corners of the 3×3 block in p and ξ. Radial transport takes an operator of its own.
Runes2P.set_fokker_planck_coefficients! — Function
set_fokker_planck_coefficients!(op, plasma, settings=CollisionSettings(); synchrotron=true,
field_in_coefficients=true)Rebuild op's coefficients in place from plasma and settings (zero_coefficients! then the terms of fokker_planck_operator, with the coefficients of add_slowing_down! and add_energy_diffusion! written in one sweep over the p faces), for a Fokker-Planck term whose plasma state changes with time (prescribed_fokker_planck_term). op's scheme, boundary conditions and declarations (AdvectionDiffusion) are unchanged; the rebuild writes no radial transport and no cross diffusion. field_in_coefficients = false leaves the field of the plasma out, for a field that is an unknown of the system. The synchrotron loss is on by default, as in fokker_planck_operator.
Runes2P.set_unit_field_coefficients! — Method
set_unit_field_coefficients!(op)Advection of an electric field of 1 V/m on the faces of op, Aᵖ = (e/mc) ξ and Aᵠ = (e/mc)(1 - ξ²)/p, into op.unit_field_advection_p and op.unit_field_advection_xi. They depend on the grid alone. An operator applied with a field as an argument (apply!(...; electric_field), FokkerPlanckTerm(...; electric_field)) adds the field times these to its advection, in place of add_electric_field! with a prescribed field.
Runes2P.zero_coefficients! — Method
zero_coefficients!(op::AdvectionDiffusion)Set every coefficient array of op to zero (not p_flux_at_lower_boundary, a boundary value the caller sets independently of the physics terms). For rebuilding an operator's coefficients from a new plasma state: the add_*! functions accumulate into the arrays, so a rebuild needs them cleared first.