Skip to content

Commit

Permalink
Merge pull request #122 from mbakker7/dev
Browse files Browse the repository at this point in the history
Release 6.6.0: refactor cross-sections
  • Loading branch information
dbrakenhoff authored Dec 20, 2024
2 parents 23827f1 + e6ce998 commit f5b9c31
Show file tree
Hide file tree
Showing 10 changed files with 424 additions and 200 deletions.
6 changes: 3 additions & 3 deletions docs/01howto/getting_started/cross_sections.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ infinitely long line-sinks, and infinitely long line-doublets. The cross-section
parallel to the x-axis. Strip inhomogeneities may extend to infinity. The following
elements are available:

1. :class:`~timml.inhomogeneity1d.StripInhomMaq` is a strip aquifer consisting of a
1. :class:`~timml.inhomogeneity1d.XsectionMaq` is a strip aquifer consisting of a
regular sequence of aquifer - leaky layer - aquifer - leaky layer, aquifer, etc., like
a ModelMaq.

2. :class:`~timml.inhomogeneity1d.StripInhom3D` is a strip aquifer consisting of a
2. :class:`~timml.inhomogeneity1d.Xsection3D` is a strip aquifer consisting of a
stack of aquifer layers.

3. :class:`~timml.linesink1d.LineSink1D` is an infinitely long line-sink for which the
Expand All @@ -22,5 +22,5 @@ elements are available:
5. :class:`~timml.linedoublet1d.LeakyLineDoublet1D` is an infinitely long leaky wall.
An impermeable wall is created by specifying an infinitely large resistance

6. :class:`~timml.stripareasink.StripAreaSink` is a strip area-sink, which can only be
6. :class:`~timml.stripareasink.XsectionAreaSink` is a strip area-sink, which can only be
added when the topboundary is confined (topboundary='conf').
250 changes: 160 additions & 90 deletions docs/04xsections/timml_xsection.ipynb

Large diffs are not rendered by default.

