Initialization
HallThruster.jl provides sensible defaults for simulation initialization, or allows you to specify your own initial condition.
Default
The default is DefaultInitialization()
, which initializes the solution domain as described in the following sections. Below, $z_0$ and $z_N$ are domain[1]
and domain[2]
, as passed into the Config
object (see Configuration), $L_{ch}$ and $A_{ch}$ are config.thruster.geometry.channel_length
and config.thruster.geometry.channel_area
, respectively, and $\dot{m}$ is config.anode_mass_flow_rate
.
The DefaultInitialization
has parameters max_electron_temperature
, min_ion_density
, and max_ion_density
, which can be used to scale the default initialized. These default to config.discharge_voltage/10
, 2e17
, and 1e18
, respectively.
Ion densities
The ion densities are Gaussian with a constant offset and a scaling factor proportional to the mass flow rate and discharge voltage. For ions with charge 1, the density is
\[\rho_{i} = \rho_min m_i \sqrt{\frac{V_d}{300}}\frac{\dot{m}}{5\times10^{-6}}\left(1 + \frac{\rho_max}{\rho_min} \exp\left[-\left(\frac{z - z_0 - L_{ch}/2}{L_{ch}/3}\right)^2\right]\right)\]
For ions with charge Z
, the density is assumed to scale as
\[\rho_i|_Z = \frac{\rho_i |_{Z=1}}{Z^2}\]
Ion velocities
Ions are initialized with the Bohm velocity at the anode. For an ion of charge $Z$, this is
\[u_i[1] = -u_{bohm} =- \sqrt{\frac{Z \;e\;T_{eV, anode}}{m_i}}\]
The maximum ion velocity is determined by the discharge voltage $V_d$:
\[u_i[\mathrm{end}] = u_{max} = \sqrt{\frac{2 \;Z \;e \; V_d}{m_i}}\]
The initial ion velocity profile between the cathode and the anode is then prescribed as:
\[u_i(z) = \begin{cases} u_{bohm} + \frac{2}{3}(u_{max} - u_{bohm})\left(\frac{z - z_0}{L_{ch}}\right)^2 & z-z_0 < L_{ch} \\ \frac{1}{3}\left(u_{bohm} + u_{max}\right)\left(1 - \frac{z - z_0 - L_{ch}}{z_N - L_{ch}}\right) + u_{max}\left(\frac{z - z_0 - L_{ch}}{z_N - L_{ch}}\right) & z - z_0 \ge L_{ch} \end{cases}\]
Neutral density
The neutral density at the anode is computed in the same way as during a simulation, namely:
\[\rho_{n, anode} = \frac{\dot{m}}{u_n A_{ch}} - \sum_s \frac{[\rho_{is} u_{is}]_{anode}}{u_n}\]
The density at the cathode is assumed to be 1/100 that at the anode. In the domain, the neutral density has a sigmoid shape:
\[\rho_n(z) = \frac{1}{2}\left(\rho_{n,anode} + \rho_{n, cathode} + (\rho_{n, anode} - \rho_{n, cathode})\tanh\left(\frac{z - z_0 - L_{ch}/2}{L_{ch} / 6}\right)\right)\]
Electron energy
The number density is computed from the ion densities. The electron temperature is a Gaussian with height $V_d / 10$ eV plus a linear baseline to make sure the boundary conditions are satisfied:
\[T_e(z) = \left(1 - \frac{z - z_0}{z_N - z_0}\right) T_{e, anode} + \left(\frac{z - z_0}{z_N - z_0}\right) T_{e, cathode} + T_{e,max}\exp\left[-\left(\frac{z - z_0 - L_{ch}}{L_{ch}/3}\right)^2\right]\]
Example
For a simulation of the SPT-100 with $V_d$= 500V, three ion charge states, a a mass flow rate of 3 mg/s, an anode electron temperature of 3 eV and a cathode electron temperature of 5 eV, the initial condition looks like:
Custom initial conditions
You may define your own initial condition by creating subtypes of HallThruster.InitialCondition
. Let's say for some reason we wanted to initialize every state variable in every cell to the z-location of its cell center. We might define our initialization as follows:
using HallThruster
struct MyInitialCondition <: HallThruster.InitialCondition end;
# output
We would then add a method to the initialize!(U, params, model)
function as follows:
import HallThruster.initialize!
function HallThruster.initialize!(U, params, model::MyInitialCondition)
(;z_cell) = params # Pull cell centers locations out of params
nvars = size(U, 1)
for (i, z) in enumerate(z_cell)
for j in 1:nvars
U[j, i] = z_cell[i]
end
end
return U # optional. Since U is modified. the return value is never used, but by Julia convention we also return the mutated object.
end;
# output
We can check the behavior of our new function:
# Dummy config and params
ncells = 100
nvars = 4
config = (;initial_condition = MyInitialCondition())
z_cell = range(0, 0.05, length = ncells)
U = zeros(nvars, ncells)
params = (;config, z_cell)
# Method of initialize! which dispatches to initialize!(U, params, config.initial_condition)
# This is what HallThruster.jl calls when initializing a simulation
HallThruster.initialize!(U, params)
U[1, :] == U[2, :] == U[3, :] == U[4, :] == collect(z_cell)
# output
true