diff --git a/firedrake/bcs.py b/firedrake/bcs.py index ee38b524e4..17a893328c 100644 --- a/firedrake/bcs.py +++ b/firedrake/bcs.py @@ -342,20 +342,21 @@ def function_arg(self, g): del self._function_arg_update except AttributeError: pass + V = self.function_space() if isinstance(g, firedrake.Function) and g.ufl_element().family() != "Real": - if g.function_space() != self.function_space(): + if g.function_space() != V: raise RuntimeError("%r is defined on incompatible FunctionSpace!" % g) self._function_arg = g elif isinstance(g, ufl.classes.Zero): - if g.ufl_shape and g.ufl_shape != self.function_space().ufl_element().value_shape: + if g.ufl_shape and g.ufl_shape != V.ufl_element().value_shape(V.mesh()): raise ValueError(f"Provided boundary value {g} does not match shape of space") # Special case. Scalar zero for direct Function.assign. self._function_arg = g elif isinstance(g, ufl.classes.Expr): - if g.ufl_shape != self.function_space().ufl_element().value_shape: + if g.ufl_shape != V.ufl_element().value_shape(V.mesh()): raise RuntimeError(f"Provided boundary value {g} does not match shape of space") try: - self._function_arg = firedrake.Function(self.function_space()) + self._function_arg = firedrake.Function(V) # Use `Interpolator` instead of assembling an `Interpolate` form # as the expression compilation needs to happen at this stage to # determine if we should use interpolation or projection @@ -363,7 +364,7 @@ def function_arg(self, g): self._function_arg_update = firedrake.Interpolator(g, self._function_arg)._interpolate except (NotImplementedError, AttributeError): # Element doesn't implement interpolation - self._function_arg = firedrake.Function(self.function_space()).project(g) + self._function_arg = firedrake.Function(V).project(g) self._function_arg_update = firedrake.Projector(g, self._function_arg).project else: try: diff --git a/firedrake/checkpointing.py b/firedrake/checkpointing.py index 28aaf04a94..57f1b00abc 100644 --- a/firedrake/checkpointing.py +++ b/firedrake/checkpointing.py @@ -935,7 +935,7 @@ def save_function(self, f, idx=None, name=None, timestepping_info={}): self._update_function_name_function_space_name_map(tmesh.name, mesh.name, {f.name(): V_name}) # Embed if necessary element = V.ufl_element() - _element = get_embedding_element_for_checkpointing(element) + _element = get_embedding_element_for_checkpointing(element, element.value_shape(mesh)) if _element != element: path = self._path_to_function_embedded(tmesh.name, mesh.name, V_name, f.name()) self.require_group(path) @@ -1337,7 +1337,7 @@ def load_function(self, mesh, name, idx=None): _name = self.get_attr(path, PREFIX_EMBEDDED + "_function") _f = self.load_function(mesh, _name, idx=idx) element = V.ufl_element() - _element = get_embedding_element_for_checkpointing(element) + _element = get_embedding_element_for_checkpointing(element, element.value_shape(mesh)) method = get_embedding_method_for_checkpointing(element) assert _element == _f.function_space().ufl_element() f = Function(V, name=name) @@ -1436,8 +1436,7 @@ def _get_shared_data_key_for_checkpointing(self, mesh, ufl_element): shape = ufl_element.reference_value_shape block_size = np.prod(shape) elif isinstance(ufl_element, finat.ufl.VectorElement): - shape = ufl_element.value_shape[:1] - block_size = np.prod(shape) + block_size = ufl_element.reference_value_shape[0] else: block_size = 1 return (nodes_per_entity, real_tensorproduct, block_size) diff --git a/firedrake/constant.py b/firedrake/constant.py index 9363e32f91..145edd5b5f 100644 --- a/firedrake/constant.py +++ b/firedrake/constant.py @@ -79,7 +79,7 @@ def __new__(cls, value, domain=None, name=None, count=None): if not isinstance(domain, ufl.AbstractDomain): cell = ufl.as_cell(domain) - coordinate_element = finat.ufl.VectorElement("Lagrange", cell, 1, gdim=cell.geometric_dimension) + coordinate_element = finat.ufl.VectorElement("Lagrange", cell, 1, dim=cell.topological_dimension()) domain = ufl.Mesh(coordinate_element) cell = domain.ufl_cell() diff --git a/firedrake/embedding.py b/firedrake/embedding.py index 3a618a44f1..e16d799902 100644 --- a/firedrake/embedding.py +++ b/firedrake/embedding.py @@ -4,7 +4,7 @@ import ufl -def get_embedding_dg_element(element, broken_cg=False): +def get_embedding_dg_element(element, value_shape, broken_cg=False): cell = element.cell family = lambda c: "DG" if c.is_simplex() else "DQ" if isinstance(cell, ufl.TensorProductCell): @@ -19,7 +19,7 @@ def get_embedding_dg_element(element, broken_cg=False): scalar_element = finat.ufl.FiniteElement(family(cell), cell=cell, degree=degree) if broken_cg: scalar_element = finat.ufl.BrokenElement(scalar_element.reconstruct(family="Lagrange")) - shape = element.value_shape + shape = value_shape if len(shape) == 0: DG = scalar_element elif len(shape) == 1: @@ -37,12 +37,12 @@ def get_embedding_dg_element(element, broken_cg=False): native_elements_for_checkpointing = {"Lagrange", "Discontinuous Lagrange", "Q", "DQ", "Real"} -def get_embedding_element_for_checkpointing(element): +def get_embedding_element_for_checkpointing(element, value_shape): """Convert the given UFL element to an element that :class:`~.CheckpointFile` can handle.""" if element.family() in native_elements_for_checkpointing: return element else: - return get_embedding_dg_element(element) + return get_embedding_dg_element(element, value_shape) def get_embedding_method_for_checkpointing(element): diff --git a/firedrake/external_operators/point_expr_operator.py b/firedrake/external_operators/point_expr_operator.py index 8d6b8fd992..b2cec6eac3 100644 --- a/firedrake/external_operators/point_expr_operator.py +++ b/firedrake/external_operators/point_expr_operator.py @@ -44,7 +44,7 @@ def __init__(self, *operands, function_space, derivatives=None, argument_slots=( if not isinstance(operator_data["func"], types.FunctionType): raise TypeError("Expecting a FunctionType pointwise expression") expr_shape = operator_data["func"](*operands).ufl_shape - if expr_shape != function_space.ufl_element().value_shape: + if expr_shape != function_space.ufl_element().value_shape(function_space.mesh()): raise ValueError("The dimension does not match with the dimension of the function space %s" % function_space) @property diff --git a/firedrake/formmanipulation.py b/firedrake/formmanipulation.py index eda7b730a1..26612c7c9b 100644 --- a/firedrake/formmanipulation.py +++ b/firedrake/formmanipulation.py @@ -125,7 +125,7 @@ def argument(self, o): else: args += [Zero() for j in numpy.ndindex( - V_is[i].ufl_element().value_shape)] + V_is[i].ufl_element().value_shape(V_is[i].mesh()))] return self._arg_cache.setdefault(o, as_vector(args)) diff --git a/firedrake/functionspace.py b/firedrake/functionspace.py index 2d6726b2a1..74dab04703 100644 --- a/firedrake/functionspace.py +++ b/firedrake/functionspace.py @@ -184,7 +184,7 @@ def VectorFunctionSpace(mesh, family, degree=None, dim=None, """ sub_element = make_scalar_element(mesh, family, degree, vfamily, vdegree, variant) if dim is None: - dim = mesh.ufl_cell().geometric_dimension() + dim = mesh.geometric_dimension() if not isinstance(dim, numbers.Integral) and dim > 0: raise ValueError(f"Can't make VectorFunctionSpace with dim={dim}") element = finat.ufl.VectorElement(sub_element, dim=dim) @@ -237,7 +237,7 @@ def TensorFunctionSpace(mesh, family, degree=None, shape=None, """ sub_element = make_scalar_element(mesh, family, degree, vfamily, vdegree, variant) - shape = shape or (mesh.ufl_cell().geometric_dimension(),) * 2 + shape = shape or (mesh.geometric_dimension(),) * 2 element = finat.ufl.TensorElement(sub_element, shape=shape, symmetry=symmetry) return FunctionSpace(mesh, element, name=name) diff --git a/firedrake/functionspaceimpl.py b/firedrake/functionspaceimpl.py index b0efa8a221..47b8647321 100644 --- a/firedrake/functionspaceimpl.py +++ b/firedrake/functionspaceimpl.py @@ -489,7 +489,7 @@ def __init__(self, mesh, element, name=None): shape_element = element if isinstance(element, finat.ufl.WithMapping): shape_element = element.wrapee - sub = shape_element.sub_elements[0].value_shape + sub = shape_element.sub_elements[0].reference_value_shape self.shape = rvs[:len(rvs) - len(sub)] else: self.shape = () diff --git a/firedrake/interpolation.py b/firedrake/interpolation.py index 70f6c31f86..c0b826f71c 100644 --- a/firedrake/interpolation.py +++ b/firedrake/interpolation.py @@ -547,7 +547,7 @@ def __init__( # VectorFunctionSpace equivalent is built from the scalar # sub-element. ufl_scalar_element = ufl_scalar_element.sub_elements[0] - if ufl_scalar_element.value_shape != (): + if ufl_scalar_element.value_shape(V_dest.mesh()) != (): raise NotImplementedError( "Can't yet cross-mesh interpolate onto function spaces made from VectorElements or TensorElements made from sub elements with value shape other than ()." ) @@ -614,7 +614,7 @@ def __init__( # I first point evaluate my expression at these locations, giving a # P0DG function on the VOM. As described in the manual, this is an # interpolation operation. - shape = V_dest.ufl_element().value_shape + shape = V_dest.ufl_element().value_shape(V_dest.mesh()) if len(shape) == 0: fs_type = firedrake.FunctionSpace elif len(shape) == 1: @@ -988,7 +988,7 @@ def callable(): else: # Make sure we have an expression of the right length i.e. a value for # each component in the value shape of each function space - dims = [numpy.prod(fs.ufl_element().value_shape, dtype=int) + dims = [numpy.prod(fs.ufl_element().value_shape(fs.mesh()), dtype=int) for fs in V] loops = [] if numpy.prod(expr.ufl_shape, dtype=int) != sum(dims): @@ -1024,13 +1024,13 @@ def _interpolator(V, tensor, expr, subset, arguments, access, bcs=None): if access is op2.READ: raise ValueError("Can't have READ access for output function") - if len(expr.ufl_shape) != len(V.ufl_element().value_shape): + if len(expr.ufl_shape) != len(V.ufl_element().value_shape(V.mesh())): raise RuntimeError('Rank mismatch: Expression rank %d, FunctionSpace rank %d' - % (len(expr.ufl_shape), len(V.ufl_element().value_shape))) + % (len(expr.ufl_shape), len(V.ufl_element().value_shape(V.mesh())))) - if expr.ufl_shape != V.ufl_element().value_shape: + if expr.ufl_shape != V.ufl_element().value_shape(V.mesh()): raise RuntimeError('Shape mismatch: Expression shape %r, FunctionSpace shape %r' - % (expr.ufl_shape, V.ufl_element().value_shape)) + % (expr.ufl_shape, V.ufl_element().value_shape(V.mesh()))) # NOTE: The par_loop is always over the target mesh cells. target_mesh = as_domain(V) diff --git a/firedrake/mesh.py b/firedrake/mesh.py index 05d7a4a77f..8624240421 100644 --- a/firedrake/mesh.py +++ b/firedrake/mesh.py @@ -66,10 +66,10 @@ } -_supported_embedded_cell_types = [ufl.Cell('interval', 2), - ufl.Cell('triangle', 3), - ufl.Cell("quadrilateral", 3), - ufl.TensorProductCell(ufl.Cell('interval'), ufl.Cell('interval'), geometric_dimension=3)] +_supported_embedded_cell_types_and_gdims = [(ufl.Cell('interval'), 2), + (ufl.Cell('triangle'), 3), + (ufl.Cell("quadrilateral"), 3), + (ufl.TensorProductCell(ufl.Cell('interval'), ufl.Cell('interval')), 3)] unmarked = -1 @@ -1477,8 +1477,8 @@ def mark_entities(self, tf, label_value, label_name=None): elem = tV.ufl_element() if tV.mesh() is not self: raise RuntimeError(f"tf must be defined on {self}: {tf.mesh()} is not {self}") - if elem.value_shape != (): - raise RuntimeError(f"tf must be scalar: {elem.value_shape} != ()") + if elem.reference_value_shape != (): + raise RuntimeError(f"tf must be scalar: {elem.reference_value_shape} != ()") if elem.family() in {"Discontinuous Lagrange", "DQ"} and elem.degree() == 0: # cells height = 0 @@ -2303,7 +2303,7 @@ def callback(self): self.topology.init() coordinates_fs = functionspace.FunctionSpace(self.topology, self.ufl_coordinate_element()) coordinates_data = dmcommon.reordered_coords(topology.topology_dm, coordinates_fs.dm.getDefaultSection(), - (self.num_vertices(), self.ufl_coordinate_element().cell.geometric_dimension())) + (self.num_vertices(), self.geometric_dimension())) coordinates = function.CoordinatelessFunction(coordinates_fs, val=coordinates_data, name=_generate_default_mesh_coordinates_name(self.name)) @@ -2470,7 +2470,7 @@ def spatial_index(self): from firedrake import function, functionspace from firedrake.parloops import par_loop, READ, MIN, MAX - gdim = self.ufl_cell().geometric_dimension() + gdim = self.geometric_dimension() if gdim <= 1: info_red("libspatialindex does not support 1-dimension, falling back on brute force.") return None @@ -2765,7 +2765,7 @@ def init_cell_orientations(self, expr): import firedrake.function as function import firedrake.functionspace as functionspace - if self.ufl_cell() not in _supported_embedded_cell_types: + if (self.ufl_cell(), self.geometric_dimension()) not in _supported_embedded_cell_types_and_gdims: raise NotImplementedError('Only implemented for intervals embedded in 2d and triangles and quadrilaterals embedded in 3d') if hasattr(self, '_cell_orientations'): @@ -2774,8 +2774,8 @@ def init_cell_orientations(self, expr): if not isinstance(expr, ufl.classes.Expr): raise TypeError("UFL expression expected!") - if expr.ufl_shape != (self.ufl_cell().geometric_dimension(), ): - raise ValueError(f"Mismatching shapes: expr.ufl_shape ({expr.ufl_shape}) != (self.ufl_cell().geometric_dimension(), ) (({self.ufl_cell().geometric_dimension}, ))") + if expr.ufl_shape != (self.geometric_dimension(), ): + raise ValueError(f"Mismatching shapes: expr.ufl_shape ({expr.ufl_shape}) != (self.geometric_dimension(), ) (({self.geometric_dimension}, ))") fs = functionspace.FunctionSpace(self, 'DG', 0) x = ufl.SpatialCoordinate(self) @@ -2848,12 +2848,9 @@ def make_mesh_from_coordinates(coordinates, name, tolerance=0.5): V = coordinates.function_space() element = coordinates.ufl_element() - if V.rank != 1 or len(element.value_shape) != 1: + if V.rank != 1 or len(element.reference_value_shape) != 1: raise ValueError("Coordinates must be from a rank-1 FunctionSpace with rank-1 value_shape.") assert V.mesh().ufl_cell().topological_dimension() <= V.value_size - # Build coordinate element - cell = element.cell.reconstruct(geometric_dimension=V.value_size) - element = element.reconstruct(cell=cell) mesh = MeshGeometry.__new__(MeshGeometry, element, coordinates.comm) mesh.__init__(coordinates) @@ -2886,11 +2883,10 @@ def make_mesh_from_mesh_topology(topology, name, tolerance=0.5): # TODO: meshfile might indicates higher-order coordinate element cell = topology.ufl_cell() geometric_dim = topology.topology_dm.getCoordinateDim() - cell = cell.reconstruct(geometric_dimension=geometric_dim) if not topology.topology_dm.getCoordinatesLocalized(): - element = finat.ufl.VectorElement("Lagrange", cell, 1) + element = finat.ufl.VectorElement("Lagrange", cell, 1, dim=geometric_dim) else: - element = finat.ufl.VectorElement("DQ" if cell in [ufl.quadrilateral, ufl.hexahedron] else "DG", cell, 1, variant="equispaced") + element = finat.ufl.VectorElement("DQ" if cell in [ufl.quadrilateral, ufl.hexahedron] else "DG", cell, 1, dim=geometric_dim, variant="equispaced") # Create mesh object mesh = MeshGeometry.__new__(MeshGeometry, element, topology.comm) mesh._init_topology(topology) @@ -2922,10 +2918,9 @@ def make_vom_from_vom_topology(topology, name, tolerance=0.5): import firedrake.function as function gdim = topology.topology_dm.getCoordinateDim() - tcell = topology.ufl_cell() - cell = tcell.reconstruct(geometric_dimension=gdim) - element = finat.ufl.VectorElement("DG", cell, 0) - vmesh = MeshGeometry.__new__(MeshGeometry, element, topology.comm) + cell = topology.ufl_cell() + element = finat.ufl.VectorElement("DG", cell, 0, dim=gdim) + vmesh = MeshGeometry.__new__(MeshGeometry, element) vmesh._init_topology(topology) # Save vertex reference coordinate (within reference cell) in function parent_tdim = topology._parent_mesh.ufl_cell().topological_dimension() @@ -3214,7 +3209,7 @@ def ExtrudedMesh(mesh, layers, layer_height=None, extrusion_type='uniform', peri pass elif extrusion_type in ("radial", "radial_hedgehog"): # do not allow radial extrusion if tdim = gdim - if mesh.ufl_cell().geometric_dimension() == mesh.ufl_cell().topological_dimension(): + if mesh.geometric_dimension() == mesh.topological_dimension(): raise RuntimeError("Cannot radially-extrude a mesh with equal geometric and topological dimension") else: # check for kernel @@ -3234,7 +3229,7 @@ def ExtrudedMesh(mesh, layers, layer_height=None, extrusion_type='uniform', peri element = finat.ufl.TensorProductElement(helement, velement) if gdim is None: - gdim = mesh.ufl_cell().geometric_dimension() + (extrusion_type == "uniform") + gdim = mesh.geometric_dimension() + (extrusion_type == "uniform") coordinates_fs = functionspace.VectorFunctionSpace(topology, element, dim=gdim) coordinates = function.CoordinatelessFunction(coordinates_fs, name=_generate_default_mesh_coordinates_name(name)) @@ -4537,8 +4532,8 @@ def RelabeledMesh(mesh, indicator_functions, subdomain_ids, **kwargs): plex1.createLabel(label_name) for f, subid in zip(indicator_functions, subdomain_ids): elem = f.topological.function_space().ufl_element() - if elem.value_shape != (): - raise RuntimeError(f"indicator functions must be scalar: got {elem.value_shape} != ()") + if elem.reference_value_shape != (): + raise RuntimeError(f"indicator functions must be scalar: got {elem.reference_value_shape} != ()") if elem.family() in {"Discontinuous Lagrange", "DQ"} and elem.degree() == 0: # cells height = 0 diff --git a/firedrake/mg/embedded.py b/firedrake/mg/embedded.py index 752ec6ff13..a5b70d8a27 100644 --- a/firedrake/mg/embedded.py +++ b/firedrake/mg/embedded.py @@ -17,9 +17,9 @@ non_native_variants = frozenset(["integral", "fdm", "alfeld"]) -def get_embedding_element(element): +def get_embedding_element(element, value_shape): broken_cg = element.sobolev_space in {ufl.H1, ufl.H2} - dg_element = get_embedding_dg_element(element, broken_cg=broken_cg) + dg_element = get_embedding_dg_element(element, value_shape, broken_cg=broken_cg) variant = element.variant() or "default" family = element.family() # Elements on Alfeld splits are embedded onto DG Powell-Sabin. @@ -40,8 +40,8 @@ class Cache(object): """A caching object for work vectors and matrices. :arg element: The element to use for the caching.""" - def __init__(self, element): - self.embedding_element = get_embedding_element(element) + def __init__(self, key): + self.embedding_element = get_embedding_dg_element(*key) self._dat_versions = {} self._V_DG_mass = {} self._DG_inv_mass = {} @@ -83,11 +83,16 @@ def _native_transfer(self, element, op): return self.native_transfers.setdefault(element, ops)[op] return None - def cache(self, element): + def cache(self, key): try: - return self.caches[element] + return self.caches[key] except KeyError: - return self.caches.setdefault(element, TransferManager.Cache(element)) + return self.caches.setdefault(key, TransferManager.Cache(key)) + + def get_cache_key(self, V): + elem = V.ufl_element() + value_shape = elem.value_shape(V.mesh()) + return elem, value_shape def V_dof_weights(self, V): """Dof weights for averaging projection. @@ -95,7 +100,7 @@ def V_dof_weights(self, V): :arg V: function space to compute weights for. :returns: A PETSc Vec. """ - cache = self.cache(V.ufl_element()) + cache = self.cache(self.get_cache_key(V)) key = V.dim() try: return cache._V_dof_weights[key] @@ -120,7 +125,7 @@ def V_DG_mass(self, V, DG): :arg DG: the DG space :returns: A PETSc Mat mapping from V -> DG """ - cache = self.cache(V.ufl_element()) + cache = self.cache(self.get_cache_key(V)) key = V.dim() try: return cache._V_DG_mass[key] @@ -135,7 +140,7 @@ def DG_inv_mass(self, DG): :arg DG: the DG space :returns: A PETSc Mat. """ - cache = self.caches[DG.ufl_element()] + cache = self.cache(self.get_cache_key(DG)) key = DG.dim() try: return cache._DG_inv_mass[key] @@ -151,7 +156,7 @@ def V_approx_inv_mass(self, V, DG): :arg DG: the DG space :returns: A PETSc Mat mapping from V -> DG. """ - cache = self.cache(V.ufl_element()) + cache = self.cache(self.get_cache_key(V)) key = V.dim() try: return cache._V_approx_inv_mass[key] @@ -169,7 +174,7 @@ def V_inv_mass_ksp(self, V): :arg V: a function space. :returns: A PETSc KSP for inverting (V, V). """ - cache = self.cache(V.ufl_element()) + cache = self.cache(self.get_cache_key(V)) key = V.dim() try: return cache._V_inv_mass_ksp[key] @@ -191,7 +196,7 @@ def DG_work(self, V): :returns: A Function in the embedding DG space. """ needs_dual = ufl.duals.is_dual(V) - cache = self.cache(V.ufl_element()) + cache = self.cache(self.get_cache_key(V)) key = (V.dim(), needs_dual) try: return cache._DG_work[key] @@ -208,28 +213,28 @@ def work_vec(self, V): :arg V: a function space. :returns: A PETSc Vec for V. """ - cache = self.cache(V.ufl_element()) + cache = self.cache(self.get_cache_key(V)) key = V.dim() try: return cache._work_vec[key] except KeyError: return cache._work_vec.setdefault(key, V.dof_dset.layout_vec.duplicate()) - def requires_transfer(self, element, transfer_op, source, target): + def requires_transfer(self, V, transfer_op, source, target): """Determine whether either the source or target have been modified since the last time a grid transfer was executed with them.""" key = (transfer_op, weakref.ref(source.dat), weakref.ref(target.dat)) dat_versions = (source.dat.dat_version, target.dat.dat_version) try: - return self.cache(element)._dat_versions[key] != dat_versions + return self.cache(self.get_cache_key(V))._dat_versions[key] != dat_versions except KeyError: return True - def cache_dat_versions(self, element, transfer_op, source, target): + def cache_dat_versions(self, V, transfer_op, source, target): """Record the returned dat_versions of the source and target.""" key = (transfer_op, weakref.ref(source.dat), weakref.ref(target.dat)) dat_versions = (source.dat.dat_version, target.dat.dat_version) - self.cache(element)._dat_versions[key] = dat_versions + self.cache(self.get_cache_key(V))._dat_versions[key] = dat_versions @PETSc.Log.EventDecorator() def op(self, source, target, transfer_op): @@ -243,7 +248,7 @@ def op(self, source, target, transfer_op): Vt = target.function_space() source_element = Vs.ufl_element() target_element = Vt.ufl_element() - if not self.requires_transfer(source_element, transfer_op, source, target): + if not self.requires_transfer(Vs, transfer_op, source, target): return if all(self.is_native(e, transfer_op) for e in (source_element, target_element)): @@ -280,7 +285,7 @@ def op(self, source, target, transfer_op): work = self.work_vec(Vt) self.V_DG_mass(Vt, VDGt).multTranspose(dgv, work) self.V_inv_mass_ksp(Vt).solve(work, t) - self.cache_dat_versions(source_element, transfer_op, source, target) + self.cache_dat_versions(Vs, transfer_op, source, target) def prolong(self, uc, uf): """Prolong a function. @@ -308,7 +313,7 @@ def restrict(self, source, target): Vt_star = target.function_space() source_element = Vs_star.ufl_element() target_element = Vt_star.ufl_element() - if not self.requires_transfer(source_element, Op.RESTRICT, source, target): + if not self.requires_transfer(Vs_star, Op.RESTRICT, source, target): return if all(self.is_native(e, Op.RESTRICT) for e in (source_element, target_element)): @@ -344,4 +349,4 @@ def restrict(self, source, target): with dgtarget.dat.vec_ro as dgv, target.dat.vec_wo as t: self.DG_inv_mass(VDGt).mult(dgv, dgwork) self.V_DG_mass(Vt, VDGt).multTranspose(dgwork, t) - self.cache_dat_versions(source_element, Op.RESTRICT, source, target) + self.cache_dat_versions(Vs_star, Op.RESTRICT, source, target) diff --git a/firedrake/mg/kernels.py b/firedrake/mg/kernels.py index 2c82092f51..fdb8ae8a08 100644 --- a/firedrake/mg/kernels.py +++ b/firedrake/mg/kernels.py @@ -46,11 +46,11 @@ def to_reference_coordinates(ufl_coordinate_element, parameters=None): # Create FInAT element element = tsfc.finatinterface.create_element(ufl_coordinate_element) - + gdim, = ufl_coordinate_element.reference_value_shape cell = ufl_coordinate_element.cell code = { - "geometric_dimension": cell.geometric_dimension(), + "geometric_dimension": gdim, "topological_dimension": cell.topological_dimension(), "to_reference_coords_newton_step": to_reference_coords_newton_step_body(ufl_coordinate_element, parameters, x0_dtype=ScalarType, dX_dtype="double"), "init_X": init_X(element.cell, parameters), @@ -220,7 +220,7 @@ def prolong_kernel(expression): assert hierarchy._meshes[int(idx)].cell_set._extruded V = expression.function_space() key = (("prolong",) - + expression.ufl_element().value_shape + + expression.ufl_element().value_shape(meshc) + entity_dofs_key(V.finat_element.complex.get_topology()) + entity_dofs_key(V.finat_element.entity_dofs()) + entity_dofs_key(coordinates.function_space().finat_element.entity_dofs())) @@ -302,7 +302,7 @@ def restrict_kernel(Vf, Vc): if Vf.extruded: assert Vc.extruded key = (("restrict",) - + Vf.ufl_element().value_shape + + Vf.ufl_element().value_shape(Vf.mesh()) + entity_dofs_key(Vf.finat_element.complex.get_topology()) + entity_dofs_key(Vc.finat_element.complex.get_topology()) + entity_dofs_key(Vf.finat_element.entity_dofs()) @@ -390,7 +390,7 @@ def inject_kernel(Vf, Vc): else: level_ratio = 1 key = (("inject", level_ratio) - + Vf.ufl_element().value_shape + + Vf.ufl_element().value_shape(Vf.mesh()) + entity_dofs_key(Vc.finat_element.complex.get_topology()) + entity_dofs_key(Vf.finat_element.complex.get_topology()) + entity_dofs_key(Vc.finat_element.entity_dofs()) diff --git a/firedrake/mg/mesh.py b/firedrake/mg/mesh.py index a40fad62f7..42ea985666 100644 --- a/firedrake/mg/mesh.py +++ b/firedrake/mg/mesh.py @@ -173,7 +173,7 @@ def MeshHierarchy(mesh, refinement_levels, scale = mesh._radius / np.linalg.norm(coords, axis=1).reshape(-1, 1) coords *= scale - meshes = [mesh] + [mesh_builder(dm, dim=mesh.ufl_cell().geometric_dimension(), + meshes = [mesh] + [mesh_builder(dm, dim=mesh.geometric_dimension(), distribution_parameters=distribution_parameters, reorder=reorder, comm=mesh.comm) for dm in dms] diff --git a/firedrake/mg/utils.py b/firedrake/mg/utils.py index f3eb475b50..2db5401c47 100644 --- a/firedrake/mg/utils.py +++ b/firedrake/mg/utils.py @@ -135,7 +135,7 @@ def coarse_cell_to_fine_node_map(Vc, Vf): def physical_node_locations(V): element = V.ufl_element() - if element.value_shape: + if element.value_shape(V.mesh()): assert isinstance(element, (finat.ufl.VectorElement, finat.ufl.TensorElement)) element = element.sub_elements[0] mesh = V.mesh() diff --git a/firedrake/pointeval_utils.py b/firedrake/pointeval_utils.py index f8a985273d..75ed2b4564 100644 --- a/firedrake/pointeval_utils.py +++ b/firedrake/pointeval_utils.py @@ -116,7 +116,7 @@ def predicate(index): extruded = isinstance(cell, TensorProductCell) code = { - "geometric_dimension": cell.geometric_dimension(), + "geometric_dimension": domain.geometric_dimension(), "layers_arg": ", int const *__restrict__ layers" if extruded else "", "layers": ", layers" if extruded else "", "extruded_define": "1" if extruded else "0", diff --git a/firedrake/pointquery_utils.py b/firedrake/pointquery_utils.py index 82059def13..238fcf4fd1 100644 --- a/firedrake/pointquery_utils.py +++ b/firedrake/pointquery_utils.py @@ -206,12 +206,12 @@ def compile_coordinate_element(ufl_coordinate_element, contains_eps, parameters= parameters = _ # Create FInAT element element = tsfc.finatinterface.create_element(ufl_coordinate_element) - + gdim, = ufl_coordinate_element.reference_value_shape cell = ufl_coordinate_element.cell extruded = isinstance(cell, ufl.TensorProductCell) code = { - "geometric_dimension": cell.geometric_dimension(), + "geometric_dimension": gdim, "topological_dimension": cell.topological_dimension(), "celldist_l1_c_expr": celldist_l1_c_expr(element.cell, "X"), "to_reference_coords_newton_step": to_reference_coords_newton_step(ufl_coordinate_element, parameters), diff --git a/firedrake/preconditioners/hiptmair.py b/firedrake/preconditioners/hiptmair.py index 51adace67e..ae2241b077 100644 --- a/firedrake/preconditioners/hiptmair.py +++ b/firedrake/preconditioners/hiptmair.py @@ -150,9 +150,9 @@ def coarsen(self, pc): element = V.ufl_element() formdegree = V.finat_element.formdegree if formdegree == 1: - celement = curl_to_grad(element) + celement = curl_to_grad(element, mesh) elif formdegree == 2: - celement = div_to_curl(element) + celement = div_to_curl(element, mesh) else: raise ValueError("Hiptmair decomposition not available for", element) @@ -211,15 +211,15 @@ def coarsen(self, pc): return coarse_operator, coarse_space_bcs, interp_petscmat -def curl_to_grad(ele): +def curl_to_grad(ele, mesh): if isinstance(ele, finat.ufl.VectorElement): - return type(ele)(curl_to_grad(ele._sub_element), dim=ele.num_sub_elements) + return type(ele)(curl_to_grad(ele._sub_element, mesh), dim=ele.num_sub_elements) elif isinstance(ele, finat.ufl.TensorElement): - return type(ele)(curl_to_grad(ele._sub_element), shape=ele.value_shape, symmetry=ele.symmetry()) + return type(ele)(curl_to_grad(ele._sub_element, mesh), shape=ele.value_shape(mesh), symmetry=ele.symmetry()) elif isinstance(ele, finat.ufl.MixedElement): - return type(ele)(*(curl_to_grad(e) for e in ele.sub_elements)) + return type(ele)(*(curl_to_grad(e, mesh) for e in ele.sub_elements)) elif isinstance(ele, finat.ufl.RestrictedElement): - return finat.ufl.RestrictedElement(curl_to_grad(ele._element), ele.restriction_domain()) + return finat.ufl.RestrictedElement(curl_to_grad(ele._element, mesh), ele.restriction_domain()) else: cell = ele.cell family = ele.family() @@ -238,25 +238,25 @@ def curl_to_grad(ele): return finat.ufl.FiniteElement(family, cell=cell, degree=degree, variant=variant) -def div_to_curl(ele): +def div_to_curl(ele, mesh): if isinstance(ele, finat.ufl.VectorElement): - return type(ele)(div_to_curl(ele._sub_element), dim=ele.num_sub_elements) + return type(ele)(div_to_curl(ele._sub_element, mesh), dim=ele.num_sub_elements) elif isinstance(ele, finat.ufl.TensorElement): - return type(ele)(div_to_curl(ele._sub_element), shape=ele.value_shape, symmetry=ele.symmetry()) + return type(ele)(div_to_curl(ele._sub_element, mesh), shape=ele.value_shape(mesh), symmetry=ele.symmetry()) elif isinstance(ele, finat.ufl.MixedElement): - return type(ele)(*(div_to_curl(e) for e in ele.sub_elements)) + return type(ele)(*(div_to_curl(e, mesh) for e in ele.sub_elements)) elif isinstance(ele, finat.ufl.RestrictedElement): - return finat.ufl.RestrictedElement(div_to_curl(ele._element), ele.restriction_domain()) + return finat.ufl.RestrictedElement(div_to_curl(ele._element, mesh), ele.restriction_domain()) elif isinstance(ele, finat.ufl.EnrichedElement): - return type(ele)(*(div_to_curl(e) for e in reversed(ele._elements))) + return type(ele)(*(div_to_curl(e, mesh) for e in reversed(ele._elements))) elif isinstance(ele, finat.ufl.TensorProductElement): - return type(ele)(*(div_to_curl(e) for e in ele.sub_elements), cell=ele.cell) + return type(ele)(*(div_to_curl(e, mesh) for e in ele.sub_elements), cell=ele.cell) elif isinstance(ele, finat.ufl.WithMapping): - return type(ele)(div_to_curl(ele.wrapee), ele.mapping()) + return type(ele)(div_to_curl(ele.wrapee, mesh), ele.mapping()) elif isinstance(ele, finat.ufl.BrokenElement): - return type(ele)(div_to_curl(ele._element)) + return type(ele)(div_to_curl(ele._element, mesh)) elif isinstance(ele, finat.ufl.HDivElement): - return finat.ufl.HCurlElement(div_to_curl(ele._element)) + return finat.ufl.HCurlElement(div_to_curl(ele._element, mesh)) elif isinstance(ele, finat.ufl.HCurlElement): raise ValueError("Expecting an H(div) element") else: diff --git a/firedrake/preconditioners/pmg.py b/firedrake/preconditioners/pmg.py index 7775219e60..d7c11aed51 100644 --- a/firedrake/preconditioners/pmg.py +++ b/firedrake/preconditioners/pmg.py @@ -132,7 +132,7 @@ def initialize(self, obj): while True: try: ele_ = self.coarsen_element(ele) - assert ele_.value_shape == ele.value_shape + assert ele_.value_shape(V.mesh()) == ele.value_shape(V.mesh()) ele = ele_ except ValueError: break @@ -1098,7 +1098,7 @@ def make_mapping_code(Q, cmapping, fmapping, t_in, t_out): if B: tensor = ufl.dot(B, tensor) if tensor else B if tensor is None: - tensor = ufl.Identity(Q.ufl_element().value_shape[0]) + tensor = ufl.Identity(Q.ufl_element().value_shape(Q.mesh())[0]) u = ufl.Coefficient(Q) expr = ufl.dot(tensor, u) @@ -1347,8 +1347,8 @@ def make_blas_kernels(self, Vf, Vc): in_place_mapping = True except Exception: qelem = finat.ufl.FiniteElement("DQ", cell=felem.cell, degree=PMGBase.max_degree(felem)) - if felem.value_shape: - qelem = finat.ufl.TensorElement(qelem, shape=felem.value_shape, symmetry=felem.symmetry()) + if felem.value_shape(Vf.mesh()): + qelem = finat.ufl.TensorElement(qelem, shape=felem.value_shape(Vf.mesh()), symmetry=felem.symmetry()) Qf = firedrake.FunctionSpace(Vf.mesh(), qelem) mapping_output = make_mapping_code(Qf, cmapping, fmapping, "t0", "t1") diff --git a/firedrake/pyplot/pgf.py b/firedrake/pyplot/pgf.py index 4f4862b722..20fc566a82 100644 --- a/firedrake/pyplot/pgf.py +++ b/firedrake/pyplot/pgf.py @@ -217,12 +217,12 @@ def pgfplot(f, filename, degree=1, complex_component='real', print_latex_example raise NotImplementedError(f"Not yet implemented for functions in spatial dimension {dim}") if mesh.extruded: raise NotImplementedError("Not yet implemented for functions on extruded meshes") - if elem.value_shape(): + if elem.value_shape(mesh): raise NotImplementedError("Currently only implemeted for scalar functions") - coordelem = get_embedding_dg_element(mesh.coordinates.function_space().ufl_element()).reconstruct(degree=degree, variant="equispaced") + coordelem = get_embedding_dg_element(mesh.coordinates.function_space().ufl_element(), (dim, )).reconstruct(degree=degree, variant="equispaced") coordV = FunctionSpace(mesh, coordelem) coords = Function(coordV).interpolate(SpatialCoordinate(mesh)) - elemdg = get_embedding_dg_element(elem).reconstruct(degree=degree, variant="equispaced") + elemdg = get_embedding_dg_element(elem, elem.value_shape(mesh)).reconstruct(degree=degree, variant="equispaced") Vdg = FunctionSpace(mesh, elemdg) fdg = Function(Vdg) method = get_embedding_method_for_checkpointing(elem) diff --git a/firedrake/slate/static_condensation/hybridization.py b/firedrake/slate/static_condensation/hybridization.py index 5dd592c44e..14872f015a 100644 --- a/firedrake/slate/static_condensation/hybridization.py +++ b/firedrake/slate/static_condensation/hybridization.py @@ -61,7 +61,7 @@ def initialize(self, pc): if len(V) != 2: raise ValueError("Expecting two function spaces.") - if all(Vi.ufl_element().value_shape for Vi in V): + if all(Vi.ufl_element().value_shape(Vi.mesh()) for Vi in V): raise ValueError("Expecting an H(div) x L2 pair of spaces.") # Automagically determine which spaces are vector and scalar diff --git a/firedrake/ufl_expr.py b/firedrake/ufl_expr.py index e129c26037..910e5c0c1f 100644 --- a/firedrake/ufl_expr.py +++ b/firedrake/ufl_expr.py @@ -76,7 +76,8 @@ def reconstruct(self, function_space=None, return self if not isinstance(number, int): raise TypeError(f"Expecting an int, not {number}") - if function_space.ufl_element().value_shape != self.ufl_element().value_shape: + mesh = self.function_space().mesh() + if function_space.ufl_element().value_shape(mesh) != self.ufl_element().value_shape(mesh): raise ValueError("Cannot reconstruct an Argument with a different value shape.") return Argument(function_space, number, part=part) @@ -140,7 +141,8 @@ def reconstruct(self, function_space=None, return self if not isinstance(number, int): raise TypeError(f"Expecting an int, not {number}") - if function_space.ufl_element().value_shape != self.ufl_element().value_shape: + mesh = self.function_space().mesh() + if function_space.ufl_element().value_shape(mesh) != self.ufl_element().value_shape(mesh): raise ValueError("Cannot reconstruct an Coargument with a different value shape.") return Coargument(function_space, number, part=part) diff --git a/tests/output/test_io_function.py b/tests/output/test_io_function.py index fc48a220b4..e8b833afe1 100644 --- a/tests/output/test_io_function.py +++ b/tests/output/test_io_function.py @@ -67,7 +67,7 @@ def _get_mesh(cell_type, comm): def _get_expr(V): mesh = V.mesh() dim = mesh.geometric_dimension() - shape = V.ufl_element().value_shape + shape = V.ufl_element().value_shape(mesh) if dim == 2: x, y = SpatialCoordinate(mesh) z = x * y diff --git a/tests/output/test_io_timestepping.py b/tests/output/test_io_timestepping.py index c12c30d74a..9a8c50c020 100644 --- a/tests/output/test_io_timestepping.py +++ b/tests/output/test_io_timestepping.py @@ -16,7 +16,7 @@ def _get_expr(V, i): mesh = V.mesh() element = V.ufl_element() x, y = SpatialCoordinate(mesh) - shape = element.value_shape + shape = element.value_shape(mesh) if element.family() == "Real": return 7. + i * i elif shape == (): diff --git a/tests/regression/test_change_coordinates.py b/tests/regression/test_change_coordinates.py index 05e46bd8d7..a712ffd6d5 100644 --- a/tests/regression/test_change_coordinates.py +++ b/tests/regression/test_change_coordinates.py @@ -13,7 +13,7 @@ def test_immerse_1d(dim): m = Mesh(new_coords) - assert m.ufl_cell().geometric_dimension() == dim + assert m.geometric_dimension() == dim def test_immerse_2d(): @@ -23,7 +23,7 @@ def test_immerse_2d(): m = Mesh(new_coords) - assert m.ufl_cell().geometric_dimension() == 3 + assert m.geometric_dimension() == 3 def test_project_2d(): @@ -33,7 +33,7 @@ def test_project_2d(): m = Mesh(new_coords) - assert m.ufl_cell().geometric_dimension() == 1 + assert m.geometric_dimension() == 1 def test_immerse_extruded(): @@ -44,4 +44,4 @@ def test_immerse_extruded(): m = Mesh(new_coords) - assert m.ufl_cell().geometric_dimension() == 3 + assert m.geometric_dimension() == 3 diff --git a/tests/regression/test_expressions.py b/tests/regression/test_expressions.py index 9387e52684..f2584bd6e4 100644 --- a/tests/regression/test_expressions.py +++ b/tests/regression/test_expressions.py @@ -295,7 +295,7 @@ def test_assign_with_different_meshes_fails(): def test_assign_vector_const_to_vfs(vcg1): f = Function(vcg1) - c = Constant(range(1, f.ufl_element().value_shape[0]+1)) + c = Constant(range(1, f.ufl_element().value_shape(vcg1.mesh())[0]+1)) f.assign(c) assert np.allclose(f.dat.data_ro, c.dat.data_ro) diff --git a/tests/regression/test_fas_snespatch.py b/tests/regression/test_fas_snespatch.py index b140f285ae..d2f755eb5f 100644 --- a/tests/regression/test_fas_snespatch.py +++ b/tests/regression/test_fas_snespatch.py @@ -170,7 +170,7 @@ def test_snespatch(mesh, CG1, solver_params): f = Constant(1, domain=mesh) F = inner(grad(u), grad(v))*dx - inner(f, v)*dx + inner(u**3 - u, v)*dx - z = zero(CG1.ufl_element().value_shape) + z = zero(CG1.ufl_element().value_shape(mesh)) bcs = DirichletBC(CG1, z, "on_boundary") nvproblem = NonlinearVariationalProblem(F, u, bcs=bcs) diff --git a/tests/regression/test_fdm.py b/tests/regression/test_fdm.py index fef477190e..b03a6fafb2 100644 --- a/tests/regression/test_fdm.py +++ b/tests/regression/test_fdm.py @@ -90,7 +90,7 @@ def build_riesz_map(V, d): x = SpatialCoordinate(V.mesh()) x -= Constant([0.5]*len(x)) - if V.ufl_element().value_shape == (): + if V.ufl_element().value_shape(V.mesh()) == (): u_exact = exp(-10*dot(x, x)) u_bc = u_exact else: @@ -195,7 +195,7 @@ def test_variable_coefficient(mesh): subs = ("on_boundary",) if mesh.cell_set._extruded: subs += ("top", "bottom") - bcs = [DirichletBC(V, zero(V.ufl_element().value_shape), sub) for sub in subs] + bcs = [DirichletBC(V, zero(V.ufl_element().value_shape(mesh)), sub) for sub in subs] uh = Function(V) problem = LinearVariationalProblem(a, L, uh, bcs=bcs) diff --git a/tests/regression/test_function.py b/tests/regression/test_function.py index 506d9bcb8e..cdc72ae09c 100644 --- a/tests/regression/test_function.py +++ b/tests/regression/test_function.py @@ -97,7 +97,7 @@ def test_mismatching_shape_interpolation(V): VV = VectorFunctionSpace(V.mesh(), 'CG', 1) f = Function(VV) with pytest.raises(RuntimeError): - f.interpolate(Constant([1] * (VV.ufl_element().value_shape[0] + 1))) + f.interpolate(Constant([1] * (VV.ufl_element().value_shape(VV.mesh())[0] + 1))) def test_function_val(V): diff --git a/tests/regression/test_interpolate.py b/tests/regression/test_interpolate.py index b375a6306d..4462c4dcb8 100644 --- a/tests/regression/test_interpolate.py +++ b/tests/regression/test_interpolate.py @@ -471,7 +471,7 @@ def test_interpolation_tensor_convergence(): V = TensorFunctionSpace(mesh, "RT", 1) x, y = SpatialCoordinate(mesh) - vs = V.ufl_element().value_shape + vs = V.ufl_element().value_shape(mesh) expr = as_tensor(np.asarray([ sin(2*pi*x*(i+1))*cos(4*pi*y*i) for i in range(np.prod(vs, dtype=int)) diff --git a/tests/regression/test_interpolate_cross_mesh.py b/tests/regression/test_interpolate_cross_mesh.py index 3f53287885..b0a87bfa9b 100644 --- a/tests/regression/test_interpolate_cross_mesh.py +++ b/tests/regression/test_interpolate_cross_mesh.py @@ -361,7 +361,7 @@ def test_interpolate_unitsquare_mixed(): # Can't go from non-mixed to mixed V_src_2 = VectorFunctionSpace(m_src, "CG", 1) - assert V_src_2.ufl_element().value_shape == V_src.ufl_element().value_shape + assert V_src_2.ufl_element().value_shape == V_src.ufl_element().value_shape(m_src) f_src_2 = Function(V_src_2) with pytest.raises(NotImplementedError): assemble(interpolate(f_src_2, V_dest)) diff --git a/tests/regression/test_interpolate_vs_project.py b/tests/regression/test_interpolate_vs_project.py index 1a6b38969e..d943abeba3 100644 --- a/tests/regression/test_interpolate_vs_project.py +++ b/tests/regression/test_interpolate_vs_project.py @@ -37,7 +37,7 @@ def test_interpolate_vs_project(V): elif dim == 3: x, y, z = SpatialCoordinate(mesh) - shape = V.ufl_element().value_shape + shape = V.ufl_element().value_shape(mesh) if dim == 2: if len(shape) == 0: expression = x + y diff --git a/tests/regression/test_p1pc.py b/tests/regression/test_p1pc.py index 1bdbfe3181..7c9bb6f195 100644 --- a/tests/regression/test_p1pc.py +++ b/tests/regression/test_p1pc.py @@ -36,7 +36,7 @@ def test_p_independence(mesh, expected): L = inner(Constant(1), v)*dx - bcs = DirichletBC(V, zero(V.ufl_element().value_shape), "on_boundary") + bcs = DirichletBC(V, zero(V.ufl_element().value_shape(mesh)), "on_boundary") uh = Function(V) problem = LinearVariationalProblem(a, L, uh, bcs=bcs) diff --git a/tests/regression/test_patch_pc.py b/tests/regression/test_patch_pc.py index 5a70438089..9abe5e94bd 100644 --- a/tests/regression/test_patch_pc.py +++ b/tests/regression/test_patch_pc.py @@ -38,7 +38,7 @@ def test_jacobi_sor_equivalence(mesh, problem_type, multiplicative): R = TensorFunctionSpace(mesh, "CG", 1) V = P*Q*R - shape = V.ufl_element().value_shape + shape = V.ufl_element().value_shape(mesh) rhs = numpy.full(shape, 1, dtype=float) u = TrialFunction(V) @@ -48,16 +48,16 @@ def test_jacobi_sor_equivalence(mesh, problem_type, multiplicative): # We also test patch pc with kernel argument compression. i = 1 # only active index f = Function(V) - fval = numpy.full(V.sub(i).ufl_element().value_shape, 1.0, dtype=float) + fval = numpy.full(V.sub(i).ufl_element().value_shape(mesh), 1.0, dtype=float) f.sub(i).interpolate(Constant(fval)) a = (inner(f[i], f[i]) * inner(grad(u), grad(v)))*dx L = inner(Constant(rhs), v)*dx - bcs = [DirichletBC(Q, zero(Q.ufl_element().value_shape), "on_boundary") + bcs = [DirichletBC(Q, zero(Q.ufl_element().value_shape(mesh)), "on_boundary") for Q in V.subfunctions] else: a = inner(grad(u), grad(v))*dx L = inner(Constant(rhs), v)*dx - bcs = DirichletBC(V, zero(V.ufl_element().value_shape), "on_boundary") + bcs = DirichletBC(V, zero(V.ufl_element().value_shape(mesh)), "on_boundary") uh = Function(V) problem = LinearVariationalProblem(a, L, uh, bcs=bcs) diff --git a/tests/regression/test_patch_precompute_element_tensors.py b/tests/regression/test_patch_precompute_element_tensors.py index 4907dcef56..a754f85e84 100644 --- a/tests/regression/test_patch_precompute_element_tensors.py +++ b/tests/regression/test_patch_precompute_element_tensors.py @@ -27,7 +27,7 @@ def test_patch_precompute_element_tensors(mesh, V): f = Constant((1, 1)) F = inner(grad(u), grad(v))*dx + gamma*inner(div(u), div(v))*dx - inner(f, v)*dx + avg(inner(u, v))*dS - z = zero(V.ufl_element().value_shape) + z = zero(V.ufl_element().value_shape(mesh)) bcs = DirichletBC(V, z, "on_boundary") sp = { diff --git a/tests/regression/test_tensor_algebra.py b/tests/regression/test_tensor_algebra.py index 8ab3192087..61871d4ef2 100644 --- a/tests/regression/test_tensor_algebra.py +++ b/tests/regression/test_tensor_algebra.py @@ -34,7 +34,7 @@ def mesh(request): "-2*mu_s*inner(grad(u), outer(conj(v), n)) * ds")], ids=lambda x: x[0]) def form_expect(request, mesh): - dim = mesh.ufl_cell().geometric_dimension() + dim = mesh.geometric_dimension() if mesh.ufl_cell().cellname() == "quadrilateral": V = FunctionSpace(mesh, "RTCF", 1) else: diff --git a/tests/vertexonly/test_swarm.py b/tests/vertexonly/test_swarm.py index e6e0848fb9..21c0b12eca 100644 --- a/tests/vertexonly/test_swarm.py +++ b/tests/vertexonly/test_swarm.py @@ -27,11 +27,11 @@ def cell_midpoints(m): num_cells_local = len(f.dat.data_ro) num_cells = MPI.COMM_WORLD.allreduce(num_cells_local, op=MPI.SUM) # reshape is for 1D case where f.dat.data_ro has shape (num_cells_local,) - local_midpoints = f.dat.data_ro.reshape(num_cells_local, m.ufl_cell().geometric_dimension()) + local_midpoints = f.dat.data_ro.reshape(num_cells_local, m.geometric_dimension()) local_midpoints_size = np.array(local_midpoints.size) local_midpoints_sizes = np.empty(MPI.COMM_WORLD.size, dtype=int) MPI.COMM_WORLD.Allgatherv(local_midpoints_size, local_midpoints_sizes) - midpoints = np.empty((num_cells, m.ufl_cell().geometric_dimension()), dtype=local_midpoints.dtype) + midpoints = np.empty((num_cells, m.geometric_dimension()), dtype=local_midpoints.dtype) MPI.COMM_WORLD.Allgatherv(local_midpoints, (midpoints, local_midpoints_sizes)) assert len(np.unique(midpoints, axis=0)) == len(midpoints) return midpoints, local_midpoints diff --git a/tests/vertexonly/test_vertex_only_mesh_generation.py b/tests/vertexonly/test_vertex_only_mesh_generation.py index 559d46fef6..ac33b461de 100644 --- a/tests/vertexonly/test_vertex_only_mesh_generation.py +++ b/tests/vertexonly/test_vertex_only_mesh_generation.py @@ -26,11 +26,11 @@ def cell_midpoints(m): num_cells_local = len(f.dat.data_ro) num_cells = MPI.COMM_WORLD.allreduce(num_cells_local, op=MPI.SUM) # reshape is for 1D case where f.dat.data_ro has shape (num_cells_local,) - local_midpoints = f.dat.data_ro.reshape(num_cells_local, m.ufl_cell().geometric_dimension()) + local_midpoints = f.dat.data_ro.reshape(num_cells_local, m.geometric_dimension()) local_midpoints_size = np.array(local_midpoints.size) local_midpoints_sizes = np.empty(MPI.COMM_WORLD.size, dtype=int) MPI.COMM_WORLD.Allgatherv(local_midpoints_size, local_midpoints_sizes) - midpoints = np.empty((num_cells, m.ufl_cell().geometric_dimension()), dtype=local_midpoints.dtype) + midpoints = np.empty((num_cells, m.geometric_dimension()), dtype=local_midpoints.dtype) MPI.COMM_WORLD.Allgatherv(local_midpoints, (midpoints, local_midpoints_sizes)) assert len(np.unique(midpoints, axis=0)) == len(midpoints) return midpoints, local_midpoints