MODFLOW 6  version 6.6.0.dev0
USGS Modular Hydrologic Model
ImsLinearSettings.f90
Go to the documentation of this file.
2  use kindmodule
7  implicit none
8  private
9 
10  integer(I4B), public, parameter :: cg_method = 1
11  integer(I4B), public, parameter :: bcgs_method = 2
12 
13  type, public :: imslinearsettingstype
14  character(len=LENMEMPATH) :: memory_path
15  real(dp), pointer :: dvclose => null() !< dependent variable closure criterion
16  real(dp), pointer :: rclose => null() !< residual closure criterion
17  integer(I4B), pointer :: icnvgopt => null() !< convergence option
18  integer(I4B), pointer :: iter1 => null() !< max. iterations
19  integer(I4B), pointer :: ilinmeth => null() !< linear solver method
20  integer(I4B), pointer :: iscl => null() !< scaling method
21  integer(I4B), pointer :: iord => null() !< reordering method
22  integer(I4B), pointer :: north => null() !< number of orthogonalizations
23  real(dp), pointer :: relax => null() !< relaxation factor
24  integer(I4B), pointer :: level => null() !< nr. of preconditioner levels
25  real(dp), pointer :: droptol => null() !< drop tolerance for preconditioner
26  integer(I4B), pointer :: ifdparam => null() !< complexity option
27  contains
28  procedure :: init
29  procedure :: preset_config
30  procedure :: read_from_file
31  procedure :: destroy
32  end type
33 
34 contains
35 
36  subroutine init(this, mem_path)
38  class(imslinearsettingstype) :: this !< linear settings
39  character(len=LENMEMPATH) :: mem_path !< solution memory path
40 
41  this%memory_path = create_mem_path(mem_path, 'IMSLINEAR')
42 
43  call mem_allocate(this%dvclose, 'DVCLOSE', this%memory_path)
44  call mem_allocate(this%rclose, 'RCLOSE', this%memory_path)
45  call mem_allocate(this%icnvgopt, 'ICNVGOPT', this%memory_path)
46  call mem_allocate(this%iter1, 'ITER1', this%memory_path)
47  call mem_allocate(this%ilinmeth, 'ILINMETH', this%memory_path)
48  call mem_allocate(this%iscl, 'ISCL', this%memory_path)
49  call mem_allocate(this%iord, 'IORD', this%memory_path)
50  call mem_allocate(this%north, 'NORTH', this%memory_path)
51  call mem_allocate(this%relax, 'RELAX', this%memory_path)
52  call mem_allocate(this%level, 'LEVEL', this%memory_path)
53  call mem_allocate(this%droptol, 'DROPTOL', this%memory_path)
54  call mem_allocate(this%ifdparam, 'IDFPARAM', this%memory_path)
55 
56  ! defaults
57  this%dvclose = dzero
58  this%rclose = dzero
59  this%icnvgopt = 0
60  this%iter1 = 0
61  this%ilinmeth = 0
62  this%iscl = 0
63  this%iord = 0
64  this%north = 0
65  this%relax = dzero
66  this%level = 0
67  this%droptol = dzero
68  this%ifdparam = 0
69 
70  end subroutine init
71 
72  !> @brief Set solver pre-configured settings based on complexity option
73  !<
74  subroutine preset_config(this, idfparam)
75  class(imslinearsettingstype) :: this !< linear settings
76  integer(I4B) :: idfparam !< complexity option
77 
78  this%ifdparam = idfparam
79 
80  select case (idfparam)
81  case (1) ! Simple option
82  this%iter1 = 50
83  this%ilinmeth = 1
84  this%iscl = 0
85  this%iord = 0
86  this%dvclose = dem3
87  this%rclose = dem1
88  this%relax = dzero
89  this%level = 0
90  this%droptol = dzero
91  this%north = 0
92  case (2) ! Moderate
93  this%iter1 = 100
94  this%ilinmeth = 2
95  this%iscl = 0
96  this%iord = 0
97  this%dvclose = dem2
98  this%rclose = dem1
99  this%relax = 0.97d0
100  this%level = 0
101  this%droptol = dzero
102  this%north = 0
103  case (3) ! Complex
104  this%iter1 = 500
105  this%ilinmeth = 2
106  this%iscl = 0
107  this%iord = 0
108  this%dvclose = dem1
109  this%rclose = dem1
110  this%relax = dzero
111  this%level = 5
112  this%droptol = dem4
113  this%north = 2
114  end select
115 
116  end subroutine preset_config
117 
118  !> @brief Read the settings for the linear solver from the .ims file,
119  !< overriding a possible pre-set configuration with set_complexity
120  subroutine read_from_file(this, parser, iout)
121  class(imslinearsettingstype) :: this !< linear settings
122  type(blockparsertype) :: parser !< block parser
123  integer(I4B) :: iout !< listing file
124  ! local
125  logical(LGP) :: block_found, end_of_block
126  integer(I4B) :: ierr
127  character(len=LINELENGTH) :: errmsg
128  character(len=LINELENGTH) :: warnmsg
129  character(len=LINELENGTH) :: keyword
130  integer(I4B) :: iscaling, iordering
131 
132  call parser%GetBlock('LINEAR', block_found, ierr, supportopenclose=.true., &
133  blockrequired=.false.)
134 
135  if (block_found) then
136  write (iout, '(/1x,a)') 'PROCESSING LINEAR DATA'
137  do
138  call parser%GetNextLine(end_of_block)
139  if (end_of_block) exit
140  call parser%GetStringCaps(keyword)
141  ! -- parse keyword
142  select case (keyword)
143  case ('INNER_DVCLOSE')
144  this%dvclose = parser%GetDouble()
145  case ('INNER_RCLOSE')
146  this%rclose = parser%GetDouble()
147  ! -- look for additional key words
148  call parser%GetStringCaps(keyword)
149  if (keyword == 'STRICT') then
150  this%icnvgopt = 1
151  else if (keyword == 'L2NORM_RCLOSE') then
152  this%icnvgopt = 2
153  else if (keyword == 'RELATIVE_RCLOSE') then
154  this%icnvgopt = 3
155  else if (keyword == 'L2NORM_RELATIVE_RCLOSE') then
156  this%icnvgopt = 4
157  end if
158  case ('INNER_MAXIMUM')
159  this%iter1 = parser%GetInteger()
160  case ('LINEAR_ACCELERATION')
161  call parser%GetStringCaps(keyword)
162  if (keyword .eq. 'CG') then
163  this%ilinmeth = 1
164  else if (keyword .eq. 'BICGSTAB') then
165  this%ilinmeth = 2
166  else
167  this%ilinmeth = 0
168  write (errmsg, '(3a)') &
169  'Unknown IMSLINEAR LINEAR_ACCELERATION method (', &
170  trim(keyword), ').'
171  call store_error(errmsg)
172  end if
173  case ('SCALING_METHOD')
174  call parser%GetStringCaps(keyword)
175  iscaling = 0
176  if (keyword .eq. 'NONE') then
177  iscaling = 0
178  else if (keyword .eq. 'DIAGONAL') then
179  iscaling = 1
180  else if (keyword .eq. 'L2NORM') then
181  iscaling = 2
182  else
183  write (errmsg, '(3a)') &
184  'Unknown IMSLINEAR SCALING_METHOD (', trim(keyword), ').'
185  call store_error(errmsg)
186  end if
187  this%iscl = iscaling
188  case ('RED_BLACK_ORDERING')
189  iordering = 0
190  case ('REORDERING_METHOD')
191  call parser%GetStringCaps(keyword)
192  iordering = 0
193  if (keyword == 'NONE') then
194  iordering = 0
195  else if (keyword == 'RCM') then
196  iordering = 1
197  else if (keyword == 'MD') then
198  iordering = 2
199  else
200  write (errmsg, '(3a)') &
201  'Unknown IMSLINEAR REORDERING_METHOD (', trim(keyword), ').'
202  call store_error(errmsg)
203  end if
204  this%iord = iordering
205  case ('NUMBER_ORTHOGONALIZATIONS')
206  this%north = parser%GetInteger()
207  case ('RELAXATION_FACTOR')
208  this%relax = parser%GetDouble()
209  case ('PRECONDITIONER_LEVELS')
210  this%level = parser%GetInteger()
211  if (this%level < 0) then
212  write (errmsg, '(a,1x,a)') &
213  'IMSLINEAR PRECONDITIONER_LEVELS must be greater than', &
214  'or equal to zero'
215  call store_error(errmsg)
216  end if
217  case ('PRECONDITIONER_DROP_TOLERANCE')
218  this%droptol = parser%GetDouble()
219  if (this%droptol < dzero) then
220  write (errmsg, '(a,1x,a)') &
221  'IMSLINEAR PRECONDITIONER_DROP_TOLERANCE', &
222  'must be greater than or equal to zero'
223  call store_error(errmsg)
224  end if
225  !
226  ! -- deprecated variables
227  case ('INNER_HCLOSE')
228  this%dvclose = parser%GetDouble()
229  !
230  ! -- create warning message
231  write (warnmsg, '(a)') &
232  'SETTING INNER_DVCLOSE TO INNER_HCLOSE VALUE'
233  !
234  ! -- create deprecation warning
235  call deprecation_warning('LINEAR', 'INNER_HCLOSE', '6.1.1', &
236  warnmsg, parser%GetUnit())
237  !
238  ! -- default
239  case default
240  write (errmsg, '(3a)') &
241  'Unknown IMSLINEAR keyword (', trim(keyword), ').'
242  call store_error(errmsg)
243  end select
244  end do
245  write (iout, '(1x,a)') 'END OF LINEAR DATA'
246  else
247  if (this%ifdparam == 0) THEN
248  write (errmsg, '(a)') 'NO LINEAR block detected.'
249  call store_error(errmsg)
250  end if
251  end if
252 
253  end subroutine read_from_file
254 
255  subroutine destroy(this)
256  class(imslinearsettingstype) :: this !< linear settings
257 
258  call mem_deallocate(this%dvclose)
259  call mem_deallocate(this%rclose)
260  call mem_deallocate(this%icnvgopt)
261  call mem_deallocate(this%iter1)
262  call mem_deallocate(this%ilinmeth)
263  call mem_deallocate(this%iscl)
264  call mem_deallocate(this%iord)
265  call mem_deallocate(this%north)
266  call mem_deallocate(this%relax)
267  call mem_deallocate(this%level)
268  call mem_deallocate(this%droptol)
269  call mem_deallocate(this%ifdparam)
270 
271  end subroutine destroy
272 
273 end module
subroutine init()
Definition: GridSorting.f90:24
This module contains block parser methods.
Definition: BlockParser.f90:7
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dem1
real constant 1e-1
Definition: Constants.f90:103
real(dp), parameter dem3
real constant 1e-3
Definition: Constants.f90:106
real(dp), parameter dem4
real constant 1e-4
Definition: Constants.f90:107
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
real(dp), parameter dem2
real constant 1e-2
Definition: Constants.f90:105
integer(i4b), parameter, public cg_method
subroutine read_from_file(this, parser, iout)
Read the settings for the linear solver from the .ims file,.
subroutine preset_config(this, idfparam)
Set solver pre-configured settings based on complexity option.
integer(i4b), parameter, public bcgs_method
This module defines variable data types.
Definition: kind.f90:8
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
subroutine, public deprecation_warning(cblock, cvar, cver, endmsg, iunit)
Store deprecation warning message.
Definition: Sim.f90:256