diff --git a/firedrake/mg/mesh.py b/firedrake/mg/mesh.py index 791775054d..b7f91fb679 100644 --- a/firedrake/mg/mesh.py +++ b/firedrake/mg/mesh.py @@ -204,7 +204,7 @@ def MeshHierarchy(mesh, refinement_levels, def ExtrudedMeshHierarchy(base_hierarchy, height, base_layer=-1, refinement_ratio=2, layers=None, - kernel=None, extrusion_type='uniform', gdim=None, + kernel=None, extrusion_type='uniform', periodic=False, gdim=None, mesh_builder=firedrake.ExtrudedMesh): """Build a hierarchy of extruded meshes by extruding a hierarchy of meshes. @@ -245,6 +245,7 @@ def ExtrudedMeshHierarchy(base_hierarchy, height, base_layer=-1, refinement_rati meshes = [mesh_builder(m, layer, kernel=kernel, layer_height=height/layer, extrusion_type=extrusion_type, + periodic=periodic, gdim=gdim) for (m, layer) in zip(base_hierarchy._meshes, layers)] diff --git a/tests/firedrake/multigrid/test_poisson_gmg_extruded.py b/tests/firedrake/multigrid/test_poisson_gmg_extruded.py index 68178ba969..659b0d17f6 100644 --- a/tests/firedrake/multigrid/test_poisson_gmg_extruded.py +++ b/tests/firedrake/multigrid/test_poisson_gmg_extruded.py @@ -2,8 +2,8 @@ import pytest -def run_poisson(typ): - if typ == "mg": +def run_poisson(solver_type, periodic=False): + if solver_type == "mg": parameters = {"snes_type": "ksponly", "ksp_type": "preonly", "pc_type": "mg", @@ -11,7 +11,7 @@ def run_poisson(typ): "mg_levels_ksp_type": "chebyshev", "mg_levels_ksp_max_it": 2, "mg_levels_pc_type": "jacobi"} - elif typ == "fas": + elif solver_type == "fas": parameters = {"snes_type": "fas", "snes_fas_type": "full", "fas_coarse_snes_type": "ksponly", @@ -25,7 +25,7 @@ def run_poisson(typ): "fas_levels_ksp_convergence_test": "skip", "snes_max_it": 1, "snes_convergence_test": "skip"} - elif typ == "newtonfas": + elif solver_type == "newtonfas": parameters = {"snes_type": "newtonls", "ksp_type": "preonly", "pc_type": "none", @@ -47,12 +47,12 @@ def run_poisson(typ): "npc_snes_max_it": 1, "npc_snes_convergence_test": "skip"} else: - raise RuntimeError("Unknown parameter set '%s' request", typ) + raise RuntimeError("Unknown parameter set '%s' request", solver_type) N = 10 base = UnitIntervalMesh(N) basemh = MeshHierarchy(base, 2) - mh = ExtrudedMeshHierarchy(basemh, height=1, base_layer=N) + mh = ExtrudedMeshHierarchy(basemh, height=1, base_layer=N, periodic=periodic) V = FunctionSpace(mh[-1], 'CG', 2) @@ -60,9 +60,8 @@ def run_poisson(typ): f = Function(V) v = TestFunction(V) F = inner(grad(u), grad(v))*dx - inner(f, v)*dx - bcs = [DirichletBC(V, 0, "on_boundary"), - DirichletBC(V, 0, "top"), - DirichletBC(V, 0, "bottom")] + subs = ("on_boundary",) if periodic else ("on_boundary", "top", "bottom") + bcs = [DirichletBC(V, 0, sub) for sub in subs] # Choose a forcing function such that the exact solution is not an # eigenmode. This stresses the preconditioner much more. e.g. 10 # iterations of ilu fails to converge this problem sufficiently. @@ -77,22 +76,12 @@ def run_poisson(typ): return norm(assemble(exact - u)) -@pytest.mark.parametrize("typ", - ["mg", "fas", "newtonfas"]) -def test_poisson_gmg(typ): - assert run_poisson(typ) < 4e-6 +@pytest.mark.parallel([1, 3]) +@pytest.mark.parametrize("solver_type", ["mg", "fas", "newtonfas"]) +def test_poisson_gmg(solver_type): + assert run_poisson(solver_type) < 4e-6 -@pytest.mark.parallel -def test_poisson_gmg_parallel_mg(): - assert run_poisson("mg") < 4e-6 - - -@pytest.mark.parallel -def test_poisson_gmg_parallel_fas(): - assert run_poisson("fas") < 4e-6 - - -@pytest.mark.parallel -def test_poisson_gmg_parallel_newtonfas(): - assert run_poisson("newtonfas") < 4e-6 +@pytest.mark.parallel([1, 3]) +def test_poisson_gmg_periodic(): + assert run_poisson("mg", periodic=True) < 4e-6