185 lines
4.7 KiB
Rust
185 lines
4.7 KiB
Rust
use argh::FromArgs;
|
|
|
|
use sbp::*;
|
|
|
|
mod eval;
|
|
mod input;
|
|
mod parsing;
|
|
mod system;
|
|
|
|
#[derive(Debug, FromArgs)]
|
|
/// Options for configuring and running the solver
|
|
struct CliOptions {
|
|
#[argh(positional)]
|
|
json: std::path::PathBuf,
|
|
/// name of output file
|
|
#[argh(
|
|
option,
|
|
short = 'o',
|
|
default = "std::path::PathBuf::from(\"output.hdf\")"
|
|
)]
|
|
output: std::path::PathBuf,
|
|
/// number of outputs to save
|
|
#[argh(option, short = 'n')]
|
|
number_of_outputs: Option<u64>,
|
|
/// print the time to complete, taken in the compute loop
|
|
#[argh(switch)]
|
|
timings: bool,
|
|
/// print error at the end of the run
|
|
#[argh(switch)]
|
|
error: bool,
|
|
/// disable the progressbar
|
|
#[argh(switch)]
|
|
no_progressbar: bool,
|
|
/// output information regarding time elapsed and error
|
|
/// in json format
|
|
#[argh(switch)]
|
|
output_json: bool,
|
|
/// distribute the computation on multiple threads
|
|
#[argh(switch)]
|
|
distribute: bool,
|
|
}
|
|
|
|
#[derive(Default, serde::Serialize)]
|
|
struct OutputInformation {
|
|
filename: std::path::PathBuf,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
time_elapsed: Option<std::time::Duration>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
error: Option<Float>,
|
|
}
|
|
|
|
fn main() {
|
|
let opt: CliOptions = argh::from_env();
|
|
let filecontents = std::fs::read_to_string(&opt.json).unwrap();
|
|
|
|
let config: input::Configuration = match json5::from_str(&filecontents) {
|
|
Ok(config) => config,
|
|
Err(e) => {
|
|
eprintln!("Configuration could not be read: {}", e);
|
|
if let json5::Error::Message {
|
|
location: Some(location),
|
|
..
|
|
} = e
|
|
{
|
|
eprintln!("\t{:?}", location);
|
|
}
|
|
return;
|
|
}
|
|
};
|
|
let parsing::RuntimeConfiguration {
|
|
names,
|
|
grids,
|
|
boundary_conditions,
|
|
op: operators,
|
|
integration_time,
|
|
initial_conditions,
|
|
} = config.into_runtime();
|
|
|
|
let basesystem = system::BaseSystem::new(
|
|
names,
|
|
grids,
|
|
0.0,
|
|
operators,
|
|
boundary_conditions,
|
|
initial_conditions,
|
|
opt.output.clone(),
|
|
);
|
|
|
|
let mut sys = if opt.distribute {
|
|
basesystem.create_distributed()
|
|
} else {
|
|
basesystem.create()
|
|
};
|
|
|
|
let dt = sys.max_dt();
|
|
sys.set_dt(dt);
|
|
let ntime = (integration_time / dt).round() as u64;
|
|
let steps_between_outputs = if let Some(n) = opt.number_of_outputs {
|
|
std::cmp::max(n / ntime, 1)
|
|
} else {
|
|
ntime
|
|
};
|
|
|
|
sys.output(0);
|
|
|
|
if !opt.no_progressbar {
|
|
sys.add_progressbar(ntime)
|
|
}
|
|
|
|
let timer = if opt.timings {
|
|
Some(std::time::Instant::now())
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let mut itime = 0;
|
|
while itime < ntime {
|
|
sys.advance(steps_between_outputs);
|
|
|
|
itime += steps_between_outputs;
|
|
sys.output(itime);
|
|
}
|
|
if itime != ntime {
|
|
sys.advance(ntime - itime);
|
|
sys.output(ntime);
|
|
}
|
|
|
|
if !opt.no_progressbar {
|
|
sys.finish_progressbar();
|
|
}
|
|
|
|
let mut outinfo = OutputInformation {
|
|
filename: opt.output,
|
|
..Default::default()
|
|
};
|
|
|
|
if let Some(timer) = timer {
|
|
let duration = timer.elapsed();
|
|
outinfo.time_elapsed = Some(duration);
|
|
}
|
|
|
|
//output.add_timestep(ntime, &sys.fnow);
|
|
|
|
/*
|
|
if opt.error {
|
|
let time = ntime as Float * dt;
|
|
let mut e = 0.0;
|
|
for ((fmod, grid), op) in sys.fnow.iter().zip(&sys.grids).zip(&sys.operators) {
|
|
let mut fvort = fmod.clone();
|
|
match &initial_conditions {
|
|
parsing::InitialConditions::Vortex(vortexparams) => {
|
|
fvort.vortex(grid.x(), grid.y(), time, &vortexparams);
|
|
}
|
|
parsing::InitialConditions::Expressions(expr) => {
|
|
let (rho, rhou, rhov, e) = fvort.components_mut();
|
|
expr.as_ref()
|
|
.evaluate(time, grid.x(), grid.y(), rho, rhou, rhov, e)
|
|
}
|
|
}
|
|
e += fmod.h2_err(&fvort, &**op);
|
|
}
|
|
outinfo.error = Some(e);
|
|
}
|
|
*/
|
|
|
|
if opt.output_json {
|
|
println!("{}", json5::to_string(&outinfo).unwrap());
|
|
} else {
|
|
if let Some(duration) = outinfo.time_elapsed {
|
|
println!("Time elapsed: {} seconds", duration.as_secs_f64());
|
|
}
|
|
if let Some(error) = outinfo.error {
|
|
println!("Total error: {:e}", error);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn progressbar(ntime: u64) -> indicatif::ProgressBar {
|
|
let progressbar = indicatif::ProgressBar::new(ntime);
|
|
progressbar.with_style(
|
|
indicatif::ProgressStyle::default_bar()
|
|
.template("{wide_bar:.cyan/blue} {pos}/{len} ({eta})"),
|
|
)
|
|
}
|