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

Automatic refinement of elements #105

Open
wants to merge 43 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
e51c476
fix parallel builds for coveralls
dbrakenhoff Dec 6, 2023
f9841e4
get rid of extra github icon
dbrakenhoff Dec 6, 2023
e042776
add Model.elements attribute
dbrakenhoff Dec 29, 2023
91f8409
Merge remote-tracking branch 'origin/dev' into refine_elements
dbrakenhoff Dec 29, 2023
a041dde
add general refine functions:
dbrakenhoff Jan 3, 2024
0956e40
add general refine functions:
dbrakenhoff Jan 3, 2024
8d4999d
add addtomodel kwarg to StripAreaSink classes
dbrakenhoff Jan 3, 2024
f053607
Add logic to refine elements in initialize in model class
dbrakenhoff Jan 3, 2024
d6a073c
add addtomodel kwarg to constant classes
dbrakenhoff Jan 3, 2024
31848ed
Add refine functionality to inhoms
dbrakenhoff Jan 3, 2024
b3a3e13
style fixes
dbrakenhoff Jan 3, 2024
72462ff
add refine logic for LineSinkBase
dbrakenhoff Jan 3, 2024
d3ecfa3
support refining in LineSinkHoBase
dbrakenhoff Jan 3, 2024
426b192
add refine functionality to HeadLineSink
dbrakenhoff Jan 3, 2024
6d68c1d
delete LineSinkStringBase (unused) and replace with LineSinkStringBase2
dbrakenhoff Jan 3, 2024
bbd9cb1
add refine support to LineSinkStringBase
dbrakenhoff Jan 3, 2024
ca78a8c
Add refine logic to HeadLineSinkString and LineSinkDitchString
dbrakenhoff Jan 3, 2024
82a69e2
add imports, use labels in HeadLineSinkContainer
dbrakenhoff Jan 3, 2024
da0ed41
Add refine logic to LineDoubletHoBase, ImpLineDoublet and LeakyLineDo…
dbrakenhoff Jan 3, 2024
70e2221
add refine logic to LineDoubletStringBase and its child classes
dbrakenhoff Jan 3, 2024
22dceb7
add imports
dbrakenhoff Jan 3, 2024
0b7b50e
add refinement notebook (move to docs later)
dbrakenhoff Jan 3, 2024
f9afcec
add addtomodel kwarg
dbrakenhoff Jan 3, 2024
3c2a9b6
add refine logic to AquiferData class (for inhoms)
dbrakenhoff Jan 3, 2024
3b62e36
use addtomodel=False to prevent inhom elements from being added to mo…
dbrakenhoff Jan 3, 2024
1605c1b
remove self.addlinesinks option
dbrakenhoff Jan 3, 2024
72fa78c
ruff check/format
dbrakenhoff Jan 3, 2024
10b01db
add refine tests
dbrakenhoff Jan 3, 2024
b7b7fba
improve notebook
dbrakenhoff Jan 4, 2024
c4c465a
avoid creating new inhom element when refining
dbrakenhoff Jan 4, 2024
f22cdd9
update notebook
dbrakenhoff Jan 4, 2024
fca242a
update import
dbrakenhoff Jan 4, 2024
49e00cf
update docstring
dbrakenhoff Jan 4, 2024
6648b78
forgot to commit updated tests
dbrakenhoff Jan 4, 2024
b673386
update docs
dbrakenhoff Jan 4, 2024
dd32638
implement resert for elements
dbrakenhoff Jan 4, 2024
d5df5de
fix failing tests
dbrakenhoff Jan 4, 2024
446a1f5
tiny improvement to notebook
dbrakenhoff Feb 13, 2024
0453134
Merge remote-tracking branch 'origin/dev' into refine_elements
dbrakenhoff Feb 13, 2024
ff9b161
remove LineSinkStringBase, HeadLineSinkStringOld
dbrakenhoff Feb 14, 2024
ac8d97e
Merge branch 'dev' into refine_elements
dbrakenhoff Feb 14, 2024
4decd0a
mucked up a merge conflict
dbrakenhoff Feb 14, 2024
2646e31
Merge branch 'dev' into refine_elements
dbrakenhoff Sep 26, 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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ ENV/

# f2py
.plist
.vscode/settings.json

.vscode

coverage/

# docs
_build/
Expand Down
1,244 changes: 1,244 additions & 0 deletions notebooks/refining_elements.ipynb

Large diffs are not rendered by default.

371 changes: 371 additions & 0 deletions tests/test_refine.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,371 @@
import numpy as np
import timml as tml


def modelmaq():
# model parameters
kh = 10 # m/day
ctop = 1000.0 # resistance top leaky layer in days
ztop = 0.0 # surface elevation
zbot = -20.0 # bottom elevation of the model
z = np.array([ztop + 1, ztop, -10, -10, zbot])
ml = tml.ModelMaq(kaq=kh, z=z, c=[ctop, 1], topboundary="semi", hstar=0.0)
return ml


