Beispiel #1
0
    def __init__(self, mesh):
        self.mesh = mesh
        self.S1 = df.FunctionSpace(mesh, 'CG', 1)
        self.S3 = df.VectorFunctionSpace(mesh, 'CG', 1, dim=3)
        #zero = df.Expression('0.3')
        m_init = df.Constant([1, 1, 1.0])
        self.m = df.interpolate(m_init, self.S3)
        self.field = df.interpolate(m_init, self.S3)
        self.dmdt = df.interpolate(m_init, self.S3)
        self.spin = self.m.vector().array()
        self.t = 0

        #It seems it's not safe to specify rank in df.interpolate???
        self._alpha = df.interpolate(df.Constant("0.001"), self.S1)
        self._alpha.vector().set_local(self._alpha.vector().array())
        print 'dolfin', self._alpha.vector().array()

        self.llg = LLG(self.S1, self.S3, unit_length=1e-9)
        #normalise doesn't work due to the wrong order
        self.llg.set_m(m_init, normalise=True)

        parameters = {
            'absolute_tolerance': 1e-10,
            'relative_tolerance': 1e-10,
            'maximum_iterations': int(1e5)
        }

        demag = Demag()

        demag.parameters['phi_1'] = parameters
        demag.parameters['phi_2'] = parameters

        self.exchange = Exchange(13e-12)
        self.zeeman = Zeeman([0, 0, 1e5])

        self.llg.effective_field.add(self.exchange)
        #self.llg.effective_field.add(demag)
        self.llg.effective_field.add(self.zeeman)

        self.m_petsc = df.as_backend_type(self.llg.m_field.f.vector()).vec()
        self.h_petsc = df.as_backend_type(self.field.vector()).vec()
        self.alpha_petsc = df.as_backend_type(self._alpha.vector()).vec()
        self.dmdt_petsc = df.as_backend_type(self.dmdt.vector()).vec()
        alpha = 0.001
        gamma = 2.21e5
        LLG1 = -gamma / (1 + alpha * alpha) * df.cross(
            self.m,
            self.field) - alpha * gamma / (1 + alpha * alpha) * df.cross(
                self.m, df.cross(self.m, self.field))
        self.L = df.dot(LLG1, df.TestFunction(self.S3)) * df.dP
Beispiel #2
0
def test_method_of_computing_the_average_matters():
    length = 20e-9  # m
    simplices = 10
    mesh = df.IntervalMesh(simplices, 0, length)
    S1 = df.FunctionSpace(mesh, "Lagrange", 1)
    S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3)

    llg = LLG(S1, S3)
    llg.set_m((
        '(2*x[0]-L)/L',
        'sqrt(1 - ((2*x[0]-L)/L)*((2*x[0]-L)/L))',
        '0'), L=length)

    average1 = llg.m_average
    average2 = np.mean(components(llg.m_numpy), axis=1)
    diff = np.abs(average1 - average2)
    assert diff.max() > 5e-2
