def set_alpha(self, value):
        """

        Set the Gilbert damping of the system as a uniform or spatially
        dependent scalar field

        ARGUMENTS:

        value     :: * For a uniform damping across the whole sample, just
                       specify a float ranging from 0 to 1

                     * In addition, you can specify a function that returns
                       values ranging from 0 to 1, which depends on the spatial
                       coordinates. For example, a damping that increases
                       linearly in the x direction:

                        def alpha_profile(r):
                            for r[0] <= 10:
                                return r[0] / 10.
                            else:
                                return 0

                     * You can also manually specify an array with n values
                     ranging from 0 to 1 with the damping values, in the same
                     order than the mesh coordinates array.

                     * Alternatively, if you previously saved the damping
                     field array to a numpy file, you can load it using
                     numpy.load(my_array)
        """
        self._alpha[:] = helper.init_scalar(value, self.mesh)
Example #2
0
    def set_pins(self, pin):
        """

        An scalar field with values 1 or 0 to specify mesh/lattice sites
        with pinned or unpinned magnetic moments, respectively

        ARGUMENTS:

        pin     :: * You can specify a function that returns 1 or 0 depending
                   on the spatial coordinates. For example, to pin the spins
                   in a range in the x direction:

                        def pin_profile(r):
                            for r[0] > 2 and r[0] < 4:
                                return 1
                            else:
                                return 0

                   * You can also manually specify an array with n elements (1
                   or 0) with the pinned/unpinned values in the same order than
                   the mesh coordinates array.

                   * Alternatively, if you previously saved the pin
                   field array to a numpy file, you can load it using
                   numpy.load(my_array)
        """
        self._pins[:] = helper.init_scalar(pin, self.mesh)

        # Sites with no material, i.e. Mu_s or mu_s equal to zero,
        # will be pinned
        for i in range(len(self._magnetisation)):
            if self._magnetisation[i] == 0.0:
                self._pins[i] = 1
Example #3
0
    def set_Ms(self, value):
        """

        Set the saturation magnetisation of the system as a uniform or
        spatially dependent scalar field, where values are in A /m.  Mesh sites
        with no material can be specified with a magnetisation of zero
        magnitude. Samples with different materials can be specified with
        different magnetisation values in specific regions of the system.

        ARGUMENTS:

        value     :: * For a homogeneous single material sample, specify a
                       float with a magnitude in A /m

                     * In addition, you can specify a function that returns
                       values in A /m, which depends on the spatial
                       coordinates. For example, a 2 nm wide cylinder centered
                       at (x, y) = (1, 1) can be specified with (if you set the
                       unit_length to 1e-9 in the mesh):

                            Ms = 1e6  # A / m

                            def Ms_profile(r):
                                for (r[0] - 1) ** 2 + (r[1] - 1) ** 2 <= 1 ** 2:
                                    return Ms
                                else:
                                    return 0

                            Sim.set_Ms(Ms_profile)

                     * You can also manually specify an array with n values
                     with the magnetisation magnitudes, in the same order than
                     the mesh coordinates array.

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

        """

        self._Ms[:] = helper.init_scalar(value, self.mesh)
        nonzero = 0
        for i in range(self.n):
            if self._Ms[i] > 0.0:
                self._Ms_inv = 1.0 / self._Ms[i]
                nonzero += 1

        # We moved this variable to the micro_driver class
        self.driver.n_nonzero = nonzero

        for i in range(len(self._Ms)):
            if self._Ms[i] == 0.0:
                self._pins[i] = 1

                # Set the neighbour index to -1 for sites with Ms = 0
                self.mesh.neighbours[self.mesh.neighbours == i] = -1

        # TODO: Check if this is necessary here, it is only defined
        # for the LLG STT in the drivers
        self.driver.Ms_const = np.max(self._Ms)
