MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
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 :: create_lstfile
81  end type numericalmodeltype
82 
83 contains
84  !
85  ! -- Type-bound procedures for a numerical model
86  !
87  subroutine model_df(this)
88  class(numericalmodeltype) :: this
89  end subroutine model_df
90 
91  subroutine model_ac(this, sparse)
92  class(numericalmodeltype) :: this
93  type(sparsematrix), intent(inout) :: sparse
94  end subroutine model_ac
95 
96  subroutine model_mc(this, matrix_sln)
97  class(numericalmodeltype) :: this
98  class(matrixbasetype), pointer :: matrix_sln
99  end subroutine model_mc
100 
101  subroutine model_ar(this)
102  class(numericalmodeltype) :: this
103  end subroutine model_ar
104 
105  subroutine model_rp(this)
106  class(numericalmodeltype) :: this
107  end subroutine model_rp
108 
109  subroutine model_ad(this)
110  class(numericalmodeltype) :: this
111  end subroutine model_ad
112 
113  subroutine model_reset(this)
114  use bndmodule, only: bndtype, getbndfromlist
115  class(numericalmodeltype) :: this
116  ! local
117  class(bndtype), pointer :: packobj
118  integer(I4B) :: ip
119 
120  do ip = 1, this%bndlist%Count()
121  packobj => getbndfromlist(this%bndlist, ip)
122  call packobj%bnd_reset()
123  end do
124 
125  end subroutine model_reset
126 
127  subroutine model_solve(this)
128  class(numericalmodeltype) :: this
129  end subroutine model_solve
130 
131  subroutine model_cf(this, kiter)
132  class(numericalmodeltype) :: this
133  integer(I4B), intent(in) :: kiter
134  end subroutine model_cf
135 
136  subroutine model_fc(this, kiter, matrix_sln, inwtflag)
137  class(numericalmodeltype) :: this
138  integer(I4B), intent(in) :: kiter
139  class(matrixbasetype), pointer :: matrix_sln
140  integer(I4B), intent(in) :: inwtflag
141  end subroutine model_fc
142 
143  subroutine model_ptcchk(this, iptc)
144  class(numericalmodeltype) :: this
145  integer(I4B), intent(inout) :: iptc
146  iptc = 0
147  end subroutine model_ptcchk
148 
149  subroutine model_ptc(this, vec_residual, iptc, ptcf)
150  class(numericalmodeltype) :: this
151  class(vectorbasetype), pointer :: vec_residual
152  integer(I4B), intent(inout) :: iptc
153  real(DP), intent(inout) :: ptcf
154  end subroutine model_ptc
155 
156  subroutine model_nr(this, kiter, matrix, inwtflag)
157  class(numericalmodeltype) :: this
158  integer(I4B), intent(in) :: kiter
159  class(matrixbasetype), pointer :: matrix
160  integer(I4B), intent(in) :: inwtflag
161  end subroutine model_nr
162 
163  subroutine model_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
164  class(numericalmodeltype) :: this
165  integer(I4B), intent(in) :: innertot
166  integer(I4B), intent(in) :: kiter
167  integer(I4B), intent(in) :: iend
168  integer(I4B), intent(in) :: icnvgmod
169  character(len=LENPAKLOC), intent(inout) :: cpak
170  integer(I4B), intent(inout) :: ipak
171  real(DP), intent(inout) :: dpak
172  end subroutine model_cc
173 
174  subroutine model_nur(this, neqmod, x, xtemp, dx, inewtonur, dxmax, locmax)
175  class(numericalmodeltype) :: this
176  integer(I4B), intent(in) :: neqmod
177  real(DP), dimension(neqmod), intent(inout) :: x
178  real(DP), dimension(neqmod), intent(in) :: xtemp
179  real(DP), dimension(neqmod), intent(inout) :: dx
180  integer(I4B), intent(inout) :: inewtonur
181  real(DP), intent(inout) :: dxmax
182  integer(I4B), intent(inout) :: locmax
183  end subroutine model_nur
184 
185  subroutine model_cq(this, icnvg, isuppress_output)
186  class(numericalmodeltype) :: this
187  integer(I4B), intent(in) :: icnvg
188  integer(I4B), intent(in) :: isuppress_output
189  end subroutine model_cq
190 
191  subroutine model_bd(this, icnvg, isuppress_output)
192  class(numericalmodeltype) :: this
193  integer(I4B), intent(in) :: icnvg
194  integer(I4B), intent(in) :: isuppress_output
195  end subroutine model_bd
196 
197  subroutine model_bdcalc(this, icnvg)
198  class(numericalmodeltype) :: this
199  integer(I4B), intent(in) :: icnvg
200  end subroutine model_bdcalc
201 
202  subroutine model_bdsave(this, icnvg)
203  class(numericalmodeltype) :: this
204  integer(I4B), intent(in) :: icnvg
205  end subroutine model_bdsave
206 
207  subroutine model_ot(this)
208  class(numericalmodeltype) :: this
209  end subroutine model_ot
210 
211  subroutine model_bdentry(this, budterm, budtxt, rowlabel)
212  class(numericalmodeltype) :: this
213  real(DP), dimension(:, :), intent(in) :: budterm
214  character(len=LENBUDTXT), dimension(:), intent(in) :: budtxt
215  character(len=*), intent(in) :: rowlabel
216  end subroutine model_bdentry
217 
218  subroutine model_fp(this)
219  class(numericalmodeltype) :: this
220  end subroutine model_fp
221 
222  subroutine model_da(this)
223  ! -- modules
225  class(numericalmodeltype) :: this
226 
227  ! -- Scalars
228  call mem_deallocate(this%neq)
229  call mem_deallocate(this%nja)
230  call mem_deallocate(this%icnvg)
231  call mem_deallocate(this%moffset)
232  deallocate (this%filename)
233  !
234  ! -- Arrays
235  call mem_deallocate(this%xold)
236  call mem_deallocate(this%flowja)
237  call mem_deallocate(this%idxglo)
238  !
239  ! -- derived types
240  call this%bndlist%Clear()
241  deallocate (this%bndlist)
242  !
243  ! -- nullify pointers
244  call mem_deallocate(this%x, 'X', this%memoryPath)
245  call mem_deallocate(this%rhs, 'RHS', this%memoryPath)
246  call mem_deallocate(this%ibound, 'IBOUND', this%memoryPath)
247  !
248  ! -- BaseModelType
249  call this%BaseModelType%model_da()
250  !
251  !
252  ! -- Return
253  return
254  end subroutine model_da
255 
256  subroutine set_moffset(this, moffset)
257  class(numericalmodeltype) :: this
258  integer(I4B), intent(in) :: moffset
259  this%moffset = moffset
260  end subroutine set_moffset
261 
262  subroutine get_mrange(this, mstart, mend)
263  class(numericalmodeltype) :: this
264  integer(I4B), intent(inout) :: mstart
265  integer(I4B), intent(inout) :: mend
266  mstart = this%moffset + 1
267  mend = mstart + this%neq - 1
268  end subroutine get_mrange
269 
270  subroutine set_idsoln(this, id)
271  class(numericalmodeltype) :: this
272  integer(I4B), intent(in) :: id
273  this%idsoln = id
274  end subroutine set_idsoln
275 
276  subroutine allocate_scalars(this, modelname)
278  class(numericalmodeltype) :: this
279  character(len=*), intent(in) :: modelname
280  !
281  ! -- allocate basetype members
282  call this%BaseModelType%allocate_scalars(modelname)
283  !
284  ! -- allocate members from this type
285  call mem_allocate(this%neq, 'NEQ', this%memoryPath)
286  call mem_allocate(this%nja, 'NJA', this%memoryPath)
287  call mem_allocate(this%icnvg, 'ICNVG', this%memoryPath)
288  call mem_allocate(this%moffset, 'MOFFSET', this%memoryPath)
289  allocate (this%filename)
290  allocate (this%bndlist)
291  !
292  this%filename = ''
293  this%neq = 0
294  this%nja = 0
295  this%icnvg = 0
296  this%moffset = 0
297  !
298  ! -- return
299  return
300  end subroutine allocate_scalars
301 
302  subroutine allocate_arrays(this)
303  use constantsmodule, only: dzero
305  class(numericalmodeltype) :: this
306  integer(I4B) :: i
307  !
308  call mem_allocate(this%xold, this%neq, 'XOLD', this%memoryPath)
309  call mem_allocate(this%flowja, this%nja, 'FLOWJA', this%memoryPath)
310  call mem_allocate(this%idxglo, this%nja, 'IDXGLO', this%memoryPath)
311  !
312  ! -- initialize
313  do i = 1, size(this%flowja)
314  this%flowja(i) = dzero
315  end do
316  !
317  ! -- return
318  return
319  end subroutine allocate_arrays
320 
321  subroutine set_xptr(this, xsln, sln_offset, varNameTgt, memPathTgt)
323  ! -- dummy
324  class(numericalmodeltype) :: this
325  real(DP), dimension(:), pointer, contiguous, intent(in) :: xsln
326  integer(I4B) :: sln_offset
327  character(len=*), intent(in) :: varNameTgt
328  character(len=*), intent(in) :: memPathTgt
329  ! -- local
330  integer(I4B) :: offset
331  ! -- code
332  offset = this%moffset - sln_offset
333  this%x => xsln(offset + 1:offset + this%neq)
334  call mem_checkin(this%x, 'X', this%memoryPath, varnametgt, mempathtgt)
335  end subroutine set_xptr
336 
337  subroutine set_rhsptr(this, rhssln, sln_offset, varNameTgt, memPathTgt)
339  ! -- dummy
340  class(numericalmodeltype) :: this
341  real(DP), dimension(:), pointer, contiguous, intent(in) :: rhssln
342  integer(I4B) :: sln_offset
343  character(len=*), intent(in) :: varNameTgt
344  character(len=*), intent(in) :: memPathTgt
345  ! -- local
346  integer(I4B) :: offset
347  ! -- code
348  offset = this%moffset - sln_offset
349  this%rhs => rhssln(offset + 1:offset + this%neq)
350  call mem_checkin(this%rhs, 'RHS', this%memoryPath, varnametgt, mempathtgt)
351  end subroutine set_rhsptr
352 
353  subroutine set_iboundptr(this, iboundsln, sln_offset, varNameTgt, memPathTgt)
355  ! -- dummy
356  class(numericalmodeltype) :: this
357  integer(I4B), dimension(:), pointer, contiguous, intent(in) :: iboundsln
358  integer(I4B) :: sln_offset
359  character(len=*), intent(in) :: varNameTgt
360  character(len=*), intent(in) :: memPathTgt
361  ! -- local
362  integer(I4B) :: offset
363  ! -- code
364  offset = this%moffset - sln_offset
365  this%ibound => iboundsln(offset + 1:offset + this%neq)
366  call mem_checkin(this%ibound, 'IBOUND', this%memoryPath, varnametgt, &
367  mempathtgt)
368  end subroutine set_iboundptr
369 
370  subroutine get_mcellid(this, node, mcellid)
371  use bndmodule, only: bndtype, getbndfromlist
372  class(numericalmodeltype) :: this
373  integer(I4B), intent(in) :: node
374  character(len=*), intent(inout) :: mcellid
375  ! -- local
376  character(len=20) :: cellid
377  integer(I4B) :: ip, ipaknode, istart, istop
378  class(bndtype), pointer :: packobj
379 
380  if (node < 1) then
381  cellid = ''
382  else if (node <= this%dis%nodes) then
383  call this%dis%noder_to_string(node, cellid)
384  else
385  cellid = '***ERROR***'
386  ipaknode = node - this%dis%nodes
387  istart = 1
388  do ip = 1, this%bndlist%Count()
389  packobj => getbndfromlist(this%bndlist, ip)
390  if (packobj%npakeq == 0) cycle
391  istop = istart + packobj%npakeq - 1
392  if (istart <= ipaknode .and. ipaknode <= istop) then
393  write (cellid, '(a, a, a, i0, a, i0, a)') '(', &
394  trim(packobj%filtyp), '_', &
395  packobj%ibcnum, '-', ipaknode - packobj%ioffset, ')'
396  exit
397  end if
398  istart = istop + 1
399  end do
400  end if
401  write (mcellid, '(i0, a, a, a, a)') this%id, '_', this%macronym, '-', &
402  trim(adjustl(cellid))
403  return
404  end subroutine get_mcellid
405 
406  subroutine get_mnodeu(this, node, nodeu)
407  use bndmodule, only: bndtype, getbndfromlist
408  class(numericalmodeltype) :: this
409  integer(I4B), intent(in) :: node
410  integer(I4B), intent(inout) :: nodeu
411  ! -- local
412  if (node <= this%dis%nodes) then
413  nodeu = this%dis%get_nodeuser(node)
414  else
415  nodeu = -(node - this%dis%nodes)
416  end if
417  return
418  end subroutine get_mnodeu
419 
420  function get_iasym(this) result(iasym)
421  class(numericalmodeltype) :: this
422  integer(I4B) :: iasym
423  iasym = 0
424  end function get_iasym
425 
426  function castasnumericalmodelclass(obj) result(res)
427  implicit none
428  class(*), pointer, intent(inout) :: obj
429  class(numericalmodeltype), pointer :: res
430  !
431  res => null()
432  if (.not. associated(obj)) return
433  !
434  select type (obj)
435  class is (numericalmodeltype)
436  res => obj
437  end select
438  return
439  end function castasnumericalmodelclass
440 
441  subroutine addnumericalmodeltolist(list, model)
442  implicit none
443  ! -- dummy
444  type(listtype), intent(inout) :: list
445  class(numericalmodeltype), pointer, intent(inout) :: model
446  ! -- local
447  class(*), pointer :: obj
448  !
449  obj => model
450  call list%Add(obj)
451  !
452  return
453  end subroutine addnumericalmodeltolist
454 
455  function getnumericalmodelfromlist(list, idx) result(res)
456  implicit none
457  ! -- dummy
458  type(listtype), intent(inout) :: list
459  integer(I4B), intent(in) :: idx
460  class(numericalmodeltype), pointer :: res
461  ! -- local
462  class(*), pointer :: obj
463  !
464  obj => list%GetItem(idx)
465  res => castasnumericalmodelclass(obj)
466  !
467  return
468  end function getnumericalmodelfromlist
469 
470  subroutine create_lstfile(this, lst_fname, model_fname, defined, headertxt)
471  ! -- modules
472  use kindmodule, only: lgp
474  ! -- dummy
475  class(numericalmodeltype) :: this
476  character(len=*), intent(inout) :: lst_fname
477  character(len=*), intent(in) :: model_fname
478  logical(LGP), intent(in) :: defined
479  character(len=*), intent(in) :: headertxt
480  ! -- local
481  integer(I4B) :: i, istart, istop
482  !
483  ! -- set list file name if not provided
484  if (.not. defined) then
485  !
486  ! -- initialize
487  lst_fname = ' '
488  istart = 0
489  istop = len_trim(model_fname)
490  !
491  ! -- identify '.' character position from back of string
492  do i = istop, 1, -1
493  if (model_fname(i:i) == '.') then
494  istart = i
495  exit
496  end if
497  end do
498  !
499  ! -- if not found start from string end
500  if (istart == 0) istart = istop + 1
501  !
502  ! -- set list file name
503  lst_fname = model_fname(1:istart)
504  istop = istart + 3
505  lst_fname(istart:istop) = '.lst'
506  end if
507  !
508  ! -- create the list file
509  this%iout = getunit()
510  call openfile(this%iout, 0, lst_fname, 'LIST', filstat_opt='REPLACE')
511  !
512  ! -- write list file header
513  call write_listfile_header(this%iout, headertxt)
514  !
515  ! -- return
516  return
517  end subroutine create_lstfile
518 
519 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:44
integer(i4b), parameter lenpakloc
maximum length of a package location
Definition: Constants.f90:49
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:64
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
Definition: Constants.f90:36
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)
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:10