///|
pub(all) struct PicConfig {
grid : Grid1D
dt : Double
steps : Int
shape : ShapeKind
boundary : Boundary1D
} derive(Debug, ToJson)
///|
pub fn PicConfig::new(grid : Grid1D, dt : Double, steps : Int) -> PicConfig {
{ grid, dt, steps: steps.max(0), shape: CIC, boundary: Periodic }
}
///|
pub fn PicConfig::validate(config : PicConfig) -> ValidationReport {
let grid_report = validate_grid(config.grid.cells, config.grid.length)
if !grid_report.valid {
grid_report
} else if config.dt <= 0.0 {
invalid_report("dt", "time step must be positive", config.dt)
} else {
validate_count(config.steps + 1, "steps")
}
}
///|
pub fn PicConfig::with_shape(
config : PicConfig,
shape : ShapeKind,
) -> PicConfig {
{ ..config, shape, }
}
///|
pub fn PicConfig::with_boundary(
config : PicConfig,
boundary : Boundary1D,
) -> PicConfig {
{ ..config, boundary, }
}
///|
pub fn pic_config_summary(config : PicConfig) -> String {
"cells=\{config.grid.cells}\nlength=\{config.grid.length}\ndt=\{config.dt}\nsteps=\{config.steps}\nshape=\{shape_name(config.shape)}\n"
}
///|
pub(all) struct SamplingConfig {
count : Int
seed : Int
drift : Double
spread : Double
profile : Profile1D
} derive(Debug, ToJson)
///|
pub fn SamplingConfig::new(
count : Int,
seed : Int,
drift : Double,
spread : Double,
) -> SamplingConfig {
{
count: count.max(0),
seed,
drift,
spread: spread.max(0.0),
profile: profile_constant(1.0),
}
}
///|
pub fn SamplingConfig::validate(config : SamplingConfig) -> ValidationReport {
if config.count < 0 {
invalid_report(
"count",
"sample count cannot be negative",
config.count.to_double(),
)
} else {
validate_non_negative(config.spread, "spread")
}
}
///|
pub fn SamplingConfig::sample(
config : SamplingConfig,
grid : Grid1D,
) -> Array[Particle] {
sample_particles(grid, config.count, config.seed, config.drift, config.spread)
}
///|
pub fn sampling_config_summary(config : SamplingConfig) -> String {
"count=\{config.count}\nseed=\{config.seed}\ndrift=\{config.drift}\nspread=\{config.spread}\n"
}
///|
pub fn validate_simulation_inputs(
grid : Grid1D,
dt : Double,
particles : Int,
steps : Int,
) -> ValidationReport {
let grid_report = validate_grid(grid.cells, grid.length)
if !grid_report.valid {
grid_report
} else if dt <= 0.0 {
invalid_report("dt", "time step must be positive", dt)
} else if particles < 0 {
invalid_report(
"particles",
"particle count cannot be negative",
particles.to_double(),
)
} else {
validate_count(steps + 1, "steps")
}
}
///|
pub fn config_to_csv(config : PicConfig) -> String {
"field,value\n\ncells,\{config.grid.cells}\nlength,\{config.grid.length}\ndt,\{config.dt}\nsteps,\{config.steps}\nshape,\{shape_name(config.shape)}\n"
}