|
6 | 6 | cwd = abspath(dirname(__file__)) |
7 | 7 |
|
8 | 8 |
|
| 9 | +def mat_equals(a, b): |
| 10 | + """Check that two Matrices are equal.""" |
| 11 | + a = a.petscmat.copy() |
| 12 | + a.axpy(-1.0, b.petscmat) |
| 13 | + return a.norm(norm_type=PETSc.NormType.NORM_FROBENIUS) < 1e-14 |
| 14 | + |
| 15 | + |
9 | 16 | def test_constant(): |
10 | 17 | cg1 = FunctionSpace(UnitSquareMesh(5, 5), "CG", 1) |
11 | 18 | f = assemble(interpolate(Constant(1.0), cg1)) |
@@ -660,3 +667,59 @@ def test_interpolate_composition(mode): |
660 | 667 | res_adj = assemble(u5) |
661 | 668 | res_adj2 = assemble(interpolate(TestFunction(V5), conj(TestFunction(V1)) * dx)) |
662 | 669 | assert np.allclose(res_adj.dat.data_ro, res_adj2.dat.data_ro) |
| 670 | + |
| 671 | + |
| 672 | +@pytest.mark.parallel([1, 3]) |
| 673 | +def test_interpolate_form(): |
| 674 | + mesh = UnitSquareMesh(5, 5) |
| 675 | + V3 = FunctionSpace(mesh, "CG", 3) |
| 676 | + V2 = FunctionSpace(mesh, "CG", 2) |
| 677 | + V1 = FunctionSpace(mesh, "CG", 1) |
| 678 | + |
| 679 | + V3_trial = TrialFunction(V3) |
| 680 | + V2_test = TestFunction(V2) |
| 681 | + V1_test = TestFunction(V1) |
| 682 | + V2_dual_trial = TrialFunction(V2.dual()) |
| 683 | + |
| 684 | + two_form = inner(V3_trial, V2_test) * dx # V3 x V2 -> R, equiv V3 -> V2^* |
| 685 | + interp = interpolate(V1_test, two_form) # V3 x V1 -> R, equiv V3 -> V1^* |
| 686 | + assert interp.arguments() == (V1_test, V3_trial) |
| 687 | + res1 = assemble(interp) |
| 688 | + |
| 689 | + I = interpolate(V1_test, V2_dual_trial) # V2^* x V1 -> R, equiv V2^* -> V1^* |
| 690 | + interp2 = action(I, two_form) # V3 -> V1^* |
| 691 | + assert interp2.arguments() == (V1_test, V3_trial) |
| 692 | + res2 = assemble(interp2) |
| 693 | + assert mat_equals(res1, res2) |
| 694 | + |
| 695 | + res3 = assemble(inner(V3_trial, V1_test) * dx) # V3 x V1 -> R |
| 696 | + assert mat_equals(res1, res3) |
| 697 | + |
| 698 | + |
| 699 | +@pytest.mark.parallel([1, 3]) |
| 700 | +def test_interpolate_form_mixed(): |
| 701 | + mesh = UnitSquareMesh(3, 3) |
| 702 | + V1 = FunctionSpace(mesh, "CG", 1) |
| 703 | + V2 = FunctionSpace(mesh, "CG", 2) |
| 704 | + V3 = FunctionSpace(mesh, "CG", 3) |
| 705 | + V4 = FunctionSpace(mesh, "CG", 4) |
| 706 | + V = V3 * V4 |
| 707 | + W = V1 * V2 |
| 708 | + |
| 709 | + u = TrialFunction(V) |
| 710 | + v = TestFunction(V) |
| 711 | + q = TestFunction(W) |
| 712 | + |
| 713 | + form = inner(u, v) * dx # V x V -> R, equiv V -> V^* |
| 714 | + interp = interpolate(q, form) # V -> W^*, equiv V x W -> R |
| 715 | + assert interp.arguments() == (q, u) |
| 716 | + res1 = assemble(interp) |
| 717 | + |
| 718 | + I = interpolate(q, TrialFunction(V.dual())) # V^* x W -> R, equiv V^* -> W^* |
| 719 | + interp2 = action(I, form) # V -> W^* |
| 720 | + assert interp2.arguments() == (q, u) |
| 721 | + res2 = assemble(interp2) |
| 722 | + assert mat_equals(res1, res2) |
| 723 | + |
| 724 | + res3 = assemble(inner(u, q) * dx) # V x W -> R |
| 725 | + assert mat_equals(res1, res3) |
0 commit comments