Example #1
0
    def assemble(self):
        """Actually assemble this :class:`Matrix`.

        This calls the stashed assembly callback or does nothing if
        the matrix is already assembled.

        .. note::

            If the boundary conditions stashed on the :class:`Matrix` have
            changed since the last time it was assembled, this will
            necessitate reassembly.  So for example:

            .. code-block:: python

                A = assemble(a, bcs=[bc1])
                solve(A, x, b)
                bc2.apply(A)
                solve(A, x, b)

            will apply boundary conditions from `bc1` in the first
            solve, but both `bc1` and `bc2` in the second solve.
        """
        if self._assembly_callback is None:
            self.assembled = True
            return
        if self.assembled:
            if self._needs_reassembly:
                from firedrake.assemble import _assemble
                _assemble(self.a, tensor=self, bcs=self.bcs)
                return self.assemble()
            return
        self._assembly_callback(self.bcs)
        self.assembled = True
        super().assemble()
Example #2
0
    def assemble(self):
        """Actually assemble this :class:`Matrix`.

        This calls the stashed assembly callback or does nothing if
        the matrix is already assembled.

        .. note::

            If the boundary conditions stashed on the :class:`Matrix` have
            changed since the last time it was assembled, this will
            necessitate reassembly.  So for example:

            .. code-block:: python

                A = assemble(a, bcs=[bc1])
                solve(A, x, b)
                bc2.apply(A)
                solve(A, x, b)

            will apply boundary conditions from `bc1` in the first
            solve, but both `bc1` and `bc2` in the second solve.
        """
        if self._assembly_callback is None:
            raise RuntimeError('Trying to assemble a Matrix, but no thunk found')
        if self._assembled:
            if self._needs_reassembly:
                from firedrake.assemble import _assemble
                _assemble(self.a, tensor=self, bcs=self.bcs)
                return self.assemble()
            return
        self._bcs_at_point_of_assembly = copy.copy(self.bcs)
        self._assembly_callback(self.bcs)
        self._assembled = True
Example #3
0
    def _Abcs(self):
        """A function storing the action of the operator on a zero Function
        satisfying the BCs.

        Used in the presence of BCs.
        """
        b = function.Function(self._W)
        for bc in self.A.bcs:
            bc.apply(b)
        from firedrake.assemble import _assemble
        if isinstance(self.A.a, slate.TensorBase):
            return _assemble(self.A.a * b)
        else:
            return _assemble(ufl.action(self.A.a, b))
Example #4
0
    def _Abcs(self):
        """A function storing the action of the operator on a zero Function
        satisfying the BCs.

        Used in the presence of BCs.
        """
        b = function.Function(self._W)
        for bc in self.A.bcs:
            bc.apply(b)
        from firedrake.assemble import _assemble
        if isinstance(self.A.a, slate.TensorBase):
            return _assemble(self.A.a * b)
        else:
            return _assemble(ufl.action(self.A.a, b))
Example #5
0
 def _form_action(self, u):
     """Assemble the form action of this :class:`Matrix`' bilinear form
     onto the :class:`Function` ``u``.
     .. note::
         This is the form **without** any boundary conditions."""
     if not hasattr(self, '_a_action'):
         self._a_action = ufl.action(self._a, u)
     if hasattr(self, '_a_action_coeff'):
         self._a_action = ufl.replace(self._a_action, {self._a_action_coeff: u})
     self._a_action_coeff = u
     # Since we assemble the cached form, the kernels will already have
     # been compiled and stashed on the form the second time round
     from firedrake.assemble import _assemble
     return _assemble(self._a_action)
Example #6
0
 def _form_action(self, u):
     """Assemble the form action of this :class:`Matrix`' bilinear form
     onto the :class:`Function` ``u``.
     .. note::
         This is the form **without** any boundary conditions."""
     if not hasattr(self, '_a_action'):
         self._a_action = ufl.action(self._a, u)
     if hasattr(self, '_a_action_coeff'):
         self._a_action = ufl.replace(self._a_action,
                                      {self._a_action_coeff: u})
     self._a_action_coeff = u
     # Since we assemble the cached form, the kernels will already have
     # been compiled and stashed on the form the second time round
     from firedrake.assemble import _assemble
     return _assemble(self._a_action)