Coverage for python/src/dolfinx_mpc/assemble_matrix.py: 91%
47 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-03 13:59 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-04-03 13:59 +0000
1# Copyright (C) 2020-2021 Jørgen S. Dokken
2#
3# This file is part of DOLFINX_MPC
4#
5# SPDX-License-Identifier: MIT
6from __future__ import annotations
8from collections.abc import Sequence
9from typing import Optional, Union
11from petsc4py import PETSc as _PETSc
13import dolfinx.cpp as _cpp
14import dolfinx.fem as _fem
16from dolfinx_mpc import cpp
18from .multipointconstraint import MultiPointConstraint
21def assemble_matrix(
22 form: _fem.Form,
23 constraint: Union[MultiPointConstraint, Sequence[MultiPointConstraint]],
24 bcs: Optional[Sequence[_fem.DirichletBC]] = None,
25 diagval: _PETSc.ScalarType = 1, # type: ignore
26 A: Optional[_PETSc.Mat] = None, # type: ignore
27) -> _PETSc.Mat: # type: ignore
28 """
29 Assemble a compiled DOLFINx bilinear form into a PETSc matrix with corresponding multi point constraints
30 and Dirichlet boundary conditions.
32 Args:
33 form: The compiled bilinear variational form
34 constraint: The multi point constraint
35 bcs: Sequence of Dirichlet boundary conditions
36 diagval: Value to set on the diagonal of the matrix
37 A: PETSc matrix to assemble into
39 Returns:
40 _PETSc.Mat: The matrix with the assembled bi-linear form #type: ignore
41 """
42 bcs = [] if bcs is None else [bc._cpp_object for bc in bcs]
43 if not isinstance(constraint, Sequence):
44 assert form.function_spaces[0] == form.function_spaces[1]
45 constraint = (constraint, constraint)
47 # Generate matrix with MPC sparsity pattern
48 if A is None:
49 A = cpp.mpc.create_matrix(form._cpp_object, constraint[0]._cpp_object, constraint[1]._cpp_object)
50 A.zeroEntries()
52 # Assemble matrix in C++
53 cpp.mpc.assemble_matrix(A, form._cpp_object, constraint[0]._cpp_object, constraint[1]._cpp_object, bcs, diagval)
55 # Add one on diagonal for Dirichlet boundary conditions
56 if form.function_spaces[0] is form.function_spaces[1]:
57 A.assemblyBegin(_PETSc.Mat.AssemblyType.FLUSH) # type: ignore
58 A.assemblyEnd(_PETSc.Mat.AssemblyType.FLUSH) # type: ignore
59 _cpp.fem.petsc.insert_diagonal(A, form.function_spaces[0], bcs, diagval)
61 A.assemble()
62 return A
65def create_sparsity_pattern(form: _fem.Form, mpc: Union[MultiPointConstraint, Sequence[MultiPointConstraint]]):
66 """
67 Create sparsity-pattern for MPC given a compiled DOLFINx form
69 Args:
70 form: The form
71 mpc: For square forms, the MPC. For rectangular forms a list of 2 MPCs on
72 axis 0 & 1, respectively
73 """
74 if isinstance(mpc, Sequence):
75 assert len(mpc) == 2
76 for mpc_ in mpc:
77 mpc_._not_finalized() # type: ignore
78 return cpp.mpc.create_sparsity_pattern(form._cpp_object, mpc[0]._cpp_object, mpc[1]._cpp_object)
79 else:
80 mpc._not_finalized() # type: ignore
81 return cpp.mpc.create_sparsity_pattern(
82 form._cpp_object,
83 mpc._cpp_object, # type: ignore
84 mpc._cpp_object, # type: ignore
85 ) # type: ignore
88def create_matrix_nest(a: Sequence[Sequence[_fem.Form]], constraints: Sequence[MultiPointConstraint]):
89 """
90 Create a PETSc matrix of type "nest" with appropriate sparsity pattern
91 given the provided multi points constraints
93 Args:
94 a: The compiled bilinear variational form provided in a rank 2 list
95 constraints: An ordered list of multi point constraints
96 """
97 assert len(constraints) == len(a)
99 A_ = [[None for _ in range(len(a[0]))] for _ in range(len(a))]
101 for i, a_row in enumerate(a):
102 for j, a_block in enumerate(a_row):
103 if a[i][j] is None:
104 continue
105 A_[i][j] = cpp.mpc.create_matrix(
106 a[i][j]._cpp_object, constraints[i]._cpp_object, constraints[j]._cpp_object
107 )
109 A = _PETSc.Mat().createNest( # type: ignore
110 A_, comm=constraints[0].function_space.mesh.comm
111 )
112 return A
115def assemble_matrix_nest(
116 A: _PETSc.Mat, # type: ignore
117 a: Sequence[Sequence[_fem.Form]],
118 constraints: Sequence[MultiPointConstraint],
119 bcs: Sequence[_fem.DirichletBC] = [],
120 diagval: _PETSc.ScalarType = 1, # type: ignore
121):
122 """
123 Assemble a compiled DOLFINx bilinear form into a PETSc matrix of type
124 "nest" with corresponding multi point constraints and Dirichlet boundary
125 conditions.
127 Args:
128 a: The compiled bilinear variational form provided in a rank 2 list
129 constraints: An ordered list of multi point constraints
130 bcs: Sequence of Dirichlet boundary conditions
131 diagval: Value to set on the diagonal of the matrix (Default 1)
132 A: PETSc matrix to assemble into
133 """
134 for i, a_row in enumerate(a):
135 for j, a_block in enumerate(a_row):
136 if a_block is not None:
137 Asub = A.getNestSubMatrix(i, j)
138 assemble_matrix(a_block, (constraints[i], constraints[j]), bcs=bcs, diagval=diagval, A=Asub)