Search code examples
pythonodeodeint

Ode Function - solve_ivp -Cathode Ray Tube


for a project I need to simulate an electron in the cathode ray tube and plot the curve of the electron.

The electron leaves the Anode with a velocity in x direction from v_x = sqrt(2U_Be/m_e) In y direction the velocity is equal 0. When the electron enters the capacitor plates there is an acceleration in y-direction: ay = U_Ae/dm_e

The experiment is looking like this

To write an ODE-Function for the trajectory from x=-l_r to x=s+l_r My code is looking like this so far. What am i doing wrong?

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp

def trajectory(t,y,d,e,m_e,U_A,U_B,l_r=10,s=5):
    # y[0] - x-position
    # y[1] - x-velocity
    # y[2] - y-position
    # y[3] - y-velocity
    while -l_r<y[0]<0:
        d2xdt2 = 0
        d2dyt2 = 0
        dxdt = np.sqrt(2*U_B*e/m_e)
        dydt=0
        return dxdt, d2xdt2, dydt, d2ydt2
    
    if 0<y[0]<s:
        d2xdt2 = 0
        dxdt = np.sqrt(2*U_B*e/m_e)
        d2ydt2 = U_A*e/(d*m_e)
        dxdt = np.sqrt(2*U_B*e/m_e)
        dydt = y[0]/(np.sqrt(2*d*m_e/(U_A*e)*y[2]))
        return dxdt, d2xdt2, dydt, d2ydt2
    
    if s<y[0]<l_s:
        d2xdt2 = 0
        d2ydt2 = 0
        dxdt = np.sqrt(2*U_B*e/m_e)
        dydt=0
        
        
        return dxdt, d2xdt2, dydt, d2ydt2
        
    
    
def hit_screen(t,y, *args):
    return y[1]
                               
hit_screen.terminal = True
hit_screen.direction = -1
                               
                               
#Konstanten definieren
U_A = 100
U_B = 300

l_r = l_s = 10
d = 0.5
m_e = 9.1*20**(-31)
e=1.602*10**(-19)

# inputparameter
x0 = -l_r
y0 = 0
v0 = np.sqrt(2*U_B*e/m_e)
v0_y = 0
start_vec=[x0,v0,y0,v0_y]
tspan = [0, 20]

sol = solve_ivp(trajectory,tspan,start_vec,args=(e,m_e,U_A,U_B,l_r),events=(hit_screen))

t = sol.t
x = sol.y[0,:]
v_x = sol.y[1,:]
y = sol.y[2,:]

plt.plot(x,y)

Solution

  • If you have x,vx,y,vy as the inputs, then no velocity computation is necessary, it is just copied from the inputs to the outputs. You only need to compute the accelerations or second derivatives. Components that are the same for all cases can be set first. In your case where the computed component is zero except in a single segment, this can also be simplified with the trinary if-operator.

    def trajectory(t,y,d,e,m_e,U_A,U_B,l_r=10,s=5):
        # y[0] - x-position
        # y[1] - x-velocity
        # y[2] - y-position
        # y[3] - y-velocity
        dxdt = y[1]
        dydt = y[3]
        d2xdt2 = 0
        d2ydt2 = U_A*e/(d*m_e)  if 0<y[0]<s  else  0
    
        return dxdt, d2xdt2, dydt, d2ydt2
    

    In hit_screen, you are wrongly returning the x-velocity, what you want is the y-coordinate y[2].