SciML / diffeqpy

Solving differential equations in Python using DifferentialEquations.jl and the SciML Scientific Machine Learning organization
MIT License
508 stars 39 forks source link

TypeError on DiscreteCallback #136

Closed max-de-rooij closed 4 months ago

max-de-rooij commented 4 months ago

Describe the bug 🐞

When trying callbacks using diffeqpy, I stumbled upon the issue that my condition cannot be evaluated on the solve call.

Expected behavior

The expected behaviour is that the callback condition can be evaluated and that my solution will compute.

Minimal Reproducible Example 👇

from diffeqpy import ode

def simple_system_b(du, u, p, t):
  du[0] = -1*p[0]*u[0]

def condition(u, t, integrator):
  return t == 0.5

def affect_b(integrator):
  integrator.u[0] += 10

cb = ode.DiscreteCallback(
  condition, affect_b
)

prob = ode.ODEProblem(simple_system_b, [1.], (0.,10.), [0.2])
sol = ode.solve(prob, ode.Tsit5(), callback=cb, tstops=0.5)

Error & Stacktrace ⚠️

---------------------------------------------------------------------------
JuliaError                                Traceback (most recent call last)
Cell In[406], [line 17](vscode-notebook-cell:?execution_count=406&line=17)
     [12](vscode-notebook-cell:?execution_count=406&line=12) cb = ode.DiscreteCallback(
     [13](vscode-notebook-cell:?execution_count=406&line=13)   condition, affect_b
     [14](vscode-notebook-cell:?execution_count=406&line=14) )
     [16](vscode-notebook-cell:?execution_count=406&line=16) prob = ode.ODEProblem(simple_system_b, [1.], (0.,10.), [0.2])
---> [17](vscode-notebook-cell:?execution_count=406&line=17) sol = ode.solve(prob, ode.Tsit5(), callback=cb)
     [19](vscode-notebook-cell:?execution_count=406&line=19) #plt.plot(np.linspace(0,10,100), sol(np.linspace(0,10,100))[0,:])

File [~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:208](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:208), in __call__(self, *args, **kwargs)
    [206](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:206)     return ValueBase.__dir__(self) + self._jl_callmethod($(pyjl_methodnum(pyjlany_dir)))
    [207](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:207) def __call__(self, *args, **kwargs):
--> [208](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:208)     return self._jl_callmethod($(pyjl_methodnum(pyjlany_call)), args, kwargs)
    [209](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:209) def __bool__(self):
    [210](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:210)     return True

