Coverage for C:\src\imod-python\imod\wq\adv.py: 43%
68 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-08 10:26 +0200
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-08 10:26 +0200
1import textwrap
3from imod.wq.pkgbase import Package
6class AdvectionFiniteDifference(Package):
7 """
8 Solve the advection term using the explicit Finite Difference method
9 (MIXELM = 0) with upstream weighting
11 Attributes
12 ----------
13 courant: float
14 Courant number (PERCEL) is the number of cells (or a fraction of a cell)
15 advection will be allowed in any direction in one transport step. For
16 implicit finite-difference or particle tracking based schemes, there is
17 no limit on PERCEL, but for accuracy reasons, it is generally not set
18 much greater than one. Note, however, that the PERCEL limit is checked
19 over the entire model grid. Thus, even if PERCEL > 1, advection may not
20 be more than one cell’s length at most model locations. For the explicit
21 finite-difference, PERCEL is also a stability constraint, which must not
22 exceed one and will be automatically reset to one if a value greater
23 than one is specified.
24 weighting : string {"upstream", "central"}, optional
25 Indication of which weighting scheme should be used, set to default
26 value "upstream" (NADVFD = 0 or 1)
27 Default value: "upstream"
28 """
30 _pkg_id = "adv"
32 _keywords = {"weighting": {"upstream": 0, "central": 1}}
34 _template = (
35 "[adv]\n"
36 " mixelm = 0\n"
37 " percel = {courant}\n"
38 " nadvfd = {weighting}\n"
39 )
41 def __init__(self, courant=0.75, weighting="upstream"):
42 super().__init__()
43 self["courant"] = courant
44 self["weighting"] = weighting
46 def _pkgcheck(self, ibound=None):
47 self._check_positive(["courant"])
50class AdvectionMOC(Package):
51 """
52 Solve the advection term using the Method of Characteristics (MIXELM = 1)
54 Nota bene: number of particles settings have not been tested. The defaults
55 here are chosen conservatively, with many particles. This increases both
56 memory usage and computational effort.
58 Attributes
59 -----------
60 courant: float
61 Courant number (PERCEL) is the number of cells (or a fraction of a cell)
62 advection will be allowed in any direction in one transport step. For
63 implicit finite-difference or particle tracking based schemes, there is
64 no limit on PERCEL, but for accuracy reasons, it is generally not set
65 much greater than one. Note, however, that the PERCEL limit is checked
66 over the entire model grid. Thus, even if PERCEL > 1, advection may not
67 be more than one cell’s length at most model locations. For the explicit
68 finite-difference, PERCEL is also a stability constraint, which must not
69 exceed one and will be automatically reset to one if a value greater
70 than one is specified.
71 max_nparticles: int
72 is the maximum total number of moving particles allowed (MXPART).
73 tracking: string {"euler", "runge-kutta", "hybrid"}, optional
74 indicates which particle tracking algorithm is selected for the
75 Eulerian-Lagrangian methods. ITRACK = 1, the first-order Euler algorithm is
76 used; ITRACK = 2, the fourth-order Runge-Kutta algorithm is used; this
77 option is computationally demanding and may be needed only when PERCEL is
78 set greater than one. ITRACK = 3, the hybrid 1st and 4th order algorithm is
79 used; the Runge- Kutta algorithm is used in sink/source cells and the cells
80 next to sinks/sources while the Euler algorithm is used elsewhere.
81 Default value is "hybrid".
82 weighting_factor: float, optional
83 is a concentration weighting factor (WD) between 0.5 and 1. It is used for
84 operator splitting in the particle tracking based methods. The value of
85 0.5 is generally adequate. The value may be adjusted to achieve better
86 mass balance. Generally, it can be increased toward 1.0 as advection
87 becomes more dominant.
88 Default value: 0.5.
89 dconcentration_epsilon: float, optional
90 is a small Relative Cell Concentration Gradient below which advective
91 transport is considered negligible. A value around 10-5 is generally
92 adequate.
93 Default value: 1.0e-5.
94 nplane: int, optional
95 is a flag indicating whether the random or fixed pattern is selected for
96 initial placement of moving particles. NPLANE = 0, the random pattern is
97 selected for initial placement. Particles are distributed randomly in
98 both the horizontal and vertical directions by calling a random number
99 generator. This option is usually preferred and leads to smaller mass
100 balance discrepancy in nonuniform or diverging/converging flow fields.
101 NPLANE > 0, the fixed pattern is selected for initial placement. The
102 value of NPLANE serves as the number of vertical "planes" on which
103 initial particles are placed within each cell block. The fixed pattern
104 may work better than the random pattern only in relatively uniform flow
105 fields. For two-dimensional simulations in plan view, set NPLANE = 1.
106 For cross sectional or three-dimensional simulations, NPLANE = 2 is
107 normally adequate. Increase NPLANE if more resolution in the vertical
108 direction is desired.
109 Default value: 2.
110 nparticles_no_advection: int, optional
111 is number of initial particles per cell to be placed at cells where the
112 Relative Cell Concentration Gradient is less than or equal to DCEPS.
113 Generally, NPL can be set to zero since advection is considered
114 insignificant when the Relative Cell Concentration Gradient is less than
115 or equal to DCEPS. Setting NPL equal to NPH causes a uniform number of
116 particles to be placed in every cell over the entire grid (i.e., the
117 uniform approach).
118 Default value: 10.
119 nparticles_advection: int, optional
120 is number of initial particles per cell to be placed at cells where the
121 Relative Cell Concentration Gradient is greater than DCEPS. The
122 selection of NPH depends on the nature of the flow field and also the
123 computer memory limitation. Generally, use a smaller number in
124 relatively uniform flow fields and a larger number in relatively
125 nonuniform flow fields. However, values exceeding 16 in twodimensional
126 simulation or 32 in three-dimensional simulation are rarely necessary.
127 If the random pattern is chosen, NPH particles are randomly distributed
128 within the cell block. If the fixed pattern is chosen, NPH is divided by
129 NPLANE to yield the number of particles to be placed per vertical plane.
130 Default value: 40.
131 cell_min_nparticles: int, optional
132 is the minimum number of particles allowed per cell. If the number of
133 particles in a cell at the end of a transport step is fewer than NPMIN,
134 new particles are inserted into that cell to maintain a sufficient
135 number of particles. NPMIN can be set to zero in relatively uniform flow
136 fields, and a number greater than zero in diverging/converging flow
137 fields. Generally, a value between zero and four is adequate.
138 Default value is 5.
139 cell_max_nparticles: int, optional
140 is the maximum number of particles allowed per cell. If the number of
141 particles in a cell exceeds NPMAX, all particles are removed from that
142 cell and replaced by a new set of particles equal to NPH to maintain
143 mass balance. Generally, NPMAX can be set to approximately twice of NPH.
144 Default value: 80.
145 """
147 _pkg_id = "adv"
148 _keywords = {"tracking": {"euler": 1, "runge-kutta": 2, "hybrid": 3}}
150 _template = textwrap.dedent(
151 """
152 [adv]
153 mixelm = 1
154 percel = {courant}
155 mxpart = {max_nparticles}
156 itrack = {tracking}
157 wd = {weighting_factor}
158 dceps = {dconcentration_epsilon}
159 nplane = {nplane}
160 npl = {nparticles_no_advection}
161 nph = {nparticles_advection}
162 npmin = {cell_min_nparticles}
163 npmax = {cell_max_nparticles}
164 """
165 )
167 def __init__(
168 self,
169 courant=0.75,
170 tracking="hybrid",
171 weighting_factor=0.5,
172 dconcentration_epsilon=1.0e-5,
173 nplane=2,
174 nparticles_no_advection=10,
175 nparticles_advection=40,
176 cell_min_nparticles=5,
177 cell_max_nparticles=80,
178 ):
179 super().__init__()
180 self["courant"] = courant
181 self["tracking"] = tracking
182 self["weighting_factor"] = weighting_factor
183 self["dconcentration_epsilon"] = dconcentration_epsilon
184 self["nplane"] = nplane
185 self["nparticles_no_advection"] = nparticles_no_advection
186 self["nparticles_advection"] = nparticles_advection
187 self["cell_min_nparticles"] = cell_min_nparticles
188 self["cell_max_nparticles"] = cell_max_nparticles
190 def _pkgcheck(self, ibound=None):
191 self._check_positive(["courant", "weighting_factor"])
194class AdvectionModifiedMOC(Package):
195 """
196 Solve the advention term using the Modified Method of Characteristics (MIXELM = 2)
197 Courant number (PERCEL) is the number of cells (or a fraction of a
198 cell) advection will be allowed in any direction in one transport step.
200 Attributes
201 ----------
202 courant: float
203 Courant number (PERCEL) is the number of cells (or a fraction of a cell)
204 advection will be allowed in any direction in one transport step. For
205 implicit finite-difference or particle tracking based schemes, there is
206 no limit on PERCEL, but for accuracy reasons, it is generally not set
207 much greater than one. Note, however, that the PERCEL limit is checked
208 over the entire model grid. Thus, even if PERCEL > 1, advection may not
209 be more than one cell’s length at most model locations. For the explicit
210 finite-difference, PERCEL is also a stability constraint, which must not
211 exceed one and will be automatically reset to one if a value greater
212 than one is specified.
213 tracking: string, {"euler", "runge-kutta", "hybrid"}
214 indicates which particle tracking algorithm is selected for the
215 Eulerian-Lagrangian methods. ITRACK = 1, the first-order Euler algorithm is
216 used; ITRACK = 2, the fourth-order Runge-Kutta algorithm is used; this
217 option is computationally demanding and may be needed only when PERCEL is
218 set greater than one. ITRACK = 3, the hybrid 1st and 4th order algorithm is
219 used; the Runge- Kutta algorithm is used in sink/source cells and the cells
220 next to sinks/sources while the Euler algorithm is used elsewhere.
221 weighting_factor: float
222 is a concentration weighting factor (WD) between 0.5 and 1. It is used for
223 operator splitting in the particle tracking based methods. The value of
224 0.5 is generally adequate. The value may be adjusted to achieve better
225 mass balance. Generally, it can be increased toward 1.0 as advection
226 becomes more dominant.
227 dconcentration_epsilon: float, optional
228 is a small Relative Cell Concentration Gradient (DCEPS) below which advective
229 transport is considered negligible. A value around 1.0e-5 is generally
230 adequate.
231 Default value: 1.0e-5.
232 sink_particle_placement: int
233 indicates whether the random or fixed pattern is selected for initial
234 placement of particles to approximate sink cells in the MMOC scheme.
235 (NLSINK)
236 sink_nparticles: int
237 is the number of particles used to approximate sink cells in the MMOC
238 scheme. (NPSINK)
239 """
241 _pkg_id = "adv"
243 _keywords = {"tracking": {"euler": 1, "runge-kutta": 2, "hybrid": 3}}
245 _template = (
246 "[adv]\n"
247 " mixelm = 2\n"
248 " percel = {courant}\n"
249 " itrack = {tracking}\n"
250 " wd = {weighting_factor}\n"
251 " interp = 1\n"
252 " nlsink = {sink_particle_placement}\n"
253 " npsink = {sink_nparticles}\n"
254 )
256 def __init__(
257 self,
258 courant=1.0,
259 tracking="hybrid",
260 weighting_factor=0.5,
261 dconcentration_epsilon=1.0e-5,
262 sink_particle_placement=2,
263 sink_nparticles=40,
264 ):
265 super().__init__()
266 self["courant"] = courant
267 self["tracking"] = tracking
268 self["weighting_factor"] = weighting_factor
269 self["sink_particle_placement"] = sink_particle_placement
270 self["sink_nparticles"] = sink_nparticles
272 def _pkgcheck(self, ibound=None):
273 self._check_positive(["courant", "weighting_factor"])
276class AdvectionHybridMOC(Package):
277 """
278 Hybrid Method of Characteristics and Modified Method of Characteristics with
279 MOC or MMOC automatically and dynamically selected (MIXELM = 3)
281 Attributes
282 ----------
283 courant: float
284 Courant number (PERCEL) is the number of cells (or a fraction of a cell)
285 advection will be allowed in any direction in one transport step. For
286 implicit finite-difference or particle tracking based schemes, there is
287 no limit on PERCEL, but for accuracy reasons, it is generally not set
288 much greater than one. Note, however, that the PERCEL limit is checked
289 over the entire model grid. Thus, even if PERCEL > 1, advection may not
290 be more than one cell’s length at most model locations. For the explicit
291 finite-difference, PERCEL is also a stability constraint, which must not
292 exceed one and will be automatically reset to one if a value greater
293 than one is specified.
294 max_particles: int
295 is the maximum total number of moving particles allowed (MXPART).
296 tracking: int
297 indicates which particle tracking algorithm is selected for the
298 Eulerian-Lagrangian methods. ITRACK = 1, the first-order Euler algorithm is
299 used; ITRACK = 2, the fourth-order Runge-Kutta algorithm is used; this
300 option is computationally demanding and may be needed only when PERCEL is
301 set greater than one. ITRACK = 3, the hybrid 1st and 4th order algorithm is
302 used; the Runge- Kutta algorithm is used in sink/source cells and the cells
303 next to sinks/sources while the Euler algorithm is used elsewhere.
304 weighting_factor: float
305 is a concentration weighting factor (WD) between 0.5 and 1. It is used for
306 operator splitting in the particle tracking based methods. The value of
307 0.5 is generally adequate. The value may be adjusted to achieve better
308 mass balance. Generally, it can be increased toward 1.0 as advection
309 becomes more dominant.
310 dceps: float
311 is a small Relative Cell Concentration Gradient below which advective
312 transport is considered negligible. A value around 10-5 is generally
313 adequate.
314 nplane: int
315 is a flag indicating whether the random or fixed pattern is selected for
316 initial placement of moving particles. NPLANE = 0, the random pattern is
317 selected for initial placement. Particles are distributed randomly in
318 both the horizontal and vertical directions by calling a random number
319 generator. This option is usually preferred and leads to smaller mass
320 balance discrepancy in nonuniform or diverging/converging flow fields.
321 NPLANE > 0, the fixed pattern is selected for initial placement. The
322 value of NPLANE serves as the number of vertical "planes" on which
323 initial particles are placed within each cell block. The fixed pattern
324 may work better than the random pattern only in relatively uniform flow
325 fields. For two-dimensional simulations in plan view, set NPLANE = 1.
326 For cross sectional or three-dimensional simulations, NPLANE = 2 is
327 normally adequate. Increase NPLANE if more resolution in the vertical
328 direction is desired.
329 npl: int
330 is number of initial particles per cell to be placed at cells where the
331 Relative Cell Concentration Gradient is less than or equal to DCEPS.
332 Generally, NPL can be set to zero since advection is considered
333 insignificant when the Relative Cell Concentration Gradient is less than
334 or equal to DCEPS. Setting NPL equal to NPH causes a uniform number of
335 particles to be placed in every cell over the entire grid (i.e., the
336 uniform approach).
337 nph: int
338 is number of initial particles per cell to be placed at cells where the
339 Relative Cell Concentration Gradient is greater than DCEPS. The
340 selection of NPH depends on the nature of the flow field and also the
341 computer memory limitation. Generally, use a smaller number in
342 relatively uniform flow fields and a larger number in relatively
343 nonuniform flow fields. However, values exceeding 16 in twodimensional
344 simulation or 32 in three-dimensional simulation are rarely necessary.
345 If the random pattern is chosen, NPH particles are randomly distributed
346 within the cell block. If the fixed pattern is chosen, NPH is divided by
347 NPLANE to yield the number of particles to be placed per vertical plane.
348 npmin: int
349 is the minimum number of particles allowed per cell. If the number of
350 particles in a cell at the end of a transport step is fewer than NPMIN,
351 new particles are inserted into that cell to maintain a sufficient
352 number of particles. NPMIN can be set to zero in relatively uniform flow
353 fields, and a number greater than zero in diverging/converging flow
354 fields. Generally, a value between zero and four is adequate.
355 npmax: int
356 is the maximum number of particles allowed per cell. If the number of
357 particles in a cell exceeds NPMAX, all particles are removed from that
358 cell and replaced by a new set of particles equal to NPH to maintain
359 mass balance. Generally, NPMAX can be set to approximately twice of NPH.
360 dchmoc: real
361 is the critical Relative Concentration Gradient for controlling the
362 selective use of either MOC or MMOC in the HMOC solution scheme. The MOC
363 solution is selected at cells where the Relative Concentration Gradient
364 is greater than DCHMOC; The MMOC solution is selected at cells where the
365 Relative Concentration Gradient is less than or equal to DCHMOC
366 """
368 _pkg_id = "adv"
370 def __init__(
371 self,
372 courant=0.75,
373 tracking="hybrid",
374 weighting_factor=0.5,
375 dconcentration_epsilon=1.0e-5,
376 nplane=2,
377 nparticles_no_advection=10,
378 nparticles_advection=40,
379 cell_min_nparticles=5,
380 cell_max_nparticles=80,
381 sink_particle_placement=2,
382 sink_nparticles=40,
383 dconcentration_hybrid=1.0e-4,
384 ):
385 super().__init__()
386 self["courant"] = courant
387 self["tracking"] = tracking
388 self["weighting_factor"] = weighting_factor
389 self["dconcentration_epsilon"] = dconcentration_epsilon
390 self["nplane"] = nplane
391 self["nparticles_no_advection"] = nparticles_no_advection
392 self["nparticles_advection"] = nparticles_advection
393 self["cell_min_nparticles"] = cell_min_nparticles
394 self["cell_max_nparticles"] = cell_max_nparticles
395 self["sink_particle_placement"] = sink_particle_placement
396 self["sink_nparticles"] = sink_nparticles
397 self["dconcentration_hybrid"] = dconcentration_hybrid
399 def _pkgcheck(self, ibound=None):
400 self._check_positive(["courant", "weighting_factor"])
403class AdvectionTVD(Package):
404 """
405 Total Variation Diminishing (TVD) formulation (ULTIMATE, MIXELM = -1).
407 Attributes
408 ----------
409 courant : float
410 Courant number (PERCEL) is the number of cells (or a fraction of a cell)
411 advection will be allowed in any direction in one transport step. For
412 implicit finite-difference or particle tracking based schemes, there is
413 no limit on PERCEL, but for accuracy reasons, it is generally not set
414 much greater than one. Note, however, that the PERCEL limit is checked
415 over the entire model grid. Thus, even if PERCEL > 1, advection may not
416 be more than one cell’s length at most model locations. For the explicit
417 finite-difference, PERCEL is also a stability constraint, which must not
418 exceed one and will be automatically reset to one if a value greater
419 than one is specified.
420 """
422 _pkg_id = "adv"
424 _template = "[adv]\n" " mixelm = -1\n" " percel = {courant}\n"
426 def __init__(self, courant=0.75):
427 super().__init__()
428 self["courant"] = courant
430 def _pkgcheck(self, ibound=None):
431 self._check_positive(["courant"])