Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make error check more compatible with SciML interface #896

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

termi-official
Copy link
Contributor

This will require some changed in many downstream packages. The main issue for now is that SciMLBase.last_step_failed never returns true if the integrator is adaptive.

Comment on lines +421 to +423
function get_retcode(integrator::DEIntegrator)
return integrator.sol.retcode
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To quickly elaborate on this, I essentially have problems where "time sub-integrators" advance parts of the solution and I could not find a sane way to define this distributed solution stuff into the current solution interface. Technically I do not even need every subintegrator to hold a solution. They just need to communicate return codes between each other. Having this interface here would be a compromise.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most integrators don't set the return code until the end though?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct. But for operator splitting methods I have essentially a tree of integrators, each solving subproblems on small time intervals. The easiest example is essentially to have an additivley split right hand side for some ODE:

$d_t u = f(u,p,t) = f_1(u,p,t) + f_2(u,p,t)$

which I want to integrate from [0,T]. Operator splitting method now definine two ODEs

$d_t u^* = f_1(u^*,p,t)$

and

$d_t u^{} = f_2(u^{},p,t)$

and they intrgrate each of these in a specific order on subintervals on $[0,T]$. The simplest rule is to solve them alternatingly on intervals with fixed dt. E.g. the first step would be

  1. Set $u^*(0) = u_0$
  2. Solve $d_t u^* = f_1(u^*,p,t)$ on $[0,dt]$ (with your algorithm of choice)
  3. Set $u^{**}(0) = u^*(dt)$
  4. Solve $d_t u^{} = f_2(u^{},p,t)$ on $[0,dt]$ (with your algorithm of choice)

In my implementation right now I have three separate integrators. One custom time integrator for the coordination of which subintegrator needs to integrate its associated problem next (+ time step controll of the time intervals to solve the subproblems on), and another two integrators for the respective subproblems. To check whether a solve worked or not the outer time integrator essentially checks the inner integrators return code after each solve of the subproblems. Does this explain it?

Probably not the best architecture, but at least it is functional.

Comment on lines +584 to +590
function controller_message_on_dtmin_error(integrator::DEIntegrator)
if isdefined(integrator, :EEst)
return ", and step error estimate = $(integrator.EEst)"
else
return ""
end
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some voodoo time adaption algorithms actually work without defining an error estimate, so I would like to remove the dependency that the integrator itself needs to carry the error estimate and would like to propose in the future that there is either some kind of ControllerCache or the contoller itself carries the estimate.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah... that's going to be rough because there needs to be a tie-in in every stepper for how to calculate and store EEst, if it's needed. I'm not opposed though, because yes some methods like a priori estimates don't need the EEst and so it shouldn't spend the time to calculate it.

(!step_accepted || (hasproperty(opts, :tstops) ?
integrator.t + integrator.dt < integrator.tdir * first(opts.tstops) :
true))
step_rejected = last_step_failed(integrator)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now this does not work, as last_step_failed is always false if the integrator is adaptive. If everyone agrees that this is closer to the semantics that we really want, then I will go through all subpackages and make the corresponding change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this could be reasonable.

Co-authored-by: Dennis Ogiermann <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants