I have a system of non linear differential equations in the form : $$\frac{dy_i}{dt}=\sum_j a_{ij} y_i y_j $$.
I first tried to solve it with Python suing scipy.integrate.odeint but it is very slow.
I'd like to solve it with an Euler method : $$y_i(t+\delta t)=y_i(t)+\frac{dy_i}{dt}\delta t $$.
How should I chose the value of $\delta t$ to ensure a good convergence ?
What I tried is the following.
Let's define the error $\epsilon$ : $$\epsilon=\sqrt{\sum_i(\delta t \times dy_i/dt)^2} $$
Starting from a low enough initial guess for $\delta t$, I looked wether the error increase or descrease.
- If the error decreases : $\epsilon(t)>\epsilon(t+\delta t)$, I change $\delta t\rightarrow 2\delta t$
- If the error increases : $\epsilon(t)<\epsilon(t+\delta t)$, I change $\delta t\rightarrow \delta t/2$
But the calculation is very slow and can even diverge.
Another possibility I tried :
- If the error decreases : $\epsilon(t)>\epsilon(t+\delta t)$, I change $\delta t\rightarrow 2^n\delta t$ with $n$ so that $\epsilon(t+2^{n}\delta t)<\epsilon(t)<\epsilon(t+2^{n+1}\delta t)$
- If the error increases : $\epsilon(t)<\epsilon(t+\delta t)$, I change $\delta t\rightarrow \delta t/2^n$ until $\epsilon(t+\delta t/2^{n})<\epsilon(t)<\epsilon(t+\delta t/2^{n-1})$
but this scheme is not very efficient too.
scipy.integrate.solve_ivp. A good explicit integrator is 'RK45', equivalent toode45in Matlab. Play with the integration tolerancesrtolandatol(set them to 1e-3, 1e-6 or 1e-9 for instance) and see how well (or not) your problem is solved. If the solver is slow, I recommend trying the implicit integrators 'BDF' (or LSODA which is nearly identical) and 'Radau'. Ideally, post a standalone code snippet that allows us to easily run your test case and play with it ;) – Laurent90 Apr 08 '21 at 10:25odeintis slow, and similarlysolve_ivpwithmethod="Radau", then the system is stiff. Which is not surprising for a quadratic right side. It would, on the other hand, require some structure in the coefficients to prevent the solution from blowing up. You will not get a useful solution faster with the Euler method. You would need step sizes that are so small that the effort becomes much higher. // Due to the algebraic construction of the right side, you might be able to employ operator splitting methods, like the exponential variants of Runge-Kutta. – Lutz Lehmann Apr 08 '21 at 11:48