Source code for jf1uids.option_classes.simulation_config
from types import NoneType
from typing import NamedTuple, Union
from jf1uids._physics_modules._stellar_wind.stellar_wind_options import WindConfig
from jaxtyping import Array, Float
# ===================== constant definition =====================
# differentiation modes
FORWARDS = 0
BACKWARDS = 1
# limiter types
MINMOD = 0
OSHER = 1
# Riemann solvers
HLL = 0
HLLC = 1
HLLC_LM = 2
# boundary conditions
OPEN_BOUNDARY = 0
REFLECTIVE_BOUNDARY = 1
PERIODIC_BOUNDARY = 2
# geometry types
CARTESIAN = 0
CYLINDRICAL = 1
SPHERICAL = 2
# axes
VARAXIS = 0
XAXIS = 1
YAXIS = 2
ZAXIS = 3
# ============================================================
# ===================== type definitions =====================
STATE_TYPE = Union[
Float[Array, "num_vars num_cells_x"],
Float[Array, "num_vars num_cells_x num_cells_y"],
Float[Array, "num_vars num_cells_x num_cells_y num_cells_z"]
]
STATE_TYPE_ALTERED = Union[
Float[Array, "num_vars num_cells_a"],
Float[Array, "num_vars num_cells_a num_cells_b"],
Float[Array, "num_vars num_cells_a num_cells_b num_cells_c"]
]
FIELD_TYPE = Union[
Float[Array, "num_cells_x"],
Float[Array, "num_cells_x num_cells_y"],
Float[Array, "num_cells_x num_cells_y num_cells_z"]
]
# =============================================================
[docs]
class BoundarySettings1D(NamedTuple):
left_boundary: int = OPEN_BOUNDARY
right_boundary: int = OPEN_BOUNDARY
[docs]
class BoundarySettings(NamedTuple):
x: BoundarySettings1D = BoundarySettings1D()
y: BoundarySettings1D = BoundarySettings1D()
z: BoundarySettings1D = BoundarySettings1D()
[docs]
class SimulationConfig(NamedTuple):
"""Configuration object for the simulation.
The simulation configuration are parameters defining
the simulation where changes necessitate recompilation."""
# Simulation parameters
#: Debug runtime errors, throws exceptions
#: on e.g. negative pressure or density.
#: Significantly reduces performance.
runtime_debugging: bool = False
#: Activate progress bar
progress_bar: bool = False
#: The number of dimensions of the simulation.
dimensionality: int = 1
#: The geometry of the simulation.
geometry: int = CARTESIAN
#: Magnetohydrodynamics switch.
mhd: bool = False
#: Self gravity switch, currently only
#: for periodic boundaries.
self_gravity: bool = False
#: The size of the simulation box.
box_size: float = 1.0
#: The number of cells in the simulation (including ghost cells).
num_cells: int = 400
#: The reconstruction order is the number of
#: cells on each side of the cell of interest
#: used to calculate the gradients for the
#: reconstruction at the interfaces.
reconstruction_order: int = 1
#: The limiter for the reconstruction.
limiter: int = MINMOD
#: The Riemann solver used
riemann_solver: int = HLLC
# Explanation of the ghost cells
# |---------|
# |---------|
# stencil |---------|
# cells || 1g | 2g | 3c | 4g | 5g ||
# reconstructions |L R|L R|L R| |
# fluxes --> -->
# update | 3c'|
# --> all others are ghost cells
#: The number of ghost cells.
num_ghost_cells: int = reconstruction_order + 1
#: Grid spacing.
grid_spacing: float = box_size / (num_cells - 1)
#: Boundary settings for the simulation.
boundary_settings: Union[NoneType, BoundarySettings1D, BoundarySettings] = None
#: Enables a fixed timestep for the simulation
#: based on the specified number of timesteps.
fixed_timestep: bool = False
#: Exactly reach the end time. In adaptive timestepping,
#: one might otherwise overshoot.
exact_end_time: bool = False
#: Adds the sources with the current timestep to
#: a hypothetical state to estimate the actual timestep.
#: Useful for time-dependent sources, but additional
#: computational overhead.
source_term_aware_timestep: bool = False
#: The number of timesteps for the fixed timestep mode.
num_timesteps: int = 1000
#: The differentiation mode one whats to use
#: the solver in (forwards or backwards).
differentiation_mode: int = FORWARDS
#: The number of checkpoints used in the setup
#: with backwards differetiability and adaptive
#: time stepping.
num_checkpoints: int = 100
#: Return intermediate snapshots of the time evolution
#: instead of only the final fluid state.
return_snapshots: bool = False
#: Call a user given function on the snapshot data,
#: e.g. for saving or plotting. Must have signature
#: callback(time, state, registered_variables).
activate_snapshot_callback: bool = False
#: The number of snapshots to return.
num_snapshots: int = 10
#: Fallback to the first order Godunov scheme.
first_order_fallback: bool = False
# physical modules
#: The configuration for the stellar wind module.
wind_config: WindConfig = WindConfig()
#: Cosmic rays
simplified_cosmic_rays: bool = False
[docs]
def finalize_config(config: SimulationConfig, state_shape) -> SimulationConfig:
"""Finalizes the simulation configuration."""
num_cells = state_shape[-1]
config = config._replace(num_cells = num_cells)
if config.dimensionality == 2:
num_cells_x, num_cells_y = state_shape[-2:]
if num_cells_x != num_cells_y:
raise ValueError("The number of cells in x and y must be equal.")
elif config.dimensionality == 3:
num_cells_x, num_cells_y, num_cells_z = state_shape[-3:]
if num_cells_x != num_cells_y or num_cells_x != num_cells_z:
raise ValueError("The number of cells in x, y and z must be equal.")
config = config._replace(grid_spacing = config.box_size / (config.num_cells - 1))
if config.geometry == SPHERICAL:
print("For spherical geometry, only HLL is currently supported.")
config = config._replace(riemann_solver = HLL)
# set boundary conditions if not set
if config.boundary_settings is None:
if config.geometry == CARTESIAN:
print("Automatically setting open boundaries for Cartesian geometry.")
if config.dimensionality == 1:
config = config._replace(boundary_settings = BoundarySettings1D(left_boundary = OPEN_BOUNDARY, right_boundary = OPEN_BOUNDARY))
else:
config = config._replace(boundary_settings = BoundarySettings())
elif config.geometry == SPHERICAL and config.dimensionality == 1:
print("Automatically setting reflective left and open right boundary for spherical geometry.")
config = config._replace(boundary_settings = BoundarySettings1D(left_boundary = REFLECTIVE_BOUNDARY, right_boundary = OPEN_BOUNDARY))
if config.wind_config.stellar_wind:
print("For stellar wind simulations, we need source term aware timesteps, turning on.")
config = config._replace(source_term_aware_timestep = True)
return config