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()
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
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))
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)