def test_not_monotonous(): # ts not strictly monotonous ts = np.random.rand(1000) ws = ts gs = ws ti = ts[0] tf = ts[-1] x0 = 1.0 dx0 = 0.0 with pytest.raises(TypeError): pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0) return None
def test_outside_range_tf(): # ti outside ts ts = np.linspace(1, 50, 1000) ws = np.linspace(1, 50, 1000) gs = np.zeros_like(ws) ti = 1.0 tf = -5.0 x0 = 1.0 dx0 = 0.0 with pytest.raises(TypeError): pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0) return None
def test_too_small(): # Same size arrays but too small ts = np.linspace(1, 50, 1) ws = np.linspace(1, 50, 1) gs = np.zeros_like(ws) ti = 1.0 tf = 50.0 x0 = 1.0 dx0 = 0.0 with pytest.raises(TypeError): pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0) return None
def test_different_size(): # Different size arrays ts = np.linspace(1, 50, 2000) ws = np.linspace(1, 50, 2001) gs = np.zeros_like(ws) ti = 1.0 tf = 50.0 x0 = 1.0 dx0 = 0.0 with pytest.raises(TypeError): pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0) return None
def test_dense_output_range(): # Dense output outside integration range ts = np.linspace(1, 50, 2000) ws = np.linspace(1, 50, 2000) gs = np.zeros_like(ws) t_eval = np.linspace(0, 60, 1000) ti = 1.0 tf = 50.0 x0 = 1.0 dx0 = 0.0 with pytest.raises(TypeError): pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0, t_eval=t_eval) return None
def test_dense_output_sorted(): # Dense output not sorted ts = np.linspace(1, 50, 2000) ws = np.linspace(1, 50, 2000) t_eval = np.linspace(1, 50, 100) t_eval = np.flip(t_eval) gs = np.zeros_like(ws) ti = 1.0 tf = 50.0 x0 = 1.0 dx0 = 0.0 with pytest.raises(TypeError): pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0, t_eval=t_eval) return None
def test_airy_backward_even(): # Integration backwards on even grid ts = np.linspace(1, 100, 5000) ws = np.sqrt(ts) gs = np.zeros_like(ws) ti = 1.0 tf = 100.0 t_eval = np.linspace(ti, tf, 5000) x0 = airy(-tf)[0] + 1j * airy(-tf)[2] dx0 = -airy(-tf)[1] - 1j * airy(-tf)[3] sol = pyoscode.solve(ts, ws, gs, tf, ti, x0, dx0, t_eval=t_eval, even_grid=True) t = np.asarray(sol['t']) x = np.asarray(sol['sol']) dense = np.asarray(sol['x_eval']) dense_d = np.asarray(sol['dx_eval']) types = np.asarray(sol['types']) ana_t = np.linspace(ti, tf, 5000) ana_x = np.asarray([airy(-T)[0] + 1j * airy(-T)[2] for T in t]) dense_ana_x = np.asarray([airy(-T)[0] + 1j * airy(-T)[2] for T in ana_t]) dense_ana_dx = np.asarray([-airy(-T)[1] - 1j * airy(-T)[3] for T in ana_t]) dense_error = np.abs((dense - dense_ana_x) / dense_ana_x) / 0.01 > 1.0 dense_error_d = np.abs( (dense_d - dense_ana_dx) / dense_ana_dx) / 0.01 > 1.0 error = np.abs((x - ana_x) / ana_x) / 0.01 > 1.0 assert (np.any(dense_error) == False and np.any(dense_error_d) == False and np.any(error) == False)
def test_no_integration(): # Tests the case when ti=tf ts = np.linspace(1, 100, 5000) ws = np.sqrt(ts) gs = np.zeros_like(ws) ti = 1.0 tf = ti x0 = airy(-ti)[0] + 1j * airy(-ti)[2] dx0 = -airy(-ti)[1] - 1j * airy(-ti)[3] sol = pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0, even_grid=True) t = np.asarray(sol['t']) x = np.asarray(sol['sol']) dx = np.asarray(sol['dsol']) assert (x.shape[0] == 1 and dx.shape[0] == 1 and x[0] == x0 and dx[0] == dx0)
gs = np.zeros_like(ws) # Define the range of integration and the initial conditions ti = 1.0 tf = 100.0 x0 = airy(-ti)[0] + 1j * airy(-ti)[2] dx0 = -airy(-ti)[1] - 1j * airy(-ti)[3] t_eval = np.linspace(ti, ti + 1.0, 10) # Solve the system # Test forward integration #sol = pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0,t_eval=t_eval) # Uneven grid assumed, even grid given #sol = pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0,t_eval=t_eval,even_grid=True) # Even grid expected, even grid given # Test backward integration #x0 = airy(-tf)[0] + 1j*airy(-tf)[2] #dx0 = -airy(-tf)[1] - 1j*airy(-tf)[3] #sol = pyoscode.solve(ts, ws, gs, tf, ti, x0, dx0,t_eval=t_eval,even_grid=True) # X sol = pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0, t_eval=t_eval) # X t = np.asarray(sol['t']) x = np.asarray(sol['sol']) dense = np.asarray(sol['x_eval']) print("dense output: ", dense[0]) types = np.asarray(sol['types']) # Plot the solution ana_t = np.linspace(ti, tf, 5000) plt.plot(ana_t, [1j * airy(-T)[0] - airy(-T)[2] for T in ana_t], color='black', lw=0.5, label='true solution') plt.plot(t[types == 0], 1j * x[types == 0], '.', color='C0', label='RK steps') plt.plot(t[types == 1], 1j * x[types == 1], '.', color='C1', label='WKB steps') plt.plot(t_eval, 1j * dense, color='C1', label='dense output') plt.legend()
import pyoscode import numpy from scipy.special import airy from matplotlib import pyplot as plt # Define the frequency and friction term over the range of integration ts = numpy.linspace(1, 1000, 5000) ws = numpy.sqrt(ts) gs = numpy.zeros_like(ws) # Define the range of integration and the initial conditions ti = 1.0 tf = 1000.0 x0 = airy(-ti)[0] + 1j * airy(-ti)[2] dx0 = -airy(-ti)[1] - 1j * airy(-ti)[3] # Solve the system sol = pyoscode.solve(ts, ws, gs, ti, tf, x0, dx0) t = numpy.asarray(sol['t']) x = numpy.asarray(sol['sol']) types = numpy.asarray(sol['types']) # Plot the solution ana_t = numpy.linspace(1, 35.0, 1000) plt.plot(ana_t, [airy(-T)[0] for T in ana_t], label='true solution') plt.plot(t[types == 0], x[types == 0], '.', color='red', label='RK steps') plt.plot(t[types == 1], x[types == 1], '.', color='green', label='WKB steps') plt.legend() plt.xlim((1.0, 35.0)) plt.ylim((-1.0, 1.0)) plt.xlabel('t') plt.ylabel('Ai(-t)') plt.savefig('airy-example.png')