Example #4
0
    def set_alpha(self, value):
        """

        Set the Gilbert damping of the system as a uniform or spatially
        dependent scalar field

        ARGUMENTS:

        value     :: * For a uniform damping across the whole sample, just
                       specify a float ranging from 0 to 1

                     * In addition, you can specify a function that returns
                       values ranging from 0 to 1, which depends on the spatial
                       coordinates. For example, a damping that increases
                       linearly in the x direction:

                        def alpha_profile(r):
                            for r[0] <= 10:
                                return r[0] / 10.
                            else:
                                return 0

                     * You can also manually specify an array with n values
                     ranging from 0 to 1 with the damping values, in the same
                     order than the mesh coordinates array.

                     * Alternatively, if you previously saved the damping
                     field array to a numpy file, you can load it using
                     numpy.load(my_array)
        """
        self._alpha[:] = helper.init_scalar(value, self.mesh)
Example #5
0
    def set_Ms(self, value):
        """

        Set the saturation magnetisation of the system as a uniform or
        spatially dependent scalar field, where values are in A /m.  Mesh sites
        with no material can be specified with a magnetisation of zero
        magnitude. Samples with different materials can be specified with
        different magnetisation values in specific regions of the system.

        ARGUMENTS:

        value     :: * For a homogeneous single material sample, specify a
                       float with a magnitude in A /m

                     * Alternatively, you can specify a function that returns
                       values in A /m, which depends on the spatial
                       coordinates. For example, a 2 nm wide cylinder centered
                       at (x, y) = (1, 1) can be specified with (if you set the
                       unit_length to 1e-9 in the mesh):

                            Ms = 1e6  # A / m

                            def Ms_profile(r):
                                for (r[0] - 1) ** 2 + (r[1] - 1) ** 2 <= 1 ** 2:
                                    return Ms
                                else:
                                    return 0

                            Sim.set_Ms(Ms_profile)

                     * You can also manually specify an array with n values
                     with the magnetisation magnitudes, in the same order than
                     the mesh coordinates array.

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

        """

        self._Ms[:] = helper.init_scalar(value, self.mesh)
        nonzero = 0
        for i in range(self.n):
            if self._Ms[i] > 0.0:
                self._Ms_inv[i] = 1.0 / self._Ms[i]
                nonzero += 1

        # We moved this variable to the micro_driver class
        self.driver.n_nonzero = nonzero

        for i in range(len(self._Ms)):
            if self._Ms[i] == 0.0:
                self._pins[i] = 1

                # Set the neighbour index to -1 for sites with Ms = 0
                self.mesh.neighbours[self.mesh.neighbours == i] = -1

        # TODO: Check if this is necessary here, it is only defined
        # for the LLG STT in the drivers
        self.driver.Ms_const = np.max(self._Ms)
Example #6
0
    def set_pins(self, pin):
        """

        An scalar field with values 1 or 0 to specify mesh/lattice sites
        with pinned or unpinned magnetic moments, respectively

        ARGUMENTS:

        pin     :: * You can specify a function that returns 1 or 0 depending
                   on the spatial coordinates. For example, to pin the spins
                   in a range in the x direction:

                        def pin_profile(r):
                            for r[0] > 2 and r[0] < 4:
                                return 1
                            else:
                                return 0

                   * You can also manually specify an array with n elements (1
                   or 0) with the pinned/unpinned values in the same order than
                   the mesh coordinates array.

                   * Alternatively, if you previously saved the pin
                   field array to a numpy file, you can load it using
                   numpy.load(my_array)
        """
        self._pins[:] = helper.init_scalar(pin, self.mesh)

        # Sites with no material, i.e. Mu_s or mu_s equal to zero,
        # will be pinned
        for i in range(len(self._magnetisation)):
            if self._magnetisation[i] == 0.0:
                self._pins[i] = 1
    def set_mu_s(self, value):
        self._mu_s[:] = helper.init_scalar(value, self.mesh)
        nonzero = 0
        for i in range(self.n):
            if self._mu_s[i] > 0.0:
                nonzero += 1

        self.n_nonzero = nonzero