78 changes: 17 additions & 61 deletions timml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,26 @@
Mark Bakker, Delft University of Technology
mark dot bakker at tudelft dot nl
TimML is a computer program for the simulation of steady-state multiaquifer flow with
TimML is a computer program for the simulation of steady-state multi-aquifer flow with
analytic elements and consists of a library of Python scripts and FORTRAN extensions.
"""
# ruff: noqa: F401
# from __future__ import division, print_function, absolute_import

# ruff: noqa: F401
# --version number
__name__ = "timml"
__author__ = "Mark Bakker"
# Import all classes and functions
from timml.inhomogeneity1d import StripInhom3D, StripInhomMaq
from timml import bessel
from timml.circareasink import CircAreaSink
from timml.constant import Constant, ConstantStar
from timml.inhomogeneity import (
BuildingPit3D,
BuildingPitMaq,
LeakyBuildingPit3D,
LeakyBuildingPitMaq,
PolygonInhom3D,
PolygonInhomMaq,
)
from timml.inhomogeneity1d import StripInhom3D, StripInhomMaq, Xsection3D, XsectionMaq
from timml.linedoublet import (
ImpLineDoublet,
ImpLineDoubletString,
Expand All @@ -31,65 +40,12 @@
LineSinkDitchString,
)
from timml.linesink1d import HeadLineSink1D, LineSink1D
from timml.model import Model, Model3D, ModelMaq
from timml.stripareasink import StripAreaSink
from timml.model import Model, Model3D, ModelMaq, ModelXsection
from timml.stripareasink import XsectionAreaSink
from timml.trace import timtraceline, timtracelines
from timml.uflow import Uflow
from timml.version import __version__
from timml.version import __version__, show_versions
from timml.well import HeadWell, LargeDiameterWell, Well, WellBase

from . import bessel
from .circareasink import CircAreaSink
from .constant import Constant, ConstantStar
from .inhomogeneity import (
BuildingPit3D,
BuildingPitMaq,
LeakyBuildingPit3D,
LeakyBuildingPitMaq,
PolygonInhom3D,
PolygonInhomMaq,
)

__all__ = [
"CircAreaSink",
"Constant",
"ConstantStar",
"BuildingPit3D",
"BuildingPitMaq",
"LeakyBuildingPit3D",
"LeakyBuildingPitMaq",
"PolygonInhom3D",
"PolygonInhomMaq",
"StripInhom3D",
"StripInhomMaq",
"ImpLineDoublet",
"ImpLineDoubletString",
"LeakyLineDoublet",
"LeakyLineDoubletString",
"ImpLineDoublet1D",
"LeakyLineDoublet1D",
"HeadLineSink",
"HeadLineSinkContainer",
"HeadLineSinkString",
"HeadLineSinkZero",
"LineSinkBase",
"LineSinkDitch",
"LineSinkDitchString",
"HeadLineSink1D",
"LineSink1D",
"Model",
"Model3D",
"ModelMaq",
"StripAreaSink",
"timtraceline",
"timtracelines",
"Uflow",
"__version__",
"HeadWell",
"LargeDiameterWell",
"Well",
"WellBase",
]

# default bessel module is numba
bessel.set_bessel_method(method="numba")
37 changes: 28 additions & 9 deletions timml/aquifer.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def findlayer(self, z):

class Aquifer(AquiferData):
def __init__(self, model, kaq, c, z, npor, ltype):
AquiferData.__init__(self, model, kaq, c, z, npor, ltype)
super().__init__(model, kaq, c, z, npor, ltype)
self.inhomlist = []
self.area = 1e300 # Needed to find smallest inhom

Expand All @@ -150,11 +150,30 @@ def find_aquifer_data(self, x, y):
if inhom.area < rv.area:
rv = inhom
return rv
# Not used anymore I think 5 Nov 2015
# def find_aquifer_number(self, x, y):
# rv = -1
# for i,inhom in enumerate(self.inhomlist):
# if inhom.isinside(x, y):
# if inhom.area < rv.area:
# rv = i
# return rv


class SimpleAquifer(Aquifer):
"""Simple aquifer for cross-section models.
Only the number of aquifers has to be specified.
Parameters
----------
naq : int
Number of aquifers.
"""

def __init__(self, naq):
self.naq = naq
self.inhomlist = []
self.area = 1e300 # Needed to find smallest inhomogeneity
self.elementlist = []

def __repr__(self):
return f"Simple Aquifer: {self.naq} aquifer(s)"

def initialize(self):
for inhom in self.inhomlist:
inhom.initialize()
for inhom in self.inhomlist:
inhom.create_elements()
158 changes: 141 additions & 17 deletions timml/inhomogeneity1d.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,78 @@
import inspect # user for storing the input
import warnings

import numpy as np

from .aquifer import AquiferData
from .aquifer_parameters import param_3d, param_maq
from .constant import ConstantStar
from .linesink1d import FluxDiffLineSink1D, HeadDiffLineSink1D
from .stripareasink import StripAreaSinkInhom
from timml.aquifer import AquiferData
from timml.aquifer_parameters import param_3d, param_maq
from timml.constant import ConstantStar
from timml.linesink1d import FluxDiffLineSink1D, HeadDiffLineSink1D
from timml.stripareasink import XsectionAreaSinkInhom

__all__ = ["StripInhomMaq", "StripInhom3D"]
__all__ = ["XsectionMaq", "Xsection3D"]


class StripInhom(AquiferData):
class Xsection(AquiferData):
"""Base class for cross-section inhomogeneities.
Parameters
----------
model : Model object
model to which the element is added, usually an instance of ModelXsection
x1 : float
left boundary of inhomogeneity (may be -np.inf if extends to infinity)
x2 : float
right boundary of inhomogeneity (may be np.inf if extends to infinity)
kaq : float, array or list
hydraulic conductivity of each layer from the top down
c : float, array or list
resistance of leaky layers from the top down
z : array or list
elevation tops and bottoms of the layers from the top down,
leaky layers may have zero thickness
npor : float, array or list
porosity of all aquifer layers from the top down
ltype : string, array or list
type of the layers: 'a' for aquifer, 'l' for leaky layer
hstar : float, optional
head value above semi-confining top, only read if topboundary='semi'
N : float, optional
infiltration rate, only read if topboundary='conf'
name : string, optional
name of the inhomogeneity
"""

tiny = 1e-12

def __init__(self, model, x1, x2, kaq, c, z, npor, ltype, hstar, N):
AquiferData.__init__(self, model, kaq, c, z, npor, ltype)
def __init__(self, model, x1, x2, kaq, c, z, npor, ltype, hstar, N, name=None):
super().__init__(model, kaq, c, z, npor, ltype)
self.x1 = x1
self.x2 = x2
self.hstar = hstar
self.N = N
self.inhom_number = self.model.aq.add_inhom(self)
if name is None:
self.name = f"inhom{self.inhom_number:02g}"
else:
self.name = name
self.addlinesinks = True # Set to False not to add line-sinks

def __repr__(self):
return "Inhom1D: " + str([self.x1, self.x2])
if self.hstar is not None:
hstar = f" with h* = {self.hstar}"
else:
hstar = ""
if self.N is not None:
inf = f" with N = {self.N}"
else:
inf = ""

return (
f"{self.name}: {self.__class__.__name__} "
+ str([self.x1, self.x2])
+ hstar
+ inf
)

def isinside(self, x, y):
return (x >= self.x1) and (x < self.x2)
Expand Down Expand Up @@ -72,15 +120,15 @@ def create_elements(self):
assert (
aqin.ilap
), "Error: infiltration can only be added if topboundary='conf'"
StripAreaSinkInhom(self.model, self.x1, self.x2, self.N, layer=0)
XsectionAreaSinkInhom(self.model, self.x1, self.x2, self.N, layer=0)
if aqin.ltype[0] == "l":
assert self.hstar is not None, "Error: hstar needs to be set"
c = ConstantStar(self.model, self.hstar, aq=aqin)
c.inhomelement = True


class StripInhomMaq(StripInhom):
"""Create a strip inhomogeneity for a mult-aquifer sequence of aquifer-leaky layer.
class XsectionMaq(Xsection):
"""Cross-section inhomogeneity for a multi-aquifer sequence.
Parameters
----------
Expand Down Expand Up @@ -130,6 +178,7 @@ def __init__(
topboundary="conf",
hstar=None,
N=None,
name=None,
):
if c is None:
c = []
Expand All @@ -142,11 +191,11 @@ def __init__(
npor,
ltype,
) = param_maq(kaq, z, c, npor, topboundary)
StripInhom.__init__(self, model, x1, x2, kaq, c, z, npor, ltype, hstar, N)
super().__init__(model, x1, x2, kaq, c, z, npor, ltype, hstar, N, name=name)


class StripInhom3D(StripInhom):
"""Strip inhomogeneity for a multi-layer model consisting of stacked aquifer layers.
class Xsection3D(Xsection):
"""Cross-section inhomogeneity consisting of stacked aquifer layers.
The resistance between the layers is computed from the vertical hydraulic
conductivity of the layers.
Expand Down Expand Up @@ -189,6 +238,8 @@ class StripInhom3D(StripInhom):
head value above semi-confining top, only read if topboundary='semi'
N : float (default is None)
infiltration rate, only read if topboundary='conf'
name : string, optional
name of the inhomogeneity
"""

