Exemplo n.º 1
0
def test_spatially_varying_anisotropy_axis(tmpdir, debug=False):
    Ms = 1e6
    A = 1.3e-11
    K1 = 6e5
    lb = bloch_parameter(A, K1)

    unit_length = 1e-9
    nx = 20
    Lx = nx * lb / unit_length
    mesh = df.IntervalMesh(nx, 0, Lx)

    # anisotropy axis goes from (0, 1, 0) at x=0 to (1, 0, 0) at x=Lx
    expr_a = df.Expression(("x[0] / sqrt(pow(x[0], 2) + pow(Lx-x[0], 2))",
                            "(Lx-x[0]) / sqrt(pow(x[0], 2) + pow(Lx-x[0], 2))",
                            "0"), Lx=Lx, degree=1)
    # in theory, a discontinuous Galerkin (constant over the cell) is a good
    # choice to represent material parameters. In this case though, the
    # parameter varies linearly, so we use the usual CG.
    V = df.VectorFunctionSpace(mesh, "CG", 1, dim=3)
    a = Field(V, expr_a)

    sim = Simulation(mesh, Ms, unit_length)
    sim.set_m((1, 1, 0))
    sim.add(UniaxialAnisotropy(K1, a))
    sim.relax()

    # probe the easy axis and the magnetisation along the interval
    points = 100
    xs = np.linspace(0, Lx, points)
    axis_xs = np.zeros((points, 3))
    m_xs = np.zeros((points, 3))

    for i, x in enumerate(xs):
        axis_xs[i] = a(x)
        m_xs[i] = sim.m_field(x)

    # we want to the magnetisation to follow the easy axis
    # it does so, except at x=0, what is happening there?
    diff = np.abs(m_xs - axis_xs)
    assert diff.max() < 0.02

    if debug:
        old = os.getcwd()
        os.chdir(tmpdir)
        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.plot(xs, axis_xs[:, 0], "b+", label="a_x")
        ax.plot(xs, m_xs[:, 0], "r--", label="m_x")
        ax.legend(loc="upper left")
        ax.set_ylim((0, 1.05))
        ax.set_xlabel("x (nm)")
        plt.savefig('spatially_varying_easy_axis.png')
        plt.close()
        sim.m_field.save_pvd('spatially_varying_easy_axis.pvd')
        os.chdir(old)
Exemplo n.º 2
0
def run_simulation(plot=False):
    mu0 = 4.0 * np.pi * 10**-7  # vacuum permeability N/A^2
    Ms = 1.0e6  # saturation magnetisation A/m
    A = 13.0e-12  # exchange coupling strength J/m
    Km = 0.5 * mu0 * Ms**2  # magnetostatic energy density scale kg/ms^2
    lexch = (A / Km)**0.5  # exchange length m
    unit_length = 1e-9
    K1 = Km

    L = lexch / unit_length
    nx = 10
    Lx = nx * L
    ny = 1
    Ly = ny * L
    nz = 30
    Lz = nz * L
    mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(Lx, Ly, Lz), nx, ny, nz)

    # Anisotropy easy axis is (0, 0, 1) in the lower half of the film and
    # (1, 0, 0) in the upper half. This is a toy model of the exchange spring
    # systems that Bob Stamps is working on.
    boundary = Lz / 2.0
    expr_a = df.Expression(("x[2] <= b ? 0 : 1", "0", "x[2] <= b ? 1 : 0"),
                           b=boundary,
                           degree=1)
    V = df.VectorFunctionSpace(mesh, "DG", 0, dim=3)
    a = Field(V, expr_a)

    sim = Simulation(mesh, Ms, unit_length)
    sim.set_m((1, 0, 1))
    sim.add(UniaxialAnisotropy(K1, a))
    sim.add(Exchange(A))
    sim.relax()

    if plot:
        points = 200
        zs = np.linspace(0, Lz, points)
        axis_zs = np.zeros((points, 3))  # easy axis probed along z-axis
        m_zs = np.zeros((points, 3))  # magnetisation probed along z-axis

        for i, z in enumerate(zs):
            axis_zs[i] = a((Lx / 2.0, Ly / 2.0, z))
            m_zs[i] = sim.m_field((Lx / 2.0, Ly / 2.0, z))

        fig = plt.figure()
        ax = fig.add_subplot(111)
        ax.plot(zs, axis_zs[:, 0], "-o", label="a_x")
        ax.plot(zs, axis_zs[:, 2], "-x", label="a_z")
        ax.plot(zs, m_zs[:, 0], "-", label="m_x")
        ax.plot(zs, m_zs[:, 2], "-", label="m_z")
        ax.set_xlabel("z (nm)")
        ax.legend(loc="upper left")
        plt.savefig(os.path.join(MODULE_DIR, "profile.png"))
        sim.m_field.save_pvd(os.path.join(MODULE_DIR, 'exchangespring.pvd'))