Example #8
0
    def set_mu_s(self, value):
        self._mu_s[:] = helper.init_scalar(value, self.mesh)
        nonzero = 0
        for i in range(self.n):
            if self._mu_s[i] > 0.0:
                nonzero += 1

        self.n_nonzero = nonzero
Example #9
0
    def set_mu_s(self, value):
        self._mu_s[:] = helper.init_scalar(value, self.mesh)
        nonzero = 0
        for i in range(self.n):
            if self._mu_s[i] > 0.0:
                self._mu_s_inv[i] = 1.0 / self._mu_s[i]
                nonzero += 1

        self.n_nonzero = nonzero

        for i in range(len(self._mu_s)):
            if self._mu_s[i] == 0.0:
                self._pins[i] = 1
Example #10
0
    def set_mu_s(self, value):
        self._mu_s[:] = helper.init_scalar(value, self.mesh)
        nonzero = 0
        for i in range(self.n):
            if self._mu_s[i] > 0.0:
                self._mu_s_inv[i] = 1.0 / self._mu_s[i]
                nonzero += 1

        self.n_nonzero = nonzero

        for i in range(len(self._mu_s)):
            if self._mu_s[i] == 0.0:
                self._pins[i] = 1
Example #11
0
    def setup(self, mesh, spin, Ms):
        super(DMI, self).setup(mesh, spin, Ms)

        # We will allow to completely specify the DMI vectors according to the
        # NNs of every lattice site, thus we need a matrix of NN * n entries
        self.Ds = np.zeros(self.NN * self.n, dtype=np.float)

        if isinstance(self.D, np.ndarray) and len(self.D) == self.NN * self.n:
            self.Ds = self.D.astype('float')
        # If we do not pass a (NN * n) array, we just create a scalar field as
        # usual and then repeat the entries NN times so every neighbour will
        # have the same DMI per lattice site (can vary spatially)
        else:
            D_array = helper.init_scalar(self.D, self.mesh)
            self.Ds = np.repeat(D_array, self.NN)
Example #12
0
    def setup(self, mesh, spin, Ms):
        super(DMI, self).setup(mesh, spin, Ms)

        # We will allow to completely specify the DMI vectors according to the
        # NNs of every lattice site, thus we need a matrix of NN * n entries
        self.Ds = np.zeros(self.NN * self.n, dtype=np.float)

        if isinstance(self.D, np.ndarray) and len(self.D) == self.NN * self.n:
            self.Ds = self.D.astype('float')
        # If we do not pass a (NN * n) array, we just create a scalar field as
        # usual and then repeat the entries NN times so every neighbour will
        # have the same DMI per lattice site (can vary spatially)
        else:
            D_array = helper.init_scalar(self.D, self.mesh)
            self.Ds = np.repeat(D_array, self.NN)
Example #13
0
    def set_Ms(self, value):
        self._Ms[:] = helper.init_scalar(value, self.mesh)
        nonzero = 0
        for i in range(self.n):
            if self._Ms[i] > 0.0:
                self._Ms_inv = 1.0 / self._Ms[i]
                nonzero += 1

        self.n_nonzero = nonzero

        for i in range(len(self._Ms)):
            if self._Ms[i] == 0.0:
                self._pins[i] = 1

        self.Ms_const = np.max(self._Ms)
Example #14
0
File: llg.py Project: owlas/fidimag
    def set_Ms(self, value):
        self._Ms[:] = helper.init_scalar(value, self.mesh)
        nonzero = 0
        for i in range(self.n):
            if self._Ms[i] > 0.0:
                self._Ms_inv = 1.0 / self._Ms[i]
                nonzero += 1

        self.n_nonzero = nonzero

        for i in range(len(self._Ms)):
            if self._Ms[i] == 0.0:
                self._pins[i] = 1

        self.Ms_const = np.max(self._Ms)