Beispiel #3
0
def test_dmdt_computation_with_oommf():
    # set up finmag
    llg = LLG(S1, S3)
    llg.set_m((-3, -2, 1))

    Ms = llg.Ms.vector().array()[0]
    Ms = float(Ms)
    h = Ms / 2
    H_app = (h / np.sqrt(3), h / np.sqrt(3), h / np.sqrt(3))
    zeeman = Zeeman(H_app)
    zeeman.setup(llg.m_field, llg.Ms, 1)
    llg.effective_field.add(zeeman)

    dmdt_finmag = df.Function(llg.S3)
    dmdt_finmag.vector()[:] = llg.solve(0)

    # set up oommf
    msh = mesh.Mesh((nL, nW, nH), size=(L, W, H))
    m0 = msh.new_field(3)
    m0.flat[0] += -3
    m0.flat[1] += -2
    m0.flat[2] += 1
    m0.flat /= np.sqrt(m0.flat[0] * m0.flat[0] + m0.flat[1] * m0.flat[1] +
                       m0.flat[2] * m0.flat[2])

    dmdt_oommf = oommf_dmdt(m0, Ms, A=0, H=H_app, alpha=0.5,
                            gamma_G=llg.gamma).flat

    # extract finmag data for comparison with oommf
    dmdt_finmag_like_oommf = msh.new_field(3)
    for i, (x, y, z) in enumerate(msh.iter_coords()):
        dmdt_x, dmdt_y, dmdt_z = dmdt_finmag(x, y, z)
        dmdt_finmag_like_oommf.flat[0, i] = dmdt_x
        dmdt_finmag_like_oommf.flat[1, i] = dmdt_y
        dmdt_finmag_like_oommf.flat[2, i] = dmdt_z

    # compare
    difference = np.abs(dmdt_finmag_like_oommf.flat - dmdt_oommf)
    relative_difference = difference / np.max(
        np.sqrt(dmdt_oommf[0]**2 + dmdt_oommf[1]**2 + dmdt_oommf[2]**2))
    print "comparison with oommf, dm/dt, relative difference:"
    print stats(relative_difference)
    assert np.max(relative_difference) < TOLERANCE

    return difference, relative_difference
def test_spatially_varying_alpha_using_LLG_class():
    """
    no property magic here - llg.alpha is a df.Function at heart and can be
    set with any type using llg.set_alpha()

    """
    length = 20
    simplices = 10
    mesh = df.IntervalMesh(simplices, 0, length)

    S1 = df.FunctionSpace(mesh, "Lagrange", 1)
    S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, 3)
    llg = LLG(S1, S3)
    llg.set_alpha(1)
    expected_alpha = np.ones(simplices + 1)

    print "Got:\n", llg.alpha.vector().array()
    print "Expected:\n", expected_alpha
    assert np.array_equal(llg.alpha.vector().array(), expected_alpha)
Beispiel #5
0
def setup_domain_wall_cobalt(node_count=NODE_COUNT,
                             A=A_Co,
                             Ms=Ms_Co,
                             K1=K1_Co,
                             length=LENGTH,
                             do_precession=True):
    mesh = df.IntervalMesh(node_count - 1, 0, length)
    S1 = df.FunctionSpace(mesh, "Lagrange", 1)
    S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3)
    llg = LLG(S1, S3)
    llg.set_m(
        np.array([initial_m(xi, node_count)
                  for xi in xrange(node_count)]).T.reshape((-1, )))

    exchange = Exchange(A)
    llg.effective_field.add(exchange)
    anis = UniaxialAnisotropy(K1, (0, 0, 1))
    llg.effective_field.add(anis)
    llg.pins = [0, node_count - 1]
    return llg
