예제 #1
0
 def _block_residual_vector_assemble(self, block_residual, block_solution):
     assert isinstance(
         self.residual_form_or_eval,
         (list, array, BlockForm1, types.FunctionType, types.MethodType))
     if isinstance(self.residual_form_or_eval, (list, array, BlockForm1)):
         residual_form_or_vector = self.residual_form_or_eval
     elif isinstance(self.residual_form_or_eval,
                     (types.FunctionType, types.MethodType)):
         residual_form_or_vector = self.residual_form_or_eval(
             block_solution)
     else:
         raise AssertionError(
             "Invalid case in BlockNonlinearProblem._block_residual_vector_assemble."
         )
     assert isinstance(residual_form_or_vector,
                       (list, array, BlockForm1, GenericBlockVector))
     if isinstance(residual_form_or_vector, (list, array, BlockForm1)):
         block_assemble(residual_form_or_vector,
                        block_tensor=block_residual)
     elif isinstance(residual_form_or_vector, GenericBlockVector):
         residual_form_or_vector = as_backend_type(residual_form_or_vector)
         block_residual = as_backend_type(block_residual)
         residual_form_or_vector.vec().swap(block_residual.vec())
         assert residual_form_or_vector.has_block_dof_map()
         block_dofmap = residual_form_or_vector.get_block_dof_map()
         if not block_residual.has_block_dof_map():
             block_residual.attach_block_dof_map(block_dofmap)
         else:
             assert block_dofmap == block_residual.get_block_dof_map()
     else:
         raise AssertionError(
             "Invalid case in BlockNonlinearProblem._block_residual_vector_assemble."
         )
 def _jacobian_matrix_assemble(self,
                               jacobian_block_form,
                               petsc_jacobian=None):
     if petsc_jacobian is None:
         return block_assemble(jacobian_block_form)
     else:
         self.jacobian_matrix = BlockPETScMatrix(petsc_jacobian)
         block_assemble(jacobian_block_form,
                        block_tensor=self.jacobian_matrix)
 def _residual_vector_assemble(self,
                               residual_block_form,
                               petsc_residual=None):
     if petsc_residual is None:
         return block_assemble(residual_block_form)
     else:
         self.residual_vector = BlockPETScVector(petsc_residual)
         block_assemble(residual_block_form,
                        block_tensor=self.residual_vector)
 def J(self, fenics_jacobian, _):
     # No need to update block solution subfunctions, this has already been done in the residual
     # Wrap FEniCS jacobian into a block jacobian
     block_jacobian = self.block_backend.wrap_matrix(fenics_jacobian)
     # Assemble the block jacobian
     block_assemble(self.jacobian_block_form, block_tensor=block_jacobian)
     # Apply boundary conditions
     if self.bcs is not None:
         self.bcs.apply(block_jacobian)
 def F(self, fenics_residual, _):
     # Update block solution subfunctions based on the third argument, which has already been
     # stored in self.block_solution.block_vector()
     self.block_solution.apply("to subfunctions")
     # Wrap FEniCS residual into a block residual
     block_residual = self.block_backend.wrap_vector(fenics_residual)
     # Assemble the block residual
     block_assemble(self.residual_block_form, block_tensor=block_residual)
     # Apply boundary conditions
     if self.bcs is not None:
         self.bcs.apply(block_residual, self.block_solution.block_vector())
예제 #6
0
 def _block_jacobian_matrix_assemble(self, block_jacobian, block_solution):
     assert isinstance(
         self.jacobian_form_or_eval,
         (list, array, BlockForm2, types.FunctionType, types.MethodType))
     if isinstance(self.jacobian_form_or_eval, (list, array, BlockForm2)):
         jacobian_form_or_matrix = self.jacobian_form_or_eval
     elif isinstance(self.jacobian_form_or_eval,
                     (types.FunctionType, types.MethodType)):
         jacobian_form_or_matrix = self.jacobian_form_or_eval(
             block_solution)
     else:
         raise AssertionError(
             "Invalid case in BlockNonlinearProblem._block_jacobian_matrix_assemble."
         )
     assert isinstance(jacobian_form_or_matrix,
                       (list, array, BlockForm2, GenericBlockMatrix))
     if isinstance(jacobian_form_or_matrix, (list, array, BlockForm2)):
         block_assemble(jacobian_form_or_matrix,
                        block_tensor=block_jacobian)
         return True
     elif isinstance(jacobian_form_or_matrix, GenericBlockMatrix):
         # =========== PETScSNESSolver::init() workaround for assembled matrices =========== #
         if block_jacobian.empty():
             return False
         # === end === PETScSNESSolver::init() workaround for assembled matrices === end === #
         else:
             jacobian_form_or_matrix = as_backend_type(
                 jacobian_form_or_matrix)
             block_jacobian = as_backend_type(block_jacobian)
             block_jacobian.zero()
             block_jacobian += jacobian_form_or_matrix
             assert jacobian_form_or_matrix.has_block_dof_map(0)
             assert jacobian_form_or_matrix.has_block_dof_map(1)
             block_dofmap_0 = jacobian_form_or_matrix.get_block_dof_map(0)
             block_dofmap_1 = jacobian_form_or_matrix.get_block_dof_map(0)
             assert block_jacobian.has_block_dof_map(
                 0) == block_jacobian.has_block_dof_map(1)
             if not block_jacobian.has_block_dof_map(0):
                 block_jacobian.attach_block_dof_map(
                     block_dofmap_0, block_dofmap_1)
             else:
                 assert block_dofmap_0 == block_jacobian.get_block_dof_map(
                     0)
                 assert block_dofmap_1 == block_jacobian.get_block_dof_map(
                     1)
             return True
     else:
         raise AssertionError(
             "Invalid case in BlockNonlinearProblem._block_jacobian_matrix_assemble."
         )