def recompute_alpha(sph_start, sph_end, t_start, t_end, mag_params):
    """
    From a change in energy we can calculate what the effective damping
    was. For more details see [Albuquerque2001,
    http://dx.doi.org/10.1063/1.1355322].

    alpha' = - (1/(M**2))  *( dE/dt  /  spaceintegral( (dm/dt**2  )))

    No space integral is needed because we are working with 0D LLG.
    """

    Ms = mag_params.Ms
    dt = t_end - t_start

    # Estimate dEnergy / dTime
    dEdt = (llg_state_energy(sph_end, mag_params, t_end)
            - llg_state_energy(sph_start, mag_params, t_start)
            )/dt

    # Estimate dMagnetisation / dTime then take sum of squares
    dmdt = [(m2 - m1)/dt for m1, m2 in
            zip(utils.sph2cart(sph_start), utils.sph2cart(sph_end))]
    dmdt_sq = sp.dot(dmdt, dmdt)

    # dE should be negative so the result should be positive.
    return - (1/(Ms**2)) * (dEdt / dmdt_sq)
def test_dfdm():

    ms = [utils.sph2cart([1.0, 0.0, pi/18]),
          utils.sph2cart([1.0, 0.0, 0.0001*pi]),
          utils.sph2cart([1.0, 0.0, 0.999*pi]),
          utils.sph2cart([1.0, 0.3*2*pi, 0.5*pi]),
          utils.sph2cart([1.0, 2*pi, pi/18]),
          ]

    for m in ms:
        yield check_dfdm, m
예제 #3
0
def test_dfdm():

    ms = [
        utils.sph2cart([1.0, 0.0, pi / 18]),
        utils.sph2cart([1.0, 0.0, 0.0001 * pi]),
        utils.sph2cart([1.0, 0.0, 0.999 * pi]),
        utils.sph2cart([1.0, 0.3 * 2 * pi, 0.5 * pi]),
        utils.sph2cart([1.0, 2 * pi, pi / 18]),
    ]

    for m in ms:
        yield check_dfdm, m
def zeeman_energy(sph, mag_params, t=None):
    """ Ez = - mu0 * (M.Happ(t)), t can be None if the field is not time
    dependant.
    """
    Ms = mag_params.Ms
    Happ = mag_params.Hvec(t)
    mu0 = mag_params.mu0

    m = utils.sph2cart(sph)
    return -1 * mu0 * Ms * sp.dot(m, Happ)
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 test_llg_residuals():
    m0_sph = [0.0, pi/18]
    m0_cart = utils.sph2cart(tuple([1.0] + m0_sph))
    # m0_constrained = list(m0_cart) + [None]  # ??ds

    residuals = [(llg.llg_cartesian_residual, m0_cart),
                 (llg.ll_residual, m0_cart),
                 # (llg_constrained_cartesian_residual, m0_constrained),
                 ]

    for r, i in residuals:
        yield check_residual, r, i
예제 #7
0
def test_llg_residuals():
    m0_sph = [0.0, pi / 18]
    m0_cart = utils.sph2cart(tuple([1.0] + m0_sph))
    # m0_constrained = list(m0_cart) + [None]  # ??ds

    residuals = [
        (llg.llg_cartesian_residual, m0_cart),
        (llg.ll_residual, m0_cart),
        # (llg_constrained_cartesian_residual, m0_constrained),
    ]

    for r, i in residuals:
        yield check_residual, r, i
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
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 ramping_field_llg_initial(*_):
    return utils.sph2cart([1.0, 0.0, sp.pi/18])
def simple_llg_initial(*_):
    return utils.sph2cart([1.0, 0.0, sp.pi/18])
def magnetocrystalline_anisotropy_energy(sph, mag_params):
    """ Eca = K1 (m.e)^2"""
    K1 = mag_params.K1
    m_cart = utils.sph2cart(sph)
    return K1 * (1 - sp.dot(m_cart, mag_params.easy_axis)**2)
예제 #13
0
def ramping_field_llg_initial(*_):
    return utils.sph2cart([1.0, 0.0, sp.pi / 18])
예제 #14
0
def simple_llg_initial(*_):
    return utils.sph2cart([1.0, 0.0, sp.pi / 18])