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

Callbacks within CallbackSet interfering with each other #973

Open
cmdenis opened this issue Aug 7, 2023 · 0 comments
Open

Callbacks within CallbackSet interfering with each other #973

cmdenis opened this issue Aug 7, 2023 · 0 comments

Comments

@cmdenis
Copy link

cmdenis commented Aug 7, 2023

Hi,

I’m trying to use callbacks to create pulses to two identical systems ran through the same set of differential equations. It seems like putting the two Callbacks together results in the Callbacks somehow interfering with each other.

Here is a (somewhat) minimal working example:

Essentially, every time that the function sin(u[1]/2) hits 0, a pulse of a magnitude of 1 is created in u[2]. Similarly, every time that the function sin(u[3]/2) hits 0, a pulse of a magnitude of 1 is created in u[4]. I’m plotting the cosines of u[1] and u[3] to illustrate the timing of pulses.

using Plots, DifferentialEquations

# System of differential equations
function f(du, u, p, t)
    du[1] = 2*π*sqrt(u[2]) 
    du[2] = -u[2]
    du[3] = 2*π*sqrt(u[4]) 
    du[4] = -u[4]
end

# Parameters
p = []

# Initial Conditions
u0 = [0.00, 1.5, 0.0, 1.5]

# Callback 1
condition1(u,t,integrator) = sin(u[1]/2)
affect1!(integrator) = integrator.u[2] += 1
cb1 = ContinuousCallback(condition1, affect1!, save_positions=(false,false))

# Callback 2
condition2(u,t,integrator) = sin(u[3]/2)
affect2!(integrator) = integrator.u[4] += 1
cb2 = ContinuousCallback(condition2, affect2!, save_positions=(false,false))

# All Callbacks together
cbs = CallbackSet(cb1, cb2)

# Define problem
prob = ODEProblem(f, u0, (0, 20), p, callback = cbs)

# Solve problem
sol = solve(prob, saveat = 0.01)
tr = cat(sol.u..., dims = 2)

# Plotting
plot()
plot!(sol.t, cos.(tr[1, :]))
plot!(sol.t, (tr[2, :]))
plot!(sol.t, cos.(tr[3, :]))
plot!(sol.t, (tr[4, :]))

When running this, the solution kind of blows up and the two pairs of solutions that should be identical to each other start differing.

image

Something peculiar is that, when changing the initial conditions to u0 = [0.001, 1.5, 0.0, 1.5], for instance, the weird behavior stops. As if having the two pulses at the exact same time creates problems.

image

Furthermore, when running u[1]-u[2] separately from u[3]-u[4] (using two different systems altogether) this behavior stops.

Thanks!

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

1 participant