Exemplo n.º 1
0
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)
Exemplo n.º 2
0
  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)
Exemplo n.º 3
0
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)
Exemplo n.º 4
0
 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))
Exemplo n.º 5
0
 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))
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
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)
Exemplo n.º 9
0
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)