Coverage for C:\src\imod-python\imod\mf6\mst.py: 100%
25 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.interfaces.iregridpackage import IRegridPackage
7from imod.mf6.package import Package
8from imod.mf6.utilities.regrid import RegridderType
9from imod.mf6.validation import PKG_DIMS_SCHEMA
10from imod.schemata import (
11 AllValueSchema,
12 DTypeSchema,
13 IdentityNoDataSchema,
14 IndexesSchema,
15)
18class MobileStorageTransfer(Package, IRegridPackage):
19 """
20 Mobile Storage.
22 Parameters
23 ----------
24 porosity: array of floats (xr.DataArray)
25 volume of interconnected voids per volume of rock (percentage).
26 decay : array of floats (xr.DataArray, optional)
27 is the rate coefficient for first or zero-order decay for the aqueous phase of the mobile domain.
28 A negative value indicates solute production. The dimensions of decay for first-order decay is one
29 over time. The dimensions of decay for zero-order decay is mass per length cubed per time. decay will
30 have no effect on simulation results unless either first- or zero-order decay is specified in the
31 options block.
32 decay_sorbed : array of floats (xr.DataArray, optional)
33 is the rate coefficient for first or zero-order decay for the sorbed phase of the mobile domain.
34 A negative value indicates solute production. The dimensions of decay_sorbed for first-order decay
35 is one over time. The dimensions of decay_sorbed for zero-order decay is mass of solute per mass of
36 aquifer per time. If decay_sorbed is not specified and both decay and sorption are active, then the
37 program will terminate with an error. decay_sorbed will have no effect on simulation results unless
38 the SORPTION keyword and either first- or zero-order decay are specified in the options block.
39 bulk_density : array of floats (xr.DataArray, optional)
40 is the bulk density of the aquifer in mass per length cubed. bulk_density is not required unless
41 the SORPTION keyword is specified.
42 distcoef : array of floats (xr.DataArray, optional)
43 is the distribution coefficient for the equilibrium-controlled linear sorption isotherm in dimensions
44 of length cubed per mass. distcoef is not required unless the SORPTION keyword is specified.
45 sp2 : array of floats (xr.DataArray, optional)
46 is the exponent for the Freundlich isotherm and the sorption capacity for the Langmuir isotherm.
47 save_flows: ({True, False}, optional)
48 Indicates that recharge flow terms will be written to the file specified
49 with "BUDGET FILEOUT" in Output Control.
50 Default is False.
51 zero_order_decay: bool, optional
52 Requires decay to be specified
53 first_order_decay: bool, optional
54 Requires decay to be specified
55 sorption: ({linear, freundlich, langmuir}, optional)
56 Type of sorption, if any.
57 validate: {True, False}
58 Flag to indicate whether the package should be validated upon
59 initialization. This raises a ValidationError if package input is
60 provided in the wrong manner. Defaults to True.
61 """
63 _grid_data = {
64 "porosity": np.float64,
65 "decay": np.float64,
66 "decay_sorbed": np.float64,
67 "bulk_density": np.float64,
68 "distcoef": np.float64,
69 "sp2": np.float64,
70 }
72 _pkg_id = "mst"
73 _template = Package._initialize_template(_pkg_id)
74 _keyword_map = {}
75 _init_schemata = {
76 "porosity": [DTypeSchema(np.floating), IndexesSchema(), PKG_DIMS_SCHEMA],
77 "decay": [DTypeSchema(np.floating), IndexesSchema(), PKG_DIMS_SCHEMA],
78 "decay_sorbed": [DTypeSchema(np.floating), IndexesSchema(), PKG_DIMS_SCHEMA],
79 "bulk_density": [DTypeSchema(np.floating), IndexesSchema(), PKG_DIMS_SCHEMA],
80 "distcoef": [DTypeSchema(np.floating), IndexesSchema(), PKG_DIMS_SCHEMA],
81 "sp2": [DTypeSchema(np.floating), IndexesSchema(), PKG_DIMS_SCHEMA],
82 "zero_order_decay": [DTypeSchema(np.bool_)],
83 "first_order_decay": [DTypeSchema(np.bool_)],
84 }
86 _write_schemata = {
87 "porosity": (
88 AllValueSchema(">=", 0.0),
89 AllValueSchema("<", 1.0),
90 IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)),
91 ),
92 "decay": (IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)),),
93 "decay_sorbed": (
94 IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)),
95 ),
96 "bulk_density": (
97 IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)),
98 ),
99 "distcoef": (IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)),),
100 "sp2": (IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)),),
101 }
103 _regrid_method = {
104 "porosity": (RegridderType.OVERLAP, "mean"),
105 "decay": (RegridderType.OVERLAP, "mean"),
106 "decay_sorbed": (
107 RegridderType.OVERLAP,
108 "mean",
109 ),
110 "bulk_density": (RegridderType.OVERLAP, "mean"),
111 "distcoef": (RegridderType.OVERLAP, "mean"),
112 "sp2": (RegridderType.OVERLAP, "mean"),
113 }
115 @init_log_decorator()
116 def __init__(
117 self,
118 porosity,
119 decay=None,
120 decay_sorbed=None,
121 bulk_density=None,
122 distcoef=None,
123 sp2=None,
124 save_flows=False,
125 zero_order_decay: bool = False,
126 first_order_decay: bool = False,
127 sorption=None,
128 validate: bool = True,
129 ):
130 if zero_order_decay and first_order_decay:
131 raise ValueError(
132 "zero_order_decay and first_order_decay may not both be True"
133 )
134 dict_dataset = {
135 "porosity": porosity,
136 "decay": decay,
137 "decay_sorbed": decay_sorbed,
138 "bulk_density": bulk_density,
139 "distcoef": distcoef,
140 "sp2": sp2,
141 "save_flows": save_flows,
142 "sorption": sorption,
143 "zero_order_decay": zero_order_decay,
144 "first_order_decay": first_order_decay,
145 }
146 super().__init__(dict_dataset)
147 self._validate_init_schemata(validate)
149 def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]:
150 return self._regrid_method