MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
loadcontextmodule Module Reference

This module contains the LoadContextModule. More...

Data Types

type  readstatevartype
 Pointer type for read state variable. More...
 
interface  setptr
 
type  loadcontexttype
 derived type for boundary package input context More...
 

Enumerations

enum  {
  load_undef = 0 , list = 1 , layerarray = 2 , gridarray = 3 ,
  keystring = 4 , advanced = 5
}
 
enum  {
  context_undef = 0 , root = 1 , sim = 2 , model = 3 ,
  modelpkg = 4 , stresspkg = 5 , exchange = 6
}
 

Functions/Subroutines

subroutine init (this, mf6_input, blockname, named_bound)
 init loader context object More...
 
subroutine allocate_scalars (this)
 allocate scalars More...
 
subroutine allocate_arrays (this)
 allocate arrays More...
 
subroutine allocate_param (this, idt)
 allocate a package dynamic input parameter More...
 
subroutine tags (this, params, nparam, input_name, create)
 get in scope package params More...
 
logical(lgp) function in_scope (this, mf6_input, blockname, tagname)
 establish if input parameter is in scope for package load More...
 
subroutine set_params (this)
 set set of in scope parameters for package More...
 
character(len=lenvarname) function rsv_alloc (this, mf6varname)
 allocate a read state variable More...
 
subroutine destroy (this)
 destroy input context object More...
 
type(inputparamdefinitiontype) function, pointer find_setting_aggregate (mf6_input, rec_cols, nrec_col)
 Return the KEYSTRING aggregate for the SETTING token in rec_cols, or null(). More...
 
subroutine expand_record_submembers (mf6_input, rec_idt, member_names, nmembers)
 Append sub-member column names from a RECORD compound entry to member_names. More...
 
logical(lgp) function, public is_keystring_period (mf6_input)
 Return .true. if mf6_input's PERIOD block uses keystring dispatch. More...
 
subroutine keystring_member_names (this, member_names, nmembers)
 Return keystring member column names for the PERIOD block. More...
 
character(len=lenvarname) function, public rsv_name (mf6varname)
 create read state variable name More...
 
subroutine allocate_charstr1d (strlen, nrow, varname, mempath)
 allocate character string type array More...
 
subroutine allocate_int1d (nrow, varname, mempath)
 allocate int1d More...
 
subroutine allocate_int2d (ncol, nrow, varname, mempath)
 allocate int2d More...
 
subroutine allocate_dbl1d (nrow, varname, mempath)
 allocate dbl1d More...
 
subroutine allocate_dbl2d (ncol, nrow, varname, mempath)
 allocate dbl2d More...
 
subroutine sum_named_bounds (named_bound, mempath, total)
 sum named dimension variables from mempath More...
 
subroutine setval (intptr, varname, mempath)
 allocate intptr and update from input contextset intptr to varname More...
 
subroutine setptr_int (intptr, varname, mempath)
 set intptr to varname More...
 
subroutine setptr_charstr1d (charstr1d, varname, mempath, strlen)
 set charstr1d pointer to varname More...
 
subroutine setptr_auxvar (auxvar, mempath)
 set auxvar pointer More...
 

Detailed Description

This module creates a load context for IDM generic loaders (ListLoadType, LayerArrayLoadType, GridArrayLoadType) that supports consistent package side access. It also determines in scope parameters for the generic dynamic loaders and all structarray based static loads.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
private
Enumerator
load_undef 

undefined load type

list 

list (structarray) based load

layerarray 

readasarrays load

gridarray 

readarraygrid load

keystring 

basic keystring period block load

advanced 

advanced keystring period block load

Definition at line 28 of file LoadContext.f90.

◆ anonymous enum

anonymous enum
private
Enumerator
context_undef 

undefined context type

root 

root context type

sim 

sim context type

model 

model context type

modelpkg 

model package context type

stresspkg 

model stress package context type

exchange 

exchange context type

Definition at line 38 of file LoadContext.f90.

Function/Subroutine Documentation

◆ allocate_arrays()

