Example #1
0
  def _assemble(self):
    """
    Helper method that assembles the mesh dependent system matrices and
    caches them once their are calculated.
    """

    if self._assemble_cache: return self._assemble_cache
    VS = FunctionSpace(self.mesh.with_shell, "Lagrange", self.order)
    VV = VectorFunctionSpace(self.mesh.with_shell, "Lagrange", 1)

    v = TestFunction(VS)
    u = TrialFunction(VS)

    sample_size = self.mesh.data['sample_size']
    transformation_order = 1 if (self.order == 1) else 2
    gx = MetricMatrix.create_for_cube(sample_size, 0, transformation_order)
    gy = MetricMatrix.create_for_cube(sample_size, 1, transformation_order)
    gz = MetricMatrix.create_for_cube(sample_size, 2, transformation_order)

    # Dummy magnetization for linear form
    m  = interpolate(Constant((0.0,0.0,0.0)), VV)

    # set up forms and boundary conditions
    dx = Measure("dx")[self.mesh.cell_domains()]
    a = Dx(v, i) * Dx(u, i)           * dx(0) + \
        Dx(v, i) * Dx(u, i)           * dx(1) + \
        Dx(v, i) * gx[i,j] * Dx(u, j) * dx(2) + \
        Dx(v, i) * gy[i,j] * Dx(u, j) * dx(3) + \
        Dx(v, i) * gz[i,j] * Dx(u, j) * dx(4)

    L = inner(grad(v), m) * dx(0)

    bc = DirichletBC(VS, Constant(0.0), DomainBoundary())

    u = Function(VS)

    # set up assembler and solver objects
    A, b = Matrix(), Vector()
    assembler = SystemAssembler(a, L, bc)
    assembler.assemble(A)

    solver = KrylovSolver(A, "cg", "amg")
    #solver.parameters["report"]                  = False
    #solver.parameters["absolute_tolerance"] = 1e-4
    #solver.parameters["relative_tolerance"] = 1e-4
    solver.parameters["nonzero_initial_guess"]   = True
    #solver.parameters["preconditioner"]["reuse"] = True # TODO seems to do nothing

    self._assemble_cache = (solver, assembler, A, b, bc, m, u)
    return self._assemble_cache
Example #2
0
    def _assemble(self):
        """
    Helper method that assembles the mesh dependent system matrices and
    caches them once their are calculated.
    """

        if self._assemble_cache: return self._assemble_cache
        VS = FunctionSpace(self.mesh.with_shell, "Lagrange", self.order)
        VV = VectorFunctionSpace(self.mesh.with_shell, "Lagrange", 1)

        v = TestFunction(VS)
        u = TrialFunction(VS)

        sample_size = self.mesh.data['sample_size']
        transformation_order = 1 if (self.order == 1) else 2
        gx = MetricMatrix.create_for_cube(sample_size, 0, transformation_order)
        gy = MetricMatrix.create_for_cube(sample_size, 1, transformation_order)
        gz = MetricMatrix.create_for_cube(sample_size, 2, transformation_order)

        # Dummy magnetization for linear form
        m = interpolate(Constant((0.0, 0.0, 0.0)), VV)

        # set up forms and boundary conditions
        dx = Measure("dx")[self.mesh.cell_domains()]
        a = Dx(v, i) * Dx(u, i)           * dx(0) + \
            Dx(v, i) * Dx(u, i)           * dx(1) + \
            Dx(v, i) * gx[i,j] * Dx(u, j) * dx(2) + \
            Dx(v, i) * gy[i,j] * Dx(u, j) * dx(3) + \
            Dx(v, i) * gz[i,j] * Dx(u, j) * dx(4)

        L = inner(grad(v), m) * dx(0)

        bc = DirichletBC(VS, Constant(0.0), DomainBoundary())

        u = Function(VS)

        # set up assembler and solver objects
        A, b = Matrix(), Vector()
        assembler = SystemAssembler(a, L, bc)
        assembler.assemble(A)

        solver = KrylovSolver(A, "cg", "amg")
        #solver.parameters["report"]                  = False
        #solver.parameters["absolute_tolerance"] = 1e-4
        #solver.parameters["relative_tolerance"] = 1e-4
        solver.parameters["nonzero_initial_guess"] = True
        #solver.parameters["preconditioner"]["reuse"] = True # TODO seems to do nothing

        self._assemble_cache = (solver, assembler, A, b, bc, m, u)
        return self._assemble_cache
