def test_bad_timestep_handling():
    """ Check that rejecting timesteps works.
    """
    tmax = 0.4
    tol = 1e-4

    def list_cummulative_sums(values, start):
        temp = [start]
        for v in values:
            temp.append(temp[-1] + v)
        return temp

    dts = [1e-6, 1e-6, 1e-6, (1. - 0.01)*tmax]
    initial_ts = list_cummulative_sums(dts[:-1], 0.)
    initial_ys = [sp.array(exp3_exact(t), ndmin=1) for t in initial_ts]

    adaptor = par(general_time_adaptor, lte_calculator=bdf2_mp_lte_estimate,
                  method_order=2)

    ts, ys = _odeint(exp3_residual, initial_ts, initial_ys, dts[-1], tmax,
                     bdf2_residual, tol, adaptor)

    # plt.plot(ts,ys)
    # plt.plot(ts[1:], utils.ts2dts(ts))
    # plt.plot(ts, map(exp3_exact, ts))
    # plt.show()

    overall_tol = len(ys) * tol * 2  # 2 is a fudge factor...
    utils.assert_list_almost_equal(ys, map(exp3_exact, ts), overall_tol)
Beispiel #2
0
def test_bad_timestep_handling():
    """ Check that rejecting timesteps works.
    """
    tmax = 0.4
    tol = 1e-4

    def list_cummulative_sums(values, start):
        temp = [start]
        for v in values:
            temp.append(temp[-1] + v)
        return temp

    dts = [1e-6, 1e-6, 1e-6, (1. - 0.01) * tmax]
    initial_ts = list_cummulative_sums(dts[:-1], 0.)
    initial_ys = [sp.array(exp3_exact(t), ndmin=1) for t in initial_ts]

    adaptor = par(general_time_adaptor,
                  lte_calculator=bdf2_mp_lte_estimate,
                  method_order=2)

    ts, ys = _odeint(exp3_residual, initial_ts, initial_ys, dts[-1], tmax,
                     bdf2_residual, tol, adaptor)

    # plt.plot(ts,ys)
    # plt.plot(ts[1:], utils.ts2dts(ts))
    # plt.plot(ts, map(exp3_exact, ts))
    # plt.show()

    overall_tol = len(ys) * tol * 2  # 2 is a fudge factor...
    utils.assert_list_almost_equal(ys, map(exp3_exact, ts), overall_tol)
    def check_explicit_stepper(stepper, exact_symb):

        exact, residual, dys, J = utils.symb2functions(exact_symb)

        base_dt = 1e-3
        ts, ys = odeint_explicit(dys[1], exact(0.0), base_dt, 1.0, stepper,
                                 time_adaptor=create_random_time_adaptor(base_dt))

        exact_ys = map(exact, ts)
        utils.assert_list_almost_equal(ys, exact_ys, 1e-4)
def check_problem(method, residual, exact, tol=1e-4, tmax=2.0):
    """Helper function to run odeint with a specified method for a problem
    and check that the solution matches.
    """

    ts, ys = odeint(residual, [exact(0.0)], tmax, dt=1e-6,
                    method=method, target_error=tol)

    # Total error should be bounded by roughly n_steps * LTE
    overall_tol = len(ys) * tol * 10
    utils.assert_list_almost_equal(ys, map(exact, ts), overall_tol)

    return ts, ys
    def check_dydt_calcs(dydt_calculator, order, dt, dydt_exact, y_exact):
        """Check that derivative approximations are roughly as accurate as
        expected for a few functions.
        """

        ts = sp.arange(0, 0.5, dt)
        exact_ys = map(y_exact, ts)
        exact_dys = map(dydt_exact, ts, exact_ys)

        est_dys = map(dydt_calculator, utils.partial_lists(ts, 5),
                      utils.partial_lists(exact_ys, 5))

        utils.assert_list_almost_equal(est_dys, exact_dys[4:], 10*(dt**order))
