Esempio n. 1
0
    def sundials_rhs(self, time, y, ydot):

        self.ode_count += 1
        timer.start("sundials_rhs", self.__class__.__name__)

        self.compute_effective_field(y)

        ydot.shape = (self.total_image_num, -1)

        for i in range(self.image_num):
            h = self.Heff[i]
            t = self.tangents[i]
            sf = self.springs[i]

            h3 = h - np.dot(h, t) * t + sf * t

            ydot[i + 1, :] = h3[:]

        ydot[0, :] = 0
        ydot[-1, :] = 0

        ydot.shape = (-1, )

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

        return 0
Esempio n. 2
0
    def sundials_rhs(self, t, y, ydot):
        self.t = t
        self._m.vector().set_local(y)

        for func in self._pre_rhs_callables:
            func(self.t)

        self.compute_effective_field()

        timer.start("sundials_rhs", self.__class__.__name__)
        # Use the same characteristic time as defined by c

        native_llb.calc_llb_dmdt(self._m.vector().array(), self.H_eff,
                                 self.dm_dt, self.material.T, self.pins,
                                 self._alpha, self.gamma_LL, self.material.Tc,
                                 self.do_precession)

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

        for func in self._post_rhs_callables:
            func(self)

        ydot[:] = self.dm_dt[:]

        return 0
Esempio n. 3
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
Esempio n. 4
0
    def sundials_rhs(self, t, y, ydot):
        self.t = t

        y.shape = (2, -1)
        self._m_field.set_with_numpy_array_debug(y[0])
        self._delta_m.vector().set_local(y[1])
        y.shape = (-1, )

        self.effective_field.update(t)
        H_eff = self.effective_field.H_eff  # alias (for readability)
        H_eff.shape = (3, -1)

        timer.start("sundials_rhs", self.__class__.__name__)
        # Use the same characteristic time as defined by c

        H_gradm = self.compute_gradient_field()
        H_gradm.shape = (3, -1)

        H_laplace = self.compute_laplace_field()
        H_laplace.shape = (3, -1)

        self.dm_dt.shape = (6, -1)

        m = self.m
        m.shape = (3, -1)

        char_time = 0.1 / self.c

        delta_m = self._delta_m.vector().array()
        delta_m.shape = (3, -1)

        native_llg.calc_llg_nonlocal_stt_dmdt(m, delta_m, H_eff, H_laplace,
                                              H_gradm, self.dm_dt, self.pins,
                                              self.gamma, self._alpha,
                                              char_time, self.P, self.tau_sd,
                                              self.tau_sf, self._Ms)

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

        self.dm_dt.shape = (-1, )
        ydot[:] = self.dm_dt[:]

        H_gradm.shape = (-1, )
        H_eff.shape = (-1, )
        m.shape = (-1, )
        delta_m.shape = (-1, )

        return 0
Esempio n. 5
0
    def sundials_rhs(self, time, y, ydot):
        """

        Right hand side of the optimization scheme used to find the minimum
        energy path. In our case, we use a LLG kind of equation:

            d Y / dt = Y x Y x D

            D = -( nabla E + [nabla E * t] t ) + F_spring

        where Y is an image: Y = (M_0, ... , M_N) and t is the tangent vector
        defined according to the energy of the neighbouring images (see
        Henkelman et al publication)

        If a climbing_image index is specified, the corresponding image
        will be iterated without the spring force and with an inversed
        component along the tangent

        """
        # Update the ODE solver
        self.ode_count += 1
        timer.start("sundials_rhs", self.__class__.__name__)

        # Compute the eff field H for every image, H = -nabla E
        # (derived with respect to M)
        self.compute_effective_field(y)

        # Reshape y and ydot in a matrix of total_image_num rows
        y.shape = (self.total_image_num, -1)
        ydot.shape = (self.total_image_num, -1)

        # Compute the total force for every image (not the extremes)
        # Rememeber that self.image_num = self.total_image_num - 2
        # The total force is:
        #   D = - (-nabla E + [nabla E * t] t) + F_spring
        # This value is different is a climbing image is specified:
        #   D_climb = -nabla E + 2 * [nabla E * t] t
        for i in range(self.image_num):
            h = self.Heff[i + 1]
            t = self.tangents[i]
            sf = self.springs[i]

            if not (self.climbing_image and i == self.climbing_image):
                h3 = h - np.dot(h, t) * t + sf * t
            else:
                h3 = h - 2 * np.dot(h, t) * t

            h[:] = h3[:]

            #ydot[i+1, :] = h3[:]

        # Update the step with the optimisation algorithm, in this
        # case we use: dY /dt = Y x Y x D
        # (check the C++ code in finmag/native/src/)
        native_neb.compute_dm_dt(y, self.Heff, ydot)

        ydot[0, :] = 0
        ydot[-1, :] = 0

        y.shape = (-1, )
        ydot.shape = (-1, )

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

        return 0