MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
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)
96  character(len=LENCOMPONENTNAME), intent(in) :: mtype_component
97  character(len=LENCOMPONENTNAME), intent(in) :: ptype_component
98  character(len=LENFTYPE), intent(in) :: pkgtype
99  logical(LGP) :: multi_pkg
100  multi_pkg = .false.
101  if (idm_integrated(mtype_component, ptype_component)) then
102  multi_pkg = idm_multi_package(mtype_component, ptype_component)
103  else
104  multi_pkg = multi_package_type(mtype_component, ptype_component, pkgtype)
105  end if
106  end function multi_pkg_type
107 
108  !> @brief create a new package type
109  !<
110  subroutine pkgtype_create(this, modeltype, modelname, pkgtype)
112  class(loadablepackagetype) :: this
113  character(len=*), intent(in) :: modeltype
114  character(len=*), intent(in) :: modelname
115  character(len=*), intent(in) :: pkgtype
116 
117  ! initialize
118  this%pkgtype = pkgtype
119  this%subcomponent_type = idm_subcomponent_type(modeltype, pkgtype)
120  this%pnum = 0
121 
122  ! allocate arrays
123  allocate (this%filenames(0))
124  allocate (this%pkgnames(0))
125  allocate (this%mempaths(0))
126  allocate (this%inunits(0))
127  end subroutine pkgtype_create
128 
129  !> @brief add a new package instance to this package type
130  !<
131  subroutine pkgtype_add(this, modelname, mtype_component, filetype, &
132  filename, pkgname, iout)
139  class(loadablepackagetype) :: this
140  character(len=*), intent(in) :: modelname
141  character(len=*), intent(in) :: mtype_component
142  character(len=*), intent(in) :: filetype
143  character(len=*), intent(in) :: filename
144  character(len=*), intent(in) :: pkgname
145  integer(I4B), intent(in) :: iout
146  character(len=LENPACKAGENAME) :: sc_name, pname
147  character(len=LENMEMPATH) :: mempath
148  character(len=LINELENGTH), pointer :: cstr
149 
150  ! reallocate
151  call expandarray(this%filenames)
152  call expandarray(this%pkgnames)
153  call expandarray(this%inunits)
154  call expandarray(this%mempaths)
155 
156  ! add new package instance
157  this%pnum = this%pnum + 1
158  this%filenames(this%pnum) = filename
159  this%pkgnames(this%pnum) = pkgname
160  this%inunits(this%pnum) = 0
161 
162  ! set pkgname if empty
163  if (this%pkgnames(this%pnum) == '') then
164  if (multi_pkg_type(mtype_component, &
165  this%subcomponent_type, &
166  filetype)) then
167  write (pname, '(a,i0)') trim(this%subcomponent_type)//'-', this%pnum
168  else
169  write (pname, '(a,i0)') trim(this%subcomponent_type)
170  end if
171  this%pkgnames(this%pnum) = pname
172  end if
173 
174  ! set up input context for model
175  if (idm_integrated(mtype_component, this%subcomponent_type)) then
176  ! set subcomponent name
177  sc_name = idm_subcomponent_name(mtype_component, this%subcomponent_type, &
178  this%pkgnames(this%pnum))
179  ! create and store the mempath
180  this%mempaths(this%pnum) = &
181  create_mem_path(modelname, sc_name, idm_context)
182  ! allocate and initialize filename for package
183  mempath = create_mem_path(modelname, sc_name, idm_context)
184  call mem_allocate(cstr, linelength, 'INPUT_FNAME', mempath)
185  cstr = filename
186  else
187  ! set mempath empty
188  this%mempaths(this%pnum) = ''
189  end if
190  end subroutine pkgtype_add
191 
192  !> @brief deallocate object
193  !<
194  subroutine pkgtype_destroy(this)
195  class(loadablepackagetype) :: this
196  ! deallocate dynamic arrays
197  deallocate (this%filenames)
198  deallocate (this%pkgnames)
199  deallocate (this%inunits)
200  deallocate (this%mempaths)
201  end subroutine pkgtype_destroy
202 
203  !> @brief initialize model package inputs object
204  !<
205  subroutine modelpkgs_init(this, modeltype, modelfname, modelname, iout)
211  class(modelpackageinputstype) :: this
212  character(len=*), intent(in) :: modeltype
213  character(len=*), intent(in) :: modelfname
214  character(len=*), intent(in) :: modelname
215  integer(I4B), intent(in) :: iout
216 
217  ! initialize object
218  this%modeltype = modeltype
219  this%modelfname = modelfname
220  this%modelname = modelname
221  this%component_type = idm_component_type(modeltype)
222  this%iout = iout
223 
224  ! allocate and set model supported package types
225  call supported_model_packages(modeltype, this%cunit, this%niunit)
226 
227  ! set memory paths
228  this%input_mempath = create_mem_path(this%modelname, 'NAM', idm_context)
229  this%model_mempath = create_mem_path(component=this%modelname, &
230  context=idm_context)
231  ! allocate managed memory
232  call mem_allocate(this%pkgtypes, lenpackagetype, 0, 'PKGTYPES', &
233  this%model_mempath)
234  call mem_allocate(this%pkgnames, lenpackagename, 0, 'PKGNAMES', &
235  this%model_mempath)
236  call mem_allocate(this%mempaths, lenmempath, 0, 'MEMPATHS', &
237  this%model_mempath)
238  call mem_allocate(this%inunits, 0, 'INUNITS', this%model_mempath)
239 
240  ! build descriptions of packages
241  call this%addpkgs()
242  end subroutine modelpkgs_init
243 
244  !> @brief create the package type list
245  !<
246  subroutine modelpkgs_create(this, ftypes)
247  use sortmodule, only: qsort
248  class(modelpackageinputstype) :: this
249  type(characterstringtype), dimension(:), contiguous, &
250  pointer :: ftypes
251  integer(I4B), dimension(:), allocatable :: cunit_idxs, indx
252  character(len=LENPACKAGETYPE) :: ftype
253  integer(I4B) :: n, m
254  logical(LGP) :: found
255 
256  ! allocate
257  allocate (cunit_idxs(0))
258 
259  ! identify input packages and check that each is supported
260  do n = 1, size(ftypes)
261  ! type from model nam file packages block
262  ftype = ftypes(n)
263  found = .false.
264 
265  ! search supported types for this filetype
266  do m = 1, this%niunit
267  if (this%cunit(m) == ftype) then
268  ! set found
269  found = .true.
270 
271  ! add to cunit list if first instance of this type
272  if (any(cunit_idxs == m)) then
273  ! no-op
274  else
275  call expandarray(cunit_idxs)
276  cunit_idxs(size(cunit_idxs)) = m
277  end if
278 
279  ! exit search
280  exit
281  end if
282  end do
283 
284  ! set error if namfile pkg filetype is not supported
285  if (.not. found) then
286  write (errmsg, '(a,a,a,a,a)') 'Model package type not supported &
287  &[model=', trim(this%modelname), ', type=', &
288  trim(ftype), '].'
289  call store_error(errmsg)
290  call store_error_filename(this%modelfname)
291  end if
292  end do
293 
294  ! allocate the pkglist
295  allocate (this%pkglist(size(cunit_idxs)))
296 
297  ! sort cunit indexes
298  allocate (indx(size(cunit_idxs)))
299  call qsort(indx, cunit_idxs)
300 
301  ! create sorted LoadablePackageType object list
302  do n = 1, size(cunit_idxs)
303  call this%pkglist(n)%create(this%modeltype, this%modelname, &
304  this%cunit(cunit_idxs(n)))
305  end do
306 
307  ! cleanup
308  deallocate (cunit_idxs)
309  deallocate (indx)
310  end subroutine modelpkgs_create
311 
312  !> @brief add a model package instance to package type list
313  !<
314  subroutine modelpkgs_add(this, pkgtype, filename, pkgname)
315  class(modelpackageinputstype) :: this
316  character(len=*), intent(in) :: pkgtype
317  character(len=*), intent(in) :: filename
318  character(len=*), intent(in) :: pkgname
319  type(loadablepackagetype) :: pkg
320  integer(I4B) :: n
321  ! locate index of pkgtype in pkglist
322  do n = 1, size(this%pkglist)
323  pkg = this%pkglist(n)
324  if (pkg%pkgtype == pkgtype) then
325  call this%pkglist(n)%add(this%modelname, this%component_type, &
326  pkgtype, filename, pkgname, this%iout)
327  exit
328  end if
329  end do
330  end subroutine modelpkgs_add
331 
332  !> @brief build the type list with all model package instances
333  !<
334  subroutine modelpkgs_addpkgs(this)
337  class(modelpackageinputstype) :: this
338  type(characterstringtype), dimension(:), contiguous, &
339  pointer :: ftypes !< file types
340  type(characterstringtype), dimension(:), contiguous, &
341  pointer :: fnames !< file names
342  type(characterstringtype), dimension(:), contiguous, &
343  pointer :: pnames !< package names
344  character(len=LINELENGTH) :: ftype, fname, pname
345  integer(I4B) :: n
346 
347  ! set pointers to input context model package attribute arrays
348  call mem_setptr(ftypes, 'FTYPE', this%input_mempath)
349  call mem_setptr(fnames, 'FNAME', this%input_mempath)
350  call mem_setptr(pnames, 'PNAME', this%input_mempath)
351 
352  ! create the package list
353  call this%create(ftypes)
354 
355  ! load model packages
356  do n = 1, size(ftypes)
357  ! attributes for this package
358  ftype = ftypes(n)
359  fname = fnames(n)
360  call inlen_check(pnames(n), pname, lenpackagename, 'PACKAGENAME')
361 
362  ! add this instance to package list
363  call this%add(ftype, fname, pname)
364  end do
365 
366  ! terminate if errors were detected
367  if (count_errors() > 0) then
368  call store_error_filename(this%modelfname)
369  end if
370  end subroutine modelpkgs_addpkgs
371 
372  !> @brief get package instance count and verify base or multi of each
373  !<
374  function modelpkgs_pkgcount(this) result(pnum)
375  class(modelpackageinputstype) :: this
376  integer(I4B) :: pnum
377  integer(I4B) :: n
378 
379  ! initialize
380  pnum = 0
381 
382  ! count model package instances
383  do n = 1, size(this%pkglist)
384  if (multi_pkg_type(this%component_type, &
385  this%pkglist(n)%subcomponent_type, &
386  this%pkglist(n)%pkgtype)) then
387  ! multiple instances ok
388  else
389  ! set error for unexpected extra packages
390  if (this%pkglist(n)%pnum > 1) then
391  write (errmsg, '(a,a,a,a,a)') &
392  'Multiple instances specified for model base package type &
393  &[model=', trim(this%modelname), ', type=', &
394  trim(this%pkglist(n)%pkgtype), '].'
395  call store_error(errmsg)
396  call store_error_filename(this%modelfname)
397  end if
398  end if
399 
400  ! add to package count
401  pnum = pnum + this%pkglist(n)%pnum
402  end do
403  end function modelpkgs_pkgcount
404 
405  !> @brief load package descriptors to managed memory
406  !<
407  subroutine modelpkgs_memload(this)
409  class(modelpackageinputstype) :: this
410  integer(I4B) :: n, m, idx
411  integer(I4B) :: pnum
412 
413  ! initialize load index
414  idx = 0
415 
416  ! set total number of package instances
417  pnum = this%pkgcount()
418 
419  ! reallocate model input package attribute arrays
420  call mem_reallocate(this%pkgtypes, lenpackagetype, pnum, 'PKGTYPES', &
421  this%model_mempath)
422  call mem_reallocate(this%pkgnames, lenpackagename, pnum, 'PKGNAMES', &
423  this%model_mempath)
424  call mem_reallocate(this%mempaths, lenmempath, pnum, 'MEMPATHS', &
425  this%model_mempath)
426  call mem_reallocate(this%inunits, pnum, 'INUNITS', this%model_mempath)
427 
428  ! load pkinfo
429  do n = 1, size(this%pkglist)
430  do m = 1, this%pkglist(n)%pnum
431  ! increment index
432  idx = idx + 1
433  ! package type like 'CHD6'
434  this%pkgtypes(idx) = trim(this%pkglist(n)%pkgtype)
435  ! package name like 'CHD-2'
436  this%pkgnames(idx) = trim(this%pkglist(n)%pkgnames(m))
437  ! memory path like '__INPUT__/MYMODEL/CHD-2'
438  this%mempaths(idx) = trim(this%pkglist(n)%mempaths(m))
439  ! input file unit number
440  this%inunits(idx) = this%pkglist(n)%inunits(m)
441  end do
442  end do
443  end subroutine modelpkgs_memload
444 
445  !> @brief deallocate object
446  !<
447  subroutine modelpkgs_destroy(this)
448  class(modelpackageinputstype) :: this
449  integer(I4B) :: n
450  do n = 1, size(this%pkglist)
451  call this%pkglist(n)%destroy()
452  end do
453  deallocate (this%pkglist)
454  deallocate (this%cunit)
455  end subroutine modelpkgs_destroy
456 
457 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:45
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:22
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:23
integer(i4b), parameter lenpackagetype
maximum length of a package type (DIS6, SFR6, CSUB6, etc.)
Definition: Constants.f90:38
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
Definition: Constants.f90:39
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
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
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
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
subroutine, public inlen_check(input_name, mf6_name, maxlen, name_type)
store an error for input exceeding internal name length
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