Coverage for C:\src\imod-python\imod\mf6\drn.py: 100%
28 statements
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-08 14:15 +0200
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-08 14:15 +0200
1from typing import Optional, Tuple
3import numpy as np
5from imod.logging import init_log_decorator
6from imod.mf6.boundary_condition import BoundaryCondition
7from imod.mf6.interfaces.iregridpackage import IRegridPackage
8from imod.mf6.utilities.regrid import RegridderType
9from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA
10from imod.schemata import (
11 AllInsideNoDataSchema,
12 AllNoDataSchema,
13 AllValueSchema,
14 CoordsSchema,
15 DimsSchema,
16 DTypeSchema,
17 IdentityNoDataSchema,
18 IndexesSchema,
19 OtherCoordsSchema,
20)
23class Drainage(BoundaryCondition, IRegridPackage):
24 """
25 The Drain package is used to simulate head-dependent flux boundaries.
26 https://water.usgs.gov/ogw/modflow/mf6io.pdf#page=67
28 Parameters
29 ----------
30 elevation: array of floats (xr.DataArray)
31 elevation of the drain. (elev)
32 conductance: array of floats (xr.DataArray)
33 is the conductance of the drain. (cond)
34 concentration: array of floats (xr.DataArray, optional)
35 if this flow package is used in simulations also involving transport, then this array is used
36 as the concentration for inflow over this boundary.
37 concentration_boundary_type: ({"AUX", "AUXMIXED"}, optional)
38 if this flow package is used in simulations also involving transport, then this keyword specifies
39 how outflow over this boundary is computed.
40 print_input: ({True, False}, optional)
41 keyword to indicate that the list of drain information will be written
42 to the listing file immediately after it is read. Default is False.
43 print_flows: ({True, False}, optional)
44 Indicates that the list of drain flow rates will be printed to the
45 listing file for every stress period time step in which "BUDGET PRINT"
46 is specified in Output Control. If there is no Output Control option and
47 PRINT FLOWS is specified, then flow rates are printed for the last time
48 step of each stress period.
49 Default is False.
50 save_flows: ({True, False}, optional)
51 Indicates that drain flow terms will be written to the file specified
52 with "BUDGET FILEOUT" in Output Control. Default is False.
53 observations: [Not yet supported.]
54 Default is None.
55 validate: {True, False}
56 Flag to indicate whether the package should be validated upon
57 initialization. This raises a ValidationError if package input is
58 provided in the wrong manner. Defaults to True.
59 repeat_stress: Optional[xr.DataArray] of datetimes
60 Used to repeat data for e.g. repeating stress periods such as
61 seasonality without duplicating the values. The DataArray should have
62 dimensions ``("repeat", "repeat_items")``. The ``repeat_items``
63 dimension should have size 2: the first value is the "key", the second
64 value is the "value". For the "key" datetime, the data of the "value"
65 datetime will be used. Can also be set with a dictionary using the
66 ``set_repeat_stress`` method.
67 """
69 _pkg_id = "drn"
71 # has to be ordered as in the list
72 _init_schemata = {
73 "elevation": [
74 DTypeSchema(np.floating),
75 IndexesSchema(),
76 CoordsSchema(("layer",)),
77 BOUNDARY_DIMS_SCHEMA,
78 ],
79 "conductance": [
80 DTypeSchema(np.floating),
81 IndexesSchema(),
82 CoordsSchema(("layer",)),
83 BOUNDARY_DIMS_SCHEMA,
84 ],
85 "concentration": [
86 DTypeSchema(np.floating),
87 IndexesSchema(),
88 CoordsSchema(
89 (
90 "species",
91 "layer",
92 )
93 ),
94 CONC_DIMS_SCHEMA,
95 ],
96 "print_flows": [DTypeSchema(np.bool_), DimsSchema()],
97 "save_flows": [DTypeSchema(np.bool_), DimsSchema()],
98 }
99 _write_schemata = {
100 "elevation": [
101 OtherCoordsSchema("idomain"),
102 AllNoDataSchema(), # Check for all nan, can occur while clipping
103 AllInsideNoDataSchema(other="idomain", is_other_notnull=(">", 0)),
104 ],
105 "conductance": [IdentityNoDataSchema("elevation"), AllValueSchema(">", 0.0)],
106 "concentration": [IdentityNoDataSchema("elevation"), AllValueSchema(">=", 0.0)],
107 }
109 _period_data = ("elevation", "conductance")
110 _keyword_map = {}
111 _template = BoundaryCondition._initialize_template(_pkg_id)
112 _auxiliary_data = {"concentration": "species"}
114 _regrid_method = {
115 "elevation": (RegridderType.OVERLAP, "mean"),
116 "conductance": (RegridderType.RELATIVEOVERLAP, "conductance"),
117 "concentration": (RegridderType.OVERLAP, "mean"),
118 }
120 @init_log_decorator()
121 def __init__(
122 self,
123 elevation,
124 conductance,
125 concentration=None,
126 concentration_boundary_type="aux",
127 print_input=False,
128 print_flows=False,
129 save_flows=False,
130 observations=None,
131 validate: bool = True,
132 repeat_stress=None,
133 ):
134 dict_dataset = {
135 "elevation": elevation,
136 "conductance": conductance,
137 "concentration": concentration,
138 "concentration_boundary_type": concentration_boundary_type,
139 "print_input": print_input,
140 "print_flows": print_flows,
141 "save_flows": save_flows,
142 "observations": observations,
143 "repeat_stress": repeat_stress,
144 }
145 super().__init__(dict_dataset)
147 self._validate_init_schemata(validate)
149 def _validate(self, schemata, **kwargs):
150 # Insert additional kwargs
151 kwargs["elevation"] = self["elevation"]
152 errors = super()._validate(schemata, **kwargs)
154 return errors
156 def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]:
157 return self._regrid_method