Exemplo n.º 1
0
    def use_zhangli(self, J_profile=(1e10, 0, 0), P=0.5, beta=0.01, using_u0=False, with_time_update=None):
        """
        if using_u0 = True, the factor of 1/(1+beta^2) will be dropped.

        With with_time_update should be a function like:
        def f(t):
            return (0, 0, J*g(t))

        We do not use a position dependent function for performance reasons.
        """

        self.do_zhangli = True
        self.fun_zhangli_time_update = with_time_update
        self._J = helpers.vector_valued_function(J_profile, self.S3)
        self.J = self._J.vector().array()
        self.compute_gradient_matrix()
        self.H_gradm = df.PETScVector()

        const_e = 1.602176565e-19
        # elementary charge in As
        mu_B = 9.27400968e-24
        # Bohr magneton

        self.P = P
        self.beta = beta

        u0 = P * mu_B / const_e  # P g mu_B/(2 e Ms) and g=2 for electrons

        if using_u0:
            self.u0 = u0
        else:
            self.u0 = u0 / (1 + beta ** 2)
Exemplo n.º 2
0
def test_dmi_pbc2d_1D(plot=False):
    def m_init_fun(p):
        if p[0] < 10:
            return [0.5, 0, 1]
        else:
            return [-0.5, 0, -1]

    mesh = df.RectangleMesh(df.Point(0, 0), df.Point(20, 2), 10, 1)
    m_init = vector_valued_function(m_init_fun, mesh)

    Ms = 8.6e5
    sim = Simulation(mesh, Ms, pbc='2d', unit_length=1e-9)

    sim.set_m(m_init_fun)

    A = 1.3e-11
    D = 5e-3
    sim.add(Exchange(A))
    sim.add(DMI(D))

    sim.relax(stopping_dmdt=0.0001)

    if plot:
        sim.m_field.plot_with_dolfin()

    mx = [sim.m_field.probe([x + 0.5, 1])[0] for x in range(20)]

    assert np.max(np.abs(mx)) < 1e-6
Exemplo n.º 3
0
    def use_zhangli(self,
                    J_profile=(1e10, 0, 0),
                    P=0.5,
                    beta=0.01,
                    using_u0=False,
                    with_time_update=None):

        self.zhangli_stt = True
        self.fun_zhangli_time_update = with_time_update
        self.P = P
        self.beta = beta

        self._J = helpers.vector_valued_function(J_profile, self.S3)
        self.J = self._J.vector().array()
        self.compute_gradient_matrix()
        self.H_gradm = df.PETScVector()

        self.integrator = native_llb.StochasticLLGIntegratorSTT(
            self.m, self.m_pred, self._Ms, self._T, self.real_volumes,
            self._alpha, self.P, self.beta, self.stochastic_update_field,
            self.method)

        # seems that in the presence of current, the time step have to very
        # small
        self.dt = 1e-14
Exemplo n.º 4
0
    def set_parameters(self,
                       J_profile=(1e10, 0, 0),
                       P=0.5,
                       D=2.5e-4,
                       lambda_sf=5e-9,
                       lambda_J=1e-9,
                       speedup=1):

        self._J = helpers.vector_valued_function(J_profile, self.S3)
        self.J = self._J.vector().array()
        self.compute_gradient_matrix()
        self.H_gradm = df.PETScVector()

        self.P = P

        self.D = D / speedup
        self.lambda_sf = lambda_sf
        self.lambda_J = lambda_J

        self.tau_sf = lambda_sf**2 / D * speedup
        self.tau_sd = lambda_J**2 / D * speedup

        self.compute_laplace_matrix()
        self.H_laplace = df.PETScVector()

        self.nodal_volume_S3 = nodal_volume(self.S3)
Exemplo n.º 5
0
def run_measurements(m, mesh, unit_length, tol, repetitions=10, H_expected=None, name="", skip=[]):
    S3 = df.VectorFunctionSpace(mesh, "CG", 1)
    m = vector_valued_function(m, S3)
    Ms = 1
    bem, boundary_to_global = compute_bem_fk(df.BoundaryMesh(mesh, 'exterior', False))

    if H_expected is not None:
        H = vector_valued_function(H_expected, S3)
        H_expected = H.vector().array()
    else:
        # use default/default as reference then.
        demag = fk.FKDemag()
        demag.precomputed_bem(bem, boundary_to_global)
        demag.setup(S3, m, Ms, unit_length)
        H_expected = demag.compute_field()
        del(demag)

    if name == "":
        pass
    else:
        name = name + "_"

    runner = create_measurement_runner(S3, m, Ms, unit_length,
                                       H_expected, tol, repetitions,
                                       bem, boundary_to_global)

    solvers = [s[0] for s in df.krylov_solver_methods()]
    preconditioners = [p[0] for p in df.krylov_solver_preconditioners()]

    results_1, failed_1 = runner("first linear solve",
                                 "phi_1_solver", solvers,
                                 "phi_1_preconditioner", preconditioners,
                                 skip,
                                 "{}timings_log_1.txt".format(name),
                                 "{}results_1.pickled".format(name))

    results_2, failed_2 = runner("second linear solve",
                                 "phi_2_solver", solvers,
                                 "phi_2_preconditioner", preconditioners,
                                 skip,
                                 "{}timings_log_2.txt".format(name),
                                 "{}results_2.pickled".format(name))

    return solvers, preconditioners, results_1, failed_1, results_2, failed_2