def model3d():
# model parameters
kh = 10 # m/day
kzoverkh = 0.25
ctop = 1000.0 # resistance top leaky layer in days
ztop = 0.0 # surface elevation
zbot = -20.0 # bottom elevation of the model
z = np.array([ztop, -10, zbot])
ml = tml.Model3D(
kaq=kh,
kzoverkh=kzoverkh,
z=z,
topres=ctop,
topthick=1.0,
topboundary="semi",
hstar=0.0,
)
return ml


def test_refine_n_segments_line():
x1, x2, y1, y2 = -5, 5, 0, 0
xy = np.array([(x1, y1), (x2, y2)])
xyr, reindexer = tml.util.refine_n_segments(xy, "line", 3)
assert np.allclose(xyr[:, 0], np.array([-5.0, -2.5, 2.5, 5.0]))
assert (reindexer == 0).all() and len(reindexer) == 3


def test_refine_n_segments_polygon():
xy = [
(-10, -5),
(10, -5),
(10, 5),
(-10, 5),
(-10, -5),
]
xyr, reindexer = tml.util.refine_n_segments(xy, "polygon", 2)
assert np.all(reindexer == np.array([0, 0, 1, 1, 2, 2, 3, 3]))
assert len(xyr) == 9


def test_refine_linesink():
ml = modelmaq()
tml.LineSinkBase(ml, refine_level=3)
ml.solve(silent=True)
assert np.allclose(ml.elementlist[-3].Qls, [25.0])
assert np.allclose(ml.elementlist[-2].Qls, [50.0])
assert np.allclose(ml.elementlist[-1].Qls, [25.0])
assert len(ml.elementlist) == 4


def test_refine_headlinesink():
ml = modelmaq()
tml.HeadLineSink(ml, refine_level=2)
ml.solve(silent=True)
assert len(ml.elementlist) == 3


def test_refine_headlinesinkstring():
ml = modelmaq()
hls = tml.HeadLineSinkString(ml, refine_level=2)
ml.solve(silent=True)
assert len(hls.lslist) == 2
assert ml.head(10, 10, layers=[0]) == 0.0
assert np.sum(hls.discharge()) == 0.0


def test_refine_leakylinedoublet():
ml = modelmaq()
tml.LeakyLineDoublet(ml, res=100, refine_level=2)
ml.solve(silent=True)
assert len(ml.elementlist) == 3
assert ml.head(10, 10, layers=[0]) == 0.0


def test_refine_leakylinedoubletstring():
ml = modelmaq()
llds = tml.LeakyLineDoubletString(ml, res=100, refine_level=2)
ml.solve(silent=True)
assert len(llds.ldlist) == 2
assert ml.head(10, 10, layers=[0]) == 0.0


def test_refine_implinedoublet():
ml = modelmaq()
tml.ImpLineDoublet(ml, refine_level=2)
ml.solve(silent=True)
assert len(ml.elementlist) == 3
assert ml.head(10, 10, layers=[0]) == 0.0


def test_refine_implinedoubletstring():
ml = modelmaq()
llds = tml.ImpLineDoubletString(ml, refine_level=2)
ml.solve(silent=True)
assert len(llds.ldlist) == 2
assert ml.head(10, 10, layers=[0]) == 0.0


def test_refine_polygonimhommaq():
ml = modelmaq()
xy = [
(-10, -5),
(10, -5),
(10, 5),
(-10, 5),
(-10, -5),
]
inhom = tml.PolygonInhomMaq(
ml,
xy,
kaq=ml.aq.kaq,
z=ml.aq.z[1:],
c=ml.aq.c[1:],
topboundary="conf",
refine_level=2,
)
tml.Well(ml, 0, 0)
ml.solve(silent=True)
eps = 1e-6
xyin = [
(-10 + eps, -5 + eps),
(10 - eps, -5 + eps),
(10 - eps, 5 - eps),
(-10 + eps, 5 - eps),
(-10 + eps, -5 + eps),
]
assert len(ml.elementlist) == 19
assert np.allclose(np.sum(ml.intnormflux(xyin, ndeg=99)), [100.0], rtol=1e-3)


def test_refine_polygonimhom3d():
ml = model3d()
xy = [
(-10, -5),
(10, -5),
(10, 5),
(-10, 5),
(-10, -5),
]
inhom = tml.PolygonInhom3D(
ml,
xy,
kaq=ml.aq.kaq,
kzoverkh=0.25,
z=ml.aq.z[1:],
topboundary="conf",
refine_level=2,
)
tml.Well(ml, 0, 0)
ml.solve(silent=True)
eps = 1e-6
xyin = [
(-10 + eps, -5 + eps),
(10 - eps, -5 + eps),
(10 - eps, 5 - eps),
(-10 + eps, 5 - eps),
(-10 + eps, -5 + eps),
]
assert len(ml.elementlist) == 19
assert np.allclose(np.sum(ml.intnormflux(xyin, ndeg=99)), [100.0], rtol=1e-3)


