Ejemplo n.º 1
0
    def run_step(self):

        self.spin_last[:] = self.spin[:]
        self.update_effective_field()

        self._new_spin[self._material] = (self.spin +
                                          self.field)[self._material]
        clib.normalise_spin(self._new_spin, self._pins, self.n)

        self._new_spin[self._material] = (
            self.spin_last + self._alpha_field *
            (self._new_spin - self.spin_last))[self._material]
        self.spin[:] = self._new_spin[:]
        clib.normalise_spin(self.spin, self._pins, self.n)
Ejemplo n.º 2
0
    def run_step(self):

        clib.random_number_array(self.eta)

        #step1
        self.update_effective_field(self.spin, self.t)
        clib.compute_llg_rhs_dw(self.dm1, self.spin, self.field, self._T,
                                self._alpha, self._mu_s_inv, self.eta,
                                self._pins, self.n, self.gamma, self.dt)
        self.next_spin = self.spin + self.theta * self.dm1

        self.minor_step += 1
        self.t = self.dt * self.minor_step

        #step2
        self.update_effective_field(self.next_spin, self.t)
        clib.compute_llg_rhs_dw(self.dm2, self.next_spin, self.field, self._T,
                                self._alpha, self._mu_s_inv, self.eta,
                                self._pins, self.n, self.gamma, self.dt)
        self.spin += (self.theta1 * self.dm1 + self.theta2 * self.dm2)

        clib.normalise_spin(self.spin, self._pins, self.n)
Ejemplo n.º 3
0
    def run_step(self):

        self.mt19937.fill_vector_gaussian(self.eta)

        #step1
        self.update_effective_field(self.spin, self.t)
        clib.compute_llg_rhs_dw(self.dm1,
                                self.spin,
                                self.field,
                                self._T,
                                self._alpha,
                                self._mu_s_inv,
                                self.eta,
                                self._pins,
                                self.n,
                                self.gamma,
                                self.dt)
        self.next_spin = self.spin + self.theta * self.dm1

        self.minor_step += 1
        self.t = self.dt*self.minor_step

        #step2
        self.update_effective_field(self.next_spin, self.t)
        clib.compute_llg_rhs_dw(self.dm2,
                                self.next_spin,
                                self.field,
                                self._T,
                                self._alpha,
                                self._mu_s_inv,
                                self.eta,
                                self._pins,
                                self.n,
                                self.gamma,
                                self.dt)
        self.spin += (self.theta1*self.dm1+self.theta2*self.dm2)

        clib.normalise_spin(self.spin, self._pins, self.n)
