diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fd012859..9b5af8dbb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,20 +8,18 @@ on: - cron: '17 3 * * 0' jobs: - flake8: - name: Flake8 + ruff: + name: Ruff runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 with: - # matches compat target in setup.py - python-version: '3.8' + submodules: true + - uses: actions/setup-python@v5 - name: "Main Script" run: | - curl -L -O https://gitlab.tiker.net/inducer/ci-support/raw/main/prepare-and-run-flake8.sh - . ./prepare-and-run-flake8.sh "$(basename $GITHUB_REPOSITORY)" test examples + pip install ruff + ruff check pylint: name: Pylint diff --git a/.gitignore b/.gitignore index 43bf8a19d..d3f9c6568 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,8 @@ a.out *.h5 *.xmf *.hdf +*.pdf +*.stl .cache .pytest_cache diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 618f9157f..29526d15e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -98,12 +98,12 @@ Documentation: tags: - python3 -Flake8: - script: - - curl -L -O https://gitlab.tiker.net/inducer/ci-support/raw/main/prepare-and-run-flake8.sh - - . ./prepare-and-run-flake8.sh "$CI_PROJECT_NAME" test examples +Ruff: + script: | + pipx install ruff + ruff check tags: - - python3 + - docker-runner except: - tags diff --git a/MANIFEST.in b/MANIFEST.in index 02f4d39c0..a5f1bc235 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,20 +1,17 @@ include doc/*.rst +include doc/*.sh include doc/Makefile -include doc/*.py -include doc/conf.py -include doc/images/*.tex -include doc/images/*.png -include doc/images/Makefile - -include examples/*.py include test/*.step -include test/blob2d*.msh +include test/*.sh include test/annulus.msh -include test/hybrid-cube.msh +include test/blob2d*.msh include test/cubed-cube.msh -include test/*.sh +include test/gh-394.msh +include test/hybrid-cube.msh include test/ref-*.pvtu -include README.rst -include LICENSE +prune .ci +prune .github +exclude .gitignore +exclude .gitlab-ci.yml diff --git a/doc/conf.py b/doc/conf.py index 1f3db8759..8750b71b9 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,3 +1,4 @@ +from importlib import metadata from urllib.request import urlopen @@ -13,15 +14,9 @@ tikz_tikzlibraries = "decorations.markings" -copyright = "2014-21, Meshmode contributors" - -ver_dic = {} -with open("../meshmode/version.py") as _inf: - exec(compile(_inf.read(), "../meshmode/version.py", "exec"), ver_dic) - -version = ".".join(str(x) for x in ver_dic["VERSION"]) -# The full version, including alpha/beta/rc tags. -release = ver_dic["VERSION_TEXT"] +copyright = "2014-2024, Meshmode contributors" +release = metadata.version("meshmode") +version = ".".join(release.split(".")[:2]) intersphinx_mapping = { "arraycontext": ("https://documen.tician.de/arraycontext", None), diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index 169d7e70d..000000000 --- a/examples/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.pdf -*.stl diff --git a/examples/from_firedrake.py b/examples/from_firedrake.py index 55419b48d..e6e39ea10 100644 --- a/examples/from_firedrake.py +++ b/examples/from_firedrake.py @@ -39,7 +39,12 @@ def main(visualize=True): return 0 from firedrake import ( - Function, FunctionSpace, SpatialCoordinate, UnitSquareMesh, cos) + Function, + FunctionSpace, + SpatialCoordinate, + UnitSquareMesh, + cos, + ) from meshmode.interop.firedrake import build_connection_from_firedrake diff --git a/examples/multiple-meshes.py b/examples/multiple-meshes.py index aea174aa2..1b977d29f 100644 --- a/examples/multiple-meshes.py +++ b/examples/multiple-meshes.py @@ -1,13 +1,13 @@ import sys -import numpy as np # noqa +import numpy as np order = 4 def main(): - from meshmode.mesh.generation import make_curve_mesh, starfish # noqa + from meshmode.mesh.generation import make_curve_mesh, starfish mesh1 = make_curve_mesh(starfish, np.linspace(0, 1, 20), 4) from meshmode.mesh.processing import affine_map, merge_disjoint_meshes diff --git a/examples/plot-connectivity.py b/examples/plot-connectivity.py index c4a4fc31d..ce27d5db4 100644 --- a/examples/plot-connectivity.py +++ b/examples/plot-connectivity.py @@ -14,7 +14,10 @@ def main(): actx = PyOpenCLArrayContext(queue) from meshmode.mesh.generation import ( # noqa: F401 - generate_icosahedron, generate_sphere, generate_torus) + generate_icosahedron, + generate_sphere, + generate_torus, + ) #mesh = generate_sphere(1, order=order) mesh = generate_icosahedron(1, order=order) @@ -22,7 +25,8 @@ def main(): from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( - PolynomialWarpAndBlend3DRestrictingGroupFactory) + PolynomialWarpAndBlend3DRestrictingGroupFactory, + ) discr = Discretization( actx, mesh, PolynomialWarpAndBlend3DRestrictingGroupFactory(order)) diff --git a/examples/simple-dg.py b/examples/simple-dg.py index a0eda7a4b..138b7d65d 100644 --- a/examples/simple-dg.py +++ b/examples/simple-dg.py @@ -29,8 +29,11 @@ import pyopencl as cl import pyopencl.array as cla # noqa from arraycontext import ( - ArrayContainer, dataclass_array_container, map_array_container, - with_container_arithmetic) + ArrayContainer, + dataclass_array_container, + map_array_container, + with_container_arithmetic, +) from pytools import log_process, memoize_method from pytools.obj_array import flat_obj_array, make_obj_array @@ -71,7 +74,8 @@ def __init__(self, actx, mesh, order): from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( - PolynomialWarpAndBlend2DRestrictingGroupFactory) + PolynomialWarpAndBlend2DRestrictingGroupFactory, + ) self.group_factory = PolynomialWarpAndBlend2DRestrictingGroupFactory( order=order) self.volume_discr = Discretization(actx, mesh, self.group_factory) @@ -100,7 +104,9 @@ def boundary_connection(self, boundary_tag): @memoize_method def interior_faces_connection(self): from meshmode.discretization.connection import ( - FACE_RESTR_INTERIOR, make_face_restriction) + FACE_RESTR_INTERIOR, + make_face_restriction, + ) return make_face_restriction( self.volume_discr._setup_actx, self.volume_discr, @@ -118,7 +124,9 @@ def opposite_face_connection(self): @memoize_method def all_faces_connection(self): from meshmode.discretization.connection import ( - FACE_RESTR_ALL, make_face_restriction) + FACE_RESTR_ALL, + make_face_restriction, + ) return make_face_restriction( self.volume_discr._setup_actx, self.volume_discr, @@ -128,8 +136,7 @@ def all_faces_connection(self): @memoize_method def get_to_all_face_embedding(self, where): - from meshmode.discretization.connection import ( - make_face_to_all_faces_embedding) + from meshmode.discretization.connection import make_face_to_all_faces_embedding faces_conn = self.get_connection("vol", where) return make_face_to_all_faces_embedding( @@ -395,7 +402,7 @@ def wave_operator(actx, discr, c, q): u=c*discr.div(q.v), v=c*discr.grad(q.u) ) - - # noqa: W504 + - discr.inverse_mass( discr.face_mass( wave_flux(actx, discr, c=c, diff --git a/examples/to_firedrake.py b/examples/to_firedrake.py index d8ca8dc3a..cb15bccbf 100644 --- a/examples/to_firedrake.py +++ b/examples/to_firedrake.py @@ -65,7 +65,8 @@ def main(): from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( - InterpolatoryQuadratureSimplexGroupFactory) + InterpolatoryQuadratureSimplexGroupFactory, + ) group_factory = InterpolatoryQuadratureSimplexGroupFactory(order=order) discr = Discretization(actx, mesh, group_factory) @@ -92,8 +93,18 @@ def main(): # set up dirichlet laplace problem in fd and solve from firedrake import ( - Constant, DirichletBC, Function, FunctionSpace, TestFunction, TrialFunction, - dx, grad, inner, project, solve) + Constant, + DirichletBC, + Function, + FunctionSpace, + TestFunction, + TrialFunction, + dx, + grad, + inner, + project, + solve, + ) # because it's easier to write down the variational problem, # we're going to project from our "DG" space diff --git a/meshmode/array_context.py b/meshmode/array_context.py index 731fd0609..fbd8e25da 100644 --- a/meshmode/array_context.py +++ b/meshmode/array_context.py @@ -25,15 +25,17 @@ THE SOFTWARE. """ -import sys from warnings import warn from arraycontext import ( PyOpenCLArrayContext as PyOpenCLArrayContextBase, - PytatoPyOpenCLArrayContext as PytatoPyOpenCLArrayContextBase) + PytatoPyOpenCLArrayContext as PytatoPyOpenCLArrayContextBase, +) from arraycontext.pytest import ( _PytestPyOpenCLArrayContextFactoryWithClass, - _PytestPytatoPyOpenCLArrayContextFactory, register_pytest_array_context_factory) + _PytestPytatoPyOpenCLArrayContextFactory, + register_pytest_array_context_factory, +) def thaw(actx, ary): @@ -157,7 +159,9 @@ def _transform_loopy_inner(t_unit): # {{{ element/dof iname tag from meshmode.transform_metadata import ( - ConcurrentDOFInameTag, ConcurrentElementInameTag) + ConcurrentDOFInameTag, + ConcurrentElementInameTag, + ) el_inames = [iname.name for iname in default_ep.inames.values() if ConcurrentElementInameTag() in iname.tags] @@ -321,27 +325,19 @@ def actx_class(self): ) -if sys.version_info >= (3, 7): - def __getattr__(name): - if name not in _actx_names: - raise AttributeError(name) +def __getattr__(name): + if name not in _actx_names: + raise AttributeError(name) - import arraycontext - result = getattr(arraycontext, name) + import arraycontext + result = getattr(arraycontext, name) - warn(f"meshmode.array_context.{name} is deprecated. " - f"Use arraycontext.{name} instead. " - f"meshmode.array_context.{name} will continue to work until 2022.", - DeprecationWarning, stacklevel=2) + warn(f"meshmode.array_context.{name} is deprecated. " + f"Use arraycontext.{name} instead. " + f"meshmode.array_context.{name} will continue to work until 2022.", + DeprecationWarning, stacklevel=2) - return result -else: - def _import_names(): - import arraycontext - for name in _actx_names: - globals()[name] = getattr(arraycontext, name) - - _import_names() + return result # }}} diff --git a/meshmode/discretization/__init__.py b/meshmode/discretization/__init__.py index ba8df8dd5..db1b8f474 100644 --- a/meshmode/discretization/__init__.py +++ b/meshmode/discretization/__init__.py @@ -38,8 +38,12 @@ from meshmode.dof_array import DOFArray as _DOFArray from meshmode.mesh import Mesh as _Mesh, MeshElementGroup as _MeshElementGroup from meshmode.transform_metadata import ( - ConcurrentDOFInameTag, ConcurrentElementInameTag, DiscretizationDOFAxisTag, - DiscretizationElementAxisTag, FirstAxisIsElementsTag) + ConcurrentDOFInameTag, + ConcurrentElementInameTag, + DiscretizationDOFAxisTag, + DiscretizationElementAxisTag, + FirstAxisIsElementsTag, +) __doc__ = """ diff --git a/meshmode/discretization/connection/__init__.py b/meshmode/discretization/connection/__init__.py index 00fa51eae..fe3ac1575 100644 --- a/meshmode/discretization/connection/__init__.py +++ b/meshmode/discretization/connection/__init__.py @@ -28,20 +28,33 @@ from arraycontext import ArrayContext from meshmode.discretization.connection.chained import ( - ChainedDiscretizationConnection, flatten_chained_connection) + ChainedDiscretizationConnection, + flatten_chained_connection, +) from meshmode.discretization.connection.direct import ( - DirectDiscretizationConnection, DiscretizationConnection, - DiscretizationConnectionElementGroup, IdentityDiscretizationConnection, - InterpolationBatch) + DirectDiscretizationConnection, + DiscretizationConnection, + DiscretizationConnectionElementGroup, + IdentityDiscretizationConnection, + InterpolationBatch, +) from meshmode.discretization.connection.face import ( - FACE_RESTR_ALL, FACE_RESTR_INTERIOR, make_face_restriction, - make_face_to_all_faces_embedding) + FACE_RESTR_ALL, + FACE_RESTR_INTERIOR, + make_face_restriction, + make_face_to_all_faces_embedding, +) from meshmode.discretization.connection.modal import ( - ModalToNodalDiscretizationConnection, NodalToModalDiscretizationConnection) + ModalToNodalDiscretizationConnection, + NodalToModalDiscretizationConnection, +) from meshmode.discretization.connection.opposite_face import ( - make_opposite_face_connection, make_partition_connection) + make_opposite_face_connection, + make_partition_connection, +) from meshmode.discretization.connection.projection import ( - L2ProjectionInverseDiscretizationConnection) + L2ProjectionInverseDiscretizationConnection, +) from meshmode.discretization.connection.refinement import make_refinement_connection from meshmode.discretization.connection.same_mesh import make_same_mesh_connection @@ -50,26 +63,25 @@ __all__ = [ - "DiscretizationConnection", - "IdentityDiscretizationConnection", - "DirectDiscretizationConnection", - "ChainedDiscretizationConnection", - "L2ProjectionInverseDiscretizationConnection", - "NodalToModalDiscretizationConnection", - "ModalToNodalDiscretizationConnection", - - "make_same_mesh_connection", - "FACE_RESTR_INTERIOR", "FACE_RESTR_ALL", - "make_face_restriction", - "make_face_to_all_faces_embedding", - "make_opposite_face_connection", - "make_partition_connection", - "make_refinement_connection", - "flatten_chained_connection", - - "InterpolationBatch", - "DiscretizationConnectionElementGroup", - ] + "FACE_RESTR_ALL", + "FACE_RESTR_INTERIOR", + "ChainedDiscretizationConnection", + "DirectDiscretizationConnection", + "DiscretizationConnection", + "DiscretizationConnectionElementGroup", + "IdentityDiscretizationConnection", + "InterpolationBatch", + "L2ProjectionInverseDiscretizationConnection", + "ModalToNodalDiscretizationConnection", + "NodalToModalDiscretizationConnection", + "flatten_chained_connection", + "make_face_restriction", + "make_face_to_all_faces_embedding", + "make_opposite_face_connection", + "make_partition_connection", + "make_refinement_connection", + "make_same_mesh_connection", +] __doc__ = """ Base classes diff --git a/meshmode/discretization/connection/chained.py b/meshmode/discretization/connection/chained.py index 79dea7cbd..51ef4f24c 100644 --- a/meshmode/discretization/connection/chained.py +++ b/meshmode/discretization/connection/chained.py @@ -196,8 +196,11 @@ def flatten_chained_connection(actx, connection): :class:`~meshmode.discretization.connection.DirectDiscretizationConnection`. """ from meshmode.discretization.connection import ( - DirectDiscretizationConnection, DiscretizationConnectionElementGroup, - IdentityDiscretizationConnection, make_same_mesh_connection) + DirectDiscretizationConnection, + DiscretizationConnectionElementGroup, + IdentityDiscretizationConnection, + make_same_mesh_connection, + ) if not hasattr(connection, "connections"): return connection @@ -283,7 +286,9 @@ def make_full_resample_matrix(actx, connection): `(connection.from_discr.ndofs, connection.to_discr.ndofs)`. """ from meshmode.discretization.connection.direct import ( - DirectDiscretizationConnection, make_direct_full_resample_matrix) + DirectDiscretizationConnection, + make_direct_full_resample_matrix, + ) if isinstance(connection, DirectDiscretizationConnection): return make_direct_full_resample_matrix(actx, connection) diff --git a/meshmode/discretization/connection/direct.py b/meshmode/discretization/connection/direct.py index d466c0d5b..06d00dd8a 100644 --- a/meshmode/discretization/connection/direct.py +++ b/meshmode/discretization/connection/direct.py @@ -28,16 +28,26 @@ import loopy as lp from arraycontext import ( - ArrayContext, ArrayOrContainerT, ArrayT, NotAnArrayContainerError, - deserialize_container, make_loopy_program, serialize_container, tag_axes) + ArrayContext, + ArrayOrContainerT, + ArrayT, + NotAnArrayContainerError, + deserialize_container, + make_loopy_program, + serialize_container, + tag_axes, +) from arraycontext.metadata import NameHint from pytools import keyed_memoize_method, memoize_in, memoize_method from meshmode.discretization import Discretization, ElementGroupBase from meshmode.dof_array import DOFArray from meshmode.transform_metadata import ( - ConcurrentDOFInameTag, ConcurrentElementInameTag, DiscretizationDOFAxisTag, - DiscretizationElementAxisTag) + ConcurrentDOFInameTag, + ConcurrentElementInameTag, + DiscretizationDOFAxisTag, + DiscretizationElementAxisTag, +) def _reshape_and_preserve_tags( @@ -515,7 +525,7 @@ def _per_target_group_pick_info( if (from_el_indices[to_el_ind] != -1).any(): from warnings import warn warn("per-batch target elements not disjoint during " - "attempted merge") + "attempted merge", stacklevel=3) return None from_el_indices[to_el_ind] = \ @@ -917,7 +927,7 @@ def knl(): from_group_sizes = [ grp.nelements*grp.nunit_dofs for grp in conn.from_discr.groups] - from_group_starts = np.cumsum([0] + from_group_sizes) + from_group_starts = np.cumsum([0, *from_group_sizes]) tgt_node_nr_base = 0 mats = [] diff --git a/meshmode/discretization/connection/face.py b/meshmode/discretization/connection/face.py index 875c3d8da..3b7705de4 100644 --- a/meshmode/discretization/connection/face.py +++ b/meshmode/discretization/connection/face.py @@ -67,8 +67,10 @@ class _ConnectionBatchData: def _build_boundary_connection(actx, vol_discr, bdry_discr, connection_data, per_face_groups): from meshmode.discretization.connection.direct import ( - DirectDiscretizationConnection, DiscretizationConnectionElementGroup, - InterpolationBatch) + DirectDiscretizationConnection, + DiscretizationConnectionElementGroup, + InterpolationBatch, + ) ibdry_grp = 0 batches = [] @@ -321,11 +323,11 @@ def make_face_restriction(actx, discr, group_factory, boundary_tag, # Find vertex_indices glob_face_vertices = mgrp.vertex_indices[ batch_boundary_el_numbers_in_grp][:, face.volume_vertex_indices] - vertex_indices[new_el_numbers] = ( # pylint: disable=possibly-used-before-assignment # noqa: E501 + vertex_indices[new_el_numbers] = ( # pylint: disable=possibly-used-before-assignment vol_to_bdry_vertices[glob_face_vertices]) # Find nodes - nodes[:, new_el_numbers, :] = np.einsum( # pylint: disable=possibly-used-before-assignment # noqa: E501 + nodes[:, new_el_numbers, :] = np.einsum( # pylint: disable=possibly-used-before-assignment "ij,dej->dei", resampling_mat, mgrp.nodes[:, batch_boundary_el_numbers_in_grp, :]) @@ -408,8 +410,10 @@ def make_face_to_all_faces_embedding(actx, faces_connection, all_faces_discr, "same number of groups") from meshmode.discretization.connection import ( - DirectDiscretizationConnection, DiscretizationConnectionElementGroup, - InterpolationBatch) + DirectDiscretizationConnection, + DiscretizationConnectionElementGroup, + InterpolationBatch, + ) i_faces_grp = 0 diff --git a/meshmode/discretization/connection/modal.py b/meshmode/discretization/connection/modal.py index 3897f8834..3b4f80e3b 100644 --- a/meshmode/discretization/connection/modal.py +++ b/meshmode/discretization/connection/modal.py @@ -28,14 +28,17 @@ import modepy as mp from arraycontext import ( - NotAnArrayContainerError, deserialize_container, serialize_container, tag_axes) + NotAnArrayContainerError, + deserialize_container, + serialize_container, + tag_axes, +) from pytools import keyed_memoize_in from meshmode.discretization import InterpolatoryElementGroupBase from meshmode.discretization.connection.direct import DiscretizationConnection from meshmode.discretization.poly_element import QuadratureSimplexElementGroup -from meshmode.transform_metadata import ( - DiscretizationDOFAxisTag, FirstAxisIsElementsTag) +from meshmode.transform_metadata import DiscretizationDOFAxisTag, FirstAxisIsElementsTag class NodalToModalDiscretizationConnection(DiscretizationConnection): diff --git a/meshmode/discretization/connection/opposite_face.py b/meshmode/discretization/connection/opposite_face.py index 5d248a705..048397a60 100644 --- a/meshmode/discretization/connection/opposite_face.py +++ b/meshmode/discretization/connection/opposite_face.py @@ -198,10 +198,12 @@ def get_map_jacobian(unit_nodes): # {{{ test map applier and jacobian if 0: + rng = np.random.default_rng(seed=None) + u = src_unit_nodes f = apply_map(u) for h in [1e-1, 1e-2]: - du = h*np.random.randn(*u.shape) + du = h*rng.normal(size=u.shape) f_2 = apply_map(u+du) @@ -511,7 +513,9 @@ def make_opposite_face_connection(actx, volume_to_bdry_conn): groups[i_tgt_grp].extend(batches) from meshmode.discretization.connection import ( - DirectDiscretizationConnection, DiscretizationConnectionElementGroup) + DirectDiscretizationConnection, + DiscretizationConnectionElementGroup, + ) return DirectDiscretizationConnection( from_discr=bdry_discr, to_discr=bdry_discr, @@ -546,7 +550,9 @@ def make_partition_connection(actx, *, local_bdry_conn, """ from meshmode.discretization.connection import ( - DirectDiscretizationConnection, DiscretizationConnectionElementGroup) + DirectDiscretizationConnection, + DiscretizationConnectionElementGroup, + ) from meshmode.mesh.processing import find_group_indices local_vol_mesh = local_bdry_conn.from_discr.mesh diff --git a/meshmode/discretization/connection/projection.py b/meshmode/discretization/connection/projection.py index 5c13d8daf..efa143acc 100644 --- a/meshmode/discretization/connection/projection.py +++ b/meshmode/discretization/connection/projection.py @@ -24,14 +24,18 @@ import loopy as lp from arraycontext import ( - NotAnArrayContainerError, deserialize_container, make_loopy_program, - serialize_container) + NotAnArrayContainerError, + deserialize_container, + make_loopy_program, + serialize_container, +) from pytools import keyed_memoize_in, keyed_memoize_method, memoize_in -from meshmode.discretization.connection.chained import ( - ChainedDiscretizationConnection) +from meshmode.discretization.connection.chained import ChainedDiscretizationConnection from meshmode.discretization.connection.direct import ( - DirectDiscretizationConnection, DiscretizationConnection) + DirectDiscretizationConnection, + DiscretizationConnection, +) from meshmode.transform_metadata import FirstAxisIsElementsTag @@ -185,7 +189,9 @@ def kproj(): name="conn_projection_knl" ) from meshmode.transform_metadata import ( - ConcurrentDOFInameTag, ConcurrentElementInameTag) + ConcurrentDOFInameTag, + ConcurrentElementInameTag, + ) return lp.tag_inames(t_unit, { "iel_init": ConcurrentElementInameTag(), "idof_init": ConcurrentDOFInameTag(), diff --git a/meshmode/discretization/connection/refinement.py b/meshmode/discretization/connection/refinement.py index f6252e323..f3cf63ce3 100644 --- a/meshmode/discretization/connection/refinement.py +++ b/meshmode/discretization/connection/refinement.py @@ -129,7 +129,9 @@ def make_refinement_connection(actx, refiner, coarse_discr, group_factory): for discretizing the fine mesh. """ from meshmode.discretization.connection import ( - DirectDiscretizationConnection, DiscretizationConnectionElementGroup) + DirectDiscretizationConnection, + DiscretizationConnectionElementGroup, + ) coarse_mesh = refiner.get_previous_mesh() fine_mesh = refiner.get_current_mesh() diff --git a/meshmode/discretization/connection/same_mesh.py b/meshmode/discretization/connection/same_mesh.py index 9cf2b24b8..2b88aa4e6 100644 --- a/meshmode/discretization/connection/same_mesh.py +++ b/meshmode/discretization/connection/same_mesh.py @@ -29,8 +29,11 @@ def make_same_mesh_connection(actx, to_discr, from_discr): from meshmode.discretization.connection.direct import ( - DirectDiscretizationConnection, DiscretizationConnectionElementGroup, - IdentityDiscretizationConnection, InterpolationBatch) + DirectDiscretizationConnection, + DiscretizationConnectionElementGroup, + IdentityDiscretizationConnection, + InterpolationBatch, + ) if from_discr.mesh is not to_discr.mesh: raise ValueError("from_discr and to_discr must be based on " diff --git a/meshmode/discretization/poly_element.py b/meshmode/discretization/poly_element.py index 7860de5a2..da6ec2b89 100644 --- a/meshmode/discretization/poly_element.py +++ b/meshmode/discretization/poly_element.py @@ -34,12 +34,18 @@ from pytools import memoize_method, memoize_on_first_arg from meshmode.discretization import ( - ElementGroupBase, ElementGroupFactory, InterpolatoryElementGroupBase, - ModalElementGroupBase, NodalElementGroupBase, NoninterpolatoryElementGroupError) + ElementGroupBase, + ElementGroupFactory, + InterpolatoryElementGroupBase, + ModalElementGroupBase, + NodalElementGroupBase, + NoninterpolatoryElementGroupError, +) from meshmode.mesh import ( MeshElementGroup as _MeshElementGroup, SimplexElementGroup as _MeshSimplexElementGroup, - TensorProductElementGroup as _MeshTensorProductElementGroup) + TensorProductElementGroup as _MeshTensorProductElementGroup, +) __doc__ = """ @@ -977,7 +983,8 @@ def default_simplex_group_factory(base_dim, order): elif base_dim == 3: return PolynomialWarpAndBlend3DRestrictingGroupFactory(order) else: - raise ValueError(f"no usable set of nodes found for {base_dim}D") + raise ValueError( + f"no usable set of nodes found for {base_dim}D") from None return PolynomialRecursiveNodesGroupFactory(order, family="lgl") diff --git a/meshmode/discretization/visualization.py b/meshmode/discretization/visualization.py index c446fceb6..4a8c8d15e 100644 --- a/meshmode/discretization/visualization.py +++ b/meshmode/discretization/visualization.py @@ -63,7 +63,10 @@ def separate_by_real_and_imag(names_and_fields, real_only): if isinstance(field, np.ndarray) and field.dtype.char == "O": assert len(field.shape) == 1 from pytools.obj_array import ( - obj_array_imag_copy, obj_array_real_copy, obj_array_vectorize) + obj_array_imag_copy, + obj_array_real_copy, + obj_array_vectorize, + ) if field[0].dtype.kind == "c": if real_only: @@ -430,7 +433,8 @@ def connectivity_for_element_group(self, grp): if isinstance(grp.mesh_el_group, SimplexElementGroup): from pyvisfile.vtk.vtk_ordering import ( vtk_lagrange_simplex_node_tuples, - vtk_lagrange_simplex_node_tuples_to_permutation) + vtk_lagrange_simplex_node_tuples_to_permutation, + ) node_tuples = vtk_lagrange_simplex_node_tuples( grp.dim, grp.order, vtk_version=vtk_version) @@ -443,7 +447,8 @@ def connectivity_for_element_group(self, grp): elif isinstance(grp.mesh_el_group, TensorProductElementGroup): from pyvisfile.vtk.vtk_ordering import ( vtk_lagrange_quad_node_tuples, - vtk_lagrange_quad_node_tuples_to_permutation) + vtk_lagrange_quad_node_tuples_to_permutation, + ) node_tuples = vtk_lagrange_quad_node_tuples( grp.dim, grp.order, vtk_version=vtk_version) @@ -583,7 +588,7 @@ def show_scalar_in_mayavi(self, field, **kwargs): nodes.append(0*nodes[0]) assert len(nodes) == 3 - args = tuple(nodes) + (field,) + args = (*nodes, field) # https://docs.enthought.com/mayavi/mayavi/auto/example_plotting_many_lines.html # noqa: E501 src = mlab.pipeline.scalar_scatter(*args) @@ -598,7 +603,7 @@ def show_scalar_in_mayavi(self, field, **kwargs): while len(nodes) < 3: nodes.append(0*nodes[0]) - args = tuple(nodes) + (vis_connectivity.reshape(-1, 3),) + args = (*nodes, vis_connectivity.reshape(-1, 3)) kwargs["scalars"] = field mlab.triangular_mesh(*args, **kwargs) @@ -737,14 +742,18 @@ def write_vtk_file(self, file_name, names_and_fields, - Added *par_manifest_filename* and *par_file_names*. - Added *use_high_order*. - """ # noqa: E501 + """ if use_high_order is None: use_high_order = False from pyvisfile.vtk import ( - VF_LIST_OF_COMPONENTS, AppendedDataXMLGenerator, DataArray, - ParallelXMLGenerator, UnstructuredGrid) + VF_LIST_OF_COMPONENTS, + AppendedDataXMLGenerator, + DataArray, + ParallelXMLGenerator, + UnstructuredGrid, + ) nodes = self._vis_nodes_numpy() @@ -1123,7 +1132,11 @@ def write_xdmf_file(self, file_name, names_and_fields, # Paraview. from pyvisfile.xdmf import ( - DataArray, GeometryType, Information, XdmfUnstructuredGrid) + DataArray, + GeometryType, + Information, + XdmfUnstructuredGrid, + ) if self.vis_discr.ambient_dim == 2: geometry_type = GeometryType.XY @@ -1202,6 +1215,7 @@ def write_xdmf_file(self, file_name, names_and_fields, def show_scalar_in_matplotlib_3d(self, field, **kwargs): import matplotlib.pyplot as plt + # This import also registers the 3D projection. import mpl_toolkits.mplot3d.art3d as art3d @@ -1294,10 +1308,12 @@ def make_visualizer(actx, discr, vis_order=None, else: if force_equidistant: from meshmode.discretization.poly_element import ( - InterpolatoryEquidistantGroupFactory as VisGroupFactory) + InterpolatoryEquidistantGroupFactory as VisGroupFactory, + ) else: from meshmode.discretization.poly_element import ( - InterpolatoryEdgeClusteredGroupFactory as VisGroupFactory) + InterpolatoryEdgeClusteredGroupFactory as VisGroupFactory, + ) vis_discr = discr.copy(actx=actx, group_factory=VisGroupFactory(vis_order)) @@ -1356,8 +1372,12 @@ def write_nodal_adjacency_vtk_file(file_name, mesh, compressor=None, overwrite=False): from pyvisfile.vtk import ( - VF_LIST_OF_COMPONENTS, VTK_LINE, AppendedDataXMLGenerator, DataArray, - UnstructuredGrid) + VF_LIST_OF_COMPONENTS, + VTK_LINE, + AppendedDataXMLGenerator, + DataArray, + UnstructuredGrid, + ) centroids = np.empty( (mesh.ambient_dim, mesh.nelements), diff --git a/meshmode/distributed.py b/meshmode/distributed.py index 18402bf49..df9e1de28 100644 --- a/meshmode/distributed.py +++ b/meshmode/distributed.py @@ -45,8 +45,7 @@ from meshmode.discretization import ElementGroupFactory from meshmode.discretization.connection import DirectDiscretizationConnection -from meshmode.mesh import ( - InteriorAdjacencyGroup, InterPartAdjacencyGroup, Mesh, PartID) +from meshmode.mesh import InteriorAdjacencyGroup, InterPartAdjacencyGroup, Mesh, PartID # This file needs to be importable without mpi4py. So don't be tempted to add diff --git a/meshmode/dof_array.py b/meshmode/dof_array.py index f72a4d045..fbd1f3e45 100644 --- a/meshmode/dof_array.py +++ b/meshmode/dof_array.py @@ -28,22 +28,30 @@ from contextlib import contextmanager from functools import partial, update_wrapper from numbers import Number -from typing import Any, Callable, Iterable, Optional, Tuple +from typing import Any, Callable, Iterable from warnings import warn import numpy as np import loopy as lp from arraycontext import ( - Array, ArrayContext, ArrayOrContainerT, NotAnArrayContainerError, - deserialize_container, make_loopy_program, mapped_over_array_containers, - multimapped_over_array_containers, rec_map_array_container, - rec_multimap_array_container, serialize_container, with_array_context, - with_container_arithmetic) + Array, + ArrayContext, + ArrayOrContainerT, + NotAnArrayContainerError, + deserialize_container, + make_loopy_program, + mapped_over_array_containers, + multimapped_over_array_containers, + rec_map_array_container, + rec_multimap_array_container, + serialize_container, + with_array_context, + with_container_arithmetic, +) from pytools import MovedFunctionDeprecationWrapper, memoize_in, single_valued -from meshmode.transform_metadata import ( - ConcurrentDOFInameTag, ConcurrentElementInameTag) +from meshmode.transform_metadata import ConcurrentDOFInameTag, ConcurrentElementInameTag __doc__ = """ @@ -130,7 +138,7 @@ class DOFArray: the array context given to :func:`array_context_for_pickling`. """ - def __init__(self, actx: Optional[ArrayContext], data: Tuple[Any]) -> None: + def __init__(self, actx: ArrayContext | None, data: tuple[Any, ...]) -> None: if __debug__: if not (actx is None or isinstance(actx, ArrayContext)): raise TypeError("actx must be of type ArrayContext") @@ -154,7 +162,7 @@ def entry_dtype(self) -> np.dtype: return single_valued(subary.dtype for subary in self._data) @classmethod - def from_list(cls, actx: Optional[ArrayContext], res_list) -> "DOFArray": + def from_list(cls, actx: ArrayContext | None, res_list) -> DOFArray: r"""Create a :class:`DOFArray` from a list of arrays (one per :class:`~meshmode.discretization.ElementGroupBase`). @@ -170,10 +178,10 @@ def from_list(cls, actx: Optional[ArrayContext], res_list) -> "DOFArray": return cls(actx, tuple(res_list)) def __str__(self) -> str: - return f"DOFArray({str(self._data)})" + return f"DOFArray({self._data})" def __repr__(self) -> str: - return f"DOFArray({repr(self._data)})" + return f"DOFArray({self._data!r})" # {{{ sequence protocol @@ -199,7 +207,7 @@ def _like_me(self, data: Iterable[Array]) -> DOFArray: return DOFArray(self.array_context, tuple(data)) @property - def shape(self) -> Tuple[int]: + def shape(self) -> tuple[int]: return (len(self),) @property @@ -255,15 +263,15 @@ def _ibop(self, f, arg): return self - def __iadd__(self, arg): return self._ibop(op.iadd, arg) # noqa: E704 - def __isub__(self, arg): return self._ibop(op.isub, arg) # noqa: E704 - def __imul__(self, arg): return self._ibop(op.imul, arg) # noqa: E704 - def __itruediv__(self, arg): return self._ibop(op.itruediv, arg) # noqa: E704 - def __imod__(self, arg): return self._ibop(op.imod, arg) # noqa: E704 + def __iadd__(self, arg): return self._ibop(op.iadd, arg) + def __isub__(self, arg): return self._ibop(op.isub, arg) + def __imul__(self, arg): return self._ibop(op.imul, arg) + def __itruediv__(self, arg): return self._ibop(op.itruediv, arg) + def __imod__(self, arg): return self._ibop(op.imod, arg) - def __iand__(self, arg): return self._ibop(op.iand, arg) # noqa: E704 - def __ixor__(self, arg): return self._ibop(op.ixor, arg) # noqa: E704 - def __ior__(self, arg): return self._ibop(op.ior, arg) # noqa: E704 + def __iand__(self, arg): return self._ibop(op.iand, arg) + def __ixor__(self, arg): return self._ibop(op.ixor, arg) + def __ior__(self, arg): return self._ibop(op.ior, arg) # }}} @@ -319,7 +327,8 @@ def __setstate__(self, state): # For backwards compatibility from warnings import warn warn("A DOFArray is being unpickled without (tag) metadata. " - "Program transformation may fail as a result.") + "Program transformation may fail as a result.", + stacklevel=2) data = state tags = [frozenset() for _ in range(len(data))] @@ -375,7 +384,7 @@ def _serialize_dof_container(ary: DOFArray): @deserialize_container.register(DOFArray) def _deserialize_dof_container( - template: Any, iterable: Iterable[Tuple[Any, Any]]): + template: Any, iterable: Iterable[tuple[Any, Any]]): if __debug__: def _raise_index_inconsistency(i, stream_i): raise ValueError( @@ -578,14 +587,14 @@ def _unflatten_group_sizes(discr, ndofs_per_element_per_group): in zip(discr.groups, ndofs_per_element_per_group)] group_sizes = [nel * ndof for nel, ndof in group_shapes] - group_starts = np.cumsum([0] + group_sizes) + group_starts = np.cumsum([0, *group_sizes]) return group_shapes, group_starts def unflatten( actx: ArrayContext, discr, ary: ArrayOrContainerT, - ndofs_per_element_per_group: Optional[Iterable[int]] = None, *, + ndofs_per_element_per_group: Iterable[int] | None = None, *, strict: bool = True, ) -> ArrayOrContainerT: r"""Convert all "flat" arrays returned by :func:`flatten` back to @@ -660,7 +669,7 @@ def _unflatten_like(_ary, _prototype): if isinstance(_prototype, DOFArray): group_shapes = [subary.shape for subary in _prototype] group_sizes = [subary.size for subary in _prototype] - group_starts = np.cumsum([0] + group_sizes) + group_starts = np.cumsum([0, *group_sizes]) return _unflatten_dof_array( actx, _ary, group_shapes, group_starts, @@ -672,9 +681,11 @@ def _unflatten_like(_ary, _prototype): serialize_container(_prototype)) except NotAnArrayContainerError: if strict: - raise ValueError("cannot unflatten array " - f"with prototype '{type(_prototype).__name__}'; " - "use 'strict=False' to leave the array unchanged") + raise ValueError( + "cannot unflatten array with prototype " + f"'{type(_prototype).__name__}': " + "use 'strict=False' to leave the array unchanged" + ) from None assert type(_ary) is type(_prototype) return _ary @@ -708,7 +719,7 @@ def _flatten_to_numpy(subary): def unflatten_from_numpy( actx: ArrayContext, discr, ary: ArrayOrContainerT, - ndofs_per_element_per_group: Optional[Iterable[int]] = None, *, + ndofs_per_element_per_group: Iterable[int] | None = None, *, strict: bool = True, ) -> ArrayOrContainerT: r"""Takes "flat" arrays returned by :func:`flatten_to_numpy` and @@ -800,7 +811,8 @@ def _rec(_ary): try: iterable = serialize_container(_ary) except NotAnArrayContainerError: - raise TypeError(f"unsupported array type: '{type(_ary).__name__}'") + raise TypeError( + f"unsupported array type: '{type(_ary).__name__}'") from None else: arys = [_rec(subary) for _, subary in iterable] return _reduce_norm(actx, arys, ord=ord) diff --git a/meshmode/interop/firedrake/__init__.py b/meshmode/interop/firedrake/__init__.py index eaf965814..464d9907f 100644 --- a/meshmode/interop/firedrake/__init__.py +++ b/meshmode/interop/firedrake/__init__.py @@ -22,13 +22,20 @@ from meshmode.interop.firedrake.connection import ( - FiredrakeConnection, build_connection_from_firedrake, - build_connection_to_firedrake) + FiredrakeConnection, + build_connection_from_firedrake, + build_connection_to_firedrake, +) from meshmode.interop.firedrake.mesh import ( - export_mesh_to_firedrake, import_firedrake_mesh) + export_mesh_to_firedrake, + import_firedrake_mesh, +) -__all__ = ["build_connection_from_firedrake", "build_connection_to_firedrake", - "FiredrakeConnection", "import_firedrake_mesh", - "export_mesh_to_firedrake", - ] +__all__ = [ + "FiredrakeConnection", + "build_connection_from_firedrake", + "build_connection_to_firedrake", + "export_mesh_to_firedrake", + "import_firedrake_mesh", +] diff --git a/meshmode/interop/firedrake/connection.py b/meshmode/interop/firedrake/connection.py index 98b7892f5..828434fc1 100644 --- a/meshmode/interop/firedrake/connection.py +++ b/meshmode/interop/firedrake/connection.py @@ -34,11 +34,17 @@ from meshmode.discretization import Discretization, InterpolatoryElementGroupBase from meshmode.discretization.poly_element import ( - ElementGroupFactory, default_simplex_group_factory) + ElementGroupFactory, + default_simplex_group_factory, +) from meshmode.interop.firedrake.mesh import ( - export_mesh_to_firedrake, import_firedrake_mesh) + export_mesh_to_firedrake, + import_firedrake_mesh, +) from meshmode.interop.firedrake.reference_cell import ( - get_affine_reference_simplex_mapping, get_finat_element_unit_nodes) + get_affine_reference_simplex_mapping, + get_finat_element_unit_nodes, +) from meshmode.mesh.processing import get_simplex_element_flip_matrix @@ -308,8 +314,8 @@ def _validate_function(self, function, function_name, raise ValueError(f"'{function_name}.dat.dtype' must be " f"{dtype}, not '{function.dat.data.dtype}'") if shape is not None and function.function_space().shape != shape: - raise ValueError("'{function_name}.function_space().shape' must be" - " {shape}, not '{function.function_space().shape}" + raise ValueError(f"'{function_name}.function_space().shape' must be" + f" {shape}, not '{function.function_space().shape}" "'") def _validate_field(self, field, field_name, shape=None, dtype=None): @@ -369,7 +375,7 @@ def check_dof_array(arr, arr_name): " for FiredrakeConnection.from_meshmode or " \ "FiredrakeConnection.from_firedrake to see how " \ "fields in a discretization are represented." - raise TypeError(prefix + "\n" + msg) + raise TypeError(f"{prefix}\n{msg}") from None else: raise TypeError("'field' must be of type DOFArray or a numpy object " "array of those, not '%s'." % type(field)) @@ -457,13 +463,13 @@ def reorder_and_resample(dof_array, fd_data): else: # firedrake drops extra dimensions if len(function_data.shape) != 1 + len(fspace_shape): - shape = (function_data.shape[0],) + fspace_shape + shape = (function_data.shape[0], *fspace_shape) function_data = function_data.reshape(shape) # otherwise, have to grab each dofarray and the corresponding # data from *function_data* for multi_index in np.ndindex(fspace_shape): dof_array = out[multi_index] - index = (np.s_[:],) + multi_index + index = (np.s_[:], *multi_index) fd_data = function_data[index] reorder_and_resample(dof_array, fd_data) @@ -537,7 +543,7 @@ def from_meshmode(self, mm_field, out=None): out_data = out.dat.data # Handle firedrake dropping dimensions if len(out.dat.data.shape) != 1 + len(fspace_shape): - shape = (out.dat.data.shape[0],) + fspace_shape + shape = (out.dat.data.shape[0], *fspace_shape) out_data = out_data.reshape(shape) def resample_and_reorder(fd_data, dof_array): @@ -560,7 +566,7 @@ def resample_and_reorder(fd_data, dof_array): # data from *function_data* for multi_index in np.ndindex(fspace_shape): # have to be careful to take view and not copy - index = (np.s_[:],) + multi_index + index = (np.s_[:], *multi_index) fd_data = out_data[index] dof_array = mm_field[multi_index] resample_and_reorder(fd_data, dof_array) diff --git a/meshmode/interop/firedrake/mesh.py b/meshmode/interop/firedrake/mesh.py index 736c30a48..e97f3a631 100644 --- a/meshmode/interop/firedrake/mesh.py +++ b/meshmode/interop/firedrake/mesh.py @@ -29,10 +29,19 @@ from pytools import ProcessLogger from meshmode.interop.firedrake.reference_cell import ( - get_affine_reference_simplex_mapping, get_finat_element_unit_nodes) + get_affine_reference_simplex_mapping, + get_finat_element_unit_nodes, +) from meshmode.mesh import ( - BTAG_ALL, BTAG_INDUCED_BOUNDARY, BoundaryAdjacencyGroup, InteriorAdjacencyGroup, - Mesh, NodalAdjacency, SimplexElementGroup, make_mesh) + BTAG_ALL, + BTAG_INDUCED_BOUNDARY, + BoundaryAdjacencyGroup, + InteriorAdjacencyGroup, + Mesh, + NodalAdjacency, + SimplexElementGroup, + make_mesh, +) __doc__ = """ @@ -398,7 +407,7 @@ def _get_firedrake_facial_adjacency_groups(fdrake_mesh_topology, # }}} - return [[interconnectivity_grp] + exterior_grps] + return [[interconnectivity_grp, *exterior_grps]] # }}} @@ -435,8 +444,7 @@ def _get_firedrake_orientations(fdrake_mesh, unflipped_group, vertices, if gdim == tdim: # If the co-dimension is 0, :mod:`meshmode` has a convenient # function to compute cell orientations - from meshmode.mesh.processing import ( - find_volume_mesh_element_group_orientation) + from meshmode.mesh.processing import find_volume_mesh_element_group_orientation orient = find_volume_mesh_element_group_orientation(vertices, unflipped_group) @@ -458,7 +466,8 @@ def _get_firedrake_orientations(fdrake_mesh, unflipped_group, vertices, if np.cross(normal, edge) < 0: orient[i] = -1.0 elif no_normals_warn: - warn("Assuming all elements are positively-oriented.") + warn("Assuming all elements are positively-oriented.", + stacklevel=2) elif tdim == 2 and gdim == 3: # In this case we have a 2-surface embedded in 3-space. @@ -638,7 +647,7 @@ def import_firedrake_mesh(fdrake_mesh, cells_to_use=None, nodes = np.real(coords.dat.data[cell_node_list]) # Add extra dim in 1D for shape (nelements, nunit_nodes, dim) if tdim == 1: - nodes = np.reshape(nodes, nodes.shape + (1,)) + nodes = np.reshape(nodes, (*nodes.shape, 1)) # Transpose nodes to have shape (dim, nelements, nunit_nodes) nodes = np.transpose(nodes, (2, 0, 1)) diff --git a/meshmode/interop/firedrake/reference_cell.py b/meshmode/interop/firedrake/reference_cell.py index b060434dc..aa25f1ce3 100644 --- a/meshmode/interop/firedrake/reference_cell.py +++ b/meshmode/interop/firedrake/reference_cell.py @@ -82,7 +82,7 @@ def get_affine_reference_simplex_mapping(ambient_dim, firedrake_to_meshmode=True # Compute matrix A and vector b so that A f_i + b -> t_i # for each "from" vertex f_i and corresponding "to" vertex t_i assert from_verts.shape == to_verts.shape - dim, nvects = from_verts.shape + _dim, nvects = from_verts.shape # If we only have one vertex, have A = I and b = to_vert - from_vert if nvects == 1: @@ -142,8 +142,8 @@ def get_finat_element_unit_nodes(finat_element): GaussLobattoLegendre, GaussLegendre) if not isinstance(finat_element, allowed_finat_elts): raise TypeError("'finat_element' is of unexpected type " - f"{type(finat_element)}. 'finat_element' must be of " - "one of the following types: {allowed_finat_elts}") + f"{type(finat_element).__name__}. 'finat_element' must be of " + f"one of the following types: {allowed_finat_elts}") if not isinstance(finat_element.cell, Simplex): raise TypeError("Reference element of the finat element MUST be a" " simplex, i.e. 'finat_element's *cell* attribute must" diff --git a/meshmode/interop/nodal_dg.py b/meshmode/interop/nodal_dg.py index 5afc62706..95fa79e5a 100644 --- a/meshmode/interop/nodal_dg.py +++ b/meshmode/interop/nodal_dg.py @@ -83,8 +83,8 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.octave.exit() - REF_AXES = ["r", "s", "t"] - AXES = ["x", "y", "z"] + REF_AXES = ("r", "s", "t") + AXES = ("x", "y", "z") def set_mesh(self, mesh: meshmode.mesh.Mesh, order): """Set the mesh information in the nodal DG Octave instance to @@ -132,7 +132,7 @@ def get_discr(self, actx) -> meshmode.discretization.Discretization: f"Nodes{dim}D(N)", nout=dim, verbose=False) equilat_to_unit_func_name = ( - "".join(self.AXES[:dim] + ["to"] + self.REF_AXES[:dim])) + "".join(self.AXES[:dim] + ("to",) + self.REF_AXES[:dim])) unit_nodes_arrays = self.octave.feval( equilat_to_unit_func_name, *unit_nodes_arrays, @@ -158,7 +158,8 @@ def get_discr(self, actx) -> meshmode.discretization.Discretization: from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( - PolynomialGivenNodesGroupFactory) + PolynomialGivenNodesGroupFactory, + ) return Discretization(actx, mesh, PolynomialGivenNodesGroupFactory(order, unit_nodes)) diff --git a/meshmode/mesh/__init__.py b/meshmode/mesh/__init__.py index 3c2d16df7..7218d943e 100644 --- a/meshmode/mesh/__init__.py +++ b/meshmode/mesh/__init__.py @@ -23,8 +23,17 @@ from abc import ABC, abstractmethod from dataclasses import InitVar, dataclass, field, replace from typing import ( - Any, ClassVar, Hashable, Iterable, Literal, Optional, Sequence, Tuple, Type, - Union) + Any, + ClassVar, + Hashable, + Iterable, + Literal, + Optional, + Sequence, + Tuple, + Type, + Union, +) from warnings import warn import numpy as np @@ -775,8 +784,10 @@ def check_mesh_consistency( some fashion. """ from meshmode import ( - InconsistentAdjacencyError, InconsistentArrayDTypeError, - InconsistentMeshError) + InconsistentAdjacencyError, + InconsistentArrayDTypeError, + InconsistentMeshError, + ) if node_vertex_consistency_tolerance is not False: _test_node_vertex_consistency(mesh, tol=node_vertex_consistency_tolerance) @@ -1550,7 +1561,7 @@ def _compute_nodal_adjacency_from_vertices(mesh): lengths = [len(el_list) for el_list in element_to_element] neighbors_starts = np.cumsum( - np.array([0] + lengths, dtype=mesh.element_id_dtype)) + np.array([0, *lengths], dtype=mesh.element_id_dtype)) from pytools import flatten neighbors = np.array( list(flatten(element_to_element)), @@ -1807,12 +1818,12 @@ def _merge_boundary_adjacency_groups( elements=np.empty((0,), dtype=element_id_dtype), element_faces=np.empty((0,), dtype=face_id_dtype)) - max_ielem = max([ + max_ielem = max( np.max(grp.elements, initial=0) - for grp in bdry_grps]) - max_iface = max([ + for grp in bdry_grps) + max_iface = max( np.max(grp.element_faces, initial=0) - for grp in bdry_grps]) + for grp in bdry_grps) face_has_adj = np.full((max_iface+1, max_ielem+1), False) @@ -2054,10 +2065,10 @@ def check_bc_coverage(mesh, boundary_tags, incomplete_ok=False, else: all_btag = BTAG_REALLY_ALL - all_bdry_grp, = [ + all_bdry_grp, = ( fagrp for fagrp in fagrp_list if isinstance(fagrp, BoundaryAdjacencyGroup) - and fagrp.boundary_tag == all_btag] + and fagrp.boundary_tag == all_btag) matching_bdry_grps = [ fagrp for fagrp in fagrp_list @@ -2100,10 +2111,10 @@ def is_boundary_tag_empty(mesh, boundary_tag): raise ValueError(f"invalid boundary tag {boundary_tag}.") for igrp in range(len(mesh.groups)): - nfaces = sum([ + nfaces = sum( len(grp.elements) for grp in mesh.facial_adjacency_groups[igrp] if isinstance(grp, BoundaryAdjacencyGroup) - and grp.boundary_tag == boundary_tag]) + and grp.boundary_tag == boundary_tag) if nfaces > 0: return False diff --git a/meshmode/mesh/generation.py b/meshmode/mesh/generation.py index 824867245..323fa66e8 100644 --- a/meshmode/mesh/generation.py +++ b/meshmode/mesh/generation.py @@ -154,7 +154,7 @@ def n_gon(n_corners: int, t: np.ndarray) -> np.ndarray: t = t*n_corners - result = np.empty((2,)+t.shape) + result = np.empty((2, *t.shape)) for side in range(n_corners): indices = np.where((side <= t) & (t < side+1)) @@ -256,7 +256,7 @@ def rotation_matrix(angle: float) -> np.ndarray: # NOTE: Split [0, 1] interval into 5 chunks that have about equal arclength. # This is possible because each chunk is a circle arc, so we know its length. - L = ( # noqa: N806 + L = ( inv_gap * r_major + inv_gap * r_minor + 2 * np.pi * r_cap) @@ -274,7 +274,7 @@ def rotation_matrix(angle: float) -> np.ndarray: # first cap m_caps0 = np.logical_and(t >= t1, t < t2).astype(t.dtype) theta = m_caps0 * (np.pi / 2 + np.pi * (t - (t2 + t1) / 2) / (t2 - t1)) - R = r_cap * rotation_matrix(-gap) # noqa: N806 + R = r_cap * rotation_matrix(-gap) f_caps0 = R @ np.stack([ np.cos(theta) - 1, np.sin(theta) ]) + r_major * np.stack([[np.cos(-gap), np.sin(-gap)]]).T @@ -287,7 +287,7 @@ def rotation_matrix(angle: float) -> np.ndarray: # second cap m_caps1 = (t >= t3).astype(t.dtype) theta = m_caps1 * (np.pi / 2 + np.pi * (t - (t3 + t4) / 2) / (t4 - t3)) - R = r_cap * rotation_matrix(np.pi + gap) # noqa: N806 + R = r_cap * rotation_matrix(np.pi + gap) f_caps1 = R @ np.stack([ np.cos(theta) + 1, np.sin(theta) ]) + r_major * np.stack([[np.cos(gap), np.sin(gap)]]).T @@ -1150,7 +1150,7 @@ def generate_box_mesh( vertex_indices = np.arange(nvertices).reshape(*shape) - vertices = np.empty((dim,)+shape, dtype=coord_dtype) + vertices = np.empty((dim, *shape), dtype=coord_dtype) for idim in range(dim): vshape = (shape[idim],) + (1,)*(dim-1-idim) vertices[idim] = axis_coords[idim].reshape(*vshape) @@ -1200,7 +1200,7 @@ def generate_box_mesh( nvertices + np.arange(nmidpoints).reshape(*shape_m1, order="F")) - midpoints = np.empty((dim,)+shape_m1, dtype=coord_dtype) + midpoints = np.empty((dim, *shape_m1), dtype=coord_dtype) for idim in range(dim): vshape = (shape_m1[idim],) + (1,)*(1-idim) left_axis_coords = axis_coords[idim][:-1] @@ -1390,8 +1390,7 @@ def generate_box_mesh( if any(periodic): from meshmode import AffineMap - from meshmode.mesh.processing import ( - BoundaryPairMapping, glue_mesh_boundaries) + from meshmode.mesh.processing import BoundaryPairMapping, glue_mesh_boundaries bdry_pair_mappings_and_tols = [] for idim in range(dim): if periodic[idim]: @@ -1591,8 +1590,7 @@ def transform(x: np.ndarray) -> Tuple[np.ndarray, np.ndarray, np.ndarray]: from meshmode.mesh.tools import AffineMap aff_map = AffineMap(matrix, center - matrix @ center) - from meshmode.mesh.processing import ( - BoundaryPairMapping, glue_mesh_boundaries) + from meshmode.mesh.processing import BoundaryPairMapping, glue_mesh_boundaries periodic_mesh = glue_mesh_boundaries( mesh, bdry_pair_mappings_and_tols=[ (BoundaryPairMapping("-theta", "+theta", aff_map), 1e-12)]) @@ -1661,8 +1659,6 @@ def warp_and_refine_until_resolved( raise TypeError( f"Unsupported element group type: '{type(egrp).__name__}'") - dim, _ = egrp.unit_nodes.shape - interp_err_est_mat = simplex_interp_error_coefficient_estimator_matrix( egrp.unit_nodes, egrp.order, n_tail_orders=1 if warped_mesh.dim > 1 else 2) diff --git a/meshmode/mesh/io.py b/meshmode/mesh/io.py index 84c0c8639..f3d3a3264 100644 --- a/meshmode/mesh/io.py +++ b/meshmode/mesh/io.py @@ -23,8 +23,14 @@ import numpy as np from gmsh_interop.reader import ( # noqa: F401 - FileSource, GmshMeshReceiverBase, GmshSimplexElementBase, - GmshTensorProductElementBase, LiteralSource, ScriptSource, ScriptWithFilesSource) + FileSource, + GmshMeshReceiverBase, + GmshSimplexElementBase, + GmshTensorProductElementBase, + LiteralSource, + ScriptSource, + ScriptWithFilesSource, +) from meshmode.mesh import Mesh @@ -152,7 +158,10 @@ def get_mesh(self, return_tag_to_elements_map=False): # }}} from meshmode.mesh import ( - SimplexElementGroup, TensorProductElementGroup, make_mesh) + SimplexElementGroup, + TensorProductElementGroup, + make_mesh, + ) bulk_el_types = set() @@ -341,10 +350,10 @@ def generate_gmsh(source, dimensions=None, order=None, other_options=None, for idim in range(dim): if (mesh.vertices[idim] == 0).all(): from warnings import warn - warn("all vertices' %s coordinate is zero--perhaps you want to pass " - "force_ambient_dim=%d (pass any fixed value to " - "force_ambient_dim to silence this warning)" % ( - AXIS_NAMES[idim], idim)) + warn(f"all vertices' {AXIS_NAMES[idim]} coordinate is zero -- " + f"perhaps you want to pass force_ambient_dim={idim} (pass " + "any fixed value to force_ambient_dim to silence this warning)", + stacklevel=2) break return result @@ -404,7 +413,9 @@ def from_vertices_and_simplices( raise ValueError("can only fix orientation of volume meshes") from meshmode.mesh.processing import ( - find_volume_mesh_element_group_orientation, flip_element_group) + find_volume_mesh_element_group_orientation, + flip_element_group, + ) orient = find_volume_mesh_element_group_orientation(vertices, grp) grp = flip_element_group(vertices, grp, orient < 0) diff --git a/meshmode/mesh/processing.py b/meshmode/mesh/processing.py index c28877dac..1c23fbc0a 100644 --- a/meshmode/mesh/processing.py +++ b/meshmode/mesh/processing.py @@ -25,7 +25,16 @@ from dataclasses import dataclass, replace from functools import reduce from typing import ( - Callable, Dict, List, Literal, Mapping, Optional, Sequence, Tuple, Union) + Callable, + Dict, + List, + Literal, + Mapping, + Optional, + Sequence, + Tuple, + Union, +) import numpy as np import numpy.linalg as la @@ -33,9 +42,18 @@ import modepy as mp from meshmode.mesh import ( - BTAG_PARTITION, BoundaryAdjacencyGroup, FacialAdjacencyGroup, - InteriorAdjacencyGroup, InterPartAdjacencyGroup, Mesh, MeshElementGroup, PartID, - TensorProductElementGroup, _FaceIDs, make_mesh) + BTAG_PARTITION, + BoundaryAdjacencyGroup, + FacialAdjacencyGroup, + InteriorAdjacencyGroup, + InterPartAdjacencyGroup, + Mesh, + MeshElementGroup, + PartID, + TensorProductElementGroup, + _FaceIDs, + make_mesh, +) from meshmode.mesh.tools import AffineMap, find_point_permutation @@ -1420,12 +1438,12 @@ def map_mesh(mesh: Mesh, f: Callable[[np.ndarray], np.ndarray]) -> Mesh: def affine_map( mesh: Mesh, - A: Optional[Union[np.generic, np.ndarray]] = None, # noqa: N803 + A: Optional[Union[np.generic, np.ndarray]] = None, b: Optional[Union[np.generic, np.ndarray]] = None) -> Mesh: """Apply the affine map :math:`f(x) = A x + b` to the geometry of *mesh*.""" if A is not None and not isinstance(A, np.ndarray): - A = np.diag([A] * mesh.ambient_dim) # noqa: N806 + A = np.diag([A] * mesh.ambient_dim) if b is not None and not isinstance(b, np.ndarray): b = np.array([b] * mesh.ambient_dim) diff --git a/meshmode/mesh/refinement/no_adjacency.py b/meshmode/mesh/refinement/no_adjacency.py index 537090db0..66be87443 100644 --- a/meshmode/mesh/refinement/no_adjacency.py +++ b/meshmode/mesh/refinement/no_adjacency.py @@ -88,8 +88,10 @@ def refine(self, refine_flags): inew_vertex = mesh.nvertices from meshmode.mesh.refinement.tessellate import ( - get_group_midpoints, get_group_tessellated_nodes, - get_group_tessellation_info) + get_group_midpoints, + get_group_tessellated_nodes, + get_group_tessellation_info, + ) for base_element_nr, grp in zip(mesh.base_element_nrs, mesh.groups): el_tess_info = get_group_tessellation_info(grp) diff --git a/meshmode/mesh/refinement/utils.py b/meshmode/mesh/refinement/utils.py index 9188be45a..ce90d9a5f 100644 --- a/meshmode/mesh/refinement/utils.py +++ b/meshmode/mesh/refinement/utils.py @@ -30,7 +30,11 @@ import numpy as np from meshmode.mesh import ( - Mesh, MeshElementGroup, SimplexElementGroup, TensorProductElementGroup) + Mesh, + MeshElementGroup, + SimplexElementGroup, + TensorProductElementGroup, +) logger = logging.getLogger(__name__) diff --git a/meshmode/mesh/tools.py b/meshmode/mesh/tools.py index 1b718e0ce..aba0f0ad3 100644 --- a/meshmode/mesh/tools.py +++ b/meshmode/mesh/tools.py @@ -70,7 +70,7 @@ def make_element_lookup_tree(mesh, eps=1e-12): # {{{ random rotation matrix -def rand_rotation_matrix(ambient_dim, deflection=1.0, randnums=None): +def rand_rotation_matrix(ambient_dim, deflection=1.0, randnums=None, rng=None): """Creates a random rotation matrix. :arg deflection: the magnitude of the rotation. For 0, no rotation; for 1, @@ -85,7 +85,10 @@ def rand_rotation_matrix(ambient_dim, deflection=1.0, randnums=None): raise NotImplementedError("ambient_dim=%d" % ambient_dim) if randnums is None: - randnums = np.random.uniform(size=(3,)) + if rng is None: + rng = np.random.default_rng() + + randnums = rng.uniform(size=(3,)) theta, phi, z = randnums @@ -100,7 +103,7 @@ def rand_rotation_matrix(ambient_dim, deflection=1.0, randnums=None): # has length sqrt(2) to eliminate the 2 in the Householder matrix. r = np.sqrt(z) - V = ( # noqa: N806 + V = ( np.sin(phi) * r, np.cos(phi) * r, np.sqrt(2.0 - z) @@ -109,11 +112,11 @@ def rand_rotation_matrix(ambient_dim, deflection=1.0, randnums=None): st = np.sin(theta) ct = np.cos(theta) - R = np.array(((ct, st, 0), (-st, ct, 0), (0, 0, 1))) # noqa: N806 + R = np.array(((ct, st, 0), (-st, ct, 0), (0, 0, 1))) # Construct the rotation matrix ( V Transpose(V) - I ) R. - M = (np.outer(V, V) - np.eye(3)).dot(R) # noqa: N806 + M = (np.outer(V, V) - np.eye(3)).dot(R) return M # }}} diff --git a/meshmode/mesh/visualization.py b/meshmode/mesh/visualization.py index 6f32de7d1..4f9d184f9 100644 --- a/meshmode/mesh/visualization.py +++ b/meshmode/mesh/visualization.py @@ -45,6 +45,7 @@ def draw_2d_mesh( mesh: Mesh, *, + rng: Optional[np.random.Generator] = None, draw_vertex_numbers: bool = True, draw_element_numbers: bool = True, draw_nodal_adjacency: bool = False, @@ -59,6 +60,9 @@ def draw_2d_mesh( """ assert mesh.ambient_dim == 2 + if rng is None: + rng = np.random.default_rng() + import matplotlib.patches as mpatches import matplotlib.pyplot as pt from matplotlib.path import Path @@ -135,8 +139,8 @@ def global_iel_to_group_and_iel(global_iel): start = centroid + 0.15*dx mag = np.max(np.abs(dx)) - start += 0.05*(np.random.rand(2)-0.5)*mag - dx += 0.05*(np.random.rand(2)-0.5)*mag + start += 0.05*(rng.random(2)-0.5)*mag + dx += 0.05*(rng.random(2)-0.5)*mag pt.arrow(start[0], start[1], 0.7*dx[0], 0.7*dx[1], length_includes_head=True, @@ -212,8 +216,16 @@ def write_vertex_vtk_file( overwrite: bool = False) -> None: # {{{ create cell_types from pyvisfile.vtk import ( - VF_LIST_OF_COMPONENTS, VTK_HEXAHEDRON, VTK_LINE, VTK_QUAD, VTK_TETRA, - VTK_TRIANGLE, AppendedDataXMLGenerator, DataArray, UnstructuredGrid) + VF_LIST_OF_COMPONENTS, + VTK_HEXAHEDRON, + VTK_LINE, + VTK_QUAD, + VTK_TETRA, + VTK_TRIANGLE, + AppendedDataXMLGenerator, + DataArray, + UnstructuredGrid, + ) from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup @@ -234,7 +246,7 @@ def write_vertex_vtk_file( }[egrp.dim] else: raise NotImplementedError("mesh vtk file writing for " - "element group of type '%s'" % type(egrp).__name__) + f"element group of type '{type(egrp).__name__}'") cell_types[base_element_nr:base_element_nr + egrp.nelements] = vtk_cell_type @@ -282,7 +294,7 @@ def write_vertex_vtk_file( if overwrite: os.remove(file_name) else: - raise FileExistsError("output file '%s' already exists" % file_name) + raise FileExistsError(f"output file '{file_name}' already exists") with open(file_name, "w") as outf: AppendedDataXMLGenerator(compressor)(grid).write(outf) @@ -309,12 +321,11 @@ def mesh_to_tikz(mesh: Mesh) -> str: centroid = np.average(elverts, axis=1) lines.append(r"\coordinate (cent%d) at (%s);" - % (el_nr, - ", ".join("%.5f" % (vi) for vi in centroid))) + % (el_nr, ", ".join(f"{vi:.5f}" for vi in centroid))) for ivert, vert in enumerate(elverts.T): lines.append(r"\coordinate (v%d-%d) at (%s);" - % (el_nr, ivert+1, ", ".join("%.5f" % vi for vi in vert))) + % (el_nr, ivert+1, ", ".join(f"{vi:.5f}" for vi in vert))) drawel_lines.append( r"\draw [#1] %s -- cycle;" % " -- ".join( @@ -342,7 +353,8 @@ def vtk_visualize_mesh( from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( - InterpolatoryEdgeClusteredGroupFactory) + InterpolatoryEdgeClusteredGroupFactory, + ) discr = Discretization(actx, mesh, InterpolatoryEdgeClusteredGroupFactory(order)) from meshmode.discretization.visualization import make_visualizer @@ -422,7 +434,8 @@ def visualize_mesh_vertex_resampling_error( from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( - InterpolatoryEdgeClusteredGroupFactory) + InterpolatoryEdgeClusteredGroupFactory, + ) discr = Discretization(actx, mesh, InterpolatoryEdgeClusteredGroupFactory(1)) from meshmode.discretization.visualization import make_visualizer diff --git a/meshmode/version.py b/meshmode/version.py index e89038fa4..6784d82a5 100644 --- a/meshmode/version.py +++ b/meshmode/version.py @@ -1,2 +1,15 @@ -VERSION = (2021, 2) -VERSION_TEXT = ".".join(str(i) for i in VERSION) +from importlib import metadata +from typing import Tuple + + +def _parse_version(version: str) -> Tuple[Tuple[int, ...], str]: + import re + + m = re.match("^([0-9.]+)([a-z0-9]*?)$", VERSION_TEXT) + assert m is not None + + return tuple(int(nr) for nr in m.group(1).split(".")), m.group(2) + + +VERSION_TEXT = metadata.version("meshmode") +VERSION, VERSION_STATUS = _parse_version(VERSION_TEXT) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..6f03b2274 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,168 @@ +[build-system] +build-backend = "setuptools.build_meta" +requires = [ + "setuptools>=63", +] + +[project] +name = "meshmode" +version = "2021.2" +description = "High-order polynomial discretizations of and on meshes" +readme = "README.rst" +license = { text = "MIT" } +authors = [ + { name = "Andreas Kloeckner", email = "inform@tiker.net" }, +] +requires-python = ">=3.8" +classifiers = [ + "Development Status :: 3 - Alpha", + "Intended Audience :: Developers", + "Intended Audience :: Other Audience", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: MIT License", + "Natural Language :: English", + "Programming Language :: Python", + "Programming Language :: Python :: 3 :: Only", + "Topic :: Scientific/Engineering", + "Topic :: Scientific/Engineering :: Information Analysis", + "Topic :: Scientific/Engineering :: Mathematics", + "Topic :: Scientific/Engineering :: Visualization", + "Topic :: Software Development :: Libraries", + "Topic :: Utilities", +] +dependencies = [ + "arraycontext>=2021.1", + "gmsh-interop>=2021.1", + "loopy>=2024.1", + "modepy>=2021.1", + "numpy", + "pymbolic>=2022.2", + "pytools>=2022.1", + "recursivenodes", +] + +[project.optional-dependencies] +doc = [ + "furo", + "sphinx>=4", + "sphinx-copybutton", +] +test = [ + "mypy", + "pylint", + "pytest", + "ruff", +] +visualization = [ + "h5py", + "pyvisfile>=2022.1", +] + +[project.urls] +Documentation = "https://documen.tician.de/meshmode" +Repository = "https://github.com/inducer/meshmode" + +[tool.setuptools.packages.find] +include = [ + "meshmode*", +] + +[tool.ruff] +preview = true + +[tool.ruff.lint] +extend-select = [ + "B", # flake8-bugbear + "C", # flake8-comprehensions + "E", # pycodestyle + "F", # pyflakes + "G", # flake8-logging-format + "I", # flake8-isort + "N", # pep8-naming + "NPY", # numpy + "Q", # flake8-quotes + "RUF", # ruff + "UP", # pyupgrade + "W", # pycodestyle +] +extend-ignore = [ + "C90", # McCabe complexity + "E226", # missing whitespace around arithmetic operator + "E241", # multiple spaces after comma + "E242", # tab after comma + "E265", # comment should have a space + "E402", # module level import not at the top of file + "N802", # function name should be lowercase + "N803", # argument name should be lowercase + "N806", # variable name should be lowercase + "N818", # error suffix in exception names + "UP031", # use f-strings instead of % format + "UP032", # use f-strings instead of .format +] + +[tool.ruff.lint.flake8-quotes] +docstring-quotes = "double" +inline-quotes = "double" +multiline-quotes = "double" + +[tool.ruff.lint.isort] +combine-as-imports = true +known-first-party = [ + "pytools", + "pyopencl", + "loopy", + "arraycontext", + "gmsh_interop", + "pyvisfile", + "modepy", + "pytato", + "pymbolic", + "pymetis", + "firedrake", +] +known-local-folder = [ + "meshmode", +] +lines-after-imports = 2 + +[tool.pytest.ini_options] +markers = [ + "mpi: test requires MPI", + "octave: test requires Octave", +] + +[tool.mypy] +python_version = "3.8" +warn_unused_ignores = true + +[[tool.mypy.overrides]] +module = [ + "meshmode.discretization.*", + "meshmode.dof_array.*", + "meshmode.interop.*", + "meshmode.mesh.*", +] +ignore_errors = true + +[[tool.mypy.overrides]] +module = [ + "FIAT.*", + "finat.*", + "firedrake.*", + "gmsh_interop.*", + "h5py.*", + "loopy.*", + "matplotlib.*", + "mayavi.*", + "mpl_toolkits.*", + "oct2py.*", + "pymbolic.*", + "pymetis.*", + "pyop2.*", + "pyopencl.*", + "pytential.*", + "pyvisfile.*", + "recursivenodes.*", + "scipy.*", +] +ignore_missing_imports = true diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 51a2dab3e..000000000 --- a/pytest.ini +++ /dev/null @@ -1,4 +0,0 @@ -[pytest] -markers = - mpi: test requires MPI - octave: test requires Octave diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index aba7af885..000000000 --- a/setup.cfg +++ /dev/null @@ -1,98 +0,0 @@ -[flake8] -ignore = E126,E127,E128,E123,E226,E241,E242,E265,W503,E402 -max-line-length=85 -exclude=meshmode/mesh/refinement/__init__.py - -inline-quotes = " -docstring-quotes = """ -multiline-quotes = """ - -# enable-flake8-bugbear -# enable-flake8-isort -# -[isort] -known_firstparty=pytools,pyopencl,loopy,arraycontext,gmsh_interop,pyvisfile,modepy,pytato,pymbolic,pymetis,firedrake -known_local_folder=meshmode -line_length = 85 -lines_after_imports = 2 -combine_as_imports = True -multi_line_output = 4 - -[mypy] -python_version = 3.8 -warn_unused_ignores = True - -[mypy-meshmode.discretization.*] -ignore_errors = True - -[mypy-meshmode.mesh] -ignore_errors = True - -[mypy-meshmode.mesh.generation] -ignore_errors = True - -[mypy-meshmode.mesh.visualization] -ignore_errors = True - -[mypy-meshmode.mesh.refinement.*] -ignore_errors = True - -[mypy-meshmode.interop.*] -ignore_errors = True - -[mypy-meshmode.dof_array] -ignore_errors = True - -[mypy-pyvisfile.*] -ignore_missing_imports = True - -[mypy-matplotlib.*] -ignore_missing_imports = True - -[mypy-mpl_toolkits.*] -ignore_missing_imports = True - -[mypy-firedrake.*] -ignore_missing_imports = True - -[mypy-pyop2.*] -ignore_missing_imports = True - -[mypy-finat.*] -ignore_missing_imports = True - -[mypy-FIAT.*] -ignore_missing_imports = True - -[mypy-loopy.*] -ignore_missing_imports = True - -[mypy-gmsh_interop.*] -ignore_missing_imports = True - -[mypy-scipy.*] -ignore_missing_imports = True - -[mypy-pymetis.*] -ignore_missing_imports = True - -[mypy-pymbolic.*] -ignore_missing_imports = True - -[mypy-recursivenodes.*] -ignore_missing_imports = True - -[mypy-mayavi.*] -ignore_missing_imports = True - -[mypy-h5py.*] -ignore_missing_imports = True - -[mypy-oct2py.*] -ignore_missing_imports = True - -[mypy-pyopencl.*] -ignore_missing_imports = True - -[mypy-pytential.*] -ignore_missing_imports = True diff --git a/setup.py b/setup.py deleted file mode 100644 index a78d0afb3..000000000 --- a/setup.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - - -def main(): - from setuptools import find_packages, setup - - version_dict = {} - init_filename = "meshmode/version.py" - exec(compile(open(init_filename, "r").read(), init_filename, "exec"), - version_dict) - - setup(name="meshmode", - version=version_dict["VERSION_TEXT"], - description="High-order polynomial discretizations of and on meshes", - long_description=open("README.rst", "rt").read(), - author="Andreas Kloeckner", - author_email="inform@tiker.net", - license="MIT", - url="https://documen.tician.de/meshmode", - classifiers=[ - "Development Status :: 3 - Alpha", - "Intended Audience :: Developers", - "Intended Audience :: Other Audience", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: MIT License", - "Natural Language :: English", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Topic :: Scientific/Engineering", - "Topic :: Scientific/Engineering :: Information Analysis", - "Topic :: Scientific/Engineering :: Mathematics", - "Topic :: Scientific/Engineering :: Visualization", - "Topic :: Software Development :: Libraries", - "Topic :: Utilities", - ], - - packages=find_packages(), - python_requires="~=3.8", - install_requires=[ - "numpy", - "modepy>=2020.2", - "gmsh_interop", - "pytools>=2024.1.1", - - # 2019.1 is required for the Firedrake CIs, which use an very specific - # version of Loopy. - "loopy>=2019.1", - - "arraycontext", - "recursivenodes", - ], - extras_require={ - "visualization": ["h5py"], - "test": ["pytest>=2.3"], - }, - ) - - -if __name__ == "__main__": - main() diff --git a/test/test_array.py b/test/test_array.py index a2908a612..f6a3b2095 100644 --- a/test/test_array.py +++ b/test/test_array.py @@ -27,14 +27,18 @@ import pytest from arraycontext import ( - dataclass_array_container, pytest_generate_tests_for_array_contexts, - with_container_arithmetic) + dataclass_array_container, + pytest_generate_tests_for_array_contexts, + with_container_arithmetic, +) from pytools.obj_array import make_obj_array from pytools.tag import Tag from meshmode import _acf # noqa: F401 from meshmode.array_context import ( - PytestPyOpenCLArrayContextFactory, PytestPytatoPyOpenCLArrayContextFactory) + PytestPyOpenCLArrayContextFactory, + PytestPytatoPyOpenCLArrayContextFactory, +) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import default_simplex_group_factory from meshmode.dof_array import DOFArray, array_context_for_pickling, flat_norm @@ -78,7 +82,9 @@ def test_flatten_unflatten(actx_factory): b=(+0.5,)*ambient_dim, nelements_per_axis=(3,)*ambient_dim, order=1) discr = Discretization(actx, mesh, default_simplex_group_factory(ambient_dim, 3)) - a = np.random.randn(discr.ndofs) + + rng = np.random.default_rng(seed=42) + a = rng.normal(size=discr.ndofs) from meshmode.dof_array import flatten, unflatten a_round_trip = actx.to_numpy(flatten(unflatten(actx, discr, actx.from_numpy(a)))) @@ -172,7 +178,7 @@ def test_container_norm(actx_factory, ord): def test_dof_array_pickling(actx_factory): actx = actx_factory() - ary_dof, ary_of_dofs, mat_of_dofs, dc_of_dofs = _get_test_containers(actx) + _, _, mat_of_dofs, dc_of_dofs = _get_test_containers(actx) from pickle import dumps, loads with array_context_for_pickling(actx): diff --git a/test/test_chained.py b/test/test_chained.py index 9ee486f32..45b366206 100644 --- a/test/test_chained.py +++ b/test/test_chained.py @@ -58,8 +58,7 @@ def create_discretization(actx, ndim, else: raise ValueError(f"unknown mesh name: {mesh_name}") elif ndim == 3: - from meshmode.mesh.generation import ( - generate_torus, generate_warped_rect_mesh) + from meshmode.mesh.generation import generate_torus, generate_warped_rect_mesh if mesh_name is None: mesh_name = "torus" @@ -78,7 +77,8 @@ def create_discretization(actx, ndim, # create discretization from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( - InterpolatoryQuadratureSimplexGroupFactory) + InterpolatoryQuadratureSimplexGroupFactory, + ) discr = Discretization(actx, mesh, InterpolatoryQuadratureSimplexGroupFactory(order)) @@ -88,10 +88,12 @@ def create_discretization(actx, ndim, def create_refined_connection(actx, discr, threshold=0.3): from meshmode.discretization.connection import make_refinement_connection from meshmode.discretization.poly_element import ( - InterpolatoryQuadratureSimplexGroupFactory) + InterpolatoryQuadratureSimplexGroupFactory, + ) from meshmode.mesh.refinement import RefinerWithoutAdjacency - flags = np.random.rand(discr.mesh.nelements) < threshold + rng = np.random.default_rng(seed=42) + flags = rng.random(size=discr.mesh.nelements) < threshold refiner = RefinerWithoutAdjacency(discr.mesh) refiner.refine(flags) @@ -103,10 +105,10 @@ def create_refined_connection(actx, discr, threshold=0.3): def create_face_connection(actx, discr): - from meshmode.discretization.connection import ( - FACE_RESTR_ALL, make_face_restriction) + from meshmode.discretization.connection import FACE_RESTR_ALL, make_face_restriction from meshmode.discretization.poly_element import ( - InterpolatoryQuadratureSimplexGroupFactory) + InterpolatoryQuadratureSimplexGroupFactory, + ) discr_order = discr.groups[0].order connection = make_face_restriction(actx, discr, @@ -120,8 +122,7 @@ def create_face_connection(actx, discr): @pytest.mark.skip(reason="implementation detail") @pytest.mark.parametrize("ndim", [2, 3]) def test_chained_batch_table(actx_factory, ndim, visualize=False): - from meshmode.discretization.connection.chained import ( - _build_element_lookup_table) + from meshmode.discretization.connection.chained import _build_element_lookup_table actx = actx_factory() @@ -360,11 +361,11 @@ def run(nelements, order): conn.to_discr, threshold=threshold) connections.append(conn) - from meshmode.discretization.connection import ( - ChainedDiscretizationConnection) + from meshmode.discretization.connection import ChainedDiscretizationConnection chained = ChainedDiscretizationConnection(connections) from meshmode.discretization.connection import ( - L2ProjectionInverseDiscretizationConnection) + L2ProjectionInverseDiscretizationConnection, + ) reverse = L2ProjectionInverseDiscretizationConnection(chained) # create test vector diff --git a/test/test_connection.py b/test/test_connection.py index dbbd5d2aa..08ee8a4e1 100644 --- a/test/test_connection.py +++ b/test/test_connection.py @@ -34,9 +34,11 @@ from meshmode.discretization.connection import FACE_RESTR_ALL from meshmode.discretization.poly_element import ( LegendreGaussLobattoTensorProductGroupFactory, - PolynomialEquidistantSimplexGroupFactory, PolynomialRecursiveNodesGroupFactory, + PolynomialEquidistantSimplexGroupFactory, + PolynomialRecursiveNodesGroupFactory, PolynomialWarpAndBlend2DRestrictingGroupFactory, - PolynomialWarpAndBlend3DRestrictingGroupFactory) + PolynomialWarpAndBlend3DRestrictingGroupFactory, +) from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup @@ -76,7 +78,9 @@ def test_bdry_restriction_is_permutation(actx_factory, group_factory, dim, order vol_discr = Discretization(actx, mesh, group_factory(order)) from meshmode.discretization.connection import ( - make_face_restriction, make_opposite_face_connection) + make_face_restriction, + make_opposite_face_connection, + ) bdry_connection = make_face_restriction( actx, vol_discr, group_factory(order), FACE_RESTR_ALL) diff --git a/test/test_discretization.py b/test/test_discretization.py index 3422fa3e7..8c4361c3c 100644 --- a/test/test_discretization.py +++ b/test/test_discretization.py @@ -29,7 +29,8 @@ from meshmode.array_context import PytestPyOpenCLArrayContextFactory from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( - InterpolatoryQuadratureSimplexGroupFactory) + InterpolatoryQuadratureSimplexGroupFactory, +) pytest_generate_tests = pytest_generate_tests_for_array_contexts( diff --git a/test/test_firedrake_interop.py b/test/test_firedrake_interop.py index d32419b1c..bed5c46e7 100644 --- a/test/test_firedrake_interop.py +++ b/test/test_firedrake_interop.py @@ -31,11 +31,14 @@ from meshmode.array_context import PytestPyOpenCLArrayContextFactory from meshmode.discretization import Discretization from meshmode.discretization.poly_element import ( - InterpolatoryQuadratureSimplexGroupFactory) + InterpolatoryQuadratureSimplexGroupFactory, +) from meshmode.dof_array import DOFArray from meshmode.interop.firedrake import ( - build_connection_from_firedrake, build_connection_to_firedrake, - import_firedrake_mesh) + build_connection_from_firedrake, + build_connection_to_firedrake, + import_firedrake_mesh, +) from meshmode.mesh import BTAG_ALL, BTAG_INDUCED_BOUNDARY, Mesh, check_bc_coverage @@ -84,8 +87,14 @@ def make_mm_mesh(name: str) -> Mesh: def make_firedrake_mesh(name: str): from firedrake import ( - Function, Mesh, SpatialCoordinate, UnitCubeMesh, UnitIntervalMesh, - UnitSquareMesh, VectorFunctionSpace) + Function, + Mesh, + SpatialCoordinate, + UnitCubeMesh, + UnitIntervalMesh, + UnitSquareMesh, + VectorFunctionSpace, + ) if name == "FiredrakeUnitIntervalMesh": return UnitIntervalMesh(100) @@ -320,8 +329,8 @@ def test_bdy_tags(mesh_name, bdy_ids, coord_indices, coord_values, if only_convert_bdy: from meshmode.interop.firedrake.connection import _get_cells_to_use cells_to_use = _get_cells_to_use(square_or_cube_mesh, "on_boundary") - mm_mesh, orient = import_firedrake_mesh(square_or_cube_mesh, - cells_to_use=cells_to_use) + mm_mesh, _orient = import_firedrake_mesh(square_or_cube_mesh, + cells_to_use=cells_to_use) # Check disjoint coverage of bdy ids and BTAG_ALL check_bc_coverage(mm_mesh, [BTAG_ALL]) check_bc_coverage(mm_mesh, bdy_ids) @@ -504,8 +513,8 @@ def get_fdrake_mesh_and_h_from_par(mesh_par): # assert that order is correct or error is "low enough" for ((fd2mm, d), eoc_rec) in eoc_recorders.items(): - print("\nfiredrake -> meshmode: %s\nvector *x* -> *sin(x[%s])*\n" - % (fd2mm, d), eoc_rec) + print(f"\nfiredrake -> meshmode: {fd2mm}\nvector *x* -> *sin(x[{d}])*\n", + eoc_rec) assert ( eoc_rec.order_estimate() >= fspace_degree or eoc_rec.max_error() < 2e-14) @@ -579,7 +588,7 @@ def test_to_fd_transfer(actx_factory, fspace_degree, mesh_name, mesh_pars, dim): # assert that order is correct or error is "low enough" for d, eoc_rec in eoc_recorders.items(): - print("\nvector *x* -> *x[%s]*\n" % d, eoc_rec) + print(f"\nvector *x* -> *x[{d}]*\n", eoc_rec) assert ( eoc_rec.order_estimate() >= fspace_degree or eoc_rec.max_error() < 2e-14) @@ -601,8 +610,13 @@ def test_from_fd_idempotency(actx_factory, actx = actx_factory() from firedrake import ( - Function, FunctionSpace, SpatialCoordinate, TensorFunctionSpace, - VectorFunctionSpace, as_tensor) + Function, + FunctionSpace, + SpatialCoordinate, + TensorFunctionSpace, + VectorFunctionSpace, + as_tensor, + ) # Make a function space and a function with unique values at each node fdrake_mesh = make_firedrake_mesh(fdrake_mesh) diff --git a/test/test_mesh.py b/test/test_mesh.py index 23172b6e8..6b0d4c87f 100644 --- a/test/test_mesh.py +++ b/test/test_mesh.py @@ -40,10 +40,16 @@ from meshmode import _acf # noqa: F401 from meshmode.array_context import PytestPyOpenCLArrayContextFactory from meshmode.discretization.poly_element import ( - LegendreGaussLobattoTensorProductGroupFactory, default_simplex_group_factory) + LegendreGaussLobattoTensorProductGroupFactory, + default_simplex_group_factory, +) from meshmode.mesh import ( - BoundaryAdjacencyGroup, InteriorAdjacencyGroup, SimplexElementGroup, - TensorProductElementGroup, make_mesh) + BoundaryAdjacencyGroup, + InteriorAdjacencyGroup, + SimplexElementGroup, + TensorProductElementGroup, + make_mesh, +) from meshmode.mesh.tools import AffineMap @@ -307,15 +313,17 @@ def test_mesh_as_python(): # {{{ test_affine_map def test_affine_map(): + rng = np.random.default_rng(seed=42) + for d in range(1, 5): for _ in range(100): - a = np.random.randn(d, d)+10*np.eye(d) - b = np.random.randn(d) + a = rng.normal(size=(d, d)) + 10*np.eye(d) + b = rng.normal(size=d) m = AffineMap(a, b) assert la.norm(m.inverted().matrix - la.inv(a)) < 1e-10*la.norm(a) - x = np.random.randn(d) + x = rng.normal(size=d) m_inv = m.inverted() assert la.norm(x-m_inv(m(x))) < 1e-10 @@ -483,7 +491,7 @@ def test_mesh_to_tikz(): FileSource(str(thisdir / "blob-2d.step")), 2, order=order, force_ambient_dim=2, other_options=[ - "-string", "Mesh.CharacteristicLengthMax = %s;" % h], + "-string", f"Mesh.CharacteristicLengthMax = {h};"], target_unit="MM", ) @@ -796,9 +804,10 @@ def test_lookup_tree(visualize=False): bbox_min, bbox_max = mproc.find_bounding_box(mesh) extent = bbox_max-bbox_min + rng = np.random.default_rng(seed=42) for _ in range(20): - pt = bbox_min + np.random.rand(2) * extent + pt = bbox_min + rng.random(size=2) * extent print(pt) for igrp, iel in tree.generate_matches(pt): print(igrp, iel) @@ -855,7 +864,7 @@ def test_boundary_tags(): def test_volume_tags(): from meshmode.mesh.io import read_gmsh - mesh, tag_to_elements_map = read_gmsh( # pylint: disable=unpacking-non-sequence + _mesh, tag_to_elements_map = read_gmsh( # pylint: disable=unpacking-non-sequence str(thisdir / "testmesh_multivol.msh"), return_tag_to_elements_map=True) assert len(tag_to_elements_map) == 2 @@ -888,7 +897,10 @@ def test_box_boundary_tags(dim, nelem, mesh_type, group_cls, visualize=False): pytest.skip("mesh type not supported on tensor product elements") from meshmode.mesh import ( - check_bc_coverage, is_boundary_tag_empty, mesh_has_boundary) + check_bc_coverage, + is_boundary_tag_empty, + mesh_has_boundary, + ) if dim == 1: a = (0,) @@ -1143,7 +1155,7 @@ def gen_rect_mesh_with_perturbed_vertices( a, b, nelements_per_axis, perturb_amount): mesh_unperturbed = mgen.generate_regular_rect_mesh( a=a, b=b, nelements_per_axis=nelements_per_axis) - return mesh_unperturbed.copy( # noqa: F841 + return mesh_unperturbed.copy( vertices=( mesh_unperturbed.vertices + perturb_amount*np.ones(mesh_unperturbed.vertices.shape)), @@ -1244,8 +1256,7 @@ def gen_rect_mesh_with_perturbed_vertices( from meshmode.discretization import Discretization group_factory = default_simplex_group_factory(1, 1) vol_discr = Discretization(actx, vol_mesh, group_factory) - from meshmode.discretization.connection import ( - FACE_RESTR_ALL, make_face_restriction) + from meshmode.discretization.connection import FACE_RESTR_ALL, make_face_restriction make_face_restriction( actx, vol_discr, group_factory, FACE_RESTR_ALL, per_face_groups=False) @@ -1266,7 +1277,7 @@ def gen_rect_mesh_with_perturbed_vertices( vol_mesh_unrotated = mgen.generate_regular_rect_mesh( a=(-1,)*2, b=(1,)*2, nelements_per_axis=(8,)*2) - vol_mesh = vol_mesh_unrotated.copy( # noqa: F841 + vol_mesh = vol_mesh_unrotated.copy( groups=[ replace( grp, diff --git a/test/test_meshmode.py b/test/test_meshmode.py index 5be44eec8..526e7a2ee 100644 --- a/test/test_meshmode.py +++ b/test/test_meshmode.py @@ -33,18 +33,28 @@ import meshmode.mesh.generation as mgen from meshmode import _acf # noqa: F401 from meshmode.array_context import ( - PytestPyOpenCLArrayContextFactory, PytestPytatoPyOpenCLArrayContextFactory) + PytestPyOpenCLArrayContextFactory, + PytestPytatoPyOpenCLArrayContextFactory, +) from meshmode.discretization.connection import FACE_RESTR_ALL, FACE_RESTR_INTERIOR from meshmode.discretization.poly_element import ( InterpolatoryQuadratureSimplexGroupFactory, LegendreGaussLobattoTensorProductGroupFactory, - PolynomialEquidistantSimplexGroupFactory, PolynomialRecursiveNodesGroupFactory, + PolynomialEquidistantSimplexGroupFactory, + PolynomialRecursiveNodesGroupFactory, PolynomialWarpAndBlend2DRestrictingGroupFactory, - PolynomialWarpAndBlend3DRestrictingGroupFactory, default_simplex_group_factory) + PolynomialWarpAndBlend3DRestrictingGroupFactory, + default_simplex_group_factory, +) from meshmode.dof_array import flat_norm from meshmode.mesh import ( - BTAG_ALL, Mesh, MeshElementGroup, SimplexElementGroup, TensorProductElementGroup, - make_mesh) + BTAG_ALL, + Mesh, + MeshElementGroup, + SimplexElementGroup, + TensorProductElementGroup, + make_mesh, +) logger = logging.getLogger(__name__) @@ -114,7 +124,9 @@ def test_boundary_interpolation(actx_factory, group_factory, boundary_tag, from meshmode.discretization import Discretization from meshmode.discretization.connection import ( - check_connection, make_face_restriction) + check_connection, + make_face_restriction, + ) eoc_rec = EOCRecorder() order = 4 @@ -179,7 +191,8 @@ def f(x): if mesh_name == "blob" and dim == 2 and mesh.nelements < 500: from meshmode.discretization.connection.direct import ( - make_direct_full_resample_matrix) + make_direct_full_resample_matrix, + ) mat = actx.to_numpy( make_direct_full_resample_matrix(actx, bdry_connection)) bdry_f_2_by_mat = mat.dot(actx.to_numpy(flatten(vol_f, actx))) @@ -233,7 +246,10 @@ def test_all_faces_interpolation(actx_factory, group_factory, from meshmode.discretization import Discretization from meshmode.discretization.connection import ( - check_connection, make_face_restriction, make_face_to_all_faces_embedding) + check_connection, + make_face_restriction, + make_face_to_all_faces_embedding, + ) eoc_rec = EOCRecorder() order = 4 @@ -255,7 +271,7 @@ def f(x): FileSource(str(thisdir / "blob-2d.step")), 2, order=order, force_ambient_dim=2, other_options=[ - "-string", "Mesh.CharacteristicLengthMax = %s;" % h], + "-string", f"Mesh.CharacteristicLengthMax = {h};"], target_unit="MM", ) print("END GEN") @@ -359,7 +375,10 @@ def test_opposite_face_interpolation(actx_factory, group_factory, from meshmode.discretization import Discretization from meshmode.discretization.connection import ( - check_connection, make_face_restriction, make_opposite_face_connection) + check_connection, + make_face_restriction, + make_opposite_face_connection, + ) eoc_rec = EOCRecorder() order = 5 @@ -389,7 +408,7 @@ def f(x): FileSource(str(thisdir / "blob-2d.step")), 2, order=order, force_ambient_dim=2, other_options=[ - "-string", "Mesh.CharacteristicLengthMax = %s;" % h], + "-string", f"Mesh.CharacteristicLengthMax = {h};"], target_unit="MM", ) print("END GEN") @@ -514,7 +533,7 @@ def test_orientation_3d(actx_factory, what, mesh_gen_func, visualize=False): from meshmode.discretization.visualization import make_visualizer vis = make_visualizer(actx, discr, 3) - vis.write_vtk_file("orientation_3d_%s_normals.vtu" % what, [ + vis.write_vtk_file(f"orientation_3d_{what}_normals.vtu", [ ("normals", normals), ]) @@ -692,9 +711,10 @@ def test_sanity_qhull_nd(actx_factory, dim, order): logging.basicConfig(level=logging.INFO) actx = actx_factory() + rng = np.random.default_rng(seed=42) from scipy.spatial import Delaunay # pylint: disable=no-name-in-module - verts = np.random.rand(1000, dim) + verts = rng.random(size=(1000, dim)) dtri = Delaunay(verts) # pylint: disable=no-member @@ -763,7 +783,7 @@ def test_sanity_balls(actx_factory, src_file, dim, mesh_order, visualize=False): from meshmode.mesh.io import FileSource, generate_gmsh mesh = generate_gmsh( FileSource(src_file), dim, order=mesh_order, - other_options=["-string", "Mesh.CharacteristicLengthMax = %g;" % h], + other_options=["-string", f"Mesh.CharacteristicLengthMax = {h};"], force_ambient_dim=dim, target_unit="MM") @@ -866,7 +886,6 @@ def test_mesh_without_vertices(actx_factory): # create one without the vertices from dataclasses import replace - grp, = mesh.groups groups = [ replace(grp, nodes=grp.nodes, vertex_indices=None) for grp in mesh.groups] @@ -954,8 +973,11 @@ def grp_factory(mesh_el_group: MeshElementGroup): # check face restrictions from meshmode.discretization.connection import ( - check_connection, make_face_restriction, make_face_to_all_faces_embedding, - make_opposite_face_connection) + check_connection, + make_face_restriction, + make_face_to_all_faces_embedding, + make_opposite_face_connection, + ) for boundary_tag in [BTAG_ALL, FACE_RESTR_INTERIOR, FACE_RESTR_ALL]: conn = make_face_restriction(actx, discr, group_factory=grp_factory, diff --git a/test/test_modal.py b/test/test_modal.py index 4289f02ef..c5e39f19a 100644 --- a/test/test_modal.py +++ b/test/test_modal.py @@ -33,14 +33,20 @@ from meshmode.array_context import PytestPyOpenCLArrayContextFactory from meshmode.discretization import Discretization from meshmode.discretization.connection.modal import ( - ModalToNodalDiscretizationConnection, NodalToModalDiscretizationConnection) + ModalToNodalDiscretizationConnection, + NodalToModalDiscretizationConnection, +) from meshmode.discretization.poly_element import ( InterpolatoryQuadratureSimplexGroupFactory, - LegendreGaussLobattoTensorProductGroupFactory, ModalSimplexGroupFactory, - ModalTensorProductGroupFactory, PolynomialEquidistantSimplexGroupFactory, + LegendreGaussLobattoTensorProductGroupFactory, + ModalSimplexGroupFactory, + ModalTensorProductGroupFactory, + PolynomialEquidistantSimplexGroupFactory, PolynomialRecursiveNodesGroupFactory, PolynomialWarpAndBlend2DRestrictingGroupFactory, - PolynomialWarpAndBlend3DRestrictingGroupFactory, QuadratureSimplexGroupFactory) + PolynomialWarpAndBlend3DRestrictingGroupFactory, + QuadratureSimplexGroupFactory, +) from meshmode.dof_array import DOFArray, flat_norm from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup diff --git a/test/test_partition.py b/test/test_partition.py index 142853c39..e179aef39 100644 --- a/test/test_partition.py +++ b/test/test_partition.py @@ -37,8 +37,11 @@ from meshmode.discretization.poly_element import default_simplex_group_factory from meshmode.dof_array import flat_norm from meshmode.mesh import ( - BTAG_ALL, BoundaryAdjacencyGroup, InteriorAdjacencyGroup, - InterPartAdjacencyGroup) + BTAG_ALL, + BoundaryAdjacencyGroup, + InteriorAdjacencyGroup, + InterPartAdjacencyGroup, +) logger = logging.getLogger(__name__) @@ -65,8 +68,8 @@ def test_partition_interpolation(actx_factory, dim, mesh_pars, num_parts, num_groups, part_method): order = 4 + rng = np.random.default_rng(seed=42) - np.random.seed(42) group_factory = default_simplex_group_factory(base_dim=dim, order=order) actx = actx_factory() @@ -88,7 +91,7 @@ def f(x): mesh = base_mesh if part_method == "random": - part_per_element = np.random.randint(num_parts, size=mesh.nelements) + part_per_element = rng.integers(0, num_parts, size=mesh.nelements) else: pytest.importorskip("pymetis") @@ -114,7 +117,10 @@ def f(x): for part_mesh in part_meshes.values()] from meshmode.discretization.connection import ( - check_connection, make_face_restriction, make_partition_connection) + check_connection, + make_face_restriction, + make_partition_connection, + ) from meshmode.mesh import BTAG_PARTITION for i_local_part, i_remote_part in connected_parts: @@ -205,7 +211,8 @@ def _check_for_cross_rank_adj(mesh, part_per_element): ]) @pytest.mark.parametrize("num_groups", [1, 2, 7]) def test_partition_mesh(mesh_size, num_parts, num_groups, dim, scramble_parts): - np.random.seed(42) + rng = np.random.default_rng(seed=42) + nelements_per_axis = (mesh_size,) * dim from meshmode.mesh.generation import generate_regular_rect_mesh meshes = [generate_regular_rect_mesh(a=(0 + i,) * dim, b=(1 + i,) * dim, @@ -215,7 +222,7 @@ def test_partition_mesh(mesh_size, num_parts, num_groups, dim, scramble_parts): mesh = merge_disjoint_meshes(meshes) if scramble_parts: - part_per_element = np.random.randint(num_parts, size=mesh.nelements) + part_per_element = rng.integers(0, num_parts, size=mesh.nelements) else: pytest.importorskip("pymetis") @@ -314,8 +321,8 @@ def test_partition_mesh(mesh_size, num_parts, num_groups, dim, scramble_parts): assert found_reverse_adj, ("InterPartAdjacencyGroup is not " "consistent") - p_grp_num = find_group_indices(mesh.groups, p_meshwide_elem) # pylint: disable=possibly-used-before-assignment # noqa: E501 - p_n_grp_num = find_group_indices(mesh.groups, p_meshwide_n_elem) # pylint: disable=possibly-used-before-assignment # noqa: E501 + p_grp_num = find_group_indices(mesh.groups, p_meshwide_elem) # pylint: disable=possibly-used-before-assignment + p_n_grp_num = find_group_indices(mesh.groups, p_meshwide_n_elem) # pylint: disable=possibly-used-before-assignment p_elem_base = mesh.base_element_nrs[p_grp_num] p_n_elem_base = mesh.base_element_nrs[p_n_grp_num] @@ -367,13 +374,13 @@ def count_tags(mesh, tag): def _test_mpi_boundary_swap(dim, order, num_groups): from mpi4py import MPI - from meshmode.distributed import ( - MPIBoundaryCommSetupHelper, membership_list_to_map) + from meshmode.distributed import MPIBoundaryCommSetupHelper, membership_list_to_map from meshmode.mesh.processing import partition_mesh mpi_comm = MPI.COMM_WORLD if mpi_comm.rank == 0: - np.random.seed(42) + rng = np.random.default_rng(seed=42) + from meshmode.mesh.generation import generate_warped_rect_mesh meshes = [generate_warped_rect_mesh(dim, order=order, nelements_side=4) for _ in range(num_groups)] @@ -384,9 +391,10 @@ def _test_mpi_boundary_swap(dim, order, num_groups): else: mesh = meshes[0] - part_id_to_part = partition_mesh(mesh, - membership_list_to_map( - np.random.randint(mpi_comm.size, size=mesh.nelements))) + part_id_to_part = partition_mesh( + mesh, + membership_list_to_map(rng.integers(0, mpi_comm.size, size=mesh.nelements)) + ) assert list(part_id_to_part.keys()) == list(range(mpi_comm.size)) parts = [part_id_to_part[i] for i in range(mpi_comm.size)] @@ -575,7 +583,7 @@ def f(x): from numpy.linalg import norm err = norm(true_local_f - local_f, np.inf) - assert err < 1e-11, "Error = %f is too large" % err + assert err < 1e-11, f"Error = {err:f} is too large" # }}} diff --git a/test/test_refinement.py b/test/test_refinement.py index e262a69f4..f265d8c3e 100644 --- a/test/test_refinement.py +++ b/test/test_refinement.py @@ -38,7 +38,8 @@ LegendreGaussLobattoTensorProductGroupFactory, PolynomialEquidistantSimplexGroupFactory, PolynomialWarpAndBlend2DRestrictingGroupFactory, - PolynomialWarpAndBlend3DRestrictingGroupFactory) + PolynomialWarpAndBlend3DRestrictingGroupFactory, +) from meshmode.dof_array import flat_norm from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup from meshmode.mesh.refinement import RefinerWithoutAdjacency @@ -143,7 +144,9 @@ def test_refinement_connection( from meshmode.discretization import Discretization from meshmode.discretization.connection import ( - check_connection, make_refinement_connection) + check_connection, + make_refinement_connection, + ) eoc_rec = EOCRecorder() for mesh_par in mesh_pars: diff --git a/test/test_visualization.py b/test/test_visualization.py index 0d7a435f3..0cd0f8fbb 100644 --- a/test/test_visualization.py +++ b/test/test_visualization.py @@ -36,7 +36,9 @@ from meshmode.array_context import PytestPyOpenCLArrayContextFactory from meshmode.discretization.poly_element import ( InterpolatoryQuadratureSimplexGroupFactory, - LegendreGaussLobattoTensorProductGroupFactory, default_simplex_group_factory) + LegendreGaussLobattoTensorProductGroupFactory, + default_simplex_group_factory, +) from meshmode.mesh import SimplexElementGroup, TensorProductElementGroup @@ -83,10 +85,10 @@ def test_parallel_vtk_file(actx_factory, dim): vis = make_visualizer(actx, discr, target_order) class FakeComm: - def Get_rank(self): # noqa: N802 + def Get_rank(self): return 0 - def Get_size(self): # noqa: N802 + def Get_size(self): return 2 file_name_pattern = f"visualizer_vtk_linear_{dim}_{{rank}}.vtu" @@ -323,7 +325,9 @@ def _try_write_vtk(writer, obj): InterpolatoryQuadratureSimplexGroupFactory(target_order)) from meshmode.discretization.visualization import ( - make_visualizer, write_nodal_adjacency_vtk_file) + make_visualizer, + write_nodal_adjacency_vtk_file, + ) from meshmode.mesh.visualization import write_vertex_vtk_file vis = make_visualizer(actx, discr, 1)