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

Allowing affect! to set values on a time interval instead of at a time point #245

Open
WenyinWei opened this issue Dec 25, 2024 · 5 comments

Comments

@WenyinWei
Copy link

WenyinWei commented Dec 25, 2024

Is your feature request related to a problem? Please describe.

Hi, everyone, DifferentialEquations.jl is awesome and efficient. I am trying to implement an affect! function to set values u[i] on a time interval instead of a single time point so that the delay differential equation module can work when I introduce, during integration, new particles whose history can be set by the callback function. Thanks a lot if you can consider making it possible to allow an affect! function to influence the state values of an integrator on a time interval, or if you have any other elegant workarounds to solving this.

Describe the solution you’d like

Instead of setting values only at one time point by a usual affect! function,

function affect!(integrator)
    integrator.u[2] = -integrator.u[2]
end

set its values for a whole time interval:

function affect!(integrator)
    #  here integrator is a DDE one (delay differential equation integrator) or others
    for integrator.t in a custom time span, e.g. [the timepoint of callback - 1.0, the timepoint of callback]:
        integrator.u .= (some custom function)
    end
end

Describe alternatives you’ve considered

Repeatedly invoke a one-time affect! in the time interval, but this probably has too much overhead.

@ChrisRackauckas
Copy link
Member

I am not sure this is going to be possible. I can see why you'd want that for a DDE solver, but by the design the history needs to be "correct". You would need to set the affect! to change u0 at the starting part of the time span, and enforce that the solution makes u equal to that custom function. Otherwise it's not technically a well-defined DAE?

@WenyinWei
Copy link
Author

Hi Chris, nice to see your response. This may be a relatively niche feature need. I can relax the requirement on the accuracy of such "history" by only adding new particles at the edge of a moving (box or sphere) frame with a particle centred at the origin. High accuracy is required only for those particles near the center of this frame so that the code can simulate the long-term behaviour of one particle without frequently enter-/exiting the computation domain. The inaccuracy due to edge particles shall be comparatively tolerable.

  1. One option I can come up with is to hack DDE implementation to trigger, at the injection time t_inj, modifying the past trajectory in the time interval [t_inj - Δt, t_inj].
  2. Or frequently invoke DiscreteCallback in the time interval [t_inj - Δt, t_inj] to set the trajectories of new particles from NaN to some values that make sense but do not need to be 100% correct.
  3. DiscreteCallback + reinit might cost too much time due to the enormous amount of particles narrowly missing the central one due to its high speed.

Thanks again and I can understand this may not be a wide-spread need from users, but it can definitely help understand N-body particle dynamics.

@ChrisRackauckas
Copy link
Member

One option I can come up with is to hack DDE implementation to trigger, at the injection time t_inj, modifying the past trajectory in the time interval [t_inj - Δt, t_inj].

The history though is the solution object. You cannot modify the history without changing the actual solution.

Or frequently invoke DiscreteCallback in the time interval [t_inj - Δt, t_inj] to set the trajectories of new particles from NaN to some values that make sense but do not need to be 100% correct.

I think what you're saying then is what you want to do is resize! the integrator to add new ODEs, and on those you want to define their history directly? In theory that's possible because the history of any new ODE is undefined. But right now this would not be easy to implement.

@WenyinWei
Copy link
Author

I try to preallocate more variables than the initial particles need with these abundant variable values set to be NaN. Can I get rid of too frequent reinit the ODE system in this way? Of course the solution itself is allowed to change for this purpose.

@ChrisRackauckas
Copy link
Member

I try to preallocate more variables than the initial particles need with these abundant variable values set to be NaN.

That would likely cause an issue in the adaptivity. But if you pass a non-standard internalnorm function that drops the NaNs, it should work.

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

No branches or pull requests

2 participants