def test_ab2(): def dydt(t, y): return y tmax = 1.0 # Oscillate dt to check variable timestep maths is ok. dt_base = 1e-4 input_dts = it.cycle([dt_base, 15 * dt_base]) # Starting values ts = [0.0, 1e-6] ys = map(exp, ts) dts = [1e-6] while ts[-1] < tmax: dtprev = dts[-1] dt = input_dts.next() y_np1 = ab2_step(dt, ys[-1], dydt(ts[-1], ys[-1]), dtprev, dydt(ts[-2], ys[-2])) ys.append(y_np1) ts.append(ts[-1] + dt) dts.append(dt) # plt.plot(ts, ys, 'x', ts, map(exp, ts)) # plt.show() utils.assert_almost_equal(ys[-1], exp(ts[-1]), 1e-5)
def test_ab2(): def dydt(t, y): return y tmax = 1.0 # Oscillate dt to check variable timestep maths is ok. dt_base = 1e-4 input_dts = it.cycle([dt_base, 15*dt_base]) # Starting values ts = [0.0, 1e-6] ys = map(exp, ts) dts = [1e-6] while ts[-1] < tmax: dtprev = dts[-1] dt = input_dts.next() y_np1 = ab2_step(dt, ys[-1], dydt(ts[-1], ys[-1]), dtprev, dydt(ts[-2], ys[-2])) ys.append(y_np1) ts.append(ts[-1] + dt) dts.append(dt) # plt.plot(ts, ys, 'x', ts, map(exp, ts)) # plt.show() utils.assert_almost_equal(ys[-1], exp(ts[-1]), 1e-5)
def _get_initial_dy(self, base_residual, ts, ys): """Calculate a step with midpoint to get dydt at y_n. """ # We want to ignore the most recent two steps (the one being solved # for "now" outside this function and the one we are computing the # derivative at). We also want to ensure nothing is modified in the # solutions list: temp_ts = copy.deepcopy(ts[:-2]) temp_ys = copy.deepcopy(ys[:-2]) # Timestep should be double the timestep used for the previous # step, so that the midpoint is at y_n. dt_n = 2 * (ts[-2] - ts[-3]) # Calculate time step temp_ys, temp_ts = _odeint(base_residual, temp_ys, temp_ts, dt_n, temp_ts[-1] + dt_n, midpoint_residual) # Check that we got the right times: the midpoint should be at # the step before the most recent time. utils.assert_almost_equal((temp_ts[-1] + temp_ts[-2]) / 2, ts[-2]) # Now invert midpoint to get the derivative dy_nph = (temp_ys[-1] - temp_ys[-2]) / dt_n # Fill in dummys (as many as we have y values) followed by the # derivative we just calculated. self.dys = [float('nan')] * (len(ys) - 1) self.dys[-1] = dy_nph
def _get_initial_dy(self, base_residual, ts, ys): """Calculate a step with midpoint to get dydt at y_n. """ # We want to ignore the most recent two steps (the one being solved # for "now" outside this function and the one we are computing the # derivative at). We also want to ensure nothing is modified in the # solutions list: temp_ts = copy.deepcopy(ts[:-2]) temp_ys = copy.deepcopy(ys[:-2]) # Timestep should be double the timestep used for the previous # step, so that the midpoint is at y_n. dt_n = 2*(ts[-2] - ts[-3]) # Calculate time step temp_ys, temp_ts = _odeint(base_residual, temp_ys, temp_ts, dt_n, temp_ts[-1] + dt_n, midpoint_residual) # Check that we got the right times: the midpoint should be at # the step before the most recent time. utils.assert_almost_equal((temp_ts[-1] + temp_ts[-2])/2, ts[-2]) # Now invert midpoint to get the derivative dy_nph = (temp_ys[-1] - temp_ys[-2])/dt_n # Fill in dummys (as many as we have y values) followed by the # derivative we just calculated. self.dys = [float('nan')] * (len(ys)-1) self.dys[-1] = dy_nph
def check_vector_timestepper(method, tol): def residual(t, y, dydt): return sp.array([-1.0 * sin(t), y[1]]) - dydt tmax = 1.0 ys, ts = odeint(residual, [cos(0.0), exp(0.0)], tmax, dt=0.001, method=method) utils.assert_almost_equal(ys[-1][0], cos(tmax), tol[0]) utils.assert_almost_equal(ys[-1][1], exp(tmax), tol[1])
def check_exp_timestepper(method, tol): def residual(t, y, dydt): return y - dydt tmax = 1.0 dt = 0.001 ys, ts = odeint(exp_residual, [exp(0.0)], tmax, dt=dt, method=method) # plt.plot(ts,ys) # plt.plot(ts, map(exp,ts), '--r') # plt.show() utils.assert_almost_equal(ys[-1], exp(tmax), tol)
def check_zeeman(m, H, ans): """Helper function for test_zeeman.""" mag_params = utils.MagParameters() mag_params.Hvec = H utils.assert_almost_equal(zeeman_energy(m, mag_params), ans(mag_params))