Skip to content

Commit 4de489c

Browse files
Simplify assemble routines (#4241)
* Remove additional callable * Typing * Simplify and typing of pack_constants * Simplify packing logic * Remove deprecated set_bc * Various
1 parent 5c4e5f7 commit 4de489c

3 files changed

Lines changed: 76 additions & 77 deletions

File tree

python/dolfinx/fem/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
create_vector,
2222
pack_coefficients,
2323
pack_constants,
24-
set_bc,
2524
)
2625
from dolfinx.fem.bcs import (
2726
DirichletBC,

python/dolfinx/fem/assemble.py

Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (C) 2018-2022 Garth N. Wells, Jack S. Hale
1+
# Copyright (C) 2018-2022 Garth N. Wells, Jack S. Hale and Paul T. Kühner
22
#
33
# This file is part of DOLFINx (https://www.fenicsproject.org)
44
#
@@ -9,7 +9,6 @@
99

1010
import functools
1111
import typing
12-
import warnings
1312
from collections.abc import Sequence
1413

1514
import numpy as np
@@ -26,9 +25,15 @@
2625
from dolfinx.fem.function import FunctionSpace
2726

2827

29-
def pack_constants(
30-
form: Form | Sequence[Form],
31-
) -> npt.NDArray | Sequence[npt.NDArray]:
28+
@typing.overload
29+
def pack_constants(form: Form) -> npt.NDArray: ...
30+
31+
32+
@typing.overload
33+
def pack_constants(form: Sequence[Form]) -> list[npt.NDArray]: ...
34+
35+
36+
def pack_constants(form):
3237
"""Pack form constants for use in assembly.
3338
3439
Pack the 'constants' that appear in forms. The packed constants can
@@ -46,23 +51,25 @@ def pack_constants(
4651
Returns:
4752
A ``constant`` array for each form.
4853
"""
54+
if form is None:
55+
return None
56+
elif isinstance(form, Sequence):
57+
return list(map(pack_constants, form))
58+
else:
59+
return _pack_constants(form._cpp_object)
4960

50-
def _pack(form):
51-
if form is None:
52-
return None
53-
elif isinstance(form, Sequence):
54-
return list(map(lambda sub_form: _pack(sub_form), form))
55-
else:
56-
return _pack_constants(form._cpp_object)
5761

58-
return _pack(form)
62+
@typing.overload
63+
def pack_coefficients(form: None | Form) -> dict[tuple[IntegralType, int], npt.NDArray]: ...
5964

6065

66+
@typing.overload
6167
def pack_coefficients(
62-
form: Form | Sequence[Form],
63-
) -> (
64-
dict[tuple[IntegralType, int], npt.NDArray] | list[dict[tuple[IntegralType, int], npt.NDArray]]
65-
):
68+
form: Sequence[Form],
69+
) -> list[dict[tuple[IntegralType, int], npt.NDArray]]: ...
70+
71+
72+
def pack_coefficients(form):
6673
"""Pack form coefficients for use in assembly.
6774
6875
Pack the ``coefficients`` that appear in forms. The packed
@@ -80,16 +87,12 @@ def pack_coefficients(
8087
Returns:
8188
Coefficients for each form.
8289
"""
83-
84-
def _pack(form):
85-
if form is None:
86-
return {}
87-
elif isinstance(form, Sequence):
88-
return list(map(lambda sub_form: _pack(sub_form), form))
89-
else:
90-
return _pack_coefficients(form._cpp_object)
91-
92-
return _pack(form)
90+
if form is None:
91+
return {}
92+
elif isinstance(form, Sequence):
93+
return list(map(pack_coefficients, form))
94+
else:
95+
return _pack_coefficients(form._cpp_object)
9396

9497

9598
# -- Vector and matrix instantiation --------------------------------------
@@ -107,7 +110,7 @@ def create_vector(V: FunctionSpace, dtype: npt.DTypeLike = default_scalar_type)
107110
"""
108111
# Can just take the first dofmap here, since all dof maps have the same
109112
# index map in mixed-topology meshes
110-
dofmap = V.dofmaps[0] # type: ignore[attr-defined]
113+
dofmap = V.dofmaps[0]
111114
return la.vector(dofmap.index_map, dofmap.index_map_bs, dtype=dtype)
112115

113116

@@ -160,8 +163,12 @@ def assemble_scalar(
160163
To compute the functional value on the whole domain, the output
161164
of this function is typically summed across all MPI ranks.
162165
"""
163-
constants = pack_constants(M) if constants is None else constants # type: ignore[assignment]
164-
coeffs = pack_coefficients(M) if coeffs is None else coeffs # type: ignore[assignment]
166+
if constants is None:
167+
constants = pack_constants(M)
168+
169+
if coeffs is None:
170+
coeffs = pack_coefficients(M)
171+
165172
return _cpp.fem.assemble_scalar(M._cpp_object, constants, coeffs)
166173

167174

