Coverage for C:\src\imod-python\imod\mf6\ims.py: 89%
46 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-08 13:27 +0200
« prev ^ index » next coverage.py v7.4.4, created at 2024-04-08 13:27 +0200
1import numpy as np
2import xarray as xr
4from imod.logging import init_log_decorator
5from imod.mf6.package import Package
6from imod.schemata import DTypeSchema
9class Solution(Package):
10 """
11 Iterative Model Solution.
12 The model solution will solve all of the models that are added to it, as
13 specified in the simulation name file, and will include Numerical Exchanges,
14 if they are present. The iterative model solution requires specification of
15 both nonlinear and linear settings.
16 https://water.usgs.gov/water-resources/software/MODFLOW-6/mf6io_6.0.4.pdf#page=147
18 Three predifined solutions settings are available: SolutionPresetSimple,
19 SolutionPresetModerate and SolutionPresetComplex. When using one of the
20 predefined solutions only the print_option, csv_output, and no_ptc have to
21 be defined. The default values for each are described below.
23 Parameters
24 ----------
25 modelnames: list of str
26 Which models to solve in this solution. Only models of the same type
27 (GWF or GWT) should be added to the same solution.
28 outer_dvclose: float
29 real value defining the head change criterion for convergence of the
30 outer (nonlinear) iterations, in units of length. When the maximum
31 absolute value of the head change at all nodes during an iteration is
32 less than or equal to outer_dvclose, iteration stops. Commonly,
33 outer_dvclose equals 0.01.
34 SolutionPresetSimple: 0.001
35 SolutionPresetModerate: 0.01
36 SolutionPresetComplex: 0.1
37 outer_maximum: int
38 integer value defining the maximum number of outer (nonlinear)
39 iterations – that is, calls to the solution routine. For a linear
40 problem outer_maximum should be 1.
41 SolutionPresetSimple: 25
42 SolutionPresetModerate: 50
43 SolutionPresetComplex: 100
44 inner_maximum: int
45 integer value defining the maximum number of inner (linear) iterations.
46 The number typically depends on the characteristics of the matrix
47 solution scheme being used. For nonlinear problems, inner_maximum
48 usually ranges from 60 to 600; a value of 100 will be sufficient for
49 most linear problems.
50 SolutionPresetSimple: 50
51 SolutionPresetModerate: 100
52 SolutionPresetComplex: 500
53 inner_dvclose: float
54 real value defining the head change criterion for convergence of the
55 inner (linear) iterations, in units of length. When the maximum absolute
56 value of the head change at all nodes during an iteration is less than
57 or equal to inner_dvclose, the matrix solver assumes convergence.
58 Commonly, inner_dvclose is set an order of magnitude less than the
59 outer_dvclose value.
60 SolutionPresetSimple: 0.001
61 SolutionPresetModerate: 0.01
62 SolutionPresetComplex: 0.1
63 inner_rclose: float
64 real value that defines the flow residual tolerance for convergence of
65 the IMS linear solver and specific flow residual criteria used. This
66 value represents the maximum allowable residual at any single node.
67 Value is in units of length cubed per time, and must be consistent with
68 MODFLOW 6 length and time units. Usually a value of 1.0 × 10−1 is
69 sufficient for the flow-residual criteria when meters and seconds are
70 the defined MODFLOW 6 length and time.
71 SolutionPresetSimple: 0.1
72 SolutionPresetModerate: 0.1
73 SolutionPresetComplex: 0.1
74 linear_acceleration: str
75 options: {"cg", "bicgstab"}
76 a keyword that defines the linear acceleration method used by the
77 default IMS linear solvers. CG - preconditioned conjugate gradient
78 method. BICGSTAB - preconditioned bi-conjugate gradient stabilized
79 method.
80 SolutionPresetSimple: "cg"
81 SolutionPresetModerate: "bicgstab"
82 SolutionPresetComplex: "bicgstab"
83 under_relaxation: str, optional
84 options: {"None", "simple", "cooley", "bdb"}
85 is an optional keyword that defines the nonlinear relative_rclose
86 schemes used. By default under_relaxation is not used.
87 None - relative_rclose is not used.
88 simple - Simple relative_rclose scheme with a fixed relaxation factor is
89 used.
90 cooley - Cooley relative_rclose scheme is used.
91 dbd - delta-bar-delta relative_rclose is used.
92 Note that the relative_rclose schemes are used in conjunction with
93 problems that use the Newton-Raphson formulation, however, experience
94 has indicated that the Cooley relative_rclose and damping work well also
95 for the Picard scheme with the wet/dry options of MODFLOW 6.
96 Default value: None
97 SolutionPresetSimple: None
98 SolutionPresetModerate: "dbd"
99 SolutionPresetComplex: "dbd"
100 under_relaxation_theta: float, optional
101 real value defining the reduction factor for the learning rate
102 (underrelaxation term) of the delta-bar-delta algorithm. The value of
103 under relaxation theta is between zero and one. If the change in the
104 variable (head) is of opposite sign to that of the previous iteration,
105 the relative_rclose term is reduced by a factor of under relaxation
106 theta. The value usually ranges from 0.3 to 0.9; a value of 0.7 works
107 well for most problems. under relaxation theta only needs to be
108 specified if under relaxation is dbd.
109 Default value: None
110 SolutionPresetSimple: 0.0
111 SolutionPresetModerate: 0.9
112 SolutionPresetComplex: 0.8
113 under_relaxation_kappa: float, optional
114 real value defining the increment for the learning rate (relative_rclose
115 term) of the delta-bar-delta algorithm. The value of under relaxation
116 kappa is between zero and one. If the change in the variable (head) is
117 of the same sign to that of the previous iteration, the relative_rclose
118 term is increased by an increment of under_relaxation_kappa. The value
119 usually ranges from 0.03 to 0.3; a value of 0.1 works well for most
120 problems. under relaxation kappa only needs to be specified if under
121 relaxation is dbd.
122 Default value: None
123 SolutionPresetSimple: 0.0
124 SolutionPresetModerate: 0.0001
125 SolutionPresetComplex: 0.0001
126 under_relaxation_gamma: float, optional
127 real value defining the history or memory term factor of the
128 delta-bardelta algorithm. under relaxation gamma is between zero and 1
129 but cannot be equal to one. When under relaxation gamma is zero, only
130 the most recent history (previous iteration value) is maintained. As
131 under relaxation gamma is increased, past history of iteration changes
132 has greater influence on the memory term. The memory term is maintained
133 as an exponential average of past changes. Retaining some past history
134 can overcome granular behavior in the calculated function surface and
135 therefore helps to overcome cyclic patterns of nonconvergence. The value
136 usually ranges from 0.1 to 0.3; a value of 0.2 works well for most
137 problems. under relaxation gamma only needs to be specified if under
138 relaxation is not none.
139 Default value: None
140 SolutionPresetSimple: 0.0
141 SolutionPresetModerate: 0.0
142 SolutionPresetComplex: 0.0
143 under_relaxation_momentum: float, optional
144 real value defining the fraction of past history changes that is added
145 as a momentum term to the step change for a nonlinear iteration. The
146 value of under relaxation momentum is between zero and one. A large
147 momentum term should only be used when small learning rates are
148 expected. Small amounts of the momentum term help convergence. The value
149 usually ranges from 0.0001 to 0.1; a value of 0.001 works well for most
150 problems. under relaxation momentum only needs to be specified if under
151 relaxation is dbd.
152 Default value: None
153 SolutionPresetSimple: 0.0
154 SolutionPresetModerate: 0.0
155 SolutionPresetComplex: 0.0
156 backtracking_number: int, optional
157 integer value defining the maximum number of backtracking iterations
158 allowed for residual reduction computations. If backtracking number = 0
159 then the backtracking iterations are omitted. The value usually ranges
160 from 2 to 20; a value of 10 works well for most problems.
161 Default value: None
162 SolutionPresetSimple: 0
163 SolutionPresetModerate: 0
164 SolutionPresetComplex: 20
165 backtracking_tolerance: float, optional
166 real value defining the tolerance for residual change that is allowed
167 for residual reduction computations. backtracking tolerance should not
168 be less than one to avoid getting stuck in local minima. A large value
169 serves to check for extreme residual increases, while a low value serves
170 to control step size more severely. The value usually ranges from 1.0 to
171 106; a value of 104 works well for most problems but lower values like
172 1.1 may be required for harder problems. backtracking tolerance only
173 needs to be specified if backtracking_number is greater than zero.
174 Default value: None
175 SolutionPresetSimple: 0.0
176 SolutionPresetModerate: 0.0
177 SolutionPresetComplex: 1.05
178 backtracking_reduction_factor: float, optional
179 real value defining the reduction in step size used for residual
180 reduction computations. The value of backtracking reduction factor is
181 between 142 MODFLOW 6 – Description of Input and Output zero and one.
182 The value usually ranges from 0.1 to 0.3; a value of 0.2 works well for
183 most problems. backtracking_reduction_factor only needs to be specified
184 if backtracking number is greater than zero.
185 Default value: None
186 SolutionPresetSimple: 0.0
187 SolutionPresetModerate: 0.0
188 SolutionPresetComplex: 0.1
189 backtracking_residual_limit: float, optional
190 real value defining the limit to which the residual is reduced with
191 backtracking. If the residual is smaller than
192 backtracking_residual_limit, then further backtracking is not performed.
193 A value of 100 is suitable for large problems and residual reduction to
194 smaller values may only slow down computations. backtracking residual
195 limit only needs to be specified if backtracking_number is greater than
196 zero.
197 Default value: None
198 SolutionPresetSimple: 0.0
199 SolutionPresetModerate: 0.0
200 SolutionPresetComplex: 0.002
201 rclose_option: str, optional
202 options: {"strict", "l2norm_rclose", "relative_rclose"}
203 an optional keyword that defines the specific flow residual criterion
204 used.
205 strict– an optional keyword that is used to specify that inner rclose
206 represents a infinity-norm (absolute convergence criteria) and that the
207 head and flow convergence criteria must be met on the first inner
208 iteration (this criteria is equivalent to the criteria used by the
209 MODFLOW-2005 PCG package (Hill, 1990)).
210 l2norm_rclose – an optionalkeyword that is used to specify that inner
211 rclose represents a l-2 norm closure criteria instead of a infinity-norm
212 (absolute convergence criteria). When l2norm_rclose is specified, a
213 reasonable initial inner rclose value is 0.1 times the number of active
214 cells when meters and seconds are the defined MODFLOW 6 length and time.
215 relative_rclose – an optional keyword that is used to specify that
216 inner_rclose represents a relative L-2 Norm reduction closure criteria
217 instead of a infinity-Norm (absolute convergence criteria). When
218 relative_rclose is specified, a reasonable initial inner_rclose value is
219 1.0 × 10−4 and convergence is achieved for a given inner (linear)
220 iteration when ∆h ≤ inner_dvclose and the current L-2 Norm is ≤ the
221 product of the relativ_rclose and the initial L-2 Norm for the current
222 inner (linear) iteration. If rclose_option is not specified, an absolute
223 residual (infinity-norm) criterion is used.
224 Default value: None
225 SolutionPresetSimple: "strict"
226 SolutionPresetModerate: "strict"
227 SolutionPresetComplex: "strict"
228 relaxation_factor: float, optional
229 optional real value that defines the relaxation factor used by the
230 incomplete LU factorization preconditioners (MILU(0) and MILUT).
231 relaxation_factor is unitless and should be greater than or equal to 0.0
232 and less than or equal to 1.0. relaxation_factor Iterative Model
233 Solution 143 values of about 1.0 are commonly used, and experience
234 suggests that convergence can be optimized in some cases with relax
235 values of 0.97. A relaxation_factor value of 0.0 will result in either
236 ILU(0) or ILUT preconditioning (depending on the value specified for
237 preconditioner_levels and/or preconditioner_drop_tolerance). By default,
238 relaxation_factor is zero.
239 Default value: None
240 SolutionPresetSimple: 0.0
241 SolutionPresetModerate: 0
242 SolutionPresetComplex: 0.0
243 preconditioner_levels: int, optional
244 optional integer value defining the level of fill for ILU decomposition
245 used in the ILUT and MILUT preconditioners. Higher levels of fill
246 provide more robustness but also require more memory. For optimal
247 performance, it is suggested that a large level of fill be applied (7 or
248 8) with use of a drop tolerance. Specification of a
249 preconditioner_levels value greater than zero results in use of the ILUT
250 preconditioner. By default, preconditioner_levels is zero and the
251 zero-fill incomplete LU factorization preconditioners (ILU(0) and
252 MILU(0)) are used.
253 Default value: None
254 SolutionPresetSimple: 0
255 SolutionPresetModerate: 0
256 SolutionPresetComplex: 5
257 preconditioner_drop_tolerance: float, optional
258 optional real value that defines the drop tolerance used to drop
259 preconditioner terms based on the magnitude of matrix entries in the
260 ILUT and MILUT preconditioners. A value of 10−4 works well for most
261 problems. By default, preconditioner_drop_tolerance is zero and the
262 zero-fill incomplete LU factorization preconditioners (ILU(0) and
263 MILU(0)) are used.
264 Default value: None
265 SolutionPresetSimple: 0
266 SolutionPresetModerate: 0.0
267 SolutionPresetComplex: 0.0001
268 number_orthogonalizations: int, optional
269 optional integer value defining the interval used to explicitly
270 recalculate the residual of the flow equation using the solver
271 coefficient matrix, the latest head estimates, and the right hand side.
272 For problems that benefit from explicit recalculation of the residual, a
273 number between 4 and 10 is appropriate. By default,
274 number_orthogonalizations is zero.
275 Default value: None
276 SolutionPresetSimple: 0
277 SolutionPresetModerate: 0
278 SolutionPresetComplex: 2
279 scaling_method: str
280 options: {"None", "diagonal", "l2norm"}
281 an optional keyword that defines the matrix scaling approach used. By
282 default, matrix scaling is not applied.
283 None - no matrix scaling applied.
284 diagonal - symmetric matrix scaling using the POLCG preconditioner
285 scaling method in Hill (1992).
286 l2norm - symmetric matrix scaling using the L2 norm.
287 Default value: None
288 SolutionPresetSimple: None
289 SolutionPresetModerate: None
290 SolutionPresetComplex: None
291 reordering_method: str
292 options: {"None", "rcm", "md"}
293 an optional keyword that defines the matrix reordering approach used. By
294 default, matrix reordering is not applied.
295 None - original ordering.
296 rcm - reverse Cuthill McKee ordering.
297 md - minimum degree ordering
298 Default value: None
299 SolutionPresetSimple: None
300 SolutionPresetModerate: None
301 SolutionPresetComplex: None
302 print_option: str
303 options: {"None", "summary", "all"}
304 is a flag that controls printing of convergence information from the
305 solver.
306 None - means print nothing.
307 summary - means print only the total
308 number of iterations and nonlinear residual reduction summaries.
309 all - means print linear matrix solver convergence information to the
310 solution listing file and model specific linear matrix solver
311 convergence information to each model listing file in addition to
312 SUMMARY information.
313 Default value: "summary"
314 SolutionPresetSimple: No Default
315 SolutionPresetModerate: No Default
316 SolutionPresetComplex: No Default
317 csv_output: str, optional
318 False if no csv is to be written for the output, enter str of filename
319 if csv is to be written.
320 Default value: False
321 SolutionPresetSimple: No Default
322 SolutionPresetModerate: No Default
323 SolutionPresetComplex: No Default
324 no_ptc: ({True, False}, optional)
325 is a flag that is used to disable pseudo-transient continuation (PTC).
326 Option only applies to steady-state stress periods for models using the
327 Newton-Raphson formulation. For many problems, PTC can significantly
328 improve convergence behavior for steady-state simulations, and for this
329 reason it is active by default. In some cases, however, PTC can worsen
330 the convergence behavior, especially when the initial conditions are
331 similar to the solution. When the initial conditions are similar to, or
332 exactly the same as, the solution and convergence is slow, then this NO
333 PTC option should be used to deactivate PTC. This NO PTC option should
334 also be used in order to compare convergence behavior with other MODFLOW
335 versions, as PTC is only available in MODFLOW 6.
336 Default value: False
337 SolutionPresetSimple: No Default
338 SolutionPresetModerate: No Default
339 SolutionPresetComplex: No Default
340 validate: {True, False}
341 Flag to indicate whether the package should be validated upon
342 initialization. This raises a ValidationError if package input is
343 provided in the wrong manner. Defaults to True.
344 """
346 _pkg_id = "ims"
347 _keyword_map = {}
349 _init_schemata = {
350 "outer_dvclose": [DTypeSchema(np.floating)],
351 "outer_maximum": [DTypeSchema(np.integer)],
352 "inner_maximum": [DTypeSchema(np.integer)],
353 "inner_dvclose": [DTypeSchema(np.floating)],
354 "inner_rclose": [DTypeSchema(np.floating)],
355 "under_relaxation_theta": [DTypeSchema(np.floating)],
356 "under_relaxation_kappa": [DTypeSchema(np.floating)],
357 "under_relaxation_gamma": [DTypeSchema(np.floating)],
358 "under_relaxation_momentum": [DTypeSchema(np.floating)],
359 "backtracking_number": [DTypeSchema(np.integer)],
360 "backtracking_tolerance": [DTypeSchema(np.floating)],
361 "backtracking_reduction_factor": [DTypeSchema(np.floating)],
362 "backtracking_residual_limit": [DTypeSchema(np.floating)],
363 "number_orthogonalizations": [DTypeSchema(np.integer)],
364 }
365 _template = Package._initialize_template(_pkg_id)
367 @init_log_decorator()
368 def __init__(
369 self,
370 modelnames,
371 outer_dvclose,
372 outer_maximum,
373 inner_maximum,
374 inner_dvclose,
375 inner_rclose,
376 linear_acceleration,
377 under_relaxation=None,
378 under_relaxation_theta=None,
379 under_relaxation_kappa=None,
380 under_relaxation_gamma=None,
381 under_relaxation_momentum=None,
382 backtracking_number=None,
383 backtracking_tolerance=None,
384 backtracking_reduction_factor=None,
385 backtracking_residual_limit=None,
386 rclose_option=None,
387 relaxation_factor=None,
388 preconditioner_levels=None,
389 preconditioner_drop_tolerance=None,
390 number_orthogonalizations=None,
391 scaling_method=None,
392 reordering_method=None,
393 print_option="summary",
394 csv_output=False,
395 no_ptc=False,
396 validate: bool = True,
397 ):
398 dict_dataset = {
399 "outer_dvclose": outer_dvclose,
400 "outer_maximum": outer_maximum,
401 "under_relaxation": under_relaxation,
402 "under_relaxation_theta": under_relaxation_theta,
403 "under_relaxation_kappa": under_relaxation_kappa,
404 "under_relaxation_gamma": under_relaxation_gamma,
405 "under_relaxation_momentum": under_relaxation_momentum,
406 "backtracking_number": backtracking_number,
407 "backtracking_tolerance": backtracking_tolerance,
408 "backtracking_reduction_factor": backtracking_reduction_factor,
409 "backtracking_residual_limit": backtracking_residual_limit,
410 "inner_maximum": inner_maximum,
411 "inner_dvclose": inner_dvclose,
412 "inner_rclose": inner_rclose,
413 "rclose_option": rclose_option,
414 "linear_acceleration": linear_acceleration,
415 "relaxation_factor": relaxation_factor,
416 "preconditioner_levels": preconditioner_levels,
417 "preconditioner_drop_tolerance": preconditioner_drop_tolerance,
418 "number_orthogonalizations": number_orthogonalizations,
419 "scaling_method": scaling_method,
420 "reordering_method": reordering_method,
421 "print_option": print_option,
422 "csv_output": csv_output,
423 "no_ptc": no_ptc,
424 }
425 # Make sure the modelnames are set as a variable rather than dimension:
426 if isinstance(modelnames, xr.DataArray):
427 dict_dataset["modelnames"] = modelnames
428 else:
429 dict_dataset["modelnames"] = ("model", modelnames)
430 super().__init__(dict_dataset)
431 self._validate_init_schemata(validate)
433 def remove_model_from_solution(self, modelname: str) -> None:
434 models_in_solution = self.get_models_in_solution()
435 if modelname not in models_in_solution:
436 raise ValueError(
437 f"attempted to remove model {modelname} from solution, but it was not found."
438 )
439 filtered_models = [m for m in models_in_solution if m != modelname]
441 if len(filtered_models) == 0:
442 self.dataset = self.dataset.drop_vars("modelnames")
443 else:
444 self.dataset.update({"modelnames": ("model", filtered_models)})
446 def add_model_to_solution(self, modelname: str) -> None:
447 models_in_solution = self.get_models_in_solution()
448 if modelname in models_in_solution:
449 raise ValueError(
450 f"attempted to add model {modelname} to solution, but it was already in it."
451 )
452 models_in_solution.append(modelname)
453 self.dataset.update({"modelnames": ("model", models_in_solution)})
455 def get_models_in_solution(self) -> list[str]:
456 models_in_solution = []
457 if "modelnames" in self.dataset.keys():
458 models_in_solution = list(self.dataset["modelnames"].values)
459 return models_in_solution
462def SolutionPresetSimple(
463 modelnames, print_option="summary", csv_output=False, no_ptc=False
464):
465 solution = Solution(
466 modelnames=modelnames,
467 print_option=print_option,
468 csv_output=csv_output,
469 no_ptc=no_ptc,
470 outer_dvclose=0.001,
471 outer_maximum=25,
472 under_relaxation=None,
473 under_relaxation_theta=0.0,
474 under_relaxation_kappa=0.0,
475 under_relaxation_gamma=0.0,
476 under_relaxation_momentum=0.0,
477 backtracking_number=0,
478 backtracking_tolerance=0.0,
479 backtracking_reduction_factor=0.0,
480 backtracking_residual_limit=0.0,
481 inner_maximum=50,
482 inner_dvclose=0.001,
483 inner_rclose=0.1,
484 rclose_option="strict",
485 linear_acceleration="cg",
486 relaxation_factor=0.0,
487 preconditioner_levels=0,
488 preconditioner_drop_tolerance=0,
489 number_orthogonalizations=0,
490 scaling_method=None,
491 reordering_method=None,
492 )
493 return solution
496def SolutionPresetModerate(
497 modelnames, print_option="summary", csv_output=False, no_ptc=False
498):
499 solution = Solution(
500 modelnames=modelnames,
501 print_option=print_option,
502 csv_output=csv_output,
503 no_ptc=no_ptc,
504 outer_dvclose=0.01,
505 outer_maximum=50,
506 under_relaxation="dbd",
507 under_relaxation_theta=0.9,
508 under_relaxation_kappa=0.0001,
509 under_relaxation_gamma=0.0,
510 under_relaxation_momentum=0.0,
511 backtracking_number=0,
512 backtracking_tolerance=0.0,
513 backtracking_reduction_factor=0.0,
514 backtracking_residual_limit=0.0,
515 inner_maximum=100,
516 inner_dvclose=0.01,
517 inner_rclose=0.1,
518 rclose_option="strict",
519 linear_acceleration="bicgstab",
520 relaxation_factor=0,
521 preconditioner_levels=0,
522 preconditioner_drop_tolerance=0.0,
523 number_orthogonalizations=0,
524 scaling_method=None,
525 reordering_method=None,
526 )
527 return solution
530def SolutionPresetComplex(
531 modelnames, print_option="summary", csv_output=False, no_ptc=False
532):
533 solution = Solution(
534 modelnames=modelnames,
535 print_option=print_option,
536 csv_output=csv_output,
537 no_ptc=no_ptc,
538 outer_dvclose=0.1,
539 outer_maximum=100,
540 under_relaxation="dbd",
541 under_relaxation_theta=0.8,
542 under_relaxation_kappa=0.0001,
543 under_relaxation_gamma=0.0,
544 under_relaxation_momentum=0.0,
545 backtracking_number=20,
546 backtracking_tolerance=1.05,
547 backtracking_reduction_factor=0.1,
548 backtracking_residual_limit=0.002,
549 inner_maximum=500,
550 inner_dvclose=0.1,
551 inner_rclose=0.1,
552 rclose_option="strict",
553 linear_acceleration="bicgstab",
554 relaxation_factor=0.0,
555 preconditioner_levels=5,
556 preconditioner_drop_tolerance=0.0001,
557 number_orthogonalizations=2,
558 scaling_method=None,
559 reordering_method=None,
560 )
561 return solution