|
1 | 1 | from firedrake import * |
| 2 | +from firedrake.formmanipulation import split_form |
2 | 3 | import pytest |
3 | 4 | import numpy as np |
4 | 5 |
|
@@ -235,3 +236,50 @@ def correct_indent(): |
235 | 236 |
|
236 | 237 | assert np.isclose(dest_eval05.evaluate(f_dest), 0.5) # x_src^2 + y_src^2 = 0.5 |
237 | 238 | assert np.isclose(dest_eval15.evaluate(f_dest), 3.0) # x_dest + y_dest = 3.0 |
| 239 | + |
| 240 | + |
| 241 | +def test_mixed_space_interpolation(): |
| 242 | + mesh = UnitSquareMesh(2, 2) |
| 243 | + V1 = FunctionSpace(mesh, "CG", 1) |
| 244 | + V2 = FunctionSpace(mesh, "CG", 2) |
| 245 | + V3 = FunctionSpace(mesh, "CG", 3) |
| 246 | + V4 = FunctionSpace(mesh, "CG", 4) |
| 247 | + W = V1 * V2 |
| 248 | + U = V3 * V4 |
| 249 | + |
| 250 | + # [test_mixed_space_interpolation 1] |
| 251 | + interp = interpolate(TrialFunction(U), W) |
| 252 | + I = assemble(interp, mat_type="nest") |
| 253 | + # [test_mixed_space_interpolation 2] |
| 254 | + |
| 255 | + # The block matrix structure is |
| 256 | + # | V3 -> V1 0 | |
| 257 | + # | 0 V4 -> V2 | |
| 258 | + for i in range(2): |
| 259 | + for j in range(2): |
| 260 | + sub_mat = I.petscmat.getNestSubMatrix(i, j) |
| 261 | + if i != j: |
| 262 | + assert not sub_mat |
| 263 | + continue |
| 264 | + else: |
| 265 | + res_block = assemble(interpolate(TrialFunction(U.sub(j)), W.sub(i))) |
| 266 | + assert np.allclose(sub_mat[:, :], res_block.petscmat[:, :]) |
| 267 | + assert sub_mat.type == "seqaij" |
| 268 | + |
| 269 | + # [test_mixed_space_interpolation 3] |
| 270 | + u0, u1 = TrialFunctions(U) |
| 271 | + expr = as_vector([u0 + u1, u0 + u1]) |
| 272 | + interp = interpolate(expr, W) |
| 273 | + I2 = assemble(interp, mat_type="nest") |
| 274 | + # [test_mixed_space_interpolation 4] |
| 275 | + |
| 276 | + # The block matrix structure is |
| 277 | + # | V3 -> V1 V4 -> V1 | |
| 278 | + # | V3 -> V2 V4 -> V2 | |
| 279 | + split_interp = dict(split_form(interp)) |
| 280 | + for i in range(2): |
| 281 | + for j in range(2): |
| 282 | + interp_ij = split_interp[(i, j)] |
| 283 | + assert isinstance(interp_ij, Interpolate) |
| 284 | + res_block = assemble(interpolate(TrialFunction(U.sub(j)), W.sub(i), allow_missing_dofs=True)) |
| 285 | + assert np.allclose(I2.petscmat.getNestSubMatrix(i, j)[:, :], res_block.petscmat[:, :]) |
0 commit comments