Beispiel #6
0
    def check_dydt_calcs(dydt_calculator, order, dt, dydt_exact, y_exact):
        """Check that derivative approximations are roughly as accurate as
        expected for a few functions.
        """

        ts = sp.arange(0, 0.5, dt)
        exact_ys = map(y_exact, ts)
        exact_dys = map(dydt_exact, ts, exact_ys)

        est_dys = map(dydt_calculator, utils.partial_lists(ts, 5),
                      utils.partial_lists(exact_ys, 5))

        utils.assert_list_almost_equal(est_dys, exact_dys[4:],
                                       10 * (dt**order))
def low_accuracy_recompute_alpha_varying_fields(
        sph_start, sph_end, t_start, t_end, mag_params):
    """
    Compute effective damping from change in magnetisation and change in
    applied field.

    From Nonlinear magnetization dynamics in nanosystems eqn (2.15).

    See notes 30/7/13.

    Derivatives are estimated using BDF1 finite differences.
    """

    # Only for normalised problems!
    assert(mag_params.Ms == 1)

    # Get some values
    dt = t_end - t_start
    m_cart_end = utils.sph2cart(sph_end)
    h_eff_end = heff(mag_params, t_end, m_cart_end)
    mxh = sp.cross(m_cart_end, h_eff_end)

    # Finite difference derivatives
    dhadt = (mag_params.Hvec(t_start) - mag_params.Hvec(t_end))/dt

    assert(all(dhadt == 0))  # no field for now

    dedt = (llg_state_energy(sph_end, mag_params, t_end)
            - llg_state_energy(sph_start, mag_params, t_start)
            )/dt

    sigma = sp.dot(mxh, mxh) / (dedt + sp.dot(m_cart_end, dhadt))

    possible_alphas = sp.roots([1, sigma, 1])

    a = (-sigma + sqrt(sigma**2 - 4))/2
    b = (-sigma - sqrt(sigma**2 - 4))/2

    possible_alphas2 = [a, b]
    utils.assert_list_almost_equal(possible_alphas, possible_alphas2)

    print(sigma, possible_alphas)

    def real_and_positive(x):
        return sp.isreal(x) and x > 0

    alphas = filter(real_and_positive, possible_alphas)
    assert(len(alphas) == 1)
    return sp.real(alphas[0])
Beispiel #8
0
    def check_explicit_stepper(stepper, exact_symb):

        exact, residual, dys, J = utils.symb2functions(exact_symb)

        base_dt = 1e-3
        ts, ys = odeint_explicit(
            dys[1],
            exact(0.0),
            base_dt,
            1.0,
            stepper,
            time_adaptor=create_random_time_adaptor(base_dt))

        exact_ys = map(exact, ts)
        utils.assert_list_almost_equal(ys, exact_ys, 1e-4)
Beispiel #9
0
def check_problem(method, residual, exact, tol=1e-4, tmax=2.0):
    """Helper function to run odeint with a specified method for a problem
    and check that the solution matches.
    """

    ts, ys = odeint(residual, [exact(0.0)],
                    tmax,
                    dt=1e-6,
                    method=method,
                    target_error=tol)

    # Total error should be bounded by roughly n_steps * LTE
    overall_tol = len(ys) * tol * 10
    utils.assert_list_almost_equal(ys, map(exact, ts), overall_tol)

    return ts, ys
    def test_damping_self_consistency(self):
        a2s = energy.recompute_alpha_list(self.sphs, self.times,
                                          self.mag_params)

        # Check that we get the same values with the varying fields version
        a3s = energy.recompute_alpha_list(self.sphs, self.times,
                                          self.mag_params,
                                          energy.recompute_alpha_varying_fields)
        utils.assert_list_almost_equal(a2s, a3s, (1.1/len(self.times)))
        # one of the examples doesn't quite pass with tol=1.0/len, so use
        # 1.1

        # Use 1/length as error estimate because it's proportional to dt
        # and so proportional to the expected error
        def check_alpha_ok(a2):
            return abs(a2 - self.mag_params.alpha) < (1.0/len(self.times))
        assert(all(map(check_alpha_ok, a2s)))