Example #15
0
    def set_pins(self, pin):
        self._pins[:] = helper.init_scalar(pin, self.mesh)

        for i in range(len(self._Ms)):
            if self._Ms[i] == 0.0:
                self._pins[i] = 1
Example #16
0
    def set_mu_s(self, value):
        """

        Set the magnetic moments values of the system as a uniform or spatially
        dependent scalar field, where values are in J / T. It is recommended to
        set values in Bohr magneton units and to use the
        fidimag.common.constant.mu_B magnitude (see example). Mesh sites with
        no material can be specified with a magnetic moment of zero magnitude.
        Samples with different materials can be specified with different
        magnetic moments in specific regions of the system.

        ARGUMENTS:

        value     :: * For a homogeneous single material sample, specify a
                       float with a magnitude in J / T. It is recommended to
                       use Bohr magneton units taking the constant from the
                       `constant` library in fidimag.common. For example:

                            import fidimag.common.constant as const

                            mu_s = 2 * const.mu_B

                     * In addition, you can specify a function that returns
                       values in J / T, which depends on the spatial
                       coordinates. For example, a 2 nm wide cylinder centered
                       at (x, y) = (1, 1) can be specified with (if you set the
                       unit_length to 1e-9 in the mesh):

                            import fidimag.common.constant as const
                            mu_s = 2 * const.mu_B

                            def mu_s_profile(r):
                                for (r[0] - 1) ** 2 + (r[1] - 1) ** 2 <= 1 ** 2:
                                    return mu_s
                                else:
                                    return 0

                            Sim.set_mu_s(mu_s_profile)

                     * You can also manually specify an array with n values
                     with the magnetisation values, in the same order than the
                     mesh coordinates array.

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

        """

        self._mu_s[:] = helper.init_scalar(value, self.mesh)
        nonzero = 0
        for i in range(self.n):
            if self._mu_s[i] > 0.0:
                self._mu_s_inv[i] = 1.0 / self._mu_s[i]
                nonzero += 1

        # We moved this variable to the micro_driver class
        self.n_nonzero = nonzero

        for i in range(len(self._mu_s)):
            if self._mu_s[i] == 0.0:
                self._pins[i] = 1

                # Set the neighbour index to -1 for sites with mu_s = 0
                self.mesh.neighbours[self.mesh.neighbours == i] = -1

        # TODO: Check if this is necessary here, it is only defined
        # for the LLG STT in the drivers
        self.driver.mu_s_const = np.max(self._mu_s)

        # David Tue 19 Jun 2018
        # Since the scaling variables in the HexagonalDemag class depend on
        # mu_s, the safest way to avoid breaking the code is to update the
        # variables here in case mu_s changes. Same for normal demag
        if self.mesh.mesh_type == 'hexagonal':
            for inter in self.interactions:
                if isinstance(inter, fidimag.atomistic.DemagHexagonal):
                    inter.mu_s_scale = self._mu_s * self.scale
                    inter.scalar2cuboid(inter.mu_s_scale, inter.mu_s_scale_c)

                if isinstance(inter, fidimag.atomistic.Demag):
                    inter.mu_s_scale = self._mu_s * self.scale
Example #17
0
 def setup(self, mesh, spin, Ms):
     super(DMI, self).setup(mesh, spin, Ms)
     self.Ds = np.zeros(self.n, dtype=np.float)
     self.Ds[:] = helper.init_scalar(self.D, self.mesh)
