Skip to content

Commit 0dd06fb

Browse files
Issue #1299 public api fixes from imod5 (#1300)
Fixes #1299 * The SimulationAllocationOptions and SimulationDistributingOptions are stowed away very far, and not part of the public API * Yet, these objects used to store default settings are required to call the public api method Modflow6Simulation.from_imod5_data... * A description of "period_times" is missing in the docstring * Example code snippets are missing from the docstring # Description This PR fixes the following things: * Makes ``SimulationAllocationOptions`` and ``SimulationDistributingOptions`` part of the public API * Makes ``allocation_options`` and ``distributing_options`` optional arguments for ``Modflow6Simulation.from_imod5_data`` and ``GroundwaterFlowModel.from_imod5_data`` * To do this, I had to change the order of arguments for Modflow6Simulation.from_imod5_data, as Python doesn't allow non-optional args after an optional arg. This can break existing scripts, however this has just been released, so not many scripts use it. As long as the tutorial material is updated within time. * Extends docstrings of ``GroundwaterFlowModel.from_imod5_data``, ``Modflow6Simulation.from_imod5_data``, ``SimulationAllocationOptions``, and ``SimulationDistributingOptions``
1 parent 56e233b commit 0dd06fb

9 files changed

Lines changed: 172 additions & 44 deletions

File tree

docs/api/changelog.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ The format is based on `Keep a Changelog`_, and this project adheres to
99
[Unreleased]
1010
------------
1111

12+
Added
13+
~~~~~
14+
15+
- :class:`imod.prepare.topsystem.SimulationAllocationOptions`,
16+
:class:`imod.prepare.topsystem.SimulationDistributingOptions`, which are used
17+
to store default allocation and distributing options respectively.
18+
1219
Fixed
1320
~~~~~
1421

@@ -19,6 +26,18 @@ Fixed
1926
- Fix bug where no ``ValidationError`` was thrown if there is an active RCH, DRN,
2027
GHB, or RIV cell where idomain = -1.
2128

29+
Changed
30+
~~~~~~~
31+
32+
- In :meth:`imod.mf6.Modflow6Simulation.from_imod5_data`, and
33+
:meth:`imod.mf6.GroundwaterFlowModel.from_imod5_data` the arguments
34+
``allocation_options``, ``distributing_options`` are now optional.
35+
- The order of arguments of :meth:`imod.mf6.Modflow6Simulation.from_imod5_data`,
36+
and :meth:`imod.mf6.GroundwaterFlowModel.from_imod5_data`. It now is
37+
``imod5_data, period_data, times, allocation_options, distributing_options, regridder_types``
38+
instead of:
39+
``imod5_data, period_data, allocation_options, distributing_options, times, regridder_types``
40+
2241

2342
[0.18.0]
2443
--------

docs/api/prepare.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ Prepare model input
3838

3939
ALLOCATION_OPTION
4040
DISTRIBUTING_OPTION
41+
SimulationAllocationOptions
42+
SimulationDistributingOptions
4143
allocate_drn_cells
4244
allocate_ghb_cells
4345
allocate_rch_cells

imod/formats/prj/prj.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ def _is_var_ipf_and_path(block_content: dict[str, Any], var: str):
10171017
return is_ipf, path
10181018

10191019

