# Solving differential equations with fast oscillations using odeint

I have wrote this code to solve an equation , I know the behavior of this function has very rapid oscillations, when I RUN it gives bogus values for some "m[x]" and some "t"'s, with this error:

C:\Users\dani\anaconda3\lib\site-packages\scipy\integrate\odepack.py:247: ODEintWarning: Excess work done on this call (perhaps wrong Dfun type). Run with full_output = 1 to get quantitative information. warnings.warn(warning_msg, ODEintWarning)

import scipy as sio
import numpy as np
import mpmath as mp
import scipy.integrate as spi
import matplotlib.pyplot as plt
import time
initial_value=np.logspace(24,27,100)
t=np.logspace(0,6,100)
m=np.logspace(0,6,100)
start_time=time.perf_counter()
phi_m={}
phi_m_prime={}
phi=[]
phi_prime=[]
j=0
i=np.pi*2.435*initial_value
while i<(np.pi*(2.435*10**(27))):
i=np.pi*2.435*initial_value[j]
phi=[]
phi_prime=[]
for x in range (len(m)):
def dzdt(z,T):
return [z, -3*1.4441*(10**(-6))*m[x]*np.sqrt(0.69)*(mp.coth(1.5*np.sqrt(0.69)*        (10**(-6))*1.4441*m[x]*T))*z - z]
z0 = [i,0]
ts = tp/m[x]
zs = spi.odeint(dzdt, z0, ts)
phi.append(zs[99,0])
phi_prime.append(zs[99,1])
phi_m[j]=phi
phi_m_prime[j]=phi_prime
j+=1
end_time=time.perf_counter()
print(end_time-start_time,"seconds")


I don't know what is the problem. how can I get correct results? or at least as accurate as possible? or maybe I should rewrite the code in another form? thank you.

UPDATE_1: I increased the steps and decreased the step sizes in this way:

tp=[]
t1=np.logspace(0,1,100)
t2=np.logspace(1,3,500)
t3=np.logspace(3,4,700)
t4=np.logspace(4,5,800)
t5=np.logspace(5,6,1000)


and used tp.append() for every single elements in t1,t2,...,t5 ; but there is still some false results for some "m[x]"'s like for x=8 to 13, surprisingly results for x<8 and x>13 are not too bad!

UPDATE_2:

once again I increased the steps number:

tp=[]
t1=np.logspace(0,1,100)
t2=np.logspace(1,3,5000)
t3=np.logspace(3,4,7000)
t4=np.logspace(4,5,8000)
t5=np.logspace(5,6,10000)


and used tp.append() for the elements; so now I have "tp" with 20100 steps that has more steps and smaller step sizes in the parts that function has his rapid oscillations; after several hours it's still under running! I do not know if this method will help or not.

• "my program doesn't work right, please fix it for me" questions are not a good fit for Stack Exchange. Please add what you have tried so far to figure it out. Please add the equation that the code is trying to implement, written as a plain text equation or using MathJax. Please add some representation of the results your program produces and explain how you believe it should look. Adding all of these will help keep your question from quickly becoming closed, and increase the possibility that you receive a helpful answer. Thanks!
– uhoh
Jun 27 at 20:22
• The immediate reason for the error is that the middle coefficient grows (linearly) in time so that the equation becomes increasingly stiff. And while the solution falls superexponentially towards zero, the frequency also increases so that the step size for a faithful sampling has to decrease. This apparently goes far enough that the time increment stalls in floating point numbers. /// * Use some kind of exponential solver (not available in scipy.integrate). // * use solve_ivp with an event to test when the solution becomes very small and stop there. Jun 28 at 6:51
• @LutzLehmann thank you; as I understand from your comment, if I increase the number of steps (and subsequently decrease the size of steps) when "the solution falls superexponentially towards zero, the frequency also increases" then I will be able to solve the problem ? I did this in the code , please check out the updates. Jun 28 at 21:01
• Yes, that has some effect, but it should not, the output nodes should not influence the internal nodes. You might get some improvement by setting tighter error tolerances. Jun 28 at 21:05