use clap::Args;
use anyhow::bail;
use anyhow::Result;
use ff_kinetics::Arrhenius;
#[derive(Debug, Args)]
pub struct RateModelArguments {
#[arg(long, default_value_t = 1e5)]
pub k0: f64,
#[arg(long)]
pub k3ws: Option<f64>,
#[arg(long)]
pub k4ws: Option<f64>,
}
impl RateModelArguments {
pub fn build_model(&self, celsius: f64) -> Arrhenius {
Arrhenius::new(celsius, self.k0, self.k3ws, self.k4ws)
}
}
#[derive(Debug, Args)]
pub struct TimelineParameters {
#[arg(long, default_value_t = 0.04)]
pub t_ext: f64,
#[arg(long, default_value_t = 1.0)]
pub t_end: f64,
#[arg(long, default_value_t = 100)]
pub t_lin: usize,
#[arg(long, default_value_t = 100)]
pub t_log: usize,
}
impl TimelineParameters {
pub fn validate(&self) -> Result<()> {
if self.t_end <= self.t_ext {
bail!("t_end ({}) must be greater than t_ext ({})", self.t_end, self.t_ext);
}
if self.t_lin == 0 && self.t_log > 1 {
bail!("t_lin must be > 0 if t_log > 1 (got t_lin={}, t_log={})", self.t_lin, self.t_log);
}
Ok(())
}
pub fn get_output_times(&self) -> Vec<f64> {
let t_end = self.t_end;
let t_ext = self.t_ext;
let t_lin = self.t_lin;
let t_log = self.t_log;
let mut times = vec![0.0];
let start = *times.last().unwrap();
let step = t_ext / t_lin as f64;
for i in 1..=t_lin {
times.push(start + i as f64 * step);
}
let start = *times.last().unwrap();
let log_start = start.ln();
let log_end = t_end.ln();
for i in 1..t_log {
let frac = i as f64 / t_log as f64;
let value = (log_start + frac * (log_end - log_start)).exp();
times.push(value);
}
times.push(t_end);
times
}
}