Beispiel #6
0
def test_external_field_depends_on_t():
    tfinal = 0.3 * 1e-9
    dt = 0.001e-9

    simplices = 2
    L = 10e-9
    mesh = df.IntervalMesh(simplices, 0, L)
    S1 = df.FunctionSpace(mesh, "Lagrange", 1)
    S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3)
    GHz = 1e9
    omega = 100 * GHz
    llg = LLG(S1, S3)
    llg.set_m(df.Constant((1, 0, 0)))

    #This is the time dependent field
    H_app_expr = df.Expression(("0.0", "0.0", "H0*sin(omega*t)"),
                               H0=1e5,
                               omega=omega,
                               t=0.0,
                               degree=1)
    H_app = TimeZeeman(H_app_expr)
    Ms_field = Field(df.FunctionSpace(mesh, 'DG', 0), 8.6e5)
    H_app.setup(llg.m_field, Ms=Ms_field)

    #define function that updates that expression, and the field object
    def update_H_ext(t):
        print "update_H_ext being called for t=%g" % t
        H_app.update(t)

    llg.effective_field.add(H_app, with_time_update=update_H_ext)

    #nothing special from here, just setting up time integration
    integrator = llg_integrator(llg, llg.m_field)

    #to gather data for later analysis
    mlist = []
    tlist = []
    hext = []

    #time loop
    times = np.linspace(0, tfinal, tfinal / dt + 1)
    for t in times:
        integrator.advance_time(t)
        print "Integrating time: %g" % t
        mlist.append(llg.m_average)
        tlist.append(t)
        hext.append(H_app.H((0)))

    #only plotting and data analysis from here on

    mx = [tmp[0] for tmp in mlist]
    my = [tmp[1] for tmp in mlist]
    mz = [tmp[2] for tmp in mlist]

    pylab.plot(tlist, mx, label='m_x')
    pylab.plot(tlist, my, label='m_y')
    pylab.plot(tlist, mz, label='m_z')
    pylab.xlabel('time [s]')
    pylab.legend()
    pylab.savefig(os.path.join(MODULE_DIR, 'results.png'))
    pylab.close()

    #if max_step is not provided, or chosen too large,
    #the external field appears not smooth in this plot.
    #What seems to happen is that the ode integrator
    #returns the solution without calling the rhs side again
    #if we request very small time steps.
    #This is only for debugging.
    pylab.plot(tlist, hext, '-x')
    pylab.ylabel('external field [A/m]')
    pylab.xlabel('time [s]')
    pylab.savefig(os.path.join(MODULE_DIR, 'hext.png'))
    pylab.close()

    #Then try to fit sinusoidal curve through results
    def sinusoidalfit(t, omega, phi, A, B):
        return A * np.cos(omega * t + phi) + B

    #if scipy available
    try:
        import scipy.optimize
    except ImportError:
        print "Couldn't import scipy.optimize, skipping test"
    else:
        popt, pcov = scipy.optimize.curve_fit(sinusoidalfit,
                                              np.array(tlist),
                                              np.array(my),
                                              p0=(omega * 1.04, 0., 0.1, 0.2))
        #p0 is the set of parameters with which the fitting
        #routine starts

        print "popt=", popt

        fittedomega, fittedphi, fittedA, fittedB = popt
        f = open(os.path.join(MODULE_DIR, "fittedresults.txt"), "w")

        print >> f, "Fitted omega           : %9g" % (fittedomega)
        print >> f, "Rel error in omega fit : %9g" % (
            (fittedomega - omega) / omega)
        print >> f, "Fitted phi             : %9f" % (fittedphi)
        print >> f, "Fitted Amplitude (A)   : %9f" % (fittedA)
        print >> f, "Fitted Amp-offset (B)  : %9f" % (fittedB)
        pylab.plot(tlist, my, label='my - simulated')
        pylab.plot(tlist,
                   sinusoidalfit(np.array(tlist), *popt),
                   '-x',
                   label='m_y - fit')
        pylab.xlabel('time [s]')
        pylab.legend()
        pylab.savefig(os.path.join(MODULE_DIR, 'fit.png'))
        deviation = np.sqrt(
            sum((sinusoidalfit(np.array(tlist), *popt) - my)**2)) / len(tlist)
        print >> f, "stddev=%g" % deviation
        f.close()

        assert (fittedomega - omega) / omega < 1e-4
        assert deviation < 5e-4
