I want to simulate the laser power along a silica fiber. The ODEs and the used parameters can be found in the paper linked below. Note that I converted all units to SI units in my code. The authors of this paper named the shooting method as a way to numerically solve this equations.
The paper I am referring to can be found here: https://www.osapublishing.org/oe/fulltext.cfm?uri=oe-21-17-20090&id=260516
I tried it in python but I did not manage to implement the root-finding. I used scypi.integrate_ivp to integrate the ODEs with a first guess. If I use a small value (~500m) at fiberlength I get a result but at a higher value in the range of km the solver does not manage to finish without an error. Can somebody please tell me how I can implement the shooting method here and also how I get the same solution as in the paper?
My code:
import matplotlib.pyplot as plt
import numpy as np
from scipy.integrate import odeint
from scipy.integrate import solve_ivp
from scipy.integrate import solve_bvp
from scipy.optimize import fsolve
#%% ODEs und Parameter
#constants
alpha = 10**(-0.25/10)/1000 #fiber loss [1/m]
a0= alpha
a1= alpha
a2= alpha
a3= alpha
g = 0.53e-3 #RamanGain [1/(W*m)]
g1= g
g2= g*0.8
g3= g*0.6
epsilon0 = 1e-4*1e-3 #Rayleigh-scattering [1/m] REFERENZ: Paper: Third order random lasing via Raman gain and Rayleigh backscattering
epsilon1 = 5e-5*1e-3
epsilon2 = 2e-5*1e-3
epsilon3 = 1e-5*1e-3
wl_start = 1365e-9
RamanShift= 13.2e12
f0=3e8/wl_start
f1= f0 - RamanShift
f2= f1 - RamanShift
f3= f2 - RamanShift
#R_L1 = 0.99 # Reflexionskoeffizienten (Fasereingang FBG)
#R_L2 = 5e-3 # Reflexionskoeffizienten (Fasereingang)
#R_R1 = 4e-5 # Reflexionskoeffizienten (Faserausgang)
#R_R2 = 4e-5 # Reflexionskoeffizienten (Faserausgang)
R=0.6 # reflectivity
# G[i] = 4*h*f[i]*df[i]*(1+1/(np.exp((h*(f[i-1]-f[i]))/(K*T))-1))
h=6.63e-34 #Placksches Wirkungsquantum [Js]
K=1.38e-23 #Bolzmannkonstante [J/K]
T=300 #Temperature [K]
#df1= 0.18e12 #Bandbreite [Hz] REFERENZ: Paper: Third order random lasing via Raman gain and Rayleigh backscattering
#df2= 0.25e12
#df3= 0.25e12
#bandwidth
df1= 0.18e12
df2= 0.25e12
df3= 0.25e12
Gamma1= 4*h*f1*df1*(1+(1/(np.exp(h*(f0-f1)/(K*T))-1)))
Gamma2= 4*h*f2*df2*(1+(1/(np.exp(h*(f1-f2)/(K*T))-1)))
Gamma3= 4*h*f3*df3*(1+(1/(np.exp(h*(f2-f3)/(K*T))-1)))
#start conditions
Pin = 2.7 #W
fiberlength = 90000 #m
points = fiberlength*100
P0 = [Pin, 0, 0, 0, 0, 0, 0, 0 ]
def odes2 (z, P):
Pump_forward = P[0]
Pump_backward = P[1]
Stokes1_forward = P[2]
Stokes1_backward = P[3]
Stokes2_forward = P[4]
Stokes2_backward = P[5]
Stokes3_forward = P[6]
Stokes3_backward = P[7]
dPump_forwarddz = - a0 * Pump_forward - g1 * f0/f1 * Pump_forward * (Stokes1_forward + Stokes1_backward + Gamma1) + epsilon0 * Pump_backward
dPump_backwarddz = + a0 * Pump_backward + g1 * f0/f1 * Pump_backward * (Stokes1_forward + Stokes1_backward + Gamma1) - epsilon0 * Pump_forward
dStokes1_forwarddz = - a1 * Stokes1_forward - g2 * f1/f2 * Stokes1_forward * (Stokes2_forward + Stokes2_backward + Gamma2) + g1 * (Stokes1_forward + 0.5 * Gamma1) * (Pump_forward + Pump_backward) + epsilon1 * Stokes1_backward
dStokes1_backwardz = + a1 * Stokes1_backward + g2 * f1/f2 * Stokes1_backward * (Stokes2_forward + Stokes2_backward + Gamma2) - g1 * (Stokes1_backward + 0.5 * Gamma1) * (Pump_forward + Pump_backward) - epsilon1 * Stokes1_forward
dStokes2_forwarddz = - a2 * Stokes2_forward - g3 * f2/f3 * Stokes2_forward * (Stokes3_forward + Stokes3_backward + Gamma3) + g2 * (Stokes2_forward + 0.5 * Gamma2) * (Stokes1_forward + Stokes1_backward) + epsilon2 * Stokes2_backward
dStokes2_backwardz = + a2 * Stokes2_backward + g3 * f2/f3 * Stokes2_backward * (Stokes3_forward + Stokes3_backward + Gamma3) - g2 * (Stokes2_backward + 0.5 * Gamma2) * (Stokes1_forward + Stokes1_backward) - epsilon2 * Stokes2_forward
dStokes3_forwarddz = - a3 * Stokes3_forward + g3 * (Stokes3_forward + 0.5 * Gamma3) * (Stokes2_forward + Stokes2_backward) + epsilon3 * Stokes3_backward
dStokes3_backwardz = + a3 * Stokes3_backward - g3 * (Stokes3_backward + 0.5 * Gamma3) * (Stokes2_forward + Stokes2_backward) - epsilon3 * Stokes3_forward
return [dPump_forwarddz, dPump_backwarddz, dStokes1_forwarddz, dStokes1_backwardz, dStokes2_forwarddz, dStokes2_backwardz, dStokes3_forwarddz, dStokes3_backwardz]
sol = solve_ivp(odes2, (0, fiberlength), P0, t_eval=np.linspace(0, fiberlength, points))
Pump_f, Pump_b, Stokes1_f, Stokes1_b, Stokes2_f, Stokes2_b, Stokes3_f, Stokes3_b = sol.y
x=sol.t
plt.figure(1)
plt.title('backwards')
plt.plot(x, Pump_b, label='pump')
plt.plot(x, Stokes1_b, label='stokes#1')
plt.plot(x, Stokes2_b, label='stokes#2')
plt.plot(x, Stokes3_b, label='stokes#3')
plt.legend(loc=1, fontsize='xx-small')
plt.grid(True)
plt.figure(2)
plt.title('forwards')
plt.plot(x, Pump_f, label='pump')
plt.plot(x, Stokes1_f, label='stokes#1')
plt.plot(x, Stokes2_f, label='stokes#2')
plt.plot(x, Stokes3_f, label='stokes#3')
plt.legend(loc=1, fontsize='xx-small')
plt.grid(True)
I also tried the solve_bvp but it wasn't successfull.