How to implement shooting method with coupled ODEs

Viewed 117

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.

0 Answers
Related