Beispiel #7
0
class Test(object):
    def __init__(self, mesh):
        self.mesh = mesh
        self.S1 = df.FunctionSpace(mesh, 'CG', 1)
        self.S3 = df.VectorFunctionSpace(mesh, 'CG', 1, dim=3)
        #zero = df.Expression('0.3')
        m_init = df.Constant([1, 1, 1.0])
        self.m = df.interpolate(m_init, self.S3)
        self.field = df.interpolate(m_init, self.S3)
        self.dmdt = df.interpolate(m_init, self.S3)
        self.spin = self.m.vector().array()
        self.t = 0

        #It seems it's not safe to specify rank in df.interpolate???
        self._alpha = df.interpolate(df.Constant("0.001"), self.S1)
        self._alpha.vector().set_local(self._alpha.vector().array())
        print 'dolfin', self._alpha.vector().array()

        self.llg = LLG(self.S1, self.S3, unit_length=1e-9)
        #normalise doesn't work due to the wrong order
        self.llg.set_m(m_init, normalise=True)

        parameters = {
            'absolute_tolerance': 1e-10,
            'relative_tolerance': 1e-10,
            'maximum_iterations': int(1e5)
        }

        demag = Demag()

        demag.parameters['phi_1'] = parameters
        demag.parameters['phi_2'] = parameters

        self.exchange = Exchange(13e-12)
        self.zeeman = Zeeman([0, 0, 1e5])

        self.llg.effective_field.add(self.exchange)
        #self.llg.effective_field.add(demag)
        self.llg.effective_field.add(self.zeeman)

        self.m_petsc = df.as_backend_type(self.llg.m_field.f.vector()).vec()
        self.h_petsc = df.as_backend_type(self.field.vector()).vec()
        self.alpha_petsc = df.as_backend_type(self._alpha.vector()).vec()
        self.dmdt_petsc = df.as_backend_type(self.dmdt.vector()).vec()
        alpha = 0.001
        gamma = 2.21e5
        LLG1 = -gamma / (1 + alpha * alpha) * df.cross(
            self.m,
            self.field) - alpha * gamma / (1 + alpha * alpha) * df.cross(
                self.m, df.cross(self.m, self.field))
        self.L = df.dot(LLG1, df.TestFunction(self.S3)) * df.dP

    def set_up_solver(self, rtol=1e-8, atol=1e-8):

        self.ode = cvode2.CvodeSolver(self.sundials_rhs, 0, self.m_petsc, rtol,
                                      atol)

    def sundials_rhs(self, t, y, ydot):

        self.llg.effective_field.update(t)
        self.field.vector().set_local(self.llg.effective_field.H_eff)

        #print y, self.h_petsc, self.m_petsc
        y.copy(self.m_petsc)
        df.assemble(self.L, tensor=self.dmdt.vector())
        self.dmdt_petsc.copy(ydot)
        """
        #llg_petsc.compute_dm_dt(y,
                                self.h_petsc,
                                ydot,
                                self.alpha_petsc,
                                self.llg.gamma,
                                self.llg.do_precession,
                                self.llg.c)
        """

        return 0

    def run_until(self, t):

        if t <= self.t:
            ode = self.ode
            self.spin = self.m.vector().array()
            return

        ode = self.ode

        flag = ode.run_until(t)

        if flag < 0:
            raise Exception("Run cython run_until failed!!!")

        self.m.vector().set_local(ode.y_np)

        self.spin = self.m.vector().array()
Beispiel #8
0
def run_simulation():
    """
    Translation of the nmag code.
    Mesh generated on the fly.

    """

    x0 = 0
    x1 = 15e-9
    nx = 30
    y0 = -4.5e-9
    y1 = 4.5e-9
    ny = 18
    z0 = -0.1e-9
    z1 = 0.1e-9
    nz = 1
    mesh = df.BoxMesh(df.Point(x0, y0, z0), df.Point(x1, y1, z1), nx, ny, nz)
    S1 = df.FunctionSpace(mesh, "Lagrange", 1)
    S3 = df.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3)

    nb_nodes = len(mesh.coordinates())

    llg = LLG(S1, S3)
    llg.Ms = 1e6
    llg.set_alpha(0.02)

    exchange = Exchange(1.3e-11)
    llg.effective_field.add(exchange)

    llg.set_m(("1",
               "5 * pow(cos(pi * (x[0] * pow(10, 9) - 11) / 6), 3) \
           * pow(cos(pi * x[1] * pow(10, 9) / 6), 3)",
               "0"))

    m = llg.m_numpy
    for i in xrange(nb_nodes):
        x, y, z = mesh.coordinates()[i]
        mx = 1
        my = 0
        mz = 0
        if 8e-9 < x < 14e-9 and -3e-9 < y < 3e-9:
            pass
        else:
            m[i] = mx
            m[i + nb_nodes] = my
            m[i + 2 * nb_nodes] = mz
    llg.m_field.set_with_numpy_array_debug(m)

    llg_wrap = lambda t, y: llg.solve_for(y, t)
    t0 = 0
    dt = 0.05e-12
    t1 = 10e-12
    r = ode(llg_wrap).set_integrator(
        "vode", method="bdf", rtol=1e-5, atol=1e-5)
    r.set_initial_value(llg.m_numpy, t0)

    fh = open(os.path.join(MODULE_DIR, "averages.txt"), "w")
    while r.successful() and r.t <= t1:
        mx, my, mz = llg.m_average
        fh.write(
            str(r.t) + " " + str(mx) + " " + str(my) + " " + str(mz) + "\n")
        r.integrate(r.t + dt)
    fh.close()