Exemplo n.º 6
0
def run_demag_benchmark(m,
                        mesh,
                        unit_length,
                        tol,
                        repetitions=10,
                        name="bench",
                        H_expected=None):
    S3 = df.VectorFunctionSpace(mesh, "CG", 1)
    m = vector_valued_function(m, S3)
    Ms = 1

    # pre-compute BEM to save time
    bem, boundary_to_global = compute_bem_fk(
        df.BoundaryMesh(mesh, 'exterior', False))

    if H_expected is not None:
        H = vector_valued_function(H_expected, S3)
        H_expected = H.vector().array()
    else:  # if no H_expected was passed, use default/default as reference
        demag = fk.FKDemag()
        demag.precomputed_bem(bem, boundary_to_global)
        demag.setup(S3, m, Ms, unit_length)
        H_expected = demag.compute_field()
        del (demag)

    # gather all solvers and preconditioners
    solvers = [s[0] for s in df.krylov_solver_methods()]
    preconditioners = [p[0] for p in df.krylov_solver_preconditioners()]

    benchmark = prepare_benchmark(S3, m, Ms, unit_length, H_expected, tol,
                                  repetitions, bem, boundary_to_global)
    results_1 = benchmark("first linear solve",
                          "phi_1_solver",
                          solvers,
                          "phi_1_preconditioner",
                          preconditioners,
                          name=name + "_1")
    results_2 = benchmark("second linear solve",
                          "phi_2_solver",
                          solvers,
                          "phi_2_preconditioner",
                          preconditioners,
                          name=name + "_2")
    return solvers, preconditioners, results_1, results_2
Exemplo n.º 7
0
    def solve(self, t):
        # we don't use self.effective_field.compute(t) for performance reasons
        self.effective_field.update(t)
        H_eff = self.effective_field.H_eff[self.v2d_xxx]  # alias (for readability)
        H_eff.shape = (3, -1)

        timer.start("solve", self.__class__.__name__)
        # Use the same characteristic time as defined by c
        char_time = 0.1 / self.c
        # Prepare the arrays in the correct shape
        m = self._m_field.get_ordered_numpy_array_xxx()
        m.shape = (3, -1)

        dmdt = np.zeros(m.shape)
        alpha__ = self.alpha.vector().array()[self.v2d_scale]
        # Calculate dm/dt
        if self.do_slonczewski:
            if self.fun_slonczewski_time_update != None:
                J_new = self.fun_slonczewski_time_update(t)
                self.J[:] = J_new
            native_llg.calc_llg_slonczewski_dmdt(
                m, H_eff, t, dmdt, self.pins,
                self.gamma, alpha__,
                char_time,
                self.Lambda, self.epsilonprime,
                self.J, self.P, self.d, self._Ms, self.p)
        elif self.do_zhangli:
            if self.fun_zhangli_time_update != None:
                J_profile = self.fun_zhangli_time_update(t)
                self._J = helpers.vector_valued_function(J_profile, self.S3)
                self.J = self._J.vector().array()
                self.compute_gradient_matrix()

            H_gradm = self.compute_gradient_field()
            H_gradm.shape = (3, -1)
            native_llg.calc_llg_zhang_li_dmdt(
                m, H_eff, H_gradm, t, dmdt, self.pins,
                self.gamma, alpha__,
                char_time,
                self.u0, self.beta, self._Ms)
            H_gradm.shape = (-1,)
        else:
            native_llg.calc_llg_dmdt(m, H_eff, t, dmdt, self.pins,
                                     self.gamma, alpha__,
                                     char_time, self.do_precession)
        dmdt.shape = (-1,)
        H_eff.shape = (-1,)

        timer.stop("solve", self.__class__.__name__)

        self._dmdt.vector().set_local(dmdt[self.d2v_xxx])

        return dmdt
