Question - ODE State at time of event #77
-
Hello Martin, I see that to detect events I need to provide a closure that has a zero crossing at the event and then I need to use the return value of OdeSolverMethod::step to check if an event has been detected. In the documentation for OdeSolverStopReason it states: In my case I would like to know both t_root and also the state at time t=t_root. Is there an easy way to obtain this information? I am sorry if this has an obvious answer, but I am new to the Rust programming language and it is not immediately obvious to me. Thanks, |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
Hi @JEMH, you can use If you are happy then continuing the integration from the internal time of the solver, then great :). However, if you wanted to restart from exactly the time of the event, then you would have to mutate the state (using Perhaps something like this (I havn't tried compiling/running this!) let t = loop {
match solver.step() {
Ok(OdeSolverStopReason::InternalTimestep) => continue,
Ok(OdeSolverStopReason::TstopReached) => panic!("We didn't set a stop time"),
Ok(OdeSolverStopReason::RootFound(t)) => break t,
Err(e) => panic!("Solver failed to converge: {}", e),
}
};
println!("Root found at t = {}", t);
let new_state = solver.interpolate(t).unwrap();
solver.state_mut().unwrap().y.copy_from(&new_state);
*solver.state_mut().unwrap().t = t;
solver.step(); Note that this is inefficient for some solvers (the BDF one) as it needs to be re-initialised after the call to |
Beta Was this translation helpful? Give feedback.
-
note I've just put together some docs on this: https://martinjrobins.github.io/diffsol/solving_the_problem.html |
Beta Was this translation helpful? Give feedback.
-
Thank you for taking the time to answer my question and providing a clear answer.
Using your draft code I was able to obtain the state at the event time and then propagate further.
The only change that I needed to make to the draft code was to replace the line
solver.state_mut().unwrap().copy_from(&new_state);
with the two lines
solver.state_mut().unwrap().y.copy_from(&new_state);
solver.state_mut().unwrap().dy.copy_from(&new_state);
The additional documentation „Solving the Problem“ is also very helpful.
Regards,
James
… Am 18.07.2024 um 20:37 schrieb Martin Robinson ***@***.***>:
note I've just put together some docs on this: https://martinjrobins.github.io/diffsol/solving_the_problem.html
—
Reply to this email directly, view it on GitHub <#74 (comment)>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ABQRDKQSB4BDQVQJU4OXCELZNADNTAVCNFSM6AAAAABLCWFH66VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDEMZXGI2DSOJYGY>.
You are receiving this because you were mentioned.
|
Beta Was this translation helpful? Give feedback.
Hi @JEMH, you can use
OdeSolverMethod::interpolate
to get the state vector at the time of the event (i.e.t_root
).If you are happy then continuing the integration from the internal time of the solver, then great :). However, if you wanted to restart from exactly the time of the event, then you would have to mutate the state (using
OdeSolverMethod::state_mut
) and set it to the interpolated state.Perhaps something like this (I havn't tried compiling/running this!)