Example #3
0
  def _assemble(self):
    """
    Helper method that assembles the mesh dependent system matrices and
    caches them once their are calculated.
    """

    if self._assemble_cache: return self._assemble_cache
    VS = FunctionSpace(self.mesh.with_shell, "Lagrange", self.order)

    v = TestFunction(VS)
    u = TrialFunction(VS)

    sample_size = self.mesh.data['sample_size']
    transformation_order = 1 if (self.order == 1) else 2
    gx = MetricMatrix.create_for_cube(sample_size, 0, transformation_order)
    gy = MetricMatrix.create_for_cube(sample_size, 1, transformation_order)
    gz = MetricMatrix.create_for_cube(sample_size, 2, transformation_order)

    # setup system
    a = Dx(v, i) * Dx(u, i)           * dx(0) + \
        Dx(v, i) * Dx(u, i)           * dx(1) + \
        Dx(v, i) * gx[i,j] * Dx(u, j) * dx(2) + \
        Dx(v, i) * gy[i,j] * Dx(u, j) * dx(3) + \
        Dx(v, i) * gz[i,j] * Dx(u, j) * dx(4)

    bc = DirichletBC(VS, Constant(0.0), DomainBoundary())

    A, An = symmetric_assemble(a, bc)

    u = Function(VS)

    solver = KrylovSolver(A, "cg", "amg")
    #solver.parameters["report"]                  = False
    #solver.parameters["absolute_tolerance"] = 1e-4
    #solver.parameters["relative_tolerance"] = 1e-4
    solver.parameters["nonzero_initial_guess"]   = True
    #solver.parameters["preconditioner"]["reuse"] = True # TODO seems to do nothing

    self._assemble_cache = (solver, An, bc, v, u, A)
    return self._assemble_cache
  def calculate_v(self, state, dt):
    """
    Calculate :math:`\\vec{v}` according to the algorithm introduced above.

    *Arguments*
        state (:class:`State`)
            The simulation state containing the magnetization configuration.
        dt (:class:`float`)
            The time-step size.
    """


    with Timer("Calculate v"):
      cache = self._assemble_cache
      if cache.requires_update(state):

        if isinstance(state.mesh, WrappedMesh):
          raise Exception("Use simple mesh with shell instead of WrappedMesh.")

        # setup function spaces
        cache.VV = VectorFunctionSpace(state.mesh, "CG", 1)
        cache.VD = FunctionSpace(state.mesh, "CG", self.demag_order)
        cache.VL = FunctionSpace(state.mesh, "CG", 1)

        # setup some stuff for the demag field
        transformation_order = 2 if (self.demag_order == 1) else 2
        shell_width = state.mesh.coordinates().max(axis=0).min() / 2.0
        sample_size = state.mesh.coordinates().max(axis=0) - shell_width
        cache.gx = MetricMatrix.create_for_cube(sample_size, 0, transformation_order)
        cache.gy = MetricMatrix.create_for_cube(sample_size, 1, transformation_order)
        cache.gz = MetricMatrix.create_for_cube(sample_size, 2, transformation_order)

      # Test and Trial Functions
      u     = TrialFunction(cache.VD)
      v     = TrialFunction(cache.VV)
      sigma = TrialFunction(cache.VL)

      w1    = TestFunction(cache.VD)
      w2    = TestFunction(cache.VV)
      w3    = TestFunction(cache.VL)

      #######################################################
      # Define weak forms
      #######################################################
      f_ex = (- 2.0 * state.material.Aex * Constants.gamma) / \
             (Constants.mu0 * state.material.ms * state.scale**2)

      # Bilinear form
      a12  = - 0.5 * Constant(dt) * inner(v, grad(w1)) * state.dx('magnetic')                            # Demag Field, Implicit RHS
      a11  = inner(grad(w1), grad(u))            * state.dx('all') \
           + inner(grad(w1), grad(u))            * state.dx(1000)  \
           + inner(grad(w1), cache.gx * grad(u)) * state.dx(1001)  \
           + inner(grad(w1), cache.gy * grad(u)) * state.dx(1002)  \
           + inner(grad(w1), cache.gz * grad(u)) * state.dx(1003)
      a21  = - Constant(state.material.ms * Constants.gamma) * inner(grad(u), w2) * state.dx('magnetic') # Demag
      a22  = Constant(state.material.alpha) * dot(v, w2) * state.dx('magnetic')                          # LLG
      a22 += dot(cross(state.m, v), w2) * state.dx('magnetic')
      a22 += - 0.5 * Constant(dt * f_ex) * Dx(v[i],j) * Dx(w2[i],j) * state.dx('magnetic')               # Exchange

      # Linear form
      L1 = inner(state.m, grad(w1)) * state.dx('magnetic')                                               # Demag Field
      L2 = Constant(f_ex) * Dx(state.m[i],j) * Dx(w2[i],j) * state.dx('magnetic')                        # Exchange

      for term in self.terms:                                                                            # Additional Terms
        L2  += term.form_rhs(state, w2) * state.dx('magnetic')
        #a22 += term.form_lhs(state, w2, Constant(0.5 * dt) * v) * state.dx('magnetic')

      #######################################################
      # Define boundary conditions
      #######################################################
      bc1 = DirichletBC(cache.VD, Constant(0.0), DomainBoundary())

      #######################################################
      # Assemble the system
      #######################################################
      A11, b1 = assemble_system(a11, L1, bc1)
      A12 = assemble(a12)
      A21 = assemble(a21)
      A22 = assemble(a22, keep_diagonal=True); A22.ident_zeros()

      v23 = TestFunction(state.VectorFunctionSpace())
      u23 = TrialFunction(state.FunctionSpace())
      A23 = assemble(u23 * dot(state.m, v23) * dP)

      v32 = TestFunction(state.FunctionSpace())
      u32 = TrialFunction(state.VectorFunctionSpace())
      A32 = assemble(v32 * dot(state.m, u32) * dP)

      #A23 = DofAssembler.assemble(TransScalarProductMatrix(cache.VL, cache.VV, state.m))
      #A32 = DofAssembler.assemble(ScalarProductMatrix(cache.VL, cache.VV, state.m))

      b2  = assemble(L2)

      #######################################################
      # Schur Ansatz
      #######################################################
      A11p   = ILU(A11)
      A11inv = ConjGrad(A11, precond=A11p)
      z1     = A11inv * b1

      S11    = A22 - A21 * A11inv * A12
      S      = block_mat([[S11, A23],
                          [A32,   0]])

      Sp11   = ILU(A22)
      Sp22   = InvDiag(collapse(A32 * LumpedInvDiag(A22) * A23))
      Sp     = block_mat([[Sp11, A23],
                          [0, -Sp22]]).scheme('sgs')

      Sinv   = BiCGStab(S, precond=Sp, tolerance=1e-8/dt)

      b      = block_vec([b2 - A21*z1, 0])
      v, _   = Sinv * b

      return Function(cache.VV, v)