Changelog#
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.18.1] - 2024-11-20#
Added#
imod.prepare.topsystem.SimulationAllocationOptions
,imod.prepare.topsystem.SimulationDistributingOptions
, which are used to store default allocation and distributing options respectively.
Fixed#
Relaxed validation for imod.mf6.StructuredDiscretization to also support cells with zero thickness where IDOMAIN = 0. Before, only cells with a zero thickness and IDOMAIN = -1 were supported, else the software threw a
not all values comply with criterion: > bottom
.Fix bug where no
ValidationError
was thrown if there is an active RCH, DRN, GHB, or RIV cell where idomain = -1.
Changed#
In
imod.mf6.Modflow6Simulation.from_imod5_data()
, andimod.mf6.GroundwaterFlowModel.from_imod5_data()
the argumentsallocation_options
,distributing_options
are now optional.The order of arguments of
imod.mf6.Modflow6Simulation.from_imod5_data()
, andimod.mf6.GroundwaterFlowModel.from_imod5_data()
. It now isimod5_data, period_data, times, allocation_options, distributing_options, regridder_types
instead of:imod5_data, period_data, allocation_options, distributing_options, times, regridder_types
[0.18.0] - 2024-11-11#
Fixed#
Multiple
HorizontalFlowBarrier
objects attached toimod.mf6.GroundwaterFlowModel
are merged into a single horizontal flow barrier for MODFLOW 6.Bug where error would be thrown when barriers in a
HorizontalFlowBarrier
would be snapped to the same cell edge. These are now summed.Improve performance validation upon Package initialization
Improve performance writing
HorizontalFlowBarrier
objectsimod.mf6.open_cbc failing with
flowja=False
on budget output for DISV models if the model contained inactive cells.imod.mf6.open_cbc now works for 2D and 1D models.
imod.prepare.fill()
previously assigned to the result of an xarray.sel
operation. This might not work for dask backed data and has been addressed.Added
imod.mf6.open_dvs()
to read dependent variable output files like the water content file ofimod.mf6.UnsaturatedZoneFlow
.imod.prj.open_projectfile_data is now able to also read IPF data for sprinkling wells in the CAP package.
Fix that caused iMOD Python to break upon import with numpy >=1.23, <2.0 .
ValidationError message now contains a suggestion to use the cleanup method, if available in the erroneous package.
Bug where error was thrown when
imod.mf6.NodePropertyFlow
was assigned toimod.mf6.GroundwaterFlowModel
with key different from"npf"
upon writing, along with well or horizontal flow barrier packages.
Changed#
imod.mf6.Well
now also validates that well filter top is above well filter bottomopen_projectfile_data()
now also imports well filter top and bottom.imod.mf6.Well
now logs a warning if any wells are removed during writing.imod.mf6.HorizontalFlowBarrierResistance
,imod.mf6.HorizontalFlowBarrierMultiplier
,imod.mf6.HorizontalFlowBarrierHydraulicCharacteristic
now uses vertical Polygons instead of Linestrings as geometry, and"ztop"
and"zbottom"
variables are not used anymore. Seeimod.prepare.linestring_to_square_zpolygons()
andimod.prepare.linestring_to_trapezoid_zpolygons()
to generate these polygons.open_projectfile_data()
now returns well data grouped by ipf name, instead of generic, separate number per entry.imod.mf6.Well
now supports wells which have a filter with zero length, where"screen_top"
equals"screen_bottom"
.imod.mf6.Well
shares the same defaultminimum_thickness
asimod.prepare.assign_wells()
, which is 0.05, before this was 1.0.imod.prepare.allocate_drn_cells()
,imod.prepare.allocate_ghb_cells()
,imod.prepare.allocate_riv_cells()
, now allocate to the first model layer when elevations are above or equal to model top for all methods inimod.prepare.ALLOCATION_OPTION()
.imod.mf6.Well.to_mf6_pkg()
got a new argument:strict_well_validation
, which controls the behavior for when wells are removed entirely during their assignment to layers. This replaces theis_partitioned
argument.imod.prepare.fill()
now takes adims
argument instead ofby
, and will fill over N dimensions. Secondly, the function no longer takes aninvalid
argument, but instead always treats NaNs as missing.Reverted the need for providing WriteContext objects to MODFLOW6 Model and Package objects’
write
method. These now use similar arguments to theimod.mf6.Modflow6Simulation.write()
method.imod.msw.CouplingMapping
,imod.msw.Sprinkling
, imod.msw.Sprinkling.MetaSwapModel, now take theimod.mf6.mf6_wel_adapter.Mf6Wel
and theimod.mf6.StructuredDiscretization
packages as arguments at their respectivewrite
method, instead of upon initializing these MetaSWAP objects.imod.msw.CouplingMapping
andimod.msw.Sprinkling
now take theimod.mf6.mf6_wel_adapter.Mf6Wel
as well argument instead of the deprecatedimod.mf6.WellDisStructured
.
Added#
imod.mf6.Modflow6Simulation.from_imod5_data()
to import imod5 data loaded withimod.formats.prj.open_projectfile_data()
as a MODFLOW 6 simulation.imod.prepare.linestring_to_square_zpolygons()
andimod.prepare.linestring_to_trapezoid_zpolygons()
to generate vertical polygons that can be used to specify horizontal flow barriers, specifically:imod.mf6.HorizontalFlowBarrierResistance
,imod.mf6.HorizontalFlowBarrierMultiplier
,imod.mf6.HorizontalFlowBarrierHydraulicCharacteristic
.imod.mf6.LayeredWell
to specify wells directly to layers instead assigning them with filter depths.imod.prepare.cleanup_drn()
,imod.prepare.cleanup_ghb()
,imod.prepare.cleanup_riv()
,imod.prepare.cleanup_wel()
. These are utility functions to clean up drainage, general head boundaries, and rivers, respectively.imod.mf6.Drainage.cleanup()
,imod.mf6.GeneralHeadboundary.cleanup()
,imod.mf6.River.cleanup()
,imod.mf6.Well.cleanup()
convenience methods to call the corresponding cleanup utility functions with the appropriate arguments.imod.msw.MetaSwapModel.regrid_like()
to regrid MetaSWAP models. This is still experimental functionality, regridding theimod.msw.Sprinkling
is not yet supported.The context
imod.util.context.print_if_error()
to print an error instead of raising it in awith
statement. This is useful for code snippets which definitely will fail.imod.msw.MetaSwapModel.regrid_like()
to regrid MetaSWAP models.imod.mf6.GroundwaterFlowModel.prepare_wel_for_mf6()
to prepare wells for MODFLOW6, for debugging purposes.
Removed#
imod.formats.prj.convert_to_disv()
has been removed. This functionality has been replaced byimod.mf6.Modflow6Simulation.from_imod5_data()
. To convert a structured simulation to an unstructured simulation, call:imod.mf6.Modflow6Simulation.regrid_like()
[0.17.2] - 2024-09-17#
Fixed#
imod.formats.prj.open_projectfile_data()
now reports the path to a faulty IPF or IDF file in the error message.Support for Numpy 2.0
Added#
Added objects with regrid settings. These can be used to provide custom settings:
imod.mf6.regrid.ConstantHeadRegridMethod
,imod.mf6.regrid.DiscretizationRegridMethod
,imod.mf6.regrid.DispersionRegridMethod
,imod.mf6.regrid.DrainageRegridMethod
,imod.mf6.regrid.EmptyRegridMethod
,imod.mf6.regrid.EvapotranspirationRegridMethod
,imod.mf6.regrid.GeneralHeadBoundaryRegridMethod
,imod.mf6.regrid.InitialConditionsRegridMethod
,imod.mf6.regrid.MobileStorageTransferRegridMethod
,imod.mf6.regrid.NodePropertyFlowRegridMethod
,imod.mf6.regrid.RechargeRegridMethod
,imod.mf6.regrid.RiverRegridMethod
,imod.mf6.regrid.SpecificStorageRegridMethod
,imod.mf6.regrid.StorageCoefficientRegridMethod
.
Changed#
Instead of providing a dictionary with settings to
Package.regrid_like
, provide one of the followingRegridMethod
objects:imod.mf6.regrid.ConstantHeadRegridMethod
,imod.mf6.regrid.DiscretizationRegridMethod
,imod.mf6.regrid.DispersionRegridMethod
,imod.mf6.regrid.DrainageRegridMethod
,imod.mf6.regrid.EmptyRegridMethod
,imod.mf6.regrid.EvapotranspirationRegridMethod
,imod.mf6.regrid.GeneralHeadBoundaryRegridMethod
,imod.mf6.regrid.InitialConditionsRegridMethod
,imod.mf6.regrid.MobileStorageTransferRegridMethod
,imod.mf6.regrid.NodePropertyFlowRegridMethod
,imod.mf6.regrid.RechargeRegridMethod
,imod.mf6.regrid.RiverRegridMethod
,imod.mf6.regrid.SpecificStorageRegridMethod
,imod.mf6.regrid.StorageCoefficientRegridMethod
.Renamed
imod.mf6.LayeredHorizontalFlowBarrier
classes toimod.mf6.SingleLayerHorizontalFlowBarrierResistance
,imod.mf6.SingleLayerHorizontalFlowBarrierHydraulicCharacteristic
,imod.mf6.SingleLayerHorizontalFlowBarrierMultiplier
,
Fixed#
imod.formats.prj.open_projectfile_data()
now reports the path to a faulty IPF or IDF file in the error message.
[0.17.1] - 2024-05-16#
Added#
Added function
imod.util.spatial.gdal_compliant_grid()
to make spatial coordinates of a NetCDF interpretable for GDAL (and so QGIS).Added
crs
argument toimod.util.spatial.mdal_compliant_ugrid2d()
,imod.mf6.Simulation.dump()
,imod.mf6.GroundwaterFlowModel.dump()
,imod.mf6.GroundwaterTransportModel.dump()
, to add a coordinate reference system to dumped files, to ease loading them in QGIS.
Changed#
imod.mf6.Simulation.dump()
,imod.mf6.GroundwaterFlowModel.dump()
,imod.mf6.GroundwaterTransportModel.dump()
write with necessary attributes to NetCDF to make these files interpretable for GDAL (and so QGIS).
Fixed#
Fix missing API docs for
dump
andwrite
methods.
[0.17.0] - 2024-05-13#
Added#
Added functions to allocate planar grids over layers for the topsystem in
imod.prepare.allocate_drn_cells()
,imod.prepare.allocate_ghb_cells()
,imod.prepare.allocate_rch_cells()
,imod.prepare.allocate_riv_cells()
, for this multiple options can be selected, available inimod.prepare.ALLOCATION_OPTION()
.Added functions to distribute conductances of planar grids over layers for the topsystem in
imod.prepare.distribute_riv_conductance()
,imod.prepare.distribute_drn_conductance()
,imod.prepare.distribute_ghb_conductance()
, for this multiple options can be selected, available inimod.prepare.DISTRIBUTING_OPTION()
.imod.prepare.celltable()
supports an optionaldtype
argument. This can be used, for example, to create celltables of float values.Added
fixed_cell
option toimod.mf6.Recharge
. This option is relevant for phreatic models, not using the Newton formulation and model cells can become inactive. The prefered method for phreatic models is to use the Newton formulation, where cells remain active, and this option irrelevant.Added support for
ats_outer_maximum_fraction
inimod.mf6.Solution
.Added validation for
linear_acceleration
,rclose_option
,scaling_method
,reordering_method
,print_option
andno_ptc
entries inimod.mf6.Solution
.
Fixed#
No
ValidationError
thrown anymore inimod.mf6.River
whenbottom_elevation
equalsbottom
in the model discretization.When wells outside of the domain are added, an exception is raised with an error message stating a well is outside of the domain.
When importing data from a .prj file, the multipliers and additions specified for ipf and idf files are now applied
Fix bug where y-coords were flipped in
imod.msw.MeteoMapping
Changed#
Replaced csv_output by outer_csvfile and inner_csvfile in
imod.mf6.Solution
to match newer MODFLOW 6 releases.Changed no_ptc from a bool to an option string in
imod.mf6.Solution
.Removed constructor arguments source and target from
imod.mf6.utilities.regrid.RegridderWeightsCache
, as they were not used.imod.mf6.open_cbc()
now returns arrays which contain np.nan for cells where budget variables are not defined. Based on new budget output a disquisition between active cells but zero flow and inactive cells can be made.imod.mf6.open_cbc()
now returns package type in return budget names. New format is “package type”-“optional package variable”_”package name”. E.g. a River package namedprimary-sys
will get a budget nameriv_primary-sys
. An UZF package with nameuzf-sys1
will get a budget nameuzf-gwrch_uzf-sys1
for the groundwater recharge budget from the UZF-CBC.
[0.16.0] - 2024-03-29#
Added#
The
imod.mf6.model.mask_all_packages()
now also masks the idomain array of the model discretization, and can be used with a mask array without a layer dimension, to mask all layers the same wayValidation for incompatible settings in the
imod.mf6.NodePropertyFlow
andimod.mf6.Dispersion
packages.Checks that only one flow model is present in a simulation when calling
imod.mf6.Modflow6Simulation.regrid_like()
,imod.mf6.Modflow6Simulation.clip_box()
orimod.mf6.Modflow6Simulation.split()
Added support for coupling a GroundwaterFlowModel and Transport Model i.c.w. the 6.4.3 release of MODFLOW. Using an older version of iMOD Python with this version of MODFLOW will result in an error.
imod.mf6.Modflow6Simulation.split()
supports splitting transport models, including multi-species simulations.imod.mf6.Modflow6Simulation.open_concentration()
andimod.mf6.Modflow6Simulation.open_transport_budget()
support opening split multi-species simulations.imod.mf6.Modflow6Simulation.regrid_like()
can now regrid simulations that have 1 or more transport models.added logging to various initialization methods, write methods and dump methods. See the documentation how to activate logging.
added
imod.data.hondsrug_simulation()
andimod.data.hondsrug_crosssection()
data.simulations and models that include a lake package now raise an exception on clipping, partitioning or regridding.
Changed#
imod.mf6.Modflow6Simulation.open_concentration()
andimod.mf6.Modflow6Simulation.open_transport_budget()
raise aValueError
ifspecies_ls
is provided with incorrect length.
Fixed#
Incorrect validation error
data values found at nodata values of idomain
for boundary condition packages with a scalar coordinate not set as dimension.Fix issue where
imod.idf.open_subdomains()
andimod.mf6.Modflow6Simulation.open_head()
(for split simulations) would return arrays with incorrectdx
anddy
coordinates for equidistant data.Fix issue where
imod.idf.open_subdomains()
returned a flippeddy
coordinate for nonequidistant data.Made
imod.util.round_extent()
available again, as it was moved without notice. Function now throws a DeprecationWarning to useimod.prepare.spatial.round_extent()
instead.:meth’imod.mf6.Modflow6Simulation.write failed after splitting the simulation. This has been fixed.
modflow options like “print flow”, “save flow”, and “print input” can now be set on
imod.mf6.Well
when regridding a
imod.mf6.Modflow6Simulation
,imod.mf6.GroundwaterFlowModel
,imod.mf6.GroundwaterTransportModel
or aimod.mf6.package
, regridding weights are now cached and can be re-used over the different objects that are regridded. This improves performance considerably in most use cases: when regridding is applied over the same grid cells with the same regridder type, but with different values/methods, multiple times.
[0.15.3] - 2024-02-22#
Fixed#
Add missing required dependencies for installing with
pip
: loguru and tomli.Ensure geopandas and shapely are optional dependencies again when installing with
pip
, and no import errors are thrown.Fixed bug where calling
copy.deepcopy
onimod.mf6.Modflow6Simulation
,imod.mf6.GroundwaterFlowModel
andimod.mf6.GroundwaterTransportModel
objects threw an error.
Added#
Developer environment: Added pixi environment
interactive
to interactively run code. Can be useful to plot data.imod.mf6.ApiPackage
was added. It can be added to both flow and transport models, and its presence allows users to interact with libMF6.dll through its API.Developer environment: Empty python 3.10, 3.11, 3.12 environments where pip install and import imod can be tested.
[0.15.2] - 2024-02-16#
Fixed#
iMOD Python now supports versions of pandas >= 2
Fixed bugs with clipping
imod.mf6.HorizontalFlowBarrier
for structured gridsPackages and boundary conditions in the
imod.mf6
module will now throw an error upon initialization if coordinate labels are inconsistent amongst variablesImproved performance for merging structured multimodel Modflow 6 output
Bug where
imod.formats.idf.open_subdomains()
did not properly support custom patternsAdded missing validation for
concentration
forimod.mf6.Drainage
andimod.mf6.EvapoTranspiration
packageAdded validation
imod.mf6.Well
package, nonp.nan
values are allowedFix support for coupling a GroundwaterFlowModel and Transport Model i.c.w. the 6.4.3 release of MODFLOW. Using an older version of iMOD Python with this version of MODFLOW will result in an error.
Changed#
We moved to using pixi to create development environments. This replaces the
imod-environment.yml
conda environment. We advice doing development installations with pixi from now on. See the documentation. This does not affect users who installed withpip install imod
,mamba install imod
orconda install imod
.Changed build system from
setuptools
tohatchling
. Users who did a development install are adviced to runpip uninstall imod
andpip install -e .
again. This does not affect users who installed withpip install imod
,mamba install imod
orconda install imod
.Decreased lower limit of MetaSWAP validation for x and y limits in the
IdfMapping
from 0 to -9999999.0.
[0.15.1] - 2023-12-22#
Fixed#
Made
specific_yield
optional argument inimod.mf6.SpecificStorage
,imod.mf6.StorageCoefficient
.Fixed bug where simulations with
imod.mf6.Well
were not partitioned into multiple models.Fixed erroneous default value for the
out_of_bounds
inimod.select.points.point_values()
Fixed bug where
imod.mf6.Well
could not be assigned to the first cell of an unstructured grid.HorizontalFlowBarrier package now dropped if completely outside partition in a split model.
HorizontalFlowBarrier package clipped with
clip_by_grid
based on active cells, consistent with how other packages are treated by this function. This affects theimod.mf6.HorizontalFlowBarrier.regrid_like()
andimod.mf6.Modflow6Simulation.split()
methods.
Changed#
All the references to GitLab have been replaced by GitHub references as part of the GitHub migration.
Added#
Added comment in Modflow6 exchanges file (GWFGWF) denoting column header.
Added Python 3.11 support.
The GWF-GWF exchange options are derived from user created packages (NPF, OC) and set automatically.
Added the
simulation_start_time
andtime_unit
arguments. To theModflow6Simulation.open_
methods, andimod.mf6.out.open_
functions. This converts the"time"
coordinate to datetimes.added
imod.mf6.Modflow6Simulation.mask_all_models()
to apply a mask to all models under a simulation, provided the simulation is not split and the models use the same discretization.
Changed#
imod.mf6.Well.mask()
masks with a 2D grid instead of returning a deepcopy of the package.
[0.15.0] - 2023-11-25#
Fixed#
The Newton option for a
imod.mf6.GroundwaterFlowModel
was being ignored. This has been corrected.The Contextily packages started throwing errors. This was caused because the default tile provider being used was Stamen. However Stamen is no longer free which caused Contextily to fail. The default tile provider has been changed to OpenStreetMap to resolve this issue.
imod.mf6.open_cbc()
now reads saved cell saturations and specific discharges.imod.mf6.open_cbc()
failed to read unstructured budgets stored following IMETH1, most importantly the storage fluxes.Fixed support of Python 3.11 by dropping the obsolete
qgs
module.Bug in
imod.mf6.SourceSinkMixing
where, in case of multiple active boundary conditions with assigned concentrations, it would write a.ssm
file with all sources/sinks on one single row.Fixed bug where TypeError was thrown upond calling
imod.mf6.HorizontalFlowBarrier.regrid_like()
andimod.mf6.HorizontalFlowBarrier.mask()
.Fixed bug where calling
imod.mf6.Well.clip_box()
over only the time dimension would remove the index coordinate.Validation errors are rendered properly when writing a simulation object or regridding a model object.
Changed#
The imod-environment.yml file has been split in an imod-environment.yml (containing all packages required to run imod-python) and a imod-environment-dev.yml file (containing additional packages for developers).
Changed the way
imod.mf6.Modflow6Simulation
,imod.mf6.GroundwaterFlowModel
,imod.mf6.GroundwaterTransportModel
, and Modflow 6 packages are represented while printing.The grid-agnostic packages
imod.mf6.Well.regrid_like()
andimod.mf6.HorizontalFlowBarrier.regrid_like()
now return a clip with the grid exterior of the target grid
Added#
The unit tests results are now published on GitLab
A
save_saturation
option toimod.mf6.NodePropertyFlow
which saves cell saturations for unconfined flow.Functions
imod.prepare.layer.get_upper_active_layer_number()
andimod.prepare.layer.get_lower_active_layer_number()
to return planar grids with numbers of the highest and lowest active cells respectively.Functions
imod.prepare.layer.get_upper_active_grid_cells()
andimod.prepare.layer.get_lower_active_grid_cells()
to return boolean grids designating respectively the highest and lowest active cells in a grid.validation of
transient
argument inimod.mf6.StorageCoefficient
andimod.mf6.SpecificStorage
.imod.mf6.Modflow6Simulation.open_concentration()
,imod.mf6.Modflow6Simulation.open_head()
,imod.mf6.Modflow6Simulation.open_transport_budget()
, andimod.mf6.Modflow6Simulation.open_flow_budget()
, were added as convenience methods to open simulation output easier (without having to specify paths).The
imod.mf6.Modflow6Simulation.split()
method has been added. This method makes it possible for a user to create a Multi-Model simulation. A user needs to provide a submodel label array in which they specify to which submodel a cell belongs. The method will then create the submodels and split the nested packages. The split method will create the gwfgwf exchanges required to connect the submodels. At the moment auxiliary variablescdist
andangldegx
are only computed for structured grids.The label array can be generated through a convenience function
imod.mf6.partition_generator.get_label_array()
Once a split simulation has been executed by MF6, we find head and balance results in each of the partition models. These can now be merged into head and balance datasets for the original domain using
imod.mf6.Modflow6Simulation.open_concentration()
,imod.mf6.Modflow6Simulation.open_head()
,imod.mf6.Modflow6Simulation.open_transport_budget()
,imod.mf6.Modflow6Simulation.open_flow_budget()
. In the case of balances, the exchanges through the partition boundary are not yet added to this merged balance.Settings such as
save_flows
can be passed throughimod.mf6.SourceSinkMixing.from_flow_model()
Added
imod.mf6.LayeredHorizontalFlowBarrierHydraulicCharacteristic
,imod.mf6.LayeredHorizontalFlowBarrierMultiplier
,imod.mf6.LayeredHorizontalFlowBarrierResistance
, for horizontal flow barriers with a specified layer number.
Removed#
Tox has been removed from the project.
Dropped support for writing .qgs files directly for QGIS, as this was hard to maintain and rarely used. To export your model to QGIS readable files, call the
dump
methodimod.mf6.Modflow6Simulation
withmdal_compliant=True
. This writes UGRID NetCDFs which can read as meshes in QGIS.Removed
declxml
from repository.
[0.14.1] - 2023-09-07#
Changed#
TWRI Modflow 6 example uses the grid-agnostic
imod.mf6.Well
package instead of theimod.mf6.WellDisStructured
package.
Fixed#
imod.mf6.HorizontalFlowBarrier
would write to a binary file by default. However, the current version of Modflow 6 does not support this. Therefore, this class now always writes to text file.
[0.14.0] - 2023-09-06#
Changed#
imod.mf6.HorizontalFlowBarrier
is specified by providing a geopandas GeoDataFrame
Added#
imod.mf6.Modflow6Simulation.regrid_like()
to regrid a Modflow6 simulation to a new grid (structured or unstructured), using xugrid’s regridding functionality. Variables are regridded with pre-selected methods. The regridding functionality is useful for a variety of applications, for example to test the effect of different grid sizes, to add detail to a simulation (by refining the grid) or to speed up a simulation (by coarsening the grid) to name a fewimod.mf6.Package.regrid_like()
to regrid packages. The user can specify their own custom regridder types and methods for variables.imod.mf6.Modflow6Simulation.clip_box()
got an extra argumentstates_for_boundary
, which takes a dictionary with modelname as key and griddata as value. This data is specified as fixed state on the model boundary. At present only imod.mf6.GroundwaterFlowModel is supported, grid data is specified as aimod.mf6.ConstantHead
at the model boundary.imod.mf6.Well
, a grid-agnostic well package, where wells can be specified based on their x,y coordinates and filter top and bottom.
[0.13.2] - 2023-07-26#
Changed#
imod.rasterio.save()
will now write ESRII ASCII rasters, even if rasterio is not installed. A fallback function has been added specifically for ASCII rasters.
Fixed#
Geopandas and rasterio were imported at the top of a module in some places. This has been fixed so that both are not optional dependencies when installing via pip (installing via conda or mamba will always pull all dependencies and supports full functionality).
imod.mf6.Modflow6Simulation._validate()
now print all validation errors for all models and packages in one message.The gen file reader can now handle feature id’s that contain commas and spaces
imod.mf6.EvapoTranspiration
now supports segments, by adding asegment
dimension to theproportion_depth
andproportion_rate
variables.imod.mf6.EvapoTranspiration
template for.evt
file now properly formatsnseg
option.Fixed bug in
imod.wq.Well
preventing saving wells without a time dimension, but with a layer dimension.imod.mf6.DiscretizationVertices._validate
threwKeyError
for"bottom"
when validating the package separately.
Added#
imod.select.grid.active_grid_boundary_xy()
&imod.select.grid.grid_boundary_xy()
are added to find grid boundaries.
[0.13.1] - 2023-05-05#
Added#
imod.mf6.SpecificStorage
andimod.mf6.StorageCoefficient
now have asave_flow
argument.
Fixed#
imod.mf6.open_cbc()
can now read storage fluxes without error.
[0.13.0] - 2023-05-02#
Added#
imod.mf6.OutputControl
now takes parametershead_file
,concentration_file
, andbudget_file
to specify where to store MODFLOW6 output files.imod.util.spatial.from_mdal_compliant_ugrid2d()
to “restack” the variables that have have been “unstacked” inimod.util.spatial.mdal_compliant_ugrid2d()
.Added support for the Modflow6 Lake package
imod.select.points_in_bounds()
,imod.select.points_indices()
,imod.select.points_values()
now support unstructured grids.Added support for the Modflow 6 Lake package:
imod.mf6.Lake
,imod.mf6.LakeData
,imod.mf6.OutletManning
,OutletSpecified
,OutletWeir
. See the examples for an application of the Lake package.imod.mf6.simulation.Modflow6Simulation.dump()
now supports dumping to MDAL compliant ugrids. These can be used to view and explore Modlfow 6 simulations in QGIS.
Fixed#
imod.wq.bas.BasicFlow.thickness()
returns a DataArray with the correct dimension order again. This confusingly resulted in an error when writing theimod.wq.btn.BasicTransport
package.Fixed bug in
imod.mf6.dis.StructuredDiscretization
andimod.mf6.dis.VerticesDiscretization
whereinactive bottom above active cell
was incorrectly raised.
[0.12.0] - 2023-03-17#
Added#
imod.prj.read_projectfile()
to read the contents of a project file into a Python dictionary.imod.prj.open_projectfile_data()
to read/open the data that is pointed to in a project file.imod.gen.read_ascii()
to read the geometry stored in ASCII text .gen files.imod.mf6.hfb.HorizontalFlowBarrier
to support Modflow6’s HFB package, works well with xugrid.snap_to_grid function.imod.mf6.simulation.Modflow6Simulation.dump()
to dump a simulation to a toml file which acts as a definition file, pointing to packages written as netcdf files. This can be used to intermediately store Modflow6 simulations.
Fixed#
imod.evaluate.budget.flow_velocity()
now properly computes velocity by dividing by the porosity. Before, this function computed the Darcian velocity.
Changed#
imod.ipf.save()
will error on duplicate IDs for associated files if a"layer"
column is present. As a dataframe is automatically broken down into a single IPF per layer, associated files for the first layer would be overwritten by the second, and so forth.imod.wq.Well.save()
will now write time varying data to associated files for extration rate and concentration.Choosing
method="geometric_mean"
in the Regridder will now result in NaN values in the regridded result if a geometric mean is computed over negative values; in general, a geometric mean should only be computed over physical quantities with a “true zero” (e.g. conductivity, but not elevation).
[0.11.6] - 2023-02-01#
Added#
Added an extra optional argument in
imod.couplers.metamod.MetaMod.write()
namedmodflow6_write_kwargs
, which can be used to provide keyword arguments to the writing of the Modflow 6 Simulation.
Fixed#
imod.mf6.out.disv.read_grb()
Remove repeated construction ofUgridDataArray
fortop
[0.11.5] - 2022-12-15#
Fixed#
imod.mf6.Modflow6Simulation.write()
withbinary=False
no longer results in invalid MODFLOW6 input for 2D grid data, such as DIS top.imod.flow.ImodflowModel.write()
no longer writes incorrect project files for non-grid values with a time and layer dimension.imod.evaluate.interpolate_value_boundaries()
: Fix edge case when successive values in z direction are exactly equal to the boundary value.
Changed#
Removed
meshzoo
dependency.Minor changes to
imod.gen.gen
backend, to support Shapely 2.0 , Shapely version above equal v1.8 is now required.
Added#
imod.flow.ImodflowModel.write()
now supports writing aconfig_run.ini
to convert the projectfile to a runfile or modflow 6 namfile with iMOD5.Added validation of Modflow6 Flow and Transport models. Incorrect model input will now throw a
ValidationError
. To turn off the validation, setvalidate=False
upon package initialization and/or when callingimod.mf6.Modflow6Simulation.write()
.
[0.11.4] - 2022-09-05#
Fixed#
imod.mf6.GroundwaterFlowModel.write()
will no longer error when a 3D DataArray with a single layer is written. It will now accept both 2D and 3D arrays with a single layer coordinate.Hotfixes for
imod.wq.model.SeawatModel.clip()
, until this merge request is fulfilled.imod.flow.ImodflowModel.write()
will set the timestring in the projectfile tosteady-state
forBoundaryConditions
without a time dimension.Added
imod.flow.OutputControl
as this was still missing.imod.ipf.read()
will no longer error when an associated files with 0 rows is read.imod.evaluate.calculate_gxg()
now correctly uses (March 14, March 28, April 14) to calculate GVG rather than (March 28, April 14, April 28).imod.mf6.out.open_cbc()
now correctly loads boundary fluxes.imod.prepare.LayerRegridder.regrid()
will now correctly skip values iftop_source
orbottom_source
are NaN.imod.gen.write()
no longer errors on dataframes with empty columns.imod.mf6.BoundaryCondition.set_repeat_stress()
reinstated. This is a temporary measure, it gives a deprecation warning.
Changed#
Deprecate the current documentation URL: https://imod.xyz. For the coming months, redirection is automatic to: https://deltares.gitlab.io/imod/imod-python/.
imod.ipf.save()
will now store associated files in separate directories namedlayer1
,layer2
, etc. The ID in the main IPF file is updated accordingly. Previously, if IDs were shared between different layers, the associated files would be overwritten as the IDs would result in the same file name being used over and over.imod.flow.ImodflowModel.time_discretization()
,imod.wq.SeawatModel.time_discretization()
,imod.mf6.Modflow6Simulation.time_discretization()
, are renamed to:imod.flow.ImodflowModel.create_time_discretization()
,imod.wq.SeawatModel.create_time_discretization()
,imod.mf6.Modflow6Simulation.create_time_discretization()
,Moved tests inside imod directory, added an entry point for pytest fixtures. Running the tests now requires an editable install, and also existing installations have to be reinstalled to run the tests.
The
imod.mf6
model packages now all run type checks on input. This is a breaking change for scripts which provide input with an incorrect dtype.imod.mf6.Solution
now requires a model_names argument to specify which models should be solved in a single numerical solution. This is required to simulate groundwater flow and transport as they should be in separate solutions.When writing MODFLOW6 input option blocks, a NaN value is now recognized as an alternative to None (and the entry will not be included in the options block).
Added#
Added support to write MetaSWAP models,
imod.msw.MetaSwapModel
.Addes support to write coupled MetaSWAP and Modflow6 simulations,
imod.couplers.MetaMod
imod.util.replace()
has been added to find and replace different values in a DataArray.imod.evaluate.calculate_gxg_points()
has been added to compute GXG values for time varying point data (i.e. loaded from IPF and presented as a Pandas dataframe).imod.evaluate.calculate_gxg()
will return the number of years used in the GxG calculation as separate variables in the output dataset.imod.visualize.spatial.plot_map()
now accepts a fix and ax argument, to enable adding maps to existing axes.imod.flow.ImodflowModel.create_time_discretization()
,imod.wq.SeawatModel.create_time_discretization()
,imod.mf6.Modflow6Simulation.create_time_discretization()
, now have a documentation section.imod.mf6.GroundwaterTransportModel
has been added with associated simple classes to allow creation of solute transport models. Advanced boundary conditions such as LAK or UZF are not yet supported.imod.mf6.Buoyancy
has been added to simulate density dependent groundwater flow.
[0.11.1] - 2021-12-23#
Fixed#
contextily
,geopandas
,pyvista
,rasterio
, andshapely
are now fully optional dependencies. Import errors are only raised when accessing functionality that requires their use.Include declxml as
imod.declxml
(should be internal use only!): declxml is no longer maintained on the official repository: gatkin/declxml. Furthermore, it has no conda feedstock, which makes distribution via conda difficult.
[0.11.0] - 2021-12-21#
Fixed#
imod.ipf.read()
accepts list of file names.imod.mf6.open_hds()
did not read the appropriate bytes from the heads file, apart for the first timestep. It will now read the right records.Use the appropriate array for modflow6 timestep duration: the
imod.mf6.GroundwaterFlowModel.write()
would write the timesteps multiplier in place of the duration array.imod.mf6.GroundwaterFlowModel.write()
will now respect the layer coordinate of DataArrays that had multiple coordinates, but were discontinuous from 1; e.g. layers [1, 3, 5] would’ve been transformed to [1, 2, 3] incorrectly.imod.mf6.Modflow6Simulation.write()
will no longer change working directory while writing model input – this could lead to errors when multiple processes are writing models in parallel.imod.prepare.laplace_interpolate()
will no longer ZeroDivisionError when given a value foribound
.
Added#
imod.idf.open_subdomains()
will now also accept iMOD-WQ output of multiple species runs.imod.wq.SeawatModel.to_netcdf()
has been added to write all model packages to netCDF files.imod.mf6.open_cbc()
has been added to read the budget data of structured (DIS) MODFLOW6 models. The data is read lazily into xarray DataArrays per timestep.imod.visualize.streamfunction()
andimod.visualize.quiver()
were added to plot a 2D representation of the groundwater flow field using either streamlines or quivers over a cross section plot (imod.visualize.cross_section()
).imod.evaluate.streamfunction_line()
andimod.evaluate.streamfunction_linestring()
were added to extract the 2D projected streamfunction of the 3D flow field for a given cross section.imod.evaluate.quiver_line()
andimod.evaluate.quiver_linestring()
were added to extract the u and v components of the 3D flow field for a given cross section.Added
imod.mf6.GroundwaterFlowModel.write_qgis_project()
to write a QGIS project for easier inspection of model input in QGIS.Added
imod.wq.SeawatModel.clip()
to clip a model to a provided extent. Boundary conditions of clipped model can be automatically derived from parent model calculation results and are applied along the edges of the extent.Added
imod.gen.read()
andimod.gen.write()
for reading and writing binary iMOD GEN files to and from geopandas GeoDataFrames.Added
imod.prepare.zonal_aggregate_raster()
andimod.prepare.zonal_aggregate_polygons()
to efficiently compute zonal aggregates for many polygons (e.g. the properties every individual ditch in the Netherlands).Added
imod.flow.ImodflowModel
to write to model iMODFLOW project file.imod.mf6.Modflow6Simulation.write()
now has abinary
keyword. When set toFalse
, all MODFLOW6 input is written to text rather than binary files.Added
imod.mf6.DiscretizationVertices
to write MODFLOW6 DISV model input.Packages for
imod.mf6.GroundwaterFlowModel
will now acceptxugrid.UgridDataArray
objects for (DISV) unstructured grids, next toxarray.DataArray
objects for structured (DIS) grids.Transient wells are now supported in
imod.mf6.WellDisStructured
andimod.mf6.WellDisVertices
.imod.util.to_ugrid2d()
has been added to convert a (structured) xarray DataArray or Dataset to a quadrilateral UGRID dataset.Functions created to create empty DataArrays with greater ease:
imod.util.empty_2d()
,imod.util.empty_2d_transient()
,imod.util.empty_3d()
, andimod.util.empty_3d_transient()
.imod.util.where()
has been added for easier if-then-else operations, especially for preserving NaN nodata values.imod.mf6.Modflow6Simulation.run()
has been added to more easily run a model, especially in examples and tests.imod.mf6.open_cbc()
andimod.mf6.open_hds()
will automatically return axugrid.UgridDataArray
for MODFLOW6 DISV model output.
Changed#
Documentation overhaul: different theme, add sample data for examples, add Frequently Asked Questions (FAQ) section, restructure API Reference. Examples now ru
Datetime columns in IPF associated files (via
imod.ipf.write_assoc()
) will not be placed within quotes, as this can break certain iMOD batch functions.imod.mf6.Well
has been renamed intoimod.mf6.WellDisStructured
.imod.mf6.GroundwaterFlowModel.write()
will now write package names into the simulation namefile.imod.mf6.open_cbc()
will now return a dictionary with keysflow-front-face, flow-lower-face, flow-right-face
for the face flows, rather thanfront-face-flow
for better consistency.Switched to composition from inheritance for all model packages: all model packages now contain an internal (xarray) Dataset, rather than inheriting from the xarray Dataset.
imod.mf6.SpecificStorage
orimod.mf6.StorageCoefficient
is now mandatory for every MODFLOW6 model to avoid accidental steady-state configuration.
Removed#
Module
imod.tec
for reading Tecplot files has been removed.
[0.10.1] - 2020-10-19#
Changed#
imod.wq.SeawatModel.write()
now generates iMOD-WQ runfiles with more intelligent use of the “macro tokens”.:
is used exclusively for ranges;$
is used to signify all layers. (This makes runfiles shorter, speeding up parsing, which takes a significant amount of time in the runfile to namefile conversion of iMOD-WQ.)Datetime formats are inferred based on length of the time string according to
%Y%m%d%H%M%S
; supported lengths 4 (year only) to 14 (full format string).
Added#
imod.wq.MassLoading
andimod.wq.TimeVaryingConstantConcentration
have been added to allow additional concentration boundary conditions.IPF writing methods support an
assoc_columns
keyword to allow greater flexibility in including and renaming columns of the associated files.Optional basemap plotting has been added to
imod.visualize.plot_map()
.
Fixed#
IO methods for IDF files will now correctly identify double precision IDFs. The correct record length identifier is 2295 rather than 2296 (2296 was a typo in the iMOD manual).
imod.wq.SeawatModel.write()
will now write the correct path for recharge package concentration given in IDF files. It did not prepend the name of the package correctly (resulting in paths likeconcentration_l1.idf
instead ofrch/concentration_l1.idf
).imod.idf.save()
will simplify constant cellsize arrays to a scalar value – this greatly speeds up drawing in the iMOD-GUI.
[0.10.0] - 2020-05-23#
Changed#
imod.wq.SeawatModel.write()
no longer automatically appends the model name to the directory where the input is written. Instead, it simply writes to the directory as specified.imod.select.points_set_values()
returns a new DataArray rather than mutating the inputda
.imod.select.points_values()
returns a DataArray with an index taken from the data of the first provided dimensions if it is apandas.Series
.imod.wq.SeawatModel.write()
now writes a runfile withstart_hour
andstart_minute
(this results in output IDFs with datetime format"%Y%m%d%H%M"
).
Added#
from_file()
constructors have been added to all imod.wq.Package. This allows loading directly package from a netCDF file (or any file supported byxarray.open_dataset
), or a path to a Zarr directory with suffix “.zarr” or “.zip”.This can be combined with the cache argument in
from_file()
to enable caching of answers to avoid repeated computation duringimod.wq.SeawatModel.write()
; it works by checking whether input and output files have changed.The
resultdir_is_workspace
argument has been added toimod.wq.SeawatModel.write()
. iMOD-wq writes a number of files (e.g. list file) in the directory where the runfile is located. This results in mixing of input and output. By setting itTrue
, all model output is written in the results directory.imod.visualize.imshow_topview()
has been added to visualize a complete DataArray with atleast dimensionsx
andy
; it dumps PNGs into a specified directory.Some support for 3D visualization has been added.
imod.visualize.grid_3d()
andimod.visualize.line_3d()
have been added to producepyvista
meshes fromxarray.DataArray
’s andshapely
polygons, respectively.imod.visualize.GridAnimation3D
andimod.visualize.StaticGridAnimation3D
have been added to setup 3D animations of DataArrays with transient data.Support for out of core computation by
imod.prepare.Regridder
ifsource
is chunked.imod.ipf.read()
now reports the problematic file if reading errors occur.imod.prepare.polygonize()
added to polygonize DataArrays to GeoDataFrames.Added more support for multiple species imod-wq models, specifically: scalar concentration for boundary condition packages and well IPFs.
Fixed#
imod.prepare.Regridder()
detects if thelike
DataArray is a subset along a dimension, in which case the dimension is not regridded.imod.prepare.Regridder()
now slices thesource
array accurately before regridding, taking cell boundaries into account rather than only cell midpoints.density
is no longer an optional argument inimod.wq.GeneralHeadboundary
andimod.wq.River
. The reason is that iMOD-WQ fully removes (!) these packages if density is not present.imod.idf.save()
andimod.rasterio.save()
will now also save DataArrays in which a coordinate other thanx
ory
is descending.imod.visualize.plot_map()
enforces decreasingy
, which ensures maps are not plotted upside down.imod.util.spatial.coord_reference()
now returns a scalar cellsize if coordinate is equidistant.imod.prepare.Regridder.regrid()
returns cellsizes as scalar when coordinates are equidistant.Raise proper ValueError in
imod.prepare.Regridder.regrid()
consistenly when the number of dimensions to regrid does not match the regridder dimensions.When writing DataArrays that have size 1 in dimension
x
ory
: raise error if cellsize (dx
ordy
) is not specified; and actually usedy
ordx
when size is 1.
[0.9.0] - 2020-01-19#
Added#
IDF files representing data of arbitrary dimensionality can be opened and saved. This enables reading and writing files with more dimensions than just x, y, layer, and time.
Added multi-species support for (
imod.wq
)GDAL rasters representing N-dimensional data can be opened and saved similar to (
imod.idf
) in (imod.rasterio
)Writing GDAL rasters using
imod.rasterio.save()
and (imod.rasterio.write()
) auto-detects GDAL driver based on file extension64-bit IDF files can be opened
imod.idf.open()
64-bit IDF files can be written using
imod.idf.save()
and (imod.idf.write()
) using keyworddtype=np.float64
sel
andisel
methods toSeawatModel
to support taking out a subdomainDocstrings for the Modflow 6 classes in
imod.mf6
imod.select.upper_active_layer()
function to get the upper active layer from iboundxr.DataArray
Changed#
imod.idf.read()
is deprecated, useimod.idf.open
insteadimod.rasterio.read()
is deprecated, useimod.rasterio.open
instead
Fixed#
imod.prepare.reproject()
working instead of silently failing when given a"+init=ESPG:XXXX
CRS string
[0.8.0] - 2019-10-14#
Added#
Laplace grid interpolation
imod.prepare.laplace_interpolate()
Experimental Modflow 6 structured model write support
imod.mf6
More supported visualizations
imod.visualize
More extensive reading and writing of GDAL raster in
imod.rasterio
Changed#
The documentation moved to a custom domain name: https://imod.xyz/
[0.7.1] - 2019-08-07#
Added#
"multilinear"
has been added as a regridding option toimod.prepare.Regridder
to do linear interpolation up to three dimensions.Boundary condition packages in
imod.wq
support a method calledadd_timemap
to do cyclical boundary conditions, such as summer and winter stages.
Fixed#
imod.idf.save
no longer fails on a single IDF when it is a voxel IDF (when it has top and bottom data).imod.prepare.celltable
now succesfully does parallel chunkwise operations, rather than raising an error.imod.Regridder
’sregrid
method now succesfully returnssource
if all dimensions already have the right cell sizes, rather than raising an error.imod.idf.open_subdomains
is much faster now at merging different subdomain IDFs of a parallel modflow simulation.imod.idf.save
no longer suffers from extremely slow execution when the DataArray to save is chunked (it got extremely slow in some cases).Package checks in
imod.wq.SeawatModel
succesfully reduces over dimensions.Fix last case in
imod.prepare.reproject
where it did not allocate a new array yet, but returnedlike
instead of the reprojected result.
[0.7.0] - 2019-07-23#
Added#
imod.wq
module to create iMODFLOW Water Quality modelsconda-forge recipe to install imod (conda-forge/imod-feedstock)
significantly extended documentation and examples
imod.prepare
module with many data mangling functionsimod.select
module for extracting data along cross sections or at pointsimod.visualize
module added to visualize resultsimod.idf.open_subdomains()
function to open and merge the IDF results of a parallelized runimod.ipf.read()
now infers delimeters for the headers and the bodyimod.ipf.read()
can now deal with heterogeneous delimiters between multiple IPF files, and between the headers and body in a single file
Changed#
Namespaces: lift many functions one level, such that you can use e.g. the function
imod.prepare.reproject
instead ofimod.prepare.reproject.reproject
Removed#
All that was deprecated in v0.6.0
Deprecated#
imod.seawat_write()
is deprecated, use the write method ofimod.wq.SeawatModel
insteadimod.run.seawat_get_runfile()
is deprecated, useimod.wq
insteadimod.run.seawat_write_runfile()
is deprecated, useimod.wq
instead
[0.6.1] - 2019-04-17#
Added#
Support nonequidistant models in runfile
Fixed#
Time conversion in runfile now also accepts cftime objects
[0.6.0] - 2019-03-15#
The primary change is that a number of functions have been renamed to better communicate what they do.
The load
function name was not appropriate for IDFs, since the IDFs
are not loaded into memory. Rather, they are opened and the headers are
read; the data is only loaded when needed, in accordance with
xarray
’s design; compare for example xarray.open_dataset
. The
function has been renamed to open
.
Similarly, load
for IPFs has been deprecated. imod.ipf.read
now
reads both single and multiple IPF files into a single
pandas.DataFrame
.
Removed#
imod.idf.setnodataheader
Deprecated#
Opening IDFs with
imod.idf.load
, useimod.idf.open
insteadOpening a set of IDFs with
imod.idf.loadset
, useimod.idf.open_dataset
insteadReading IPFs with
imod.ipf.load
, useimod.ipf.read
Reading IDF data into a dask array with
imod.idf.dask
, useimod.idf._dask
insteadReading an iMOD-seawat .tec file, use
imod.tec.read
instead.
Changed#
Use
np.datetime64
when dates are within time bounds, usecftime.DatetimeProlepticGregorian
when they are not (matchesxarray
defaults)assert
is no longer used to catch faulty input arguments, appropriate exceptions are raised instead
Fixed#
idf.open
: sorts both paths and headers consistently so data does not end up mixed up in the DataArrayidf.open
: Return anxarray.CFTimeIndex
rather than an array ofcftime.DatimeProlepticGregorian
objectsidf.save
properly forwardsnodata
argument towrite
idf.write
coerces coordinates to floats before writingipf.read
: Significant performance increase for reading IPF timeseries by specifying the datetime formatipf.write
no longer writes,,
for missing data (which iMOD does not accept)
[0.5.0] - 2019-02-26#
Removed#
Reading IDFs with the
chunks
option
Deprecated#
Reading IDFs with the
memmap
optionimod.idf.dataarray
, useimod.idf.load
instead
Changed#
Reading IDFs gives delayed objects, which are only read on demand by dask
IDF: instead of
res
andtransform
attributes, usedx
anddy
coordinates (0D or 1D)Use
cftime.DatetimeProlepticGregorian
to support time instead ofnp.datetime64
, allowing longer timespansRepository moved from
https://gitlab.com/deltares/
tohttps://gitlab.com/deltares/imod/
Added#
Notebook in
examples
folder for synthetic model exampleSupport for nonequidistant IDF files, by adding
dx
anddy
coordinates
Fixed#
IPF support implicit
itype