///|
pub(all) struct PlasmaBenchmarkCase {
name : String
cells : Int
particles : Int
steps : Int
initial_energy : Double
final_energy : Double
charge_error : Double
} derive(Debug, ToJson)
///|
pub(all) struct PlasmaBenchmarkReport {
cases : Array[PlasmaBenchmarkCase]
total_steps : Int
} derive(Debug, ToJson)
///|
fn make_pic_case(
name : String,
cells : Int,
particles : Int,
steps : Int,
) -> PlasmaBenchmarkCase {
let grid = Grid1D::new(cells, 1.0)
let initial = PicState::new(grid, two_stream_particles(particles, 1.0, 1.0e5))
let initial_energy = kinetic_energy(initial.particles) +
field_energy(initial.field)
let final_state = initial.run(1.0e-12, steps)
let final_energy = kinetic_energy(final_state.particles) +
field_energy(final_state.field)
{
name,
cells,
particles,
steps,
initial_energy,
final_energy,
charge_error: (total_particle_charge(final_state.particles) -
total_particle_charge(initial.particles)).abs(),
}
}
///|
fn make_landau_case() -> PlasmaBenchmarkCase {
let config = VlasovConfig::new(
Grid1D::new(32, 1.0),
velocity_min=-4.0,
velocity_max=4.0,
velocity_bins=32,
dt=0.001,
)
let initial = make_landau_initial(config, density0=1.0e12, thermal_speed=1.0)
let final_state = initial.step().step()
let initial_mass = distribution_sum(config, initial.distribution)
let final_mass = distribution_sum(config, final_state.distribution)
{
name: "landau-advection",
cells: config.grid.cells,
particles: config.velocity_bins,
steps: 2,
initial_energy: initial_mass,
final_energy: final_mass,
charge_error: (final_mass - initial_mass).abs(),
}
}
///|
pub fn run_plasma_benchmark_catalog() -> PlasmaBenchmarkReport {
let cases = [
make_pic_case("two-stream-small", 32, 64, 8),
make_pic_case("two-stream-medium", 64, 128, 16),
make_pic_case("two-stream-boundary", 16, 32, 4),
make_landau_case(),
]
let total_steps = cases.fold(init=0, fn(total, sample) {
total + sample.steps
})
{ cases, total_steps }
}
///|
pub fn benchmark_report_csv(report : PlasmaBenchmarkReport) -> String {
let out = StringBuilder::new()
out.write_string(
"name,cells,particles,steps,initial_energy,final_energy,charge_error\n",
)
for sample in report.cases {
out.write_string(
"\{sample.name},\{sample.cells},\{sample.particles},\{sample.steps},\{sample.initial_energy},\{sample.final_energy},\{sample.charge_error}\n",
)
}
out.to_string()
}