def check_residual(residual, initial_m):
    mag_params = utils.MagParameters()
    tmax = 3.0
    f_residual = ft.partial(residual, mag_params)

    # Timestep to a solution + convert to spherical
    result_times, m_list = ode.odeint(f_residual, sp.array(initial_m),
                                      tmax, dt=0.01)
    m_sph = [utils.array2sph(m) for m in m_list]
    result_pols = [m.pol for m in m_sph]
    result_azis = [m.azi for m in m_sph]

    # Calculate exact solutions
    exact_times, exact_azis = \
        mlsn.calculate_equivalent_dynamics(mag_params, result_pols)

    # Check
    utils.assert_list_almost_equal(exact_azis, result_azis, 1e-3)
    utils.assert_list_almost_equal(exact_times, result_times, 1e-3)
Beispiel #12
0
    def test_damping_self_consistency(self):
        a2s = energy.recompute_alpha_list(self.sphs, self.times,
                                          self.mag_params)

        # Check that we get the same values with the varying fields version
        a3s = energy.recompute_alpha_list(
            self.sphs, self.times, self.mag_params,
            energy.recompute_alpha_varying_fields)
        utils.assert_list_almost_equal(a2s, a3s, (1.1 / len(self.times)))

        # one of the examples doesn't quite pass with tol=1.0/len, so use
        # 1.1

        # Use 1/length as error estimate because it's proportional to dt
        # and so proportional to the expected error
        def check_alpha_ok(a2):
            return abs(a2 - self.mag_params.alpha) < (1.0 / len(self.times))

        assert (all(map(check_alpha_ok, a2s)))
Beispiel #13
0
def check_residual(residual, initial_m):
    mag_params = utils.MagParameters()
    tmax = 3.0
    f_residual = ft.partial(residual, mag_params)

    # Timestep to a solution + convert to spherical
    result_times, m_list = ode.odeint(f_residual,
                                      sp.array(initial_m),
                                      tmax,
                                      dt=0.01)
    m_sph = [utils.array2sph(m) for m in m_list]
    result_pols = [m.pol for m in m_sph]
    result_azis = [m.azi for m in m_sph]

    # Calculate exact solutions
    exact_times, exact_azis = \
        mlsn.calculate_equivalent_dynamics(mag_params, result_pols)

    # Check
    utils.assert_list_almost_equal(exact_azis, result_azis, 1e-3)
    utils.assert_list_almost_equal(exact_times, result_times, 1e-3)
Beispiel #14
0
 def check_newton(residual, exact):
     solution = newton(residual, sp.array([1.0] * len(exact)))
     utils.assert_list_almost_equal(solution, exact)
 def check_newton(residual, exact):
     solution = newton(residual, sp.array([1.0]*len(exact)))
     utils.assert_list_almost_equal(solution, exact)
def test_tr_ab2_scheme_generation():
    """Make sure tr-ab can be derived using same methodology as I'm using
    (also checks lte expressions).
    """

    dddy = sympy.symbols("y'''")
    y_np1_tr = sympy.symbols("y_{n+1}_tr")

    ab_pred, ynp1_ab2_expr = generate_predictor_scheme([PTInfo(0, None, None),
                                                        PTInfo(
                                                            1,
                                                            "corr_val",
                                                            "exp test"),
                                                        PTInfo(
                                                            2, "corr_val", "exp test")],
                                                       "ab2",
                                                       symbolic=sympy.exp(St))

    # ??ds hacky, have to change the symbol to represent where y''' is being
    # evaluated by hand!
    ynp1_ab2_expr = ynp1_ab2_expr.subs(Sdddynph, dddy)

    # Check that it gives the same result as we know from the lte
    utils.assert_sym_eq(y_np1_exact - ab2_lte(Sdts[0], Sdts[1], dddy),
                        ynp1_ab2_expr)

    # Now do the solve etc.
    y_np1_tr_expr = y_np1_exact - tr_lte(Sdts[0], dddy)
    A = system2matrix([ynp1_ab2_expr, y_np1_tr_expr], [dddy, y_np1_exact])
    x = A.inv()

    exact_ynp1_symb = sum([y_est * xi.factor() for xi, y_est in
                           zip(x.row(1), [y_np1_p1, y_np1_tr])])

    exact_ynp1_f = sympy.lambdify(
        (y_np1_p1,
         y_np1_tr,
         Sdts[0],
         Sdts[1]),
        exact_ynp1_symb)

    utils.assert_sym_eq(exact_ynp1_symb - y_np1_tr,
                        (y_np1_p1 - y_np1_tr)/(3*(1 + Sdts[1]/Sdts[0])))

    # Construct an lte estimator from this estimate
    def lte_est(ts, ys):
        ynp1_p = ab_pred(ts, ys)

        dtn = ts[-1] - ts[-2]
        dtnm1 = ts[-2] - ts[-3]

        ynp1_exact = exact_ynp1_f(ynp1_p, ys[-1], dtn, dtnm1)
        return ynp1_exact - ys[-1]

    # Solve exp using tr
    t0 = 0.0
    dt = 1e-2
    ts, ys = ode.odeint(er.exp_residual, er.exp_exact(t0),
                        tmax=2.0, dt=dt, method='tr')

    # Get error estimates using standard tr ab and the one we just
    # constructed here, then compare.
    this_ltes = ode.get_ltes_from_data(ts, ys, lte_est)

    tr_ab_lte = par(ode.tr_ab_lte_estimate, dydt_func=lambda t, y: y)
    standard_ltes = ode.get_ltes_from_data(ts, ys, tr_ab_lte)

    # Should be the same (actually the sign is different, but this doesn't
    # matter in lte).
    utils.assert_list_almost_equal(
        this_ltes, map(lambda a: a*-1, standard_ltes), 1e-8)