JuliaError: TypeError: non-boolean (Py) used in boolean context
Stacktrace:
  [1] apply_discrete_callback!
    @ [~/.julia/packages/DiffEqBase/SlYdg/src/callbacks.jl:596](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/DiffEqBase/SlYdg/src/callbacks.jl:596) [inlined]
  [2] handle_callbacks!(integrator::Any)
    @ OrdinaryDiffEq [~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/integrators/integrator_utils.jl:340](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/integrators/integrator_utils.jl:340) [inlined]
  [3] _loopfooter!(integrator::OrdinaryDiffEq.ODEIntegrator{OrdinaryDiffEq.Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, true, Vector{Float64}, Nothing, Float64, PyList{Any}, Float64, Float64, Float64, Float64, Vector{Vector{Float64}}, SciMLBase.ODESolution{Float64, 2, Vector{Vector{Float64}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{Vector{Float64}}}, SciMLBase.ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, PyList{Any}, SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{Float64}, Vector{Float64}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}}, false}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, @Kwargs{}, SciMLBase.StandardODEProblem}, OrdinaryDiffEq.Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, OrdinaryDiffEq.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{Float64}, Vector{Float64}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}}, false}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Vector{Vector{Float64}}, Vector{Float64}, Vector{Vector{Vector{Float64}}}, OrdinaryDiffEq.Tsit5Cache{Vector{Float64}, Vector{Float64}, Vector{Float64}, typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}}, SciMLBase.DEStats, Nothing}, SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{Float64}, Vector{Float64}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}}, false}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, OrdinaryDiffEq.Tsit5Cache{Vector{Float64}, Vector{Float64}, Vector{Float64}, typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, OrdinaryDiffEq.DEOptions{Float64, Float64, Float64, Float64, OrdinaryDiffEq.PIController{Rational{Int64}}, typeof(DiffEqBase.ODE_DEFAULT_NORM), typeof(LinearAlgebra.opnorm), Nothing, SciMLBase.CallbackSet{Tuple{}, Tuple{SciMLBase.DiscreteCallback{Py, Py, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), DataStructures.BinaryHeap{Float64, DataStructures.FasterForward}, DataStructures.BinaryHeap{Float64, DataStructures.FasterForward}, Nothing, Nothing, Int64, Tuple{}, Tuple{}, Tuple{}}, Vector{Float64}, Float64, Nothing, OrdinaryDiffEq.DefaultInit})
    @ OrdinaryDiffEq [~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/integrators/integrator_utils.jl:247](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/integrators/integrator_utils.jl:247)
  [4] loopfooter!
    @ [~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/integrators/integrator_utils.jl:200](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/integrators/integrator_utils.jl:200) [inlined]
  [5] solve!(integrator::OrdinaryDiffEq.ODEIntegrator{OrdinaryDiffEq.Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, true, Vector{Float64}, Nothing, Float64, PyList{Any}, Float64, Float64, Float64, Float64, Vector{Vector{Float64}}, SciMLBase.ODESolution{Float64, 2, Vector{Vector{Float64}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{Vector{Float64}}}, SciMLBase.ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, PyList{Any}, SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{Float64}, Vector{Float64}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}}, false}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, @Kwargs{}, SciMLBase.StandardODEProblem}, OrdinaryDiffEq.Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, OrdinaryDiffEq.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{Float64}, Vector{Float64}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}}, false}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, Vector{Vector{Float64}}, Vector{Float64}, Vector{Vector{Vector{Float64}}}, OrdinaryDiffEq.Tsit5Cache{Vector{Float64}, Vector{Float64}, Vector{Float64}, typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}}, SciMLBase.DEStats, Nothing}, SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{Float64}, Vector{Float64}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}}, false}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, OrdinaryDiffEq.Tsit5Cache{Vector{Float64}, Vector{Float64}, Vector{Float64}, typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}, OrdinaryDiffEq.DEOptions{Float64, Float64, Float64, Float64, OrdinaryDiffEq.PIController{Rational{Int64}}, typeof(DiffEqBase.ODE_DEFAULT_NORM), typeof(LinearAlgebra.opnorm), Nothing, SciMLBase.CallbackSet{Tuple{}, Tuple{SciMLBase.DiscreteCallback{Py, Py, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT)}}}, typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), DataStructures.BinaryHeap{Float64, DataStructures.FasterForward}, DataStructures.BinaryHeap{Float64, DataStructures.FasterForward}, Nothing, Nothing, Int64, Tuple{}, Tuple{}, Tuple{}}, Vector{Float64}, Float64, Nothing, OrdinaryDiffEq.DefaultInit})
    @ OrdinaryDiffEq [~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/solve.jl:539](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/solve.jl:539)
  [6] #__solve#746
    @ [~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/solve.jl:6](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/solve.jl:6) [inlined]
  [7] __solve
    @ [~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/solve.jl:1](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/OrdinaryDiffEq/Y6bIX/src/solve.jl:1) [inlined]
  [8] solve_call(_prob::SciMLBase.ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, PyList{Any}, SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, FunctionWrappersWrappers.FunctionWrappersWrapper{Tuple{FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{Float64}, Vector{Float64}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, Float64}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{Float64}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}, FunctionWrappers.FunctionWrapper{Nothing, Tuple{Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, Vector{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}, PyList{Any}, ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.OrdinaryDiffEqTag, Float64}, Float64, 1}}}}, false}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, @Kwargs{}, SciMLBase.StandardODEProblem}, args::OrdinaryDiffEq.Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}; merge_callbacks::Bool, kwargshandle::Nothing, kwargs::@Kwargs{callback::SciMLBase.DiscreteCallback{Py, Py, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT)}})
    @ DiffEqBase [~/.julia/packages/DiffEqBase/SlYdg/src/solve.jl:561](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/DiffEqBase/SlYdg/src/solve.jl:561)
  [9] solve_up(prob::SciMLBase.ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, PyList{Any}, SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, ComposedFunction{typeof(SciMLBasePythonCallExt._pyconvert), Py}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, @Kwargs{}, SciMLBase.StandardODEProblem}, sensealg::Nothing, u0::Vector{Float64}, p::PyList{Any}, args::OrdinaryDiffEq.Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}; kwargs::@Kwargs{callback::SciMLBase.DiscreteCallback{Py, Py, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT)}})
    @ DiffEqBase [~/.julia/packages/DiffEqBase/SlYdg/src/solve.jl:1010](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/DiffEqBase/SlYdg/src/solve.jl:1010)
 [10] solve_up
    @ [~/.julia/packages/DiffEqBase/SlYdg/src/solve.jl:996](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/DiffEqBase/SlYdg/src/solve.jl:996) [inlined]
 [11] solve(prob::SciMLBase.ODEProblem{Vector{Float64}, Tuple{Float64, Float64}, true, PyList{Any}, SciMLBase.ODEFunction{true, SciMLBase.AutoSpecialize, ComposedFunction{typeof(SciMLBasePythonCallExt._pyconvert), Py}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Nothing}, @Kwargs{}, SciMLBase.StandardODEProblem}, args::OrdinaryDiffEq.Tsit5{typeof(OrdinaryDiffEq.trivial_limiter!), typeof(OrdinaryDiffEq.trivial_limiter!), Static.False}; sensealg::Nothing, u0::Nothing, p::Nothing, wrap::Val{true}, kwargs::@Kwargs{callback::SciMLBase.DiscreteCallback{Py, Py, typeof(SciMLBase.INITIALIZE_DEFAULT), typeof(SciMLBase.FINALIZE_DEFAULT)}})
    @ DiffEqBase [~/.julia/packages/DiffEqBase/SlYdg/src/solve.jl:933](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/DiffEqBase/SlYdg/src/solve.jl:933)
 [12] pyjlany_call(self::typeof(CommonSolve.solve), args_::Py, kwargs_::Py)
    @ PythonCall [~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:34](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/PythonCall/wXfah/src/jlwrap/any.jl:34)
 [13] _pyjl_callmethod(f::Any, self_::Ptr{PythonCall.C.PyObject}, args_::Ptr{PythonCall.C.PyObject}, nargs::Int64)
    @ PythonCall [~/.julia/packages/PythonCall/wXfah/src/jlwrap/base.jl:69](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/PythonCall/wXfah/src/jlwrap/base.jl:69)
 [14] _pyjl_callmethod(o::Ptr{PythonCall.C.PyObject}, args::Ptr{PythonCall.C.PyObject})
    @ PythonCall.C [~/.julia/packages/PythonCall/wXfah/src/cpython/jlwrap.jl:47](https://file+.vscode-resource.vscode-cdn.net/Users/max/TUe/8bm050-dev/notebooks/~/.julia/packages/PythonCall/wXfah/src/cpython/jlwrap.jl:47)

Additional context

When I modify my condition using ode.seval(), it does work, which made me think it had something to do with the condition in this case:

from diffeqpy import ode

def simple_system_b(du, u, p, t):
  du[0] = -1*p[0]*u[0]

# def condition(u, t, integrator):
#   return t == 0.5
condition = ode.seval(
  """
  function condition(u, t, integrator)
    t == 0.5
  end
  """
)

def affect_b(integrator):
  integrator.u[0] += 10

cb = ode.DiscreteCallback(
  condition, affect_b
)

prob = ode.ODEProblem(simple_system_b, [1.], (0.,10.), [0.2])
sol = ode.solve(prob, ode.Tsit5(), callback=cb, tstops=0.5)

Which works fine.

ChrisRackauckas commented 4 months ago

@LilithHafner This seems like it's due to a conversion missing. Did you look into Bools? I would've assumed Bools would be something that auto-converts?

LilithHafner commented 4 months ago

Almost nothing auto-converts in PythonCall, which is why we wrap all Python functions passed in with pyconvert. I imagine the issue is that we missed that wrapper on conditions.