# ------------------------------------------------------------------------- # # PYTHON for DUMMIES 19-20 # # Shooting technique # Vincent Legat - 2018 # Ecole Polytechnique de Louvain # # ------------------------------------------------------------------------- from numpy import * from matplotlib import pyplot as plt import matplotlib matplotlib.rcParams['toolbar'] = 'None' # plt.rcParams['figure.facecolor'] = 'lavender' # plt.rcParams['axes.facecolor'] = 'lavender' # ------------------------------------------------------------------------- # # -1- Intégration de la trajectoire de l'obus # # dxdt(t) = u(t) # dudt(t) = - gamma*u(t) # dydt(t) = v(t) # dvdt(t) = - 9.81 - gamma*v(t) # # def f(u): friction = 0.1 * sqrt(u[1]*u[1]+u[3]*u[3]) dxdt = u[1] dudt = - friction *u[1] dydt = u[3] dvdt = -9.81 - friction * u[3] return array([dxdt,dudt,dydt,dvdt]) # ------------------------------------------------------------------------- # # -2- Schema de Runge-Kutta classique d'ordre 4 # def rungekutta(a,h): imax = int(8/h) u = a * cos(pi/4) v = a * sin(pi/4) X = arange(imax+1)*h U = zeros((imax+1,4)); U[0,:] = [0,u,0,v] i = 0 while (U[i,2] >= 0) and (i < imax) : K1 = f(U[i,:] ) K2 = f(U[i,:]+K1*h/2) K3 = f(U[i,:]+K2*h/2) K4 = f(U[i,:]+K3*h ) U[i+1,:] = U[i,:] + h*(K1+2*K2+2*K3+K4)/6 i = i+1 return i,X,U # # -3- Méthode de bissection # def shoot(a,h): i,X,U = rungekutta(a,h) plt.plot(U[:i,0],U[:i,2],'-b') return (35-U[i,0]) def shootingMethod(h,tol): n = 1; nmax = 40; a = 100; fa = shoot(a,h) b = 2000; fb = shoot(b,h) n = 0; delta = (b-a)/2; x = a; if (fa*fb > 0) : raise RuntimeError('Bad initial interval') while (abs(delta) >= tol and n <= nmax) : delta = (b-a)/2; n = n + 1; x = a + delta; fx = shoot(x,h) print(" x = %14.7e (Estimated error %13.7e at iteration %d)" % (x,abs(delta),n)) if (fx*fa > 0) : a = x; fa = fx else : b = x; fb = fx if (n > nmax) : raise RuntimeError('Too much iterations') return x # ------------------------------------------------------------------------- fig = plt.figure("Shooting techniques") h = 0.01 tol = 1e-1 a = shootingMethod(h,tol) i,X,U = rungekutta(a,h) plt.plot(U[:i,0],U[:i,2],'-r') plt.show() print(" ============ Final value for x(%f) = %.4f " % (X[i],U[i,0]))