Beispiel #9
0
 def __init__(self, S1, S3):
     LLG.__init__(self, S1, S3)
     self.alpha = 0.5
     self.p = Constant(self.gamma / (1 + self.alpha ** 2))
Beispiel #10
0
import dolfin
import numpy
from scipy.integrate import odeint
from finmag.physics.llg import LLG
"""
Compute the behaviour of a one-dimensional strip of magnetic material,
with exchange interaction.

"""

length = 40e-9  # in meters
simplexes = 10
mesh = dolfin.Interval(simplexes, 0, length)

llg = LLG(mesh)
llg.H_app = (0, 0, llg.Ms)
llg.set_alpha(0.1)
llg.set_m(('1', '0', '0'))
llg.setup()
#llg.pins = [0, 10]

print "Solving problem..."

import visual
y = llg.m[:]
y.shape = (3, len(llg.m) / 3)
arrows = []
coordinates = (mesh.coordinates() / length - 0.5) * len(
    mesh.coordinates()) * 0.4
for i in range(y.shape[1]):
Beispiel #11
0
import dolfin as df
from finmag.physics.llg import LLG

x0 = 0
x1 = 100e-9
xn = 50
y0 = 0
y1 = 10e-9
yn = 5
nanowire = df.RectangleMesh(df.Point(x0, y0), df.Point(x1, y1), xn, yn,
                            "left/right")
S1 = df.FunctionSpace(nanowire, "Lagrange", 1)
S3 = df.VectorFunctionSpace(nanowire, "Lagrange", 1, dim=3)

llg = LLG(S1, S3)
"""
We want to increase the damping at the boundary of the object.
It is convenient to channel the power of dolfin expressions for this task.

"""

alpha_expression = df.Expression("(x[0] > x_limit) ? 1.0 : 0.5",
                                 x_limit=80e-9,
                                 degree=1)
llg.set_alpha(alpha_expression)

print "alpha vector:\n", llg.alpha.vector().array()
df.plot(llg.alpha, interactive=True)
Beispiel #12
0
"""
Compute the behaviour of a one-dimensional strip of magnetic material,
with exchange interaction.

"""

A = 1.3e-11
Ms = 8.6e5

length = 20e-9  # in meters
simplexes = 10
mesh = dolfin.Interval(simplexes, 0, length)
S1 = dolfin.FunctionSpace(mesh, "Lagrange", 1)
S3 = dolfin.VectorFunctionSpace(mesh, "Lagrange", 1, dim=3)

llg = LLG(S1, S3)
llg.set_m(('2*x[0]/L - 1', 'sqrt(1 - (2*x[0]/L - 1)*(2*x[0]/L - 1))', '0'),
          L=length)
llg.pins = [0, 10]
exchange = Exchange(A)
llg.effective_field.add(exchange)

print "Solving problem..."

ts = numpy.linspace(0, 1e-9, 10)
ys, infodict = odeint(llg.solve_for, llg.m, ts, full_output=True)

print "Used", infodict["nfe"][-1], "function evaluations."
print "Saving data..."

numpy.savetxt("1d_times.txt", ts)