Beispiel #17
0
def test_tr_ab2_scheme_generation():
    """Make sure tr-ab can be derived using same methodology as I'm using
    (also checks lte expressions).
    """

    dddy = sympy.symbols("y'''")
    y_np1_tr = sympy.symbols("y_{n+1}_tr")

    ab_pred, ynp1_ab2_expr = generate_predictor_scheme([
        PTInfo(0, None, None),
        PTInfo(1, "corr_val", "exp test"),
        PTInfo(2, "corr_val", "exp test")
    ],
                                                       "ab2",
                                                       symbolic=sympy.exp(St))

    # ??ds hacky, have to change the symbol to represent where y''' is being
    # evaluated by hand!
    ynp1_ab2_expr = ynp1_ab2_expr.subs(Sdddynph, dddy)

    # Check that it gives the same result as we know from the lte
    utils.assert_sym_eq(y_np1_exact - ab2_lte(Sdts[0], Sdts[1], dddy),
                        ynp1_ab2_expr)

    # Now do the solve etc.
    y_np1_tr_expr = y_np1_exact - tr_lte(Sdts[0], dddy)
    A = system2matrix([ynp1_ab2_expr, y_np1_tr_expr], [dddy, y_np1_exact])
    x = A.inv()

    exact_ynp1_symb = sum([
        y_est * xi.factor()
        for xi, y_est in zip(x.row(1), [y_np1_p1, y_np1_tr])
    ])

    exact_ynp1_f = sympy.lambdify((y_np1_p1, y_np1_tr, Sdts[0], Sdts[1]),
                                  exact_ynp1_symb)

    utils.assert_sym_eq(exact_ynp1_symb - y_np1_tr,
                        (y_np1_p1 - y_np1_tr) / (3 * (1 + Sdts[1] / Sdts[0])))

    # Construct an lte estimator from this estimate
    def lte_est(ts, ys):
        ynp1_p = ab_pred(ts, ys)

        dtn = ts[-1] - ts[-2]
        dtnm1 = ts[-2] - ts[-3]

        ynp1_exact = exact_ynp1_f(ynp1_p, ys[-1], dtn, dtnm1)
        return ynp1_exact - ys[-1]

    # Solve exp using tr
    t0 = 0.0
    dt = 1e-2
    ts, ys = ode.odeint(er.exp_residual,
                        er.exp_exact(t0),
                        tmax=2.0,
                        dt=dt,
                        method='tr')

    # Get error estimates using standard tr ab and the one we just
    # constructed here, then compare.
    this_ltes = ode.get_ltes_from_data(ts, ys, lte_est)

    tr_ab_lte = par(ode.tr_ab_lte_estimate, dydt_func=lambda t, y: y)
    standard_ltes = ode.get_ltes_from_data(ts, ys, tr_ab_lte)

    # Should be the same (actually the sign is different, but this doesn't
    # matter in lte).
    utils.assert_list_almost_equal(this_ltes,
                                   map(lambda a: a * -1, standard_ltes), 1e-8)