From b5a111799f583aa43196de7d3ba51ec10c2bd1ee Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Wed, 5 Feb 2025 15:06:40 +0000 Subject: [PATCH 01/21] STY: Formatting with ruff --- requirements.txt | 3 -- src/porepy/__init__.py | 2 +- src/porepy/applications/test_utils/arrays.py | 3 +- .../test_utils/common_xpfa_tests.py | 4 +- src/porepy/applications/test_utils/grids.py | 3 +- src/porepy/applications/test_utils/vtk.py | 3 +- .../applications/test_utils/well_models.py | 4 +- src/porepy/compositional/base.py | 8 ---- .../compositional/compositional_mixins.py | 19 +++++----- src/porepy/examples/terzaghi_biot.py | 1 - src/porepy/fracs/fracture_network.py | 4 +- src/porepy/fracs/fracture_network_2d.py | 6 +-- src/porepy/fracs/fracture_network_3d.py | 4 +- src/porepy/fracs/meshing.py | 2 +- src/porepy/fracs/simplex.py | 2 +- src/porepy/fracs/split_grid.py | 2 +- src/porepy/fracs/structured.py | 12 +++--- src/porepy/fracs/utils.py | 2 +- src/porepy/geometry/intersections.py | 4 +- src/porepy/geometry/map_geometry.py | 4 +- src/porepy/grids/coarsening.py | 4 +- src/porepy/grids/md_grid.py | 2 +- src/porepy/grids/mdg_generation.py | 2 +- src/porepy/grids/refinement.py | 6 +-- src/porepy/models/constitutive_laws.py | 3 -- src/porepy/models/fluid_property_library.py | 2 +- src/porepy/models/geometry.py | 4 +- src/porepy/models/mass_and_energy_balance.py | 2 +- src/porepy/models/poromechanics.py | 6 +-- src/porepy/models/run_models.py | 2 +- src/porepy/models/solution_strategy.py | 6 +-- src/porepy/models/thermoporomechanics.py | 6 +-- src/porepy/numerics/ad/__init__.py | 2 +- src/porepy/numerics/ad/_ad_utils.py | 1 - src/porepy/numerics/ad/forward_mode.py | 3 +- src/porepy/numerics/ad/grid_operators.py | 2 +- src/porepy/numerics/ad/operator_functions.py | 12 +++--- src/porepy/numerics/ad/operators.py | 38 +++++++++---------- src/porepy/numerics/ad/surrogate_operator.py | 2 - src/porepy/numerics/discretization.py | 2 +- .../propagate_fracture.py | 6 +-- src/porepy/numerics/fv/biot.py | 2 +- src/porepy/numerics/fv/fvutils.py | 12 ++++-- src/porepy/numerics/fv/mpfa.py | 6 +-- src/porepy/numerics/fv/tpsa.py | 5 +-- src/porepy/numerics/linalg/__init__.py | 3 +- .../numerics/linalg/matrix_operations.py | 1 - src/porepy/numerics/vem/__init__.py | 3 +- src/porepy/numerics/vem/hybrid.py | 1 + src/porepy/params/data.py | 2 +- src/porepy/params/parameter_dictionaries.py | 2 +- src/porepy/params/tensor.py | 9 ++--- src/porepy/utils/graph.py | 2 +- src/porepy/utils/grid_utils.py | 3 +- src/porepy/utils/interpolation_tables.py | 2 +- src/porepy/utils/mcolon.py | 4 +- src/porepy/utils/permutations.py | 3 +- src/porepy/utils/setmembership.py | 4 +- src/porepy/utils/sort_points.py | 3 +- src/porepy/viz/diagnostics_mixin.py | 4 +- 60 files changed, 121 insertions(+), 155 deletions(-) diff --git a/requirements.txt b/requirements.txt index 9b5a77f404..a1242cfe29 100644 --- a/requirements.txt +++ b/requirements.txt @@ -12,10 +12,7 @@ shapely six sympy typing_extensions -black == 24.* deepdiff -flake8 -isort mypy pytest >= 4.6 pytest-cov diff --git a/src/porepy/__init__.py b/src/porepy/__init__.py index 48afec3957..d425d313b7 100644 --- a/src/porepy/__init__.py +++ b/src/porepy/__init__.py @@ -1,4 +1,4 @@ -""" PorePy. +"""PorePy. Root directory for the PorePy package. Contains the following sub-packages: diff --git a/src/porepy/applications/test_utils/arrays.py b/src/porepy/applications/test_utils/arrays.py index e94dcc3851..b2d9ded6d8 100644 --- a/src/porepy/applications/test_utils/arrays.py +++ b/src/porepy/applications/test_utils/arrays.py @@ -1,5 +1,4 @@ -"""Test helpers for arrays and matrices. -""" +"""Test helpers for arrays and matrices.""" import numpy as np import scipy.sparse as sps diff --git a/src/porepy/applications/test_utils/common_xpfa_tests.py b/src/porepy/applications/test_utils/common_xpfa_tests.py index e4f8295313..c6073e607c 100644 --- a/src/porepy/applications/test_utils/common_xpfa_tests.py +++ b/src/porepy/applications/test_utils/common_xpfa_tests.py @@ -56,7 +56,7 @@ def perturb_grid(g, rate, dx): def create_grid_mpfa_mpsa_reproduce_known_values( - grid_type: Literal["cart", "simplex"] + grid_type: Literal["cart", "simplex"], ) -> tuple[pp.Grid, pp.Grid]: """Create grids for the tests that mpfa and mpsa reproduce known values. @@ -822,7 +822,7 @@ def test_linear_pressure_dirichlet_conditions_perturbed_grid(self): def test_split_discretization_into_subproblems( - discr_class: Union[pp.Mpfa, pp.Mpsa, pp.Biot] + discr_class: Union[pp.Mpfa, pp.Mpsa, pp.Biot], ): """Test that the discretization matrices produced by Mpxa are the same if they are split into subproblems or not. diff --git a/src/porepy/applications/test_utils/grids.py b/src/porepy/applications/test_utils/grids.py index 5c42e3cfc3..d565910954 100644 --- a/src/porepy/applications/test_utils/grids.py +++ b/src/porepy/applications/test_utils/grids.py @@ -1,5 +1,4 @@ -"""Helper methods to compare grids. -""" +"""Helper methods to compare grids.""" import numpy as np diff --git a/src/porepy/applications/test_utils/vtk.py b/src/porepy/applications/test_utils/vtk.py index a25829be43..d75e7fa3d7 100644 --- a/src/porepy/applications/test_utils/vtk.py +++ b/src/porepy/applications/test_utils/vtk.py @@ -1,5 +1,4 @@ -"""Test helpers for the vtk files. -""" +"""Test helpers for the vtk files.""" import shutil import xml.etree.ElementTree as ET diff --git a/src/porepy/applications/test_utils/well_models.py b/src/porepy/applications/test_utils/well_models.py index 6332e6a827..e8b6c6dd8d 100644 --- a/src/porepy/applications/test_utils/well_models.py +++ b/src/porepy/applications/test_utils/well_models.py @@ -1,5 +1,4 @@ -"""Contains code for setting up a simple but non-trivial model with a well. -""" +"""Contains code for setting up a simple but non-trivial model with a well.""" import numpy as np @@ -7,7 +6,6 @@ class OneVerticalWell: - domain: pp.Domain """Domain for the model.""" diff --git a/src/porepy/compositional/base.py b/src/porepy/compositional/base.py index 925d39a1a6..fb1a7ba9e7 100644 --- a/src/porepy/compositional/base.py +++ b/src/porepy/compositional/base.py @@ -96,7 +96,6 @@ class Component: """ def __init__(self, *args, **kwargs) -> None: - self.name: str = str(kwargs.get("name", "unnamed_component")) """Name of the component. Can be named by providing a keyword argument 'name' when instantiating.""" @@ -162,7 +161,6 @@ class Compound(Component, Generic[ComponentLike]): """ def __init__(self, *args, **kwargs) -> None: - self.molar_mass: pp.number if "molar_mass" not in kwargs: raise ValueError( @@ -476,7 +474,6 @@ def __init__( state: PhysicalState, name: str, ) -> None: - self._ref_component_index: int = 0 """See :meth:`reference_component_index`.""" @@ -732,7 +729,6 @@ def __init__( components: list[ComponentLike], phases: list[PhaseLike], ) -> None: - self._ref_phase_index: int = 0 """See :meth:`reference_phase_index`.""" self._ref_component_index: int = 0 @@ -959,7 +955,6 @@ def density(self, domains: pp.SubdomainsOrBoundaries) -> pp.ad.Operator: """ if self.num_phases > 1: - op = pp.ad.sum_operator_list( [ phase.saturation(domains) * phase.density(domains) @@ -1010,7 +1005,6 @@ def specific_enthalpy(self, domains: pp.SubdomainsOrBoundaries) -> pp.ad.Operato """ if self.num_phases > 1: - op = pp.ad.sum_operator_list( [ phase.fraction(domains) * phase.specific_enthalpy(domains) @@ -1049,7 +1043,6 @@ def thermal_conductivity( """ if self.num_phases > 1: - op = pp.ad.sum_operator_list( [ phase.saturation(domains) * phase.thermal_conductivity(domains) @@ -1059,7 +1052,6 @@ def thermal_conductivity( ) else: - op = self.reference_phase.thermal_conductivity(domains) op.set_name("fluid_thermal_conductivity") diff --git a/src/porepy/compositional/compositional_mixins.py b/src/porepy/compositional/compositional_mixins.py index 286d65b464..1f726bac4d 100644 --- a/src/porepy/compositional/compositional_mixins.py +++ b/src/porepy/compositional/compositional_mixins.py @@ -768,9 +768,9 @@ def tracer_fraction( A callable which returns the tracer fraction for a given set of domains. """ - assert ( - tracer in compound.active_tracers - ), f"Solute {tracer.name} not in compound {compound.name}" + assert tracer in compound.active_tracers, ( + f"Solute {tracer.name} not in compound {compound.name}" + ) if self.has_independent_tracer_fraction(tracer, compound): fraction = self._fraction_factory( @@ -894,9 +894,9 @@ def extended_fraction( A callable which returns the extended fraction for a given set of domains. """ - assert ( - component in phase - ), f"Component {component.name} not in phase {phase.name}" + assert component in phase, ( + f"Component {component.name} not in phase {phase.name}" + ) fraction: DomainFunctionType @@ -956,9 +956,9 @@ def partial_fraction( A callable which returns the extended fraction for a given set of domains. """ - assert ( - component in phase - ), f"Component {component.name} not in phase {phase.name}" + assert component in phase, ( + f"Component {component.name} not in phase {phase.name}" + ) fraction: DomainFunctionType @@ -983,7 +983,6 @@ def fraction(domains: pp.SubdomainsOrBoundaries) -> pp.ad.Operator: elif component == phase.reference_component: def fraction(domains: pp.SubdomainsOrBoundaries) -> pp.ad.Operator: - x_r = pp.ad.Scalar(1.0) - pp.ad.sum_operator_list( [ phase.partial_fraction_of[comp](domains) diff --git a/src/porepy/examples/terzaghi_biot.py b/src/porepy/examples/terzaghi_biot.py index 1e5ba7f196..ece05fe80d 100644 --- a/src/porepy/examples/terzaghi_biot.py +++ b/src/porepy/examples/terzaghi_biot.py @@ -528,7 +528,6 @@ def meshing_arguments(self) -> dict: # -----> Boundary conditions class TerzaghiBoundaryConditionsMechanics(mechanics.BoundaryConditionsMomentumBalance): - def applied_load(self) -> pp.number: """Obtain vertical load in scaled [Pa].""" applied_load = self.params.get("vertical_load", 6e8) # [Pa] diff --git a/src/porepy/fracs/fracture_network.py b/src/porepy/fracs/fracture_network.py index 57eb56c8f3..63a70050ae 100644 --- a/src/porepy/fracs/fracture_network.py +++ b/src/porepy/fracs/fracture_network.py @@ -127,7 +127,9 @@ def create_fracture_network( # check above, it is safe to ignore the argument type if dim == 2: fracture_network_2d = FractureNetwork2d( - fractures=fracs, domain=domain, tol=tol # type: ignore[arg-type] + fractures=fracs, + domain=domain, + tol=tol, # type: ignore[arg-type] ) return fracture_network_2d else: diff --git a/src/porepy/fracs/fracture_network_2d.py b/src/porepy/fracs/fracture_network_2d.py index dce24e782a..fb4cd16ccd 100644 --- a/src/porepy/fracs/fracture_network_2d.py +++ b/src/porepy/fracs/fracture_network_2d.py @@ -506,9 +506,9 @@ def _find_and_split_intersections(self, constraints: np.ndarray) -> None: tags = np.zeros((2, edges.shape[1]), dtype=int) - tags[0][ - np.logical_not(self.tags["boundary"]) - ] = GmshInterfaceTags.FRACTURE.value + tags[0][np.logical_not(self.tags["boundary"])] = ( + GmshInterfaceTags.FRACTURE.value + ) tags[0][self.tags["boundary"]] = GmshInterfaceTags.DOMAIN_BOUNDARY_LINE.value tags[0][constraints] = GmshInterfaceTags.AUXILIARY_LINE.value diff --git a/src/porepy/fracs/fracture_network_3d.py b/src/porepy/fracs/fracture_network_3d.py index e275ce57f3..3c406858e3 100644 --- a/src/porepy/fracs/fracture_network_3d.py +++ b/src/porepy/fracs/fracture_network_3d.py @@ -1182,7 +1182,9 @@ def _remove_edge_intersections( # somewhat to obtain a more robust algorithm. Not sure about how to do # this consistent. p_new, edges_new, tags = pp.intersections.split_intersecting_segments_2d( - p_2d, edges_2d, tol=self.tol # type: ignore[misc] + p_2d, + edges_2d, + tol=self.tol, # type: ignore[misc] ) # Then, patch things up by converting new points to 3D, diff --git a/src/porepy/fracs/meshing.py b/src/porepy/fracs/meshing.py index 1208ff0c95..2fb9c4cbc0 100644 --- a/src/porepy/fracs/meshing.py +++ b/src/porepy/fracs/meshing.py @@ -240,7 +240,7 @@ def _tag_faces(grids, check_highest_dim=True): # Assume only one grid of highest dimension if check_highest_dim: - assert len(grids[0]) == 1, "Must be exactly" "1 grid of dim: " + str(len(grids)) + assert len(grids[0]) == 1, "Must be exactly1 grid of dim: " + str(len(grids)) for g_h in np.atleast_1d(grids[0]): bnd_faces = g_h.get_all_boundary_faces() diff --git a/src/porepy/fracs/simplex.py b/src/porepy/fracs/simplex.py index 1600a542fd..226b989221 100644 --- a/src/porepy/fracs/simplex.py +++ b/src/porepy/fracs/simplex.py @@ -1,5 +1,5 @@ """Module with functionality to create simplex grids with fractures from a -tesselation generated by gmsh. """ +tesselation generated by gmsh.""" from __future__ import annotations diff --git a/src/porepy/fracs/split_grid.py b/src/porepy/fracs/split_grid.py index 8761a67fed..20386f8c89 100644 --- a/src/porepy/fracs/split_grid.py +++ b/src/porepy/fracs/split_grid.py @@ -558,7 +558,7 @@ def update_cell_connectivity( # domain. Check that each face added two cells: if sum(left_cell) * 2 != left_cell.size: raise ValueError( - "Fractures must either be" "on boundary or completely inside domain" + "Fractures must either beon boundary or completely inside domain" ) # We create a cell_faces mapping for the new faces. This will be added on the end diff --git a/src/porepy/fracs/structured.py b/src/porepy/fracs/structured.py index 083fda968a..083c8bf62f 100644 --- a/src/porepy/fracs/structured.py +++ b/src/porepy/fracs/structured.py @@ -213,9 +213,9 @@ def _create_lower_dim_grids_3d( is_xy_frac = np.allclose(f[2, 0], f[2]) is_xz_frac = np.allclose(f[1, 0], f[1]) is_yz_frac = np.allclose(f[0, 0], f[0]) - assert ( - is_xy_frac + is_xz_frac + is_yz_frac == 1 - ), "Fracture must align to x-, y- or z-axis" + assert is_xy_frac + is_xz_frac + is_yz_frac == 1, ( + "Fracture must align to x-, y- or z-axis" + ) # snap to grid if physdims is None: @@ -356,10 +356,10 @@ def _create_lower_dim_grids_3d( e_pt = pts[:, edges[1, e]] nodes = _find_nodes_on_line(g_3d, nx, s_pt, e_pt) loc_coord = g_3d.nodes[:, nodes] - assert ( - loc_coord.shape[1] > 1 - ), "1d grid in intersection should span\ + assert loc_coord.shape[1] > 1, ( + "1d grid in intersection should span\ more than one node" + ) g = msh_2_grid.create_embedded_line_grid(loc_coord, nodes) g_1d.append(g) diff --git a/src/porepy/fracs/utils.py b/src/porepy/fracs/utils.py index cf6f91376e..5f8c77b343 100644 --- a/src/porepy/fracs/utils.py +++ b/src/porepy/fracs/utils.py @@ -1,5 +1,5 @@ """This module contains (frontend) utility functions related to fractures and their -meshing. """ +meshing.""" from __future__ import annotations diff --git a/src/porepy/geometry/intersections.py b/src/porepy/geometry/intersections.py index 7d388d4a78..06bca584db 100644 --- a/src/porepy/geometry/intersections.py +++ b/src/porepy/geometry/intersections.py @@ -2062,7 +2062,9 @@ def _min_max_coord(coord): is_ccw = np.array( [ pp.geometry_property_checks.is_ccw_polyline( - start[:, i], middle[:, i], end[:, i] # type:ignore + start[:, i], + middle[:, i], + end[:, i], # type:ignore ) for i in range(poly.shape[1]) # type:ignore ] diff --git a/src/porepy/geometry/map_geometry.py b/src/porepy/geometry/map_geometry.py index 06e984abad..452d42733f 100644 --- a/src/porepy/geometry/map_geometry.py +++ b/src/porepy/geometry/map_geometry.py @@ -10,7 +10,7 @@ def force_point_collinearity( - pts: np.ndarray[Any, np.dtype[np.float64]] + pts: np.ndarray[Any, np.dtype[np.float64]], ) -> np.ndarray[Any, np.dtype[np.float64]]: """Given a set of points, return them aligned on a line. @@ -555,7 +555,7 @@ def compute_normal( def compute_normals_1d( - pts: np.ndarray[Any, np.dtype[np.float64]] + pts: np.ndarray[Any, np.dtype[np.float64]], ) -> np.ndarray[Any, np.dtype[np.float64]]: """Compute the normals of a set of points aligned along a 1d line. diff --git a/src/porepy/grids/coarsening.py b/src/porepy/grids/coarsening.py index 69a91f9cb9..196190c8f2 100644 --- a/src/porepy/grids/coarsening.py +++ b/src/porepy/grids/coarsening.py @@ -64,9 +64,7 @@ def coarsen( if method_kwargs.get("if_seeds", False): seeds = generate_seeds(g) matrix = _tpfa_matrix(g) - partition = create_partition( - matrix, g, seeds=seeds, **method_kwargs - ) # type: ignore + partition = create_partition(matrix, g, seeds=seeds, **method_kwargs) # type: ignore else: raise ValueError(f"Undefined method `{method}` for coarsening algorithm.") diff --git a/src/porepy/grids/md_grid.py b/src/porepy/grids/md_grid.py index 9842d4f667..a6919793d1 100644 --- a/src/porepy/grids/md_grid.py +++ b/src/porepy/grids/md_grid.py @@ -976,7 +976,7 @@ def __repr__(self) -> str: for sd in self.subdomains(dim=dim): num_sd += 1 nc += sd.num_cells - s += f"{num_sd} grids of dimension {dim}" f" with in total {nc} cells\n" + s += f"{num_sd} grids of dimension {dim} with in total {nc} cells\n" if self.num_interfaces() > 0: for dim in range(self.dim_max(), self.dim_min(), -1): num_intf = 0 diff --git a/src/porepy/grids/mdg_generation.py b/src/porepy/grids/mdg_generation.py index 67fce4a0b1..6558057652 100644 --- a/src/porepy/grids/mdg_generation.py +++ b/src/porepy/grids/mdg_generation.py @@ -57,7 +57,7 @@ def _validate_args_types( def _validate_grid_type_value( - grid_type: Literal["simplex", "cartesian", "tensor_grid"] + grid_type: Literal["simplex", "cartesian", "tensor_grid"], ): """Validates grid_type value. diff --git a/src/porepy/grids/refinement.py b/src/porepy/grids/refinement.py index 6f94c941f9..f8fde8a7ca 100644 --- a/src/porepy/grids/refinement.py +++ b/src/porepy/grids/refinement.py @@ -577,9 +577,9 @@ def structured_refinement( data = np.ones(indices.size) coarse_fine = sps.csc_matrix((data, indices, indptr)) - assert ( - indices.size == g_ref.num_cells - ), "Every fine cell should be inside exactly one coarse cell" + assert indices.size == g_ref.num_cells, ( + "Every fine cell should be inside exactly one coarse cell" + ) return coarse_fine diff --git a/src/porepy/models/constitutive_laws.py b/src/porepy/models/constitutive_laws.py index 03f798c74d..d6437abead 100644 --- a/src/porepy/models/constitutive_laws.py +++ b/src/porepy/models/constitutive_laws.py @@ -467,7 +467,6 @@ def aperture(self, subdomains: list[pp.Grid]) -> pp.ad.Operator: class SecondOrderTensorUtils(pp.PorePyModel): - def isotropic_second_order_tensor( self, subdomains: list[pp.Grid], permeability: pp.ad.Operator ) -> pp.ad.Operator: @@ -3069,7 +3068,6 @@ def thermal_stress(self, subdomains: list[pp.Grid]) -> pp.ad.Operator: class ConstantSolidDensity(pp.PorePyModel): - def solid_density(self, subdomains: list[pp.Grid]) -> pp.ad.Scalar: """Constant solid density. @@ -3631,7 +3629,6 @@ def specific_storage(self, subdomains: list[pp.Grid]) -> pp.ad.Operator: class ConstantPorosity(pp.PorePyModel): - def porosity(self, subdomains: list[pp.Grid]) -> pp.ad.Operator: """Constant porosity [-]. diff --git a/src/porepy/models/fluid_property_library.py b/src/porepy/models/fluid_property_library.py index 0de36c21be..e660bc2fe6 100644 --- a/src/porepy/models/fluid_property_library.py +++ b/src/porepy/models/fluid_property_library.py @@ -1,4 +1,4 @@ -""""Module containing some constant heuristic fluid property implemenations. +""" "Module containing some constant heuristic fluid property implemenations. Most of the laws implemented here are meant for 1-phase, 1-component mixtures, using some fluid component stored in the fluid's reference component. diff --git a/src/porepy/models/geometry.py b/src/porepy/models/geometry.py index c43b0f022f..a13a010a8c 100644 --- a/src/porepy/models/geometry.py +++ b/src/porepy/models/geometry.py @@ -1,6 +1,4 @@ -"""Geometry definition for simulation setup. - -""" +"""Geometry definition for simulation setup.""" from __future__ import annotations diff --git a/src/porepy/models/mass_and_energy_balance.py b/src/porepy/models/mass_and_energy_balance.py index e7cec2e64f..332a0dfbb4 100644 --- a/src/porepy/models/mass_and_energy_balance.py +++ b/src/porepy/models/mass_and_energy_balance.py @@ -1,4 +1,4 @@ -"""Combine single-physics models into coupled mass and energy balance equations. """ +"""Combine single-physics models into coupled mass and energy balance equations.""" from __future__ import annotations diff --git a/src/porepy/models/poromechanics.py b/src/porepy/models/poromechanics.py index a283f42f31..33f8316345 100644 --- a/src/porepy/models/poromechanics.py +++ b/src/porepy/models/poromechanics.py @@ -169,9 +169,9 @@ def set_discretization_parameters(self) -> None: "scalar_vector_mappings", {} ) scalar_vector_mappings[self.darcy_keyword] = self.biot_tensor([sd]) - data[pp.PARAMETERS][self.stress_keyword][ - "scalar_vector_mappings" - ] = scalar_vector_mappings + data[pp.PARAMETERS][self.stress_keyword]["scalar_vector_mappings"] = ( + scalar_vector_mappings + ) def _is_nonlinear_problem(self) -> bool: """The coupled problem is nonlinear.""" diff --git a/src/porepy/models/run_models.py b/src/porepy/models/run_models.py index fecfaaed9b..d19c4424fc 100644 --- a/src/porepy/models/run_models.py +++ b/src/porepy/models/run_models.py @@ -1,4 +1,4 @@ -""" This module contains functions to run stationary and time-dependent models.""" +"""This module contains functions to run stationary and time-dependent models.""" from __future__ import annotations diff --git a/src/porepy/models/solution_strategy.py b/src/porepy/models/solution_strategy.py index 41b1e93548..853c0a6de9 100644 --- a/src/porepy/models/solution_strategy.py +++ b/src/porepy/models/solution_strategy.py @@ -287,9 +287,9 @@ def set_materials(self): dict[str, pp.Constants], self.params.get("material_constants", {}) ) # If the user provided material constants, assert they are in dictionary form - assert isinstance( - constants, dict - ), "model.params['material_constants'] must be a dictionary." + assert isinstance(constants, dict), ( + "model.params['material_constants'] must be a dictionary." + ) # Use standard models for fluid, solid and numerical constants if not provided. # Otherwise get the given constants. diff --git a/src/porepy/models/thermoporomechanics.py b/src/porepy/models/thermoporomechanics.py index b140483352..2490f98676 100644 --- a/src/porepy/models/thermoporomechanics.py +++ b/src/porepy/models/thermoporomechanics.py @@ -194,9 +194,9 @@ def set_discretization_parameters(self) -> None: self.solid_thermal_expansion_tensor([sd]) ) scalar_vector_mappings[self.darcy_keyword] = self.biot_tensor([sd]) - data[pp.PARAMETERS][self.stress_keyword][ - "scalar_vector_mappings" - ] = scalar_vector_mappings + data[pp.PARAMETERS][self.stress_keyword]["scalar_vector_mappings"] = ( + scalar_vector_mappings + ) def set_nonlinear_discretizations(self) -> None: """Collect discretizations for nonlinear terms.""" diff --git a/src/porepy/numerics/ad/__init__.py b/src/porepy/numerics/ad/__init__.py index d930125e59..7f1677d9c3 100644 --- a/src/porepy/numerics/ad/__init__.py +++ b/src/porepy/numerics/ad/__init__.py @@ -1,4 +1,4 @@ -""" Init file for all AD functionality. +"""Init file for all AD functionality. They should all be accessible through a calling >>> import porepy as pp diff --git a/src/porepy/numerics/ad/_ad_utils.py b/src/porepy/numerics/ad/_ad_utils.py index b17c43a39e..083f482c82 100644 --- a/src/porepy/numerics/ad/_ad_utils.py +++ b/src/porepy/numerics/ad/_ad_utils.py @@ -145,7 +145,6 @@ def wrap_discretization( # Loop over all identified terms, assign a MergedOperator to non-coupling terms, # while postponing the treatment of coupling terms. for discretization_key in discretization_term_key: - operators[discretization_key] = {} # Fetch all physics keywords associated with this discretization term. The diff --git a/src/porepy/numerics/ad/forward_mode.py b/src/porepy/numerics/ad/forward_mode.py index 2a65475d6a..b01058c544 100644 --- a/src/porepy/numerics/ad/forward_mode.py +++ b/src/porepy/numerics/ad/forward_mode.py @@ -1,5 +1,4 @@ -"""The module contains the data class for forward mode automatic differentiation. -""" +"""The module contains the data class for forward mode automatic differentiation.""" from __future__ import annotations diff --git a/src/porepy/numerics/ad/grid_operators.py b/src/porepy/numerics/ad/grid_operators.py index ce123476e5..db653f57e1 100644 --- a/src/porepy/numerics/ad/grid_operators.py +++ b/src/porepy/numerics/ad/grid_operators.py @@ -1,4 +1,4 @@ -""" Ad representation of grid-related quantities needed to write equations. The classes +"""Ad representation of grid-related quantities needed to write equations. The classes defined here are mainly wrappers that constructs Ad matrices based on grid information. """ diff --git a/src/porepy/numerics/ad/operator_functions.py b/src/porepy/numerics/ad/operator_functions.py index 7fb934788b..31941ebc2e 100644 --- a/src/porepy/numerics/ad/operator_functions.py +++ b/src/porepy/numerics/ad/operator_functions.py @@ -95,9 +95,9 @@ def __call__(self, *args: pp.ad.Operator) -> pp.ad.Operator: to make the numerical function available during parsing (see :meth:`parse`). """ - assert ( - len(args) > 0 - ), "Operator functions must be called with at least 1 argument." + assert len(args) > 0, ( + "Operator functions must be called with at least 1 argument." + ) op = Operator( name=f"{self.name}{[a.name for a in args]}", @@ -319,9 +319,9 @@ def get_values(self, *args: float | np.ndarray | AdArray) -> float | np.ndarray: return result.val if isinstance(result, AdArray) else result def get_jacobian(self, *args: float | np.ndarray | AdArray) -> sps.spmatrix: - assert any( - isinstance(a, AdArray) for a in args - ), "No Ad arrays passed as arguments." + assert any(isinstance(a, AdArray) for a in args), ( + "No Ad arrays passed as arguments." + ) result = self._func(*args) assert isinstance(result, AdArray) return result.jac diff --git a/src/porepy/numerics/ad/operators.py b/src/porepy/numerics/ad/operators.py index a2ae2e9328..b7e0b3064a 100644 --- a/src/porepy/numerics/ad/operators.py +++ b/src/porepy/numerics/ad/operators.py @@ -1,5 +1,4 @@ -""" Implementation of wrappers for Ad representations of several operators. -""" +"""Implementation of wrappers for Ad representations of several operators.""" from __future__ import annotations @@ -84,7 +83,6 @@ def _get_previous_time_or_iterate( # Else we are in the middle of the operator tree and need to go deeper, creating # copies along. else: - # Create new operator from the tree, with the only difference being the new # children, for which the recursion is invoked # NOTE copy takes care of references to original_operator and func @@ -366,9 +364,9 @@ def _parse_operator( return op # to continue, we must assert it is an actual, unparsed operator - assert isinstance( - op, Operator - ), f"Failure in parsing: Unsupported type in operor tree {type(op)}." + assert isinstance(op, Operator), ( + f"Failure in parsing: Unsupported type in operor tree {type(op)}." + ) # Case 2) Leaf operators or variables # NOTE Should MD variables really be leaves? @@ -1539,7 +1537,8 @@ def __init__(self, values: np.ndarray, name: Optional[str] = None) -> None: # TODO: Make readonly, see https://github.com/pmgbergen/porepy/issues/1214 self._hash_value: str = sha256( - self._values, usedforsecurity=False # type: ignore[arg-type] + self._values, + usedforsecurity=False, # type: ignore[arg-type] ).hexdigest() """String to uniquly identify the array.""" @@ -1793,7 +1792,6 @@ def __init__( domain: GridLike, tags: Optional[dict[str, Any]] = None, ) -> None: - # Variables are not supported on the boundary. if not isinstance(domain, (pp.Grid, pp.MortarGrid)): raise NotImplementedError( @@ -1982,22 +1980,22 @@ def __init__(self, variables: list[Variable]) -> None: # check assumptions if len(variables) > 0: - assert ( - len(set(time_indices)) == 1 - ), "Cannot create md-variable from variables at different time steps." + assert len(set(time_indices)) == 1, ( + "Cannot create md-variable from variables at different time steps." + ) # NOTE both must be unique for all sub-variables, to avoid md-variables # having sub-variables at different iterate states. # Both current value, and most recent previous iterate have iterate index 0, # hence the need to check the size of the current_iter set. - assert ( - len(set(iter_indices)) == 1 and len(set(current_iter)) == 1 - ), "Cannot create md-variable from variables at different iterates." - assert ( - len(set(names)) == 1 - ), "Cannot create md-variable from variables with different names." - assert len(set(domains)) == len( - domains - ), "Cannot create md-variable from variables with overlapping domains." + assert len(set(iter_indices)) == 1 and len(set(current_iter)) == 1, ( + "Cannot create md-variable from variables at different iterates." + ) + assert len(set(names)) == 1, ( + "Cannot create md-variable from variables with different names." + ) + assert len(set(domains)) == len(domains), ( + "Cannot create md-variable from variables with overlapping domains." + ) # Default values for empty md variable else: time_indices = [-1] diff --git a/src/porepy/numerics/ad/surrogate_operator.py b/src/porepy/numerics/ad/surrogate_operator.py index babd69c1dd..28f4f815d1 100644 --- a/src/porepy/numerics/ad/surrogate_operator.py +++ b/src/porepy/numerics/ad/surrogate_operator.py @@ -171,7 +171,6 @@ def __init__( domains: Sequence[pp.Grid] | Sequence[pp.MortarGrid], children: Sequence[pp.ad.Variable], ) -> None: - super().__init__( name=name, domains=domains, @@ -445,7 +444,6 @@ def __init__( dependencies: Sequence[Callable[[pp.GridLikeSequence], pp.ad.Variable]], dof_info: Optional[dict[pp.ad.equation_system.GridEntity, int]] = None, ) -> None: - if len(dependencies) == 0: raise ValueError("Surrogate operators must have dependencies.") diff --git a/src/porepy/numerics/discretization.py b/src/porepy/numerics/discretization.py index f41287e47b..9e8ae89ec9 100644 --- a/src/porepy/numerics/discretization.py +++ b/src/porepy/numerics/discretization.py @@ -1,4 +1,4 @@ -""" Module contains the abstract superclass for all discretizations.""" +"""Module contains the abstract superclass for all discretizations.""" import abc from typing import Dict, Union diff --git a/src/porepy/numerics/fracture_deformation/propagate_fracture.py b/src/porepy/numerics/fracture_deformation/propagate_fracture.py index 6278e5135f..baae01bac2 100644 --- a/src/porepy/numerics/fracture_deformation/propagate_fracture.py +++ b/src/porepy/numerics/fracture_deformation/propagate_fracture.py @@ -624,9 +624,9 @@ def _update_connectivity_fracture_grid( sd_primary.tags["domain_boundary_nodes"][fi], axis=0 ) sd_secondary.tags["tip_faces"][new_face_indices_l] = ~domain_boundary_faces - sd_secondary.tags["domain_boundary_faces"][ - new_face_indices_l - ] = domain_boundary_faces + sd_secondary.tags["domain_boundary_faces"][new_face_indices_l] = ( + domain_boundary_faces + ) # Expand array of face-nodes in sd_secondary all_faces_l = np.append(all_faces_l, faces_l[:, ~exist], axis=1) diff --git a/src/porepy/numerics/fv/biot.py b/src/porepy/numerics/fv/biot.py index ff1e12bdf9..3797647a5e 100644 --- a/src/porepy/numerics/fv/biot.py +++ b/src/porepy/numerics/fv/biot.py @@ -1,4 +1,4 @@ -""" Modules contains discretization of poro-elasticity by the multi-point stress +"""Modules contains discretization of poro-elasticity by the multi-point stress approximation. The discretization scheme is described in diff --git a/src/porepy/numerics/fv/fvutils.py b/src/porepy/numerics/fv/fvutils.py index 3ece21e5d0..e1c771fcd0 100644 --- a/src/porepy/numerics/fv/fvutils.py +++ b/src/porepy/numerics/fv/fvutils.py @@ -353,7 +353,7 @@ def find_active_indices( def parse_partition_arguments( - partition_arguments: Optional[dict[str, int]] = None + partition_arguments: Optional[dict[str, int]] = None, ) -> tuple[int | None, int | None]: """Parse arguments related to the splitting of discretization into subproblems. @@ -477,9 +477,13 @@ def subproblems( raise ValueError("Either max_memory or num_subproblems must be given") if num_part == 1: - yield sd, np.arange(sd.num_faces), np.arange(sd.num_cells), np.arange( - sd.num_cells - ), np.arange(sd.num_faces) + yield ( + sd, + np.arange(sd.num_faces), + np.arange(sd.num_cells), + np.arange(sd.num_cells), + np.arange(sd.num_faces), + ) else: # Since MPxA discretizations are based on interaction regions (cells in the dual diff --git a/src/porepy/numerics/fv/mpfa.py b/src/porepy/numerics/fv/mpfa.py index b3c977ddb3..7c19d68752 100644 --- a/src/porepy/numerics/fv/mpfa.py +++ b/src/porepy/numerics/fv/mpfa.py @@ -1,6 +1,4 @@ -"""Implementation of the multi-point flux approximation O-method. - -""" +"""Implementation of the multi-point flux approximation O-method.""" from __future__ import annotations @@ -1553,7 +1551,7 @@ def _create_bound_rhs( elif num_bound == 0: # all of them are empty neu_rob_dir_ind = neu_rob_ind else: - raise ValueError("Boundary values should be either Dirichlet or " "Neumann") + raise ValueError("Boundary values should be either Dirichlet or Neumann") num_subfno = subcell_topology.num_subfno_unique diff --git a/src/porepy/numerics/fv/tpsa.py b/src/porepy/numerics/fv/tpsa.py index c6be13ccee..7eda1b6db5 100644 --- a/src/porepy/numerics/fv/tpsa.py +++ b/src/porepy/numerics/fv/tpsa.py @@ -259,7 +259,6 @@ class Tpsa: """ def __init__(self, keyword: str) -> None: - self.keyword: str = keyword """Keyword used to identify the parameter dictionary.""" @@ -677,9 +676,7 @@ def discretize(self, sd: Grid, data: dict) -> None: ) + t_shear_rob # Contribution from Robin boundary conditions. ) - ).reshape( - (nd, nf), order="F" - ) # + ).reshape((nd, nf), order="F") # # Discretize the stress-displacement relation. stress, bound_stress = self._vector_laplace_matrices( diff --git a/src/porepy/numerics/linalg/__init__.py b/src/porepy/numerics/linalg/__init__.py index a9a2076fa1..3bc99d885b 100644 --- a/src/porepy/numerics/linalg/__init__.py +++ b/src/porepy/numerics/linalg/__init__.py @@ -1,2 +1 @@ -"""Directory is intended to contain various linear algebra modules. -""" +"""Directory is intended to contain various linear algebra modules.""" diff --git a/src/porepy/numerics/linalg/matrix_operations.py b/src/porepy/numerics/linalg/matrix_operations.py index 97d979ffaa..f972da8839 100644 --- a/src/porepy/numerics/linalg/matrix_operations.py +++ b/src/porepy/numerics/linalg/matrix_operations.py @@ -659,7 +659,6 @@ def invert_diagonal_blocks_numba(a: sps.csr_matrix, size: np.ndarray) -> np.ndar parallel=True, ) def inv_compiled_function(is_csr_q, data, indices, indptr, sz): - # Construction of simple data structures (low complexity) # Indices for block positions, flattened inverse block positions and nonzeros # Expanded block positions diff --git a/src/porepy/numerics/vem/__init__.py b/src/porepy/numerics/vem/__init__.py index 3c4716afa1..cc97d1ba15 100644 --- a/src/porepy/numerics/vem/__init__.py +++ b/src/porepy/numerics/vem/__init__.py @@ -1,2 +1 @@ -""" Implementation of methods related to the virtual element method. -""" +"""Implementation of methods related to the virtual element method.""" diff --git a/src/porepy/numerics/vem/hybrid.py b/src/porepy/numerics/vem/hybrid.py index a057599d39..c727ce8583 100644 --- a/src/porepy/numerics/vem/hybrid.py +++ b/src/porepy/numerics/vem/hybrid.py @@ -3,6 +3,7 @@ @author: fumagalli, alessio """ + import numpy as np import scipy.sparse as sps from numpy.linalg import solve diff --git a/src/porepy/params/data.py b/src/porepy/params/data.py index de839c3e13..ab7a986155 100644 --- a/src/porepy/params/data.py +++ b/src/porepy/params/data.py @@ -1,4 +1,4 @@ -r""" Contains class for storing data / parameters associated with a grid. +r"""Contains class for storing data / parameters associated with a grid. At present, the Parameters class is a simple wrapper around a dictionary. diff --git a/src/porepy/params/parameter_dictionaries.py b/src/porepy/params/parameter_dictionaries.py index 700f8e6c95..36114239d2 100644 --- a/src/porepy/params/parameter_dictionaries.py +++ b/src/porepy/params/parameter_dictionaries.py @@ -1,4 +1,4 @@ -""" Parameter dictionaries. +"""Parameter dictionaries. Here, we store various parameter dictionaries with "sensible" (typically unitary or zero) default values for the parameters required by the discretization objects. diff --git a/src/porepy/params/tensor.py b/src/porepy/params/tensor.py index f7895ec9a8..4510fb20a7 100644 --- a/src/porepy/params/tensor.py +++ b/src/porepy/params/tensor.py @@ -46,8 +46,7 @@ def __init__( if np.any(kxx < 0): raise ValueError( - "Tensor is not positive definite because of " - "components in x-direction" + "Tensor is not positive definite because of components in x-direction" ) perm[0, 0, ::] = kxx @@ -64,8 +63,7 @@ def __init__( # Onsager's principle - tensor should be positive definite if np.any((kxx * kyy - kxy * kxy) < 0): raise ValueError( - "Tensor is not positive definite because of " - "components in y-direction" + "Tensor is not positive definite because of components in y-direction" ) perm[1, 0, ::] = kxy @@ -92,8 +90,7 @@ def __init__( < 0 ): raise ValueError( - "Tensor is not positive definite because of " - "components in z-direction" + "Tensor is not positive definite because of components in z-direction" ) perm[2, 0, ::] = kxz diff --git a/src/porepy/utils/graph.py b/src/porepy/utils/graph.py index d046a8876b..bb5ebcd61a 100644 --- a/src/porepy/utils/graph.py +++ b/src/porepy/utils/graph.py @@ -47,7 +47,7 @@ def color_nodes(self): else: return raise RuntimeWarning( - "number of regions can not be greater than " "number of nodes" + "number of regions can not be greater than number of nodes" ) def bfs(self, start, color): diff --git a/src/porepy/utils/grid_utils.py b/src/porepy/utils/grid_utils.py index c8aeb47a10..5d33bde320 100644 --- a/src/porepy/utils/grid_utils.py +++ b/src/porepy/utils/grid_utils.py @@ -1,5 +1,4 @@ -"""Module contains various utility functions for working with grids. -""" +"""Module contains various utility functions for working with grids.""" import numpy as np import scipy.sparse as sps diff --git a/src/porepy/utils/interpolation_tables.py b/src/porepy/utils/interpolation_tables.py index 1a1839a101..670ee3f60a 100644 --- a/src/porepy/utils/interpolation_tables.py +++ b/src/porepy/utils/interpolation_tables.py @@ -1,4 +1,4 @@ -""" The module contains interpolation tables, intended for use in function +"""The module contains interpolation tables, intended for use in function evaluations. Specifically, the motivation is to facilitate the parametrization framework described in diff --git a/src/porepy/utils/mcolon.py b/src/porepy/utils/mcolon.py index 6f894261b4..7ba40f7ac8 100644 --- a/src/porepy/utils/mcolon.py +++ b/src/porepy/utils/mcolon.py @@ -1,4 +1,4 @@ -""" Efficient numpy.arange for arrays of start and end indices. +"""Efficient numpy.arange for arrays of start and end indices. Acknowledgements: The functions are a python translation of the corresponding matlab @@ -43,7 +43,7 @@ def mcolon(lo, hi): hi = hi * np.ones(lo.size, dtype=np.int64) if lo.size != hi.size: raise ValueError( - "Low and high should have same number of elements, " "or a single item " + "Low and high should have same number of elements, or a single item " ) i = hi >= lo + 1 diff --git a/src/porepy/utils/permutations.py b/src/porepy/utils/permutations.py index a6b40f39d5..98a3847545 100644 --- a/src/porepy/utils/permutations.py +++ b/src/porepy/utils/permutations.py @@ -1,5 +1,4 @@ -""" Utility function for permutation of numbers. -""" +"""Utility function for permutation of numbers.""" def multinary_permutations(base, length): diff --git a/src/porepy/utils/setmembership.py b/src/porepy/utils/setmembership.py index 4abe903102..d263d944b8 100644 --- a/src/porepy/utils/setmembership.py +++ b/src/porepy/utils/setmembership.py @@ -10,7 +10,9 @@ from scipy.spatial import KDTree -def unique_rows(data: np.ndarray[Any, np.dtype[np.float64]]) -> Tuple[ +def unique_rows( + data: np.ndarray[Any, np.dtype[np.float64]], +) -> Tuple[ np.ndarray[Any, np.dtype[np.float64]], np.ndarray[Any, np.dtype[np.int64]], np.ndarray[Any, np.dtype[np.int64]], diff --git a/src/porepy/utils/sort_points.py b/src/porepy/utils/sort_points.py index 504d0a10ac..273538dfce 100644 --- a/src/porepy/utils/sort_points.py +++ b/src/porepy/utils/sort_points.py @@ -1,5 +1,4 @@ -""" Functions to sort points and edges belonging to geometric objects. -""" +"""Functions to sort points and edges belonging to geometric objects.""" from __future__ import annotations diff --git a/src/porepy/viz/diagnostics_mixin.py b/src/porepy/viz/diagnostics_mixin.py index bf46470dad..e296441323 100644 --- a/src/porepy/viz/diagnostics_mixin.py +++ b/src/porepy/viz/diagnostics_mixin.py @@ -1,6 +1,4 @@ -"""Module for diagnostics of PorePy's models built on seaborn. - -""" +"""Module for diagnostics of PorePy's models built on seaborn.""" from __future__ import annotations From 1fe46879f1768186f622ef99b67e2ff596af8ef3 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Wed, 5 Feb 2025 15:30:37 +0000 Subject: [PATCH 02/21] STY: Prepare for linting with ruff --- .../applications/boundary_conditions/__init__.py | 2 ++ src/porepy/applications/test_utils/__init__.py | 11 +++++++++++ src/porepy/examples/__init__.py | 8 ++++++++ src/porepy/grids/mortar_grid.py | 2 +- 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/porepy/applications/boundary_conditions/__init__.py b/src/porepy/applications/boundary_conditions/__init__.py index 43ea7a9b9e..cf9b1ccbd6 100644 --- a/src/porepy/applications/boundary_conditions/__init__.py +++ b/src/porepy/applications/boundary_conditions/__init__.py @@ -1 +1,3 @@ from . import model_boundary_conditions + +__all__ = ["model_boundary_conditions"] diff --git a/src/porepy/applications/test_utils/__init__.py b/src/porepy/applications/test_utils/__init__.py index 80c72cf922..03df7e557b 100644 --- a/src/porepy/applications/test_utils/__init__.py +++ b/src/porepy/applications/test_utils/__init__.py @@ -15,3 +15,14 @@ reference_sparse_arrays, vtk, ) + +__all__ = [ + "arrays", + "common_xpfa_tests", + "grids", + "models", + "partial_discretization", + "reference_dense_arrays", + "reference_sparse_arrays", + "vtk", +] diff --git a/src/porepy/examples/__init__.py b/src/porepy/examples/__init__.py index 3ec1f4cce7..210f654a01 100644 --- a/src/porepy/examples/__init__.py +++ b/src/porepy/examples/__init__.py @@ -16,3 +16,11 @@ from .flow_benchmark_3d_case_3 import FlowBenchmark3dCase3Model from .mandel_biot import MandelExactSolution, MandelSolutionStrategy from .terzaghi_biot import TerzaghiExactSolution, TerzaghiSetup + +__all__ = [ + FlowBenchmark3dCase3Model, + MandelExactSolution, + MandelSolutionStrategy, + TerzaghiExactSolution, + TerzaghiSetup, +] diff --git a/src/porepy/grids/mortar_grid.py b/src/porepy/grids/mortar_grid.py index 7e9aff066e..afc71dec97 100644 --- a/src/porepy/grids/mortar_grid.py +++ b/src/porepy/grids/mortar_grid.py @@ -160,7 +160,7 @@ def __init__( """Nodes in the side grids with ``shape=(3, num_nodes)``.""" # Set projections - if not (primary_secondary is None): + if primary_secondary is not None: self._init_projections(primary_secondary, face_duplicate_ind) self._set_projections() From 0482cd7c4077b859b7d886086fa7ec4acf3f6840 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Wed, 5 Feb 2025 15:33:53 +0000 Subject: [PATCH 03/21] BLD: Migrating to a pyproject.toml setup file --- pyproject.toml | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000..be2fbf4608 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,77 @@ +[build-system] +requires = ["setuptools>=42", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "porepy" +version = "1.10.0" +description = "Simulation tool for fractured and deformable porous media" +readme = "Readme.md" +license = { text = "GPL" } +keywords = ["porous media simulation fractures deformable"] +maintainers = [ + { name = "Eirik Keilegavlen", email = "Eirik.Keilegavlen@uib.no" }, + { name = "Ivar Stefansson", email = "Ivar.Stefansson@uib.no" }, + { name = "Jakub Both", email = "Jakub.Both@uib.no" } +] +urls = { "Homepage" = "https://github.com/pmgbergen/porepy" } +classifiers = [ + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "License :: OSI Approved :: GNU General Public License (GPL)", + "Operating System :: OS Independent" +] +dependencies = [ + "future", + "gmsh", + "matplotlib < 3.11", + "meshio >= 5.0", + "networkx", + "numba >= 0.57", + "numpy", + "requests", + "scipy", + "seaborn", + "shapely", + "six", + "sympy", + "typing_extensions", + "deepdiff", + "mypy", + "pytest >= 4.6", + "pytest-cov", + "pytest-runner" +] + +[project.optional-dependencies] +testing = [ + "pytest >= 4.6", + "pytest-cov", + "pytest-runner" +] + +[tool.pytest.ini_options] +python_files = "tests/*.py" +addopts = "--cov=src/porepy --cov-report term-missing -p no:warnings" + +[tool.ruff.lint] +#max-line-length = 95 +ignore = [ + "F541", # f-string is missing placeholders + "E731", # do not assign a lambda expression, use a def + "E266", # too many leading '#' for block comment + "W605", # allow to use \dot + "E701", # Multiple statements on each line - this conflicts with black's preferences +] +exclude = [ + "src/porepy/__init__.py", + "src/porepy/numerics/ad/__init__.py", + "src/porepy/compositional/__init__.py" +] + +[tool.mypy] +warn_unused_configs = true +plugins = ["numpy.typing.mypy_plugin"] + +[tool.setuptools.packages.find] +where = ["src"] \ No newline at end of file From 5019bc4ca17de8c6ea7a04ac968c13be0913f26d Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 07:16:38 +0000 Subject: [PATCH 04/21] BLD: Migrate setup information to pyproject.toml --- pyproject.toml | 22 +++++++++++++++------- setup.py | 29 ++--------------------------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index be2fbf4608..9ea92b9776 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,6 +2,7 @@ requires = ["setuptools>=42", "wheel"] build-backend = "setuptools.build_meta" +# Project information. [project] name = "porepy" version = "1.10.0" @@ -30,6 +31,7 @@ dependencies = [ "numba >= 0.57", "numpy", "requests", + "ruff", "scipy", "seaborn", "shapely", @@ -50,18 +52,27 @@ testing = [ "pytest-runner" ] +# Information for the build system. +[tool.setuptools.packages.find] +where = ["src"] + +[tool.setuptools.package-data] +"porepy" = [ + "py.typed", + "applications/md_grids/gmsh_file_library/**/*.csv", + "applications/md_grids/gmsh_file_library/**/*.geo" +] + +# Testing. [tool.pytest.ini_options] python_files = "tests/*.py" addopts = "--cov=src/porepy --cov-report term-missing -p no:warnings" +# Static analysis. [tool.ruff.lint] -#max-line-length = 95 ignore = [ - "F541", # f-string is missing placeholders "E731", # do not assign a lambda expression, use a def "E266", # too many leading '#' for block comment - "W605", # allow to use \dot - "E701", # Multiple statements on each line - this conflicts with black's preferences ] exclude = [ "src/porepy/__init__.py", @@ -72,6 +83,3 @@ exclude = [ [tool.mypy] warn_unused_configs = true plugins = ["numpy.typing.mypy_plugin"] - -[tool.setuptools.packages.find] -where = ["src"] \ No newline at end of file diff --git a/setup.py b/setup.py index 8346773d17..b3e9a79cc3 100644 --- a/setup.py +++ b/setup.py @@ -1,30 +1,5 @@ """Set-up file for PorePy for installations usins ``pip install .``""" -from setuptools import find_packages, setup +from setuptools import setup -with open("requirements.txt") as f: - required = f.read().splitlines() - - -setup( - name="porepy", - url="https://github.com/pmgbergen/porepy", - version="1.10.0", - license="GPL", - keywords=["porous media simulation fractures deformable"], - install_requires=required, - description="Simulation tool for fractured and deformable porous media", - maintainer="Eirik Keilegavlen", - maintainer_email="Eirik.Keilegavlen@uib.no", - platforms=["Linux", "Windows", "Mac OS-X"], - package_data={ - "porepy": [ - "py.typed", - "applications/md_grids/gmsh_file_library/**/*.csv", - "applications/md_grids/gmsh_file_library/**/*.geo", - ], - }, - packages=find_packages("src"), - package_dir={"": "src"}, - zip_safe=False, -) +setup() From 72d40a17a22e095d429406f9e800066c488065f7 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 07:17:18 +0000 Subject: [PATCH 05/21] STY: Reformat f-strings without expressions They can be standard strings --- src/porepy/compositional/base.py | 2 +- src/porepy/numerics/ad/operators.py | 2 +- src/porepy/params/tensor.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/porepy/compositional/base.py b/src/porepy/compositional/base.py index fb1a7ba9e7..531b5211dd 100644 --- a/src/porepy/compositional/base.py +++ b/src/porepy/compositional/base.py @@ -256,7 +256,7 @@ def compound_molar_mass(self, domains: pp.SubdomainsOrBoundaries) -> pp.ad.Opera # fluid component. if not hasattr(pc, "molar_mass"): raise TypeError( - f"Cannot assemble compound molar mass: Active tracer of type" + "Cannot assemble compound molar mass: Active tracer of type" + f" {type(pc)} has no attribute `molar_mass`." ) else: diff --git a/src/porepy/numerics/ad/operators.py b/src/porepy/numerics/ad/operators.py index b7e0b3064a..566a4a036e 100644 --- a/src/porepy/numerics/ad/operators.py +++ b/src/porepy/numerics/ad/operators.py @@ -527,7 +527,7 @@ def _parse_operator( assert len(results) >= 1, "Operator functions must have at least 1 child." assert hasattr(op, "func"), ( f"Operators with operation {operation} must have a functional" - + f" representation `func` implemented as a callable member." + + " representation `func` implemented as a callable member." ) try: diff --git a/src/porepy/params/tensor.py b/src/porepy/params/tensor.py index 4510fb20a7..6ced3143f9 100644 --- a/src/porepy/params/tensor.py +++ b/src/porepy/params/tensor.py @@ -265,9 +265,9 @@ def __str__(self) -> str: # below acknowledges the full fourth-order nature of this tensor (as opposed to # the storage format in self.values, which joins two and two dimensions). if self.values.shape[:2] == (4, 4): - s += f"Each cell has a tensor of shape (2, 2, 2, 2)" + s += "Each cell has a tensor of shape (2, 2, 2, 2)" elif self.values.shape[:2] == (9, 9): - s += f"Each cell has a tensor of shape (3, 3, 3, 3)" + s += "Each cell has a tensor of shape (3, 3, 3, 3)" else: # In EK's understanding, this should never happen. Give a fair description # of the situation, and hope the user knows what is going on. From aed4bfd180f297a7138aa724954b0d51c5394403 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 07:57:56 +0000 Subject: [PATCH 06/21] BLD: Introduce ruff in static GH actions Also updated the install instruction after the move to pyproject.toml --- .github/workflows/run-static-checks.yml | 34 +++++++++++++++---------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/.github/workflows/run-static-checks.yml b/.github/workflows/run-static-checks.yml index a6a719bc48..ade278f77d 100644 --- a/.github/workflows/run-static-checks.yml +++ b/.github/workflows/run-static-checks.yml @@ -1,4 +1,4 @@ -# Run static tests for code quality: Isort, black, flake8, mypy. +# Run static tests for code quality: Isort, ruff (formatting and linting), mypy. name: Static tests @@ -83,28 +83,34 @@ jobs: path: mypy-cache-${{ matrix.python-version}} key: ${{ runner.os }}-mypy - # Install the requirements. Mypy needs this to access stubs for numpy etc. + # Install the dependencies, which is needed to make mypy happy. Unravelling of the + # second command: The expression in the angular brackets is a python command that + # fetches the dependencies section in pyproject.toml; this is then made available to + # pip via -r. Option --no-bulid-isolation makes pip not use an isolated environment + # for the install (hence the installed packages are sure to be available also after + # the build), while --no-deps will only install the specified packages (in this + # case, the dependencies of PorePy). + # + # Thanks, copilot! - name: Install requirements run: | pip install -U pip - # Install requirements, using eager updates to avoid stalled dependencies due to caching - # https://blog.allenai.org/python-caching-in-github-actions-e9452698e98d - pip install --upgrade --upgrade-strategy eager -r requirements.txt - pip freeze + pip install --no-build-isolation --no-deps -r <(python -c "import toml; print('\n'.join(toml.load('pyproject.toml')['project']['dependencies']))") - # Run black, isort, flake8, and mypy. - # Note that since these are static checks, we have not installed PorePy. - - name: black + # Run the various checks + - name: Ruff linting if: ${{ always() }} - run: black --check src + run: ruff check src - - name: isort + - name: Ruff formatting if: ${{always()}} - run: isort --check src + run: ruff formatter --check src - - name: flake8 + # EK note to self: Ruff may introduce sorting of imports in the future, if so, we + # we should use that instead of isort. + - name: isort if: ${{ always() }} - run: flake8 src + run: isort src - name: mypy if: ${{ always() }} From d3791c249e9b1c902b306f22bd575276ef55c8db Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 08:06:06 +0000 Subject: [PATCH 07/21] BLD: Split out development dependencies in pyproject.toml --- pyproject.toml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 9ea92b9776..c9000afeb9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -23,29 +23,28 @@ classifiers = [ "Operating System :: OS Independent" ] dependencies = [ + "deepdiff", "future", "gmsh", "matplotlib < 3.11", - "meshio >= 5.0", + "meshio", "networkx", - "numba >= 0.57", + "numba", "numpy", - "requests", - "ruff", "scipy", "seaborn", "shapely", "six", "sympy", "typing_extensions", - "deepdiff", - "mypy", - "pytest >= 4.6", - "pytest-cov", - "pytest-runner" ] [project.optional-dependencies] +development = [ + "isort", + "ruff", + "mypy" +] testing = [ "pytest >= 4.6", "pytest-cov", From 31660edb17e5109619c1eaab493be101ce50d5d8 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 08:14:13 +0000 Subject: [PATCH 08/21] BLD: Update GH actions installation of PorePy With pyproject.toml instead of requiremnets, the install is changed somewhat. --- .github/workflows/check_tutorials.yml | 15 ++++++--------- .github/workflows/run-pytest-all.yml | 23 ++++++----------------- .github/workflows/run-pytest.yml | 14 +++++--------- .github/workflows/run-static-checks.yml | 4 +++- 4 files changed, 20 insertions(+), 36 deletions(-) diff --git a/.github/workflows/check_tutorials.yml b/.github/workflows/check_tutorials.yml index f8b3ea3a28..3fa41bc1f7 100644 --- a/.github/workflows/check_tutorials.yml +++ b/.github/workflows/check_tutorials.yml @@ -65,22 +65,19 @@ jobs: sudo apt-get install libglu1-mesa libgeos-dev libffi-dev export LD_LIBRARY_PATH=/usr/local/lib64/:$LD_LIBRARY_PATH - - name: Install requirements + # Install the requirements, including the extras needed for testing, and PorePy + # itself. + - name: Install requirements and PorePy run: | pip install -U pip - # Install requirements, using eager updates to avoid stalled dependencies due to caching - # https://blog.allenai.org/python-caching-in-github-actions-e9452698e98d - pip install --upgrade --upgrade-strategy eager -r requirements.txt + pip install .[testing] + pip freeze + # Install jupyter - needed to run the tutorial notebooks. - name: Install jupyter run: | pip install jupyter - - name: Install PorePy - run: | - pip install . - pip freeze - - name: Check tutorials if: ${{always()}} run: pytest tests -m tutorials diff --git a/.github/workflows/run-pytest-all.yml b/.github/workflows/run-pytest-all.yml index 6a97e605c7..cce8658fba 100644 --- a/.github/workflows/run-pytest-all.yml +++ b/.github/workflows/run-pytest-all.yml @@ -56,29 +56,18 @@ jobs: sudo apt-get install libglu1-mesa libgeos-dev libffi-dev export LD_LIBRARY_PATH=/usr/local/lib64/:$LD_LIBRARY_PATH - - name: Install requirements + # Install the requirements, including the extras needed for testing, and PorePy + # itself. + - name: Install requirements and PorePy run: | pip install -U pip - # Install requirements, using eager updates to avoid stalled dependencies due to caching - # https://blog.allenai.org/python-caching-in-github-actions-e9452698e98d - pip install --upgrade --upgrade-strategy eager -r requirements.txt + pip install .[testing] + pip freeze - name: Install pypardiso run: | pip install pypardiso - - name: Install jupyter - run: | - pip install jupyter - - - name: Install PorePy - run: | - pip install . - pip freeze - - name: all tests if: ${{always()}} - run: pytest --run-skipped -m "not tutorials" - - - + run: pytest --run-skipped -m "not tutorials" \ No newline at end of file diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml index f74978d89d..09aef3f9ef 100644 --- a/.github/workflows/run-pytest.yml +++ b/.github/workflows/run-pytest.yml @@ -64,17 +64,13 @@ jobs: sudo apt-get install libglu1-mesa libgeos-dev libffi-dev export LD_LIBRARY_PATH=/usr/local/lib64/:$LD_LIBRARY_PATH - - name: Install requirements + # Install the requirements, including the extras needed for testing, and PorePy + # itself. + - name: Install requirements and PorePy run: | pip install -U pip - # Install requirements, using eager updates to avoid stalled dependencies due to caching - # https://blog.allenai.org/python-caching-in-github-actions-e9452698e98d - pip install --upgrade --upgrade-strategy eager -r requirements.txt - - - name: Install PorePy - run: | - pip install . - pip freeze + pip install .[testing] + pip freeze - name: Run tests if: ${{always()}} diff --git a/.github/workflows/run-static-checks.yml b/.github/workflows/run-static-checks.yml index ade278f77d..4222248a67 100644 --- a/.github/workflows/run-static-checks.yml +++ b/.github/workflows/run-static-checks.yml @@ -89,13 +89,15 @@ jobs: # pip via -r. Option --no-bulid-isolation makes pip not use an isolated environment # for the install (hence the installed packages are sure to be available also after # the build), while --no-deps will only install the specified packages (in this - # case, the dependencies of PorePy). + # case, the dependencies of PorePy). The third line similarly installs the + # development dependencies. # # Thanks, copilot! - name: Install requirements run: | pip install -U pip pip install --no-build-isolation --no-deps -r <(python -c "import toml; print('\n'.join(toml.load('pyproject.toml')['project']['dependencies']))") + pip install --no-build-isolation --no-deps -r <(python -c "import toml; print('\n'.join(toml.load('pyproject.toml')['project']['optional-dependencies']['development']))") # Run the various checks - name: Ruff linting From 8a62a50451e38ebbf8abc098ef29dbbe31927f49 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 08:14:44 +0000 Subject: [PATCH 09/21] BLD: Deleted old setup.cfg and requiremnets files These are superseeded by pyproject.toml --- requirements.txt | 19 ------------------- setup.cfg | 40 ---------------------------------------- 2 files changed, 59 deletions(-) delete mode 100644 requirements.txt delete mode 100644 setup.cfg diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index a1242cfe29..0000000000 --- a/requirements.txt +++ /dev/null @@ -1,19 +0,0 @@ -future -gmsh -matplotlib < 3.11 -meshio >= 5.0 -networkx -numba >= 0.57 -numpy -requests -scipy -seaborn -shapely -six -sympy -typing_extensions -deepdiff -mypy -pytest >= 4.6 -pytest-cov -pytest-runner diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index ab65e82880..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,40 +0,0 @@ -[metadata] -description-file = Readme.md - -[aliases] -test=pytest - -[tool:pytest] -python_files = tests/*.py -addopts = --cov=src/porepy --cov-report term-missing -p no:warnings - -[flake8] -max-line-length = 95 -ignore = - # F541: f-string is missing placeholders - F541, - # W503: line break before binary operator - W503, - # E731 do not assign a lambda expression, use a def - E731, - # E203 whitespace before ':' - E203, - # E266 too many leading '#' for block comment - E266, - # allow to use \dot - W605 - # Multiple statements on each line - this conflicts with black's preferences - E701 - E704 -exclude = - src/porepy/__init__.py, - src/porepy/numerics/ad/__init__.py, -per-file-ignores = - # F401: imported but unused on files __init__.py - __init__.py:F401 - # F403: from .module import *, ignore because of definition of __all__ - src/porepy/compositional/__init__.py:F403,F401 - -[mypy] -warn_unused_configs = True -plugins = numpy.typing.mypy_plugin From 57a99f5e27a0a35955c877ce1fe2c5516a2b12ff Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 10:04:00 +0000 Subject: [PATCH 10/21] BLD: Fixes of GH action files --- .github/workflows/check_tutorials.yml | 11 ++++------- .github/workflows/run-pytest-all.yml | 11 ++++------- .github/workflows/run-pytest.yml | 11 ++++------- .github/workflows/run-static-checks.yml | 10 ++++------ 4 files changed, 16 insertions(+), 27 deletions(-) diff --git a/.github/workflows/check_tutorials.yml b/.github/workflows/check_tutorials.yml index 3fa41bc1f7..be0e7e6477 100644 --- a/.github/workflows/check_tutorials.yml +++ b/.github/workflows/check_tutorials.yml @@ -37,10 +37,10 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Python ${{ matrix.python-version}} - uses: actions/setup-python@v3 + uses: actions/setup-python@v5 with: # Version range or exact version of a Python version to use, using SemVer's version range syntax. python-version: ${{ matrix.python-version}} @@ -50,14 +50,11 @@ jobs: # Cache pip dependencies # Source: https://github.com/actions/cache/blob/main/examples.md#python---pip - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 id: cache with: - # Cache the full python environment, this is more efficient than just caching pip - # https://blog.allenai.org/python-caching-in-github-actions-e9452698e98d path: ${{ env.pythonLocation }} - # Hash both ordinary requirements and those specific for developmnet. - key: ${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ hashFiles('**/requirements.txt', '**/requirements-dev.txt') }} + key: ${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }} - name: Install external libraries run: | diff --git a/.github/workflows/run-pytest-all.yml b/.github/workflows/run-pytest-all.yml index cce8658fba..6cec1f6f00 100644 --- a/.github/workflows/run-pytest-all.yml +++ b/.github/workflows/run-pytest-all.yml @@ -28,10 +28,10 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Python ${{ matrix.python-version}} - uses: actions/setup-python@v3 + uses: actions/setup-python@v5 with: # Version range or exact version of a Python version to use, using SemVer's version range syntax. python-version: ${{ matrix.python-version}} @@ -41,14 +41,11 @@ jobs: # Cache pip dependencies # Source: https://github.com/actions/cache/blob/main/examples.md#python---pip - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 id: cache with: - # Cache the full python environment, this is more efficient than just caching pip - # https://blog.allenai.org/python-caching-in-github-actions-e9452698e98d path: ${{ env.pythonLocation }} - # Hash requirements. - key: ${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ hashFiles('**/requirements.txt') }} + key: ${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }} - name: Install external libraries run: | diff --git a/.github/workflows/run-pytest.yml b/.github/workflows/run-pytest.yml index 09aef3f9ef..eaacc504db 100644 --- a/.github/workflows/run-pytest.yml +++ b/.github/workflows/run-pytest.yml @@ -36,10 +36,10 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Python ${{ matrix.python-version}} - uses: actions/setup-python@v3 + uses: actions/setup-python@v5 with: # Version range or exact version of a Python version to use, using SemVer's version range syntax. python-version: ${{ matrix.python-version}} @@ -49,14 +49,11 @@ jobs: # Cache pip dependencies # Source: https://github.com/actions/cache/blob/main/examples.md#python---pip - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 id: cache with: - # Cache the full python environment, this is more efficient than just caching pip - # https://blog.allenai.org/python-caching-in-github-actions-e9452698e98d path: ${{ env.pythonLocation }} - # Hash requirements. - key: ${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ hashFiles('**/requirements.txt') }} + key: ${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }} - name: Install external libraries run: | diff --git a/.github/workflows/run-static-checks.yml b/.github/workflows/run-static-checks.yml index 4222248a67..58dc20ad8c 100644 --- a/.github/workflows/run-static-checks.yml +++ b/.github/workflows/run-static-checks.yml @@ -55,7 +55,7 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it. - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Python ${{ matrix.python-version}} uses: actions/setup-python@v3 @@ -68,16 +68,14 @@ jobs: # Cache pip dependencies # Source: https://github.com/actions/cache/blob/main/examples.md#python---pip - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v5 id: cache with: - # Cache the full python environment, this is more efficient than just caching pip - # https://blog.allenai.org/python-caching-in-github-actions-e9452698e98d path: ${{ env.pythonLocation }} - key: ${{ env.pythonLocation }}-${{ hashFiles('setup.py') }}-${{ hashFiles('**/requirements.txt', '**/requirements-dev.txt') }} + key: ${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }} - name: Cache mypy - uses: actions/cache@v3 + uses: actions/cache@v4 id: cache-mypy with: path: mypy-cache-${{ matrix.python-version}} From b4ca5eacff25cb1c865da05cadbd91462aa606db Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 10:08:53 +0000 Subject: [PATCH 11/21] BLD: One more fix in GH action. Typo in last commit --- .github/workflows/run-static-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run-static-checks.yml b/.github/workflows/run-static-checks.yml index 58dc20ad8c..068005c5d9 100644 --- a/.github/workflows/run-static-checks.yml +++ b/.github/workflows/run-static-checks.yml @@ -68,7 +68,7 @@ jobs: # Cache pip dependencies # Source: https://github.com/actions/cache/blob/main/examples.md#python---pip - name: Cache dependencies - uses: actions/cache@v5 + uses: actions/cache@v4 id: cache with: path: ${{ env.pythonLocation }} From 9b31d4564650e0c3d799449cb666db9e6fc83fa8 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 10:15:18 +0000 Subject: [PATCH 12/21] BLD: Update to GH action static checks --- .github/workflows/run-static-checks.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/run-static-checks.yml b/.github/workflows/run-static-checks.yml index 068005c5d9..556b29958d 100644 --- a/.github/workflows/run-static-checks.yml +++ b/.github/workflows/run-static-checks.yml @@ -58,7 +58,7 @@ jobs: - uses: actions/checkout@v4 - name: Setup Python ${{ matrix.python-version}} - uses: actions/setup-python@v3 + uses: actions/setup-python@v5 with: # Version range or exact version of a Python version to use, using SemVer's version range syntax. python-version: ${{ matrix.python-version}} @@ -67,12 +67,12 @@ jobs: # Cache pip dependencies # Source: https://github.com/actions/cache/blob/main/examples.md#python---pip - - name: Cache dependencies - uses: actions/cache@v4 - id: cache - with: - path: ${{ env.pythonLocation }} - key: ${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }} + # - name: Cache dependencies + # uses: actions/cache@v4 + # id: cache + # with: + # path: ${{ env.pythonLocation }} + # key: ${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }} - name: Cache mypy uses: actions/cache@v4 From 85218529d2e3b12ed2cdd788e4cfeb9e589d023f Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 10:17:28 +0000 Subject: [PATCH 13/21] BLD: Update of static check GH action Toml must be available. --- .github/workflows/run-static-checks.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run-static-checks.yml b/.github/workflows/run-static-checks.yml index 556b29958d..46bb3d2955 100644 --- a/.github/workflows/run-static-checks.yml +++ b/.github/workflows/run-static-checks.yml @@ -94,6 +94,7 @@ jobs: - name: Install requirements run: | pip install -U pip + pip install toml pip install --no-build-isolation --no-deps -r <(python -c "import toml; print('\n'.join(toml.load('pyproject.toml')['project']['dependencies']))") pip install --no-build-isolation --no-deps -r <(python -c "import toml; print('\n'.join(toml.load('pyproject.toml')['project']['optional-dependencies']['development']))") From 74e4c184d97768e66f03f617b2e3362a8ce57aa4 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 10:25:01 +0000 Subject: [PATCH 14/21] BLD: Update to pyproject and GH action files --- .github/workflows/run-static-checks.yml | 2 +- pyproject.toml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/run-static-checks.yml b/.github/workflows/run-static-checks.yml index 46bb3d2955..9f6b19f5fb 100644 --- a/.github/workflows/run-static-checks.yml +++ b/.github/workflows/run-static-checks.yml @@ -105,7 +105,7 @@ jobs: - name: Ruff formatting if: ${{always()}} - run: ruff formatter --check src + run: ruff format --check src # EK note to self: Ruff may introduce sorting of imports in the future, if so, we # we should use that instead of isort. diff --git a/pyproject.toml b/pyproject.toml index c9000afeb9..469b0311e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,7 +43,8 @@ dependencies = [ development = [ "isort", "ruff", - "mypy" + "mypy", + "mypy-extensions" ] testing = [ "pytest >= 4.6", From 5d7f8d67dba2f02bb73e1f498fbc037a246c23d4 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 10:42:25 +0000 Subject: [PATCH 15/21] STY: Mypy errors No idea what the issue really is. --- src/porepy/examples/__init__.py | 10 +++++----- src/porepy/fracs/fracture_network.py | 8 ++++---- src/porepy/geometry/intersections.py | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/porepy/examples/__init__.py b/src/porepy/examples/__init__.py index 210f654a01..bdee8d8c92 100644 --- a/src/porepy/examples/__init__.py +++ b/src/porepy/examples/__init__.py @@ -18,9 +18,9 @@ from .terzaghi_biot import TerzaghiExactSolution, TerzaghiSetup __all__ = [ - FlowBenchmark3dCase3Model, - MandelExactSolution, - MandelSolutionStrategy, - TerzaghiExactSolution, - TerzaghiSetup, + "FlowBenchmark3dCase3Model", + "MandelExactSolution", + "MandelSolutionStrategy", + "TerzaghiExactSolution", + "TerzaghiSetup", ] diff --git a/src/porepy/fracs/fracture_network.py b/src/porepy/fracs/fracture_network.py index 63a70050ae..57c879844a 100644 --- a/src/porepy/fracs/fracture_network.py +++ b/src/porepy/fracs/fracture_network.py @@ -6,14 +6,14 @@ from __future__ import annotations import warnings -from typing import List, Optional, Union +from typing import Optional, Union, cast import porepy as pp from porepy.fracs.fracture_network_2d import FractureNetwork2d from porepy.fracs.fracture_network_3d import FractureNetwork3d # Custom typings -FractureList = Union[List[pp.LineFracture], List[pp.PlaneFracture]] +FractureList = Union[list[pp.LineFracture], list[pp.PlaneFracture]] FractureNetwork = Union[FractureNetwork2d, FractureNetwork3d] @@ -127,14 +127,14 @@ def create_fracture_network( # check above, it is safe to ignore the argument type if dim == 2: fracture_network_2d = FractureNetwork2d( - fractures=fracs, + fractures=cast(list[pp.LineFracture], fracs), domain=domain, tol=tol, # type: ignore[arg-type] ) return fracture_network_2d else: fracture_network_3d = FractureNetwork3d( - fractures=fracs, # type: ignore[arg-type] + fractures=cast(list[pp.PlaneFracture], fracs), domain=domain, tol=tol, run_checks=run_checks, diff --git a/src/porepy/geometry/intersections.py b/src/porepy/geometry/intersections.py index 06bca584db..8d53e79e08 100644 --- a/src/porepy/geometry/intersections.py +++ b/src/porepy/geometry/intersections.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging -from typing import Any, Optional, Union +from typing import Any, Optional, Union, cast import numpy as np import scipy.sparse as sps @@ -2062,8 +2062,8 @@ def _min_max_coord(coord): is_ccw = np.array( [ pp.geometry_property_checks.is_ccw_polyline( - start[:, i], - middle[:, i], + start[:, i], # type: ignore + middle[:, i], # type: ignore end[:, i], # type:ignore ) for i in range(poly.shape[1]) # type:ignore From 2ac81f42bfa9831cafd0cfe0472c06e1a5a690a1 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 10:42:54 +0000 Subject: [PATCH 16/21] BLD: Update GH static check action --- .github/workflows/run-static-checks.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/run-static-checks.yml b/.github/workflows/run-static-checks.yml index 9f6b19f5fb..6c5a55f779 100644 --- a/.github/workflows/run-static-checks.yml +++ b/.github/workflows/run-static-checks.yml @@ -67,12 +67,12 @@ jobs: # Cache pip dependencies # Source: https://github.com/actions/cache/blob/main/examples.md#python---pip - # - name: Cache dependencies - # uses: actions/cache@v4 - # id: cache - # with: - # path: ${{ env.pythonLocation }} - # key: ${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }} + - name: Cache dependencies + uses: actions/cache@v4 + id: cache + with: + path: ${{ env.pythonLocation }} + key: ${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }} - name: Cache mypy uses: actions/cache@v4 @@ -97,6 +97,7 @@ jobs: pip install toml pip install --no-build-isolation --no-deps -r <(python -c "import toml; print('\n'.join(toml.load('pyproject.toml')['project']['dependencies']))") pip install --no-build-isolation --no-deps -r <(python -c "import toml; print('\n'.join(toml.load('pyproject.toml')['project']['optional-dependencies']['development']))") + pip freeze # Run the various checks - name: Ruff linting From 3e55333af7507d24034b7d6600704d5085224e1d Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 10:45:21 +0000 Subject: [PATCH 17/21] STY: Remove unused import --- src/porepy/geometry/intersections.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/porepy/geometry/intersections.py b/src/porepy/geometry/intersections.py index 8d53e79e08..c3e4073ba3 100644 --- a/src/porepy/geometry/intersections.py +++ b/src/porepy/geometry/intersections.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging -from typing import Any, Optional, Union, cast +from typing import Any, Optional, Union import numpy as np import scipy.sparse as sps From 4549b03b2f792ec8043248d00c04a047b7c9d90c Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Thu, 6 Feb 2025 16:48:18 +0100 Subject: [PATCH 18/21] Apply suggestions from code review Co-authored-by: Ivar Stefansson --- .github/workflows/run-static-checks.yml | 2 +- src/porepy/fracs/meshing.py | 2 +- src/porepy/fracs/split_grid.py | 2 +- src/porepy/fracs/structured.py | 2 +- src/porepy/models/fluid_property_library.py | 2 +- src/porepy/numerics/fv/tpsa.py | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/run-static-checks.yml b/.github/workflows/run-static-checks.yml index 6c5a55f779..6695b84904 100644 --- a/.github/workflows/run-static-checks.yml +++ b/.github/workflows/run-static-checks.yml @@ -109,7 +109,7 @@ jobs: run: ruff format --check src # EK note to self: Ruff may introduce sorting of imports in the future, if so, we - # we should use that instead of isort. + # should use that instead of isort. - name: isort if: ${{ always() }} run: isort src diff --git a/src/porepy/fracs/meshing.py b/src/porepy/fracs/meshing.py index 2fb9c4cbc0..50ef808f07 100644 --- a/src/porepy/fracs/meshing.py +++ b/src/porepy/fracs/meshing.py @@ -240,7 +240,7 @@ def _tag_faces(grids, check_highest_dim=True): # Assume only one grid of highest dimension if check_highest_dim: - assert len(grids[0]) == 1, "Must be exactly1 grid of dim: " + str(len(grids)) + assert len(grids[0]) == 1, "There must be exactly 1 grid of dim: " + str(len(grids)) for g_h in np.atleast_1d(grids[0]): bnd_faces = g_h.get_all_boundary_faces() diff --git a/src/porepy/fracs/split_grid.py b/src/porepy/fracs/split_grid.py index 20386f8c89..0df261a9a3 100644 --- a/src/porepy/fracs/split_grid.py +++ b/src/porepy/fracs/split_grid.py @@ -558,7 +558,7 @@ def update_cell_connectivity( # domain. Check that each face added two cells: if sum(left_cell) * 2 != left_cell.size: raise ValueError( - "Fractures must either beon boundary or completely inside domain" + "Fractures must either be on boundary or completely inside domain" ) # We create a cell_faces mapping for the new faces. This will be added on the end diff --git a/src/porepy/fracs/structured.py b/src/porepy/fracs/structured.py index 083c8bf62f..d06c58257c 100644 --- a/src/porepy/fracs/structured.py +++ b/src/porepy/fracs/structured.py @@ -214,7 +214,7 @@ def _create_lower_dim_grids_3d( is_xz_frac = np.allclose(f[1, 0], f[1]) is_yz_frac = np.allclose(f[0, 0], f[0]) assert is_xy_frac + is_xz_frac + is_yz_frac == 1, ( - "Fracture must align to x-, y- or z-axis" + "Fracture must align to x-, y- or z-axis." ) # snap to grid diff --git a/src/porepy/models/fluid_property_library.py b/src/porepy/models/fluid_property_library.py index e660bc2fe6..a468239f00 100644 --- a/src/porepy/models/fluid_property_library.py +++ b/src/porepy/models/fluid_property_library.py @@ -1,4 +1,4 @@ -""" "Module containing some constant heuristic fluid property implemenations. +"""Module containing some constant heuristic fluid property implemenations. Most of the laws implemented here are meant for 1-phase, 1-component mixtures, using some fluid component stored in the fluid's reference component. diff --git a/src/porepy/numerics/fv/tpsa.py b/src/porepy/numerics/fv/tpsa.py index 7eda1b6db5..1c5a7a4e01 100644 --- a/src/porepy/numerics/fv/tpsa.py +++ b/src/porepy/numerics/fv/tpsa.py @@ -676,7 +676,7 @@ def discretize(self, sd: Grid, data: dict) -> None: ) + t_shear_rob # Contribution from Robin boundary conditions. ) - ).reshape((nd, nf), order="F") # + ).reshape((nd, nf), order="F") # Discretize the stress-displacement relation. stress, bound_stress = self._vector_laplace_matrices( From c559ec3afd5d02390fa850f43ec3c75dc26433e4 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Fri, 7 Feb 2025 10:06:41 +0000 Subject: [PATCH 19/21] STY: Ruff formatting --- src/porepy/fracs/meshing.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/porepy/fracs/meshing.py b/src/porepy/fracs/meshing.py index 50ef808f07..3bb67eb1b6 100644 --- a/src/porepy/fracs/meshing.py +++ b/src/porepy/fracs/meshing.py @@ -240,7 +240,9 @@ def _tag_faces(grids, check_highest_dim=True): # Assume only one grid of highest dimension if check_highest_dim: - assert len(grids[0]) == 1, "There must be exactly 1 grid of dim: " + str(len(grids)) + assert len(grids[0]) == 1, "There must be exactly 1 grid of dim: " + str( + len(grids) + ) for g_h in np.atleast_1d(grids[0]): bnd_faces = g_h.get_all_boundary_faces() From 24b485c7ef60bb57f7a9f9004b278b3e653a88d4 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Fri, 7 Feb 2025 10:10:09 +0000 Subject: [PATCH 20/21] DOC: Update Readme, badges for tests --- Readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 288711c4da..656401eee1 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,7 @@ ![Pytest](https://github.com/pmgbergen/porepy/actions/workflows/run-pytest.yml/badge.svg) ![Pytest including slow](https://github.com/pmgbergen/porepy/actions/workflows/run-pytest-all.yml/badge.svg) -![Mypy, black, isort, flake8](https://github.com/pmgbergen/porepy/actions/workflows/run-static-checks.yml/badge.svg) +![Mypy, ruff, isort](https://github.com/pmgbergen/porepy/actions/workflows/run-static-checks.yml/badge.svg) +![Tutorials](https://github.com/pmgbergen/porepy/actions/workflows/check_tutorials.yml/badge.svg) [![DOI](https://zenodo.org/badge/89228838.svg)](https://zenodo.org/badge/latestdoi/89228838) [![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0) From ed15e8d1e3424c1301034b8c86fab2ae623b1315 Mon Sep 17 00:00:00 2001 From: Eirik Keilegavlen Date: Wed, 12 Feb 2025 12:09:41 +0000 Subject: [PATCH 21/21] BLD: Limit numpy version to <2.2 to avoid mypy issues --- pyproject.toml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 469b0311e2..495817cc43 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ dependencies = [ "meshio", "networkx", "numba", - "numpy", + "numpy < 2.2", "scipy", "seaborn", "shapely", @@ -79,7 +79,3 @@ exclude = [ "src/porepy/numerics/ad/__init__.py", "src/porepy/compositional/__init__.py" ] - -[tool.mypy] -warn_unused_configs = true -plugins = ["numpy.typing.mypy_plugin"]