Using the detachment controller
N.b. currently this code has been developed for and tested only in 1D and with a single processor.
Overview
The DetachmentController
is designed to adjust plasma parameters
dynamically to maintain the detachment front at a desired position. It
uses a proportional-integral-derivative (PID) controller approach,
customized with specific logic for detachment control in plasma
simulations. The controller modifies the source terms for energy or
particle density based on the difference between the current and desired
detachment front locations.
Key Components
Constructor: Initializes the controller with simulation options, including setpoints, control parameters (gain, integral time, derivative time), actuator type (power or particles), and other relevant settings.
transform(Options& state): Main method called at each simulation timestep to calculate the control action. It performs several steps:
Computes the current location of the detachment front based on plasma densities.
Calculates the error between the desired and current detachment front locations.
Updates the control signal based on the PID algorithm.
Applies the control signal to adjust the source terms accordingly.
outputVars(Options& state): Outputs diagnostic variables related to the control process, such as the detachment front location, control signal, and PID terms.
restartVars(Options& state): Manages state variables for restarting the simulation from saved states, ensuring the controller can smoothly continue from a previous point, without perturbations due to reinitialising internal variables.
Usage
To use the DetachmentController
in a BOUT++ simulation, you must
provide a setpoint for the detachment front location, choose the
actuator type, and configure the PID controller parameters (gain,
integral time, derivative time). The input for a minimum working example
would be something like
[hermes]
components = (d+, d, e, detachment_controller, ...)
[detachment_controller]
; Desired location of the detachment front, in metres from the target
detachment_front_setpoint = 1.0
; What is the main neutral species?
neutral_species = "d+"
; What should we adjust to control the detachment front?
actuator = "power"
; What species should we look at for `source_shape`
species_for_source_shape = e
; What species should we control, and how much control should apply
; to each species?
species_list = e, d+
scaling_factors_list = 1.0, 1.0
; What value to use for Kp? See the rest of the documentation
controller_gain = 1.0
[Pe]
function = 1.0
source_shape = (power_flux*2/3 / (mesh:length_xpt))*H(mesh:y_xpt - y)
[Pd+]
function = Pe:function
; No Pd+ source or source_shape
Top-level overview of the algorithm
Detachment Front Location Calculation: Determines the point where the neutral density exceeds the electron density, which is taken as the position of the detachment front.
PID Controller Implementation: Adjusts the control signal based on the error between the current and target detachment front locations. Supports both velocity and position form PID control.
Actuator Type: Defines whether the control action adjusts power or particle sources in the simulation.
Control Signal Application: Modifies the source terms for specified plasma species based on the control signal, influencing the plasma dynamics to achieve the desired detachment front location.
Fine details
Finding the detachment front
We define the detachment front as the point where the neutral density
(N_neutral_species
) becomes larger than the electron density
(Ne
). There’s lots of other (better) definitions, but this one is
the easiest to calculate. For each timestep, the controller starts at
the divertor target and checks whether a cell has \(n_N > n_e\). The
first time it finds a cell fulfilling that condition, it calculates to
first order the position where the cross-over would occur, by comparing
the last point where \(n_N > n_e\) (point 1) with the first point
where \(n_e > n_N\) (point 2);
Note that, since the \(y\) values aren’t stored directly, we compute it from \(dy\) while iterating along cells.
Calculating the feedback response via PID control
Once we have the detachment position, we need to control its position. Firstly, we define the error \(e = x_S - x_D\) where \(x_S\) is our setpoint and \(x_D\) is the actual position of the detachment front. We also fetch the current time \(t\).
If starting a new simulation, we don’t actually want to start
controlling the detachment front straight away, but instead wait for
settling_time
(in seconds). Until then, we just set
control = initial_control
.
Once we’re through the settling_time
, we only apply control if the
time has changed by some min_time_for_change
and if the absolute
change of the error is at least min_error_for_change
. Usually we set
min_time_for_change
to be a small, but non-zero number, which
prevents us from dividing by zero when evaluating the derivative of the
error. Often the min_error_for_change
is zero, although you can
experiment with this and see if it gives you improved performance of the
controller. Once these conditions are met, we update the control value.
There are two options for the control algorithm to use — the ‘position’ and ‘velocity’ forms of the PID. These are, respectively,
and
where * \(C\) is the control value applied to the source * \(s\) is the response sign (\(+1\) for particles or \(-1\) for power) * \(K_c\) is the controller gain * \(\tau_I\) is the integral time * \(\tau_D\) is the derivative time * \(\int e\cdot dt\) is the error integral * \(\frac{d e}{d t}\) is the error derivative * \(C_0\) is the control offset (usually zero, unless you’re running in proportional-only mode and need a finite control when the error is zero) * \(C_{prev}\) is the previous value of \(C\)
In the position form, we directly update the control value, while in the
velocity form we calculate the change of the control value and add it to
the previous control value. These two approaches should be largely
equivalent, although the velocity form has the advantage of avoiding
integral windup when the control is at either its min or max value.
Conversely, with the position form we can apply other anti-windup
schemes which explicitly change the error integral. A particularly
useful anti-windup method (only available in position form) is
reset_integral_on_first_crossing
, where the error integral is reset
when the detachment front first reaches the setpoint.
In either scheme, the control value is bounded by
minval_for_source_multiplier
and maxval_for_source_multiplier
,
which can be used either to ensure that the system stays within
physical, engineering or numerical-stability constraints.
Understanding PID control and tuning the coefficients
See en.wikipedia.org/wiki/Proportional-integral-derivative_controller. Most relevant sections are
Input Parameters
``detachment_front_setpoint``: The desired position of the detachment front from the divertor target, measured in meters from the divertor target. It represents the target location where the control system aims to maintain the front.
``velocity_form``: A boolean flag indicating whether to use the velocity form (if
true
) or the position form (iffalse
) of the PID controller.``min_time_for_change``: The minimum time interval, in seconds, before the control signal can be updated. This parameter prevents divide-by-zero errors when evaluating the error derivative.
``min_error_for_change``: The minimum change in error required before the control signal is updated. This term is mostly left for experimenting.
``minval_for_source_multiplier``: The minimum value that the control signal (source multiplier) can take.
``maxval_for_source_multiplier``: The maximum value for the control signal (source multiplier).
``species_for_source_shape``: Specifies the plasma species from which to select the source shape. The feedback source is the product of the control signal (source multiplier) and the source shape. If
actuator='power'
this will setsource_shape=Ps::source_shape
wheres=species_for_source_shape
, and ifactuator='particles'
this will setsource_shape=Ns::source_shape
.``neutral_species``: Indicates the main neutral species in the plasma. This species is used to determine the location of the detachment front.
``actuator``: Defines the actuator to be adjusted to control the detachment front position. Options include ‘power’ for energy sources or ‘particles’ for particle density sources.
``initial_control``: The initial value for the source multiplier (control signal) at the start of the simulation.
``control_offset``: The expected control value when the error equals zero. It serves as a baseline around which the control signal is modulated. Only used in position form.
``settling_time``: The time allowed for the system to settle before activating certain control terms, measured in seconds. It delays the start of control actions to ensure initial transients have subsided.
``ignore_restart``: A flag to ignore the restart file, mainly useful for development purposes. It forces the controller to initialize from the provided settings rather than loading a previous state.
``reset_integral_on_first_crossing``: Resets the error integral to zero when the detachment front first reaches the desired position. This feature can help prevent integral wind-up and improve control stability.
``controller_gain`` (Kc): The proportional gain of the PID controller. It determines the strength of the response to the error.
``integral_time``: The integral time of the PID controller, which influences the rate at which the integral term accumulates error over time.
``derivative_time``: The derivative time of the PID controller, affecting how strongly the controller reacts to the rate of change of the error.
``buffer_size``: The number of points to store for calculating derivatives. It determines the size of the window over which the derivative of the error is computed. Usually a value of around 3 to 5 seems to filter out the worst of the noise due to small time-steps. Very large values will potentially introduce a destabilising lag in the derivative response (and also will eventually start to impact computational performance).
``species_list``: A comma-separated list of species to which the PI-controlled source will be applied.
``scaling_factors_list``: A comma-separated list of scaling factors corresponding to each species listed in
species_list
. These factors adjust the magnitude of the control action applied to each species.``diagnose``: Enables the output of additional diagnostic variables related to the control process if set to
true
.``debug``: Controls the level of debugging information printed to the screen. A value of
0
disables debugging output,1
enables basic output, and2
provides extensive debugging information.