Prescribed Sources
The prescribed_sources package deposits energy into a material
according to a user-supplied schedule — a time series of the
cumulative energy delivered to that material. It is the way to drive a
simulation with an externally specified energy input (for example a
modeled laser or radiation drive) without resolving the physical
source. Any number of independent sources may be defined, each
targeting one material. The package requires hydrodynamics.
Governing Equations
Each source is specified by a monotonically increasing schedule \(\mathcal{E}_m(t)\) giving the cumulative, total energy delivered to material \(m\) up to time \(t\), integrated over all of that material in the domain. Over a step from \(t\) to \(t+\Delta t\) the total energy added to the material is the increment
This total is converted to a specific energy increment by dividing by the material’s current total mass \(M_m\) (summed over the whole domain, Section Numerical Method), and deposited uniformly by mass: a cell holding a partial density \(\bar\rho_m\) of the material receives
The increment therefore adds the same specific energy \(\Delta
E_m/M_m\) everywhere the material is present, so the source heats the
material uniformly per unit mass rather than per unit volume. The
energy is added to the bulk total energy
(ccbulk::total_material_energy); the per-material internal
energies, temperature, and pressure are then recovered through the
equation-of-state and PTE closure of Chapter Materials and Equations of State.
Warning
The schedule is cumulative: the file records total energy delivered so far, not an instantaneous rate. Because the source is applied as a specific energy increment, a multi-phase material is heated with a single \(\mathrm{d}e/\mathrm{d}t\) common to all its phases.
Warning
The energies in the schedule have units of total energy, not specific, even though a specific energy is used internally by the actual source terms.
Numerical Method
The package runs as an operator-split step after the hydrodynamic update. On each step it adds the energy increment to the bulk total energy, then recomputes the derived material state (internal energies and a PTE solve), exchanges boundary data, and fills derived quantities again. The domain-summed per-material masses \(M_m\) needed to convert total to specific energy are reduced before each step (and once before the main loop, so they are present in the first output).
The schedule file is read as an ASCII table and resampled onto a
uniform time grid at initialization; values are interpolated within
the tabulated range and held constant (constant extrapolation) outside
it. The package also votes on the time step: it limits \(\Delta
t\) so that the energy deposited does not change a material’s
temperature too abruptly, scaling the estimate by dt_safety.
Input Parameters
Prescribed sources are enabled with prescribed_sources = true
in the <physics> block (Section Enabling Physics: the <physics> Block);
hydro must also be enabled. A single global control lives in the
<prescribed_sources> block, and each source is defined in its own
contiguous, zero-based <energy_source0>, <energy_source1>,
… block.
Parameter |
Type |
Default |
Description |
|---|---|---|---|
dt_safety |
Real |
|
Safety factor applied to the source time-step limit. |
Parameter |
Type |
Default |
Description |
|---|---|---|---|
material |
int |
— |
Index of the material this source drives; required. |
cumulative_energies |
string |
— |
Path to an ASCII file giving the schedule; required. |
active |
bool |
|
Set |
The Schedule File
The cumulative_energies file is a two-column ASCII table: the
first column is time and the second is the cumulative total energy
delivered to the material by that time. The energies must be
monotonically increasing and non-negative, and the first energy entry
must be exactly 0. The table need not be uniformly spaced — RIOT
resamples it onto a uniform grid on read.
Example
Drive material 0 with a tabulated energy schedule, and record the
per-material masses and energies in the history file:
riot.input("physics", hydro=True, prescribed_sources=True,
sparse_physics=False)
riot.input("energy_source0",
material=0,
cumulative_energies="drive_schedule.dat") # time, cumulative energy
riot.input("diagnostics", packages=["masses", "energies"])
A minimal drive_schedule.dat delivering \(100\) (energy units)
linearly over the first microsecond and holding thereafter:
# time cumulative_energy
0.0 0.0
1.0e-6 100.0
1.0e-3 100.0