Coverage for C:\src\imod-python\imod\flow\slv.py: 100%

24 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-08 14:15 +0200

1import jinja2 

2 

3from imod.flow.pkgbase import Package 

4 

5 

6class PreconditionedConjugateGradientSolver(Package): 

7 """ 

8 The Preconditioned Conjugate Gradient Solver is used to solve the finite 

9 difference equations in each step of a MODFLOW stress period. 

10 

11 Parameters 

12 ---------- 

13 max_iter: int 

14 is the maximum number of outer iterations - that is, calss to the 

15 solutions routine (MXITER). For a linear problem max_iter should be 1, unless 

16 more than 50 inner iterations are required, when max_iter could be as 

17 large as 10. A larger number (generally less than 100) is required for a 

18 nonlinear problem. 

19 inner_iter: int 

20 is the number of inner iterations (iter1). For nonlinear problems, 

21 inner_iter usually ranges from 10 to 30; a value of 30 will be 

22 sufficient for most linear problems. 

23 rclose: float 

24 is the residual criterion for convergence, in units of cubic length per 

25 time. The units for length and time are the same as established for all 

26 model data. When the maximum absolute value of the residual at all nodes 

27 during an iteration is less than or equal to RCLOSE, and the criterion 

28 for HCLOSE is also satisfied (see below), iteration stops. 

29 

30 Default value: 100.0. **Nota bene**: this is aimed at regional modelling. 

31 For detailed studies (e.g. lab experiments) much smaller values can be 

32 required. 

33 Very general rule of thumb: should be less than 10% of smallest cell volume. 

34 hclose: float 

35 is the head change criterion for convergence, in units of length. When 

36 the maximum absolute value of head change from all nodes during an 

37 iteration is less than or equal to HCLOSE, and the criterion for RCLOSE 

38 is also satisfied (see above), iteration stops. 

39 Default value: 1.0e-4. **Nota bene**: This is aimed at regional modelling, ` 

40 for detailed studies (e.g. lab experiments) much smaller values can be 

41 required. 

42 relax: float, optional 

43 is the relaxation parameter used. Usually, RELAX = 1.0, but for some 

44 problems a value of 0.99, 0.98, or 0.97 will reduce the number of 

45 iterations required for convergence. 

46 Default value: 0.98. 

47 matrix_conditioning_method: int, optional 

48 the flag used to select the matrix conditioning method 

49 1 is for Modified Incomplete Cholesky (for use on scalar computers) 

50 2 is for Polynomial (for use on vector computers or to conserve computer memory) 

51 damp: float, optional 

52 the damping factor. 

53 It is typically set equal to one, which indicates 

54 no damping. A value less than 1 and greater than 0 causes damping. DAMP 

55 does not affect inner iterations; instead, it affects outer iterations. 

56 Default value: 1.0. 

57 damp_transient: float, optional 

58 the damping factor for transient stress periods. 

59 it is read only when `damp` is specified as a negative value. 

60 If damp_transient is not read, then the single damping factor, 

61 `damp`, is used for both transient and steady-state stress periods. 

62 printout_interval: int, optional 

63 is the printout interval for PCG. 

64 If equal to zero, it is changed to 999. 

65 The maximum head change (positive or negative) and 

66 residual change are printed for each iteration of a time step 

67 whenever the time step is an even multiple of printout_interval. 

68 This printout also occurs at the end of each stress period 

69 regardless of the value of printout_interval. 

70 print_convergence_info: int, optional 

71 a flag that controls printing of convergence information from the solver: 

72 0 is for printing tables of maximum head change and residual each iteration 

73 1 is for printing only the total number of iterations 

74 2 is for no printing 

75 3 is for printing only if convergence fails 

76 """ 

77 

78 _pkg_id = "pcg" 

79 

80 # TODO: update when all options are known 

81 _variable_order = [ 

82 "max_iter", 

83 "inner_iter", 

84 "hclose", 

85 "rclose", 

86 "relax", 

87 "matrix_conditioning_method", 

88 "damp", 

89 "damp_transient", 

90 "printout_interval", 

91 "print_convergence_info", 

92 ] 

93 

94 _template_projectfile = jinja2.Template( 

95 "0001, ({{pkg_id}}), 1, Precondition Conjugate-Gradient\n" 

96 "{{max_iter}}, {{inner_iter}}, {{hclose}}, {{rclose}}, {{relax}}, " 

97 "{{matrix_conditioning_method}}, {{printout_interval}}, {{print_convergence_info}}, {{damp}}, {{damp_transient}}, " 

98 "{{IQERROR}}, {{QERROR}}\n" 

99 ) 

100 

101 def __init__( 

102 self, 

103 max_iter=150, 

104 inner_iter=100, 

105 rclose=1.0, 

106 hclose=1.0e-4, 

107 relax=0.98, 

108 damp=1.0, 

109 damp_transient=1.0, 

110 matrix_conditioning_method=1, 

111 printout_interval=0, 

112 print_convergence_info=1, 

113 ): 

114 super().__init__() 

115 self.dataset["max_iter"] = max_iter 

116 self.dataset["inner_iter"] = inner_iter 

117 self.dataset["rclose"] = rclose 

118 self.dataset["hclose"] = hclose 

119 self.dataset["relax"] = relax 

120 self.dataset["matrix_conditioning_method"] = matrix_conditioning_method 

121 self.dataset["damp"] = damp 

122 self.dataset["damp_transient"] = damp_transient 

123 self.dataset["printout_interval"] = printout_interval 

124 self.dataset["print_convergence_info"] = print_convergence_info 

125 

126 # TODO Check with Peter what these settings do 

127 # I now used the settings from the LHM here... 

128 self.dataset["IQERROR"] = 1 

129 self.dataset["QERROR"] = 5.0 

130 

131 def _render_projectfile(self, **kwargs): 

132 d = {k: v.item() for k, v in self.dataset.items()} 

133 d["pkg_id"] = self._pkg_id 

134 

135 return self._template_projectfile.render(**d)