Ejemplo n.º 4
0
    def run_step(self):
        """
        Numpy version of the calculation
        """

        # ---------------------------------------------------------------------

        self.mxH.shape = (-1, 3)
        self.mxmxH.shape = (-1, 3)
        self.spin.shape = (-1, 3)

        mxH_sq_norm = np.sum(self.mxH**2, axis=1)
        factor_plus = 4 + (self.tau**2) * mxH_sq_norm
        factor_minus = 4 - (self.tau**2) * mxH_sq_norm

        # Compute: m[i+1] = ((4 - t^2 A^2) * m[i] - 4 * t * m[i] x m[i] x H) / (4 + t^2 A^2)
        # where "t = self.tau" is the time step and "A = m[i] x H"
        new_spin = (
            factor_minus[:, np.newaxis] * self.spin -
            (4 * self.tau)[:, np.newaxis] * self.mxmxH
            # this term should be zero:
            # + (2 * (self.tau ** 2) * np.sum(self.mxH * self.spin, axis=1))[:, np.newaxis] * self.mxH
        )
        new_spin = new_spin / factor_plus[:, np.newaxis]

        self.mxH.shape = (-1, )
        self.mxmxH.shape = (-1, )
        self.spin.shape = (-1, )
        new_spin.shape = (-1, )

        self.spin_last[:] = self.spin[:]
        self.spin[:] = new_spin[:]
        atom_clib.normalise_spin(self.spin, self._pins, self.n)

        # ---------------------------------------------------------------------

        # Update the effective field, torques and time step for the next iter
        self.compute_effective_field()
        # self._n_field[:] = self.field[:]
        # atom_clib.normalise_spin(self._n_field, self._pins, self.n)
        self.mxmxH_last[:] = self.mxmxH[:]
        self.mxH[:] = self.field_cross_product(self.spin,
                                               self.scale * self.field)[:]
        self.mxmxH[:] = self.field_cross_product(self.spin, self.mxH)[:]

        # ---------------------------------------------------------------------
        # Define the time step tau

        ds = (self.spin - self.spin_last).reshape(-1, 3)
        dy = (self.mxmxH - self.mxmxH_last).reshape(-1, 3)

        if self.step % 2 == 0:
            num = np.sum(ds * ds, axis=1)
            den = np.sum(ds * dy, axis=1)
        else:
            num = np.sum(ds * dy, axis=1)
            den = np.sum(dy * dy, axis=1)

        # The criteria is taken from the Micromagnum code
        self.tau = self._tmax * np.ones_like(num)
        self.tau[den != 0] = num[den != 0] / den[den != 0]

        tau_signs = np.sign(self.tau)

        self._tmax_arr[:, 0] = np.abs(self.tau)
        # Set the minimum between the abs value of tau and the max tolerance
        self._tmin_arr[:, 0] = np.min(self._tmax_arr, axis=1)
        # Set the maximum between the previous minimum and the min tolerance
        self.tau = tau_signs * np.max(self._tmin_arr, axis=1)
    def run_step(self):
        """
        Numpy version of the calculation
        """

        # ---------------------------------------------------------------------

        self.mxH.shape = (-1, 3)
        self.mxmxH.shape = (-1, 3)
        self.spin.shape = (-1, 3)

        mxH_sq_norm = np.sum(self.mxH**2, axis=1)
        factor_plus = 4 + (self.tau**2) * mxH_sq_norm
        factor_minus = 4 - (self.tau**2) * mxH_sq_norm

        # Compute: m[i+1] = ((4 - t^2 A^2) * m[i] - 4 * t * m[i] x m[i] x H) / (4 + t^2 A^2)
        # where "t = self.tau" is the time step and "A = m[i] x H"
        new_spin = (
            factor_minus[:, np.newaxis] * self.spin - 4 * self.tau * self.mxmxH
            # this term should be zero:
            # + (2 * (self.tau ** 2) * np.sum(self.mxH * self.spin, axis=1))[:, np.newaxis] * self.mxH
        )
        new_spin = new_spin / factor_plus[:, np.newaxis]

        self.mxH.shape = (-1, )
        self.mxmxH.shape = (-1, )
        self.spin.shape = (-1, )
        new_spin.shape = (-1, )

        self.spin_last[:] = self.spin[:]
        self.spin[:] = new_spin[:]
        atom_clib.normalise_spin(self.spin, self._pins, self.n)

        # ---------------------------------------------------------------------

        # Update the effective field, torques and time step for the next iter
        self.compute_effective_field()

        self.mxmxH_last[:] = self.mxmxH[:]
        self.mxH[:] = self.field_cross_product(self.spin,
                                               self.scale * self.field)[:]
        self.mxmxH[:] = self.field_cross_product(self.spin, self.mxH)[:]

        # ---------------------------------------------------------------------
        # Define the time step tau

        ds = (self.spin - self.spin_last).reshape(-1, 3)
        dy = (self.mxmxH - self.mxmxH_last).reshape(-1, 3)

        if self.step % 2 == 0:
            num = np.sum(ds * ds)
            den = np.sum(ds * dy)
        else:
            num = np.sum(ds * dy)
            den = np.sum(dy * dy)

        # The criteria is taken from the Micromagnum code
        if den == 0:
            self.tau = self._tmax
        else:
            self.tau = num / den