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])
def recompute_alpha_varying_fields_at_midpoint(sph_start, sph_end,
                                               t_start, t_end, mag_params):
    """
    Compute effective damping from change in magnetisation and change in
    applied field.

    See notes 30/7/13 pg 5.

    Derivatives are estimated using midpoint method finite differences, all
    values are computed at the midpoint (m = (m_n + m_n-1)/2, similarly for
    t).
    """

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

    # Get some values
    dt = t_end - t_start
    t = (t_end + t_start)/2
    m = (sp.array(utils.sph2cart(sph_end))
         + sp.array(utils.sph2cart(sph_start)))/2

    h_eff = heff(mag_params, t, m)
    mxh = sp.cross(m, h_eff)

    # Finite difference derivatives
    dhadt = (mag_params.Hvec(t_end) - mag_params.Hvec(t_start))/dt
    dedt = (llg_state_energy(sph_end, mag_params, t_end)
            - llg_state_energy(sph_start, mag_params, t_start)
            )/dt
    dmdt = (sp.array(utils.sph2cart(sph_end))
            - sp.array(utils.sph2cart(sph_start)))/dt

    # utils.assert_almost_equal(dedt, sp.dot(m_cart_end, dhadt)
    #                           + sp.dot(dmdt, h_eff_end), 1e-2)

    # print(sp.dot(m_cart_end, dhadt), dedt)

    # Calculate alpha itself using the forumla derived in notes
    alpha = -((dedt + sp.dot(m, dhadt))
              / (sp.dot(h_eff, sp.cross(m, dmdt))))

    return alpha
def 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.

    See notes 30/7/13 pg 5.

    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
    dedt = (llg_state_energy(sph_end, mag_params, t_end)
            - llg_state_energy(sph_start, mag_params, t_start)
            )/dt
    dmdt = (sp.array(utils.sph2cart(sph_start))
            - sp.array(m_cart_end))/dt

    utils.assert_almost_equal(dedt, sp.dot(m_cart_end, dhadt)
                              + sp.dot(dmdt, h_eff_end), 1e-2)

    # print(sp.dot(m_cart_end, dhadt), dedt)

    # Calculate alpha itself using the forumla derived in notes
    alpha = ((dedt - sp.dot(m_cart_end, dhadt))
             / (sp.dot(h_eff_end, sp.cross(m_cart_end, dmdt))))

    return alpha