def three_dimensional_problem():
    x_max = 10e-9
    y_max = 1e-9
    z_max = 1e-9
    mesh = df.BoxMesh(df.Point(0, 0, 0), df.Point(x_max, y_max, z_max), 40, 2,
                      2)

    V = df.VectorFunctionSpace(mesh, 'Lagrange', 1)

    Ms = 8.6e5

    m0_x = "pow(sin(0.2*x[0]*1e9), 2)"
    m0_y = "0"
    m0_z = "pow(cos(0.2*x[0]*1e9), 2)"
    m = Field(V,
              value=vector_valued_function((m0_x, m0_y, m0_z),
                                           V,
                                           normalise=True))

    C = 1.3e-11

    u_exch = Exchange(C)
    u_exch.setup(m, Field(df.FunctionSpace(mesh, 'DG', 0), Ms))
    finmag_exch = u_exch.compute_field()

    magpar_result = os.path.join(MODULE_DIR, 'magpar_result', 'test_exch')
    nodes, magpar_exch = magpar.get_field(magpar_result, 'exch')

    ## Uncomment the line below to invoke magpar to compute the results,
    ## rather than using our previously saved results.
    # nodes, magpar_exch = magpar.compute_exch_magpar(m, A=C, Ms=Ms)

    print magpar_exch

    # Because magpar have changed the order of the nodes!!!

    tmp = df.Function(V)
    tmp_c = mesh.coordinates()
    mesh.coordinates()[:] = tmp_c * 1e9

    finmag_exch, magpar_exch, \
        diff, rel_diff = magpar.compare_field(
            mesh.coordinates(), finmag_exch,
            nodes, magpar_exch)

    return dict(m0=m.get_numpy_array_debug(),
                mesh=mesh,
                exch=finmag_exch,
                magpar_exch=magpar_exch,
                diff=diff,
                rel_diff=rel_diff)
Exemplo n.º 9
0
    def set_m(self, value, normalise=True, **kwargs):
        """
        Set the magnetisation (if `normalise` is True, it is automatically
        normalised to unit length).

        `value` can have any of the forms accepted by the function
        'finmag.util.helpers.vector_valued_function' (see its
        docstring for details).

        You can call this method anytime during the simulation. However, when
        providing a numpy array during time integration, the use of
        the attribute m instead of this method is advised for performance
        reasons and because the attribute m doesn't normalise the vector.

        """
        self.m = helpers.vector_valued_function(value,
                                                self.S3,
                                                normalise=normalise,
                                                **kwargs).vector().array()
Exemplo n.º 10
0
    def setup(self, m, Ms, unit_length=1):
        self.m = m
        self.Ms = Ms
        self.unit_length = unit_length
        if self.scalar_df_expression:
            dofmap = m.functionspace.dofmap()
            self.S1 = df.FunctionSpace(
                m.mesh(),
                "Lagrange",
                1,
                constrained_domain=dofmap.constrained_domain)
            self.h0 = helpers.scalar_valued_function(self.df_expression,
                                                     self.S1).vector().array()
            self.H0 = df.Function(m.functionspace)
        else:
            self.H0 = helpers.vector_valued_function(self.df_expression,
                                                     self.m.functionspace)

        self.E = -mu0 * self.Ms.f * df.dot(self.m.f, self.H0)

        self.H_init = self.H0.vector().array()
        self.H = self.H_init.copy()
Exemplo n.º 11
0
    def set_m(self, value, normalise=True, **kwargs):
        """
        Set the magnetisation (if `normalise` is True, it is automatically
        normalised to unit length).

        `value` can have any of the forms accepted by the function
        'finmag.util.helpers.vector_valued_function' (see its
        docstring for details).

        You can call this method anytime during the simulation. However, when
        providing a numpy array during time integration, the use of
        the attribute m instead of this method is advised for performance
        reasons and because the attribute m doesn't normalise the vector.

        """
        m0 = helpers.vector_valued_function(value, self.S3, normalise=False, **kwargs).vector().array()[self.v2d_xxx]

        if np.any(np.isnan(m0)):
            raise ValueError("Attempting to initialise m with NaN(s)")

        if normalise:
            m0 = helpers.fnormalise(m0)
        self._m_field.set_with_ordered_numpy_array_xxx(m0)
Exemplo n.º 12
0
 def set_m(self, value, normalise=True):
     m_tmp = helpers.vector_valued_function(
         value, self.S3, normalise=normalise).vector().array()
     self._m_field.set_with_numpy_array_debug(m_tmp)
     self.m[:] = self._m_field.get_numpy_array_debug()
Exemplo n.º 13
0
 def set_M(self, value, **kwargs):
     self._M = helpers.vector_valued_function(value, self.S3, normalise=False)
     self.M[:]=self._M.vector().array()[:]
Exemplo n.º 14
0
 def get_dolfin_function(self, interaction_name, region=None):
     interaction = self.get(interaction_name)
     return vector_valued_function(interaction.compute_field(),
                                   self.m_field.functionspace)