def __init__(
Expand All @@ -205,6 +256,7 @@ def __init__(
topres=None,
topthick=0.0,
N=None,
name=None,
):
if z is None:
z = [1, 0]
Expand All @@ -217,4 +269,76 @@ def __init__(
) = param_3d(kaq, z, kzoverkh, npor, topboundary, topres)
if topboundary == "semi":
z = np.hstack((z[0] + topthick, z))
StripInhom.__init__(self, model, x1, x2, kaq, c, z, npor, ltype, hstar, N)
super().__init__(model, x1, x2, kaq, c, z, npor, ltype, hstar, N, name=name)


class StripInhom(Xsection):
def __init__(self, model, x1, x2, kaq, c, z, npor, ltype, hstar, N, name=None):
warnings.warn(
"'StripInhom' is deprecated and has been renamed to 'Xsection'",
DeprecationWarning,
stacklevel=2,
)
super().__init__(model, x1, x2, kaq, c, z, npor, ltype, hstar, N, name=name)


class StripInhomMaq(XsectionMaq):
def __init__(
self,
model,
x1,
x2,
kaq=1,
z=None,
c=None,
npor=0.3,
topboundary="conf",
hstar=None,
N=None,
name=None,
):
warnings.warn(
"'StripInhomMaq' is deprecated and has been renamed to 'XsectionMaq'",
DeprecationWarning,
stacklevel=2,
)
super().__init__(model, x1, x2, kaq, z, c, npor, topboundary, hstar, N, name)


class StripInhom3D(Xsection3D):
def __init__(
self,
model,
x1,
x2,
kaq,
z=None,
kzoverkh=1,
npor=0.3,
topboundary="conf",
hstar=None,
topres=None,
topthick=0.0,
N=None,
name=None,
):
warnings.warn(
"'StripInhom3D' is deprecated and has been renamed to 'Xsection3D'",
DeprecationWarning,
stacklevel=2,
)
super().__init__(
model,
x1,
x2,
kaq,
z,
kzoverkh,
npor,
topboundary,
hstar,
topres,
topthick,
N,
name,
)
Loading

0 comments on commit f5b9c31

Please sign in to comment.