class AnisotropyField(module.Module): def __init__(self): super(AnisotropyField, self).__init__() def calculates(self): return ["H_aniso", "E_aniso"] def params(self): return ["k_uniaxial", "k_cubic", "axis1", "axis2"] def properties(self): return {'EFFECTIVE_FIELD_TERM': "H_aniso", 'EFFECTIVE_FIELD_ENERGY': "E_aniso"} def initialize(self, system): self.system = system self.k_uniaxial = Field(self.system.mesh); self.k_uniaxial.fill(0.0) self.k_cubic = Field(self.system.mesh); self.k_cubic.fill(0.0) self.axis1 = VectorField(self.system.mesh); self.axis1.fill((0.0, 0.0, 0.0)) self.axis2 = VectorField(self.system.mesh); self.axis2.fill((0.0, 0.0, 0.0)) def calculate(self, state, id): if id == "H_aniso": if hasattr(state.cache, "H_aniso"): return state.cache.H_aniso H_aniso = state.cache.H_aniso = VectorField(self.system.mesh) axis1 = self.axis1 axis2 = self.axis2 k_uni = self.k_uniaxial k_cub = self.k_cubic skip_uni = k_uni.isUniform() and k_uni.uniform_value == 0.0 have_uni = not skip_uni skip_cub = k_cub.isUniform() and k_cub.uniform_value == 0.0 have_cub = not skip_cub Ms = self.system.Ms if not have_uni and not have_cub: H_aniso.fill((0.0, 0.0, 0.0)) state.cache.E_aniso_sum = 0.0 elif not have_uni and have_cub: state.cache.E_aniso_sum = magneto.cubic_anisotropy(axis1, axis2, k_cub, Ms, state.M, H_aniso) elif have_uni and not have_cub: state.cache.E_aniso_sum = magneto.uniaxial_anisotropy(axis1, k_uni, Ms, state.M, H_aniso) elif have_uni and have_cub: tmp = VectorField(self.system.mesh) E0 = magneto.uniaxial_anisotropy(axis1, k_uni, Ms, state.M, tmp) E1 = magneto.cubic_anisotropy(axis1, axis2, k_cub, Ms, state.M, H_aniso) state.cache.E_aniso_sum = E0 + E1 H_aniso.add(tmp) return H_aniso elif id == "E_aniso": if not hasattr(state.cache, "E_aniso"): foo = state.H_aniso return state.cache.E_aniso_sum * self.system.mesh.cell_volume else: raise KeyError("AnisotropyField.calculate: Can't calculate %s", id)
def calculate(self, state, id): if id == self.__var: # Get parameters... offs = getattr(self, self.__offs) amp = getattr(self, self.__amp) freq = getattr(self, self.__freq) phase = getattr(self, self.__phase) fn = getattr(self, self.__func) # Calculate field 'A'. t = state.t if fn: # with user function if any(x != (0.0, 0.0, 0.0) for x in (amp, freq, phase, offs)): raise ValueError("AlternatingField.calculates: If %s is defined, the parameters %s, %s, %s and %s must be zero vectors, i.e. (0.0, 0.0, 0.0)" % (self.__func, self.__offs, self.__amp, self.__freq, self.__phase)) # call user function A = fn(t) else: # with 'offs', 'amp', 'freq', 'phase' parameters A = tuple(offs[c] + amp[c] * sin(t * freq[c] + phase[c]) for c in range(3)) # Convert 3-vector to VectorField if necessary. if isinstance(A, tuple): tmp = A; A = VectorField(self.system.mesh); A.fill(tmp) # Return field 'A' return A else: raise KeyError("AlternatingField.calculates: Can't calculate %s", id)
class MacroSpinTorque(module.Module): def __init__(self, do_precess=True): super(MacroSpinTorque, self).__init__() self.do_precess = do_precess if not do_precess: raise NotImplementedError( "The MacroSpinTorque module does not support do_precess=False." ) def calculates(self): return ["dMdt_ST"] def params(self): return ["a_j", "p"] def properties(self): return {'LLGE_TERM': "dMdt_ST"} def initialize(self, system): self.system = system self.a_j = 0.0 self.p = VectorField(self.system.mesh) self.p.fill((0.0, 0.0, 0.0)) def calculate(self, state, id): cache = state.cache if id == "dMdt_ST": if hasattr(cache, "dMdt_ST"): return cache.dMdt_ST dMdt_ST = cache.dMdt_ST = VectorField(self.system.mesh) # Calculate macro spin torque term due to Slonchewski nx, ny, nz = self.system.mesh.num_nodes dx, dy, dz = self.system.mesh.delta magneto.fdm_slonchewski( nx, ny, nz, dx, dy, dz, #self.do_precess, self.a_j, self.p, self.system.get_param("Ms"), self.system.get_param("alpha"), state.M, dMdt_ST) return dMdt_ST else: raise KeyError("MacroSpinTorque.calculate: Can't calculate %s", id)
def set_param(self, id, val): if id == self.__var_id: if isinstance(val, numbers.Number): fld = Field(self.system.mesh) fld.fill(val) elif hasattr(val, "__iter__") and len(val) == 3: val = tuple(map(float, val)) field = VectorField(self.system.mesh) field.fill(val) elif isinstance(val, Field): fld = Field(self.system.mesh) fld.assign(val) elif isinstance(val, VectorField): fld = VectorField(self.system.mesh) fld.assign(val) else: raise ValueError self.__field = fld else: raise ValueError("%s: Don't know how to update %s." % (self.name(), id))
def set_param(self, id, val): if id == self.__var_id: if isinstance(val, numbers.Number): fld = Field(self.system.mesh) fld.fill(val) elif hasattr(val, "__iter__") and len(val) == 3: val = tuple(map(float, val)) field = VectorField(self.system.mesh) field.fill(val) elif isinstance(val, Field): fld = Field(self.system.mesh) fld.assign(val) elif isinstance(val, VectorField): fld = VectorField(self.system.mesh) fld.assign(val) else: raise ValueError self.__field = fld else: raise ValueError("%s: Don't know how to update %s." % (self.name(), id))
class MacroSpinTorque(module.Module): def __init__(self, do_precess = True): super(MacroSpinTorque, self).__init__() self.do_precess = do_precess if not do_precess: raise NotImplementedError("The MacroSpinTorque module does not support do_precess=False.") def calculates(self): return ["dMdt_ST"] def params(self): return ["a_j", "p"] def properties(self): return {'LLGE_TERM': "dMdt_ST"} def initialize(self, system): self.system = system self.a_j = 0.0 self.p = VectorField(self.system.mesh); self.p.fill((0.0, 0.0, 0.0)) def calculate(self, state, id): cache = state.cache if id == "dMdt_ST": if hasattr(cache, "dMdt_ST"): return cache.dMdt_ST dMdt_ST = cache.dMdt_ST = VectorField(self.system.mesh) # Calculate macro spin torque term due to Slonchewski nx, ny, nz = self.system.mesh.num_nodes dx, dy, dz = self.system.mesh.delta magneto.fdm_slonchewski( nx, ny, nz, dx, dy, dz, #self.do_precess, self.a_j, self.p, self.system.get_param("Ms"), self.system.get_param("alpha"), state.M, dMdt_ST ) return dMdt_ST else: raise KeyError("MacroSpinTorque.calculate: Can't calculate %s", id)
def calculate(self, state, id): if id == self.__var: # Get parameters... offs = getattr(self, self.__offs) amp = getattr(self, self.__amp) freq = getattr(self, self.__freq) phase = getattr(self, self.__phase) fn = getattr(self, self.__func) # Calculate field 'A'. t = state.t if fn: # with user function if any(x != (0.0, 0.0, 0.0) for x in (amp, freq, phase, offs)): raise ValueError( "AlternatingField.calculates: If %s is defined, the parameters %s, %s, %s and %s must be zero vectors, i.e. (0.0, 0.0, 0.0)" % (self.__func, self.__offs, self.__amp, self.__freq, self.__phase)) # call user function A = fn(t) else: # with 'offs', 'amp', 'freq', 'phase' parameters A = (offs[0] + amp[0] * sin(t * freq[0] + phase[0]), offs[1] + amp[1] * sin(t * freq[1] + phase[1]), offs[2] + amp[2] * sin(t * freq[2] + phase[2])) # Convert 3-vector to VectorField if necessary. if isinstance(A, tuple): tmp = A A = VectorField(self.system.mesh) A.fill(tmp) # Return field 'A' return A else: raise KeyError("AlternatingField.calculates: Can't calculate %s", id)
class AnisotropyField(module.Module): def __init__(self): super(AnisotropyField, self).__init__() def calculates(self): return ["H_aniso", "E_aniso"] def params(self): return ["k_uniaxial", "k_cubic", "axis1", "axis2"] def properties(self): return { 'EFFECTIVE_FIELD_TERM': "H_aniso", 'EFFECTIVE_FIELD_ENERGY': "E_aniso" } def initialize(self, system): self.system = system self.k_uniaxial = Field(self.system.mesh) self.k_uniaxial.fill(0.0) self.k_cubic = Field(self.system.mesh) self.k_cubic.fill(0.0) self.axis1 = VectorField(self.system.mesh) self.axis1.fill((0.0, 0.0, 0.0)) self.axis2 = VectorField(self.system.mesh) self.axis2.fill((0.0, 0.0, 0.0)) def on_param_update(self, id): if id in self.params() + ["Ms"]: axis1, axis2 = self.axis1, self.axis2 k_uni, k_cub = self.k_uniaxial, self.k_cubic Ms = self.system.get_param("Ms") def compute_none(state, H_aniso): H_aniso.fill((0.0, 0.0, 0.0)) return 0.0 def compute_uniaxial(state, H_aniso): return magneto.uniaxial_anisotropy(axis1, k_uni, Ms, state.M, H_aniso) def compute_cubic(state, H_aniso): return magneto.cubic_anisotropy(axis1, axis2, k_cub, Ms, state.M, H_aniso) def compute_uniaxial_and_cubic(state, H_aniso): tmp = VectorField(self.system.mesh) E0 = magneto.uniaxial_anisotropy(axis1, k_uni, Ms, state.M, tmp) E1 = magneto.cubic_anisotropy(axis1, axis2, k_cub, Ms, state.M, H_aniso) state.cache.E_aniso_sum = E0 + E1 H_aniso.add(tmp) fns = { (False, False): compute_none, (True, False): compute_uniaxial, (False, True): compute_cubic, (True, True): compute_uniaxial_and_cubic } have_uni = not (k_uni.isUniform() and k_uni.uniform_value == 0.0) have_cub = not (k_cub.isUniform() and k_cub.uniform_value == 0.0) self.__compute_fn = fns[have_uni, have_cub] def calculate(self, state, id): cache = state.cache if id == "H_aniso": if hasattr(cache, "H_aniso"): return cache.H_aniso H_aniso = cache.H_aniso = VectorField(self.system.mesh) cache.E_aniso_sum = self.__compute_fn(state, H_aniso) return H_aniso elif id == "E_aniso": if not hasattr(cache, "E_aniso_sum"): self.calculate(state, "H_aniso") return cache.E_aniso_sum * self.system.mesh.cell_volume else: raise KeyError("AnisotropyField.calculate: Can't calculate %s", id)
class AnisotropyField(module.Module): def __init__(self): super(AnisotropyField, self).__init__() def calculates(self): return ["H_aniso", "E_aniso"] def params(self): return ["k_uniaxial", "k_cubic", "axis1", "axis2"] def properties(self): return {'EFFECTIVE_FIELD_TERM': "H_aniso", 'EFFECTIVE_FIELD_ENERGY': "E_aniso"} def initialize(self, system): self.system = system self.k_uniaxial = Field(self.system.mesh); self.k_uniaxial.fill(0.0) self.k_cubic = Field(self.system.mesh); self.k_cubic.fill(0.0) self.axis1 = VectorField(self.system.mesh); self.axis1.fill((0.0, 0.0, 0.0)) self.axis2 = VectorField(self.system.mesh); self.axis2.fill((0.0, 0.0, 0.0)) def on_param_update(self, id): if id in self.params() + ["Ms"]: axis1, axi2 = self.axis1, self.axis2 k_uni, k_cub = self.k_uniaxial, self.k_cubic Ms = self.system.Ms def compute_none(state, H_aniso): H_aniso.fill((0.0, 0.0, 0.0)) return 0.0 def compute_uniaxial(state, H_aniso): return magneto.uniaxial_anisotropy(axis1, k_uni, Ms, state.M, H_aniso) def compute_cubic(state, H_aniso): return magneto.cubic_anisotropy(axis1, axis2, k_cub, Ms, state.M, H_aniso) def compute_uniaxial_and_cubic(state, H_aniso): tmp = VectorField(self.system.mesh) E0 = magneto.uniaxial_anisotropy(axis1, k_uni, Ms, state.M, tmp) E1 = magneto.cubic_anisotropy(axis1, axis2, k_cub, Ms, state.M, H_aniso) state.cache.E_aniso_sum = E0 + E1 H_aniso.add(tmp) fns = {(False, False): compute_none, ( True, False): compute_uniaxial, (False, True): compute_cubic, ( True, True): compute_uniaxial_and_cubic} have_uni = not (k_uni.isUniform() and k_uni.uniform_value == 0.0) have_cub = not (k_cub.isUniform() and k_cub.uniform_value == 0.0) self.__compute_fn = fns[have_uni, have_cub] def calculate(self, state, id): if id == "H_aniso": if hasattr(state.cache, "H_aniso"): return state.cache.H_aniso H_aniso = state.cache.H_aniso = VectorField(self.system.mesh) state.cache.E_aniso_sum = self.__compute_fn(state, H_aniso) return H_aniso elif id == "E_aniso": if not hasattr(state.cache, "E_aniso_sum"): self.calculate(state, "H_aniso") return state.cache.E_aniso_sum * self.system.mesh.cell_volume else: raise KeyError("AnisotropyField.calculate: Can't calculate %s", id)