MODFLOW 6  version 6.7.0.dev2
USGS Modular Hydrologic Model
NumericalModel.f90
Go to the documentation of this file.
2 
3  use kindmodule, only: dp, i4b
6  use basedismodule, only: disbasetype
7  use sparsemodule, only: sparsematrix
9  use listmodule, only: listtype
13 
14  implicit none
15  private
18 
20  character(len=LINELENGTH), pointer :: filename => null() !input file name
21  integer(I4B), pointer :: neq => null() !number of equations
22  integer(I4B), pointer :: nja => null() !number of connections
23  integer(I4B), pointer :: moffset => null() !offset of this model in the solution
24  integer(I4B), pointer :: icnvg => null() !convergence flag
25  integer(I4B), dimension(:), pointer, contiguous :: ia => null() !csr row pointer
26  integer(I4B), dimension(:), pointer, contiguous :: ja => null() !csr columns
27  real(dp), dimension(:), pointer, contiguous :: x => null() !dependent variable (head, conc, etc)
28  real(dp), dimension(:), pointer, contiguous :: rhs => null() !right-hand side vector
29  real(dp), dimension(:), pointer, contiguous :: cond => null() !conductance matrix
30  integer(I4B), dimension(:), pointer, contiguous :: idxglo => null() !pointer to position in solution matrix
31  real(dp), dimension(:), pointer, contiguous :: xold => null() !dependent variable for previous timestep
32  real(dp), dimension(:), pointer, contiguous :: flowja => null() !intercell flows
33  integer(I4B), dimension(:), pointer, contiguous :: ibound => null() !ibound array
34  !
35  ! -- Derived types
36  type(listtype), pointer :: bndlist => null() !array of boundary packages for this model
37  class(disbasetype), pointer :: dis => null() !discretization object
38 
39  contains
40  !
41  ! -- Required for all models (override procedures defined in BaseModelType)
42  procedure :: model_df
43  procedure :: model_ar
44  procedure :: model_fp
45  procedure :: model_da
46  !
47  ! -- Methods specific to a numerical model
48  procedure :: model_ac
49  procedure :: model_mc
50  procedure :: model_rp
51  procedure :: model_ad
52  procedure :: model_reset
53  procedure :: model_solve
54  procedure :: model_cf
55  procedure :: model_fc
56  procedure :: model_ptcchk
57  procedure :: model_ptc
58  procedure :: model_nr
59  procedure :: model_cc
60  procedure :: model_nur
61  procedure :: model_cq
62  procedure :: model_bd
63  procedure :: model_bdcalc
64  procedure :: model_bdsave
65  procedure :: model_ot
66  procedure :: model_bdentry
67  !
68  ! -- Utility methods
69  procedure :: allocate_scalars
70  procedure :: allocate_arrays
71  procedure :: set_moffset
72  procedure :: set_idsoln
73  procedure :: set_xptr
74  procedure :: set_rhsptr
75  procedure :: set_iboundptr
76  procedure :: get_mrange
77  procedure :: get_mcellid
78  procedure :: get_mnodeu
79  procedure :: get_iasym
80  procedure :: get_idv_scale
81  procedure :: create_lstfile
82  end type numericalmodeltype
83 
84 contains
85  !
86  ! -- Type-bound procedures for a numerical model
87  !
88  subroutine model_df(this)
89  class(numericalmodeltype) :: this
90  end subroutine model_df
91 
92  subroutine model_ac(this, sparse)
93  class(numericalmodeltype) :: this
94  type(sparsematrix), intent(inout) :: sparse
95  end subroutine model_ac
96 
97  subroutine model_mc(this, matrix_sln)
98  class(numericalmodeltype) :: this
99  class(matrixbasetype), pointer :: matrix_sln
100  end subroutine model_mc
101 
102  subroutine model_ar(this)
103  class(numericalmodeltype) :: this
104  end subroutine model_ar
105 
106  subroutine model_rp(this)
107  class(numericalmodeltype) :: this
108  end subroutine model_rp
109 
110  subroutine model_ad(this)
111  class(numericalmodeltype) :: this
112  end subroutine model_ad
113 
114  subroutine model_reset(this)
115  use bndmodule, only: bndtype, getbndfromlist
116  class(numericalmodeltype) :: this
117  ! local
118  class(bndtype), pointer :: packobj
119  integer(I4B) :: ip
120 
121  do ip = 1, this%bndlist%Count()
122  packobj => getbndfromlist(this%bndlist, ip)
123  call packobj%bnd_reset()
124  end do
125 
126  end subroutine model_reset
127 
128  subroutine model_solve(this)
129  class(numericalmodeltype) :: this
130  end subroutine model_solve
131 
132  subroutine model_cf(this, kiter)
133  class(numericalmodeltype) :: this
134  integer(I4B), intent(in) :: kiter
135  end subroutine model_cf
136 
137  subroutine model_fc(this, kiter, matrix_sln, inwtflag)
138  class(numericalmodeltype) :: this
139  integer(I4B), intent(in) :: kiter
140  class(matrixbasetype), pointer :: matrix_sln
141  integer(I4B), intent(in) :: inwtflag
142  end subroutine model_fc
143 
144  subroutine model_ptcchk(this, iptc)
145  class(numericalmodeltype) :: this
146  integer(I4B), intent(inout) :: iptc
147  iptc = 0
148  end subroutine model_ptcchk
149 
150  subroutine model_ptc(this, vec_residual, iptc, ptcf)
151  class(numericalmodeltype) :: this
152  class(vectorbasetype), pointer :: vec_residual
153  integer(I4B), intent(inout) :: iptc
154  real(DP), intent(inout) :: ptcf
155  end subroutine model_ptc
156 
157  subroutine model_nr(this, kiter, matrix, inwtflag)
158  class(numericalmodeltype) :: this
159  integer(I4B), intent(in) :: kiter
160  class(matrixbasetype), pointer :: matrix
161  integer(I4B), intent(in) :: inwtflag
162  end subroutine model_nr
163 
164  subroutine model_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
165  class(numericalmodeltype) :: this
166  integer(I4B), intent(in) :: innertot
167  integer(I4B), intent(in) :: kiter
168  integer(I4B), intent(in) :: iend
169  integer(I4B), intent(in) :: icnvgmod
170  character(len=LENPAKLOC), intent(inout) :: cpak
171  integer(I4B), intent(inout) :: ipak
172  real(DP), intent(inout) :: dpak
173  end subroutine model_cc
174 
175  subroutine model_nur(this, neqmod, x, xtemp, dx, inewtonur, dxmax, locmax)
176  class(numericalmodeltype) :: this
177  integer(I4B), intent(in) :: neqmod
178  real(DP), dimension(neqmod), intent(inout) :: x
179  real(DP), dimension(neqmod), intent(in) :: xtemp
180  real(DP), dimension(neqmod), intent(inout) :: dx
181  integer(I4B), intent(inout) :: inewtonur
182  real(DP), intent(inout) :: dxmax
183  integer(I4B), intent(inout) :: locmax
184  end subroutine model_nur
185 
186  subroutine model_cq(this, icnvg, isuppress_output)
187  class(numericalmodeltype) :: this
188  integer(I4B), intent(in) :: icnvg
189  integer(I4B), intent(in) :: isuppress_output
190  end subroutine model_cq
191 
192  subroutine model_bd(this, icnvg, isuppress_output)
193  class(numericalmodeltype) :: this
194  integer(I4B), intent(in) :: icnvg
195  integer(I4B), intent(in) :: isuppress_output
196  end subroutine model_bd
197 
198  subroutine model_bdcalc(this, icnvg)
199  class(numericalmodeltype) :: this
200  integer(I4B), intent(in) :: icnvg
201  end subroutine model_bdcalc
202 
203  subroutine model_bdsave(this, icnvg)
204  class(numericalmodeltype) :: this
205  integer(I4B), intent(in) :: icnvg
206  end subroutine model_bdsave
207 
208  subroutine model_ot(this)
209  class(numericalmodeltype) :: this
210  end subroutine model_ot
211 
212  subroutine model_bdentry(this, budterm, budtxt, rowlabel)
213  class(numericalmodeltype) :: this
214  real(DP), dimension(:, :), intent(in) :: budterm
215  character(len=LENBUDTXT), dimension(:), intent(in) :: budtxt
216  character(len=*), intent(in) :: rowlabel
217  end subroutine model_bdentry
218 
219  subroutine model_fp(this)
220  class(numericalmodeltype) :: this
221  end subroutine model_fp
222 
223  subroutine model_da(this)
224  ! -- modules
226  class(numericalmodeltype) :: this
227 
228  ! -- Scalars
229  call mem_deallocate(this%neq)
230  call mem_deallocate(this%nja)
231  call mem_deallocate(this%icnvg)
232  call mem_deallocate(this%moffset)
233  deallocate (this%filename)
234  !
235  ! -- Arrays
236  call mem_deallocate(this%xold)
237  call mem_deallocate(this%flowja, 'FLOWJA', this%memoryPath)
238  call mem_deallocate(this%idxglo)
239  !
240  ! -- derived types
241  call this%bndlist%Clear()
242  deallocate (this%bndlist)
243  !
244  ! -- nullify pointers
245  call mem_deallocate(this%x, 'X', this%memoryPath)
246  call mem_deallocate(this%rhs, 'RHS', this%memoryPath)
247  call mem_deallocate(this%ibound, 'IBOUND', this%memoryPath)
248  !
249  ! -- BaseModelType
250  call this%BaseModelType%model_da()
251  !
252  end subroutine model_da
253 
254  subroutine set_moffset(this, moffset)
255  class(numericalmodeltype) :: this
256  integer(I4B), intent(in) :: moffset
257  this%moffset = moffset
258  end subroutine set_moffset
259 
260  subroutine get_mrange(this, mstart, mend)
261  class(numericalmodeltype) :: this
262  integer(I4B), intent(inout) :: mstart
263  integer(I4B), intent(inout) :: mend
264  mstart = this%moffset + 1
265  mend = mstart + this%neq - 1
266  end subroutine get_mrange
267 
268  subroutine set_idsoln(this, id)
269  class(numericalmodeltype) :: this
270  integer(I4B), intent(in) :: id
271  this%idsoln = id
272  end subroutine set_idsoln
273 
274  subroutine allocate_scalars(this, modelname)
276  class(numericalmodeltype) :: this
277  character(len=*), intent(in) :: modelname
278  !
279  ! -- allocate basetype members
280  call this%BaseModelType%allocate_scalars(modelname)
281  !
282  ! -- allocate members from this type
283  call mem_allocate(this%neq, 'NEQ', this%memoryPath)
284  call mem_allocate(this%nja, 'NJA', this%memoryPath)
285  call mem_allocate(this%icnvg, 'ICNVG', this%memoryPath)
286  call mem_allocate(this%moffset, 'MOFFSET', this%memoryPath)
287  allocate (this%filename)
288  allocate (this%bndlist)
289  !
290  this%filename = ''
291  this%neq = 0
292  this%nja = 0
293  this%icnvg = 0
294  this%moffset = 0
295  end subroutine allocate_scalars
296 
297  subroutine allocate_arrays(this)
298  use constantsmodule, only: dzero
300  class(numericalmodeltype) :: this
301  integer(I4B) :: i
302  !
303  call mem_allocate(this%xold, this%neq, 'XOLD', this%memoryPath)
304  call mem_allocate(this%flowja, this%nja, 'FLOWJA', this%memoryPath)
305  call mem_allocate(this%idxglo, this%nja, 'IDXGLO', this%memoryPath)
306  !
307  ! -- initialize
308  do i = 1, size(this%flowja)
309  this%flowja(i) = dzero
310  end do
311  end subroutine allocate_arrays
312 
313  subroutine set_xptr(this, xsln, sln_offset, varNameTgt, memPathTgt)
315  ! -- dummy
316  class(numericalmodeltype) :: this
317  real(DP), dimension(:), pointer, contiguous, intent(in) :: xsln
318  integer(I4B) :: sln_offset
319  character(len=*), intent(in) :: varNameTgt
320  character(len=*), intent(in) :: memPathTgt
321  ! -- local
322  integer(I4B) :: offset
323  ! -- code
324  offset = this%moffset - sln_offset
325  this%x => xsln(offset + 1:offset + this%neq)
326  call mem_checkin(this%x, 'X', this%memoryPath, varnametgt, mempathtgt)
327  end subroutine set_xptr
328 
329  subroutine set_rhsptr(this, rhssln, sln_offset, varNameTgt, memPathTgt)
331  ! -- dummy
332  class(numericalmodeltype) :: this
333  real(DP), dimension(:), pointer, contiguous, intent(in) :: rhssln
334  integer(I4B) :: sln_offset
335  character(len=*), intent(in) :: varNameTgt
336  character(len=*), intent(in) :: memPathTgt
337  ! -- local
338  integer(I4B) :: offset
339  ! -- code
340  offset = this%moffset - sln_offset
341  this%rhs => rhssln(offset + 1:offset + this%neq)
342  call mem_checkin(this%rhs, 'RHS', this%memoryPath, varnametgt, mempathtgt)
343  end subroutine set_rhsptr
344 
345  subroutine set_iboundptr(this, iboundsln, sln_offset, varNameTgt, memPathTgt)
347  ! -- dummy
348  class(numericalmodeltype) :: this
349  integer(I4B), dimension(:), pointer, contiguous, intent(in) :: iboundsln
350  integer(I4B) :: sln_offset
351  character(len=*), intent(in) :: varNameTgt
352  character(len=*), intent(in) :: memPathTgt
353  ! -- local
354  integer(I4B) :: offset
355  ! -- code
356  offset = this%moffset - sln_offset
357  this%ibound => iboundsln(offset + 1:offset + this%neq)
358  call mem_checkin(this%ibound, 'IBOUND', this%memoryPath, varnametgt, &
359  mempathtgt)
360  end subroutine set_iboundptr
361 
362  subroutine get_mcellid(this, node, mcellid)
363  use bndmodule, only: bndtype, getbndfromlist
364  class(numericalmodeltype) :: this
365  integer(I4B), intent(in) :: node
366  character(len=*), intent(inout) :: mcellid
367  ! -- local
368  character(len=20) :: cellid
369  integer(I4B) :: ip, ipaknode, istart, istop
370  class(bndtype), pointer :: packobj
371 
372  if (node < 1) then
373  cellid = ''
374  else if (node <= this%dis%nodes) then
375  call this%dis%noder_to_string(node, cellid)
376  else
377  cellid = '***ERROR***'
378  ipaknode = node - this%dis%nodes
379  istart = 1
380  do ip = 1, this%bndlist%Count()
381  packobj => getbndfromlist(this%bndlist, ip)
382  if (packobj%npakeq == 0) cycle
383  istop = istart + packobj%npakeq - 1
384  if (istart <= ipaknode .and. ipaknode <= istop) then
385  write (cellid, '(a, a, a, i0, a, i0, a)') '(', &
386  trim(packobj%filtyp), '_', &
387  packobj%ibcnum, '-', ipaknode - packobj%ioffset, ')'
388  exit
389  end if
390  istart = istop + 1
391  end do
392  end if
393  write (mcellid, '(i0, a, a, a, a)') this%id, '_', this%macronym, '-', &
394  trim(adjustl(cellid))
395  end subroutine get_mcellid
396 
397  subroutine get_mnodeu(this, node, nodeu)
398  use bndmodule, only: bndtype, getbndfromlist
399  class(numericalmodeltype) :: this
400  integer(I4B), intent(in) :: node
401  integer(I4B), intent(inout) :: nodeu
402  ! -- local
403  if (node <= this%dis%nodes) then
404  nodeu = this%dis%get_nodeuser(node)
405  else
406  nodeu = -(node - this%dis%nodes)
407  end if
408  end subroutine get_mnodeu
409 
410  function get_iasym(this) result(iasym)
411  class(numericalmodeltype) :: this
412  integer(I4B) :: iasym
413  iasym = 0
414  end function get_iasym
415 
416  function get_idv_scale(this) result(idv_scale)
417  class(numericalmodeltype) :: this
418  integer(I4B) :: idv_scale
419  idv_scale = 0
420  end function get_idv_scale
421 
422  function castasnumericalmodelclass(obj) result(res)
423  implicit none
424  class(*), pointer, intent(inout) :: obj
425  class(numericalmodeltype), pointer :: res
426  !
427  res => null()
428  if (.not. associated(obj)) return
429  !
430  select type (obj)
431  class is (numericalmodeltype)
432  res => obj
433  end select
434  end function castasnumericalmodelclass
435 
436  subroutine addnumericalmodeltolist(list, model)
437  implicit none
438  ! -- dummy
439  type(listtype), intent(inout) :: list
440  class(numericalmodeltype), pointer, intent(inout) :: model
441  ! -- local
442  class(*), pointer :: obj
443  !
444  obj => model
445  call list%Add(obj)
446  end subroutine addnumericalmodeltolist
447 
448  function getnumericalmodelfromlist(list, idx) result(res)
449  implicit none
450  ! -- dummy
451  type(listtype), intent(inout) :: list
452  integer(I4B), intent(in) :: idx
453  class(numericalmodeltype), pointer :: res
454  ! -- local
455  class(*), pointer :: obj
456  !
457  obj => list%GetItem(idx)
458  res => castasnumericalmodelclass(obj)
459  end function getnumericalmodelfromlist
460 
461  subroutine create_lstfile(this, lst_fname, model_fname, defined, headertxt)
462  ! -- modules
463  use kindmodule, only: lgp
465  ! -- dummy
466  class(numericalmodeltype) :: this
467  character(len=*), intent(inout) :: lst_fname
468  character(len=*), intent(in) :: model_fname
469  logical(LGP), intent(in) :: defined
470  character(len=*), intent(in) :: headertxt
471  ! -- local
472  integer(I4B) :: i, istart, istop
473  !
474  ! -- set list file name if not provided
475  if (.not. defined) then
476  !
477  ! -- initialize
478  lst_fname = ' '
479  istart = 0
480  istop = len_trim(model_fname)
481  !
482  ! -- identify '.' character position from back of string
483  do i = istop, 1, -1
484  if (model_fname(i:i) == '.') then
485  istart = i
486  exit
487  end if
488  end do
489  !
490  ! -- if not found start from string end
491  if (istart == 0) istart = istop + 1
492  !
493  ! -- set list file name
494  lst_fname = model_fname(1:istart)
495  istop = istart + 3
496  lst_fname(istart:istop) = '.lst'
497  end if
498  !
499  ! -- create the list file
500  this%iout = getunit()
501  call openfile(this%iout, 0, lst_fname, 'LIST', filstat_opt='REPLACE')
502  !
503  ! -- write list file header
504  call write_listfile_header(this%iout, headertxt)
505  end subroutine create_lstfile
506 
507 end module numericalmodelmodule
This module contains the base boundary package.
class(bndtype) function, pointer, public getbndfromlist(list, idx)
Get boundary from package list.
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
integer(i4b), parameter lenpakloc
maximum length of a package location
Definition: Constants.f90:50
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
Definition: Constants.f90:37
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
This module defines variable data types.
Definition: kind.f90:8
subroutine, public addnumericalmodeltolist(list, model)
subroutine model_ac(this, sparse)
subroutine model_df(this)
subroutine model_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
subroutine model_bdsave(this, icnvg)
subroutine model_ad(this)
subroutine model_solve(this)
subroutine get_mrange(this, mstart, mend)
subroutine model_mc(this, matrix_sln)
class(numericalmodeltype) function, pointer, public getnumericalmodelfromlist(list, idx)
subroutine set_rhsptr(this, rhssln, sln_offset, varNameTgt, memPathTgt)
subroutine model_ar(this)
subroutine model_nr(this, kiter, matrix, inwtflag)
subroutine set_idsoln(this, id)
subroutine get_mnodeu(this, node, nodeu)
subroutine model_nur(this, neqmod, x, xtemp, dx, inewtonur, dxmax, locmax)
subroutine model_cq(this, icnvg, isuppress_output)
subroutine model_da(this)
subroutine model_bd(this, icnvg, isuppress_output)
subroutine model_bdcalc(this, icnvg)
subroutine model_fp(this)
subroutine get_mcellid(this, node, mcellid)
subroutine model_reset(this)
class(numericalmodeltype) function, pointer castasnumericalmodelclass(obj)
subroutine model_ptc(this, vec_residual, iptc, ptcf)
subroutine set_moffset(this, moffset)
subroutine model_ptcchk(this, iptc)
subroutine create_lstfile(this, lst_fname, model_fname, defined, headertxt)
subroutine allocate_arrays(this)
integer(i4b) function get_iasym(this)
subroutine allocate_scalars(this, modelname)
integer(i4b) function get_idv_scale(this)
subroutine set_iboundptr(this, iboundsln, sln_offset, varNameTgt, memPathTgt)
subroutine model_fc(this, kiter, matrix_sln, inwtflag)
subroutine model_ot(this)
subroutine model_cf(this, kiter)
subroutine set_xptr(this, xsln, sln_offset, varNameTgt, memPathTgt)
subroutine model_bdentry(this, budterm, budtxt, rowlabel)
subroutine model_rp(this)
This module contains version information.
Definition: version.f90:7
subroutine write_listfile_header(iout, cmodel_type, write_sys_command, write_kind_info)
@ brief Write program header
Definition: version.f90:98
Highest level model type. All models extend this parent type.
Definition: BaseModel.f90:13
@ brief BndType
A generic heterogeneous doubly-linked list.
Definition: List.f90:14