1414
1515
1616def prepare_interpolation_data (
17- expr : ufl .core .expr .Expr , Q : dolfinx .fem .FunctionSpace
17+ expr : ufl .core .expr .Expr ,
18+ Q : dolfinx .fem .FunctionSpace ,
19+ interpolation_entities : npt .NDArray [np .int32 ] | None = None ,
1820) -> npt .NDArray [np .inexact ]:
1921 """Convenience function for preparing data required for assembling the interpolation matrix
2022
@@ -30,29 +32,60 @@ def prepare_interpolation_data(
3032 Args:
3133 expr: The UFL expression containing a trial function from space `V`
3234 Q: Output interpolation space
35+ interpolation_entities: Entities of the domain of the input space `V` that one
36+ should evaluate the `expr` at. If not provided, it is assumed that
37+ we are integrating over all cells in `V` and that `Q` is defined on the same grid.
3338 Returns:
3439 Interpolation data per cell, as an numpy array.
3540 """
3641 if np .issubdtype (dolfinx .default_scalar_type , np .complexfloating ):
3742 raise NotImplementedError ("No complex support" )
3843
44+ # Extract argument from expr (in V)
45+ arguments = ufl .algorithms .extract_arguments (expr )
46+ assert len (arguments ) == 1
47+ V = arguments [0 ].ufl_function_space ()
48+
49+ mesh = V .mesh
50+
51+ if Q .mesh .topology .dim == V .mesh .topology .dim :
52+ if interpolation_entities is None :
53+ tdim = mesh .topology .dim
54+ num_cells = mesh .topology .index_map (tdim ).size_local
55+ interpolation_entities = np .arange (num_cells , dtype = np .int32 )
56+ else :
57+ if (ndim := interpolation_entities .ndim ) != 1 :
58+ raise ValueError (
59+ f"Interpolation entities has wrong input shape, should be 1D, got { ndim } "
60+ )
61+ num_cells = len (interpolation_entities )
62+ elif Q .mesh .topology .dim == V .mesh .topology .dim - 1 :
63+ if interpolation_entities is None :
64+ raise ValueError (
65+ "For integration onto a submesh of codim 1,"
66+ + "the integration entities has to be provided"
67+ )
68+ else :
69+ if (ndim := interpolation_entities .ndim ) != 2 :
70+ raise ValueError (
71+ f"Interpolation entities has wrong input shape, should be 2D, got { ndim } "
72+ )
73+ num_cells = interpolation_entities .shape [0 ]
74+ else :
75+ raise RuntimeError ("Only codim-1 interpolation matrices can be defined" )
76+
77+ # Extract quadrature points for expression (in Q space)
3978 try :
4079 q_points = Q .element .interpolation_points ()
4180 except TypeError :
4281 q_points = Q .element .interpolation_points
4382
44- arguments = ufl .algorithms .extract_arguments (expr )
45- assert len (arguments ) == 1
46- V = arguments [0 ].ufl_function_space ()
47-
83+ # Compile expression
4884 num_points = q_points .shape [0 ]
4985 compiled_expr = dolfinx .fem .Expression (expr , q_points )
50- mesh = Q .mesh
51- tdim = mesh .topology .dim
52- num_cells = mesh .topology .index_map (tdim ).size_local
53- #
86+
5487 # (num_cells, num_points, num_dofs*bs, expr_value_size)
55- array_evaluated = compiled_expr .eval (mesh , np . arange ( num_cells , dtype = np . int32 ) )
88+ array_evaluated = compiled_expr .eval (mesh , interpolation_entities )
5689 assert np .prod (Q .value_shape ) == np .prod (expr .ufl_shape )
5790
5891 # Get data as (num_cells*num_points,1, expr_shape, num_test_basis_functions*test_block_size)
0 commit comments