subroutine loadcontextmodule::allocate_arrays ( class(loadcontexttype this)

call this routine after input parameters have been allocated, e.g. after load_params() with create has been called for array based loaders or after all mem_create_vector() calls have been made for list based load.

Definition at line 305 of file LoadContext.f90.

307  class(LoadContextType) :: this
308  integer(I4B), dimension(:, :), pointer, contiguous :: cellid
309  integer(I4B), dimension(:), pointer, contiguous :: nodeulist
310 
311  if (this%ctxtype == stresspkg .and. &
312  this%blockname == 'PERIOD') then
313  ! allocate cellid if this is not list input
314  if (this%readarray) then
315  call mem_allocate(cellid, 0, 0, 'CELLID', this%mf6_input%mempath)
316  end if
317 
318  ! allocate nodeulist for list and layerarray packages only;
319  ! keystring and advanced packages do not use a flat nodeulist
320  if (this%loadtype /= gridarray .and. &
321  this%loadtype /= keystring .and. &
322  this%loadtype /= advanced) then
323  call mem_allocate(nodeulist, 0, 'NODEULIST', this%mf6_input%mempath)
324  end if
325 
326  ! set pointers to aux/bound arrays for list and layerarray packages only;
327  ! keystring and advanced packages manage aux through struct array columns
328  if (this%loadtype /= keystring .and. &
329  this%loadtype /= advanced) then
330  call setptr(this%auxname_cst, 'AUXILIARY', &
331  this%mf6_input%mempath, lenauxname)
332  call setptr(this%boundname_cst, 'BOUNDNAME', &
333  this%mf6_input%mempath, lenboundname)
334  call setptr(this%auxvar, this%mf6_input%mempath)
335  end if
336 
337  else if (this%ctxtype == exchange) then
338  ! set pointers to arrays
339  call setptr(this%auxname_cst, 'AUXILIARY', &
340  this%mf6_input%mempath, lenauxname)
341  call setptr(this%boundname_cst, 'BOUNDNAME', &
342  this%mf6_input%mempath, lenboundname)
343  call setptr(this%auxvar, this%mf6_input%mempath)
344  end if
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
Here is the call graph for this function:

◆ allocate_charstr1d()

subroutine loadcontextmodule::allocate_charstr1d ( integer(i4b), intent(in)  strlen,
integer(i4b), intent(in)  nrow,
character(len=*), intent(in)  varname,
character(len=*), intent(in)  mempath 
)
Parameters
[in]strlenstring number of characters
[in]nrowinteger array number of rows
[in]varnamevariable name
[in]mempathvariable mempath

Definition at line 865 of file LoadContext.f90.

867  integer(I4B), intent(in) :: strlen !< string number of characters
868  integer(I4B), intent(in) :: nrow !< integer array number of rows
869  character(len=*), intent(in) :: varname !< variable name
870  character(len=*), intent(in) :: mempath !< variable mempath
871  type(CharacterStringType), dimension(:), pointer, &
872  contiguous :: charstr1d
873  integer(I4B) :: n
874  call mem_allocate(charstr1d, strlen, nrow, varname, mempath)
875  do n = 1, nrow
876  charstr1d(n) = ''
877  end do
Here is the caller graph for this function:

◆ allocate_dbl1d()

subroutine loadcontextmodule::allocate_dbl1d ( integer(i4b), intent(in)  nrow,
character(len=*), intent(in)  varname,
character(len=*), intent(in)  mempath 
)
Parameters
[in]nrowinteger array number of rows
[in]varnamevariable name
[in]mempathvariable mempath

Definition at line 915 of file LoadContext.f90.

917  integer(I4B), intent(in) :: nrow !< integer array number of rows
918  character(len=*), intent(in) :: varname !< variable name
919  character(len=*), intent(in) :: mempath !< variable mempath
920  real(DP), dimension(:), pointer, contiguous :: dbl1d
921  integer(I4B) :: n
922  call mem_allocate(dbl1d, nrow, varname, mempath)
923  do n = 1, nrow
924  dbl1d(n) = dzero
925  end do
Here is the caller graph for this function:

◆ allocate_dbl2d()

subroutine loadcontextmodule::allocate_dbl2d ( integer(i4b), intent(in)  ncol,
integer(i4b), intent(in)  nrow,
character(len=*), intent(in)  varname,
character(len=*), intent(in)  mempath 
)
Parameters
[in]ncolinteger array number of cols
[in]nrowinteger array number of rows
[in]varnamevariable name
[in]mempathvariable mempath

Definition at line 930 of file LoadContext.f90.

932  integer(I4B), intent(in) :: ncol !< integer array number of cols
933  integer(I4B), intent(in) :: nrow !< integer array number of rows
934  character(len=*), intent(in) :: varname !< variable name
935  character(len=*), intent(in) :: mempath !< variable mempath
936  real(DP), dimension(:, :), pointer, contiguous :: dbl2d
937  integer(I4B) :: n, m
938  call mem_allocate(dbl2d, ncol, nrow, varname, mempath)
939  do m = 1, nrow
940  do n = 1, ncol
941  dbl2d(n, m) = dzero
942  end do
943  end do
Here is the caller graph for this function:

◆ allocate_int1d()

subroutine loadcontextmodule::allocate_int1d ( integer(i4b), intent(in)  nrow,
character(len=*), intent(in)  varname,
character(len=*), intent(in)  mempath 
)
Parameters
[in]nrowinteger array number of rows
[in]varnamevariable name
[in]mempathvariable mempath

Definition at line 882 of file LoadContext.f90.

884  integer(I4B), intent(in) :: nrow !< integer array number of rows
885  character(len=*), intent(in) :: varname !< variable name
886  character(len=*), intent(in) :: mempath !< variable mempath
887  integer(I4B), dimension(:), pointer, contiguous :: int1d
888  integer(I4B) :: n
889  call mem_allocate(int1d, nrow, varname, mempath)
890  do n = 1, nrow
891  int1d(n) = izero
892  end do
Here is the caller graph for this function:

◆ allocate_int2d()

subroutine loadcontextmodule::allocate_int2d ( integer(i4b), intent(in)  ncol,
integer(i4b), intent(in)  nrow,
character(len=*), intent(in)  varname,
character(len=*), intent(in)  mempath 
)
Parameters
[in]ncolinteger array number of cols
[in]nrowinteger array number of rows
[in]varnamevariable name
[in]mempathvariable mempath

Definition at line 897 of file LoadContext.f90.

899  integer(I4B), intent(in) :: ncol !< integer array number of cols
900  integer(I4B), intent(in) :: nrow !< integer array number of rows
901  character(len=*), intent(in) :: varname !< variable name
902  character(len=*), intent(in) :: mempath !< variable mempath
903  integer(I4B), dimension(:, :), pointer, contiguous :: int2d
904  integer(I4B) :: n, m
905  call mem_allocate(int2d, ncol, nrow, varname, mempath)
906  do m = 1, nrow
907  do n = 1, ncol
908  int2d(n, m) = izero
909  end do
910  end do
Here is the caller graph for this function:

◆ allocate_param()

subroutine loadcontextmodule::allocate_param ( class(loadcontexttype this,
type(inputparamdefinitiontype), pointer  idt 
)

Definition at line 349 of file LoadContext.f90.

351  class(LoadContextType) :: this
352  type(InputParamDefinitionType), pointer :: idt
353  integer(I4B) :: dimsize
354 
355  ! initialize
356  dimsize = 0
357 
358  if (this%readarray) then
359  select case (idt%shape)
360  case ('NCPL', 'NAUX NCPL')
361  dimsize = this%ncpl
362  case ('NODES', 'NAUX NODES')
363  dimsize = this%maxbound
364  case default
365  end select
366  end if
367 
368  select case (idt%datatype)
369  case ('INTEGER')
370  if (this%loadtype == list) then
371  call allocate_int1d(this%maxbound, idt%mf6varname, &
372  this%mf6_input%mempath)
373  end if
374  case ('DOUBLE')
375  if (this%loadtype == list) then
376  call allocate_dbl1d(this%maxbound, idt%mf6varname, &
377  this%mf6_input%mempath)
378  end if
379  case ('STRING')
380  if (this%loadtype == list) then
381  call allocate_charstr1d(lenboundname, this%maxbound, idt%mf6varname, &
382  this%mf6_input%mempath)
383  end if
384  case ('INTEGER1D')
385  if (this%loadtype == list) then
386  if (idt%shape == 'NCELLDIM') then
387  call allocate_int2d(size(this%mshape), this%maxbound, &
388  idt%mf6varname, this%mf6_input%mempath)
389  end if
390  else if (this%readarray) then
391  call allocate_int1d(dimsize, idt%mf6varname, &
392  this%mf6_input%mempath)
393  end if
394  case ('DOUBLE1D')
395  if (idt%shape == 'NAUX') then
396  call allocate_dbl2d(this%naux, this%maxbound, &
397  idt%mf6varname, this%mf6_input%mempath)
398  else if (this%readarray) then
399  call allocate_dbl1d(dimsize, idt%mf6varname, &
400  this%mf6_input%mempath)
401  end if
402  case ('DOUBLE2D')
403  if (this%readarray) then
404  call allocate_dbl2d(this%naux, dimsize, idt%mf6varname, &
405  this%mf6_input%mempath)
406  end if
407  case default
408  end select
Input definition module.
Input parameter definition. Describes an input parameter.
Here is the call graph for this function:

◆ allocate_scalars()

subroutine loadcontextmodule::allocate_scalars ( class(loadcontexttype this)

Definition at line 219 of file LoadContext.f90.

223  class(LoadContextType) :: this
224  type(InputParamDefinitionType), pointer :: aidt, ks_aidt
225  character(len=LINELENGTH), allocatable :: cols(:), ks_cols(:)
226  integer(I4B) :: nmembers, ncol, isize
227  integer(I4B), pointer :: maxbound_ptr
228 
229  if (this%ctxtype == exchange .or. &
230  this%ctxtype == modelpkg .or. &
231  this%ctxtype == stresspkg) then
232 
233  call setptr(this%nbound, 'NBOUND', this%mf6_input%mempath)
234  call setval(this%naux, 'NAUX', this%mf6_input%mempath)
235  call setval(this%ncpl, 'NCPL', this%mf6_input%mempath)
236  call setval(this%nodes, 'NODES', this%mf6_input%mempath)
237  call setval(this%boundnames, 'BOUNDNAMES', this%mf6_input%mempath)
238  call setval(this%iprpak, 'IPRPAK', this%mf6_input%mempath)
239 
240  ! resolve maxbound: sum all named_bound variable values
241  allocate (this%maxbound)
242  this%maxbound = 0
243  call sum_named_bounds(this%named_bound, this%mf6_input%mempath, &
244  this%maxbound)
245  ! fallback: try MAXBOUND directly when named_bound tokens yield nothing
246  if (this%maxbound == 0) then
247  call get_isize('MAXBOUND', this%mf6_input%mempath, isize)
248  if (isize > -1) then
249  call mem_setptr(maxbound_ptr, 'MAXBOUND', this%mf6_input%mempath)
250  this%maxbound = maxbound_ptr
251  nullify (maxbound_ptr)
252  end if
253  end if
254 
255  ! reset nbound
256  this%nbound = 0
257  end if
258 
259  if (this%ctxtype == stresspkg .and. &
260  this%blockname == 'PERIOD') then
261  call mem_setptr(this%mshape, 'MODEL_SHAPE', &
262  this%mf6_input%component_mempath)
263 
264  if (this%ncpl == 0) then
265  if (size(this%mshape) == 2) then
266  this%ncpl = this%mshape(2)
267  else if (size(this%mshape) == 3) then
268  this%ncpl = this%mshape(2) * this%mshape(3)
269  end if
270  end if
271 
272  if (this%nodes == 0) this%nodes = product(this%mshape)
273 
274  ! scale maxbound by keystring member count; fall back to nodes * nmembers
275  ! when no DIMENSIONS block is present (e.g. TVK/TVS)
276  if (this%loadtype == keystring .or. &
277  this%loadtype == advanced) then
278  ! count members from the KEYSTRING aggregate type definition, which
279  ! names exactly the dispatchable members
280  nmembers = 0
281  aidt => get_aggregate_definition_type(this%mf6_input%aggregate_dfns, &
282  this%mf6_input%component_type, &
283  this%mf6_input%subcomponent_type, &
284  'PERIOD')
285  call idt_parse_rectype(aidt, cols, ncol)
286  ks_aidt => find_setting_aggregate(this%mf6_input, cols, ncol)
287  if (associated(ks_aidt)) then
288  call idt_parse_rectype(ks_aidt, ks_cols, nmembers)
289  end if
290  if (allocated(cols)) deallocate (cols)
291  if (allocated(ks_cols)) deallocate (ks_cols)
292  if (this%maxbound == 0) this%maxbound = this%nodes * nmembers
293  end if
294  end if
This module contains the DefinitionSelectModule.
type(inputparamdefinitiontype) function, pointer, public get_aggregate_definition_type(input_definition_types, component_type, subcomponent_type, blockname)
Return aggregate definition.
subroutine, public idt_parse_rectype(idt, cols, ncol)
allocate and set RECARRAY, KEYSTRING or RECORD param list
Here is the call graph for this function:

◆ destroy()

subroutine loadcontextmodule::destroy ( class(loadcontexttype this)

Definition at line 653 of file LoadContext.f90.

654  class(LoadContextType) :: this
655 
656  if (allocated(this%named_bound)) deallocate (this%named_bound)
657 
658  if (this%ctxtype == exchange .or. &
659  this%ctxtype == stresspkg) then
660  ! deallocate local
661  deallocate (this%naux)
662  deallocate (this%ncpl)
663  deallocate (this%nodes)
664  deallocate (this%maxbound)
665  deallocate (this%boundnames)
666  deallocate (this%iprpak)
667  end if
668 
669  ! nullify
670  nullify (this%naux)
671  nullify (this%nbound)
672  nullify (this%ncpl)
673  nullify (this%nodes)
674  nullify (this%maxbound)
675  nullify (this%boundnames)
676  nullify (this%iprpak)
677  nullify (this%auxname_cst)
678  nullify (this%boundname_cst)
679  nullify (this%auxvar)
680  nullify (this%mshape)

◆ expand_record_submembers()

subroutine loadcontextmodule::expand_record_submembers ( type(modflowinputtype), intent(in)  mf6_input,
type(inputparamdefinitiontype), intent(in), pointer  rec_idt,
character(len=linelength), dimension(:), intent(inout), allocatable  member_names,
integer(i4b), intent(inout)  nmembers 
)

Definition at line 716 of file LoadContext.f90.

717  use inputoutputmodule, only: upcase
720  type(ModflowInputType), intent(in) :: mf6_input
721  type(InputParamDefinitionType), pointer, intent(in) :: rec_idt
722  character(len=LINELENGTH), allocatable, intent(inout) :: member_names(:)
723  integer(I4B), intent(inout) :: nmembers
724  type(InputParamDefinitionType), pointer :: sub_idt
725  character(len=LINELENGTH), allocatable :: sub_cols(:)
726  character(len=LINELENGTH) :: token, tagname
727  integer(I4B) :: k, j, nsub_col
728  call idt_parse_rectype(rec_idt, sub_cols, nsub_col)
729  do k = 1, nsub_col
730  token = trim(sub_cols(k))
731  call upcase(token)
732  do j = 1, size(mf6_input%param_dfns)
733  sub_idt => mf6_input%param_dfns(j)
734  if (sub_idt%blockname /= 'PERIOD') cycle
735  tagname = sub_idt%tagname
736  call upcase(tagname)
737  if (trim(tagname) /= trim(token)) cycle
738  if (idt_datatype(sub_idt) == 'RECORD') cycle
739  nmembers = nmembers + 1
740  call expandarray(member_names)
741  member_names(nmembers) = trim(sub_idt%tagname)
742  exit
743  end do
744  end do
745  if (allocated(sub_cols)) deallocate (sub_cols)
character(len=linelength) function, public idt_datatype(idt)
return input definition type datatype
subroutine, public upcase(word)
Convert to upper case.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_setting_aggregate()

type(inputparamdefinitiontype) function, pointer loadcontextmodule::find_setting_aggregate ( type(modflowinputtype), intent(in)  mf6_input,
character(len=linelength), dimension(:), intent(in)  rec_cols,
integer(i4b), intent(in)  nrec_col 
)
private

Definition at line 685 of file LoadContext.f90.

686  use inputoutputmodule, only: upcase
688  type(ModflowInputType), intent(in) :: mf6_input
689  character(len=LINELENGTH), intent(in) :: rec_cols(:)
690  integer(I4B), intent(in) :: nrec_col
691  type(InputParamDefinitionType), pointer :: ks_aidt
692  character(len=LINELENGTH) :: token, tagname
693  integer(I4B) :: m, n, ilen
694  ks_aidt => null()
695  do m = 1, nrec_col
696  token = trim(rec_cols(m))
697  call upcase(token)
698  ilen = len_trim(token)
699  if (ilen < 8) cycle
700  if (token(ilen - 6:ilen) /= 'SETTING') cycle
701  do n = 1, size(mf6_input%aggregate_dfns)
702  tagname = mf6_input%aggregate_dfns(n)%tagname
703  call upcase(tagname)
704  if (trim(tagname) == trim(token)) then
705  ks_aidt => mf6_input%aggregate_dfns(n)
706  if (idt_datatype(ks_aidt) /= 'KEYSTRING') ks_aidt => null()
707  exit
708  end if
709  end do
710  exit
711  end do
Here is the call graph for this function:
Here is the caller graph for this function:

◆ in_scope()

logical(lgp) function loadcontextmodule::in_scope ( class(loadcontexttype this,
type(modflowinputtype), intent(in)  mf6_input,
character(len=*), intent(in)  blockname,
character(len=*), intent(in)  tagname 
)

Definition at line 466 of file LoadContext.f90.

469  class(LoadContextType) :: this
470  type(ModflowInputType), intent(in) :: mf6_input
471  character(len=*), intent(in) :: blockname
472  character(len=*), intent(in) :: tagname
473  logical(LGP) :: in_scope
474  type(InputParamDefinitionType), pointer :: idt
475  character(len=LENVARNAME) :: checkname
476  character(len=LINELENGTH) :: datatype
477  integer(I4B) :: isize, checksize
478  integer(I4B), pointer :: intptr
479 
480  idt => &
481  get_param_definition_type(mf6_input%param_dfns, &
482  mf6_input%component_type, &
483  mf6_input%subcomponent_type, &
484  blockname, tagname, '')
485  if (idt%required) then
486  in_scope = .true.
487  return
488  else
489  in_scope = .false.
490  datatype = idt_datatype(idt)
491  if (datatype == 'KEYSTRING' .or. &
492  datatype == 'RECARRAY' .or. &
493  datatype == 'RECORD') return
494  end if
495 
496  ! initialize
497  checkname = ''
498  checksize = 0
499 
500  if (tagname == 'AUXVAR' .or. &
501  tagname == 'AUX') then
502  checkname = 'NAUX'
503  else if (tagname == 'BOUNDNAME') then
504  checkname = 'BOUNDNAMES'
505  else if (tagname == 'I'//trim(mf6_input%subcomponent_type(1:3))) then
506  if (this%loadtype == layerarray) in_scope = .true.
507  else
508  select case (mf6_input%subcomponent_type)
509  case ('EVT')
510  if (tagname == 'PXDP' .or. tagname == 'PETM') then
511  checkname = 'NSEG'
512  checksize = 1
513  else if (tagname == 'PETM0') then
514  checkname = 'SURFRATESPEC'
515  end if
516  case ('MVR', 'MVT', 'MVE')
517  if (tagname == 'MNAME' .or. &
518  tagname == 'MNAME1' .or. &
519  tagname == 'MNAME2') then
520  checkname = 'MODELNAMES'
521  end if
522  case ('NAM')
523  in_scope = .true.
524  case ('SSM')
525  if (tagname == 'MIXED') in_scope = .true.
526  case ('SPC', 'SPCA')
527  in_scope = .true.
528  case default
529  errmsg = 'LoadContext in_scope needs new check for: '// &
530  trim(mf6_input%subcomponent_type)//'/'//trim(idt%tagname)
531  call store_error(errmsg, .true.)
532  end select
533  end if
534 
535  ! apply checks
536  if (.not. in_scope) then
537  call get_isize(checkname, mf6_input%mempath, isize)
538  if (isize > 0) then
539  call mem_setptr(intptr, checkname, mf6_input%mempath)
540  if (intptr > checksize) in_scope = .true.
541  end if
542  end if
type(inputparamdefinitiontype) function, pointer, public get_param_definition_type(input_definition_types, component_type, subcomponent_type, blockname, tagname, filename, found)
Return parameter definition.
Here is the call graph for this function:

◆ init()

subroutine loadcontextmodule::init ( class(loadcontexttype this,
type(modflowinputtype), intent(in)  mf6_input,
character(len=*), intent(in), optional  blockname,
character(len=*), dimension(:), intent(in), optional  named_bound 
)
private

Definition at line 105 of file LoadContext.f90.

106  use inputoutputmodule, only: upcase
108  class(LoadContextType) :: this
109  type(ModflowInputType), intent(in) :: mf6_input
110  character(len=*), optional, intent(in) :: blockname
111  character(len=*), dimension(:), optional, intent(in) :: named_bound
112  type(InputParamDefinitionType), pointer :: idt
113  integer(I4B) :: n
114 
115  this%mf6_input = mf6_input
116  this%readarray = .false.
117  this%loadtype = load_undef
118  this%ctxtype = context_undef
119 
120  select case (mf6_input%load_scope)
121  case ('ROOT')
122  this%ctxtype = root
123  case ('SIM')
124  if (mf6_input%subcomponent_type == 'NAM') then
125  this%ctxtype = model
126  else if (mf6_input%subcomponent_type == 'TDIS' .or. &
127  mf6_input%subcomponent_type == 'HPC') then
128  this%ctxtype = sim
129  else if (mf6_input%component_type == 'EXG') then
130  this%ctxtype = exchange
131  end if
132  case ('MODEL')
133  if (mf6_input%subcomponent_type == 'OC' .or. &
134  mf6_input%subcomponent_type == 'STO') then
135  this%ctxtype = modelpkg
136  else
137  this%ctxtype = stresspkg
138  end if
139  case default
140  end select
141 
142  if (this%ctxtype == context_undef) then
143  errmsg = 'LoadContext unidentified context for mempath: '// &
144  trim(mf6_input%mempath)
145  call store_error(errmsg, .true.)
146  end if
147 
148  if (present(blockname)) then
149  this%blockname = blockname
150  call upcase(this%blockname)
151  else
152  this%blockname = 'PERIOD'
153  end if
154 
155  if (present(named_bound)) then
156  allocate (this%named_bound(size(named_bound)))
157  do n = 1, size(named_bound)
158  this%named_bound(n) = named_bound(n)
159  call upcase(this%named_bound(n))
160  end do
161  else
162  allocate (this%named_bound(1))
163  this%named_bound(1) = 'MAXBOUND'
164  end if
165 
166  ! determine aggregate load type
167  do n = 1, size(mf6_input%block_dfns)
168  if (mf6_input%block_dfns(n)%blockname == this%blockname) then
169  if (mf6_input%block_dfns(n)%aggregate) then
170  if (this%blockname == 'PERIOD' .and. &
171  is_keystring_period(mf6_input)) then
172  this%loadtype = keystring
173  else
174  this%loadtype = list
175  end if
176  exit
177  end if
178  end if
179  end do
180 
181  ! check if KEYSTRING type is ADVANCED package
182  if (this%loadtype == keystring) then
183  do n = 1, size(mf6_input%block_dfns)
184  if (mf6_input%block_dfns(n)%blockname == 'PACKAGEDATA') then
185  this%loadtype = advanced
186  exit
187  end if
188  end do
189  end if
190 
191  ! determine if array based load
192  if (this%loadtype == load_undef) then
193  do n = 1, size(mf6_input%param_dfns)
194  idt => mf6_input%param_dfns(n)
195  if (idt%blockname == 'OPTIONS') then
196  select case (idt%tagname)
197  case ('READASARRAYS')
198  this%loadtype = layerarray
199  this%readarray = .true.
200  case ('READARRAYGRID')
201  this%loadtype = gridarray
202  this%readarray = .true.
203  case default
204  ! no-op
205  end select
206  end if
207  end do
208  end if
209 
210  ! set in scope params for load
211  call this%set_params()
212 
213  ! allocate load context scalars
214  call this%allocate_scalars()
This module contains the ModelPackageInputsModule.
logical(lgp) function, public supported_model(ctype)
is this a supported MODFLOW 6 model type
Here is the call graph for this function:

◆ is_keystring_period()

logical(lgp) function, public loadcontextmodule::is_keystring_period ( type(modflowinputtype), intent(in)  mf6_input)

Definition at line 750 of file LoadContext.f90.

753  type(ModflowInputType), intent(in) :: mf6_input
754  logical(LGP) :: res, has_period
755  type(InputParamDefinitionType), pointer :: aidt, ks_aidt
756  character(len=LINELENGTH), allocatable :: cols(:)
757  integer(I4B) :: n, ncol
758  res = .false.
759  has_period = .false.
760  do n = 1, size(mf6_input%block_dfns)
761  if (mf6_input%block_dfns(n)%blockname == 'PERIOD') then
762  has_period = .true.
763  end if
764  end do
765  if (.not. has_period) return
766  aidt => get_aggregate_definition_type(mf6_input%aggregate_dfns, &
767  mf6_input%component_type, &
768  mf6_input%subcomponent_type, &
769  'PERIOD')
770  call idt_parse_rectype(aidt, cols, ncol)
771  if (ncol >= 2) then
772  ks_aidt => find_setting_aggregate(mf6_input, cols, ncol)
773  if (associated(ks_aidt)) res = .true.
774  end if
775  if (allocated(cols)) deallocate (cols)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ keystring_member_names()

subroutine loadcontextmodule::keystring_member_names ( class(loadcontexttype this,
character(len=linelength), dimension(:), intent(out), allocatable  member_names,
integer(i4b), intent(out)  nmembers 
)

Column order follows the KEYSTRING aggregate definition token list, which is the single authoritative source of order — independent of the order in which individual params appear in param_dfns. For each token in the aggregate:

  • RECORD compound group: sub-members are expanded in RECORD type order
  • direct-dispatch param: appended as-is

Definition at line 787 of file LoadContext.f90.

788  use inputoutputmodule, only: upcase
792  class(LoadContextType) :: this
793  character(len=LINELENGTH), allocatable, intent(out) :: member_names(:)
794  integer(I4B), intent(out) :: nmembers
795  type(InputParamDefinitionType), pointer :: aidt, ks_aidt, idt
796  character(len=LINELENGTH), allocatable :: rec_cols(:), ks_cols(:)
797  character(len=LINELENGTH) :: rec_token, tagname
798  integer(I4B) :: m, n, nrec_col, nks_col
799 
800  nmembers = 0
801 
802  ! get RECARRAY aggregate for period block and parse its column tokens
803  aidt => get_aggregate_definition_type(this%mf6_input%aggregate_dfns, &
804  this%mf6_input%component_type, &
805  this%mf6_input%subcomponent_type, &
806  this%blockname)
807  call idt_parse_rectype(aidt, rec_cols, nrec_col)
808 
809  ! find the KEYSTRING aggregate for the SETTING token
810  ks_aidt => find_setting_aggregate(this%mf6_input, rec_cols, nrec_col)
811  if (allocated(rec_cols)) deallocate (rec_cols)
812  if (.not. associated(ks_aidt)) return
813 
814  ! parse the KEYSTRING aggregate to get member token list — canonical order
815  call idt_parse_rectype(ks_aidt, ks_cols, nks_col)
816 
817  ! walk the keystring token list in aggregate order
818  do m = 1, nks_col
819  rec_token = trim(ks_cols(m))
820  call upcase(rec_token)
821 
822  ! locate matching param_dfns entry for this token
823  do n = 1, size(this%mf6_input%param_dfns)
824  if (this%mf6_input%param_dfns(n)%blockname /= 'PERIOD') cycle
825  tagname = this%mf6_input%param_dfns(n)%tagname
826  call upcase(tagname)
827  if (trim(tagname) /= trim(rec_token)) cycle
828 
829  idt => this%mf6_input%param_dfns(n)
830  if (idt_datatype(idt) == 'RECORD') then
831  ! compound group: expand sub-members in RECORD type order
832  call expand_record_submembers(this%mf6_input, idt, member_names, &
833  nmembers)
834  else
835  ! direct-dispatch param
836  nmembers = nmembers + 1
837  call expandarray(member_names)
838  member_names(nmembers) = trim(this%mf6_input%param_dfns(n)%tagname)
839  end if
840  exit
841  end do
842  end do
843 
844  if (allocated(ks_cols)) deallocate (ks_cols)
Here is the call graph for this function:

◆ rsv_alloc()

character(len=lenvarname) function loadcontextmodule::rsv_alloc ( class(loadcontexttype this,
character(len=*), intent(in)  mf6varname 
)

Create and set a read state variable, e.g. 'INRECHARGE', which are updated per iper load as follows: -1: unset, not in use 0: not read in most recent period block 1: numeric input read in most recent period block 2: time series input read in most recent period block

Definition at line 639 of file LoadContext.f90.

640  use constantsmodule, only: lenvarname
642  class(LoadContextType) :: this
643  character(len=*), intent(in) :: mf6varname
644  character(len=LENVARNAME) :: varname
645  integer(I4B), pointer :: intvar
646  varname = rsv_name(mf6varname)
647  call mem_allocate(intvar, varname, this%mf6_input%mempath)
648  intvar = -1
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
Here is the call graph for this function:

◆ rsv_name()

character(len=lenvarname) function, public loadcontextmodule::rsv_name ( character(len=*), intent(in)  mf6varname)

Definition at line 849 of file LoadContext.f90.

850  use constantsmodule, only: lenvarname
851  character(len=*), intent(in) :: mf6varname
852  character(len=LENVARNAME) :: varname
853  integer(I4B) :: ilen
854  character(len=2) :: prefix = 'IN'
855  ilen = len_trim(mf6varname)
856  if (ilen > (lenvarname - len(prefix))) then
857  varname = prefix//mf6varname(1:(lenvarname - len(prefix)))
858  else
859  varname = prefix//trim(mf6varname)
860  end if
Here is the caller graph for this function:

◆ set_params()

subroutine loadcontextmodule::set_params ( class(loadcontexttype this)

Definition at line 547 of file LoadContext.f90.

552  class(LoadContextType) :: this
553  type(InputParamDefinitionType), pointer :: idt, aidt
554  character(len=LINELENGTH), dimension(:), allocatable :: tags
555  character(len=LINELENGTH), dimension(:), allocatable :: cols
556  integer(I4B) :: keepcnt, iparam, nparam
557  logical(LGP) :: keep, tag_found
558 
559  ! initialize
560  keepcnt = 0
561 
562  if (this%loadtype == list .or. &
563  this%loadtype == keystring .or. &
564  this%loadtype == advanced) then
565  ! get aggregate param definition for period block
566  aidt => &
567  get_aggregate_definition_type(this%mf6_input%aggregate_dfns, &
568  this%mf6_input%component_type, &
569  this%mf6_input%subcomponent_type, &
570  this%blockname)
571  ! split recarray definition
572  call idt_parse_rectype(aidt, cols, nparam)
573  else
574  nparam = size(this%mf6_input%param_dfns)
575  end if
576 
577  ! allocate dfn input params
578  do iparam = 1, nparam
579  if (this%loadtype == list .or. &
580  this%loadtype == keystring .or. &
581  this%loadtype == advanced) then
582  ! use found so keystring placeholders are silently skipped
583  idt => get_param_definition_type(this%mf6_input%param_dfns, &
584  this%mf6_input%component_type, &
585  this%mf6_input%subcomponent_type, &
586  this%blockname, cols(iparam), '', &
587  found=tag_found)
588  else
589  tag_found = .true.
590  idt => this%mf6_input%param_dfns(iparam)
591  end if
592 
593  if (.not. tag_found) then
594  keep = .false.
595  else if (idt%blockname /= this%blockname) then
596  keep = .false.
597  else
598  keep = this%in_scope(this%mf6_input, this%blockname, idt%tagname)
599  end if
600 
601  if (keep) then
602  keepcnt = keepcnt + 1
603  call expandarray(tags)
604  tags(keepcnt) = trim(idt%tagname)
605  end if
606  end do
607 
608  ! update nparam
609  nparam = keepcnt
610 
611  ! for LIST/KEYSTRING/ADVANCED packages record the leading-column count;
612  ! this is the count of aggregate columns before the keystring placeholder
613  if (this%loadtype == list .or. &
614  this%loadtype == keystring .or. &
615  this%loadtype == advanced) this%nleading = nparam
616 
617  ! allocate filtcols
618  allocate (this%params(nparam))
619 
620  ! set filtcols
621  do iparam = 1, nparam
622  this%params(iparam) = trim(tags(iparam))
623  end do
624 
625  ! cleanup
626  if (allocated(tags)) deallocate (tags)
Here is the call graph for this function:

◆ setptr_auxvar()

subroutine loadcontextmodule::setptr_auxvar ( real(dp), dimension(:, :), intent(inout), pointer, contiguous  auxvar,
character(len=*), intent(in)  mempath 
)

Definition at line 1024 of file LoadContext.f90.

1026  real(DP), dimension(:, :), pointer, &
1027  contiguous, intent(inout) :: auxvar
1028  character(len=*), intent(in) :: mempath
1029  integer(I4B) :: isize
1030  call get_isize('AUXVAR', mempath, isize)
1031  if (isize > -1) then
1032  call mem_setptr(auxvar, 'AUXVAR', mempath)
1033  else
1034  call mem_allocate(auxvar, 0, 0, 'AUXVAR', mempath)
1035  end if

◆ setptr_charstr1d()

subroutine loadcontextmodule::setptr_charstr1d ( type(characterstringtype), dimension(:), intent(inout), pointer, contiguous  charstr1d,
character(len=*), intent(in)  varname,
character(len=*), intent(in)  mempath,
integer(i4b), intent(in)  strlen 
)

Definition at line 1005 of file LoadContext.f90.

1007  type(CharacterStringType), dimension(:), pointer, &
1008  contiguous, intent(inout) :: charstr1d
1009  character(len=*), intent(in) :: varname
1010  character(len=*), intent(in) :: mempath
1011  integer(I4B), intent(in) :: strlen
1012  integer(I4B) :: isize
1013  call get_isize(varname, mempath, isize)
1014  if (isize > -1) then
1015  call mem_setptr(charstr1d, varname, mempath)
1016  else
1017  call mem_allocate(charstr1d, strlen, 0, varname, mempath)
1018  end if

◆ setptr_int()

subroutine loadcontextmodule::setptr_int ( integer(i4b), intent(inout), pointer  intptr,
character(len=*), intent(in)  varname,
character(len=*), intent(in)  mempath 
)

Definition at line 988 of file LoadContext.f90.

990  integer(I4B), pointer, intent(inout) :: intptr
991  character(len=*), intent(in) :: varname
992  character(len=*), intent(in) :: mempath
993  integer(I4B) :: isize
994  call get_isize(varname, mempath, isize)
995  if (isize > -1) then
996  call mem_setptr(intptr, varname, mempath)
997  else
998  call mem_allocate(intptr, varname, mempath)
999  intptr = 0
1000  end if

◆ setval()

subroutine loadcontextmodule::setval ( integer(i4b), intent(inout), pointer  intptr,
character(len=*), intent(in)  varname,
character(len=*), intent(in)  mempath 
)

Definition at line 974 of file LoadContext.f90.

976  integer(I4B), pointer, intent(inout) :: intptr
977  character(len=*), intent(in) :: varname
978  character(len=*), intent(in) :: mempath
979  logical(LGP) :: found
980  allocate (intptr)
981  intptr = 0
982  call mem_set_value(intptr, varname, mempath, found)
Here is the caller graph for this function:

◆ sum_named_bounds()

subroutine loadcontextmodule::sum_named_bounds ( character(len=*), dimension(:), intent(in)  named_bound,
character(len=*), intent(in)  mempath,
integer(i4b), intent(inout)  total 
)

Loops over each name in named_bound and accumulates its value from mempath into total. Variables not present in mempath are silently skipped.

Definition at line 953 of file LoadContext.f90.

955  character(len=*), dimension(:), intent(in) :: named_bound
956  character(len=*), intent(in) :: mempath
957  integer(I4B), intent(inout) :: total
958  integer(I4B), pointer :: dimptr
959  integer(I4B) :: n, isize
960 
961  do n = 1, size(named_bound)
962  call get_isize(trim(named_bound(n)), mempath, isize)
963  if (isize > -1) then
964  call mem_setptr(dimptr, trim(named_bound(n)), mempath)
965  total = total + dimptr
966  nullify (dimptr)
967  end if
968  end do
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tags()

subroutine loadcontextmodule::tags ( class(loadcontexttype this,
character(len=linelength), dimension(:), intent(inout), allocatable  params,
integer(i4b), intent(inout)  nparam,
character(len=*), intent(in)  input_name,
logical(lgp), intent(in), optional  create 
)

set input array to tagnames of in scope params, optionally allocate the parameters based on datatype.

Definition at line 417 of file LoadContext.f90.

419  use simvariablesmodule, only: iout
421  class(LoadContextType) :: this
422  character(len=LINELENGTH), dimension(:), allocatable, &
423  intent(inout) :: params
424  integer(I4B), intent(inout) :: nparam
425  character(len=*), intent(in) :: input_name
426  logical(LGP), optional, intent(in) :: create
427  type(InputParamDefinitionType), pointer :: idt
428  character(len=LINELENGTH) :: dev_msg
429  logical(LGP) :: allocate_params
430  integer(I4B) :: n
431 
432  ! initialize allocate_params
433  allocate_params = .false.
434 
435  ! override default if provided
436  if (present(create)) then
437  allocate_params = create
438  end if
439 
440  if (allocated(params)) deallocate (params)
441  nparam = size(this%params)
442  allocate (params(nparam))
443  do n = 1, nparam
444  idt => &
445  get_param_definition_type(this%mf6_input%param_dfns, &
446  this%mf6_input%component_type, &
447  this%mf6_input%subcomponent_type, &
448  this%blockname, this%params(n), '')
449 
450  ! check if input param is developmode
451  if (idt%developmode) then
452  dev_msg = 'Input tag "'//trim(idt%tagname)// &
453  &'" read from file "'//trim(input_name)// &
454  &'" is still under development. Install the &
455  &nightly build or compile from source with IDEVELOPMODE = 1.'
456  call developmode(dev_msg, iout)
457  end if
458 
459  params(n) = this%params(n)
460  if (allocate_params) call this%allocate_param(idt)
461  end do
Disable development features in release mode.
Definition: FeatureFlags.f90:2
subroutine, public developmode(errmsg, iunit)
Terminate if in release mode (guard development features)
This module contains simulation variables.
Definition: SimVariables.f90:9
integer(i4b) iout
file unit number for simulation output
Here is the call graph for this function: