Example #1
0
 def set_options(self,
                 J=50.0 * const.k_B,
                 J1=0,
                 D=0,
                 D1=0,
                 Kc=0,
                 H=None,
                 seed=100,
                 T=10.0,
                 S=1):
     """
     J, D and Kc in units of Joule
     H in units of Tesla.
     S is the spin length
     """
     self.mc.set_seed(seed)
     self.J = J / const.k_B
     self.J1 = J1 / const.k_B
     self.D = D / const.k_B
     self.D1 = D1 / const.k_B
     self.T = T
     self.Kc = Kc / const.k_B
     self.mu_s = 1.0
     if H is not None:
         self._H[:] = helper.init_vector(H, self.mesh)
         self._H[:] = self._H[:] * const.mu_s_1 * S / const.k_B
Example #2
0
    def set_m(self, m0=(1, 0, 0),
              normalise=True):
        """

        Set the magnetisation/spin three dimensional vector field profile.

        ARGUMENTS:

        m0      :: * To set every spin with the same direction,
                   set this value as a 3 elements tuple or list.

                   * For a spatially dependent vector field, you can specify a
                   function that returns a 3 element list depending on the
                   spatial coordinates. For example, a magnetisation field that
                   depends on the x position:

                        def m_profile(r):
                            for r[0] > 2:
                                return (0, 0, 1)
                            else:
                                return (0, 0, -1)

                   * You can also manually specify an array with (3 * n)
                   elements with the spins directions in the following order:

                        [mx_0 my_0 mz_0 mx_1 my_1 ... mx_n, my_n, mz_n]

                   where n is the number of mesh nodes and the order of the
                   magnetisation vectors follow the same order than the mesh
                   coordinates array.

                   * Alternatively, if you previously saved the magnetisation
                   field array to a numpy file, you can load it using
                   numpy.load(my_array)

        """

        self.spin[:] = helper.init_vector(m0, self.mesh, 3, normalise)

        # TODO: carefully checking and requires to call set_mu first

        # Set the magnetisation/spin direction to (0, 0, 0) for sites
        # with no material, i.e. M_s = 0 or mu_s = 0
        # TODO: Check for atomistic and micromagnetic cases
        self.spin.shape = (-1, 3)
        for i in range(self.spin.shape[0]):
            if self._magnetisation[i] == 0:
                self.spin[i, :] = 0
        self.spin.shape = (-1,)

        # Set the initial state for the Sundials integrator using the
        # spins array
        # Minimiser methods do not have integrator
        try:
            self.driver.integrator.set_initial_value(self.spin, self.driver.t)
        except AttributeError:
            pass
Example #3
0
    def setup(self, mesh, spin, mu_s, mu_s_inv):
        self.mesh = mesh
        self.spin = spin
        self.n = mesh.n

        self.mu_s = mu_s

        self.field = np.zeros(3 * self.n)
        self.field[:] = helper.init_vector(self.B0, self.mesh)
Example #4
0
    def set_m(self, m0=(1, 0, 0), normalise=True):
        self.spin[:] = helper.init_vector(m0, self.mesh, normalise)

        # TODO: carefully checking and requires to call set_mu first

        self.spin.shape = (-1, 3)
        for i in range(self.spin.shape[0]):
            if self._mu_s[i] == 0:
                self.spin[i, :] = 0
        self.spin.shape = (-1, )
    def set_m(self, m0=(1, 0, 0), normalise=True):
        self.spin[:] = helper.init_vector(m0, self.mesh, normalise)

        # TODO: carefully checking and requires to call set_mu first

        self.spin.shape = (-1, 3)
        for i in range(self.spin.shape[0]):
            if self._mu_s[i] == 0:
                self.spin[i, :] = 0
        self.spin.shape = (-1,)
Example #6
0
    def set_m(self, m0=(1, 0, 0),
              normalise=True):
        """

        Set the magnetisation/spin three dimensional vector field profile.

        ARGUMENTS:

        m0      :: * To set every spin with the same direction,
                   set this value as a 3 elements tuple or list.

                   * For a spatially dependent vector field, you can specify a
                   function that returns a 3 element list depending on the
                   spatial coordinates. For example, a magnetisation field that
                   depends on the x position:

                        def m_profile(r):
                            for r[0] > 2:
                                return (0, 0, 1)
                            else:
                                return (0, 0, -1)

                   * You can also manually specify an array with (3 * n)
                   elements with the spins directions in the following order:

                        [mx_0 my_0 mz_0 mx_1 my_1 ... mx_n, my_n, mz_n]

                   where n is the number of mesh nodes and the order of the
                   magnetisation vectors follow the same order than the mesh
                   coordinates array.

                   * Alternatively, if you previously saved the magnetisation
                   field array to a numpy file, you can load it using
                   numpy.load(my_array)

        """

        self.spin[:] = helper.init_vector(m0, self.mesh, normalise)

        # TODO: carefully checking and requires to call set_mu first

        # Set the magnetisation/spin direction to (0, 0, 0) for sites
        # with no material, i.e. M_s = 0 or mu_s = 0
        # TODO: Check for atomistic and micromagnetic cases
        self.spin.shape = (-1, 3)
        for i in range(self.spin.shape[0]):
            if self._magnetisation[i] == 0:
                self.spin[i, :] = 0
        self.spin.shape = (-1,)

        # Set the initial state for the Sundials integrator using the
        # spins array
        self.driver.integrator.set_initial_value(self.spin, self.driver.t)
Example #7
0
    def setup(self, mesh, spin, Ms, Ms_inv):
        self.mesh = mesh
        self.spin = spin
        self.n = mesh.n

        self.Ms = Ms

        # TODO: Check if it is necessary to define a 3D matrix for
        # the Ms vectors. Maybe there is a way that uses less memory
        # (see the calculation in the *compute_energy* function)
        self.field = np.zeros(3 * self.n)
        self.field[:] = helper.init_vector(self.H0, self.mesh, 3)
Example #8
0
 def set_options(self, J=50.0, D=0, H=None, seed=100, T=10.0):
     """
     J and D in units of k_B
     H in units of Tesla.
     """
     clib.init_random(seed)
     self.J = J
     self.D = D
     self.T = T
     self.mu_s =  1.0
     if H is not None:
         self._H[:] = helper.init_vector(H, self.mesh)
         self._H[:] = self._H[:]*const.mu_s_1/const.k_B
Example #9
0
    def setup(self, mesh, spin, Ms):
        self.mesh = mesh
        self.spin = spin
        self.n = mesh.n

        self.Ms = Ms
        self.Ms_long = np.zeros(3 * mesh.n)

        self.Ms_long.shape = (3, -1)
        for i in range(mesh.n):
            self.Ms_long[:, i] = Ms[i]

        self.Ms_long.shape = (-1,)
        self.field = np.zeros(3 * self.n)
        self.field[:] = helper.init_vector(self.H0, self.mesh)
Example #10
0
    def setup(self, mesh, spin, mu_s):
        self.mesh = mesh
        self.spin = spin
        self.n = mesh.n

        self.mu_s = mu_s
        self.mu_s_long = np.zeros(3 * mesh.n)

        self.mu_s_long.shape = (-1, 3)
        for i in range(mesh.n):
            self.mu_s_long[i, :] = mu_s[i]

        self.mu_s_long.shape = (-1, )

        self.field = np.zeros(3 * self.n)
        self.field[:] = helper.init_vector(self.H0, self.mesh)
Example #11
0
    def setup(self, mesh, spin, mu_s):
        self.mesh = mesh
        self.spin = spin
        self.n = mesh.n

        self.mu_s = mu_s
        self.mu_s_long = np.zeros(3 * mesh.n)

        self.mu_s_long.shape = (-1, 3)
        for i in range(mesh.n):
            self.mu_s_long[i, :] = mu_s[i]

        self.mu_s_long.shape = (-1,)

        self.field = np.zeros(3 * self.n)
        self.field[:] = helper.init_vector(self.H0, self.mesh)
 def set_options(self, J=50.0, J1=0, D=0, D1=0, Kc=0, H=None, seed=100, T=10.0, S=1):
     """
     J, D and Kc in units of k_B
     H in units of Tesla.
     S is the spin length
     """
     self.mc.set_seed(seed)
     self.J = J
     self.J1 = J1
     self.D = D
     self.D1 = D1
     self.T = T
     self.Kc = Kc
     self.mu_s =  1.0
     if H is not None:
         self._H[:] = helper.init_vector(H, self.mesh)
         self._H[:] = self._H[:]*const.mu_s_1*S/const.k_B  #We have set k_B = 1
Example #13
0
    def setup(self, mesh, spin, Ms):
        self.mesh = mesh
        self.spin = spin
        self.n = mesh.n

        self.Ms = Ms
        self.Ms_long = np.zeros(3 * mesh.n)

        # TODO: Check if it is necessary to define a 3D matrix for
        # the Ms vectors. Maybe there is a way that uses less memory
        # (see the calculation in the *compute_energy* function)
        self.Ms_long.shape = (3, -1)
        for i in range(mesh.n):
            self.Ms_long[:, i] = Ms[i]

        self.Ms_long.shape = (-1,)
        self.field = np.zeros(3 * self.n)
        self.field[:] = helper.init_vector(self.H0, self.mesh)
Example #14
0
    def setup(self, mesh, spin, Ms):
        self.mesh = mesh
        self.spin = spin
        self.n = mesh.n

        self.Ms = Ms
        self.Ms_long = np.zeros(3 * mesh.n)

        # TODO: Check if it is necessary to define a 3D matrix for
        # the Ms vectors. Maybe there is a way that uses less memory
        # (see the calculation in the *compute_energy* function)
        self.Ms_long.shape = (3, -1)
        for i in range(mesh.n):
            self.Ms_long[:, i] = Ms[i]

        self.Ms_long.shape = (-1,)
        self.field = np.zeros(3 * self.n)
        self.field[:] = helper.init_vector(self.H0, self.mesh)
    def setup(self, mesh, spin, Ms, Ms_inv):
        super(UniaxialAnisotropy4, self).setup(mesh, spin, Ms, Ms_inv)

        self._K1 = helper.init_scalar(self.K1, self.mesh)
        self._K2 = helper.init_scalar(self.K2, self.mesh)
        self._axis = helper.init_vector(self.axis, self.mesh, 3, norm=True)
Example #16
0
 def update_field(self, B0):
     self.B0 = B0
     self.field[:] = helper.init_vector(self.B0, self.mesh)
Example #17
0
 def set_p(self, value):
     self._p[:] = helper.init_vector(value, self.mesh, 3)
Example #18
0
 def update_field(self, H0):
     self.H0 = H0
     self.field[:] = helper.init_vector(self.H0, self.mesh)
Example #19
0
    def setup(self, mesh, spin, mu_s, mu_s_inv):
        super(Anisotropy, self).setup(mesh, spin, mu_s, mu_s_inv)

        self._Ku = helper.init_scalar(self.Ku, self.mesh)
        self._axis = helper.init_vector(self.axis, self.mesh, norm=True)
 def set_p(self, value):
     self._p[:] = helper.init_vector(value, self.mesh)
Example #21
0
    def setup(self, mesh, spin, Ms):
        super(UniaxialAnisotropy, self).setup(mesh, spin, Ms)

        self._Ku = helper.init_scalar(self.Ku, self.mesh)
        self._axis = helper.init_vector(self.axis, self.mesh, True)
Example #22
0
 def update_field(self, H0):
     self.H0 = H0
     self.field[:] = helper.init_vector(self.H0, self.mesh)
Example #23
0
    def setup(self, mesh, spin, Ms):
        super(UniaxialAnisotropy, self).setup(mesh, spin, Ms)

        self._Ku = helper.init_scalar(self.Ku, self.mesh)
        self._axis = helper.init_vector(self.axis, self.mesh, True)
Example #24
0
    def setup(self, mesh, spin, Ms, Ms_inv):
        super(DMI, self).setup(mesh, spin, Ms, Ms_inv)

        if self.dmi_type == 'bulk':
            self.dmi_vector = np.array([
                -1., 0, 0, 1., 0, 0, 0, -1., 0, 0, 1., 0, 0, 0, -1., 0, 0, 1.
            ])

        elif self.dmi_type == 'interfacial':
            self.dmi_vector = np.array([
                0,
                -1.,
                0,  # -x
                0,
                1.,
                0,  # +x
                1.,
                0,
                0,  # -y
                -1.,
                0,
                0,  # +y
                0,
                0,
                0,  # -z
                0,
                0,
                0  # +z
            ])

        elif self.dmi_type == 'D_2d':
            self.dmi_vector = np.array([
                1.,
                0,
                0,  # -x
                -1.,
                0,
                0,  # +x
                0,
                -1.,
                0,  # -y
                0,
                1.,
                0,  # +y
                0,
                0,
                0,  # -z
                0,
                0,
                0  # +z
            ])

        # For the following DMIs with two constants check:
        # Leonov: Chiral skyrmion states in non-centrosymmetric magnets
        # https://arxiv.org/pdf/1406.2177.pdf
        # Leonov thesis: http://nbn-resolving.de/urn:nbn:de:bsz:14-qucosa-83823
        elif self.dmi_type == 'D_n':
            self.dmi_vector = np.array([
                -1,
                0,
                0,  # D1 components
                1,
                0,
                0,
                0,
                -1,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,  # D2 components
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                1,
                0,
                0,
                -1,
            ])

        elif self.dmi_type == 'C_n':
            self.dmi_vector = np.array([
                0,
                -1.,
                0,  # -x
                0,
                1.,
                0,  # +x
                1.,
                0,
                0,  # -y
                -1.,
                0,
                0,  # +y
                0,
                0,
                0,  # -z
                0,
                0,
                0,  # +z
                -1,
                0,
                0,  # D2 components
                1,
                0,
                0,
                0,
                -1,
                0,
                0,
                1,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
            ])
        elif self.dmi_type == 'custom':
            self.dmi_vector = np.array(self.dmi_vector)
            # Example:
            # self.DMI_vector = [ 0, 0, D1,  # DMI 1
            #                     0, 0, -D1,
            #                     0, 0, 0,
            #                     0, 0, 0,
            #                     0, 0, 0,
            #                     0, 0, 0,
            #                     0, 0, 0,   # DMI 2
            #                     0, 0, 0,
            #                     0, D2, 0,
            #                     0, -D2, 0,
            #                     0, 0, 0,
            #                     0, 0, 0,
            #                   ]
            n_Ds = len(self.dmi_vector) // 18

            if len(self.dmi_vector) % 18 != 0:
                raise Exception('The DMI vector length must be a mult of 18: '
                                ' N of DMIs times 3 * number of ngbs = 18')

            if n_Ds > 1:
                self.Ds = helper.init_vector(self.D, self.mesh, dim=n_Ds)
            else:
                self.Ds = helper.init_scalar(self.D, self.mesh)

            self.n_dmis = n_Ds

        if self.dmi_type == 'C_n' or self.dmi_type == 'D_n':
            self.Ds = helper.init_vector(self.D, self.mesh, dim=2)
            self.n_dmis = 2
        else:
            self.Ds = helper.init_scalar(self.D, self.mesh)
            self.n_dmis = 1