What does "user_cache: method has not been implemented for the integrator" mean?

I have been working through the example of a Discrete Callback that I need to adapt for my code but Atom generates an error. I cannot find a definition of user_cache so I need your help. I am an introductory Julia user using Julia v.1, on Windows 10 and have updated all packages.

The error is:

user_cache: method has not been implemented for the integrator

The example code is

using DifferentialEquations
mutable struct SimType{T} <: DEDataVector{T}
    x::Array{T,1}
    f1::T
end
function f(du,u,p,t)
    du[1] = -0.5*u[1] + u.f1
    du[2] = -0.5*u[2]
end
const tstop1 = [5.]
const tstop2 = [8.]

function condition(u,t,integrator)
  t in tstop1
end

function condition2(u,t,integrator)
  t in tstop2
end
function affect!(integrator)
  for c in user_cache(integrator)
    c.f1 = 1.5
  end
end

function affect2!(integrator)
  for c in user_cache(integrator)
    c.f1 = -1.5
  end
end
save_positions = (true,true)

cb = DiscreteCallback(condition, affect!, save_positions=save_positions)

save_positions = (false,true)

cb2 = DiscreteCallback(condition2, affect2!, save_positions=save_positions)

cbs = CallbackSet(cb,cb2)
u0 = SimType([10.0;10.0], 0.0)
prob = ODEProblem(f,u0,(0.0,10.0))
const tstop = [5.;8.]
sol = solve(prob,Tsit5(),callback = cbs, tstops=tstop)

I need to understand what is happening so I can put a callback into my code.

Those docs need to be updated. It should be full_cache now.

There’s problems with that approach, though. First, when using autodiff, the type constraint on the “user-defined” fields of the data do not match, i.e. only one of the fields is a dual at a time. So, using e.g. Trapezoid() instead of Tsit5 as solver, I get the error:

MethodError: no method matching SimType(::Array{ForwardDiff.Dual{ForwardDiff.Tag{DiffEqBase.UJacobianWrapper{ODEFunction{true,typeof(f),LinearAlgebra.UniformScaling{Bool},Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing,Nothing},Float64,DiffEqBase.NullParameters},Float64}(),Float64,2},1}, ::Float64)
Closest candidates are:
  SimType(::Array{T,1}, !Matched::T) where T ... 

I remember there is a way of solving this, I read it somewhere some time ago. But, IMO, that’s rather complicated for a “standard user”. Is there any better way?

Ok, so let’s turn off autodiff by using Trapezoid(autodiff=false). I then get:

MethodError: no method matching SimType(::Array{Float64,2}, ::Float64)
Closest candidates are:
  SimType(!Matched::Array{T,1}, ::T) where T ... 

So, somehow, this (and many other solvers) try to initialise a 2D array…?

You can do https://docs.sciml.ai/latest/basics/faq/#I-get-Dual-number-errors-when-I-solve-my-ODE-with-Rosenbrock-or-SDIRK-methods-1 , but that’s a very different issue. I think the issue of how to handle explicit algebraic variables is much deeper, and I’ll respond in your other thread.

Updated: https://diffeq.sciml.ai/latest/basics/faq/#I-get-Dual-number-errors-when-I-solve-my-ODE-with-Rosenbrock-or-SDIRK-methods-1