MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
ModelPackageInputs.f90
Go to the documentation of this file.
1 !> @brief This module contains the ModelPackageInputsModule
2 !!
3 !! This module contains the high-level routines for assembling
4 !! model package information and loading to the input context
5 !!
6 !<
8 
9  use kindmodule, only: dp, i4b, lgp
10  use simvariablesmodule, only: errmsg
14  use simvariablesmodule, only: iout
17 
18  implicit none
19  private
20  public :: modelpackageinputstype
21 
22  !> @brief derived type for loadable package type
23  !!
24  !! This derived type is used to store package instance
25  !! descriptions for a supported package type.
26  !!
27  !<
29  ! -- package type, e.g. 'DIS6' or 'CHD6'
30  character(len=LENPACKAGETYPE) :: pkgtype
31  ! -- component type, e.g. 'DIS' or 'CHD'
32  character(len=LENCOMPONENTNAME) :: subcomponent_type
33  ! -- package instance attribute arrays
34  character(len=LINELENGTH), dimension(:), allocatable :: filenames
35  character(len=LENPACKAGENAME), dimension(:), allocatable :: pkgnames
36  character(len=LENMEMPATH), dimension(:), allocatable :: mempaths
37  integer(I4B), dimension(:), allocatable :: inunits
38  ! -- number of package instances
39  integer(I4B) :: pnum
40  contains
41  procedure :: create => pkgtype_create
42  procedure :: add => pkgtype_add
43  procedure :: destroy => pkgtype_destroy
44  end type loadablepackagetype
45 
46  !> @brief derived type for model package inputs type
47  !!
48  !! This derived type is used to define input package
49  !! descriptors for a model and load to managed memory.
50  !!
51  !<
53  ! -- model attributes
54  character(len=LENPACKAGETYPE) :: modeltype ! -- model type, e.g. 'GWF6'
55  character(len=LINELENGTH) :: modelfname
56  character(len=LENMODELNAME) :: modelname
57  ! -- component type
58  character(len=LENCOMPONENTNAME) :: component_type ! -- e.g. 'GWF'
59  ! -- mempaths
60  character(len=LENMEMPATH) :: input_mempath
61  character(len=LENMEMPATH) :: model_mempath
62  ! -- pointers to created managed memory
63  type(characterstringtype), dimension(:), contiguous, &
64  pointer :: pkgtypes => null()
65  type(characterstringtype), dimension(:), contiguous, &
66  pointer :: pkgnames => null()
67  type(characterstringtype), dimension(:), contiguous, &
68  pointer :: mempaths => null()
69  integer(I4B), dimension(:), contiguous, &
70  pointer :: inunits => null()
71  ! -- loadable package type array
72  type(loadablepackagetype), dimension(:), allocatable :: pkglist
73  ! -- pkgtype definitions
74  integer(I4B) :: niunit
75  character(len=LENPACKAGETYPE), dimension(:), allocatable :: cunit
76  ! -- out handle
77  integer(I4B) :: iout
78  contains
79  procedure :: init => modelpkgs_init
80  procedure :: memload => modelpkgs_memload
81  procedure :: destroy => modelpkgs_destroy
82  procedure, private :: create => modelpkgs_create
83  procedure, private :: addpkgs => modelpkgs_addpkgs
84  procedure, private :: add => modelpkgs_add
85  procedure, private :: pkgcount => modelpkgs_pkgcount
86  end type modelpackageinputstype
87 
88 contains
89 
90  !> @brief does model support multiple instances of this package type
91  !<
92  function multi_pkg_type(mtype_component, ptype_component, pkgtype) &
93  result(multi_pkg)
94  ! -- modules
97  ! -- dummy
98  character(len=LENCOMPONENTNAME), intent(in) :: mtype_component
99  character(len=LENCOMPONENTNAME), intent(in) :: ptype_component
100  character(len=LENFTYPE), intent(in) :: pkgtype
101  ! -- return
102  logical(LGP) :: multi_pkg
103  ! -- local
104  !
105  multi_pkg = .false.
106  !
107  if (idm_integrated(mtype_component, ptype_component)) then
108  multi_pkg = idm_multi_package(mtype_component, ptype_component)
109  !
110  else
111  multi_pkg = multi_package_type(mtype_component, ptype_component, pkgtype)
112  !
113  end if
114  !
115  ! -- return
116  return
117  end function multi_pkg_type
118 
119  !> @brief create a new package type
120  !<
121  subroutine pkgtype_create(this, modeltype, modelname, pkgtype)
122  ! -- modules
124  ! -- dummy
125  class(loadablepackagetype) :: this
126  character(len=*), intent(in) :: modeltype
127  character(len=*), intent(in) :: modelname
128  character(len=*), intent(in) :: pkgtype
129  ! -- local
130  !
131  ! -- initialize
132  this%pkgtype = pkgtype
133  this%subcomponent_type = idm_subcomponent_type(modeltype, pkgtype)
134  this%pnum = 0
135  !
136  ! -- allocate arrays
137  allocate (this%filenames(0))
138  allocate (this%pkgnames(0))
139  allocate (this%mempaths(0))
140  allocate (this%inunits(0))
141  !
142  ! -- return
143  return
144  end subroutine pkgtype_create
145 
146  !> @brief add a new package instance to this package type
147  !<
148  subroutine pkgtype_add(this, modelname, mtype_component, filetype, &
149  filename, pkgname, iout)
150  ! -- modules
157  ! -- dummy
158  class(loadablepackagetype) :: this
159  character(len=*), intent(in) :: modelname
160  character(len=*), intent(in) :: mtype_component
161  character(len=*), intent(in) :: filetype
162  character(len=*), intent(in) :: filename
163  character(len=*), intent(in) :: pkgname
164  integer(I4B), intent(in) :: iout
165  ! -- local
166  character(len=LENPACKAGENAME) :: sc_name, pname
167  character(len=LENMEMPATH) :: mempath
168  character(len=LINELENGTH), pointer :: cstr
169  !
170  ! -- reallocate
171  call expandarray(this%filenames)
172  call expandarray(this%pkgnames)
173  call expandarray(this%inunits)
174  call expandarray(this%mempaths)
175  !
176  ! -- add new package instance
177  this%pnum = this%pnum + 1
178  this%filenames(this%pnum) = filename
179  this%pkgnames(this%pnum) = pkgname
180  this%inunits(this%pnum) = 0
181  !
182  ! -- set pkgname if empty
183  if (this%pkgnames(this%pnum) == '') then
184  write (pname, '(a,i0)') trim(this%subcomponent_type)//'-', this%pnum
185  this%pkgnames(this%pnum) = pname
186  end if
187  !
188  ! -- set up input context for model
189  if (idm_integrated(mtype_component, this%subcomponent_type)) then
190  !
191  ! -- set subcomponent name
192  sc_name = idm_subcomponent_name(mtype_component, this%subcomponent_type, &
193  this%pkgnames(this%pnum))
194  !
195  ! -- create and store the mempath
196  this%mempaths(this%pnum) = &
197  create_mem_path(modelname, sc_name, idm_context)
198  !
199  ! -- allocate and initialize filename for package
200  mempath = create_mem_path(modelname, sc_name, idm_context)
201  call mem_allocate(cstr, linelength, 'INPUT_FNAME', mempath)
202  cstr = filename
203  !
204  else
205  !
206  ! -- set mempath empty
207  this%mempaths(this%pnum) = ''
208  end if
209  !
210  ! -- return
211  return
212  end subroutine pkgtype_add
213 
214  !> @brief deallocate object
215  !<
216  subroutine pkgtype_destroy(this)
217  ! -- modules
218  ! -- dummy
219  class(loadablepackagetype) :: this
220  ! -- local
221  !
222  ! -- deallocate dynamic arrays
223  deallocate (this%filenames)
224  deallocate (this%pkgnames)
225  deallocate (this%inunits)
226  deallocate (this%mempaths)
227  !
228  ! -- return
229  return
230  end subroutine pkgtype_destroy
231 
232  !> @brief initialize model package inputs object
233  !<
234  subroutine modelpkgs_init(this, modeltype, modelfname, modelname, iout)
235  ! -- modules
241  ! -- dummy
242  class(modelpackageinputstype) :: this
243  character(len=*), intent(in) :: modeltype
244  character(len=*), intent(in) :: modelfname
245  character(len=*), intent(in) :: modelname
246  integer(I4B), intent(in) :: iout
247  ! -- local
248  !
249  ! -- initialize object
250  this%modeltype = modeltype
251  this%modelfname = modelfname
252  this%modelname = modelname
253  this%component_type = idm_component_type(modeltype)
254  this%iout = iout
255  !
256  ! -- allocate and set model supported package types
257  call supported_model_packages(modeltype, this%cunit, this%niunit)
258  !
259  ! -- set memory paths
260  this%input_mempath = create_mem_path(this%modelname, 'NAM', idm_context)
261  this%model_mempath = create_mem_path(component=this%modelname, &
262  context=idm_context)
263  !
264  ! -- allocate managed memory
265  call mem_allocate(this%pkgtypes, lenpackagetype, 0, 'PKGTYPES', &
266  this%model_mempath)
267  call mem_allocate(this%pkgnames, lenpackagename, 0, 'PKGNAMES', &
268  this%model_mempath)
269  call mem_allocate(this%mempaths, lenmempath, 0, 'MEMPATHS', &
270  this%model_mempath)
271  call mem_allocate(this%inunits, 0, 'INUNITS', this%model_mempath)
272  !
273  ! build descriptions of packages
274  call this%addpkgs()
275  !
276  ! -- return
277  return
278  end subroutine modelpkgs_init
279 
280  !> @brief create the package type list
281  !<
282  subroutine modelpkgs_create(this, ftypes)
283  ! -- modules
284  use sortmodule, only: qsort
285  ! -- dummy
286  class(modelpackageinputstype) :: this
287  type(characterstringtype), dimension(:), contiguous, &
288  pointer :: ftypes
289  ! -- local
290  integer(I4B), dimension(:), allocatable :: cunit_idxs, indx
291  character(len=LENPACKAGETYPE) :: ftype
292  integer(I4B) :: n, m
293  logical(LGP) :: found
294  !
295  ! -- allocate
296  allocate (cunit_idxs(0))
297  !
298  ! -- identify input packages and check that each is supported
299  do n = 1, size(ftypes)
300  !
301  ! -- type from model nam file packages block
302  ftype = ftypes(n)
303  found = .false.
304  !
305  ! -- search supported types for this filetype
306  do m = 1, this%niunit
307  if (this%cunit(m) == ftype) then
308  ! -- set found
309  found = .true.
310  !
311  ! -- add to cunit list if first instance of this type
312  if (any(cunit_idxs == m)) then
313  ! no-op
314  else
315  call expandarray(cunit_idxs)
316  cunit_idxs(size(cunit_idxs)) = m
317  end if
318  !
319  ! -- exit search
320  exit
321  end if
322  end do
323  !
324  ! -- set error if namfile pkg filetype is not supported
325  if (.not. found) then
326  write (errmsg, '(a,a,a,a,a)') 'Model package type not supported &
327  &[model=', trim(this%modelname), ', type=', &
328  trim(ftype), '].'
329  call store_error(errmsg)
330  call store_error_filename(this%modelfname)
331  end if
332  end do
333  !
334  ! -- allocate the pkglist
335  allocate (this%pkglist(size(cunit_idxs)))
336  !
337  ! -- sort cunit indexes
338  allocate (indx(size(cunit_idxs)))
339  call qsort(indx, cunit_idxs)
340  !
341  ! -- create sorted LoadablePackageType object list
342  do n = 1, size(cunit_idxs)
343  call this%pkglist(n)%create(this%modeltype, this%modelname, &
344  this%cunit(cunit_idxs(n)))
345  end do
346  !
347  ! -- cleanup
348  deallocate (cunit_idxs)
349  deallocate (indx)
350  !
351  ! -- return
352  return
353  end subroutine modelpkgs_create
354 
355  !> @brief add a model package instance to package type list
356  !<
357  subroutine modelpkgs_add(this, pkgtype, filename, pkgname)
358  ! -- modules
359  ! -- dummy
360  class(modelpackageinputstype) :: this
361  character(len=*), intent(in) :: pkgtype
362  character(len=*), intent(in) :: filename
363  character(len=*), intent(in) :: pkgname
364  ! -- local
365  type(loadablepackagetype) :: pkg
366  integer(I4B) :: n
367  !
368  ! -- locate index of pkgtype in pkglist
369  do n = 1, size(this%pkglist)
370  pkg = this%pkglist(n)
371  if (pkg%pkgtype == pkgtype) then
372  call this%pkglist(n)%add(this%modelname, this%component_type, &
373  pkgtype, filename, pkgname, this%iout)
374  exit
375  end if
376  end do
377  !
378  ! -- return
379  return
380  end subroutine modelpkgs_add
381 
382  !> @brief build the type list with all model package instances
383  !<
384  subroutine modelpkgs_addpkgs(this)
385  ! -- modules
387  ! -- dummy
388  class(modelpackageinputstype) :: this
389  ! -- local
390  type(characterstringtype), dimension(:), contiguous, &
391  pointer :: ftypes !< file types
392  type(characterstringtype), dimension(:), contiguous, &
393  pointer :: fnames !< file names
394  type(characterstringtype), dimension(:), contiguous, &
395  pointer :: pnames !< package names
396  character(len=LINELENGTH) :: ftype, fname, pname
397  integer(I4B) :: n
398  !
399  ! -- set pointers to input context model package attribute arrays
400  call mem_setptr(ftypes, 'FTYPE', this%input_mempath)
401  call mem_setptr(fnames, 'FNAME', this%input_mempath)
402  call mem_setptr(pnames, 'PNAME', this%input_mempath)
403  !
404  ! -- create the package list
405  call this%create(ftypes)
406  !
407  ! -- load model packages
408  do n = 1, size(ftypes)
409  !
410  ! -- attributes for this package
411  ftype = ftypes(n)
412  fname = fnames(n)
413  pname = pnames(n)
414  !
415  ! -- add this instance to package list
416  call this%add(ftype, fname, pname)
417  end do
418  !
419  ! --
420  return
421  end subroutine modelpkgs_addpkgs
422 
423  !> @brief get package instance count and verify base or multi of each
424  !<
425  function modelpkgs_pkgcount(this) result(pnum)
426  ! -- modules
427  ! -- dummy
428  class(modelpackageinputstype) :: this
429  !
430  ! -- return
431  integer(I4B) :: pnum
432  ! -- local
433  integer(I4B) :: n
434  !
435  ! -- initialize
436  pnum = 0
437  !
438  ! -- count model package instances
439  do n = 1, size(this%pkglist)
440  !
441  if (multi_pkg_type(this%component_type, &
442  this%pkglist(n)%subcomponent_type, &
443  this%pkglist(n)%pkgtype)) then
444  ! multiple instances ok
445  else
446  ! -- set error for unexpected extra packages
447  if (this%pkglist(n)%pnum > 1) then
448  write (errmsg, '(a,a,a,a,a)') &
449  'Multiple instances specified for model base package type &
450  &[model=', trim(this%modelname), ', type=', &
451  trim(this%pkglist(n)%pkgtype), '].'
452  call store_error(errmsg)
453  call store_error_filename(this%modelfname)
454  end if
455  end if
456  !
457  ! -- add to package count
458  pnum = pnum + this%pkglist(n)%pnum
459  end do
460  !
461  ! -- return
462  return
463  end function modelpkgs_pkgcount
464 
465  !> @brief load package descriptors to managed memory
466  !<
467  subroutine modelpkgs_memload(this)
468  ! -- modules
470  ! -- dummy
471  class(modelpackageinputstype) :: this
472  ! -- local
473  integer(I4B) :: n, m, idx
474  integer(I4B) :: pnum
475  !
476  ! -- initialize load index
477  idx = 0
478  !
479  ! -- set total number of package instances
480  pnum = this%pkgcount()
481  !
482  ! -- reallocate model input package attribute arrays
483  call mem_reallocate(this%pkgtypes, lenpackagetype, pnum, 'PKGTYPES', &
484  this%model_mempath)
485  call mem_reallocate(this%pkgnames, lenpackagename, pnum, 'PKGNAMES', &
486  this%model_mempath)
487  call mem_reallocate(this%mempaths, lenmempath, pnum, 'MEMPATHS', &
488  this%model_mempath)
489  call mem_reallocate(this%inunits, pnum, 'INUNITS', this%model_mempath)
490  !
491  ! -- load pkinfo
492  do n = 1, size(this%pkglist)
493  !
494  do m = 1, this%pkglist(n)%pnum
495  ! -- increment index
496  idx = idx + 1
497  ! -- package type like 'CHD6'
498  this%pkgtypes(idx) = trim(this%pkglist(n)%pkgtype)
499  ! -- package name like 'CHD-2'
500  this%pkgnames(idx) = trim(this%pkglist(n)%pkgnames(m))
501  ! -- memory path like '__INPUT__/MYMODEL/CHD-2'
502  this%mempaths(idx) = trim(this%pkglist(n)%mempaths(m))
503  ! -- input file unit number
504  this%inunits(idx) = this%pkglist(n)%inunits(m)
505  end do
506  end do
507  !
508  ! -- return
509  return
510  end subroutine modelpkgs_memload
511 
512  !> @brief deallocate object
513  !<
514  subroutine modelpkgs_destroy(this)
515  ! -- modules
516  ! -- dummy
517  class(modelpackageinputstype) :: this
518  ! -- local
519  integer(I4B) :: n
520  !
521  ! --
522  do n = 1, size(this%pkglist)
523  call this%pkglist(n)%destroy()
524  end do
525  !
526  deallocate (this%pkglist)
527  deallocate (this%cunit)
528  !
529  ! -- return
530  return
531  end subroutine modelpkgs_destroy
532 
533 end module modelpackageinputsmodule
subroutine init()
Definition: GridSorting.f90:24
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 lencomponentname
maximum length of a component name
Definition: Constants.f90:18
integer(i4b), parameter lenmodelname
maximum length of the model name
Definition: Constants.f90:21
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:22
integer(i4b), parameter lenpackagetype
maximum length of a package type (DIS6, SFR6, CSUB6, etc.)
Definition: Constants.f90:37
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
Definition: Constants.f90:38
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:26
logical function, public idm_integrated(component, subcomponent)
logical function, public idm_multi_package(component, subcomponent)
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 the ModelPackageInputModule.
logical(lgp) function, public multi_package_type(mtype_component, ptype_component, pkgtype)
Is the package multi-instance.
subroutine, public supported_model_packages(mtype, pkgtypes, numpkgs)
set supported package types for model
This module contains the ModelPackageInputsModule.
subroutine modelpkgs_add(this, pkgtype, filename, pkgname)
add a model package instance to package type list
subroutine modelpkgs_init(this, modeltype, modelfname, modelname, iout)
initialize model package inputs object
subroutine pkgtype_destroy(this)
deallocate object
subroutine pkgtype_create(this, modeltype, modelname, pkgtype)
create a new package type
logical(lgp) function multi_pkg_type(mtype_component, ptype_component, pkgtype)
does model support multiple instances of this package type
subroutine modelpkgs_destroy(this)
deallocate object
subroutine modelpkgs_addpkgs(this)
build the type list with all model package instances
subroutine modelpkgs_memload(this)
load package descriptors to managed memory
subroutine modelpkgs_create(this, ftypes)
create the package type list
subroutine pkgtype_add(this, modelname, mtype_component, filetype, filename, pkgname, iout)
add a new package instance to this package type
integer(i4b) function modelpkgs_pkgcount(this)
get package instance count and verify base or multi of each
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 store_error_filename(filename, terminate)
Store the erroring file name.
Definition: Sim.f90:203
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
character(len=linelength) idm_context
integer(i4b) iout
file unit number for simulation output
This module contains the SourceCommonModule.
Definition: SourceCommon.f90:7
character(len=lencomponentname) function, public idm_subcomponent_type(component, subcomponent)
component from package or model type
character(len=lencomponentname) function, public idm_component_type(component)
component from package or model type
character(len=lenpackagename) function, public idm_subcomponent_name(component_type, subcomponent_type, sc_name)
model package subcomponent name
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
derived type for loadable package type
derived type for model package inputs type