MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
mf6filekeystringmodule Module Reference

Period block keystring-based input loader. More...

Data Types

type  intarraytype
 Wraps an allocatable int array for a per-column cache table. More...
 
type  keystringloadtype
 Keystring period block loader. More...
 

Functions/Subroutines

subroutine ainit (this, mf6_input, component_name, component_input_name, input_name, iperblock, parser, iout)
 
subroutine df (this)
 
subroutine ts_advance (this)
 
subroutine rp (this, parser)
 
subroutine allocate_subindex (this)
 Allocate ctxsubindex_dependency targets (subindex params excluded from allocate_items), and cache everything apply_subindex needs every period. More...
 
subroutine allocate_permanent_array (this, name, nfeatures, init_value)
 Allocate a permanent per-feature array named name with init_value, unless already allocated. More...
 
subroutine allocate_items (this)
 Allocate a permanent array for every IDM-managed item, using the descriptor's per-item feature count and init value. More...
 
logical(lgp) function valid_address (this, ifno, nfeatures, ifno_tagname, row)
 Validate ifno against nfeatures, storing an error keyed by ifno_tagname (the leading column's public tag) if out of range. More...
 
subroutine apply_auxiliary (this)
 Apply PERIOD AUXILIARY settings to the permanent AUX array. TS-linked rows resolve via the struct array's own ts_strlocs; literal rows resolve AUXNAME here and clear any stale TS link. More...
 
subroutine apply_subindex (this)
 Apply PERIOD settings for ctxsubindex_dependency's targets, via ts_update_indexed – same mechanism as BEDK/MANNING, but each row's target index comes from a named subindex field through the cached offset table rather than the leading id column alone. More...
 
subroutine apply_items (this)
 Apply IDM-managed feature- and node-addressed settings to their permanent arrays; each row's address comes from resolve_row_addr. Indexed-body and AUX are handled in their own routines. More...
 
integer(i4b) function resolve_row_addr (this, item, irow, period_ifno, cellid, ndim, leading_tag)
 Resolve one row's target index for an item, dispatching on addr_mode. Returns 0 (skip) if out of range. More...
 
integer(i4b) function, dimension(:), allocatable resolve_subindex_offsets (this, dimname)
 Per-feature cumulative offset table from an array-valued dimension, permuted into feature-index order first. Indexed by feature (not the dimension's own summed total). More...
 
integer(i4b) function, dimension(:), allocatable resolve_subindex_address (this, id_mf6varname, head_mf6varname, subindex_icol, offsets, nfeatures, nbound)
 Row -> resolved feature index for an item whose local position comes from a subindex field, via the offset table. More...
 
subroutine reset (this)
 
subroutine destroy (this)
 
subroutine create_structarray (this)
 

Detailed Description

Each keystring item maps to a typed column in a StructArrayType. A dispatch keyword on each input row selects the target column.

Simple dispatch: keyword matches a DOUBLE/STRING/INTEGER column; one value token is read into that column.

Compound dispatch: keyword matches a KEYWORD-type column (e.g. FLOWING_WELL). The keyword token is stored directly; subsequent non-KEYWORD body columns are read in order.

Function/Subroutine Documentation

◆ ainit()

subroutine mf6filekeystringmodule::ainit ( class(keystringloadtype), intent(inout)  this,
type(modflowinputtype), intent(in)  mf6_input,
character(len=*), intent(in)  component_name,
character(len=*), intent(in)  component_input_name,
character(len=*), intent(in)  input_name,
integer(i4b), intent(in)  iperblock,
type(blockparsertype), intent(inout), pointer  parser,
integer(i4b), intent(in)  iout 
)
private

Definition at line 87 of file Mf6FileKeystring.f90.

89  use inputoutputmodule, only: getunit
93  class(KeystringLoadType), intent(inout) :: this
94  type(ModflowInputType), intent(in) :: mf6_input
95  character(len=*), intent(in) :: component_name
96  character(len=*), intent(in) :: component_input_name
97  character(len=*), intent(in) :: input_name
98  integer(I4B), intent(in) :: iperblock
99  type(BlockParserType), pointer, intent(inout) :: parser
100  integer(I4B), intent(in) :: iout
101  type(CharacterStringType), dimension(:), pointer, contiguous :: ts_fnames
102  character(len=LINELENGTH) :: fname
103  character(len=LENVARNAME) :: named_bound
104  logical(LGP) :: has_named_bound
105  integer(I4B) :: n, isize
106 
107  call this%DynamicPkgLoadType%init(mf6_input, component_name, &
108  component_input_name, input_name, &
109  iperblock, iout)
110  this%ts_active = .false.
111  this%nleading = 0
112 
113  allocate (this%tsmanager)
114  call tsmanager_cr(this%tsmanager, iout)
115 
116  ! load static input (TS6_FILENAME tag sets static_loader%ts_active)
117  call this%static_loader%load(parser, mf6_input, this%nc_vars, &
118  this%input_name, iout)
119 
120  ! add declared TS files to tsmanager
121  if (this%static_loader%ts_active) then
122  this%ts_active = .true.
123  call get_isize('TS6_FILENAME', mf6_input%mempath, isize)
124  if (isize > 0) then
125  call mem_setptr(ts_fnames, 'TS6_FILENAME', mf6_input%mempath)
126  do n = 1, size(ts_fnames)
127  fname = ts_fnames(n)
128  call this%tsmanager%add_tsfile(fname, getunit())
129  end do
130  end if
131  end if
132 
133  ! find a DIMENSIONS parameter to alias as maxbound (skipped for
134  ! advanced packages, which get their count from PACKAGEDATA)
135  has_named_bound = .false.
136  if (.not. is_advanced(mf6_input)) then
137  do n = 1, size(mf6_input%param_dfns)
138  if (mf6_input%param_dfns(n)%blockname == 'DIMENSIONS') then
139  named_bound = trim(mf6_input%param_dfns(n)%mf6varname)
140  has_named_bound = .true.
141  exit
142  end if
143  end do
144  end if
145 
146  ! init load context
147  if (has_named_bound) then
148  call this%ctx%init(mf6_input, named_bound=named_bound)
149  else
150  call this%ctx%init(mf6_input)
151  end if
152 
153  ! params is fully elaborated: leading cols + item names
154  this%param_names = this%ctx%params
155  this%nparam = size(this%ctx%params)
156  this%nleading = this%ctx%nleading
157  call this%ctx%check_developmode(this%input_name)
158 
159  ! finalize context setup (allocates NBOUND, NODEULIST, etc.)
160  call this%ctx%allocate_arrays()
161 
162  ! pre-allocate structarray; reused across all periods
163  call this%create_structarray()
164 
integer(i4b) function, public getunit()
Get a free unit number.
This module contains the LoadMf6FileModule.
Definition: LoadMf6File.f90:8
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
Static parser based input loader.
Definition: LoadMf6File.f90:54
Here is the call graph for this function:

◆ allocate_items()

subroutine mf6filekeystringmodule::allocate_items ( class(keystringloadtype), intent(inout)  this)

Definition at line 340 of file Mf6FileKeystring.f90.

342  class(KeystringLoadType), intent(inout) :: this
343  integer(I4B) :: k
344 
345  if (.not. allocated(this%ctx%keystring_items)) return
346 
347  do k = 1, size(this%ctx%keystring_items)
348  if (.not. this%ctx%keystring_items(k)%idm_managed) cycle
349  ! subindex arrays are allocated in allocate_subindex (df-time
350  ! dimension); skip here
351  if (this%ctx%keystring_items(k)%addr_mode == addr_subindex) cycle
352  if (this%ctx%keystring_items(k)%nfeatures < 1) cycle
353  call this%allocate_permanent_array( &
354  this%ctx%keystring_items(k)%idt%mf6varname, &
355  this%ctx%keystring_items(k)%nfeatures, &
356  this%ctx%keystring_items(k)%init_value)
357  end do
358  if (count_errors() > 0) then
359  call store_error_filename(this%input_name)
360  end if
This module contains simulation methods.
Definition: Sim.f90:10
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:204
Here is the call graph for this function:

◆ allocate_permanent_array()

subroutine mf6filekeystringmodule::allocate_permanent_array ( class(keystringloadtype), intent(inout)  this,
character(len=*), intent(in)  name,
integer(i4b), intent(in)  nfeatures,
real(dp), intent(in)  init_value 
)

Definition at line 322 of file Mf6FileKeystring.f90.

324  class(KeystringLoadType), intent(inout) :: this
325  character(len=*), intent(in) :: name
326  integer(I4B), intent(in) :: nfeatures
327  real(DP), intent(in) :: init_value
328  real(DP), dimension(:), pointer, contiguous :: featarr => null()
329  integer(I4B) :: isize
330 
331  call get_isize(name, this%mf6_input%mempath, isize)
332  if (isize > 0) return ! already allocated (shouldn't happen; df() runs once)
333  call mem_allocate(featarr, nfeatures, name, this%mf6_input%mempath)
334  featarr = init_value

◆ allocate_subindex()

subroutine mf6filekeystringmodule::allocate_subindex ( class(keystringloadtype), intent(inout)  this)

Definition at line 250 of file Mf6FileKeystring.f90.

252  class(KeystringLoadType), intent(inout) :: this
253  type(InputParamDefinitionType), pointer :: idt, id_idt
254  character(len=LENVARNAME) :: dimname, subindex_tagname
255  integer(I4B) :: icol, sa_icol, padj, nfeatures, n
256  logical(LGP) :: found
257 
258  if (.not. allocated(this%subindex_nfeatures)) then
259  allocate (this%subindex_nfeatures(this%structarray%count()))
260  allocate (this%subindex_offsets(this%structarray%count()))
261  allocate (this%subindex_icol(this%structarray%count()))
262  allocate (this%subindex_head_icol(this%structarray%count()))
263  this%subindex_nfeatures = 0
264  this%subindex_icol = 0
265  this%subindex_head_icol = 0
266  end if
267 
268  padj = 0
269  if (this%ctx%has_setting_dispatch) padj = 1
270 
271  id_idt => get_param_definition_type(this%mf6_input%param_dfns, &
272  this%mf6_input%component_type, &
273  this%mf6_input%subcomponent_type, &
274  this%ctx%blockname, &
275  this%param_names(1), &
276  this%input_name)
277  this%subindex_id_varname = trim(id_idt%mf6varname)
278 
279  do icol = this%nleading + 1, this%nparam
280  if (.not. this%ctx%keystring_items(icol - this%nleading)%is_body) cycle
281  idt => get_param_definition_type(this%mf6_input%param_dfns, &
282  this%mf6_input%component_type, &
283  this%mf6_input%subcomponent_type, &
284  this%ctx%blockname, &
285  this%param_names(icol), &
286  this%input_name)
287  found = this%ctx%subindex_dependency(idt%tagname, dimname, &
288  subindex_tagname)
289  if (.not. found) cycle
290 
291  sa_icol = icol + padj
292  nfeatures = this%ctx%resolve_item_nfeatures(idt%tagname, dimname, 0)
293  if (nfeatures < 1) cycle
294  this%subindex_nfeatures(sa_icol) = nfeatures
295  this%subindex_offsets(sa_icol)%vals = &
296  this%resolve_subindex_offsets(dimname)
297  call this%allocate_permanent_array( &
298  trim(idt%mf6varname), nfeatures, dzero)
299 
300  ! resolve the subindex column (by ctx-given tag) and this
301  ! target's subindex head, both structurally (body_start/head_nbody)
302  do n = 1, this%structarray%count()
303  if (trim(this%structarray%struct_vectors(n)%idt%tagname) == &
304  trim(subindex_tagname)) this%subindex_icol(sa_icol) = n
305  if (this%structarray%struct_vectors(n)%head_nbody > 0) then
306  if (sa_icol >= this%structarray%struct_vectors(n)%body_start .and. &
307  sa_icol < this%structarray%struct_vectors(n)%body_start + &
308  this%structarray%struct_vectors(n)%head_nbody) &
309  this%subindex_head_icol(sa_icol) = n
310  end if
311  end do
312  ! neither subindex nor head found (misconfigured ctx entry): not a target
313  if (this%subindex_icol(sa_icol) == 0 .or. &
314  this%subindex_head_icol(sa_icol) == 0) &
315  this%subindex_nfeatures(sa_icol) = 0
316  end do
This module contains the DefinitionSelectModule.
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:

◆ apply_auxiliary()

subroutine mf6filekeystringmodule::apply_auxiliary ( class(keystringloadtype), intent(inout)  this)

Definition at line 389 of file Mf6FileKeystring.f90.

393  class(KeystringLoadType), intent(inout) :: this
394  integer(I4B), pointer :: nbound => null()
395  integer(I4B), dimension(:), pointer, contiguous :: period_ifno => null()
396  type(CharacterStringType), dimension(:), pointer, contiguous :: &
397  period_setting => null()
398  type(CharacterStringType), dimension(:), pointer, contiguous :: &
399  period_auxname => null()
400  type(CharacterStringType), dimension(:), pointer, contiguous :: &
401  auxnames => null()
402  real(DP), dimension(:, :), pointer, contiguous :: aux => null()
403  real(DP), pointer :: bndElem
404  type(InputParamDefinitionType), pointer :: idt
405  type(TSStringLocType), pointer :: ts_strloc
406  integer(I4B) :: i, n, ifno, jj, isize, naux, nfeatures, sa_icol, k, nts
407  logical(LGP) :: found
408  logical(LGP), dimension(:), allocatable :: handled
409  character(len=LINELENGTH) :: setting, auxname, thisauxname
410  character(len=LENVARNAME) :: ifno_tagname
411 
412  call get_isize('AUXILIARY', this%mf6_input%mempath, naux)
413  if (naux <= 0) return
414 
415  call get_isize('NBOUND', this%mf6_input%mempath, isize)
416  if (isize < 1) return
417  call mem_setptr(nbound, 'NBOUND', this%mf6_input%mempath)
418  if (nbound <= 0) return
419 
420  call get_isize('AUXNAME', this%mf6_input%mempath, isize)
421  if (isize < 1) return
422 
423  ! leading column's public tag (e.g. MAWNO for MWE), for the error
424  ! message below -- its memory-manager key is always IFNO (MF6INTERNAL)
425  idt => get_param_definition_type(this%mf6_input%param_dfns, &
426  this%mf6_input%component_type, &
427  this%mf6_input%subcomponent_type, &
428  this%ctx%blockname, &
429  this%param_names(1), &
430  this%input_name)
431  ifno_tagname = trim(idt%tagname)
432 
433  ! AUXILIARY dispatch keyword's own mf6varname (e.g. LAK's
434  ! PERIOD_AUXILIARY), since SETTING stores mf6varname, not tagname
435  idt => get_param_definition_type(this%mf6_input%param_dfns, &
436  this%mf6_input%component_type, &
437  this%mf6_input%subcomponent_type, &
438  this%ctx%blockname, 'AUXILIARY', &
439  this%input_name)
440 
441  call mem_setptr(period_ifno, 'IFNO', this%mf6_input%mempath)
442  call mem_setptr(period_setting, 'SETTING', this%mf6_input%mempath)
443  call mem_setptr(period_auxname, 'AUXNAME', this%mf6_input%mempath)
444  call mem_setptr(auxnames, 'AUXILIARY', this%mf6_input%mempath)
445  call mem_setptr(aux, 'AUX', this%mf6_input%mempath)
446  nfeatures = size(aux, 2)
447 
448  sa_icol = 0
449  do n = 1, this%structarray%count()
450  if (is_auxval(this%structarray%struct_vectors(n)%idt)) then
451  sa_icol = n
452  exit
453  end if
454  end do
455  if (sa_icol == 0) return
456 
457  allocate (handled(nbound))
458  handled = .false.
459 
460  ! TS-linked rows: resolve AUXNAME here too, same as literal rows
461  nts = this%structarray%struct_vectors(sa_icol)%ts_strlocs%count()
462  do k = 1, nts
463  ts_strloc => this%structarray%struct_vectors(sa_icol)%get_ts_strloc(k)
464  i = ts_strloc%row
465  ifno = period_ifno(i)
466  if (.not. this%valid_address(ifno, nfeatures, ifno_tagname, i)) cycle
467  auxname = period_auxname(i)
468  jj = find_auxname_index(auxname, auxnames, naux)
469  if (jj < 1) cycle
470  thisauxname = auxnames(jj)
471  bndelem => aux(jj, ifno)
472  call read_value_or_time_series_adv(ts_strloc%token, ifno, jj, bndelem, &
473  this%mf6_input%subcomponent_name, &
474  'AUX', this%tsmanager, &
475  this%ctx%iprpak, trim(thisauxname))
476  handled(i) = .true.
477  end do
478 
479  ! literal rows: resolve AUXNAME here, clear any stale link, assign
480  do i = 1, nbound
481  if (handled(i)) cycle
482  setting = period_setting(i)
483  if (trim(setting) /= trim(idt%mf6varname)) cycle
484  ifno = period_ifno(i)
485  if (.not. this%valid_address(ifno, nfeatures, ifno_tagname, i)) cycle
486  auxname = period_auxname(i)
487  jj = find_auxname_index(auxname, auxnames, naux)
488  if (jj < 1) cycle
489  thisauxname = auxnames(jj)
490  found = remove_existing_link(this%tsmanager, ifno, jj, &
491  this%mf6_input%subcomponent_name, &
492  'AUX', trim(thisauxname))
493  aux(jj, ifno) = this%structarray%struct_vectors(sa_icol)%dbl1d(i)
494  end do
495  if (count_errors() > 0) then
496  call store_error_filename(this%input_name)
497  end if
498  deallocate (handled)
499  call this%structarray%struct_vectors(sa_icol)%clear()
This module contains the StructVectorModule.
Definition: StructVector.f90:7
derived type which describes time series string field
Here is the call graph for this function:

◆ apply_items()

subroutine mf6filekeystringmodule::apply_items ( class(keystringloadtype), intent(inout)  this)
private

Definition at line 550 of file Mf6FileKeystring.f90.

553  class(KeystringLoadType), intent(inout) :: this
554  integer(I4B), pointer :: nbound => null()
555  integer(I4B), dimension(:, :), pointer, contiguous :: cellid => null()
556  integer(I4B), dimension(:), pointer, contiguous :: period_ifno => null()
557  type(CharacterStringType), dimension(:), pointer, contiguous :: &
558  period_setting => null()
559  real(DP), dimension(:), pointer, contiguous :: featarr => null()
560  integer(I4B), dimension(:), allocatable :: row_addr
561  integer(I4B) :: i, k, isize, ndim
562  character(len=LINELENGTH) :: setting
563  character(len=LENVARNAME) :: dispatch_key
564  character(len=LENVARNAME) :: leading_tag
565  type(InputParamDefinitionType), pointer :: lead_idt
566 
567  if (.not. allocated(this%ctx%keystring_items)) return
568 
569  call get_isize('NBOUND', this%mf6_input%mempath, isize)
570  if (isize < 1) return
571  call mem_setptr(nbound, 'NBOUND', this%mf6_input%mempath)
572  if (nbound <= 0) return
573 
574  call mem_setptr(period_setting, 'SETTING', this%mf6_input%mempath)
575 
576  ! addressing sources, resolved once
577  ndim = 0
578  leading_tag = ''
579  if (this%ctx%keystring_by_node) then
580  if (.not. associated(this%ctx%mshape)) return
581  ndim = size(this%ctx%mshape)
582  call mem_setptr(cellid, 'CELLID', this%mf6_input%mempath)
583  else
584  call mem_setptr(period_ifno, this%ctx%feature_id_varname, &
585  this%mf6_input%mempath)
586  ! leading id column's public tag (e.g. MAWNO), for the out-of-range
587  ! message -- the invalid value is the row's leading id, not the
588  ! setting. Feature-addressed only; node loads validate via CELLID.
589  lead_idt => get_param_definition_type(this%mf6_input%param_dfns, &
590  this%mf6_input%component_type, &
591  this%mf6_input%subcomponent_type, &
592  this%ctx%blockname, &
593  this%param_names(1), &
594  this%input_name)
595  leading_tag = trim(lead_idt%tagname)
596  end if
597 
598  do k = 1, size(this%ctx%keystring_items)
599  if (.not. this%ctx%keystring_items(k)%idm_managed) cycle
600  if (this%ctx%keystring_items(k)%addr_mode == addr_subindex) cycle ! separate path
601  if (this%ctx%keystring_items(k)%nfeatures < 1) cycle
602  call mem_setptr(featarr, this%ctx%keystring_items(k)%idt%mf6varname, &
603  this%mf6_input%mempath)
604 
605  ! dispatch key: a RECORD body matches its owning head's SETTING
606  ! keyword (the token on the row); a standalone item matches its own
607  ! mf6varname. resolve_row_addr maps the matched row to a feature.
608  if (this%ctx%keystring_items(k)%is_body) then
609  dispatch_key = this%ctx%keystring_items(k)%head_setting_varname
610  else
611  dispatch_key = this%ctx%keystring_items(k)%idt%mf6varname
612  end if
613 
614  allocate (row_addr(nbound))
615  do i = 1, nbound
616  row_addr(i) = 0
617  setting = period_setting(i)
618  if (trim(setting) /= trim(dispatch_key)) cycle
619  row_addr(i) = &
620  this%resolve_row_addr(this%ctx%keystring_items(k), i, period_ifno, &
621  cellid, ndim, leading_tag)
622  end do
623  call this%structarray%ts_update_indexed( &
624  this%ctx%keystring_items(k)%sa_icol, this%tsmanager, &
625  this%mf6_input%subcomponent_name, this%ctx%iprpak, nbound, row_addr, &
626  this%ctx%keystring_items(k)%idt%tagname, featarr)
627  deallocate (row_addr)
628  end do
629  if (count_errors() > 0) then
630  call store_error_filename(this%input_name)
631  end if
Here is the call graph for this function:

◆ apply_subindex()

subroutine mf6filekeystringmodule::apply_subindex ( class(keystringloadtype), intent(inout)  this)

Definition at line 507 of file Mf6FileKeystring.f90.

508  class(KeystringLoadType), intent(inout) :: this
509  type(InputParamDefinitionType), pointer :: idt, head_idt
510  real(DP), dimension(:), pointer, contiguous :: featarr => null()
511  integer(I4B), pointer :: nbound => null()
512  integer(I4B), dimension(:), allocatable :: row_addr
513  integer(I4B) :: icol, sa_icol, padj, isize
514 
515  if (.not. allocated(this%subindex_nfeatures)) return
516 
517  call get_isize('NBOUND', this%mf6_input%mempath, isize)
518  if (isize < 1) return
519  call mem_setptr(nbound, 'NBOUND', this%mf6_input%mempath)
520  if (nbound <= 0) return
521 
522  padj = 0
523  if (this%ctx%has_setting_dispatch) padj = 1
524 
525  do icol = this%nleading + 1, this%nparam
526  sa_icol = icol + padj
527  if (sa_icol > size(this%subindex_nfeatures)) cycle
528  if (this%subindex_nfeatures(sa_icol) < 1) cycle
529 
530  idt => this%structarray%struct_vectors(sa_icol)%idt
531  head_idt => &
532  this%structarray%struct_vectors(this%subindex_head_icol(sa_icol))%idt
533  call mem_setptr(featarr, trim(idt%mf6varname), this%mf6_input%mempath)
534  row_addr = &
535  this%resolve_subindex_address( &
536  this%subindex_id_varname, trim(head_idt%mf6varname), &
537  this%subindex_icol(sa_icol), &
538  this%subindex_offsets(sa_icol)%vals, &
539  this%subindex_nfeatures(sa_icol), nbound)
540  call this%structarray%ts_update_indexed( &
541  sa_icol, this%tsmanager, this%mf6_input%subcomponent_name, &
542  this%ctx%iprpak, nbound, row_addr, trim(idt%tagname), featarr)
543  end do
Here is the call graph for this function:

◆ create_structarray()

subroutine mf6filekeystringmodule::create_structarray ( class(keystringloadtype), intent(inout)  this)
private

Definition at line 805 of file Mf6FileKeystring.f90.

807  class(KeystringLoadType), intent(inout) :: this
808  type(InputParamDefinitionType), pointer :: idt
809  integer(I4B) :: icol, sa_icol, nrow_prealloc, nsub, padj
810  logical(LGP) :: has_setting
811 
812  has_setting = this%ctx%has_setting_dispatch
813 
814  ! use pre-allocated managed memory (maxbound = features * nkeystring_items);
815  ! fall back to deferred shape (-1) if maxbound is unavailable
816  if (associated(this%ctx%maxbound) .and. this%ctx%maxbound > 0) then
817  nrow_prealloc = this%ctx%maxbound
818  else
819  nrow_prealloc = -1
820  end if
821 
822  ! SETTING column inserted at nleading+1 when has_setting
823  padj = 0
824  if (has_setting) padj = 1
825 
826  if (has_setting .and. nrow_prealloc < 0) then
827  ! fallback for a genuinely unresolvable count (e.g. empty
828  ! PACKAGEDATA), when PACKAGEDATA/DIMENSIONS can't supply one
829  this%structarray => &
830  constructstructarray(this%mf6_input, this%nparam + padj, &
831  nrow_prealloc, 0, this%mf6_input%mempath, &
832  this%mf6_input%component_mempath, size_init=64)
833  else
834  this%structarray => &
835  constructstructarray(this%mf6_input, this%nparam + padj, &
836  nrow_prealloc, 0, this%mf6_input%mempath, &
837  this%mf6_input%component_mempath)
838  end if
839 
840  ! create leading (pre-keystring) columns unchanged
841  do icol = 1, this%nleading
842  idt => get_param_definition_type(this%mf6_input%param_dfns, &
843  this%mf6_input%component_type, &
844  this%mf6_input%subcomponent_type, &
845  this%ctx%blockname, &
846  this%param_names(icol), this%input_name)
847  call this%structarray%mem_create_vector(icol, idt)
848  end do
849 
850  ! create SETTING column (ctx owns setting_idt)
851  if (has_setting) then
852  sa_icol = this%nleading + 1
853  call this%structarray%mem_create_vector(sa_icol, this%ctx%setting_idt, &
854  charlen=lenvarname)
855  end if
856 
857  ! create item columns
858  do icol = this%nleading + 1, this%nparam
859  sa_icol = icol + padj
860  idt => get_param_definition_type(this%mf6_input%param_dfns, &
861  this%mf6_input%component_type, &
862  this%mf6_input%subcomponent_type, &
863  this%ctx%blockname, &
864  this%param_names(icol), this%input_name)
865  ! nsub from descriptor: 0 = direct dispatch, N = KEYWORD compound with N body members
866  nsub = this%ctx%keystring_items(icol - this%nleading)%head_nbody
867  if (nsub > 0) then
868  ! metadata vector: no data allocated; body_start points to next SA col
869  call this%structarray%mem_create_metadata_vector(sa_icol, idt, &
870  sa_icol + 1, nsub)
871  else if (trim(idt%datatype) == 'STRING') then
872  ! string value columns (e.g. STATUS) stored at LENVARNAME
873  call this%structarray%mem_create_vector(sa_icol, idt, &
874  charlen=lenvarname)
875  else if (idt%datatype == 'DOUBLE' .and. &
876  (this%ctx%keystring_items(icol - this%nleading)%idm_managed .or. &
877  this%ctx%keystring_items(icol - this%nleading)%addr_mode == &
878  addr_subindex)) then
879  ! managed/subindex double: raw read array uses the suffixed input
880  ! name, leaving mf6varname for the permanent array the loader populates
881  call this%structarray%mem_create_vector(sa_icol, idt, &
882  varname=idm_input_varname(idt))
883  else
884  call this%structarray%mem_create_vector(sa_icol, idt)
885  end if
886  end do
Here is the call graph for this function:

◆ destroy()

subroutine mf6filekeystringmodule::destroy ( class(keystringloadtype), intent(inout)  this)

Definition at line 788 of file Mf6FileKeystring.f90.

789  class(KeystringLoadType), intent(inout) :: this
790 
791  call this%static_loader%cleanup()
792 
793  call this%tsmanager%da()
794  deallocate (this%tsmanager)
795  nullify (this%tsmanager)
796 
797  if (associated(this%structarray)) then
798  call destructstructarray(this%structarray)
799  end if
800 
801  call this%ctx%destroy()
802  call this%DynamicPkgLoadType%destroy()
Here is the call graph for this function:

◆ df()

subroutine mf6filekeystringmodule::df ( class(keystringloadtype), intent(inout)  this)

Definition at line 167 of file Mf6FileKeystring.f90.

171  class(KeystringLoadType), intent(inout) :: this
172  type(StructArrayType), pointer :: sa
173  type(CharacterStringType), dimension(:), pointer, contiguous :: &
174  auxnames => null()
175  integer(I4B), dimension(:), pointer, contiguous :: pkg_ifno => null()
176  integer(I4B) :: n, naux
177  ! init tsmanager (TDIS now available)
178  call this%tsmanager%tsmanager_df()
179  ! resolve aux names for PACKAGEDATA AUX TS registration
180  call get_isize('AUXILIARY', this%mf6_input%mempath, naux)
181  if (naux > 0) call mem_setptr(auxnames, 'AUXILIARY', this%mf6_input%mempath)
182  ! advanced packages: address AUX TS links by feature number (not
183  ! PACKAGEDATA row position), so a later PERIOD override finds it
184  if (this%ctx%is_advanced) then
185  call mem_setptr(pkg_ifno, 'PACKAGEDATA_IFNO', this%mf6_input%mempath)
186  end if
187  ! link static TS strlocs; preserve for re-registration after reset()
188  do n = 1, this%static_loader%ts_sa_count()
189  sa => this%static_loader%get_ts_sa(n)
190  if (associated(sa)) then
191  if (associated(pkg_ifno)) then
192  call sa%ts_update(this%tsmanager, &
193  this%mf6_input%subcomponent_name, &
194  this%ctx%iprpak, this%input_name, &
195  clear_strlocs=.false., auxname_cst=auxnames, &
196  ifno_map=pkg_ifno)
197  else
198  call sa%ts_update(this%tsmanager, &
199  this%mf6_input%subcomponent_name, &
200  this%ctx%iprpak, this%input_name, &
201  clear_strlocs=.false., auxname_cst=auxnames)
202  end if
203  end if
204  end do
205  ! allocate feature-addressed (DZERO) and node-addressed (DNODATA) items
206  call this%allocate_items()
207  ! subindex df-time dimension fields + permanent arrays
208  if (this%ctx%is_advanced) call this%allocate_subindex()
This module contains the StructArrayModule.
Definition: StructArray.f90:8
type for structured array
Definition: StructArray.f90:47
Here is the call graph for this function:

◆ reset()

subroutine mf6filekeystringmodule::reset ( class(keystringloadtype), intent(inout)  this)

Definition at line 758 of file Mf6FileKeystring.f90.

762  class(KeystringLoadType), intent(inout) :: this
763  type(StructArrayType), pointer :: sa
764  type(CharacterStringType), dimension(:), pointer, contiguous :: &
765  auxnames => null()
766  integer(I4B) :: n, naux
767  ! every KEYSTRING subtype with SETTING dispatch: PERIOD settings
768  ! persist across periods unless reissued, so TS links never reset
769  if (this%ctx%has_setting_dispatch) return
770  ! clear TS links
771  call this%tsmanager%reset(this%mf6_input%subcomponent_name)
772  ! re-register static TS links (strlocs preserved in df)
773  if (this%ts_active) then
774  call get_isize('AUXILIARY', this%mf6_input%mempath, naux)
775  if (naux > 0) call mem_setptr(auxnames, 'AUXILIARY', this%mf6_input%mempath)
776  do n = 1, this%static_loader%ts_sa_count()
777  sa => this%static_loader%get_ts_sa(n)
778  if (associated(sa)) then
779  call sa%ts_update(this%tsmanager, &
780  this%mf6_input%subcomponent_name, &
781  this%ctx%iprpak, this%input_name, &
782  clear_strlocs=.false., auxname_cst=auxnames)
783  end if
784  end do
785  end if
Here is the call graph for this function:

◆ resolve_row_addr()

integer(i4b) function mf6filekeystringmodule::resolve_row_addr ( class(keystringloadtype), intent(inout)  this,
type(keystringitemtype), intent(in)  item,
integer(i4b), intent(in)  irow,
integer(i4b), dimension(:), intent(in), pointer, contiguous  period_ifno,
integer(i4b), dimension(:, :), intent(in), pointer, contiguous  cellid,
integer(i4b), intent(in)  ndim,
character(len=*), intent(in)  leading_tag 
)
Parameters
[in]leading_tagleading id column's public tag (for the out-of-range message)

Definition at line 637 of file Mf6FileKeystring.f90.

640  use geomutilmodule, only: get_node
641  class(KeystringLoadType), intent(inout) :: this
642  type(KeystringItemType), intent(in) :: item
643  integer(I4B), intent(in) :: irow
644  integer(I4B), dimension(:), pointer, contiguous, intent(in) :: period_ifno
645  integer(I4B), dimension(:, :), pointer, contiguous, intent(in) :: cellid
646  integer(I4B), intent(in) :: ndim
647  character(len=*), intent(in) :: leading_tag !< leading id column's public tag (for the out-of-range message)
648  integer(I4B) :: addr
649  integer(I4B) :: ifno, nodeu
650 
651  addr = 0
652  select case (item%addr_mode)
653  case (addr_feature)
654  ifno = period_ifno(irow)
655  if (.not. this%valid_address(ifno, item%nfeatures, leading_tag, irow)) &
656  return
657  addr = ifno
658  case (addr_node)
659  if (ndim == 1) then
660  nodeu = cellid(1, irow)
661  else if (ndim == 2) then
662  nodeu = get_node(cellid(1, irow), 1, cellid(2, irow), &
663  this%ctx%mshape(1), 1, this%ctx%mshape(2))
664  else
665  nodeu = get_node(cellid(1, irow), cellid(2, irow), cellid(3, irow), &
666  this%ctx%mshape(1), this%ctx%mshape(2), &
667  this%ctx%mshape(3))
668  end if
669  if (nodeu < 1 .or. nodeu > item%nfeatures) return
670  addr = nodeu
671  end select
integer(i4b) function, public get_node(ilay, irow, icol, nlay, nrow, ncol)
Get node number, given layer, row, and column indices for a structured grid. If any argument is inval...
Definition: GeomUtil.f90:92
Here is the call graph for this function:

◆ resolve_subindex_address()

integer(i4b) function, dimension(:), allocatable mf6filekeystringmodule::resolve_subindex_address ( class(keystringloadtype), intent(inout)  this,
character(len=*), intent(in)  id_mf6varname,
character(len=*), intent(in)  head_mf6varname,
integer(i4b), intent(in)  subindex_icol,
integer(i4b), dimension(:), intent(in)  offsets,
integer(i4b), intent(in)  nfeatures,
integer(i4b), intent(in)  nbound 
)
private
Parameters
[in]subindex_icolSA column holding the subindex (e.g. IDV)

Definition at line 709 of file Mf6FileKeystring.f90.

712  use simmodule, only: store_error
713  use simvariablesmodule, only: errmsg
714  class(KeystringLoadType), intent(inout) :: this
715  character(len=*), intent(in) :: id_mf6varname
716  character(len=*), intent(in) :: head_mf6varname
717  integer(I4B), intent(in) :: subindex_icol !< SA column holding the subindex (e.g. IDV)
718  integer(I4B), dimension(:), intent(in) :: offsets
719  integer(I4B), intent(in) :: nfeatures
720  integer(I4B), intent(in) :: nbound
721  integer(I4B), dimension(:), allocatable :: row_addr
722  integer(I4B), dimension(:), pointer, contiguous :: period_ifno => null()
723  type(CharacterStringType), dimension(:), pointer, contiguous :: &
724  period_setting => null()
725  integer(I4B) :: i, ifno, idx_local, nlocal
726  character(len=LINELENGTH) :: setting
727  character(len=LENVARNAME) :: id_tag, idx_tag
728 
729  call mem_setptr(period_ifno, id_mf6varname, this%mf6_input%mempath)
730  call mem_setptr(period_setting, 'SETTING', this%mf6_input%mempath)
731  id_tag = trim(this%structarray%struct_vectors(1)%idt%tagname)
732  idx_tag = trim(this%structarray%struct_vectors(subindex_icol)%idt%tagname)
733  allocate (row_addr(nbound))
734  do i = 1, nbound
735  row_addr(i) = 0
736  setting = period_setting(i)
737  if (trim(setting) /= trim(head_mf6varname)) cycle
738  ifno = period_ifno(i)
739  if (ifno < 1 .or. ifno > size(offsets)) cycle
740  ! per-id local count from the cumulative offset table
741  if (ifno < size(offsets)) then
742  nlocal = offsets(ifno + 1) - offsets(ifno)
743  else
744  nlocal = nfeatures - offsets(ifno) + 1
745  end if
746  idx_local = this%structarray%struct_vectors(subindex_icol)%int1d(i)
747  if (idx_local < 1 .or. idx_local > nlocal) then
748  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,1x,a,1x,a,1x,i0,a)') &
749  'index', trim(idx_tag), idx_local, 'must be between 1 and', nlocal, &
750  'for', trim(id_tag), ifno, '.'
751  call store_error(errmsg)
752  cycle
753  end if
754  row_addr(i) = offsets(ifno) + idx_local - 1
755  end do
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
Here is the call graph for this function:

◆ resolve_subindex_offsets()

integer(i4b) function, dimension(:), allocatable mf6filekeystringmodule::resolve_subindex_offsets ( class(keystringloadtype), intent(inout)  this,
character(len=*), intent(in)  dimname 
)

Definition at line 678 of file Mf6FileKeystring.f90.

679  class(KeystringLoadType), intent(inout) :: this
680  character(len=*), intent(in) :: dimname
681  integer(I4B), dimension(:), allocatable :: offsets
682  integer(I4B), dimension(:), pointer, contiguous :: counts_raw => null()
683  integer(I4B), dimension(:), pointer, contiguous :: pkg_ifno => null()
684  integer(I4B), dimension(:), allocatable :: counts
685  integer(I4B) :: i, n, running, ndomain
686 
687  call mem_setptr(counts_raw, trim(dimname), this%mf6_input%mempath)
688  call mem_setptr(pkg_ifno, 'PACKAGEDATA_IFNO', this%mf6_input%mempath)
689  ndomain = size(counts_raw)
690  allocate (counts(ndomain))
691  counts = 0
692  do i = 1, size(counts_raw)
693  n = pkg_ifno(i)
694  if (n < 1 .or. n > ndomain) cycle
695  counts(n) = counts_raw(i)
696  end do
697 
698  allocate (offsets(ndomain))
699  running = 1
700  do n = 1, ndomain
701  offsets(n) = running
702  running = running + counts(n)
703  end do

◆ rp()

subroutine mf6filekeystringmodule::rp ( class(keystringloadtype), intent(inout)  this,
type(blockparsertype), intent(inout), pointer  parser 
)
private

Definition at line 216 of file Mf6FileKeystring.f90.

218  class(KeystringLoadType), intent(inout) :: this
219  type(BlockParserType), pointer, intent(inout) :: parser
220 
221  call this%reset()
222 
223  call idm_log_header(this%mf6_input%component_name, &
224  this%mf6_input%subcomponent_name, this%iout)
225 
226  this%ctx%nbound = &
227  this%structarray%read_from_parser_keystring(parser, this%ts_active, &
228  this%nleading, this%iout, &
229  this%input_name)
230 
231  if (this%ctx%is_advanced) call this%apply_auxiliary()
232  if (this%ctx%is_advanced) call this%apply_subindex()
233  ! apply feature- and node-addressed items
234  call this%apply_items()
235 
236  if (this%ts_active) then
237  call this%structarray%ts_update(this%tsmanager, &
238  this%mf6_input%subcomponent_name, &
239  this%ctx%iprpak, this%input_name)
240  end if
241 
242  call idm_log_close(this%mf6_input%component_name, &
243  this%mf6_input%subcomponent_name, this%iout)
This module contains the Input Data Model Logger Module.
Definition: IdmLogger.f90:7
subroutine, public idm_log_close(component, subcomponent, iout)
@ brief log the closing message
Definition: IdmLogger.f90:56
subroutine, public idm_log_header(component, subcomponent, iout)
@ brief log a header message
Definition: IdmLogger.f90:44
Here is the call graph for this function:

◆ ts_advance()

subroutine mf6filekeystringmodule::ts_advance ( class(keystringloadtype), intent(inout)  this)

Definition at line 211 of file Mf6FileKeystring.f90.

212  class(KeystringLoadType), intent(inout) :: this
213  call this%tsmanager%ad()

◆ valid_address()

logical(lgp) function mf6filekeystringmodule::valid_address ( class(keystringloadtype), intent(inout)  this,
integer(i4b), intent(in)  ifno,
integer(i4b), intent(in)  nfeatures,
character(len=*), intent(in)  ifno_tagname,
integer(i4b), intent(in)  row 
)

Definition at line 366 of file Mf6FileKeystring.f90.

367  use simmodule, only: store_error
368  use simvariablesmodule, only: errmsg
369  class(KeystringLoadType), intent(inout) :: this
370  integer(I4B), intent(in) :: ifno
371  integer(I4B), intent(in) :: nfeatures
372  character(len=*), intent(in) :: ifno_tagname
373  integer(I4B), intent(in) :: row
374  logical(LGP) :: valid
375 
376  valid = (ifno >= 1 .and. ifno <= nfeatures)
377  if (.not. valid) then
378  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,a)') &
379  trim(ifno_tagname), ifno, 'on row', row, &
380  'must be greater than 0 and less than or equal to', nfeatures, '.'
381  call store_error(errmsg)
382  end if
Here is the call graph for this function: