Skip to content

Commit 9a449c5

Browse files
committed
PC: FunctionSpace() -> V.reconstruct()
1 parent 7a07dff commit 9a449c5

File tree

8 files changed

+28
-38
lines changed

8 files changed

+28
-38
lines changed

firedrake/functionspaceimpl.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -889,7 +889,6 @@ class RestrictedFunctionSpace(FunctionSpace):
889889
def __new__(cls, function_space, boundary_set=frozenset(), name=None):
890890
mesh = function_space.mesh()
891891
if mesh is not mesh.topology:
892-
# Restrict WithGeometry and return a WithGeometry
893892
V = RestrictedFunctionSpace(function_space.topological,
894893
boundary_set=boundary_set, name=name)
895894
return type(function_space).create(V, mesh)

firedrake/preconditioners/bddc.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from firedrake.petsc import PETSc
55
from firedrake.dmhooks import get_function_space, get_appctx
66
from firedrake.ufl_expr import TestFunction, TrialFunction
7-
from firedrake.functionspace import FunctionSpace, VectorFunctionSpace, TensorFunctionSpace
87
from ufl import curl, div, HCurl, HDiv, inner, dx
98
from pyop2.utils import as_tuple
109
import numpy
@@ -88,13 +87,7 @@ def initialize(self, pc):
8887
if B is None:
8988
from firedrake.assemble import assemble
9089
d = {HCurl: curl, HDiv: div}[sobolev_space]
91-
if V.shape == ():
92-
make_function_space = FunctionSpace
93-
elif len(V.shape) == 1:
94-
make_function_space = VectorFunctionSpace
95-
else:
96-
make_function_space = TensorFunctionSpace
97-
Q = make_function_space(V.mesh(), "DG", degree-1)
90+
Q = V.reconstruct(family="DG", degree=degree-1)
9891
b = inner(d(TrialFunction(V)), TestFunction(Q)) * dx(degree=2*(degree-1))
9992
B = assemble(b, mat_type="matfree")
10093
bddcpc.setBDDCDivergenceMat(B.petscmat)
@@ -103,7 +96,7 @@ def initialize(self, pc):
10396
if gradient is None:
10497
from firedrake.preconditioners.fdm import tabulate_exterior_derivative
10598
from firedrake.preconditioners.hiptmair import curl_to_grad
106-
Q = FunctionSpace(V.mesh(), curl_to_grad(V.ufl_element()))
99+
Q = V.reconstruct(element=curl_to_grad(V.ufl_element()))
107100
gradient = tabulate_exterior_derivative(Q, V)
108101
corners = get_vertex_dofs(Q)
109102
gradient.compose('_elements_corners', corners)
@@ -135,7 +128,7 @@ def applyTranspose(self, pc, x, y):
135128

136129

137130
def get_vertex_dofs(V):
138-
W = FunctionSpace(V.mesh(), restrict(V.ufl_element(), "vertex"))
131+
W = V.reconstruct(element=restrict(V.ufl_element(), "vertex"))
139132
indices = get_restriction_indices(V, W)
140133
V.dof_dset.lgmap.apply(indices, result=indices)
141134
vertex_dofs = PETSc.IS().createGeneral(indices, comm=V.comm)

firedrake/preconditioners/facet_split.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from finat.ufl import RestrictedElement, MixedElement, TensorElement, VectorElement
55
from firedrake.petsc import PETSc
66
from firedrake.preconditioners.base import PCBase
7+
from firedrake.bcs import restricted_function_space
78
import firedrake.dmhooks as dmhooks
89
import numpy
910

@@ -58,6 +59,8 @@ def initialize(self, pc):
5859
element = V.ufl_element()
5960
elements = [restrict(element, domain) for domain in domains]
6061
W = FunctionSpace(V.mesh(), elements[0] if len(elements) == 1 else MixedElement(elements))
62+
if V.boundary_set:
63+
W = restricted_function_space(W, [V.boundary_set]*len(W))
6164

6265
args = (TestFunction(W), TrialFunction(W))
6366
if len(W) > 1:

firedrake/preconditioners/fdm.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ def allocate_matrix(self, Amat, V, J, bcs, fcp, pmat_type, use_static_condensati
246246
elif len(ifacet) == 1:
247247
Vfacet = V[ifacet[0]]
248248
ebig, = set(unrestrict_element(Vsub.ufl_element()) for Vsub in V)
249-
Vbig = FunctionSpace(V.mesh(), ebig)
249+
Vbig = V.reconstruct(element=ebig)
250250
if len(V) > 1:
251251
dims = [Vsub.finat_element.space_dimension() for Vsub in V]
252252
assert sum(dims) == Vbig.finat_element.space_dimension()
@@ -436,17 +436,17 @@ def condense(self, A, J, bcs, fcp, pc_type="icc"):
436436
V0 = next((Vi for Vi in V if is_restricted(Vi.finat_element)[0]), None)
437437
V1 = next((Vi for Vi in V if is_restricted(Vi.finat_element)[1]), None)
438438
if V0 is None:
439-
V0 = FunctionSpace(V.mesh(), restrict_element(self.embedding_element, "interior"))
439+
V0 = V.reconstruct(element=restrict_element(self.embedding_element, "interior"))
440440
if V1 is None:
441-
V1 = FunctionSpace(V.mesh(), restrict_element(self.embedding_element, "facet"))
441+
V1 = V.reconstruct(element=restrict_element(self.embedding_element, "facet"))
442442
if len(V) == 1:
443443
J00 = J(*(t.reconstruct(function_space=V0) for t in J.arguments()))
444444
elif len(V) == 2:
445445
J00 = ExtractSubBlock().split(J, argument_indices=(V0.index, V0.index))
446446
ises = V.dof_dset.field_ises
447447
Smats[V[0], V[1]] = A.createSubMatrix(ises[0], ises[1])
448448
Smats[V[1], V[0]] = A.createSubMatrix(ises[1], ises[0])
449-
unindexed = {Vsub: FunctionSpace(Vsub.mesh(), Vsub.ufl_element()) for Vsub in V}
449+
unindexed = {Vsub: Vsub.collapse() for Vsub in V}
450450
bcs = tuple(bc.reconstruct(V=unindexed[bc.function_space()], g=0) for bc in bcs)
451451
else:
452452
raise ValueError("Expecting at most 2 components")
@@ -708,7 +708,7 @@ def _element_kernels(self):
708708
element_kernel = TripleProductKernel(R1, M, C1)
709709
schur_kernel = self.schur_kernel.get(Vrow) if Vrow == Vcol else None
710710
if schur_kernel is not None:
711-
V0 = FunctionSpace(Vrow.mesh(), restrict_element(self.embedding_element, "interior"))
711+
V0 = Vrow.collapse().reconstruct(element=restrict_element(self.embedding_element, "interior"))
712712
C0 = self.assemble_reference_tensor(V0, sort_interior=True)
713713
R0 = self.assemble_reference_tensor(V0, sort_interior=True, transpose=True)
714714
element_kernel = schur_kernel(element_kernel,
@@ -826,7 +826,7 @@ def set_values(self, A, Vrow, Vcol, mat_type=None):
826826
element_kernel = TripleProductKernel(R1, M, C1)
827827
schur_kernel = self.schur_kernel.get(Vrow) if on_diag else None
828828
if schur_kernel is not None:
829-
V0 = FunctionSpace(Vrow.mesh(), restrict_element(self.embedding_element, "interior"))
829+
V0 = Vrow.collapse().reconstruct(element=restrict_element(self.embedding_element, "interior"))
830830
C0 = self.assemble_reference_tensor(V0, sort_interior=True)
831831
R0 = self.assemble_reference_tensor(V0, sort_interior=True, transpose=True)
832832
element_kernel = schur_kernel(element_kernel,
@@ -1462,9 +1462,9 @@ def __init__(self, kernel, name=None):
14621462
fcp = self.child.fcp
14631463
args = form.arguments()
14641464
Q = args[0].function_space()
1465-
V = FunctionSpace(Q.mesh(), unrestrict_element(Q.ufl_element()))
1466-
V0 = FunctionSpace(Q.mesh(), restrict_element(V.ufl_element(), "interior"))
1467-
V1 = FunctionSpace(Q.mesh(), restrict_element(V.ufl_element(), "facet"))
1465+
V = Q.reconstruct(element=unrestrict_element(Q.ufl_element()))
1466+
V0 = Q.reconstruct(element=restrict_element(V.ufl_element(), "interior"))
1467+
V1 = Q.reconstruct(element=restrict_element(V.ufl_element(), "facet"))
14681468
idofs = PETSc.IS().createBlock(V.block_size, restricted_dofs(V0.finat_element, V.finat_element), comm=comm)
14691469
fdofs = PETSc.IS().createBlock(V.block_size, restricted_dofs(V1.finat_element, V.finat_element), comm=comm)
14701470
size = idofs.size + fdofs.size

firedrake/preconditioners/hiptmair.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from firedrake.bcs import DirichletBC
66
from firedrake.petsc import PETSc
77
from firedrake.preconditioners.base import PCBase
8-
from firedrake.functionspace import FunctionSpace
98
from firedrake.ufl_expr import TestFunction, TrialFunction
109
from firedrake.preconditioners.hypre_ams import chop
1110
from firedrake.preconditioners.facet_split import restrict
@@ -163,7 +162,7 @@ def coarsen(self, pc):
163162
if domain:
164163
celement = restrict(celement, domain)
165164

166-
coarse_space = FunctionSpace(mesh, celement)
165+
coarse_space = V.reconstruct(element=celement)
167166
assert coarse_space.finat_element.formdegree + 1 == formdegree
168167
coarse_space_bcs = [bc.reconstruct(V=coarse_space, g=0) for bc in bcs]
169168

firedrake/preconditioners/hypre_ads.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import firedrake.assemble as assemble
22
from firedrake.preconditioners.base import PCBase
33
from firedrake.petsc import PETSc
4-
from firedrake.functionspace import FunctionSpace, VectorFunctionSpace
54
from firedrake.ufl_expr import TestFunction
65
from firedrake.dmhooks import get_function_space
76
from firedrake.preconditioners.hypre_ams import chop
87
from firedrake.__future__ import interpolate
8+
from finat.ufl import VectorElement
99
from ufl import grad, curl, SpatialCoordinate
1010
from pyop2.utils import as_tuple
1111

@@ -26,8 +26,8 @@ def initialize(self, obj):
2626
if formdegree != 2 or degree != 1:
2727
raise ValueError("Hypre ADS requires lowest order RT elements! (not %s of degree %d)" % (family, degree))
2828

29-
P1 = FunctionSpace(mesh, "Lagrange", 1)
30-
NC1 = FunctionSpace(mesh, "N1curl" if mesh.ufl_cell().is_simplex() else "NCE", 1)
29+
P1 = V.reconstruct(family="Lagrange", degree=1)
30+
NC1 = V.reconstruct(family="N1curl" if mesh.ufl_cell().is_simplex() else "NCE", degree=1)
3131
G_callback = appctx.get("get_gradient", None)
3232
if G_callback is None:
3333
G = chop(assemble.assemble(interpolate(grad(TestFunction(P1)), NC1)).petscmat)
@@ -49,7 +49,7 @@ def initialize(self, obj):
4949
pc.setHYPREDiscreteGradient(G)
5050
pc.setHYPREDiscreteCurl(C)
5151

52-
VectorP1 = VectorFunctionSpace(mesh, "Lagrange", 1)
52+
VectorP1 = P1.reconstruct(element=VectorElement(P1.ufl_element()))
5353
interp = interpolate(SpatialCoordinate(mesh), VectorP1)
5454
pc.setCoordinates(assemble.assemble(interp).dat.data_ro.copy())
5555

firedrake/preconditioners/hypre_ams.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import firedrake.assemble as assemble
22
from firedrake.preconditioners.base import PCBase
33
from firedrake.petsc import PETSc
4-
from firedrake.functionspace import FunctionSpace, VectorFunctionSpace
54
from firedrake.ufl_expr import TestFunction
65
from firedrake.dmhooks import get_function_space
76
from firedrake.utils import complex_mode
87
from firedrake_citations import Citations
98
from firedrake import SpatialCoordinate
109
from firedrake.__future__ import interpolate
10+
from finat.ufl import VectorElement
1111
from ufl import grad
1212
from pyop2.utils import as_tuple
1313

@@ -47,7 +47,7 @@ def initialize(self, obj):
4747
if formdegree != 1 or degree != 1:
4848
raise ValueError("Hypre AMS requires lowest order Nedelec elements! (not %s of degree %d)" % (family, degree))
4949

50-
P1 = FunctionSpace(mesh, "Lagrange", 1)
50+
P1 = V.reconstruct(family="Lagrange", degree=1)
5151
G_callback = appctx.get("get_gradient", None)
5252
if G_callback is None:
5353
G = chop(assemble.assemble(interpolate(grad(TestFunction(P1)), V)).petscmat)
@@ -67,7 +67,7 @@ def initialize(self, obj):
6767
if zero_beta:
6868
pc.setHYPRESetBetaPoissonMatrix(None)
6969

70-
VectorP1 = VectorFunctionSpace(mesh, "Lagrange", 1)
70+
VectorP1 = P1.reconstruct(element=VectorElement(P1.ufl_element()))
7171
interp = interpolate(SpatialCoordinate(mesh), VectorP1)
7272
pc.setCoordinates(assemble.assemble(interp).dat.data_ro.copy())
7373
pc.setFromOptions()

firedrake/preconditioners/patch.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -654,22 +654,18 @@ def sort_entities(self, dm, axis, dir, ndiv=None, divisions=None):
654654
raise RuntimeError("Must either set ndiv or divisions for PlaneSmoother!")
655655

656656
mesh = dm.getAttr("__firedrake_mesh__")
657-
ele = mesh.coordinates.function_space().ufl_element()
658-
V = mesh.coordinates.function_space()
659-
if V.finat_element.entity_dofs() == V.finat_element.entity_closure_dofs():
657+
coordinates = mesh.coordinates
658+
V = coordinates.function_space()
659+
if V.finat_element.is_dg():
660660
# We're using DG or DQ for our coordinates, so we got
661661
# a periodic mesh. We need to interpolate to CGk
662662
# with access descriptor MAX to define a consistent opinion
663663
# about where the vertices are.
664-
CGkele = ele.reconstruct(family="Lagrange")
665664
# Need to supply the actual mesh to the FunctionSpace constructor,
666665
# not its weakref proxy (the variable `mesh`)
667666
# as interpolation fails because they are not hashable
668-
CGk = FunctionSpace(mesh.coordinates.function_space().mesh(), CGkele)
669-
coordinates = Interpolate(mesh.coordinates, CGk, access=op2.MAX)
670-
coordinates = assemble(coordinates)
671-
else:
672-
coordinates = mesh.coordinates
667+
CGk = V.reconstruct(family="Lagrange")
668+
coordinates = assemble(Interpolate(coordinates, CGk, access=op2.MAX))
673669

674670
select = partial(select_entity, dm=dm, exclude="pyop2_ghost")
675671
entities = [(p, self.coords(dm, p, coordinates)) for p in

0 commit comments

Comments
 (0)