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
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
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)
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,)
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)
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)
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
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)
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 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
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)
def update_field(self, B0): self.B0 = B0 self.field[:] = helper.init_vector(self.B0, self.mesh)
def set_p(self, value): self._p[:] = helper.init_vector(value, self.mesh, 3)
def update_field(self, H0): self.H0 = H0 self.field[:] = helper.init_vector(self.H0, self.mesh)
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)
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)
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