def test_refine_buildingpitmaq():
ml = modelmaq()
xy = [
(-10, -5),
(10, -5),
(10, 5),
(-10, 5),
(-10, -5),
]
tml.BuildingPitMaq(
ml,
xy,
kaq=ml.aq.kaq,
z=ml.aq.z[1:],
c=ml.aq.c[1:],
topboundary="conf",
refine_level=2,
)
tml.Well(ml, 0, 0)
ml.solve(silent=True)
eps = 1e-6
xyin = [
(-10 + eps, -5 + eps),
(10 - eps, -5 + eps),
(10 - eps, 5 - eps),
(-10 + eps, 5 - eps),
(-10 + eps, -5 + eps),
]
assert len(ml.elementlist) == 35
# accuracy of intnormflux around inner boundary is reasonable but not perfect
assert np.allclose(
np.sum(ml.intnormflux(xyin, ndeg=99), axis=1),
[0.0, 100.0],
atol=1e-1,
rtol=1e-3,
)


def test_refine_buildingpit3d():
ml = model3d()
xy = [
(-10, -5),
(10, -5),
(10, 5),
(-10, 5),
(-10, -5),
]
tml.BuildingPit3D(
ml,
xy,
kaq=ml.aq.kaq,
kzoverkh=0.25,
z=ml.aq.z[1:],
topboundary="conf",
refine_level=2,
)
tml.Well(ml, 0, 0)
ml.solve(silent=True)
eps = 1e-6
xyin = [
(-10 + eps, -5 + eps),
(10 - eps, -5 + eps),
(10 - eps, 5 - eps),
(-10 + eps, 5 - eps),
(-10 + eps, -5 + eps),
]
assert len(ml.elementlist) == 35
# NOTE: accuracy of intnormflux around inner boundary isn't great...
assert np.allclose(
np.sum(ml.intnormflux(xyin, ndeg=99), axis=1),
[0.0, 100.0],
atol=1.0,
rtol=1e-3,
)


def test_refine_leakybuildingpitmaq():
ml = modelmaq()
xy = [
(-10, -5),
(10, -5),
(10, 5),
(-10, 5),
(-10, -5),
]
tml.LeakyBuildingPitMaq(
ml,
xy,
kaq=ml.aq.kaq,
z=ml.aq.z[1:],
c=ml.aq.c[1:],
res=[100, 100, 1, 100],
topboundary="conf",
refine_level=2,
)
tml.Well(ml, 0, 0)
ml.solve(silent=True)
eps = 1e-6
xyin = [
(-10 + eps, -5 + eps),
(10 - eps, -5 + eps),
(10 - eps, 5 - eps),
(-10 + eps, 5 - eps),
(-10 + eps, -5 + eps),
]
assert len(ml.elementlist) == 35
# accuracy of intnormflux around inner boundary is reasonable but not perfect
assert np.allclose(np.sum(ml.intnormflux(xyin, ndeg=99)), [100.0], rtol=1e-3)


def test_refine_leakybuildingpit3d():
ml = model3d()
xy = [
(-10, -5),
(10, -5),
(10, 5),
(-10, 5),
(-10, -5),
]
tml.LeakyBuildingPit3D(
ml,
xy,
kaq=ml.aq.kaq,
kzoverkh=0.25,
z=ml.aq.z[1:],
res=[100, 100, 1, 100],
topboundary="conf",
refine_level=2,
)
tml.Well(ml, 0, 0)
ml.solve(silent=True)
eps = 1e-6
xyin = [
(-10 + eps, -5 + eps),
(10 - eps, -5 + eps),
(10 - eps, 5 - eps),
(-10 + eps, 5 - eps),
(-10 + eps, -5 + eps),
]
assert len(ml.elementlist) == 35
# accuracy of intnormflux around inner boundary is reasonable but not perfect
assert np.allclose(np.sum(ml.intnormflux(xyin, ndeg=99)), [100.0], rtol=1e-3)


def test_global_refine_option():
ml = modelmaq()
tml.HeadLineSink(ml, refine_level=1)
ml.solve(refine_level=3, silent=True)
assert len(ml.elementlist) == 4


def test_multiple_solves():
ml = modelmaq()
tml.HeadLineSink(ml, refine_level=3)
ml.solve(silent=True)
assert len(ml.elementlist) == 4
ml.solve(silent=True, refine_level=1)
assert len(ml.elementlist) == 2


def test_reset_headlinesinkstring():
ml = modelmaq()
hls = tml.HeadLineSinkString(ml, refine_level=2)
ml.initialize()
assert len(hls.lslist) == 2
ml.initialize(refine_level=1)
assert len(hls.lslist) == 1


def test_reset_leakybuildingpitmaq():
ml = modelmaq()
xy = [
(-10, -5),
(10, -5),
(10, 5),
(-10, 5),
(-10, -5),
]
tml.LeakyBuildingPitMaq(
ml,
xy,
kaq=ml.aq.kaq,
z=ml.aq.z[1:],
c=ml.aq.c[1:],
res=[100, 100, 1, 100],
topboundary="conf",
refine_level=2,
)
tml.Well(ml, 0, 0)
ml.initialize()
assert len(ml.elementlist) == 35
ml.initialize(refine_level=1)
assert len(ml.elementlist) == 19
Loading
Loading