I want to solve an ODE problem involving some piecewise functions and I would like to ask for advice on what could be the best strategy to solve them.
Physically, the ODEs I want to solve represent a contact element sticking and sliding according to Coulomb’s friction law and with variable normal load. The code for the forces is the following
using OrdinaryDiffEq, Plots
normal(xn) = xn > 0.0 ? xn : 0.0
function tangential!(w, xt, N)
w_init = w[1]
if (N > 0.0) && (abs(xt - w_init) < N)
T = xt - w_init
return T
elseif (N > 0.0) && (abs(xt - w_init) ≥ N)
sg = sign(xt - w_init)
@. w = xt - sg * N
T = sg * N
return T
else
@. w = xt
T = 0.0
return T
end
end
where w
is a mutating 1-element vector that takes into account the “memory” of the friction state. Then, the ODE is defined and solved as
function f!(du, u, p, t)
w = p
N = normal(u[2])
T = tangential!(w, u[1], N)
du[1] = u[3]
du[2] = u[4]
du[3] = 0.75sin(t) - T
du[4] = -N + 0.5
end
begin
u0 = [0.0, 2.0, 0.0, 0.0]
p = [0.0]
tspan = (0, 40π)
prob = ODEProblem(f!, u0, tspan, p)
sol = solve(prob, Midpoint())
plot(sol)
end
where the Midpoint method has been used. The idea is to find the best strategy to solve this simple problem to, in the end, use multiple of these contacts in a more complex setup. I have thought of the following strategies using the OrdinaryDiffEq package:
- Low order explicit methods
- High order explicit methods using callbacks
- Implicit methods
The use of low order explicit methods is easy to implement since the code above just runs perfectly.
High order explicit methods cannot be used directly, since our function does not have continuous derivatives. Therefore, the only way I can see the use of a high order scheme is to add callbacks to the problem. Using callbacks I could stop the integration when we move from one section to the piecewise function to another and, since each section is infinitely differentiable, the use of high order schemes could give good results.
Finally, I found that I could only make implicit methods work by implementing them myself specifically suited for this problem. If I try to execute an implicit scheme with my system I get errors when it tries to automatically differentiate, which I suspect is expected due to the mutations that are going on in my function. Therefore, I do not know if using an implicit method is viable in my problem with the interface of DifferentialEquations and I would like if someone could give some advice on this issue.