1020-
def open_projectfile_data(path: FilePath) -> Dict[str, Any]:
1020+
def open_projectfile_data(path: FilePath) -> tuple[dict[str, Any], dict[str, Any]]:
10211021
"""
10221022
Read the contents of an iMOD project file and read/open the data present in
10231023
it:

imod/mf6/model_gwf.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,22 +192,35 @@ def from_imod5_data(
192192
cls,
193193
imod5_data: dict[str, dict[str, GridDataArray]],
194194
period_data: dict[str, list[datetime]],
195-
allocation_options: SimulationAllocationOptions,
196-
distributing_options: SimulationDistributingOptions,
197195
times: list[datetime],
198-
regridder_types: dict[str, RegridMethodType],
196+
allocation_options: Optional[SimulationAllocationOptions] = None,
197+
distributing_options: Optional[SimulationDistributingOptions] = None,
198+
regridder_types: Optional[dict[str, RegridMethodType]] = None,
199199
) -> "GroundwaterFlowModel":
200200
"""
201-
Imports a GroundwaterFlowModel (GWF) from the data in an IMOD5 project file.
202-
It adds the packages for which import from imod5 is supported.
203-
Some packages (like OC) must be added manually later.
201+
Imports a GroundwaterFlowModel (GWF) from the data in an iMOD5 project
202+
file and puts it in a simulation. Quasi-3D iMOD5 models, i.e. models
203+
where there is only horizontal flow in aquifers and vertical flow in
204+
aquitards, are not supported.
204205
206+
This method adds all static and boundary condition packages from the
207+
projectfile to the simulation. Output Control (OC) must be added
208+
manually after importing.
205209
206210
Parameters
207211
----------
208212
imod5_data: dict[str, dict[str, GridDataArray]]
209213
dictionary containing the arrays mentioned in the project file as xarray datasets,
210214
under the key of the package type to which it belongs
215+
period_data: dict[str, list[datetime]]
216+
dictionary containing the package names mapped to a list of repeated
217+
stress periods. These are set as ``repeat_stress``.
218+
times: list[datetime]
219+
Time discretization of the simulation. These times are used for the
220+
following:
221+
* Times of wells with associated timeseries are resampled to these times
222+
* Start- and end times in the list are used to repeat the stresses
223+
of periodic data (e.g. river stages in iMOD5 for "summer", "winter")
211224
allocation_options: SimulationAllocationOptions
212225
object containing the allocation options per package type.
213226
If you want a package to have a different allocation option,
@@ -216,10 +229,6 @@ def from_imod5_data(
216229
object containing the conductivity distribution options per package type.
217230
If you want a package to have a different allocation option,
218231
then it should be imported separately
219-
time_min: datetime
220-
Begin-time of the simulation.
221-
time_max: datetime
222-
End-time of the simulation.
223232
regridder_types: dict[str, RegridMethodType]
224233
the key is the package name. The value is a subclass of RegridMethodType.
225234
@@ -229,6 +238,13 @@ def from_imod5_data(
229238
add the OC package to the model.
230239
231240
"""
241+
if allocation_options is None:
242+
allocation_options = SimulationAllocationOptions()
243+
if distributing_options is None:
244+
distributing_options = SimulationDistributingOptions()
245+
if regridder_types is None:
246+
regridder_types = {}
247+
232248
# first import the singleton packages
233249
# import dis
234250
regrid_cache = RegridderWeightsCache()

imod/mf6/simulation.py

Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,51 +1331,100 @@ def mask_all_models(
13311331
def from_imod5_data(
13321332
cls,
13331333
imod5_data: dict[str, dict[str, GridDataArray]],
1334-
period_data: dict[str, dict[str, GridDataArray]],
1335-
allocation_options: SimulationAllocationOptions,
1336-
distributing_options: SimulationDistributingOptions,
1334+
period_data: dict[str, list[datetime]],
13371335
times: list[datetime],
1338-
regridder_types: dict[str, RegridMethodType] = {},
1336+
allocation_options: Optional[SimulationAllocationOptions] = None,
1337+
distributing_options: Optional[SimulationDistributingOptions] = None,
1338+
regridder_types: Optional[dict[str, RegridMethodType]] = None,
13391339
) -> "Modflow6Simulation":
13401340
"""
1341-
Imports a GroundwaterFlowModel (GWF) from the data in an IMOD5 project file.
1342-
It adds the packages for which import from imod5 is supported.
1343-
Some packages (like OC) must be added manually later.
1344-
1341+
Imports a GroundwaterFlowModel (GWF) from the data in an iMOD5 project
1342+
file and puts it in a simulation. Quasi-3D iMOD5 models, i.e. models
1343+
where there is only horizontal flow in aquifers and vertical flow in
1344+
aquitards, are not supported.
1345+
1346+
This method adds all static and boundary condition packages from the
1347+
projectfile to the simulation. Output Control (OC) must be added
1348+
manually after importing. The
1349+
:func:`imod.mf6.ims.SolutionPresetModerate` solver settings are added
1350+
automatically under the "ims" key, but these can be overrided by the
1351+
user after importing.
13451352
13461353
Parameters
13471354
----------
13481355
imod5_data: dict[str, dict[str, GridDataArray]]
13491356
dictionary containing the arrays mentioned in the project file as xarray datasets,
1350-
under the key of the package type to which it belongs
1351-
allocation_options: SimulationAllocationOptions
1352-
object containing the allocation options per package type.
1353-
If you want a package to have a different allocation option,
1354-
then it should be imported separately
1355-
distributing_options: SimulationDistributingOptions
1356-
object containing the conductivity distribution options per package type.
1357-
If you want a package to have a different allocation option,
1358-
then it should be imported separately
1357+
under the key of the package type to which it belongs.
1358+
period_data: dict[str, list[datetime]]
1359+
dictionary containing the package names mapped to a list of repeated
1360+
stress periods. These are set as ``repeat_stress``.
13591361
times: list[datetime]
1360-
time discretization of the model to be imported.
1362+
time discretization of the model to be imported. This is used for
1363+
the following:
1364+
* Times of wells with associated timeseries are resampled to these times
1365+
* Start and end times in the list are used to repeat the stresses
1366+
of periodic data (e.g. river stages in iMOD5 for "summer", "winter")
1367+
* The simulation is discretized to these times, using
1368+
:meth:`imod.mf6.Modflow6Simulation.create_time_discretization`
1369+
allocation_options: SimulationAllocationOptions, optional
1370+
object containing the allocation options per package type. If you
1371+
want a specific package to have a different allocation option, then
1372+
it should be imported separately.
1373+
distributing_options: SimulationDistributingOptions, optional
1374+
object containing the conductivity distribution options per package
1375+
type. If you want a package to have a different allocation option,
1376+
then it should be imported separately.
13611377
regridder_types: dict[str, RegridMethodType]
13621378
the key is the package name. The value is the RegridMethodType
13631379
object containing the settings for regridding the package with the
1364-
specified key
1380+
specified key.
13651381
13661382
Returns
13671383
-------
1384+
Modflow6Simulation
1385+
Simulation prepared for MODFLOW6
1386+
1387+
Examples
1388+
--------
1389+
Open projectfile data first:
1390+
1391+
>>> from imod.formats.prj import open_projectfile_data
1392+
>>> imod5_data, period_data = open_projectfile_data("path/to/projectfile")
1393+
1394+
You can then import the simulation as follows:
1395+
1396+
>>> times = [np.datetime("2001-01-01"), np.datetime("2002-01-01"), np.datetime("2003-01-01")]
1397+
>>> mf6_sim = imod.mf6.Modflow6Simulation.from_imod5_data(imod5_data, period_data, times)
1398+
1399+
Allocate rivers differently:
1400+
1401+
>>> from imod.prepare.topsystem import SimulationAllocationOptions, ALLOCATION_OPTION
1402+
>>> allocation_options = SimulationAllocationOptions()
1403+
>>> allocation_options.riv = ALLOCATION_OPTION.at_elevation
1404+
>>> mf6_sim = imod.mf6.Modflow6Simulation.from_imod5_data(imod5_data, period_data, times, allocation_options)
1405+
1406+
You can override solver settings if needed after importing:
1407+
1408+
>>> mf6_sim["imported_model"]["ims"] = SolutionPresetComplex()
1409+
13681410
"""
1411+
if allocation_options is None:
1412+
allocation_options = SimulationAllocationOptions()
1413+
if distributing_options is None:
1414+
distributing_options = SimulationDistributingOptions()
1415+
if regridder_types is None:
1416+
regridder_types = {}
1417+
13691418
simulation = Modflow6Simulation("imported_simulation")
13701419
simulation._validation_context.strict_well_validation = False
13711420

13721421
# import GWF model,
13731422
groundwaterFlowModel = GroundwaterFlowModel.from_imod5_data(
13741423
imod5_data,
13751424
period_data,
1425+
times,
13761426
allocation_options,
13771427
distributing_options,
1378-
times,
13791428
regridder_types,
13801429
)
13811430
simulation["imported_model"] = groundwaterFlowModel

imod/prepare/topsystem/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,8 @@
1111
distribute_ghb_conductance,
1212
distribute_riv_conductance,
1313
)
14+
from imod.prepare.topsystem.default_allocation_methods import (
15+
SimulationAllocationOptions,
16+
SimulationDistributingOptions,
17+
)
1418
from imod.prepare.topsystem.resistance import c_leakage, c_radial

imod/prepare/topsystem/default_allocation_methods.py

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,33 @@
77
@dataclass()
88
class SimulationAllocationOptions:
99
"""
10-
Object containing allocation otpions, specified per packages type on
11-
importing fron imod5. Can be used to set defaults when importing a
10+
Object containing default allocation options, specified per packages type on
11+
importing from imod5. Can be used to set defaults when importing a
1212
simulation or a GroundwaterFlowModel from imod5.
1313
1414
Parameters
1515
----------
16-
drn: allocation option to be used for drainage packages
17-
riv: allocation option to be used for river packages
16+
drn: ALLOCATION_OPTION
17+
allocation option to be used for drainage packages, defaults to
18+
``first_active_to_elevation``.
19+
riv: ALLOCATION_OPTION
20+
allocation option to be used for river packages, defaults to
21+
``stage_to_riv_bot``.
22+
ghb: ALLOCATION_OPTION
23+
allocation option to be used for general head boundary packages,
24+
defaults to ``at_elevation``.
25+
26+
Examples
27+
--------
28+
29+
Initiate allocation default options
30+
31+
>>> alloc_options = SimulationAllocationOptions()
32+
33+
You can set different options as follows:
34+
35+
>>> from imod.prepare.topsystem import ALLOCATION_OPTION
36+
>>> alloc_options.riv = ALLOCATION_OPTION.at_elevation
1837
1938
"""
2039

@@ -26,14 +45,33 @@ class SimulationAllocationOptions:
2645
@dataclass()
2746
class SimulationDistributingOptions:
2847
"""
29-
Object containing conductivity distribution methods, specified per packages
48+
Object containing conductance distribution methods, specified per packages
3049
type. Can be used to set defaults when importing a simulation or a
3150
GroundwaterFlowModel from imod5.
3251
3352
Parameters
3453
----------
35-
drn: distribution option to be used for drainage packages
36-
riv: distribution option to be used for river packages
54+
drn: DISTRIBUTING_OPTION
55+
distribution option to be used for drainage packages, defaults to
56+
``by_corrected_transmissivity``.
57+
riv: DISTRIBUTING_OPTION
58+
distribution option to be used for river packages, defaults to
59+
``by_corrected_transmissivity``.
60+
ghb: DISTRIBUTING_OPTION
61+
distribution option to be used for general head boundary packages,
62+
defaults to ``by_layer_transmissivity``.
63+
64+
Examples
65+
--------
66+
67+
Initiate default distributing options
68+
69+
>>> dist_options = SimulationDistributingOptions()
70+
71+
You can set different options as follows:
72+
73+
>>> from imod.prepare.topsystem import DISTRIBUTING_OPTION
74+
>>> dist_options.riv = DISTRIBUTING_OPTION.by_layer_transmissivity
3775
3876
"""
3977

imod/tests/test_mf6/test_mf6_LHM.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ def LHM_imod5_data():
5050
simulation = Modflow6Simulation.from_imod5_data(
5151
imod5_data,
5252
period_data,
53+
times,
5354
default_simulation_allocation_options,
5455
default_simulation_distributing_options,
55-
times,
5656
regridding_option,
5757
)
5858
simulation["imported_model"]["oc"] = OutputControl(

imod/tests/test_mf6/test_mf6_simulation.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -491,9 +491,9 @@ def test_import_from_imod5(imod5_dataset, tmp_path):
491491
simulation = Modflow6Simulation.from_imod5_data(
492492
imod5_data,
493493
period_data,
494+
datelist,
494495
default_simulation_allocation_options,
495496
default_simulation_distributing_options,
496-
datelist,
497497
)
498498
simulation["imported_model"]["oc"] = OutputControl(
499499
save_head="last", save_budget="last"
@@ -527,9 +527,9 @@ def test_from_imod5__strict_well_validation_set(imod5_dataset):
527527
simulation = Modflow6Simulation.from_imod5_data(
528528
imod5_data,
529529
period_data,
530+
datelist,
530531
default_simulation_allocation_options,
531532
default_simulation_distributing_options,
532-
datelist,
533533
)
534534
assert simulation._validation_context.strict_well_validation is False
535535
assert Modflow6Simulation("test")._validation_context.strict_well_validation is True
@@ -554,9 +554,9 @@ def test_import_from_imod5__correct_well_type(imod5_dataset):
554554
simulation = Modflow6Simulation.from_imod5_data(
555555
imod5_data,
556556
period_data,
557+
datelist,
557558
default_simulation_allocation_options,
558559
default_simulation_distributing_options,
559-
datelist,
560560
)
561561
# Set layer back to right value (before AssertionError might be thrown)
562562
imod5_data["wel-WELLS_L3"]["layer"] = original_wel_layer
@@ -583,9 +583,9 @@ def test_import_from_imod5__nonstandard_regridding(imod5_dataset, tmp_path):
583583
simulation = Modflow6Simulation.from_imod5_data(
584584
imod5_data,
585585
period_data,
586+
times,
586587
default_simulation_allocation_options,
587588
default_simulation_distributing_options,
588-
times,
589589
regridding_option,
590590
)
591591
simulation["imported_model"]["oc"] = OutputControl(
@@ -621,9 +621,9 @@ def test_import_from_imod5_no_storage_no_recharge(imod5_dataset, tmp_path):
621621
simulation = Modflow6Simulation.from_imod5_data(
622622
imod5_data,
623623
period_data,
624+
times,
624625
default_simulation_allocation_options,
625626
default_simulation_distributing_options,
626-
times,
627627
)
628628
simulation["imported_model"]["oc"] = OutputControl(
629629
save_head="last", save_budget="last"

0 commit comments

Comments
 (0)