@@ -209,8 +216,13 @@ def _assemble_vector_form(
209216
"""
210217
b = create_vector(L.function_spaces[0], L.dtype)
211218
b.array[:] = 0
212-
constants = pack_constants(L) if constants is None else constants # type: ignore[assignment]
213-
coeffs = pack_coefficients(L) if coeffs is None else coeffs # type: ignore[assignment]
219+
220+
if constants is None:
221+
constants = pack_constants(L)
222+
223+
if coeffs is None:
224+
coeffs = pack_coefficients(L)
225+
214226
_assemble_vector_array(b.array, L, constants, coeffs)
215227
return b
216228

@@ -244,8 +256,12 @@ def _assemble_vector_array(
244256
:func:`dolfinx.la.Vector.scatter_reverse` on the return vector
245257
can accumulate ghost contributions.
246258
"""
247-
constants = pack_constants(L) if constants is None else constants # type: ignore[assignment]
248-
coeffs = pack_coefficients(L) if coeffs is None else coeffs # type: ignore[assignment]
259+
if constants is None:
260+
constants = pack_constants(L)
261+
262+
if coeffs is None:
263+
coeffs = pack_coefficients(L)
264+
249265
_cpp.fem.assemble_vector(b, L._cpp_object, constants, coeffs)
250266
return b
251267

@@ -287,8 +303,10 @@ def assemble_matrix(
287303
The returned matrix is not finalised, i.e. ghost values are not
288304
accumulated.
289305
"""
290-
bcs = [] if bcs is None else bcs
291-
A: la.MatrixCSR = create_matrix(a, block_mode)
306+
if bcs is None:
307+
bcs = []
308+
309+
A = create_matrix(a, block_mode)
292310
_assemble_matrix_csr(A, a, bcs, diag, constants, coeffs)
293311
return A
294312

@@ -326,8 +344,13 @@ def _assemble_matrix_csr(
326344
accumulated.
327345
"""
328346
bcs = [] if bcs is None else [bc._cpp_object for bc in bcs]
329-
constants = pack_constants(a) if constants is None else constants # type: ignore[assignment]
330-
coeffs = pack_coefficients(a) if coeffs is None else coeffs # type: ignore[assignment]
347+
348+
if constants is None:
349+
constants = pack_constants(a)
350+
351+
if coeffs is None:
352+
coeffs = pack_coefficients(a)
353+
331354
_cpp.fem.assemble_matrix(A._cpp_object, a._cpp_object, constants, coeffs, bcs)
332355

333356
# If matrix is a 'diagonal'block, set diagonal entry for constrained
@@ -346,8 +369,8 @@ def apply_lifting(
346369
bcs: Sequence[Sequence[DirichletBC]],
347370
x0: Sequence[npt.NDArray] | None = None,
348371
alpha: float = 1,
349-
constants: npt.NDArray | None = None,
350-
coeffs: dict[tuple[IntegralType, int], npt.NDArray] | None = None,
372+
constants: Sequence[npt.NDArray] | None = None,
373+
coeffs: Sequence[dict[tuple[IntegralType, int], npt.NDArray]] | None = None,
351374
) -> None:
352375
"""Modify right-hand side for lifting of Dirichlet conditions.
353376
@@ -442,40 +465,17 @@ def apply_lifting(
442465
function. Use :func:`dolfinx.fem.DirichletBC.set` to set values
443466
in ``b``.
444467
""" # noqa: D301
445-
x0 = [] if x0 is None else x0
446-
constants = (
447-
[pack_constants(form) if form is not None else np.array([], dtype=b.dtype) for form in a] # type: ignore[assignment]
448-
if constants is None
449-
else constants
450-
)
451-
coeffs = (
452-
[{} if form is None else pack_coefficients(form) for form in a] # type: ignore[assignment]
453-
if coeffs is None
454-
else coeffs
455-
)
456-
_a = [None if form is None else form._cpp_object for form in a]
457-
_bcs = [[bc._cpp_object for bc in bcs0] for bcs0 in bcs]
458-
_cpp.fem.apply_lifting(b, _a, constants, coeffs, _bcs, x0, alpha)
468+
if x0 is None:
469+
x0 = []
459470

471+
if constants is None:
472+
constants = [
473+
pack_constants(form) if form is not None else np.array([], dtype=b.dtype) for form in a
474+
]
460475

461-
def set_bc(
462-
b: npt.NDArray,
463-
bcs: Sequence[DirichletBC],
464-
x0: npt.NDArray | None = None,
465-
alpha: float = 1,
466-
) -> None:
467-
"""Insert boundary condition values into vector.
468-
469-
Note:
470-
This function is deprecated.
476+
if coeffs is None:
477+
coeffs = [pack_coefficients(form) for form in a]
471478

472-
Only local (owned) entries are set, hence communication after
473-
calling this function is not required unless ghost entries need to
474-
be updated to the boundary condition value.
475-
"""
476-
warnings.warn(
477-
"dolfinx.fem.assembler.set_bc is deprecated. Use dolfinx.fem.DirichletBC.set instead.",
478-
DeprecationWarning,
479-
)
480-
for bc in bcs:
481-
bc.set(b, x0, alpha)
479+
_a = [None if form is None else form._cpp_object for form in a]
480+
_bcs = [[bc._cpp_object for bc in bcs0] for bcs0 in bcs]
481+
_cpp.fem.apply_lifting(b, _a, constants, coeffs, _bcs, x0, alpha)

python/dolfinx/fem/petsc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,8 +609,8 @@ def apply_lifting(
609609
for i, (a_, off0, off1, offg0, offg1) in enumerate(
610610
zip(a, offset0, offset0[1:], offset1, offset1[1:])
611611
):
612-
const = pack_constants(a_) if constants is None else constants[i] # type: ignore[arg-type]
613-
coeff = pack_coefficients(a_) if coeffs is None else coeffs[i] # type: ignore[arg-type, assignment, index]
612+
const = pack_constants(a_) if constants is None else constants[i] # type: ignore[arg-type, call-overload]
613+
coeff = pack_coefficients(a_) if coeffs is None else coeffs[i] # type: ignore[arg-type, assignment, index, call-overload]
614614
const_ = [
615615
np.empty(0, dtype=PETSc.ScalarType) if val is None else val # type: ignore[attr-defined]
616616
for val in const

0 commit comments

Comments
 (0)