use alloc::format;
use crate::solvers::dec::step_output::{RunOutput, StepOutput};
use deep_causality_physics::PhysicsError;
use deep_causality_physics::SolenoidalField;
use super::DecNsSolver;
use crate::solvers::dec::DecNsScalar;
impl<const D: usize, R: DecNsScalar> DecNsSolver<'_, D, R> {
pub fn run_n(
&self,
initial: SolenoidalField<R>,
n: usize,
) -> Result<RunOutput<R>, PhysicsError> {
let mut state = initial;
for i in 1..=n {
state = self
.step(&state)
.map_err(|e| Self::at_step(i, e))?
.into_state();
}
Ok(RunOutput::new(state, n, true))
}
pub fn run_until<P>(
&self,
initial: SolenoidalField<R>,
mut predicate: P,
max_steps: usize,
) -> Result<RunOutput<R>, PhysicsError>
where
P: FnMut(usize, &StepOutput<R>) -> bool,
{
let mut state = initial;
for i in 1..=max_steps {
let output = self.step(&state).map_err(|e| Self::at_step(i, e))?;
if predicate(i, &output) {
return Ok(RunOutput::new(output.into_state(), i, true));
}
state = output.into_state();
}
Ok(RunOutput::new(state, max_steps, false))
}
fn at_step(index: usize, e: PhysicsError) -> PhysicsError {
PhysicsError::CalculationError(format!("march failed at step {index}: {e}"))
}
}