def events(t, y): value = [y[0]] isterminal = [1] direction = [-1] return [value, isterminal, direction] def dydt(t, y): return [y[1], -9.8] tstart = 0 tfinal = 30 y0 = [0.0, 20.0] options = Odeoptions() options.odeset('Refine', 10) options.odeset('Events', events) tout = np.array([tstart]) yout = np.array([[y0[0]], [y0[1]]]) teout = np.array([0]) yeout = np.array([[0], [0]]) ieout = np.array([0]) for i in range(10): tspan = np.array([tstart, tfinal]) res = ode45(dydt, tspan, y0, options) nt = len(res.t)
parentdir = os.path.dirname(currentdir) sys.path.append(parentdir) from ode45 import ode45 from odeoptions import Odeoptions def sin(t, y): dydt = np.cos(t) return dydt tspan = [0, 10] y0 = [0] myOptions = Odeoptions() #Create an option with default value. myOptions.odeset('RelTol', 1e-5) myOptions.odeset('AbsTol', 1e-8) myOptions.odeset('Refine', 10) myOptions.odeset('NormControl', True) myOptions.odeset('MaxStep', 1) myOptions.odeset('InitialStep', 0.1) sol = ode45(sin, tspan, y0, myOptions) #Plot ode45 approx fig = plt.figure() plt.title('Ode45 approx') plt.xlabel('t') plt.ylabel('y') plt.plot(sol.t, sol.y[0])
def odearguments(FcnHandlesUsed, solver, ode, tspan, y0, options, extras): if FcnHandlesUsed: tspan = np.array(tspan) if tspan.size < 2: raise Exception("pyhton:odearguments:tspan.size < 2") htspan = np.abs(tspan[1] - tspan[0]) tspan = np.array(tspan) ntspan = tspan.size t0 = tspan[0] NEXT = 1 # NEXT entry in tspan tfinal = tspan[ntspan - 1] args = extras y0 = np.array(y0) neq = len(y0) # Test that tspan is internally consistent. if any(np.isnan(tspan)): raise Exception("pyhton:odearguments:TspanNaNValues") if t0 == tfinal: raise Exception("pyhton:odearguments:TspanEndpointsNotDistinct") if tfinal > t0: tdir = 1 else: tdir = -1 if any(tdir * np.diff(tspan) <= 0): raise Exception("pyhton:odearguments:TspanNotMonotonic") f0 = feval(ode, t0, y0, args) if options is None: options = Odeoptions() #Use default values if options.MaxStep is None: options.MaxStep = np.abs(0.1 * (tfinal - t0)) rtol = np.array([options.RelTol]) if (len(rtol) != 1 or rtol <= 0): raise Exception("pyhton:odearguments:RelTolNotPosScalar") if rtol < 100 * np.finfo(float).eps: rtol = 100 * np.finfo(float).eps atol = options.AbsTol if isinstance(atol, list): atol = np.array(atol) else: atol = np.array([atol]) if any(atol <= 0): raise Exception("python:odearguments:AbsTolNotPos") normcontrol = options.NormControl if normcontrol: if len(atol) != 1: raise Exception("python:odearguments:NonScalarAbsTol") normy = np.linalg.norm(y0) else: if ((len(atol) != 1) and (len(atol) != neq)): raise Exception("python:odearguments:SizeAbsTol") normy = None threshold = atol / rtol hmax = np.array([options.MaxStep]) if hmax <= 0: raise Exception("python:odearguments:MaxStepLEzero") htry = options.InitialStep if htry is not None: if htry <= 0: raise Exception("python:odearguments:InitialStepLEzero") odeFcn = ode dataType = 'float64' return neq, tspan, ntspan, NEXT, t0, tfinal, tdir, y0, f0, args, odeFcn, options, threshold, rtol, normcontrol, normy, hmax, htry, htspan, dataType
#Add parent folder to the path. Code taken from https://codeolives.com/2020/01/10/python-reference-module-in-parent-directory/ import os, sys currentdir = os.path.dirname(os.path.realpath(__file__)) parentdir = os.path.dirname(currentdir) sys.path.append(parentdir) from odeoptions import Odeoptions from ode45 import ode45 def odefcn(x, y): epsilon = 1e-2 return ((1 - x) * y - y**2) / epsilon epsilon = 1e-6 y0 = [1] xspan = [0, 2] options = Odeoptions() options.odeset('NonNegative', [0]) res = ode45(odefcn, xspan, y0, options) fig = plt.figure() plt.title('The knee problem') plt.xlabel('x') plt.ylabel('y') plt.plot(res.t, res.y[0], label='Non-negativity') plt.show()
precision_mean = np.zeros([nbr_Input, nbr_test]) #### INPUT 1 INPUT = 0 tspan = [ 0.74414985, 3.5823718, 6.42059375, 9.2588157, 12.09703764, 14.93525959, 17.77348154, 20.61170349, 23.44992544, 26.28814739, 29.12636934, 31.96459129 ] y0_1 = [4.53897499] y0_2 = [1.20051259, 1.17666892] y0_3 = [0.45052893, 7.03086018, -1.50526611] A = -2.83009697 B = -4.97673659 C = -3.50342477 opts = Odeoptions() precision_mean[INPUT, :] = compute_tests(tspan, y0_1, y0_2, y0_3, opts, A, B, C) #### INPUT 2 INPUT = INPUT + 1 tspan = [ 1.69850555, 4.63711663, 7.57572772, 10.5143388, 13.45294988, 16.39156097, 19.33017205, 22.26878314, 25.20739422, 28.1460053, 31.08461639, 34.02322747, 36.96183856, 39.90044964, 42.83906072, 45.77767181, 48.71628289 ] y0_1 = [-6.38784938] y0_2 = [1.60628946, 1.18921585] y0_3 = [-7.09018137, 4.81021195, -7.82701511] A = 2.25480317
M[0, 0] = 1 M[1, 1] = m1 + m2 M[1, 5] = -m2 * L * np.sin(y[4]) M[2, 2] = 1 M[3, 3] = m1 + m2 M[3, 5] = m2 * L * np.cos(y[4]) M[4, 4] = 1 M[5, 1] = -L * np.sin(y[4]) M[5, 3] = L * np.cos(y[4]) M[5, 5] = L**2 return M tspan = np.linspace(0, 4, 25) y0 = [0, 4, 2, 20, -np.pi / 2, 2] options = Odeoptions() options.odeset('Mass', mass) res = ode45(dydt, tspan, y0, options) #Plot ode45 approx fig = plt.figure() plt.title('A thrown baton problem with mass matrix M(t,y)') plt.xlabel('x') plt.ylabel('y') for j in range(len(res.t)): theta = res.y[4, j] X = res.y[0, j] Y = res.y[2, j] xvals = np.array([X, X + L * np.cos(theta)])
((y[0] - mustar) / r23), -2 * y[2] + y[1] - mustar * (y[1] / r13) - mu * (y[1] / r23) ]) def events(t, y): y0 = np.array([1.2, 0, 0, -1.04935750983031990726]) dDSQdt = 2 * np.dot((y[0:2] - y0[0:2]), y[2:4]) value = np.array([dDSQdt, dDSQdt]) isterminal = np.array([1, 0]) # stop at local minimum direction = np.array([1, -1]) # [local minimum, local maximum] return [value, isterminal, direction] y0 = [1.2, 0, 0, -1.04935750983031990726] tspan = [0, 7] options = Odeoptions() options.odeset('Events', events) options.odeset('RelTol', 1e-5) options.odeset('AbsTol', 1e-4) res = ode45(dydt, tspan, y0, options) #PLOT fig = plt.figure() plt.title('Restricted three body problem') plt.xlabel('x(t)') plt.ylabel('y(t)') plt.plot(res.y[0], res.y[1]) plt.plot(res.ye[0], res.ye[1], 'ro') plt.show()