The ElectricField
class holds settings for the parallel electric field solved for by DREAM,
which is described by the unknown E_field
. This quantity is defined as
where angle brackets \(\langle\cdot\rangle\) denote a flux-surface average, \(\boldsymbol{E}\) denotes the electric field, \(\boldsymbol{B}\) the magnetic field and \(\varphi\) the toroidal angle.
The electric field can be solved for in three different ways:
By prescribing the electric field profile in time \(E_\parallel = \tilde{E}(t,r)\) (TYPE_PRESCRIBED
)
By solving the induction equation (TYPE_SELFCONSISTENT
):
By requiring Ohm’s law to be satisfied, \(j_\Omega=\sigma E_\parallel\), and providing the ohmic current density profile \(j_\Omega\), along with the temperature and density required to determine the plasma conductivity \(\sigma\).
(1)¶\[\begin{split} \begin{cases} \frac{\partial\psi_{\rm p}}{\partial t} &= V_{\rm loop},\\ \mu_0\frac{j_\parallel}{B}\left\langle \boldsymbol{B}\cdot\nabla\varphi \right\rangle &= \frac{1}{V'}\frac{\partial}{\partial r}\left[ V'\left\langle \frac{\left|\nabla r\right|^2}{R^2} \right\rangle \frac{\partial\psi_{\rm p}}{\partial r} \right] \end{cases}\end{split}\]where \(\psi_{\rm p}\) is the poloidal flux, \(\mu_0\) is the vacuum permeability, \(V'\) the spatial Jacobian and \(r\) the minor radius in the outer midplane. The loop voltage \(V_{\rm loop}\) is defined by
\[V_{\rm loop} = 2\pi \frac{\langle \boldsymbol{E}\cdot\boldsymbol{B} \rangle}{\langle \nabla \varphi \cdot \boldsymbol{B} \rangle}.\]
The electric field can be prescribed in both space and time. The full syntax for prescribing an electric field evolution is
ds.eqsys.E_field.setPrescribedData(efield=E_field, radius=E_field_r, times=E_field_t)
where E_field
is an array of shape (nt, nr)
specifying the parallel
electric field strength in space and time, E_field_r
is a vector with nr
elements representing the radial grid on which the electric field is prescribed,
and E_field_t
is a vector with nt
elements representing the time grid on
which the electric field is prescribed.
For convenience, it is possible to prescribe a constant and radially uniform electric field by only specifying it as a scalar:
ds.eqsys.E_field.setPrescribedData(0.3)
This will cause the electric field to be \(E_\parallel = 0.3\,\mathrm{V/m}\) at every radius, in every time step, during the simulation.
In this mode the electric field is evolved by solving the system
(1). The evolution of the electric field is thus coupled to the
poloidal flux \(\psi_{\rm p}\) and, by extension, to the total plasma
current density \(j_{\rm tot}\). To evolve the electric field
self-consistently, the first thing one must do is to set the type of the
electric field to TYPE_SELFCONSISTENT
via a call to
setType()
:
import DREAM.Settings.Equations.ElectricField as ElectricField
...
ds.eqsys.E_field.setType(ElectricField.TYPE_SELFCONSISTENT)
By default, the initial electric field profile will be identically zero. This
is automatically overridden if the settings are loaded from an old output file
(see restart), but the initial profile can also be set explicitly via a
call to setInitialProfile()
:
ds.eqsys.E_field.setInitialProfile(efield=E_field, radius=E_field_r)
where E_field
is a vector of size nr
giving the initial electric field
profile, and E_field_r
is a vector representing the radial grid on which the
initial electrc field profile is defined.
Alternatively, the electric field can be initialized such that it gives the desired ohmic current density profile (achieved by inverting Ohm’s law):
ds.eqsys.j_ohm.setInitialProfile(j=j_ohm, radius=j_ohm_r, Ip0=Ip0)
where j_ohm
is the desired current density profile and j_ohm_r
its grid.
If the optional parameter Ip0
is provided, the given current density
profile is rescaled such that the prescribed ohmic current density profile
yields exactly a total plasma current Ip0
when integrated on the internal
DREAM grid (which is not necessarily the same as the grid on which j_ohm
is
given).
The second equation in (1) requires a boundary condition at \(r=r_{\rm wall}\) to be given. In DREAM, three different boundary conditions can be applied at the tokamak wall.
The first boundary condition, BC_TYPE_PRESCRIBED
, prescribes the time
evolution of the loop voltage \(V_{\rm loop,wall}\) on the tokamak wall
(normalized to the tokamak major radius \(R_0\)). This is particularly
useful for simulating experimental scenarios where the parameter
\(V_{\rm loop,wall}\) has been measured.
import DREAM.Settings.Equations.ElectricField as ElectricField
ds = DREAMSettings()
...
# Tokamak major radius
R0 = 1.65
# Define evolution of V_loop/R0
Vmax = 1
V_loop_t = np.linspace(0, 1, 100)
V_loop_R0 = (Vmax/R0)*(1 - (1-t)**2)
ds.eqsys.E_field.setBoundaryCondition(bctype=ElectricField.BC_TYPE_PRESCRIBED,
V_loop_wall_R0=V_loop_R0, times=V_loop_t, R0=R0)
The second boundary condition, BC_TYPE_SELFCONSISTENT
, instead lets the user
specify the (inverse) tokamak wall time, \(1/\tau_{\rm wall}\), which
directly corresponds to the wall resistivity. The perfectly conducting limit
\(\tau_{\rm wall} = \infty\) is supported, and is obtained by setting
inverse_wall_time = 0
. In case a cylindrical geometry is used, the major
radius R0
can be explicitly set, independently of the geometry used, since
the external inductance otherwise diverges for infinite major radius.
import DREAM.Settings.Equations.ElectricField as ElectricField
ds = DREAMSettings()
...
# Tokamak major radius
R0 = 1.65
# Wall time
tau_wall = .01 # (s)
ds.eqsys.E_field.setBoundaryCondition(bctype=ElectricField.BC_TYPE_SELFCONSISTENT,
inverse_wall_time=1/tau_wall, R0=R0)
The third boundary condition, BC_TYPE_TRANSFORMER
, can be seen as a
combination of the two other boundary conditions, with a resistive wall and
a prescribed loop voltage (although at the transformer, which passes through the
axis of symmetry at \(R=0\)).
import DREAM.Settings.Equations.ElectricField as ElectricField
ds = DREAMSettings()
...
# Tokamak major radius
R0 = 1.65
# Define evolution of V_loop/R0
Vmax = 1
V_loop_t = np.linspace(0, 1, 100)
V_loop_R0 = (Vmax/R0)*(1 - (1-t)**2)
# Wall time
tau_wal = .01 # (s)
ds.eqsys.E_field.setBoundaryCondition(bctype=ElectricField.BC_TYPE_PRESCRIBED,
inverse_wall_time=1/tau_wall, R0=R0,
V_loop_wall_R0=V_loop_R0, times=V_loop_t)
Note
With all boundary conditions, the tokamak wall location wall_radius
must
be specified. This parameter denotes the minor radial coordinate of the
tokamak wall (i.e. the distance of the wall from the center of the plasma).
This is done via the call ds.radialgrid.setWallRadius(b)
, where b
is
the desired wall radius.
The initial value of the electric field can be set either using the
setInitialProfile()
method, as shown above, or by specifying the desired
initial current density profile. The electric field will then be initialized to
whatever profile gives the necessary ohmic current density profile, so that the
prescribed total current density profile is obtained.
More details about how to initialize the electric field via a current density profile can be found on the page for the ohmic current density.
If the desired ohmic current density profile \(j_\Omega\) is known, the corresponding electric field can be found by inverting Ohm’s law
where \(\sigma\) denotes the plasma conductivity, which depends on primarily the electron density and temperature. To evaluate the electric field from this law, the following configuration can be made:
import DREAM.Settings.Equations.ElectricField as ElectricField
ds.eqsys.E_field.setType(ElectricField.TYPE_PRESCRIBED_OHMIC_CURRENT)
ds.eqsys.j_ohm.setCurrentProfile(j=j_ohm, radius=r, times=t, Ip0=Ip0)
where j_ohm
is the desired current density profile, r
is the radial
grid on which the profile is specified, and t
is its time grid. If no time
evolving current density is needed, j_ohm
can be given as a 1D array. If the
optional scalar parameter Ip0
is given, the current density profile is
rescaled such that, when integrated over the plasma cross-section, it yields
exactly the total plasma current Ip0
.