Example #18
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 #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)
Example #20
0
File: llg.py Project: owlas/fidimag
 def set_alpha(self, value):
     self._alpha[:] = helper.init_scalar(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 set_T(self, T0):
     self._T[:] = helper.init_scalar(T0, 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 #24
0
 def set_a_J(self, value, *args):
     self._a_J[:] = helper.init_scalar(value, self.mesh, *args)
Example #25
0
    def set_mu_s(self, value):
        """

        Set the magnetic moments values of the system as a uniform or spatially
        dependent scalar field, where values are in J / T. It is recommended to
        set values in Bohr magneton units and to use the
        fidimag.common.constant.mu_B magnitude (see example). Mesh sites with
        no material can be specified with a magnetic moment of zero magnitude.
        Samples with different materials can be specified with different
        magnetic moments in specific regions of the system.

        ARGUMENTS:

        value     :: * For a homogeneous single material sample, specify a
                       float with a magnitude in J / T. It is recommended to
                       use Bohr magneton units taking the constant from the
                       `constant` library in fidimag.common. For example:

                            import fidimag.common.constant as const

                            mu_s = 2 * const.mu_B

                     * In addition, you can specify a function that returns
                       values in J / T, which depends on the spatial
                       coordinates. For example, a 2 nm wide cylinder centered
                       at (x, y) = (1, 1) can be specified with (if you set the
                       unit_length to 1e-9 in the mesh):

                            import fidimag.common.constant as const
                            mu_s = 2 * const.mu_B

                            def mu_s_profile(r):
                                for (r[0] - 1) ** 2 + (r[1] - 1) ** 2 <= 1 ** 2:
                                    return mu_s
                                else:
                                    return 0

                            Sim.set_mu_s(mu_s_profile)

                     * You can also manually specify an array with n values
                     with the magnetisation values, in the same order than the
                     mesh coordinates array.

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

        """

        self._mu_s[:] = helper.init_scalar(value, self.mesh)
        nonzero = 0
        for i in range(self.n):
            if self._mu_s[i] > 0.0:
                self._mu_s_inv[i] = 1.0 / self._mu_s[i]
                nonzero += 1

        # We moved this variable to the micro_driver class
        self.n_nonzero = nonzero

        for i in range(len(self._mu_s)):
            if self._mu_s[i] == 0.0:
                self._pins[i] = 1

                # Set the neighbour index to -1 for sites with mu_s = 0
                self.mesh.neighbours[self.mesh.neighbours == i] = -1

        # TODO: Check if this is necessary here, it is only defined
        # for the LLG STT in the drivers
        self.driver.mu_s_const = np.max(self._mu_s)
Example #26
0
 def setup(self, mesh, spin, Ms):
     super(DMI, self).setup(mesh, spin, Ms)
     self.Ds = np.zeros(self.n, dtype=np.float)
     self.Ds[:] = helper.init_scalar(self.D, self.mesh)
Example #27
0
 def set_jy(self, value, *args):
     self._jy[:] = helper.init_scalar(value, self.mesh, *args)
Example #28
0
 def set_alpha(self, value):
     self._alpha[:] = helper.init_scalar(value, self.mesh)
Example #29
0
File: llg.py Project: owlas/fidimag
    def set_pins(self, pin):
        self._pins[:] = helper.init_scalar(pin, self.mesh)

        for i in range(len(self._Ms)):
            if self._Ms[i] == 0.0:
                self._pins[i] = 1
Example #30
0
 def setup(self, mesh, spin, mu_s, mu_s_inv):
     super(CubicAnisotropy, self).setup(mesh, spin, mu_s, mu_s_inv)
     self._Kc = helper.init_scalar(self.Kc, self.mesh)
 def set_a_J(self, value):
     self._a_J[:] = helper.init_scalar(value, self.mesh)
Example #32
0
 def set_jz(self, value):
     self._jz[:] = helper.init_scalar(value, self.mesh)
Example #33
0
 def setup(self, mesh, spin, mu_s):
     super(CubicAnisotropy, self).setup(mesh, spin, mu_s)
     self._Kc = helper.init_scalar(self.Kc, self.mesh)
Example #34
0
 def set_T(self, T0):
     self._T[:] = helper.init_scalar(T0, self.mesh)
Example #35
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