From 24b3414dcc8825344090a82c6e1c093cffa77ab3 Mon Sep 17 00:00:00 2001 From: ksagiyam Date: Sat, 8 Oct 2022 21:21:55 +0100 Subject: [PATCH 1/8] extrusion: enable periodic extrusion --- firedrake/assemble.py | 12 +++++++- firedrake/cython/dmcommon.pyx | 34 ++++++++++++++++------ firedrake/extrusion_utils.py | 52 ++++++++++++++++++++++++++++++++++ firedrake/functionspacedata.py | 17 +++++++---- firedrake/functionspaceimpl.py | 13 +++++++-- firedrake/mesh.py | 32 +++++++++++++++------ 6 files changed, 135 insertions(+), 25 deletions(-) diff --git a/firedrake/assemble.py b/firedrake/assemble.py index 967debcdd7..2d3de8e337 100644 --- a/firedrake/assemble.py +++ b/firedrake/assemble.py @@ -792,6 +792,7 @@ def build(self): "interior_facet_horiz": op2.ON_INTERIOR_FACETS} iteration_region = iteration_regions.get(self._integral_type, None) extruded = self._mesh.extruded + extruded_periodic = self._mesh.extruded_periodic constant_layers = extruded and not self._mesh.variable_layers return op2.GlobalKernel(self._kinfo.kernel, @@ -799,6 +800,7 @@ def build(self): iteration_region=iteration_region, pass_layer_arg=self._kinfo.pass_layer_arg, extruded=extruded, + extruded_periodic=extruded_periodic, constant_layers=constant_layers, subset=self._needs_subset) @@ -860,8 +862,16 @@ def _get_map_arg(self, finat_element): offset += offset else: offset = None + if self._mesh.extruded_periodic: + offset_quotient = eutils.calculate_dof_offset_quotient(finat_element) + if offset_quotient is not None: + offset_quotient = tuple(offset_quotient) + if self._integral_type in {"interior_facet", "interior_facet_vert"}: + offset_quotient += offset_quotient + else: + offset_quotient = None - map_arg = op2.MapKernelArg(arity, offset) + map_arg = op2.MapKernelArg(arity, offset, offset_quotient) self._map_arg_cache[key] = map_arg return map_arg diff --git a/firedrake/cython/dmcommon.pyx b/firedrake/cython/dmcommon.pyx index c71d59ad1a..b473263c44 100644 --- a/firedrake/cython/dmcommon.pyx +++ b/firedrake/cython/dmcommon.pyx @@ -1168,6 +1168,7 @@ def create_section(mesh, nodes_per_entity, on_base=False, block_size=1): variable = mesh.variable_layers extruded = mesh.cell_set._extruded + extruded_periodic = mesh.cell_set._extruded_periodic on_base_ = on_base nodes_per_entity = np.asarray(nodes_per_entity, dtype=IntType) if variable: @@ -1176,7 +1177,10 @@ def create_section(mesh, nodes_per_entity, on_base=False, block_size=1): if on_base: nodes_per_entity = sum(nodes_per_entity[:, i] for i in range(2)) else: - nodes_per_entity = sum(nodes_per_entity[:, i]*(mesh.layers - i) for i in range(2)) + if extruded_periodic: + nodes_per_entity = sum(nodes_per_entity[:, i]*(mesh.layers - 1) for i in range(2)) + else: + nodes_per_entity = sum(nodes_per_entity[:, i]*(mesh.layers - i) for i in range(2)) section = PETSc.Section().create(comm=mesh._comm) @@ -1242,7 +1246,7 @@ def get_cell_nodes(mesh, np.ndarray[PetscInt, ndim=2, mode="c"] layer_extents np.ndarray[PetscInt, ndim=2, mode="c"] cell_closures np.ndarray[PetscInt, ndim=2, mode="c"] entity_orientations - bint is_swarm, variable + bint is_swarm, variable, extruded_periodic_1_layer dm = mesh.topology_dm is_swarm = type(dm) is PETSc.DMSwarm @@ -1255,6 +1259,10 @@ def get_cell_nodes(mesh, layer_extents = mesh.layer_extents if offset is None: raise ValueError("Offset cannot be None with variable layer extents") + # Special case: DoFs on the top layer are identified as those on the bottom layer. + extruded_periodic_1_layer = isinstance(mesh, firedrake.mesh.ExtrudedMeshTopology) and \ + mesh.extruded_periodic and \ + mesh.layers == 1 + 1 nclosure = cell_closures.shape[1] # Extract ordering from FInAT element entity DoFs ndofs_list = [] @@ -1315,15 +1323,25 @@ def get_cell_nodes(mesh, if variable: off += offset[flat_index[k]]*(layer_extents[c, 0] - layer_extents[entity, 0]) if entity_permutations is not None: - for j in range(ceil_ndofs[i]): - cell_nodes[cell, flat_index[k]] = off + entity_permutations_c[perm_offset + ceil_ndofs[i] * orient + j] - k += 1 + if extruded_periodic_1_layer: + for j in range(ceil_ndofs[i]): + cell_nodes[cell, flat_index[k]] = off + entity_permutations_c[perm_offset + ceil_ndofs[i] * orient + j] % offset[flat_index[k]] + k += 1 + else: + for j in range(ceil_ndofs[i]): + cell_nodes[cell, flat_index[k]] = off + entity_permutations_c[perm_offset + ceil_ndofs[i] * orient + j] + k += 1 perm_offset += ceil_ndofs[i] * num_orientations_c[i] else: # FInAT element must eventually add entity_permutations() method - for j in range(ceil_ndofs[i]): - cell_nodes[cell, flat_index[k]] = off + j - k += 1 + if extruded_periodic_1_layer: + for j in range(ceil_ndofs[i]): + cell_nodes[cell, flat_index[k]] = off + j % offset[flat_index[k]] + k += 1 + else: + for j in range(ceil_ndofs[i]): + cell_nodes[cell, flat_index[k]] = off + j + k += 1 CHKERR(PetscFree(ceil_ndofs)) CHKERR(PetscFree(flat_index)) if entity_permutations is not None: diff --git a/firedrake/extrusion_utils.py b/firedrake/extrusion_utils.py index bda7e77c41..d63fad9c56 100644 --- a/firedrake/extrusion_utils.py +++ b/firedrake/extrusion_utils.py @@ -354,6 +354,58 @@ def calculate_dof_offset(finat_element): return dof_offset +@functools.lru_cache() +def calculate_dof_offset_quotient(finat_element): + """Return the offset quotient for each DoF within the base cell. + + :arg finat_element: A FInAT element. + :returns: A numpy array containing the offset quotient for each DoF. + + offset_quotient q of each DoF (in a local cell) is defined as + i // o, where i is the local DoF ID of the DoF on the entity and + o is the offset of that DoF computed in ``calculate_dof_offset()``. + + Let DOF(e, l, i) represent a DoF on (base-)entity e on layer l that has local ID i + and suppose this DoF has offset o and offset_quotient q. In periodic extrusion it + is convenient to identify DOF(e, l, i) as DOF(e, l + q, i % o); this transformation + allows one to always work with the "unit cell" in which i < o always holds. + + In FEA offset_quotient is 0 or 1. + + Example:: + + local ID offset offset_quotient + + 2--2--2 2--2--2 1--1--1 + | | | | | | + CG2 1 1 1 2 2 2 0 0 0 + | | | | | | + 0--0--0 2--2--2 0--0--0 + + +-----+ +-----+ +-----+ + | 1 3 | | 4 4 | | 0 0 | + DG1 | | | | | | + | 0 2 | | 4 4 | | 0 0 | + +-----+ +-----+ +-----+ + + """ + # scalar-valued elements only + if isinstance(finat_element, finat.TensorFiniteElement): + finat_element = finat_element.base_element + if is_real_tensor_product_element(finat_element): + return None + dof_offset_quotient = numpy.zeros(finat_element.space_dimension(), dtype=IntType) + for (b, v), entities in finat_element.entity_dofs().items(): + for entity, dof_indices in entities.items(): + quotient = 1 if v == 0 and entity % 2 == 1 else 0 + for i in dof_indices: + dof_offset_quotient[i] = quotient + if (dof_offset_quotient == 0).all(): + # Avoid unnecessary codegen in pyop2/codegen/builder. + dof_offset_quotient = None + return dof_offset_quotient + + def is_real_tensor_product_element(element): """Is the provided FInAT element a tensor product involving the real space? diff --git a/firedrake/functionspacedata.py b/firedrake/functionspacedata.py index fdddb10f2c..9f7f807103 100644 --- a/firedrake/functionspacedata.py +++ b/firedrake/functionspacedata.py @@ -283,6 +283,8 @@ def get_top_bottom_boundary_nodes(mesh, key, V): offset, sub_domain) else: + if mesh.extruded_periodic and sub_domain == "top": + raise ValueError("Invalid subdomain 'top': 'top' boundary is identified as 'bottom' boundary in periodic extrusion") idx = {"bottom": -2, "top": -1}[sub_domain] section, indices, facet_points = V.cell_boundary_masks facet = facet_points[idx] @@ -397,7 +399,7 @@ class FunctionSpaceData(object): """ __slots__ = ("real_tensorproduct", "map_cache", "entity_node_lists", "node_set", "cell_boundary_masks", - "interior_facet_boundary_masks", "offset", + "interior_facet_boundary_masks", "offset", "offset_quotient", "extruded", "mesh", "global_numbering") @PETSc.Log.EventDecorator() @@ -436,6 +438,10 @@ def __init__(self, mesh, ufl_element): self.offset = eutils.calculate_dof_offset(finat_element) else: self.offset = None + if isinstance(mesh, mesh_mod.ExtrudedMeshTopology) and mesh.extruded_periodic: + self.offset_quotient = eutils.calculate_dof_offset_quotient(finat_element) + else: + self.offset_quotient = None self.entity_node_lists = get_entity_node_lists(mesh, (edofs_key, real_tensorproduct, eperm_key), entity_dofs, entity_permutations, global_numbering, self.offset) self.node_set = node_set @@ -478,7 +484,7 @@ def boundary_nodes(self, V, sub_domain): return get_facet_closure_nodes(V.mesh(), key, V) @PETSc.Log.EventDecorator() - def get_map(self, V, entity_set, map_arity, name, offset): + def get_map(self, V, entity_set, map_arity, name, offset, offset_quotient): """Return a :class:`pyop2.Map` from some topological entity to degrees of freedom. @@ -486,18 +492,19 @@ def get_map(self, V, entity_set, map_arity, name, offset): :arg entity_set: The :class:`pyop2.Set` of entities to map from. :arg map_arity: The arity of the resulting map. :arg name: A name for the resulting map. - :arg offset: Map offset (for extruded).""" + :arg offset: Map offset (for extruded). + :arg offset_quotient: Map offset_quotient (for extruded).""" # V is only really used for error checking and "name". assert len(V) == 1, "get_map should not be called on MixedFunctionSpace" entity_node_list = self.entity_node_lists[entity_set] - val = self.map_cache[entity_set] if val is None: val = op2.Map(entity_set, self.node_set, map_arity, entity_node_list, ("%s_"+name) % (V.name), - offset=offset) + offset=offset, + offset_quotient=offset_quotient) self.map_cache[entity_set] = val return val diff --git a/firedrake/functionspaceimpl.py b/firedrake/functionspaceimpl.py index 11a8f3375d..a29a384685 100644 --- a/firedrake/functionspaceimpl.py +++ b/firedrake/functionspaceimpl.py @@ -400,6 +400,7 @@ def __init__(self, mesh, element, name=None): self.real_tensorproduct = sdata.real_tensorproduct self.extruded = sdata.extruded self.offset = sdata.offset + self.offset_quotient = sdata.offset_quotient self.cell_boundary_masks = sdata.cell_boundary_masks self.interior_facet_boundary_masks = sdata.interior_facet_boundary_masks @@ -564,7 +565,8 @@ def cell_node_map(self): self.mesh().cell_set, self.finat_element.space_dimension(), "cell_node", - self.offset) + self.offset, + self.offset_quotient) def interior_facet_node_map(self): r"""Return the :class:`pyop2.types.map.Map` from interior facets to @@ -573,11 +575,15 @@ def interior_facet_node_map(self): offset = self.cell_node_map().offset if offset is not None: offset = numpy.append(offset, offset) + offset_quotient = self.cell_node_map().offset_quotient + if offset_quotient is not None: + offset_quotient = numpy.append(offset_quotient, offset_quotient) return sdata.get_map(self, self.mesh().interior_facets.set, 2*self.finat_element.space_dimension(), "interior_facet_node", - offset) + offset, + offset_quotient) def exterior_facet_node_map(self): r"""Return the :class:`pyop2.types.map.Map` from exterior facets to @@ -587,7 +593,8 @@ def exterior_facet_node_map(self): self.mesh().exterior_facets.set, self.finat_element.space_dimension(), "exterior_facet_node", - self.offset) + self.offset, + self.offset_quotient) def boundary_nodes(self, sub_domain): r"""Return the boundary nodes for this :class:`~.FunctionSpace`. diff --git a/firedrake/mesh.py b/firedrake/mesh.py index 58044e0ad4..99b170369b 100644 --- a/firedrake/mesh.py +++ b/firedrake/mesh.py @@ -831,6 +831,10 @@ def mark_entities(self, tf, label_name, label_value): """ pass + @utils.cached_property + def extruded_periodic(self): + return self.cell_set._extruded_periodic + class MeshTopology(AbstractMeshTopology): """A representation of mesh topology implemented on a PETSc DMPlex.""" @@ -1277,12 +1281,12 @@ class ExtrudedMeshTopology(MeshTopology): """Representation of an extruded mesh topology.""" @PETSc.Log.EventDecorator() - def __init__(self, mesh, layers, name=None, tolerance=1.0): + def __init__(self, mesh, layers, periodic=False, name=None, tolerance=1.0): """Build an extruded mesh topology from an input mesh topology :arg mesh: the unstructured base mesh topology - :arg layers: number of extruded cell layers in the "vertical" - direction. + :arg layers: number of occurence of base layer in the "vertical" direction. + :arg periodic: the flag for periodic extrusion; if True, only constant layer extrusion is allowed. :arg name: optional name of the extruded mesh topology. :kwarg tolerance: The relative tolerance (i.e. as defined on the reference cell) for the distance a point can be @@ -1303,6 +1307,8 @@ def __init__(self, mesh, layers, name=None, tolerance=1.0): if isinstance(mesh.topology, VertexOnlyMeshTopology): raise NotImplementedError("Extrusion not implemented for VertexOnlyMeshTopology") + if layers.shape and periodic: + raise ValueError("Must provide constant layer for periodic extrusion") mesh.init() self._base_mesh = mesh @@ -1343,7 +1349,7 @@ def __init__(self, mesh, layers, name=None, tolerance=1.0): """ else: self.variable_layers = False - self.cell_set = op2.ExtrudedSet(mesh.cell_set, layers=layers) + self.cell_set = op2.ExtrudedSet(mesh.cell_set, layers=layers, extruded_periodic=periodic) @utils.cached_property def cell_closure(self): @@ -1417,7 +1423,10 @@ def node_classes(self, nodes_per_entity, real_tensorproduct=False): return extnum.node_classes(self, nodes_per_entity) else: nodes = np.asarray(nodes_per_entity) - nodes_per_entity = sum(nodes[:, i]*(self.layers - i) for i in range(2)) + if self.extruded_periodic: + nodes_per_entity = sum(nodes[:, i]*(self.layers - 1) for i in range(2)) + else: + nodes_per_entity = sum(nodes[:, i]*(self.layers - i) for i in range(2)) return super(ExtrudedMeshTopology, self).node_classes(nodes_per_entity) @utils.cached_property @@ -2347,7 +2356,7 @@ def Mesh(meshfile, **kwargs): @PETSc.Log.EventDecorator("CreateExtMesh") -def ExtrudedMesh(mesh, layers, layer_height=None, extrusion_type='uniform', kernel=None, gdim=None, name=None, tolerance=1.0): +def ExtrudedMesh(mesh, layers, layer_height=None, extrusion_type='uniform', periodic=False, kernel=None, gdim=None, name=None, tolerance=1.0): """Build an extruded mesh from an input mesh :arg mesh: the unstructured base mesh @@ -2368,6 +2377,8 @@ def ExtrudedMesh(mesh, layers, layer_height=None, extrusion_type='uniform', kern :arg extrusion_type: the algorithm to employ to calculate the extruded coordinates. One of "uniform", "radial", "radial_hedgehog" or "custom". See below. + :arg periodic: the flag for periodic extrusion; if True, only constant layer extrusion is allowed. + Can be used with any "extrusion_type" to make annulus, torus, etc. :arg kernel: a ``pyop2.Kernel`` to produce coordinates for the extruded mesh. See :func:`~.make_extruded_coords` for more details. @@ -2417,6 +2428,8 @@ def ExtrudedMesh(mesh, layers, layer_height=None, extrusion_type='uniform', kern mesh.init() layers = np.asarray(layers, dtype=IntType) if layers.shape: + if periodic: + raise ValueError("Must provide constant layer for periodic extrusion") if layers.shape != (mesh.cell_set.total_size, 2): raise ValueError("Must provide single layer number or array of shape (%d, 2), not %s", mesh.cell_set.total_size, layers.shape) @@ -2447,7 +2460,7 @@ def ExtrudedMesh(mesh, layers, layer_height=None, extrusion_type='uniform', kern # layer_height is a scalar; equi-distant layers are fine pass - topology = ExtrudedMeshTopology(mesh.topology, layers, tolerance=tolerance) + topology = ExtrudedMeshTopology(mesh.topology, layers, periodic=periodic, tolerance=tolerance) if extrusion_type == "uniform": pass @@ -2466,7 +2479,10 @@ def ExtrudedMesh(mesh, layers, layer_height=None, extrusion_type='uniform', kern helement = mesh._coordinates.ufl_element().sub_elements()[0] if extrusion_type == 'radial_hedgehog': helement = helement.reconstruct(family="DG", variant="equispaced") - velement = ufl.FiniteElement("Lagrange", ufl.interval, 1) + if periodic: + velement = ufl.FiniteElement("DP", ufl.interval, 1, variant="equispaced") + else: + velement = ufl.FiniteElement("Lagrange", ufl.interval, 1) element = ufl.TensorProductElement(helement, velement) if gdim is None: From 8ff6d758452c148605bc44fba306793ee59850ac Mon Sep 17 00:00:00 2001 From: ksagiyam Date: Sat, 15 Oct 2022 22:22:21 +0100 Subject: [PATCH 2/8] extrusion: enable periodic extrusion (io) --- firedrake/checkpointing.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/firedrake/checkpointing.py b/firedrake/checkpointing.py index 68df3843fe..6da9094955 100644 --- a/firedrake/checkpointing.py +++ b/firedrake/checkpointing.py @@ -573,6 +573,7 @@ def save_mesh(self, mesh, distribution_name=None, permutation_name=None): path = self._path_to_topology_extruded(tmesh.name) self.require_group(path) self.set_attr(path, PREFIX_EXTRUDED + "_base_mesh", base_tmesh.name) + self.set_attr(path, PREFIX_EXTRUDED + "_periodic", tmesh.extruded_periodic) self.set_attr(path, PREFIX_EXTRUDED + "_variable_layers", tmesh.variable_layers) if tmesh.variable_layers: # Save tmesh.layers, which contains (start layer, stop layer)-tuple for each cell @@ -874,6 +875,7 @@ def load_mesh(self, name=DEFAULT_MESH_NAME, reorder=None, distribution_parameter if tmesh_key in self._tmesh_cache: tmesh = self._tmesh_cache[tmesh_key] else: + periodic = self.get_attr(path, PREFIX_EXTRUDED + "_periodic") if self.has_attr(path, PREFIX_EXTRUDED + "_periodic") else False variable_layers = self.get_attr(path, PREFIX_EXTRUDED + "_variable_layers") if variable_layers: cell = base_tmesh.ufl_cell() @@ -898,7 +900,7 @@ def load_mesh(self, name=DEFAULT_MESH_NAME, reorder=None, distribution_parameter lsf.bcastEnd(unit, layers_a, layers, MPI.REPLACE) else: layers = self.get_attr(path, PREFIX_EXTRUDED + "_layers") - tmesh = ExtrudedMeshTopology(base_tmesh, layers, name=tmesh_name) + tmesh = ExtrudedMeshTopology(base_tmesh, layers, periodic=periodic, name=tmesh_name) self._tmesh_cache[tmesh_key] = tmesh # -- Load mesh -- mesh_key = self._generate_mesh_key_from_names(name, From aebceadceb8c5ad9d25671ac4947025651843697 Mon Sep 17 00:00:00 2001 From: ksagiyam Date: Thu, 13 Oct 2022 15:47:40 +0100 Subject: [PATCH 3/8] extrusion: enable periodic extrusion (add test) --- tests/extrusion/test_extruded_periodic.py | 181 ++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 tests/extrusion/test_extruded_periodic.py diff --git a/tests/extrusion/test_extruded_periodic.py b/tests/extrusion/test_extruded_periodic.py new file mode 100644 index 0000000000..780b175103 --- /dev/null +++ b/tests/extrusion/test_extruded_periodic.py @@ -0,0 +1,181 @@ +import pytest +from firedrake import * +from firedrake.utils import ScalarType +from firedrake.mesh import make_mesh_from_coordinates +import numpy as np + + +def test_extruded_periodic_facet_integrals(): + # +---+---+ + # | 5.|13.| + # +---+---+ + # | 3.|11.| + # +---+---+ + # | 2.| 7.| + # +---+---+ + mesh = RectangleMesh(2, 1, 2.0, 1.0, quadrilateral=True) + extm = ExtrudedMesh(mesh, layers=3, layer_height=1.0, extrusion_type="uniform", periodic=True) + x, y, z = SpatialCoordinate(extm) + V = FunctionSpace(extm, "DG", 0) + f = Function(V).interpolate(conditional(And(x < 1.0, z < 1.0), 2.0, + conditional(And(x < 1.0, z < 2.0), 3.0, + conditional(And(x < 1.0, z < 3.0), 5.0, + conditional(And(x < 2.0, z < 1.0), 7.0, # noqa: E128 + conditional(And(x < 2.0, z < 2.0), 11.0, 13.0)))))) # noqa: E128 + val = assemble(f('-')*dS_h) + assert abs(val - 41.) < 1.e-12 + val = assemble(f('+')*dS_h) + assert abs(val - 41.) < 1.e-12 + val = assemble(f('-') * dS_v) + assert abs(val - 31.) < 1.e-12 + val = assemble(f('+') * dS_v) + assert abs(val - 10.) < 1.e-12 + val = assemble(f * ds_v(1)) + assert abs(val - 10.) < 1.e-12 + val = assemble(f * ds_v(2)) + assert abs(val - 31.) < 1.e-12 + val = assemble(f * ds_v(3)) + assert abs(val - 41.) < 1.e-12 + val = assemble(f * ds_v(4)) + assert abs(val - 41.) < 1.e-12 + val = assemble(f * ds_b) + assert abs(val - 9.) < 1.e-12 + val = assemble(f * ds_t) + assert abs(val - 18.) < 1.e-12 + + +def test_extruded_periodic_boundary_nodes(): + # +-----+------+ + # | | | + # 7 3 11 15 19 + # | | | + # 6--2--10-14-18 + # | | | + # 5 1 9 13 17 + # | | | + # 4--0--8--12-16 + mesh = UnitIntervalMesh(2) + extm = ExtrudedMesh(mesh, layers=2, extrusion_type="uniform", periodic=True) + V = FunctionSpace(extm, "CG", 2) + assert (V.boundary_nodes(1) == np.array([4, 5, 6, 7])).all() + assert (V.boundary_nodes(2) == np.array([16, 17, 18, 19])).all() + assert (V.boundary_nodes("bottom") == np.array([0, 4, 8, 12, 16])).all() + with pytest.raises(ValueError): + assert V.boundary_nodes("top") + + +def test_extruded_periodic_1_layer(): + # Test coner cases. + mesh = UnitIntervalMesh(1) + extm = ExtrudedMesh(mesh, layers=1, extrusion_type="uniform", periodic=True) + # DG0 x CG1: +---+ + # | | + # +-0-+ + # Identified as DG0 x DG0 + elem = TensorProductElement(FiniteElement("DG", mesh.ufl_cell(), 0), + FiniteElement("CG", "interval", 1)) + V = FunctionSpace(extm, elem) + v = TestFunction(V) + u = TrialFunction(V) + A = assemble(inner(u, v) * dx) + assert np.allclose(A.M.values, np.array([[1.]], dtype=ScalarType)) + # DG0 x CG2: +---+ + # | 1 | + # +-0-+ + elem = TensorProductElement(FiniteElement("DG", mesh.ufl_cell(), 0), + FiniteElement("CG", "interval", 2)) + V = FunctionSpace(extm, elem) + v = TestFunction(V) + u = TrialFunction(V) + A = assemble(inner(u, v) * dx) + assert np.allclose(A.M.values, np.array([[1. / 5., 2. / 15.], [2. / 15., 8. / 15]], dtype=ScalarType)) + + +@pytest.mark.parallel(nprocs=3) +def test_extruded_periodic_poisson(): + n = 64 + mesh = UnitIntervalMesh(n) + extm = ExtrudedMesh(mesh, layers=n, extrusion_type="uniform", periodic=True) + V = FunctionSpace(extm, "CG", 2) + u = TrialFunction(V) + v = TestFunction(V) + f = Function(V) + x, y = SpatialCoordinate(extm) + f.interpolate(- 8.0 * pi * pi * cos(2 * pi * x) * cos(2 * pi * y)) + a = - inner(grad(u), grad(v)) * dx + L = inner(f, v) * dx + exact = Function(V).interpolate(cos(2 * pi * x) * cos(2 * pi * y)) + bc = DirichletBC(V, exact, (1, 2)) + sol = Function(V) + solve(a == L, sol, bcs=[bc]) + assert sqrt(assemble(inner(sol - exact, sol - exact) * dx)) < 1.e-7 + + +@pytest.mark.parallel(nprocs=3) +def test_extruded_periodic_annulus(): + m = 5 # num. element in radial direction + n = 7 # num. element in circumferential direction + # Make reference mesh: mesh0 + mesh = CircleManifoldMesh(n) + mesh0 = ExtrudedMesh(mesh, layers=m, layer_height=1.0 / m, extrusion_type="radial") + # Make test mesh: mesh1 + mesh = IntervalMesh(m, 1.0, 2.0) + mesh1 = ExtrudedMesh(mesh, layers=n, layer_height=2 * pi / n, extrusion_type="uniform", periodic=True) + elem1 = mesh1.coordinates.ufl_element() + coordV1 = FunctionSpace(mesh1, elem1) + x1, y1 = SpatialCoordinate(mesh1) + coord1 = Function(coordV1).interpolate(as_vector([x1 * cos(y1), x1 * sin(y1)])) + mesh1 = make_mesh_from_coordinates(coord1.topological, "annulus") + mesh1._base_mesh = mesh + # Check volume + x0, y0 = SpatialCoordinate(mesh0) + x1, y1 = SpatialCoordinate(mesh1) + vol0 = assemble(Constant(1) * dx(domain=mesh0)) + vol1 = assemble(Constant(1) * dx(domain=mesh1)) + assert abs(vol1 - vol0) < 1.e-12 + # Check projection + RTCF0 = FunctionSpace(mesh0, "RTCF", 3) + RTCF1 = FunctionSpace(mesh1, "RTCF", 3) + f0 = Function(RTCF0).project(as_vector([sin(x0) + 2.0, cos(y0) + 3.0]), solver_parameters={"ksp_rtol": 1.e-13}) + f1 = Function(RTCF1).project(as_vector([sin(x1) + 2.0, cos(y1) + 3.0]), solver_parameters={"ksp_rtol": 1.e-13}) + int0 = assemble(inner(f0, as_vector([x0 + 5.0, y0 + 7.0])) * dx) + int1 = assemble(inner(f1, as_vector([x1 + 5.0, y1 + 7.0])) * dx) + assert abs(int1 - int0) < 1.e-12 + # Check mixed poisson + inner_boun_id0 = "bottom" + outer_boun_id0 = "top" + inner_boun_id1 = 1 + outer_boun_id1 = 2 + # -- reference + DG0 = FunctionSpace(mesh0, "DG", 2) + W0 = RTCF0 * DG0 + u0, p0 = TrialFunctions(W0) + v0, q0 = TestFunctions(W0) + u0_ = f0 + p0_ = Function(DG0).interpolate(x0 + y0 + 1.0) + a0 = (inner(u0, v0) + inner(p0, div(v0)) + inner(div(u0), q0)) * dx + L0 = conj(q0) * dx + bcs0 = [DirichletBC(W0.sub(0), u0_, outer_boun_id0), + DirichletBC(W0.sub(1), p0_, inner_boun_id0)] + w0 = Function(W0) + solve(a0 == L0, w0, bcs=bcs0) + # -- test + DG1 = FunctionSpace(mesh1, "DG", 2) + W1 = RTCF1 * DG1 + u1, p1 = TrialFunctions(W1) + v1, q1 = TestFunctions(W1) + u1_ = f1 + p1_ = Function(DG1).interpolate(x1 + y1 + 1.0) + a1 = (inner(u1, v1) + inner(p1, div(v1)) + inner(div(u1), q1)) * dx + L1 = conj(q1) * dx + bcs1 = [DirichletBC(W1.sub(0), u1_, outer_boun_id1), + DirichletBC(W1.sub(1), p1_, inner_boun_id1)] + w1 = Function(W1) + solve(a1 == L1, w1, bcs=bcs1) + # -- Check solutions + uint0 = assemble(inner(w0.sub(0), as_vector([sin(x0) + 0.2, cos(y0) + 0.3])) * dx) + uint1 = assemble(inner(w1.sub(0), as_vector([sin(x1) + 0.2, cos(y1) + 0.3])) * dx) + assert abs(uint1 - uint0) < 1.e-12 + pint0 = assemble(inner(w0.sub(1), x0 * y0 + 2.0) * dx) + pint1 = assemble(inner(w1.sub(1), x1 * y1 + 2.0) * dx) + assert abs(pint1 - pint0) < 1.e-12 From 46db24efbe890e14d68421f8ee6848b9a5db02e3 Mon Sep 17 00:00:00 2001 From: ksagiyam Date: Sat, 15 Oct 2022 22:22:32 +0100 Subject: [PATCH 4/8] extrusion: enable periodic extrusion (add test io) --- tests/output/test_io_function.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/output/test_io_function.py b/tests/output/test_io_function.py index 588ef6b84b..208e6a63c5 100644 --- a/tests/output/test_io_function.py +++ b/tests/output/test_io_function.py @@ -4,6 +4,7 @@ from os.path import abspath, dirname, join import functools from pyop2.mpi import COMM_WORLD +from firedrake.mesh import make_mesh_from_coordinates from firedrake.embedding import get_embedding_method_for_checkpointing from firedrake.utils import IntType @@ -552,6 +553,35 @@ def test_io_function_extrusion_variable_layer(cell_family_degree_vfamily_vdegree _load_check_save_functions(filename, func_name, comm, method, extruded_mesh_name, variable_layers=True) +@pytest.mark.parallel(nprocs=3) +def test_io_function_extrusion_periodic(tmpdir): + filename = join(str(tmpdir), "test_io_function_extrusion_periodic_dump.h5") + filename = COMM_WORLD.bcast(filename, root=0) + m = 5 # num. element in radial direction + n = 31 # num. element in circumferential direction + mesh = IntervalMesh(m, 1.0, 2.0, name=mesh_name) + extm = ExtrudedMesh(mesh, layers=n, layer_height=2 * pi / n, extrusion_type="uniform", periodic=True, name=extruded_mesh_name) + elem = extm.coordinates.ufl_element() + coordV = FunctionSpace(extm, elem) + x, y = SpatialCoordinate(extm) + coord = Function(coordV).interpolate(as_vector([x * cos(y), x * sin(y)])) + extm = make_mesh_from_coordinates(coord.topological, name=extruded_mesh_name) + extm._base_mesh = mesh + V = FunctionSpace(extm, "RTCF", 3) + method = get_embedding_method_for_checkpointing(V.ufl_element()) + f = Function(V, name=func_name) + _initialise_function(f, _get_expr(V), method) + with CheckpointFile(filename, 'w', comm=COMM_WORLD) as afile: + afile.save_function(f) + # Load -> View cycle + ntimes = COMM_WORLD.size + for i in range(ntimes): + mycolor = (COMM_WORLD.rank > ntimes - 1 - i) + comm = COMM_WORLD.Split(color=mycolor, key=COMM_WORLD.rank) + if mycolor == 0: + _load_check_save_functions(filename, func_name, comm, method, extruded_mesh_name) + + @pytest.mark.parallel(nprocs=2) @pytest.mark.parametrize("cell_family_degree", [("triangle", "P", 1), ("quadrilateral", "Q", 1)]) From 6b3dbdfc9756844bde165e1c332269705acece3f Mon Sep 17 00:00:00 2001 From: ksagiyam Date: Fri, 17 Feb 2023 16:36:19 +0000 Subject: [PATCH 5/8] utility_meshes: add AnnulusMesh and SolidTorusMesh --- firedrake/utility_meshes.py | 106 ++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) diff --git a/firedrake/utility_meshes.py b/firedrake/utility_meshes.py index 1626c036e1..e186ceac85 100644 --- a/firedrake/utility_meshes.py +++ b/firedrake/utility_meshes.py @@ -56,6 +56,8 @@ "CubedSphereMesh", "UnitCubedSphereMesh", "TorusMesh", + "AnnulusMesh", + "SolidTorusMesh", "CylinderMesh", ] @@ -2540,6 +2542,110 @@ def TorusMesh( return m +@PETSc.Log.EventDecorator() +def AnnulusMesh( + R, + r, + nr=4, + nt=32, + distribution_parameters=None, + comm=COMM_WORLD, + name=mesh.DEFAULT_MESH_NAME, + distribution_name=None, + permutation_name=None, +): + """Generate an annulus mesh periodically extruding an interval mesh + + :arg R: The outer radius + :arg r: The inner radius + :kwarg nr: (optional), number of cells in the radial direction + :kwarg nt: (optional), number of cells in the circumferential direction (min 3) + :kwarg comm: Optional communicator to build the mesh on (defaults to + COMM_WORLD). + :kwarg name: Optional name of the mesh. + :kwarg distribution_name: the name of parallel distribution used + when checkpointing; if ``None``, the name is automatically + generated. + :kwarg permutation_name: the name of entity permutation (reordering) used + when checkpointing; if ``None``, the name is automatically + generated. + """ + if nt < 3: + raise ValueError("Must have at least 3 cells in the circumferential direction") + base_name = name + "_base" + base = IntervalMesh(nr, + r, + right=R, + distribution_parameters=distribution_parameters, + comm=comm, + name=base_name, + distribution_name=distribution_name, + permutation_name=permutation_name) + bar = mesh.ExtrudedMesh(base, layers=nt, layer_height=2 * np.pi / nt, extrusion_type="uniform", periodic=True) + x, y = ufl.SpatialCoordinate(bar) + V = bar.coordinates.function_space() + coord = Function(V).interpolate(ufl.as_vector([x * ufl.cos(y), x * ufl.sin(y)])) + annulus = mesh.make_mesh_from_coordinates(coord.topological, name) + annulus.topology.name = mesh._generate_default_mesh_topology_name(name) + annulus._base_mesh = base + return annulus + + +@PETSc.Log.EventDecorator() +def SolidTorusMesh( + R, + r, + nR=8, + refinement_level=0, + reorder=None, + distribution_parameters=None, + comm=COMM_WORLD, + name=mesh.DEFAULT_MESH_NAME, + distribution_name=None, + permutation_name=None, +): + """Generate a solid toroidal mesh (with axis z) periodically extruding a disk mesh + + :arg R: The major radius + :arg r: The minor radius + :kwarg nR: (optional), number of cells in the major direction (min 3, defaults to 8) + :kwarg refinement_level: (optional), number of times the base disk mesh is refined (defaults to 0). + :kwarg reorder: (optional), should the mesh be reordered + :kwarg comm: Optional communicator to build the mesh on (defaults to + COMM_WORLD). + :kwarg name: Optional name of the mesh. + :kwarg distribution_name: the name of parallel distribution used + when checkpointing; if ``None``, the name is automatically + generated. + :kwarg permutation_name: the name of entity permutation (reordering) used + when checkpointing; if ``None``, the name is automatically + generated. + """ + if nR < 3: + raise ValueError("Must have at least 3 cells in the major direction") + base_name = name + "_base" + unit = UnitDiskMesh(refinement_level=refinement_level, + reorder=reorder, + distribution_parameters=distribution_parameters, + comm=comm, + distribution_name=distribution_name, + permutation_name=permutation_name) + x, y = ufl.SpatialCoordinate(unit) + V = unit.coordinates.function_space() + coord = Function(V).interpolate(ufl.as_vector([r * x + R, r * y])) + disk = mesh.make_mesh_from_coordinates(coord.topological, base_name) + disk.topology.name = mesh._generate_default_mesh_topology_name(base_name) + disk.topology.topology_dm.setName(disk.topology.name) + bar = mesh.ExtrudedMesh(disk, layers=nR, layer_height=2 * np.pi / nR, extrusion_type="uniform", periodic=True) + x, y, z = ufl.SpatialCoordinate(bar) + V = bar.coordinates.function_space() + coord = Function(V).interpolate(ufl.as_vector([x * ufl.cos(z), x * ufl.sin(z), -y])) + torus = mesh.make_mesh_from_coordinates(coord.topological, name) + torus.topology.name = mesh._generate_default_mesh_topology_name(name) + torus._base_mesh = disk + return torus + + @PETSc.Log.EventDecorator() def CylinderMesh( nr, From 958b079a5fcea8ca211ae9fb5b85894a2eff1e70 Mon Sep 17 00:00:00 2001 From: ksagiyam Date: Fri, 17 Feb 2023 16:54:59 +0000 Subject: [PATCH 6/8] utility_meshes: add AnnulusMesh and SolidTorusMesh (add test) --- tests/meshes/test_meshes_volume.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/meshes/test_meshes_volume.py diff --git a/tests/meshes/test_meshes_volume.py b/tests/meshes/test_meshes_volume.py new file mode 100644 index 0000000000..d355ca120e --- /dev/null +++ b/tests/meshes/test_meshes_volume.py @@ -0,0 +1,22 @@ +import pytest +from firedrake import * + + +@pytest.mark.parallel(nprocs=3) +def test_meshes_volume_annulusmesh(): + R = 4 + r = 3 + mesh = AnnulusMesh(R, r, nr=8, nt=128) + vol = assemble(Constant(1., domain=mesh) * dx) + exact = pi * (R**2 - r**2) + assert abs(vol - exact) / exact < .0005 + + +@pytest.mark.parallel(nprocs=3) +def test_meshes_volume_solidtorusmesh(): + R = 7 # major radius + r = 3 # minor radius + mesh = SolidTorusMesh(R, r, nR=128, refinement_level=6) + vol = assemble(Constant(1., domain=mesh) * dx) + exact = (pi * r * r) * (2 * pi * R) + assert abs(vol - exact) / exact < .0005 From f7ff136111baee29cadaf4b44bceeea1c4323a58 Mon Sep 17 00:00:00 2001 From: ksagiyam Date: Thu, 23 Feb 2023 00:28:03 +0000 Subject: [PATCH 7/8] utility_mesh: add distribution_parameters to doc strings --- firedrake/utility_meshes.py | 62 +++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/firedrake/utility_meshes.py b/firedrake/utility_meshes.py index e186ceac85..d9feb3aa34 100644 --- a/firedrake/utility_meshes.py +++ b/firedrake/utility_meshes.py @@ -82,6 +82,8 @@ def IntervalMesh( :arg right: (optional) position of the right boundary point (in which case ``length_or_left`` should be the left boundary point). + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -155,6 +157,8 @@ def UnitIntervalMesh( Generate a uniform mesh of the interval [0,1]. :arg ncells: The number of the cells over the interval. + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -194,6 +198,8 @@ def PeriodicIntervalMesh( :arg ncells: The number of cells over the interval. :arg length: The length the interval. + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -281,6 +287,8 @@ def PeriodicUnitIntervalMesh( """Generate a periodic mesh of the unit interval :arg ncells: The number of cells in the interval. + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -320,6 +328,8 @@ def OneElementThickMesh( :arg ncells: The number of cells in the mesh. :arg Lx: The width of the domain in the x-direction. :arg Ly: The width of the domain in the y-direction. + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -541,6 +551,8 @@ def RectangleMesh( :arg Ly: The extent in the y direction :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg diagonal: For triangular meshes, should the diagonal got @@ -600,6 +612,8 @@ def TensorRectangleMesh( :arg ycoords: mesh points for the y direction :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg diagonal: For triangular meshes, should the diagonal got @@ -725,6 +739,8 @@ def SquareMesh( :arg L: The extent in the x and y directions :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -777,6 +793,8 @@ def UnitSquareMesh( :arg ny: The number of cells in the y direction :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -835,6 +853,8 @@ def PeriodicRectangleMesh( ``"both"``, ``"x"`` or ``"y"``. :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. ``"left"`` is the default. Not valid for quad meshes. Only used for direction ``"x"`` or direction ``"y"``. :kwarg comm: Optional communicator to build the mesh on (defaults to @@ -998,6 +1018,8 @@ def PeriodicSquareMesh( ``"both"``, ``"x"`` or ``"y"``. :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. ``"left"`` is the default. Not valid for quad meshes. :kwarg comm: Optional communicator to build the mesh on (defaults to @@ -1059,6 +1081,8 @@ def PeriodicUnitSquareMesh( ``"both"``, ``"x"`` or ``"y"``. :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. ``"left"`` is the default. Not valid for quad meshes. :kwarg comm: Optional communicator to build the mesh on (defaults to @@ -1116,6 +1140,8 @@ def CircleManifoldMesh( (defaults to 1). :kwarg degree: polynomial degree of coordinate space (defaults to 1: cells are straight line segments) + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -1190,6 +1216,8 @@ def UnitDiskMesh( :kwarg refinement_level: optional number of refinements (0 is a diamond) :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -1269,6 +1297,8 @@ def UnitBallMesh( :kwarg refinement_level: optional number of refinements (0 is an octahedron) :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional MPI communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -1402,6 +1432,8 @@ def BoxMesh( :arg Ly: The extent in the y direction :arg Lz: The extent in the z direction :kwarg hexahedral: (optional), creates hexahedral mesh, defaults to False + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg diagonal: Two ways of cutting hexadra, should be cut into 6 tetrahedra (``"default"``), or 5 tetrahedra thus less biased (``"crossed"``) @@ -1546,6 +1578,8 @@ def CubeMesh( :arg L: The extent in the x, y and z directions :kwarg hexahedral: (optional), creates hexahedral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -1602,6 +1636,8 @@ def UnitCubeMesh( :arg nz: The number of cells in the z direction :kwarg hexahedral: (optional), creates hexahedral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -1660,6 +1696,8 @@ def PeriodicBoxMesh( :arg Ly: The extent in the y direction :arg Lz: The extent in the z direction :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -1804,6 +1842,8 @@ def PeriodicUnitCubeMesh( :arg ny: The number of cells in the y direction :arg nz: The number of cells in the z direction :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -1858,6 +1898,8 @@ def IcosahedralSphereMesh( :kwarg degree: polynomial degree of coordinate space (defaults to 1: flat triangles) :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -1978,6 +2020,8 @@ def UnitIcosahedralSphereMesh( :kwarg degree: polynomial degree of coordinate space (defaults to 1: flat triangles) :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -2031,6 +2075,8 @@ def OctahedralSphereMesh( are just pushed out radially from the equivalent P1 mesh. (defaults to z0=0.8). :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -2182,6 +2228,8 @@ def UnitOctahedralSphereMesh( are just pushed out radially from the equivalent P1 mesh. (defaults to z0=0.8). :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -2360,6 +2408,8 @@ def CubedSphereMesh( :kwarg degree: polynomial degree of coordinate space (defaults to 1: bilinear quads) :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -2428,6 +2478,8 @@ def UnitCubedSphereMesh( :kwarg degree: polynomial degree of coordinate space (defaults to 1: bilinear quads) :kwarg reorder: (optional), should the mesh be reordered? + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -2472,6 +2524,8 @@ def TorusMesh( :arg r: The minor radius :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -2560,6 +2614,8 @@ def AnnulusMesh( :arg r: The inner radius :kwarg nr: (optional), number of cells in the radial direction :kwarg nt: (optional), number of cells in the circumferential direction (min 3) + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -2611,6 +2667,8 @@ def SolidTorusMesh( :kwarg nR: (optional), number of cells in the major direction (min 3, defaults to 8) :kwarg refinement_level: (optional), number of times the base disk mesh is refined (defaults to 0). :kwarg reorder: (optional), should the mesh be reordered + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg comm: Optional communicator to build the mesh on (defaults to COMM_WORLD). :kwarg name: Optional name of the mesh. @@ -2674,6 +2732,8 @@ def CylinderMesh( :kwarg longitudinal_direction: (option) direction for the longitudinal axis of the cylinder. :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. ``"left"`` is the default. Not valid for quad meshes. :kwarg comm: Optional communicator to build the mesh on (defaults to @@ -2840,6 +2900,8 @@ def PartiallyPeriodicRectangleMesh( :kwarg direction: The direction of the periodicity (default x). :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False :kwarg reorder: (optional), should the mesh be reordered + :kwarg distribution_parameters: options controlling mesh + distribution, see :func:`.Mesh` for details. :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. ``"left"`` is the default. Not valid for quad meshes. :kwarg comm: Optional communicator to build the mesh on (defaults to From a8c1c7a4e70de7eca39f0755dbbf1edb99daf2cd Mon Sep 17 00:00:00 2001 From: ksagiyam Date: Thu, 23 Feb 2023 00:43:25 +0000 Subject: [PATCH 8/8] utility_mesh: remove 'defaults to' --- firedrake/utility_meshes.py | 188 ++++++++++++++---------------------- 1 file changed, 75 insertions(+), 113 deletions(-) diff --git a/firedrake/utility_meshes.py b/firedrake/utility_meshes.py index d9feb3aa34..30a9685680 100644 --- a/firedrake/utility_meshes.py +++ b/firedrake/utility_meshes.py @@ -84,8 +84,7 @@ def IntervalMesh( be the left boundary point). :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -159,8 +158,7 @@ def UnitIntervalMesh( :arg ncells: The number of the cells over the interval. :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -200,8 +198,7 @@ def PeriodicIntervalMesh( :arg length: The length the interval. :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -289,8 +286,7 @@ def PeriodicUnitIntervalMesh( :arg ncells: The number of cells in the interval. :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -330,8 +326,7 @@ def OneElementThickMesh( :arg Ly: The width of the domain in the y-direction. :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -503,8 +498,7 @@ def UnitTriangleMesh( ): """Generate a mesh of the reference triangle - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -549,12 +543,11 @@ def RectangleMesh( :arg ny: The number of cells in the y direction :arg Lx: The extent in the x direction :arg Ly: The extent in the y direction - :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg quadrilateral: (optional), creates quadrilateral mesh. :kwarg reorder: (optional), should the mesh be reordered :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg diagonal: For triangular meshes, should the diagonal got from bottom left to top right (``"right"``), or top left to bottom right (``"left"``), or put in both diagonals (``"crossed"``). @@ -610,12 +603,11 @@ def TensorRectangleMesh( :arg xcoords: mesh points for the x direction :arg ycoords: mesh points for the y direction - :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg quadrilateral: (optional), creates quadrilateral mesh. :kwarg reorder: (optional), should the mesh be reordered :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg diagonal: For triangular meshes, should the diagonal got from bottom left to top right (``"right"``), or top left to bottom right (``"left"``), or put in both diagonals (``"crossed"``). @@ -737,12 +729,11 @@ def SquareMesh( :arg nx: The number of cells in the x direction :arg ny: The number of cells in the y direction :arg L: The extent in the x and y directions - :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg quadrilateral: (optional), creates quadrilateral mesh. :kwarg reorder: (optional), should the mesh be reordered :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -791,12 +782,11 @@ def UnitSquareMesh( :arg nx: The number of cells in the x direction :arg ny: The number of cells in the y direction - :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg quadrilateral: (optional), creates quadrilateral mesh. :kwarg reorder: (optional), should the mesh be reordered :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -851,14 +841,13 @@ def PeriodicRectangleMesh( :arg Ly: The extent in the y direction :arg direction: The direction of the periodicity, one of ``"both"``, ``"x"`` or ``"y"``. - :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg quadrilateral: (optional), creates quadrilateral mesh. :kwarg reorder: (optional), should the mesh be reordered :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. ``"left"`` is the default. + :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. Not valid for quad meshes. Only used for direction ``"x"`` or direction ``"y"``. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1016,14 +1005,13 @@ def PeriodicSquareMesh( :arg L: The extent in the x and y directions :arg direction: The direction of the periodicity, one of ``"both"``, ``"x"`` or ``"y"``. - :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg quadrilateral: (optional), creates quadrilateral mesh. :kwarg reorder: (optional), should the mesh be reordered :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. ``"left"`` is the default. + :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. Not valid for quad meshes. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1079,14 +1067,13 @@ def PeriodicUnitSquareMesh( :arg ny: The number of cells in the y direction :arg direction: The direction of the periodicity, one of ``"both"``, ``"x"`` or ``"y"``. - :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg quadrilateral: (optional), creates quadrilateral mesh. :kwarg reorder: (optional), should the mesh be reordered :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. ``"left"`` is the default. + :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. Not valid for quad meshes. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1136,14 +1123,12 @@ def CircleManifoldMesh( :arg ncells: number of cells the circle should be divided into (min 3) - :kwarg radius: (optional) radius of the circle to approximate - (defaults to 1). - :kwarg degree: polynomial degree of coordinate space (defaults - to 1: cells are straight line segments) + :kwarg radius: (optional) radius of the circle to approximate. + :kwarg degree: polynomial degree of coordinate space (e.g., + cells are straight line segments if degree=1). :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1218,8 +1203,7 @@ def UnitDiskMesh( :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1299,8 +1283,7 @@ def UnitBallMesh( :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional MPI communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional MPI communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1380,8 +1363,7 @@ def UnitTetrahedronMesh( ): """Generate a mesh of the reference tetrahedron. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1431,15 +1413,14 @@ def BoxMesh( :arg Lx: The extent in the x direction :arg Ly: The extent in the y direction :arg Lz: The extent in the z direction - :kwarg hexahedral: (optional), creates hexahedral mesh, defaults to False + :kwarg hexahedral: (optional), creates hexahedral mesh. :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. :kwarg diagonal: Two ways of cutting hexadra, should be cut into 6 tetrahedra (``"default"``), or 5 tetrahedra thus less biased (``"crossed"``) :kwarg reorder: (optional), should the mesh be reordered? - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. The boundary surfaces are numbered as follows: @@ -1576,12 +1557,11 @@ def CubeMesh( :arg ny: The number of cells in the y direction :arg nz: The number of cells in the z direction :arg L: The extent in the x, y and z directions - :kwarg hexahedral: (optional), creates hexahedral mesh, defaults to False + :kwarg hexahedral: (optional), creates hexahedral mesh. :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1634,12 +1614,11 @@ def UnitCubeMesh( :arg nx: The number of cells in the x direction :arg ny: The number of cells in the y direction :arg nz: The number of cells in the z direction - :kwarg hexahedral: (optional), creates hexahedral mesh, defaults to False + :kwarg hexahedral: (optional), creates hexahedral mesh. :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1698,8 +1677,7 @@ def PeriodicBoxMesh( :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1844,8 +1822,7 @@ def PeriodicUnitCubeMesh( :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -1895,13 +1872,12 @@ def IcosahedralSphereMesh( :kwarg refinement_level: optional number of refinements (0 is an icosahedron). - :kwarg degree: polynomial degree of coordinate space (defaults - to 1: flat triangles) + :kwarg degree: polynomial degree of coordinate space (e.g., + flat triangles if degree=1). :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -2017,13 +1993,12 @@ def UnitIcosahedralSphereMesh( :kwarg refinement_level: optional number of refinements (0 is an icosahedron). - :kwarg degree: polynomial degree of coordinate space (defaults - to 1: flat triangles) + :kwarg degree: polynomial degree of coordinate space (e.g., + flat triangles if degree=1). :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -2067,18 +2042,16 @@ def OctahedralSphereMesh( :arg radius: The radius of the sphere to approximate. :kwarg refinement_level: optional number of refinements (0 is an octahedron). - :kwarg degree: polynomial degree of coordinate space (defaults - to 1: flat triangles) - :kwarg hemisphere: One of "both" (default), "north", or "south" + :kwarg degree: polynomial degree of coordinate space (e.g., + flat triangles if degree=1). + :kwarg hemisphere: One of "both", "north", or "south" :kwarg z0: for abs(z/R)>z0, blend from a mesh where the higher-order non-vertex nodes are on lines of latitude to a mesh where these nodes - are just pushed out radially from the equivalent P1 mesh. (defaults to - z0=0.8). + are just pushed out radially from the equivalent P1 mesh. :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -2220,18 +2193,16 @@ def UnitOctahedralSphereMesh( :kwarg refinement_level: optional number of refinements (0 is an octahedron). - :kwarg degree: polynomial degree of coordinate space (defaults - to 1: flat triangles) - :kwarg hemisphere: One of "both" (default), "north", or "south" + :kwarg degree: polynomial degree of coordinate space (e.g., + flat triangles if degree=1). + :kwarg hemisphere: One of "both", "north", or "south" :kwarg z0: for abs(z)>z0, blend from a mesh where the higher-order non-vertex nodes are on lines of latitude to a mesh where these nodes - are just pushed out radially from the equivalent P1 mesh. (defaults to - z0=0.8). + are just pushed out radially from the equivalent P1 mesh. :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -2405,13 +2376,12 @@ def CubedSphereMesh( :arg radius: The radius of the sphere to approximate. :kwarg refinement_level: optional number of refinements (0 is a cube). - :kwarg degree: polynomial degree of coordinate space (defaults - to 1: bilinear quads) + :kwarg degree: polynomial degree of coordinate space (e.g., + bilinear quads if degree=1). :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -2475,13 +2445,12 @@ def UnitCubedSphereMesh( """Generate a cubed approximation to the unit sphere. :kwarg refinement_level: optional number of refinements (0 is a cube). - :kwarg degree: polynomial degree of coordinate space (defaults - to 1: bilinear quads) + :kwarg degree: polynomial degree of coordinate space (e.g., + bilinear quads if degree=1). :kwarg reorder: (optional), should the mesh be reordered? :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -2522,12 +2491,11 @@ def TorusMesh( :arg nr: The number of cells in the minor direction (min 3) :arg R: The major radius :arg r: The minor radius - :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg quadrilateral: (optional), creates quadrilateral mesh. :kwarg reorder: (optional), should the mesh be reordered :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -2616,8 +2584,7 @@ def AnnulusMesh( :kwarg nt: (optional), number of cells in the circumferential direction (min 3) :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if ``None``, the name is automatically @@ -2664,13 +2631,12 @@ def SolidTorusMesh( :arg R: The major radius :arg r: The minor radius - :kwarg nR: (optional), number of cells in the major direction (min 3, defaults to 8) - :kwarg refinement_level: (optional), number of times the base disk mesh is refined (defaults to 0). + :kwarg nR: (optional), number of cells in the major direction (min 3) + :kwarg refinement_level: (optional), number of times the base disk mesh is refined. :kwarg reorder: (optional), should the mesh be reordered :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if ``None``, the name is automatically @@ -2725,19 +2691,16 @@ def CylinderMesh( :arg nr: number of cells the cylinder circumference should be divided into (min 3) :arg nl: number of cells along the longitudinal axis of the cylinder - :kwarg radius: (optional) radius of the cylinder to approximate - (default 1). - :kwarg depth: (optional) depth of the cylinder to approximate - (default 1). + :kwarg radius: (optional) radius of the cylinder to approximate. + :kwarg depth: (optional) depth of the cylinder to approximate. :kwarg longitudinal_direction: (option) direction for the longitudinal axis of the cylinder. - :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg quadrilateral: (optional), creates quadrilateral mesh. :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. ``"left"`` is the default. + :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. Not valid for quad meshes. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically @@ -2897,15 +2860,14 @@ def PartiallyPeriodicRectangleMesh( :arg ny: The number of cells in the y direction :arg Lx: The extent in the x direction :arg Ly: The extent in the y direction - :kwarg direction: The direction of the periodicity (default x). - :kwarg quadrilateral: (optional), creates quadrilateral mesh, defaults to False + :kwarg direction: The direction of the periodicity. + :kwarg quadrilateral: (optional), creates quadrilateral mesh. :kwarg reorder: (optional), should the mesh be reordered :kwarg distribution_parameters: options controlling mesh distribution, see :func:`.Mesh` for details. - :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. ``"left"`` is the default. + :kwarg diagonal: (optional), one of ``"crossed"``, ``"left"``, ``"right"``. Not valid for quad meshes. - :kwarg comm: Optional communicator to build the mesh on (defaults to - COMM_WORLD). + :kwarg comm: Optional communicator to build the mesh on. :kwarg name: Optional name of the mesh. :kwarg distribution_name: the name of parallel distribution used when checkpointing; if `None`, the name is automatically