Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extending fluid concept to fit CF & Standard formulations #1244

Open
wants to merge 55 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
3f80872
MOD: Renaming classes and methods for compatibility with modelling fr…
vlipovac Oct 17, 2024
8fffb9b
MOD: Material constants are now data classes replacing chemical species.
vlipovac Oct 17, 2024
5b9e0af
MOD: Make hashable dict for material constants ordered.
vlipovac Oct 18, 2024
014fbf5
MIN: Moving material constants to porepy.compositional.materials
vlipovac Oct 18, 2024
559a4b3
TEST: Adapting tests to new signature of material constants.
vlipovac Oct 18, 2024
87437a8
MOD: changing solution strategy to create a 1-phase, 1-component flui…
vlipovac Oct 18, 2024
3fec45b
MIN: Import and instantiation issues after change in material constants
vlipovac Oct 18, 2024
4b93858
MOD: Adapting usage of SolidConstants throughout package.
vlipovac Oct 18, 2024
0fce4f1
MOD: moving all functionality from chem_species.py to materials.py an…
vlipovac Oct 19, 2024
32a768b
MOD: Adapted usage of FluidConstants to recent changes.
vlipovac Oct 19, 2024
3dc1964
Merge branch 'develop' into fluid_concep
vlipovac Oct 19, 2024
349d5d0
MIN: Removing some unused mixin annotations.
vlipovac Oct 20, 2024
c07a4d8
MOD: Adapting some remaining, untyped usage of fluid and solid consta…
vlipovac Oct 20, 2024
c72012d
MOD: Refactor fluid constitutive laws to general fluid.
vlipovac Oct 21, 2024
e2c6c7f
MIN: Changing argument names for fluid property function to match pp …
vlipovac Oct 21, 2024
8bd3179
MIN: Shorten namespace of some objects in pp.compositional to pp.*
vlipovac Oct 21, 2024
7c91748
MOD: Adding FluidMixin to base models.
vlipovac Oct 21, 2024
18a035e
TEST: All tests pass now.
vlipovac Oct 21, 2024
3ec6590
STY: mypy, flake8, isort, black
vlipovac Oct 21, 2024
1b1b78c
Merge branch 'develop' into fluid_concept
vlipovac Oct 23, 2024
4b719c4
Merge branch 'develop' into fluid_concept
vlipovac Oct 23, 2024
8100f32
Apply suggestions from code review
vlipovac Oct 23, 2024
61c300c
Applying minor changes from review.
vlipovac Oct 24, 2024
dfbc7ba
Porepy Model Protocol (#1234)
Yuriyzabegaev Oct 24, 2024
3275229
MOD: transferring conver_units to Units class (issue 1247)
vlipovac Oct 25, 2024
01cfabd
MOD: Renaming classes and methods for compatibility with modelling fr…
vlipovac Oct 17, 2024
6648647
MOD: Material constants are now data classes replacing chemical species.
vlipovac Oct 17, 2024
0bf2b73
MOD: Make hashable dict for material constants ordered.
vlipovac Oct 18, 2024
8f0f8e3
MIN: Moving material constants to porepy.compositional.materials
vlipovac Oct 18, 2024
ccc35e1
TEST: Adapting tests to new signature of material constants.
vlipovac Oct 18, 2024
9855184
MOD: changing solution strategy to create a 1-phase, 1-component flui…
vlipovac Oct 18, 2024
a0c0721
MIN: Import and instantiation issues after change in material constants
vlipovac Oct 18, 2024
fc900d9
MOD: Adapting usage of SolidConstants throughout package.
vlipovac Oct 18, 2024
5ad1ef1
MOD: moving all functionality from chem_species.py to materials.py an…
vlipovac Oct 19, 2024
a182cbe
MOD: Adapted usage of FluidConstants to recent changes.
vlipovac Oct 19, 2024
bd8aa16
MOD: Adapting some remaining, untyped usage of fluid and solid consta…
vlipovac Oct 20, 2024
9f2c380
MOD: Refactor fluid constitutive laws to general fluid.
vlipovac Oct 21, 2024
ff53f37
MIN: Changing argument names for fluid property function to match pp …
vlipovac Oct 21, 2024
95a08b7
MIN: Shorten namespace of some objects in pp.compositional to pp.*
vlipovac Oct 21, 2024
ca91c68
MOD: Adding FluidMixin to base models.
vlipovac Oct 21, 2024
38a395d
TEST: All tests pass now.
vlipovac Oct 21, 2024
d0c115c
STY: mypy, flake8, isort, black
vlipovac Oct 21, 2024
eaa2c77
Apply suggestions from code review
vlipovac Oct 23, 2024
94bf9c6
Applying minor changes from review.
vlipovac Oct 24, 2024
7fe5a2a
MOD: transferring conver_units to Units class (issue 1247)
vlipovac Oct 25, 2024
5c043d5
ENH: Introducing the FluidProtocol into the base PorePyModel
vlipovac Oct 25, 2024
b0e7117
FIX: Lost changes after rebase onto develop (with protocols).
vlipovac Oct 25, 2024
4460b2f
Mergde 'origin/fluid_concept' into fluid_concept.
vlipovac Oct 25, 2024
b61a416
MIN: Docs of fluid protocol.
vlipovac Oct 25, 2024
5f62371
MIN: Docs in fluid protocol
vlipovac Oct 25, 2024
b6dc203
STY: flake8, black
vlipovac Oct 25, 2024
495df0e
TEST: All tests pass now.
vlipovac Oct 25, 2024
8d6ec7c
testing
vlipovac Oct 25, 2024
da986bf
FIX: Inconsistent assignment of constructor in porepy models.
vlipovac Oct 25, 2024
a2a6c4f
MIN: Improving docs and clean-up.
vlipovac Oct 25, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions src/porepy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,18 +176,22 @@
from porepy.models.boundary_condition import BoundaryConditionMixin
from porepy.models.geometry import ModelGeometry
from porepy.models.units import Units
from porepy.models.material_constants import (
FluidConstants,
SolidConstants,
MaterialConstants,
)


from porepy.viz.data_saving_model_mixin import DataSavingMixin
from porepy.viz.diagnostics_mixin import DiagnosticsMixin
from porepy.models.solution_strategy import SolutionStrategy
from porepy.models import constitutive_laws

# composite subpackage
from . import compositional
from porepy.compositional.materials import (
FluidConstants,
SolidConstants,
MaterialConstants,
)
from porepy.compositional.base import Component, Phase, Fluid
from porepy.compositional.compositional_mixins import CompositionalVariables, FluidMixin

# "Primary" models
from porepy.models import fluid_mass_balance, momentum_balance

Expand Down Expand Up @@ -233,6 +237,3 @@
from porepy.applications.boundary_conditions import model_boundary_conditions
from porepy.applications import test_utils
from porepy import applications

# composite subpackage
from . import compositional
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from __future__ import annotations

import warnings
from typing import Any

import numpy as np

Expand All @@ -20,8 +19,6 @@ class BoundaryConditionsMassDirWestEast(pp.BoundaryConditionMixin):

"""

fluid: pp.FluidConstants

def bc_type_darcy_flux(self, sd: pp.Grid) -> pp.BoundaryCondition:
"""Boundary condition type for Darcy flux.

Expand Down Expand Up @@ -54,7 +51,9 @@ def bc_values_pressure(self, boundary_grid: pp.BoundaryGrid) -> np.ndarray:
"""
domain_sides = self.domain_boundary_sides(boundary_grid)
values = np.zeros(boundary_grid.num_cells)
values[domain_sides.west + domain_sides.east] = self.fluid.pressure()
values[domain_sides.west + domain_sides.east] = (
self.fluid.reference_component.pressure
)
return values

def bc_type_fluid_flux(self, sd: pp.Grid) -> pp.BoundaryCondition:
Expand Down Expand Up @@ -84,8 +83,6 @@ class BoundaryConditionsMassDirNorthSouth(pp.BoundaryConditionMixin):

"""

fluid: pp.FluidConstants

def bc_type_darcy_flux(self, sd: pp.Grid) -> pp.BoundaryCondition:
"""Boundary condition type for Darcy flux.

Expand Down Expand Up @@ -118,7 +115,9 @@ def bc_values_pressure(self, boundary_grid: pp.BoundaryGrid) -> np.ndarray:
"""
domain_sides = self.domain_boundary_sides(boundary_grid)
values = np.zeros(boundary_grid.num_cells)
values[domain_sides.north + domain_sides.south] = self.fluid.pressure()
values[domain_sides.north + domain_sides.south] = (
self.fluid.reference_component.pressure
)
return values

def bc_type_fluid_flux(self, sd: pp.Grid) -> pp.BoundaryCondition:
Expand Down Expand Up @@ -190,15 +189,6 @@ class BoundaryConditionsMechanicsDirNorthSouth(pp.BoundaryConditionMixin):

"""

params: dict[str, Any]
"""Model parameters."""
solid: pp.SolidConstants
"""Solid parameters."""
fluid: pp.FluidConstants
"""Fluid parameters."""
nd: int
"""Number of dimensions."""

def bc_type_mechanics(self, sd: pp.Grid) -> pp.BoundaryConditionVectorial:
"""Boundary condition type for mechanics.

Expand Down Expand Up @@ -251,8 +241,8 @@ def bc_values_displacement(self, boundary_grid: pp.BoundaryGrid) -> np.ndarray:
u_s = np.tile(
self.params.get("u_south", np.zeros(self.nd)), (boundary_grid.num_cells, 1)
).T
values[:, sides.north] = self.solid.convert_units(u_n, "m")[:, sides.north]
values[:, sides.south] = self.solid.convert_units(u_s, "m")[:, sides.south]
values[:, sides.north] = self.units.convert_units(u_n, "m")[:, sides.north]
values[:, sides.south] = self.units.convert_units(u_s, "m")[:, sides.south]
return values.ravel("F")


Expand All @@ -266,8 +256,8 @@ class TimeDependentMechanicalBCsDirNorthSouth(BoundaryConditionsMechanicsDirNort
def bc_values_displacement(self, boundary_grid: pp.BoundaryGrid) -> np.ndarray:
"""Displacement values.

Initial value is u_y = self.solid.fracture_gap() +
self.solid.maximum_elastic_fracture_opening() at north boundary. Adding it on
Initial value is u_y = self.solid.fracture_gap +
self.solid.maximum_elastic_fracture_opening at north boundary. Adding it on
the boundary ensures a stress-free initial state, as it compensates for those
two values corresponding to zero traction contact according to the class
:class:`~porepy.models.constitutive_laws.FractureGap`. For positive times,
Expand All @@ -287,8 +277,7 @@ def bc_values_displacement(self, boundary_grid: pp.BoundaryGrid) -> np.ndarray:
# Add fracture width on top if there is a fracture.
if len(self.mdg.subdomains()) > 1:
frac_val = (
self.solid.fracture_gap()
+ self.solid.maximum_elastic_fracture_opening()
self.solid.fracture_gap + self.solid.maximum_elastic_fracture_opening
)
else:
frac_val = 0
Expand Down
49 changes: 8 additions & 41 deletions src/porepy/applications/md_grids/model_geometries.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from . import domains, fracture_sets


class SquareDomainOrthogonalFractures:
class SquareDomainOrthogonalFractures(pp.ModelGeometry):
"""Create a mixed-dimensional grid for a square domain with up to two
orthogonal fractures.

Expand All @@ -16,21 +16,6 @@ class SquareDomainOrthogonalFractures:

"""

params: dict
"""Parameters for the model geometry. Entries relevant for this mixin are:
- domain_size: The side length of the square domain.
- fracture_indices: List of indices of fractures to be included in the grid.

"""
units: pp.Units
"""Units for the model geometry."""
solid: pp.SolidConstants
"""Solid constant object that takes care of scaling of solid-related quantities.
Normally, this is set by a mixin of instance
:class:`~porepy.models.solution_strategy.SolutionStrategy`.

"""

@property
def domain_size(self) -> pp.number:
"""Return the side length of the square domain.
Expand All @@ -40,7 +25,7 @@ def domain_size(self) -> pp.number:

"""
# Scale by length unit.
return self.solid.convert_units(self.params.get("domain_size", 1.0), "m")
return self.units.convert_units(self.params.get("domain_size", 1.0), "m")

def set_fractures(self) -> None:
"""Assigns 0 to 2 fractures to the domain.
Expand All @@ -67,7 +52,7 @@ def set_domain(self) -> None:
self._domain = domains.nd_cube_domain(2, self.domain_size)


class CubeDomainOrthogonalFractures:
class CubeDomainOrthogonalFractures(pp.ModelGeometry):
"""Create a mixed-dimensional grid for a cube domain with up to three
orthogonal fractures.

Expand All @@ -76,26 +61,11 @@ class CubeDomainOrthogonalFractures:

"""

params: dict
"""Parameters for the model geometry. Entries relevant for this mixin are:
- domain_size: The side length of the cube domain.
- fracture_indices: List of indices of fractures to be included in the grid.

"""
units: pp.Units
"""Units for the model geometry."""
solid: pp.SolidConstants
"""Solid constant object that takes care of scaling of solid-related quantities.
Normally, this is set by a mixin of instance
:class:`~porepy.models.solution_strategy.SolutionStrategy`.

"""

@property
def domain_size(self) -> pp.number:
"""Return the side length of the cube domain."""
# Scale by length unit.
return self.solid.convert_units(self.params.get("domain_size", 1.0), "m")
return self.units.convert_units(self.params.get("domain_size", 1.0), "m")

def set_fractures(self) -> None:
"""Assigns 0 to 3 fractures."""
Expand All @@ -120,12 +90,9 @@ class RectangularDomainThreeFractures(pp.ModelGeometry):

"""

params: dict
"""Parameters for the model."""

def set_fractures(self) -> None:
# Length scale:
ls = self.solid.convert_units(1, "m")
ls = self.units.convert_units(1, "m")

fracture_indices = self.params.get("fracture_indices", [0])
fractures = [
Expand All @@ -137,7 +104,7 @@ def set_fractures(self) -> None:

def meshing_arguments(self) -> dict:
# Divide by length scale:
ls = self.solid.convert_units(1, "m")
ls = self.units.convert_units(1, "m")

mesh_sizes = {
# Cartesian: 2 by 8 cells.
Expand All @@ -157,7 +124,7 @@ def set_domain(self) -> None:
self.params["grid_type"] = "cartesian"

# Length scale:
ls = self.solid.convert_units(1, "m")
ls = self.units.convert_units(1, "m")

# Mono-dimensional grid by default
phys_dims = np.array([2, 1]) * ls
Expand All @@ -179,7 +146,7 @@ class OrthogonalFractures3d(CubeDomainOrthogonalFractures):

def meshing_arguments(self) -> dict:
# Length scale:
ls = self.solid.convert_units(1, "m")
ls = self.units.convert_units(1, "m")

mesh_sizes = {
"cell_size": 0.5 * ls,
Expand Down
86 changes: 80 additions & 6 deletions src/porepy/applications/test_utils/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@


class NoPhysics( # type: ignore[misc]
pp.ModelGeometry, pp.SolutionStrategy, pp.DataSavingMixin, pp.BoundaryConditionMixin
pp.ModelGeometry,
pp.SolutionStrategy,
pp.DataSavingMixin,
pp.BoundaryConditionMixin,
pp.FluidMixin,
):
"""A model with no physics, for testing purposes.

Expand Down Expand Up @@ -245,11 +249,12 @@ def subdomains_or_interfaces_from_method_name(
assert len(signature.parameters) == 1

# The domain is a list of either subdomains or interfaces.
domains: list[pp.Grid] | list[pp.MortarGrid]
if "subdomains" in signature.parameters or "domains" in signature.parameters:
# If relevant, filter out the domains that are not to be tested.
domains = mdg.subdomains(dim=domain_dimension)
elif "interfaces" in signature.parameters:
domains = mdg.interfaces(dim=domain_dimension) # type: ignore[assignment]
domains = mdg.interfaces(dim=domain_dimension)

return domains

Expand Down Expand Up @@ -328,8 +333,8 @@ def compare_scaled_primary_variables(
variables=[var_name], time_step_index=0
)
# Convert back to SI units.
values_0 = setup_0.fluid.convert_units(scaled_values_0, var_unit, to_si=True)
values_1 = setup_1.fluid.convert_units(scaled_values_1, var_unit, to_si=True)
values_0 = setup_0.units.convert_units(scaled_values_0, var_unit, to_si=True)
values_1 = setup_1.units.convert_units(scaled_values_1, var_unit, to_si=True)
compare_values(values_0, values_1, cell_wise=cell_wise)


Expand Down Expand Up @@ -369,7 +374,7 @@ def compare_scaled_model_quantities(
)
# Convert back to SI units.
value = method(domains).value(setup.equation_system)
values.append(setup.fluid.convert_units(value, method_unit, to_si=True))
values.append(setup.units.convert_units(value, method_unit, to_si=True))
compare_values(values[0], values[1], cell_wise=cell_wise)


Expand Down Expand Up @@ -447,4 +452,73 @@ def get_model_methods_returning_ad_operator(model_setup) -> list[str]:
):
testable_methods.append(method)

return testable_methods
# Appending testable methods of the fluid
fluid_methods = [
method for method in dir(model_setup.fluid) if not method.startswith("_")
]
testable_fluid_methods: list[str] = []
# The basic flow model has no energy-related
skip_methods = ["specific_enthalpy", "thermal_conductivity"]
for method in fluid_methods:
if method in skip_methods:
continue
# Get method in callable form
callable_method = getattr(model_setup.fluid, method)

# Retrieve method signature via inspect
try:
signature = inspect.signature(callable_method)
except TypeError:
continue

# Append method to the `testable_methods` list if the conditions are met
if (
len(signature.parameters) == 1
and (
"subdomains" in signature.parameters
or "interfaces" in signature.parameters
or "domains" in signature.parameters
)
and (
"pp.ad.Operator" in signature.return_annotation
or "pp.ad.DenseArray" in signature.return_annotation
)
):
testable_fluid_methods.append(f"fluid.{method}")

# The fluid is represented by a reference phase, whose saturation is 1
# I.e., it's thermodynamic properties are equal to the fluid properties
phase_methods = [
method
for method in dir(model_setup.fluid.reference_phase)
if not method.startswith("_")
]
testable_phase_methods: list[str] = []
for method in phase_methods:
if method in skip_methods:
continue
# Get method in callable form
callable_method = getattr(model_setup.fluid.reference_phase, method)

# Retrieve method signature via inspect
try:
signature = inspect.signature(callable_method)
except TypeError:
continue

# Append method to the `testable_methods` list if the conditions are met
if (
len(signature.parameters) == 1
and (
"subdomains" in signature.parameters
or "interfaces" in signature.parameters
or "domains" in signature.parameters
)
and (
"pp.ad.Operator" in signature.return_annotation
or "pp.ad.DenseArray" in signature.return_annotation
)
):
testable_phase_methods.append(f"fluid.reference_phase.{method}")

return testable_methods + testable_fluid_methods + testable_phase_methods
Loading
Loading