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

This module contains the StructArrayModule. More...

Data Types

type  structarraytype
 type for structured array More...
 

Functions/Subroutines

type(structarraytype) function, pointer, public constructstructarray (mf6_input, ncol, nrow, blocknum, mempath, component_mempath, size_init)
 constructor for a struct_array More...
 
subroutine, public destructstructarray (struct_array)
 destructor for a struct_array More...
 
subroutine mem_create_vector (this, icol, idt, charlen, varname)
 create new vector in StructArrayType More...
 
subroutine mem_create_metadata_vector (this, icol, idt, body_start, head_nbody)
 Create a metadata-only StructVector for a KEYWORD indicator column. More...
 
character(len=lenvarname) function, public idm_input_varname (idt)
 Derive a TS-capable setting's raw input array name, distinct from its persistent array (allocated under mf6varname itself). More...
 
integer(i4b) function count (this)
 
subroutine set_pointer (sv, sv_target)
 
type(structvectortype) function, pointer get (this, idx)
 
subroutine allocate_int_type (this, sv)
 allocate integer input type More...
 
subroutine allocate_dbl_type (this, sv)
 allocate double input type More...
 
subroutine allocate_charstr_type (this, sv)
 allocate charstr input type More...
 
subroutine allocate_int1d_type (this, sv)
 allocate int1d input type More...
 
subroutine allocate_dbl1d_type (this, sv)
 allocate dbl1d input type More...
 
subroutine load_deferred_vector (this, icol)
 
subroutine memload_vectors (this)
 load deferred vectors into managed memory More...
 
subroutine log_structarray_vars (this, iout)
 log information about the StructArrayType More...
 
subroutine check_reallocate (this)
 reallocate local memory for deferred vectors if necessary More...
 
subroutine read_param (this, parser, sv_col, irow, timeseries, iout)
 
logical(lgp) function, public is_auxval (idt)
 True if idt is AUXVAL: its AUX index is resolved dynamically from a sibling AUXNAME, not feature-indexed by its own mf6varname. More...
 
integer(i4b) function, public find_auxname_index (auxname, auxnames, naux)
 Find the AUX array position matching auxname, 0 if none. More...
 
integer(i4b) function read_from_parser (this, parser, timeseries, iout, input_name)
 read from the block parser to fill the StructArrayType More...
 
integer(i4b) function read_from_parser_keystring (this, parser, timeseries, nleading, iout, input_name)
 read keystring period block into the StructArrayType More...
 
integer(i4b) function read_from_binary (this, inunit, iout)
 read from binary input to fill the StructArrayType More...
 
subroutine ts_update (this, tsmanager, subcomp_name, iprpak, input_name, auxname_cst, clear_strlocs, ifno_map)
 link time-series strings in this struct array to a tsmanager More...
 
subroutine ts_update_dedup (this, icol, tsmanager, subcomp_name, iprpak, nrows, addr_map, category, names, featarr2d, raw2d)
 Shared dedup-aware TS resolution for one PERIOD-block column: TS-linked rows resolve via their preserved token, remaining literal rows via remove_existing_link, then clear(). naux=1 (via both rank remaps in ts_update_indexed) covers the single-column BND case. More...
 
subroutine ts_update_adv (this, icol, tsmanager, subcomp_name, iprpak, nrows, ifno_map, auxname_cst, featarr2d)
 Dedup-aware counterpart to ts_update for one MTYPE_DBL2D (AUX) PERIOD-block column. More...
 
subroutine ts_update_indexed (this, icol, tsmanager, subcomp_name, iprpak, nrows, row_addr, varname, featarr)
 Dedup-aware resolution of one MTYPE_DBL PERIOD-block column into its permanent array, shared by both loaders. nrows is explicit since the list loader's row_addr is a permanent, maxbound-sized array, not sized to nrows. More...
 

Detailed Description

This module contains the routines for reading a structured list, which consists of a separate vector for each column in the list.

Function/Subroutine Documentation

◆ allocate_charstr_type()

subroutine structarraymodule::allocate_charstr_type ( class(structarraytype)  this,
type(structvectortype), intent(inout)  sv 
)
private
Parameters
thisStructArrayType

Definition at line 331 of file StructArray.f90.

332  class(StructArrayType) :: this !< StructArrayType
333  type(StructVectorType), intent(inout) :: sv
334  type(CharacterStringType), dimension(:), pointer, contiguous :: charstr1d
335  integer(I4B) :: j, nrow
336 
337  if (this%deferred_shape) then
338  ! shape not known, allocate locally
339  nrow = this%deferred_size_init
340  allocate (charstr1d(this%deferred_size_init))
341  else
342  ! shape known, allocate in managed memory
343  nrow = this%nrow
344  call mem_allocate(charstr1d, sv%charlen, this%nrow, &
345  sv%idt%mf6varname, this%mempath)
346  end if
347 
348  do j = 1, nrow
349  charstr1d(j) = ''
350  end do
351 
352  sv%memtype = mtype_str
353  sv%charstr1d => charstr1d

◆ allocate_dbl1d_type()

subroutine structarraymodule::allocate_dbl1d_type ( class(structarraytype)  this,
type(structvectortype), intent(inout)  sv 
)
Parameters
thisStructArrayType

Definition at line 444 of file StructArray.f90.

445  use memorymanagermodule, only: get_isize
446  class(StructArrayType) :: this !< StructArrayType
447  type(StructVectorType), intent(inout) :: sv
448  real(DP), dimension(:, :), pointer, contiguous :: dbl2d
449  integer(I4B), pointer :: naux, nseg, nseg_1
450  integer(I4B) :: nseg1_isize, n, m
451 
452  if (sv%idt%shape == 'NAUX') then
453  call mem_setptr(naux, sv%idt%shape, this%mempath)
454 
455  if (this%deferred_shape) then
456  ! deferred: plain allocate so check_reallocate can grow it safely
457  allocate (dbl2d(naux, sv%size))
458  else
459  call mem_allocate(dbl2d, naux, this%nrow, sv%idt%mf6varname, this%mempath)
460  end if
461 
462  ! initialize
463  do m = 1, sv%size
464  do n = 1, naux
465  dbl2d(n, m) = dzero
466  end do
467  end do
468 
469  sv%memtype = mtype_dbl2d
470  sv%dbl2d => dbl2d
471  sv%intshape => naux
472  else if (sv%idt%shape == 'NSEG-1') then
473  call mem_setptr(nseg, 'NSEG', this%mempath)
474  call get_isize('NSEG_1', this%mempath, nseg1_isize)
475 
476  if (nseg1_isize < 0) then
477  call mem_allocate(nseg_1, 'NSEG_1', this%mempath)
478  nseg_1 = nseg - 1
479  else
480  call mem_setptr(nseg_1, 'NSEG_1', this%mempath)
481  end if
482 
483  if (this%deferred_shape) then
484  ! deferred: plain allocate so check_reallocate can grow it safely
485  allocate (dbl2d(nseg_1, sv%size))
486  else
487  call mem_allocate(dbl2d, nseg_1, sv%size, sv%idt%mf6varname, this%mempath)
488  end if
489 
490  ! initialize
491  do m = 1, sv%size
492  do n = 1, nseg_1
493  dbl2d(n, m) = dzero
494  end do
495  end do
496 
497  sv%memtype = mtype_dbl2d
498  sv%dbl2d => dbl2d
499  sv%intshape => nseg_1
500  else
501  errmsg = 'IDM unimplemented. StructArray::allocate_dbl1d_type &
502  & unsupported shape "'//trim(sv%idt%shape)//'".'
503  call store_error(errmsg, terminate=.true.)
504  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_dbl_type()

subroutine structarraymodule::allocate_dbl_type ( class(structarraytype)  this,
type(structvectortype), intent(inout)  sv 
)
private
Parameters
thisStructArrayType

Definition at line 300 of file StructArray.f90.

301  class(StructArrayType) :: this !< StructArrayType
302  type(StructVectorType), intent(inout) :: sv
303  real(DP), dimension(:), pointer, contiguous :: dbl1d
304  character(len=LENVARNAME) :: varname
305  integer(I4B) :: j, nrow
306 
307  varname = sv%idt%mf6varname
308  if (len_trim(sv%varname_override) > 0) varname = sv%varname_override
309 
310  if (this%deferred_shape) then
311  ! shape not known, allocate locally
312  nrow = this%deferred_size_init
313  allocate (dbl1d(this%deferred_size_init))
314  else
315  ! shape known, allocate in managed memory
316  nrow = this%nrow
317  call mem_allocate(dbl1d, this%nrow, varname, this%mempath)
318  end if
319 
320  ! initialize
321  do j = 1, nrow
322  dbl1d(j) = dzero
323  end do
324 
325  sv%memtype = mtype_dbl
326  sv%dbl1d => dbl1d

◆ allocate_int1d_type()

subroutine structarraymodule::allocate_int1d_type ( class(structarraytype)  this,
type(structvectortype), intent(inout)  sv 
)
private
Parameters
thisStructArrayType

Definition at line 358 of file StructArray.f90.

359  use constantsmodule, only: lenmodelname
362  class(StructArrayType) :: this !< StructArrayType
363  type(StructVectorType), intent(inout) :: sv
364  integer(I4B), dimension(:, :), pointer, contiguous :: int2d
365  type(STLVecInt), pointer :: intvector
366  type(STLVecInt), pointer :: intvector_ia
367  integer(I4B), pointer :: ncelldim, exgid
368  character(len=LENMEMPATH) :: input_mempath
369  character(len=LENMODELNAME) :: mname
370  type(CharacterStringType), dimension(:), contiguous, &
371  pointer :: charstr1d
372  integer(I4B) :: nrow, n, m
373 
374  if (sv%idt%shape == 'NCELLDIM') then
375  ! if EXCHANGE set to NCELLDIM of appropriate model
376  if (this%mf6_input%component_type == 'EXG') then
377  ! set pointer to EXGID
378  call mem_setptr(exgid, 'EXGID', this%mf6_input%mempath)
379  ! set pointer to appropriate exchange model array
380  input_mempath = create_mem_path('SIM', 'NAM', idm_context)
381  if (sv%idt%tagname == 'CELLIDM1') then
382  call mem_setptr(charstr1d, 'EXGMNAMEA', input_mempath)
383  else if (sv%idt%tagname == 'CELLIDM2') then
384  call mem_setptr(charstr1d, 'EXGMNAMEB', input_mempath)
385  end if
386 
387  ! set the model name
388  mname = charstr1d(exgid)
389 
390  ! set ncelldim pointer
391  input_mempath = create_mem_path(component=mname, context=idm_context)
392  call mem_setptr(ncelldim, sv%idt%shape, input_mempath)
393  else
394  call mem_setptr(ncelldim, sv%idt%shape, this%component_mempath)
395  end if
396 
397  if (this%deferred_shape) then
398  ! shape not known, allocate locally
399  nrow = this%deferred_size_init
400  allocate (int2d(ncelldim, this%deferred_size_init))
401  else
402  ! shape known, allocate in managed memory
403  nrow = this%nrow
404  call mem_allocate(int2d, ncelldim, this%nrow, &
405  sv%idt%mf6varname, this%mempath)
406  end if
407 
408  ! initialize
409  do m = 1, nrow
410  do n = 1, ncelldim
411  int2d(n, m) = izero
412  end do
413  end do
414 
415  sv%memtype = mtype_int2d
416  sv%int2d => int2d
417  sv%intshape => ncelldim
418  else
419  ! allocate intvector object
420  allocate (intvector)
421  ! initialize STLVecInt
422  call intvector%init()
423  sv%memtype = mtype_intvec
424  sv%intvector => intvector
425  sv%size = -1
426  ! seed the CSR row-offset vector (ia(1) = 1)
427  allocate (intvector_ia)
428  call intvector_ia%init()
429  call intvector_ia%push_back(1)
430  sv%intvector_ia => intvector_ia
431  if (trim(sv%idt%shape) == ':') then
432  ! ragged column: width unknown until read_param reads to end of
433  ! record; intvector_shape stays unassociated
434  sv%intvector_ragged = .true.
435  else
436  ! set pointer to dynamic shape
437  call mem_setptr(sv%intvector_shape, sv%idt%shape, this%mempath)
438  end if
439  end if
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter lenmodelname
maximum length of the model name
Definition: Constants.f90:22
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=linelength) idm_context
Here is the call graph for this function:

◆ allocate_int_type()

subroutine structarraymodule::allocate_int_type ( class(structarraytype)  this,
type(structvectortype), intent(inout)  sv 
)
private
Parameters
thisStructArrayType

Definition at line 273 of file StructArray.f90.

274  class(StructArrayType) :: this !< StructArrayType
275  type(StructVectorType), intent(inout) :: sv
276  integer(I4B), dimension(:), pointer, contiguous :: int1d
277  integer(I4B) :: j, nrow
278 
279  if (this%deferred_shape) then
280  ! shape not known, allocate locally
281  nrow = this%deferred_size_init
282  allocate (int1d(this%deferred_size_init))
283  else
284  ! shape known, allocate in managed memory
285  nrow = this%nrow
286  call mem_allocate(int1d, this%nrow, sv%idt%mf6varname, this%mempath)
287  end if
288 
289  ! initialize vector values
290  do j = 1, nrow
291  int1d(j) = izero
292  end do
293 
294  sv%memtype = mtype_int
295  sv%int1d => int1d

◆ check_reallocate()

subroutine structarraymodule::check_reallocate ( class(structarraytype)  this)
private
Parameters
thisStructArrayType

Definition at line 806 of file StructArray.f90.

807  class(StructArrayType) :: this !< StructArrayType
808  integer(I4B) :: i, j, k, newsize
809  integer(I4B), dimension(:), pointer, contiguous :: p_int1d
810  integer(I4B), dimension(:, :), pointer, contiguous :: p_int2d
811  real(DP), dimension(:), pointer, contiguous :: p_dbl1d
812  real(DP), dimension(:, :), pointer, contiguous :: p_dbl2d
813  type(CharacterStringType), dimension(:), pointer, contiguous :: p_charstr1d
814  integer(I4B) :: reallocate_mult
815 
816  ! set growth rate
817  reallocate_mult = 2
818 
819  do j = 1, this%ncol
820  ! reallocate based on memtype
821  select case (this%struct_vectors(j)%memtype)
822  case (mtype_int)
823  ! check if more space needed
824  if (this%nrow > this%struct_vectors(j)%size) then
825  ! calculate new size
826  newsize = this%struct_vectors(j)%size * reallocate_mult
827  ! allocate new vector
828  allocate (p_int1d(newsize))
829 
830  ! copy from old to new
831  do i = 1, this%struct_vectors(j)%size
832  p_int1d(i) = this%struct_vectors(j)%int1d(i)
833  end do
834 
835  ! deallocate old vector
836  deallocate (this%struct_vectors(j)%int1d)
837 
838  ! update struct array object
839  this%struct_vectors(j)%int1d => p_int1d
840  this%struct_vectors(j)%size = newsize
841  end if
842  case (mtype_dbl)
843  if (this%nrow > this%struct_vectors(j)%size) then
844  newsize = this%struct_vectors(j)%size * reallocate_mult
845  allocate (p_dbl1d(newsize))
846 
847  do i = 1, this%struct_vectors(j)%size
848  p_dbl1d(i) = this%struct_vectors(j)%dbl1d(i)
849  end do
850 
851  deallocate (this%struct_vectors(j)%dbl1d)
852 
853  this%struct_vectors(j)%dbl1d => p_dbl1d
854  this%struct_vectors(j)%size = newsize
855  end if
856  !
857  case (mtype_str)
858  if (this%nrow > this%struct_vectors(j)%size) then
859  newsize = this%struct_vectors(j)%size * reallocate_mult
860  allocate (p_charstr1d(newsize))
861 
862  do i = 1, this%struct_vectors(j)%size
863  p_charstr1d(i) = this%struct_vectors(j)%charstr1d(i)
864  call this%struct_vectors(j)%charstr1d(i)%destroy()
865  end do
866 
867  deallocate (this%struct_vectors(j)%charstr1d)
868 
869  this%struct_vectors(j)%charstr1d => p_charstr1d
870  this%struct_vectors(j)%size = newsize
871  end if
872  case (mtype_int2d)
873  if (this%nrow > this%struct_vectors(j)%size) then
874  newsize = this%struct_vectors(j)%size * reallocate_mult
875  allocate (p_int2d(this%struct_vectors(j)%intshape, newsize))
876 
877  do i = 1, this%struct_vectors(j)%size
878  do k = 1, this%struct_vectors(j)%intshape
879  p_int2d(k, i) = this%struct_vectors(j)%int2d(k, i)
880  end do
881  end do
882 
883  deallocate (this%struct_vectors(j)%int2d)
884 
885  this%struct_vectors(j)%int2d => p_int2d
886  this%struct_vectors(j)%size = newsize
887  end if
888  case (mtype_dbl2d)
889  if (this%nrow > this%struct_vectors(j)%size) then
890  newsize = this%struct_vectors(j)%size * reallocate_mult
891  allocate (p_dbl2d(this%struct_vectors(j)%intshape, newsize))
892 
893  do i = 1, this%struct_vectors(j)%size
894  do k = 1, this%struct_vectors(j)%intshape
895  p_dbl2d(k, i) = this%struct_vectors(j)%dbl2d(k, i)
896  end do
897  end do
898 
899  deallocate (this%struct_vectors(j)%dbl2d)
900 
901  this%struct_vectors(j)%dbl2d => p_dbl2d
902  this%struct_vectors(j)%size = newsize
903  end if
904  case (mtype_undef, mtype_intvec)
905  ! metadata-only or unsupported: skip reallocation check
906  case default
907  errmsg = 'IDM unimplemented. StructArray::check_reallocate &
908  &unsupported memtype.'
909  call store_error(errmsg, terminate=.true.)
910  end select
911  end do
Here is the call graph for this function:

◆ constructstructarray()

type(structarraytype) function, pointer, public structarraymodule::constructstructarray ( type(modflowinputtype), intent(in)  mf6_input,
integer(i4b), intent(in)  ncol,
integer(i4b), intent(in)  nrow,
integer(i4b), intent(in)  blocknum,
character(len=*), intent(in)  mempath,
character(len=*), intent(in)  component_mempath,
integer(i4b), intent(in), optional  size_init 
)
Parameters
[in]ncolnumber of columns in the StructArrayType
[in]nrownumber of rows in the StructArrayType
[in]blocknumvalid block number or 0
[in]mempathmemory path for storing the vector
[in]size_initinitial deferred allocation size (default 5)
Returns
new StructArrayType

Definition at line 88 of file StructArray.f90.

90  type(ModflowInputType), intent(in) :: mf6_input
91  integer(I4B), intent(in) :: ncol !< number of columns in the StructArrayType
92  integer(I4B), intent(in) :: nrow !< number of rows in the StructArrayType
93  integer(I4B), intent(in) :: blocknum !< valid block number or 0
94  character(len=*), intent(in) :: mempath !< memory path for storing the vector
95  character(len=*), intent(in) :: component_mempath
96  integer(I4B), optional, intent(in) :: size_init !< initial deferred allocation size (default 5)
97  type(StructArrayType), pointer :: struct_array !< new StructArrayType
98 
99  ! allocate StructArrayType
100  allocate (struct_array)
101 
102  ! set description of input
103  struct_array%mf6_input = mf6_input
104 
105  ! set number of arrays
106  struct_array%ncol = ncol
107 
108  ! set rows if known or set deferred
109  struct_array%nrow = nrow
110  if (struct_array%nrow == -1) then
111  struct_array%nrow = 0
112  struct_array%deferred_shape = .true.
113  if (present(size_init)) then
114  ! ignore a non-sensible value and keep the default deferred_size_init
115  if (size_init >= 1) struct_array%deferred_size_init = size_init
116  end if
117  end if
118 
119  ! set blocknum
120  if (blocknum > 0) then
121  struct_array%blocknum = blocknum
122  else
123  struct_array%blocknum = 0
124  end if
125 
126  ! set mempath
127  struct_array%mempath = mempath
128  struct_array%component_mempath = component_mempath
129 
130  ! allocate StructVectorType objects
131  allocate (struct_array%struct_vectors(ncol))
132  allocate (struct_array%startidx(ncol))
133  allocate (struct_array%numcols(ncol))
Here is the caller graph for this function:

◆ count()

integer(i4b) function structarraymodule::count ( class(structarraytype)  this)
private
Parameters
thisStructArrayType

Definition at line 252 of file StructArray.f90.

253  class(StructArrayType) :: this !< StructArrayType
254  integer(I4B) :: count
255  count = size(this%struct_vectors)

◆ destructstructarray()

subroutine, public structarraymodule::destructstructarray ( type(structarraytype), intent(inout), pointer  struct_array)
Parameters
[in,out]struct_arrayStructArrayType to destroy

Definition at line 138 of file StructArray.f90.

139  type(StructArrayType), pointer, intent(inout) :: struct_array !< StructArrayType to destroy
140  deallocate (struct_array%struct_vectors)
141  deallocate (struct_array%startidx)
142  deallocate (struct_array%numcols)
143  deallocate (struct_array)
144  nullify (struct_array)
Here is the caller graph for this function:

◆ find_auxname_index()

integer(i4b) function, public structarraymodule::find_auxname_index ( character(len=*), intent(in)  auxname,
type(characterstringtype), dimension(:), intent(in)  auxnames,
integer(i4b), intent(in)  naux 
)

Definition at line 1054 of file StructArray.f90.

1055  character(len=*), intent(in) :: auxname
1056  type(CharacterStringType), dimension(:), intent(in) :: auxnames
1057  integer(I4B), intent(in) :: naux
1058  integer(I4B) :: jj
1059  character(len=LINELENGTH) :: thisauxname
1060  integer(I4B) :: n
1061 
1062  jj = 0
1063  do n = 1, naux
1064  thisauxname = auxnames(n)
1065  if (trim(auxname) == trim(thisauxname)) then
1066  jj = n
1067  return
1068  end if
1069  end do
Here is the caller graph for this function:

◆ get()

type(structvectortype) function, pointer structarraymodule::get ( class(structarraytype)  this,
integer(i4b), intent(in)  idx 
)
private
Parameters
thisStructArrayType

Definition at line 264 of file StructArray.f90.

265  class(StructArrayType) :: this !< StructArrayType
266  integer(I4B), intent(in) :: idx
267  type(StructVectorType), pointer :: sv
268  call set_pointer(sv, this%struct_vectors(idx))
Here is the call graph for this function:

◆ idm_input_varname()

character(len=lenvarname) function, public structarraymodule::idm_input_varname ( type(inputparamdefinitiontype), intent(in)  idt)

Definition at line 237 of file StructArray.f90.

238  type(InputParamDefinitionType), intent(in) :: idt
239  character(len=LENVARNAME) :: varname
240 
241  if (len_trim(idt%mf6varname) + len(idm_input_suffix) > lenvarname) then
242  write (errmsg, '(*(G0))') &
243  'IDM mf6internal "', trim(idt%mf6varname), '" exceeds ', &
244  lenvarname - len(idm_input_suffix), ' characters (IDM reserves ', &
245  len(idm_input_suffix), ' for the internal input-array suffix "', &
246  idm_input_suffix, '").'
247  call store_error(errmsg, terminate=.true.)
248  end if
249  varname = trim(idt%mf6varname)//idm_input_suffix
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_auxval()

logical(lgp) function, public structarraymodule::is_auxval ( type(inputparamdefinitiontype), intent(in)  idt)

Definition at line 1045 of file StructArray.f90.

1046  type(InputParamDefinitionType), intent(in) :: idt
1047  logical(LGP) :: res
1048 
1049  res = (trim(idt%tagname) == 'AUXVAL')
Here is the caller graph for this function:

◆ load_deferred_vector()

subroutine structarraymodule::load_deferred_vector ( class(structarraytype)  this,
integer(i4b), intent(in)  icol 
)
Parameters
thisStructArrayType

Definition at line 507 of file StructArray.f90.

508  use memorymanagermodule, only: get_isize
509  class(StructArrayType) :: this !< StructArrayType
510  integer(I4B), intent(in) :: icol
511  integer(I4B) :: i, j, isize
512  integer(I4B), dimension(:), pointer, contiguous :: p_int1d
513  integer(I4B), dimension(:, :), pointer, contiguous :: p_int2d
514  real(DP), dimension(:), pointer, contiguous :: p_dbl1d
515  real(DP), dimension(:, :), pointer, contiguous :: p_dbl2d
516  type(CharacterStringType), dimension(:), pointer, contiguous :: p_charstr1d
517  character(len=LENVARNAME) :: varname
518  logical(LGP) :: overwrite
519 
520  overwrite = .true.
521  if (this%struct_vectors(icol)%idt%blockname == 'SOLUTIONGROUP') &
522  overwrite = .false.
523 
524  ! set varname
525  varname = this%struct_vectors(icol)%idt%mf6varname
526  ! check if already mem managed variable
527  call get_isize(varname, this%mempath, isize)
528 
529  ! allocate and load based on memtype
530  select case (this%struct_vectors(icol)%memtype)
531  case (mtype_int)
532  if (isize > -1) then
533  ! variable exists, reallocate and append
534  call mem_setptr(p_int1d, varname, this%mempath)
535 
536  if (overwrite) then
537  ! overwrite existing array
538  if (this%nrow > isize) then
539  ! reallocate
540  call mem_reallocate(p_int1d, this%nrow, varname, this%mempath)
541  end if
542 
543  ! write new data
544  do i = 1, this%nrow
545  p_int1d(i) = this%struct_vectors(icol)%int1d(i)
546  end do
547 
548  if (isize > this%nrow) then
549  ! initialize excess space
550  do i = this%nrow + 1, isize
551  p_int1d(i) = izero
552  end do
553  end if
554  else
555  ! reallocate to new size
556  call mem_reallocate(p_int1d, this%nrow + isize, varname, this%mempath)
557 
558  ! write new data after existing
559  do i = 1, this%nrow
560  p_int1d(isize + i) = this%struct_vectors(icol)%int1d(i)
561  end do
562  end if
563  else
564  ! allocate memory manager vector
565  call mem_allocate(p_int1d, this%nrow, varname, this%mempath)
566 
567  ! load local vector to managed memory
568  do i = 1, this%nrow
569  p_int1d(i) = this%struct_vectors(icol)%int1d(i)
570  end do
571  end if
572 
573  ! deallocate local memory
574  deallocate (this%struct_vectors(icol)%int1d)
575 
576  ! update structvector
577  this%struct_vectors(icol)%int1d => p_int1d
578  this%struct_vectors(icol)%size = this%nrow
579  case (mtype_dbl)
580  if (isize > -1) then
581  call mem_setptr(p_dbl1d, varname, this%mempath)
582 
583  if (overwrite) then
584  if (this%nrow > isize) then
585  call mem_reallocate(p_dbl1d, this%nrow, varname, this%mempath)
586  end if
587 
588  do i = 1, this%nrow
589  p_dbl1d(i) = this%struct_vectors(icol)%dbl1d(i)
590  end do
591 
592  if (isize > this%nrow) then
593  do i = this%nrow + 1, isize
594  p_dbl1d(i) = dzero
595  end do
596  end if
597  else
598  call mem_reallocate(p_dbl1d, this%nrow + isize, varname, &
599  this%mempath)
600  do i = 1, this%nrow
601  p_dbl1d(isize + i) = this%struct_vectors(icol)%dbl1d(i)
602  end do
603  end if
604  else
605  call mem_allocate(p_dbl1d, this%nrow, varname, this%mempath)
606 
607  do i = 1, this%nrow
608  p_dbl1d(i) = this%struct_vectors(icol)%dbl1d(i)
609  end do
610  end if
611 
612  deallocate (this%struct_vectors(icol)%dbl1d)
613 
614  this%struct_vectors(icol)%dbl1d => p_dbl1d
615  this%struct_vectors(icol)%size = this%nrow
616  !
617  case (mtype_str)
618  if (isize > -1) then
619  call mem_setptr(p_charstr1d, varname, this%mempath)
620 
621  if (overwrite) then
622  if (this%nrow > isize) then
623  call mem_reallocate(p_charstr1d, this%struct_vectors(icol)%charlen, &
624  this%nrow, varname, this%mempath)
625  end if
626 
627  do i = 1, this%nrow
628  p_charstr1d(i) = this%struct_vectors(icol)%charstr1d(i)
629  end do
630 
631  if (isize > this%nrow) then
632  do i = this%nrow + 1, isize
633  p_charstr1d(i) = ''
634  end do
635  end if
636  else
637  call mem_reallocate(p_charstr1d, this%struct_vectors(icol)%charlen, &
638  this%nrow + isize, varname, this%mempath)
639  do i = 1, this%nrow
640  p_charstr1d(isize + i) = this%struct_vectors(icol)%charstr1d(i)
641  end do
642  end if
643  else
644  call mem_allocate(p_charstr1d, this%struct_vectors(icol)%charlen, &
645  this%nrow, varname, this%mempath)
646  do i = 1, this%nrow
647  p_charstr1d(i) = this%struct_vectors(icol)%charstr1d(i)
648  call this%struct_vectors(icol)%charstr1d(i)%destroy()
649  end do
650  end if
651 
652  deallocate (this%struct_vectors(icol)%charstr1d)
653 
654  this%struct_vectors(icol)%charstr1d => p_charstr1d
655  this%struct_vectors(icol)%size = this%nrow
656  case (mtype_intvec) ! intvector reallocate unimplemented
657  errmsg = 'StructArray::load_deferred_vector &
658  &intvector reallocate unimplemented.'
659  call store_error(errmsg, terminate=.true.)
660  case (mtype_int2d)
661  if (isize > -1) then
662  errmsg = 'StructArray::load_deferred_vector &
663  &int2d reallocate unimplemented.'
664  call store_error(errmsg, terminate=.true.)
665  else
666  call mem_allocate(p_int2d, this%struct_vectors(icol)%intshape, &
667  this%nrow, varname, this%mempath)
668  do i = 1, this%nrow
669  do j = 1, this%struct_vectors(icol)%intshape
670  p_int2d(j, i) = this%struct_vectors(icol)%int2d(j, i)
671  end do
672  end do
673  end if
674 
675  deallocate (this%struct_vectors(icol)%int2d)
676 
677  this%struct_vectors(icol)%int2d => p_int2d
678  this%struct_vectors(icol)%size = this%nrow
679  case (mtype_dbl2d)
680  if (isize > -1) then
681  errmsg = 'StructArray::load_deferred_vector &
682  &dbl2d reallocate unimplemented.'
683  call store_error(errmsg, terminate=.true.)
684  else
685  call mem_allocate(p_dbl2d, this%struct_vectors(icol)%intshape, &
686  this%nrow, varname, this%mempath)
687  do i = 1, this%nrow
688  do j = 1, this%struct_vectors(icol)%intshape
689  p_dbl2d(j, i) = this%struct_vectors(icol)%dbl2d(j, i)
690  end do
691  end do
692  end if
693 
694  deallocate (this%struct_vectors(icol)%dbl2d)
695 
696  this%struct_vectors(icol)%dbl2d => p_dbl2d
697  this%struct_vectors(icol)%size = this%nrow
698  case default
699  end select
Here is the call graph for this function:

◆ log_structarray_vars()

subroutine structarraymodule::log_structarray_vars ( class(structarraytype)  this,
integer(i4b), intent(in)  iout 
)
private
Parameters
thisStructArrayType
[in]ioutunit number for output

Definition at line 754 of file StructArray.f90.

755  class(StructArrayType) :: this !< StructArrayType
756  integer(I4B), intent(in) :: iout !< unit number for output
757  integer(I4B) :: j, nts
758  integer(I4B), dimension(:), pointer, contiguous :: int1d
759  character(len=LINELENGTH) :: ts_count_str
760 
761  ! idm variable logging
762  do j = 1, this%ncol
763  ! log based on memtype
764  select case (this%struct_vectors(j)%memtype)
765  case (mtype_int)
766  call idm_log_var(this%struct_vectors(j)%int1d, &
767  this%struct_vectors(j)%idt%tagname, &
768  this%mempath, iout)
769  case (mtype_dbl)
770  nts = this%struct_vectors(j)%ts_strlocs%count()
771  if (nts > 0) then
772  write (ts_count_str, '(i0, " time-series bound entries")') nts
773  call idm_log_var(this%struct_vectors(j)%idt%tagname, &
774  this%mempath, iout, .false., trim(ts_count_str))
775  else
776  call idm_log_var(this%struct_vectors(j)%dbl1d, &
777  this%struct_vectors(j)%idt%tagname, &
778  this%mempath, iout)
779  end if
780  case (mtype_intvec)
781  call mem_setptr(int1d, this%struct_vectors(j)%idt%mf6varname, &
782  this%mempath)
783  call idm_log_var(int1d, this%struct_vectors(j)%idt%tagname, &
784  this%mempath, iout)
785  case (mtype_int2d)
786  call idm_log_var(this%struct_vectors(j)%int2d, &
787  this%struct_vectors(j)%idt%tagname, &
788  this%mempath, iout)
789  case (mtype_dbl2d)
790  nts = this%struct_vectors(j)%ts_strlocs%count()
791  if (nts > 0) then
792  write (ts_count_str, '(i0, " time-series bound entries")') nts
793  call idm_log_var(this%struct_vectors(j)%idt%tagname, &
794  this%mempath, iout, .false., trim(ts_count_str))
795  else
796  call idm_log_var(this%struct_vectors(j)%dbl2d, &
797  this%struct_vectors(j)%idt%tagname, &
798  this%mempath, iout)
799  end if
800  end select
801  end do

◆ mem_create_metadata_vector()

subroutine structarraymodule::mem_create_metadata_vector ( class(structarraytype)  this,
integer(i4b), intent(in)  icol,
type(inputparamdefinitiontype), pointer  idt,
integer(i4b), intent(in)  body_start,
integer(i4b), intent(in)  head_nbody 
)
private

Sets idt, body_start, and head_nbody but allocates no data arrays. Used for KEYWORD indicator columns that have been consolidated into the SETTING column; these vectors serve only as dispatch-map entries.

Parameters
thisStructArrayType
[in]icolcolumn index
idtinput definition (for tagname lookup)
[in]body_startSA column index of the head's first body (0 if none)
[in]head_nbodynumber of body columns following the head

Definition at line 210 of file StructArray.f90.

211  class(StructArrayType) :: this !< StructArrayType
212  integer(I4B), intent(in) :: icol !< column index
213  type(InputParamDefinitionType), pointer :: idt !< input definition (for tagname lookup)
214  integer(I4B), intent(in) :: body_start !< SA column index of the head's first body (0 if none)
215  integer(I4B), intent(in) :: head_nbody !< number of body columns following the head
216  type(StructVectorType) :: sv
217 
218  sv%idt => idt
219  sv%icol = icol
220  sv%body_start = body_start
221  sv%head_nbody = head_nbody
222  sv%memtype = mtype_undef
223  sv%size = 0
224 
225  this%struct_vectors(icol) = sv
226  this%numcols(icol) = 0
227  if (icol == 1) then
228  this%startidx(icol) = 1
229  else
230  this%startidx(icol) = this%startidx(icol - 1) + this%numcols(icol - 1)
231  end if

◆ mem_create_vector()

subroutine structarraymodule::mem_create_vector ( class(structarraytype)  this,
integer(i4b), intent(in)  icol,
type(inputparamdefinitiontype), pointer  idt,
integer(i4b), intent(in), optional  charlen,
character(len=*), intent(in), optional  varname 
)
private
Parameters
thisStructArrayType
[in]icolcolumn to create
[in]charlenoverride character length for charstr1d
[in]varnameoverride the memory-manager name (default idtmf6varname)

Definition at line 149 of file StructArray.f90.

150  class(StructArrayType) :: this !< StructArrayType
151  integer(I4B), intent(in) :: icol !< column to create
152  type(InputParamDefinitionType), pointer :: idt
153  integer(I4B), optional, intent(in) :: charlen !< override character length for charstr1d
154  character(len=*), optional, intent(in) :: varname !< override the memory-manager name (default idt%mf6varname)
155  type(StructVectorType) :: sv
156  integer(I4B) :: numcol
157 
158  ! initialize
159  numcol = 1
160  sv%idt => idt
161  sv%icol = icol
162  if (present(charlen)) sv%charlen = charlen
163  if (present(varname)) sv%varname_override = varname
164 
165  ! set size
166  if (this%deferred_shape) then
167  sv%size = this%deferred_size_init
168  else
169  sv%size = this%nrow
170  end if
171 
172  ! allocate array memory for StructVectorType
173  select case (idt%datatype)
174  case ('INTEGER')
175  call this%allocate_int_type(sv)
176  case ('DOUBLE')
177  call this%allocate_dbl_type(sv)
178  case ('STRING', 'KEYWORD')
179  call this%allocate_charstr_type(sv)
180  case ('INTEGER1D')
181  call this%allocate_int1d_type(sv)
182  if (sv%memtype == mtype_int2d) then
183  numcol = sv%intshape
184  end if
185  case ('DOUBLE1D')
186  call this%allocate_dbl1d_type(sv)
187  numcol = sv%intshape
188  case default
189  errmsg = 'IDM unimplemented. StructArray::mem_create_vector &
190  &type='//trim(idt%datatype)
191  call store_error(errmsg, .true.)
192  end select
193 
194  ! set the object in the Struct Array
195  this%struct_vectors(icol) = sv
196  this%numcols(icol) = numcol
197  if (icol == 1) then
198  this%startidx(icol) = 1
199  else
200  this%startidx(icol) = this%startidx(icol - 1) + this%numcols(icol - 1)
201  end if
Here is the call graph for this function:

◆ memload_vectors()

subroutine structarraymodule::memload_vectors ( class(structarraytype)  this)
Parameters
thisStructArrayType

Definition at line 704 of file StructArray.f90.

705  class(StructArrayType) :: this !< StructArrayType
706  integer(I4B) :: icol, j
707  integer(I4B), dimension(:), pointer, contiguous :: p_intvector
708  integer(I4B), dimension(:), pointer, contiguous :: p_intvector_ia
709  character(len=LENVARNAME) :: varname
710 
711  do icol = 1, this%ncol
712  ! set varname
713  varname = this%struct_vectors(icol)%idt%mf6varname
714 
715  if (this%struct_vectors(icol)%memtype == mtype_intvec) then
716  ! intvectors always need to be loaded
717  ! size intvector to number of values read
718  call this%struct_vectors(icol)%intvector%shrink_to_fit()
719 
720  ! allocate memory manager vector
721  call mem_allocate(p_intvector, &
722  this%struct_vectors(icol)%intvector%size, &
723  varname, this%mempath)
724 
725  ! load local vector to managed memory
726  do j = 1, this%struct_vectors(icol)%intvector%size
727  p_intvector(j) = this%struct_vectors(icol)%intvector%at(j)
728  end do
729 
730  ! cleanup local memory
731  call this%struct_vectors(icol)%intvector%destroy()
732  deallocate (this%struct_vectors(icol)%intvector)
733  nullify (this%struct_vectors(icol)%intvector_shape)
734 
735  ! publish the parallel CSR-style row-offset vector as <TAGNAME>_IA
736  call mem_allocate(p_intvector_ia, &
737  this%struct_vectors(icol)%intvector_ia%size, &
738  trim(varname)//'_IA', this%mempath)
739  do j = 1, this%struct_vectors(icol)%intvector_ia%size
740  p_intvector_ia(j) = this%struct_vectors(icol)%intvector_ia%at(j)
741  end do
742  call this%struct_vectors(icol)%intvector_ia%destroy()
743  deallocate (this%struct_vectors(icol)%intvector_ia)
744  nullify (this%struct_vectors(icol)%intvector_ia)
745  else if (this%deferred_shape) then
746  ! load as shape wasn't known
747  call this%load_deferred_vector(icol)
748  end if
749  end do

◆ read_from_binary()

integer(i4b) function structarraymodule::read_from_binary ( class(structarraytype)  this,
integer(i4b), intent(in)  inunit,
integer(i4b), intent(in)  iout 
)
Parameters
thisStructArrayType
[in]inunitunit number for binary input
[in]ioutunit number for output

Definition at line 1299 of file StructArray.f90.

1300  class(StructArrayType) :: this !< StructArrayType
1301  integer(I4B), intent(in) :: inunit !< unit number for binary input
1302  integer(I4B), intent(in) :: iout !< unit number for output
1303  integer(I4B) :: irow, ierr
1304  integer(I4B) :: j, k
1305  integer(I4B) :: intval, numval
1306  character(len=LINELENGTH) :: fname
1307  character(len=*), parameter :: fmtlsterronly = &
1308  "('Error reading LIST from file: ',&
1309  &1x,a,1x,' on UNIT: ',I0)"
1310 
1311  ! set error and exit if deferred shape
1312  if (this%deferred_shape) then
1313  errmsg = 'IDM unimplemented. StructArray::read_from_binary deferred shape &
1314  &not supported for binary inputs.'
1315  call store_error(errmsg, terminate=.true.)
1316  end if
1317  ! initialize
1318  irow = 0
1319  ierr = 0
1320  readloop: do
1321  ! update irow index
1322  irow = irow + 1
1323  ! handle line reads by column memtype
1324  do j = 1, this%ncol
1325  select case (this%struct_vectors(j)%memtype)
1326  case (mtype_int)
1327  read (inunit, iostat=ierr) this%struct_vectors(j)%int1d(irow)
1328  case (mtype_dbl)
1329  read (inunit, iostat=ierr) this%struct_vectors(j)%dbl1d(irow)
1330  case (mtype_str)
1331  errmsg = 'List style binary inputs not supported &
1332  &for text columns, tag='// &
1333  trim(this%struct_vectors(j)%idt%tagname)//'.'
1334  call store_error(errmsg, terminate=.true.)
1335  case (mtype_intvec)
1336  if (this%struct_vectors(j)%intvector_ragged) then
1337  errmsg = 'List style binary inputs not supported for &
1338  &self-sizing (ragged) columns, tag='// &
1339  trim(this%struct_vectors(j)%idt%tagname)//'.'
1340  call store_error(errmsg, terminate=.true.)
1341  end if
1342  ! get shape for this row
1343  numval = this%struct_vectors(j)%intvector_shape(irow)
1344  ! read and store row values
1345  do k = 1, numval
1346  if (ierr == 0) then
1347  read (inunit, iostat=ierr) intval
1348  call this%struct_vectors(j)%intvector%push_back(intval)
1349  end if
1350  end do
1351  case (mtype_int2d)
1352  ! read and store row values
1353  do k = 1, this%struct_vectors(j)%intshape
1354  if (ierr == 0) then
1355  read (inunit, iostat=ierr) this%struct_vectors(j)%int2d(k, irow)
1356  end if
1357  end do
1358  case (mtype_dbl2d)
1359  do k = 1, this%struct_vectors(j)%intshape
1360  if (ierr == 0) then
1361  read (inunit, iostat=ierr) this%struct_vectors(j)%dbl2d(k, irow)
1362  end if
1363  end do
1364  end select
1365 
1366  ! handle error cases
1367  select case (ierr)
1368  case (0)
1369  ! no error
1370  case (:-1)
1371  ! End of block was encountered
1372  irow = irow - 1
1373  exit readloop
1374  case (1:)
1375  ! Error
1376  inquire (unit=inunit, name=fname)
1377  write (errmsg, fmtlsterronly) trim(adjustl(fname)), inunit
1378  call store_error(errmsg, terminate=.true.)
1379  case default
1380  end select
1381  end do
1382  if (irow == this%nrow) exit readloop
1383  end do readloop
1384 
1385  ! Stop if errors were detected
1386  !if (count_errors() > 0) then
1387  ! call store_error_unit(inunit)
1388  !end if
1389 
1390  ! if deferred shape vectors were read, load to input path
1391  call this%memload_vectors()
1392 
1393  ! log loaded variables
1394  if (iout > 0) then
1395  call this%log_structarray_vars(iout)
1396  end if
Here is the call graph for this function:

◆ read_from_parser()

integer(i4b) function structarraymodule::read_from_parser ( class(structarraytype)  this,
type(blockparsertype), intent(inout)  parser,
logical(lgp), intent(in)  timeseries,
integer(i4b), intent(in)  iout,
character(len=*), intent(in)  input_name 
)
private
Parameters
thisStructArrayType
[in,out]parserblock parser to read from
[in]ioutunit number for output
[in]input_nameinput filename for error messages

Definition at line 1074 of file StructArray.f90.

1076  class(StructArrayType) :: this !< StructArrayType
1077  type(BlockParserType), intent(inout) :: parser !< block parser to read from
1078  logical(LGP), intent(in) :: timeseries
1079  integer(I4B), intent(in) :: iout !< unit number for output
1080  character(len=*), intent(in) :: input_name !< input filename for error messages
1081  integer(I4B) :: irow, j
1082  logical(LGP) :: endOfBlock
1083 
1084  ! initialize index irow
1085  irow = 0
1086 
1087  ! reset nrow if deferred shape
1088  if (this%deferred_shape) then
1089  this%nrow = 0
1090  end if
1091 
1092  ! read entire block
1093  do
1094  ! read next line
1095  call parser%GetNextLine(endofblock)
1096  if (endofblock) then
1097  ! no more lines
1098  exit
1099  else if (this%deferred_shape) then
1100  ! shape unknown, track lines read
1101  this%nrow = this%nrow + 1
1102  ! check and update memory allocation
1103  call this%check_reallocate()
1104  end if
1105  ! update irow index
1106  irow = irow + 1
1107  if (this%deferred_shape) then
1108  else
1109  ! check allocated array size against user bound
1110  if (irow > this%nrow) then
1111  write (errmsg, '(a,i0,a)') &
1112  'Input error: line count exceeds input dimension. Expected rows=', &
1113  this%nrow, '.'
1114  call store_error(errmsg)
1115  call store_error_filename(input_name)
1116  end if
1117  end if
1118  ! handle line reads by column memtype
1119  do j = 1, this%ncol
1120  call this%read_param(parser, j, irow, timeseries, iout)
1121  end do
1122  end do
1123  ! if deferred shape vectors were read, load to input path
1124  call this%memload_vectors()
1125  ! log loaded variables
1126  if (iout > 0) then
1127  call this%log_structarray_vars(iout)
1128  end if
Here is the call graph for this function:

◆ read_from_parser_keystring()

integer(i4b) function structarraymodule::read_from_parser_keystring ( class(structarraytype)  this,
type(blockparsertype), intent(inout)  parser,
logical(lgp), intent(in)  timeseries,
integer(i4b), intent(in)  nleading,
integer(i4b), intent(in)  iout,
character(len=*), intent(in)  input_name 
)
private

Each input line contains nleading fixed columns followed by a dispatch keyword. Two dispatch modes are supported:

Simple dispatch: keyword matches a DOUBLE/STRING/INTEGER column. One value token is read from the parser into that column. All other member columns receive their sentinel for that row.

Compound dispatch: keyword matches a KEYWORD-type column (e.g. FLOWING_WELL). No parser token is read for the KEYWORD column — the dispatch keyword itself is stored. Subsequent non-KEYWORD columns (the compound sub-members, e.g. FWELEV/FWCOND/FWRLEN) are read from the parser in order until the next KEYWORD column or the end of the member columns.

No-value KEYWORD dispatch: a KEYWORD column with no sub-members immediately following stores the dispatch keyword and reads nothing further.

Parameters
thisStructArrayType
[in,out]parserblock parser to read from
[in]timeseries.true. when TS files loaded
[in]nleadingnumber of leading (fixed) columns
[in]ioutunit number for output
[in]input_nameinput filename for error messages

Definition at line 1152 of file StructArray.f90.

1154  use inputoutputmodule, only: upcase
1155  use simmodule, only: store_error_filename
1156  class(StructArrayType) :: this !< StructArrayType
1157  type(BlockParserType), intent(inout) :: parser !< block parser to read from
1158  logical(LGP), intent(in) :: timeseries !< .true. when TS files loaded
1159  integer(I4B), intent(in) :: nleading !< number of leading (fixed) columns
1160  integer(I4B), intent(in) :: iout !< unit number for output
1161  character(len=*), intent(in) :: input_name !< input filename for error messages
1162  integer(I4B) :: irow
1163  logical(LGP) :: endOfBlock, is_keyword_dispatch
1164  character(len=LINELENGTH) :: keyword
1165  integer(I4B) :: icol, found_col, last_set_col, setting_icol
1166 
1167  irow = 0
1168 
1169  ! SETTING column is always at nleading+1 when present; detect by tagname
1170  setting_icol = 0
1171  if (nleading + 1 <= this%ncol) then
1172  if (trim(this%struct_vectors(nleading + 1)%idt%tagname) == 'SETTING') then
1173  setting_icol = nleading + 1
1174  end if
1175  end if
1176 
1177  ! reset nrow if deferred shape
1178  if (this%deferred_shape) then
1179  this%nrow = 0
1180  end if
1181 
1182  do
1183  call parser%GetNextLine(endofblock)
1184  if (endofblock) exit
1185 
1186  if (this%deferred_shape) then
1187  this%nrow = this%nrow + 1
1188  call this%check_reallocate()
1189  end if
1190  irow = irow + 1
1191 
1192  ! bounds check for pre-allocated (non-deferred) arrays
1193  if (.not. this%deferred_shape) then
1194  if (irow > this%nrow) then
1195  write (errmsg, '(a,i0,a)') &
1196  'Input error: keystring row count exceeds pre-allocated maxbound=', &
1197  this%nrow, '.'
1198  call store_error(errmsg)
1199  call store_error_filename(input_name)
1200  exit
1201  end if
1202  end if
1203 
1204  ! read leading fixed columns (e.g. CELLID, IFNO)
1205  do icol = 1, nleading
1206  call this%read_param(parser, icol, irow, .false., iout)
1207  end do
1208 
1209  ! read dispatch keyword
1210  call parser%GetString(keyword)
1211  call upcase(keyword)
1212 
1213  ! match the keystring-member column, skipping SETTING and a KEYWORD
1214  ! header's own sub-members (reachable only through their header)
1215  found_col = 0
1216  icol = nleading + 1
1217  do while (icol <= this%ncol)
1218  if (icol == setting_icol) then
1219  icol = icol + 1
1220  cycle
1221  end if
1222  if (trim(this%struct_vectors(icol)%idt%tagname) == trim(keyword)) then
1223  found_col = icol
1224  exit
1225  end if
1226  if (this%struct_vectors(icol)%head_nbody > 0) then
1227  icol = icol + this%struct_vectors(icol)%head_nbody + 1
1228  else
1229  icol = icol + 1
1230  end if
1231  end do
1232 
1233  if (found_col < 1) then
1234  write (errmsg, '(a,a,a)') &
1235  'Unrecognized keystring keyword "', trim(keyword), &
1236  '" in PERIOD block.'
1237  call store_error(errmsg)
1238  call store_error_filename(input_name)
1239  cycle
1240  end if
1241 
1242  ! write mf6varname, not tagname, since SETTING is also used as
1243  ! a memory-manager name and tagname can exceed LENVARNAME
1244  if (setting_icol > 0) then
1245  this%struct_vectors(setting_icol)%charstr1d(irow) = &
1246  trim(this%struct_vectors(found_col)%idt%mf6varname)
1247  end if
1248 
1249  ! determine dispatch mode and set/read matched column(s)
1250  is_keyword_dispatch = &
1251  (this%struct_vectors(found_col)%idt%datatype == 'KEYWORD')
1252 
1253  if (is_keyword_dispatch) then
1254  ! compound/no-value KEYWORD dispatch has no data of its own;
1255  ! read its body members starting at body_start instead
1256  last_set_col = found_col
1257  if (this%struct_vectors(found_col)%body_start > 0) then
1258  do icol = this%struct_vectors(found_col)%body_start, &
1259  this%struct_vectors(found_col)%body_start + &
1260  this%struct_vectors(found_col)%head_nbody - 1
1261  if (icol > this%ncol) exit
1262  call this%read_param(parser, icol, irow, timeseries, iout)
1263  last_set_col = icol
1264  end do
1265  end if
1266  else
1267  ! Simple single-value dispatch: read one value for the matched column
1268  call this%read_param(parser, found_col, irow, timeseries, iout)
1269  last_set_col = found_col
1270  end if
1271 
1272  ! fill sentinels for all non-matched member columns
1273  do icol = nleading + 1, this%ncol
1274  ! skip SETTING column (always written above when present)
1275  if (icol == setting_icol) cycle
1276  ! skip metadata vectors (MTYPE_UNDEF, no allocated data arrays)
1277  if (this%struct_vectors(icol)%memtype == mtype_undef) cycle
1278  if (icol >= found_col .and. icol <= last_set_col) cycle
1279  select case (this%struct_vectors(icol)%memtype)
1280  case (mtype_int) ! INTEGER: use IZERO sentinel
1281  this%struct_vectors(icol)%int1d(irow) = izero
1282  case (mtype_dbl) ! DOUBLE: use DNODATA sentinel
1283  this%struct_vectors(icol)%dbl1d(irow) = dnodata
1284  case (mtype_str) ! STRING or KEYWORD: use empty string sentinel
1285  this%struct_vectors(icol)%charstr1d(irow) = ''
1286  end select
1287  end do
1288  end do
1289 
1290  call this%memload_vectors()
1291 
1292  if (iout > 0) then
1293  call this%log_structarray_vars(iout)
1294  end if
subroutine, public upcase(word)
Convert to upper case.
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
Definition: Sim.f90:204
Here is the call graph for this function:

◆ read_param()

subroutine structarraymodule::read_param ( class(structarraytype)  this,
type(blockparsertype), intent(inout)  parser,
integer(i4b), intent(in)  sv_col,
integer(i4b), intent(in)  irow,
logical(lgp), intent(in)  timeseries,
integer(i4b), intent(in)  iout 
)
private
Parameters
thisStructArrayType
[in,out]parserblock parser to read from
[in]ioutunit number for output

Definition at line 914 of file StructArray.f90.

915  use inputoutputmodule, only: upcase
916  class(StructArrayType) :: this !< StructArrayType
917  type(BlockParserType), intent(inout) :: parser !< block parser to read from
918  integer(I4B), intent(in) :: sv_col
919  integer(I4B), intent(in) :: irow
920  logical(LGP), intent(in) :: timeseries
921  integer(I4B), intent(in) :: iout !< unit number for output
922  integer(I4B) :: n, intval, numval, icol
923  character(len=LINELENGTH) :: str
924  character(len=:), allocatable :: line
925  logical(LGP) :: preserve_case, success
926 
927  select case (this%struct_vectors(sv_col)%memtype)
928  case (mtype_undef)
929  ! MTYPE_UNDEF vectors are metadata-only (KEYWORD dispatch headers).
930  write (errmsg, '(a,i0)') &
931  'IDM read_param called for MTYPE_UNDEF metadata vector at column ', sv_col
932  call store_error(errmsg, .true.)
933  case (mtype_int)
934  ! if reloadable block and first col, store blocknum
935  if (sv_col == 1 .and. this%blocknum > 0) then
936  ! store blocknum
937  this%struct_vectors(sv_col)%int1d(irow) = this%blocknum
938  else
939  ! read and store int
940  this%struct_vectors(sv_col)%int1d(irow) = parser%GetInteger()
941  end if
942  case (mtype_dbl)
943  if (this%struct_vectors(sv_col)%idt%timeseries .and. timeseries) then
944  call parser%GetString(str)
945  this%struct_vectors(sv_col)%dbl1d(irow) = &
946  this%struct_vectors(sv_col)%read_token(str, this%startidx(sv_col), &
947  1, irow)
948  else if (sv_col == this%ncol .and. &
949  .not. this%struct_vectors(sv_col)%idt%required) then
950  call parser%TryGetDouble(this%struct_vectors(sv_col)%dbl1d(irow), success)
951  if (.not. success) &
952  this%struct_vectors(sv_col)%dbl1d(irow) = dnodata
953  else
954  this%struct_vectors(sv_col)%dbl1d(irow) = parser%GetDouble()
955  end if
956  case (mtype_str)
957  if (this%struct_vectors(sv_col)%idt%shape /= '' .and. &
958  sv_col == this%ncol) then
959  ! last column with any shape: store rest of line
960  call parser%GetRemainingLine(line)
961  this%struct_vectors(sv_col)%charstr1d(irow) = line
962  deallocate (line)
963  else
964  ! read string token; a shape on a non-last column marks something
965  ! other than "rest of line", so it reads the same as unshaped
966  preserve_case = (.not. this%struct_vectors(sv_col)%idt%preserve_case)
967  call parser%GetString(str, preserve_case)
968  this%struct_vectors(sv_col)%charstr1d(irow) = str
969  end if
970  case (mtype_intvec)
971  if (this%struct_vectors(sv_col)%intvector_ragged) then
972  ! read to end of record; consumers compare the actual count read
973  ! against whatever width they independently expect
974  numval = 0
975  success = .true.
976  do while (success)
977  call parser%TryGetInteger(intval, success)
978  if (success) then
979  call this%struct_vectors(sv_col)%intvector%push_back(intval)
980  numval = numval + 1
981  end if
982  end do
983  else
984  ! get shape for this row
985  numval = this%struct_vectors(sv_col)%intvector_shape(irow)
986  ! read and store row values
987  do n = 1, numval
988  intval = parser%GetInteger()
989  call this%struct_vectors(sv_col)%intvector%push_back(intval)
990  end do
991  end if
992  ! extend the CSR-style row-offset vector with this row's running total
993  call this%struct_vectors(sv_col)%intvector_ia%push_back( &
994  this%struct_vectors(sv_col)%intvector_ia%at( &
995  this%struct_vectors(sv_col)%intvector_ia%size) + numval)
996  case (mtype_int2d)
997  ! read and store row values
998  ! handle 'NONE' keyword (SFR unconnected reaches) for backward compatibility
999  if (trim(this%mf6_input%subcomponent_type) == 'SFR' .and. &
1000  this%struct_vectors(sv_col)%idt%tagname == 'CELLID') then
1001  call parser%GetString(str)
1002  call upcase(str)
1003  if (str == 'NONE') then
1004  ! NONE means unconnected; store zeros for all dimensions
1005  do n = 1, this%struct_vectors(sv_col)%intshape
1006  this%struct_vectors(sv_col)%int2d(n, irow) = 0
1007  end do
1008  else
1009  ! first token already read as str; parse as integer and read the rest
1010  read (str, *, iostat=numval) intval
1011  if (numval /= 0) then
1012  write (errmsg, '(a,a,a)') &
1013  'CELLID must be an integer or the keyword NONE, got: ', &
1014  trim(str), '.'
1015  call store_error(errmsg, terminate=.true.)
1016  end if
1017  this%struct_vectors(sv_col)%int2d(1, irow) = intval
1018  do n = 2, this%struct_vectors(sv_col)%intshape
1019  this%struct_vectors(sv_col)%int2d(n, irow) = parser%GetInteger()
1020  end do
1021  end if
1022  else
1023  do n = 1, this%struct_vectors(sv_col)%intshape
1024  this%struct_vectors(sv_col)%int2d(n, irow) = parser%GetInteger()
1025  end do
1026  end if
1027  case (mtype_dbl2d)
1028  ! read and store row values
1029  do n = 1, this%struct_vectors(sv_col)%intshape
1030  if (this%struct_vectors(sv_col)%idt%timeseries .and. timeseries) then
1031  call parser%GetString(str)
1032  icol = this%startidx(sv_col) + n - 1
1033  this%struct_vectors(sv_col)%dbl2d(n, irow) = &
1034  this%struct_vectors(sv_col)%read_token(str, icol, n, irow)
1035  else
1036  this%struct_vectors(sv_col)%dbl2d(n, irow) = parser%GetDouble()
1037  end if
1038  end do
1039  end select
Here is the call graph for this function:

◆ set_pointer()

subroutine structarraymodule::set_pointer ( type(structvectortype), pointer  sv,
type(structvectortype), target  sv_target 
)
private

Definition at line 258 of file StructArray.f90.

259  type(StructVectorType), pointer :: sv
260  type(StructVectorType), target :: sv_target
261  sv => sv_target
Here is the caller graph for this function:

◆ ts_update()

subroutine structarraymodule::ts_update ( class(structarraytype), intent(inout)  this,
type(timeseriesmanagertype), intent(inout), pointer  tsmanager,
character(len=*), intent(in)  subcomp_name,
integer(i4b), intent(in)  iprpak,
character(len=*), intent(in)  input_name,
type(characterstringtype), dimension(:), intent(in), optional, pointer  auxname_cst,
logical(lgp), intent(in), optional  clear_strlocs,
integer(i4b), dimension(:), intent(in), optional  ifno_map 
)
private

Iterates over struct vectors that carry deferred TS tokens and registers each with the supplied tsmanager. Handles both BND (MTYPE_DBL / dbl1d) and AUX (MTYPE_DBL2D / dbl2d) columns. Pass auxname_cst only when AUX columns may carry time series.

Parameters
[in]clear_strlocsif .false. strlocs are preserved for re-registration (default .true.)
[in]ifno_mapif present, maps ts_strlocrow (PACKAGEDATA row) to its feature number, used as the TS link row address

Definition at line 1407 of file StructArray.f90.

1409  class(StructArrayType), intent(inout) :: this
1410  type(TimeSeriesManagerType), pointer, intent(inout) :: tsmanager
1411  character(len=*), intent(in) :: subcomp_name
1412  integer(I4B), intent(in) :: iprpak
1413  character(len=*), intent(in) :: input_name
1414  type(CharacterStringType), dimension(:), pointer, intent(in), &
1415  optional :: auxname_cst
1416  logical(LGP), optional, intent(in) :: clear_strlocs !< if .false. strlocs are preserved for re-registration (default .true.)
1417  integer(I4B), dimension(:), optional, intent(in) :: ifno_map !< if present, maps ts_strloc%row (PACKAGEDATA row) to its feature number, used as the TS link row address
1418  type(TSStringLocType), pointer :: ts_strloc
1419  type(TimeSeriesLinkType), pointer :: tsLink
1420  real(DP), pointer :: bndElem
1421  character(len=LENBOUNDNAME) :: boundname
1422  integer(I4B) :: m, n, iboundname, irow
1423  logical(LGP) :: do_clear
1424 
1425  do_clear = .true.
1426  if (present(clear_strlocs)) do_clear = clear_strlocs
1427 
1428  ! find BOUNDNAME column (0 = none)
1429  iboundname = 0
1430  do m = 1, this%ncol
1431  if (this%struct_vectors(m)%idt%mf6varname == 'BOUNDNAME') then
1432  iboundname = m
1433  exit
1434  end if
1435  end do
1436 
1437  do m = 1, this%ncol
1438  if (.not. this%struct_vectors(m)%idt%timeseries) cycle
1439  do n = 1, this%struct_vectors(m)%ts_strlocs%count()
1440  ts_strloc => this%struct_vectors(m)%get_ts_strloc(n)
1441  nullify (tslink)
1442  irow = ts_strloc%row
1443  if (present(ifno_map)) irow = ifno_map(ts_strloc%row)
1444  select case (this%struct_vectors(m)%memtype)
1445  case (mtype_dbl) ! dbl1d (BND)
1446  bndelem => this%struct_vectors(m)%dbl1d(ts_strloc%row)
1447  ! -- JCol=0, consistent with ts_update_indexed, so a stale
1448  ! -- PACKAGEDATA-level link is found and cleared like AUX's
1449  call read_value_or_time_series(ts_strloc%token, irow, &
1450  0, bndelem, &
1451  subcomp_name, 'BND', tsmanager, &
1452  iprpak, tslink)
1453  if (associated(tslink)) then
1454  tslink%Text = this%struct_vectors(m)%idt%mf6varname
1455  if (iboundname > 0) then
1456  boundname = &
1457  this%struct_vectors(iboundname)%charstr1d(ts_strloc%row)
1458  tslink%BndName = boundname
1459  end if
1460  end if
1461  case (mtype_dbl2d) ! dbl2d (AUX)
1462  if (.not. present(auxname_cst)) cycle
1463  if (.not. associated(auxname_cst)) cycle
1464  bndelem => this%struct_vectors(m)%dbl2d(ts_strloc%col, ts_strloc%row)
1465  ! -- JCol is the AUX array position (ts_strloc%col), not the
1466  ! -- row-schema column, so remove_existing_link can find it
1467  call read_value_or_time_series(ts_strloc%token, irow, &
1468  ts_strloc%col, bndelem, &
1469  subcomp_name, 'AUX', tsmanager, &
1470  iprpak, tslink)
1471  if (associated(tslink)) then
1472  tslink%Text = auxname_cst(ts_strloc%col)
1473  if (iboundname > 0) then
1474  boundname = &
1475  this%struct_vectors(iboundname)%charstr1d(ts_strloc%row)
1476  tslink%BndName = boundname
1477  end if
1478  end if
1479  end select
1480  end do
1481  if (do_clear) call this%struct_vectors(m)%clear()
1482  end do
1483 
1484  if (count_errors() > 0) then
1485  call store_error_filename(input_name)
1486  end if
Here is the call graph for this function:

◆ ts_update_adv()

subroutine structarraymodule::ts_update_adv ( class(structarraytype), intent(inout)  this,
integer(i4b), intent(in)  icol,
type(timeseriesmanagertype), intent(inout), pointer  tsmanager,
character(len=*), intent(in)  subcomp_name,
integer(i4b), intent(in)  iprpak,
integer(i4b), intent(in)  nrows,
integer(i4b), dimension(:), intent(in)  ifno_map,
type(characterstringtype), dimension(:), intent(in), pointer  auxname_cst,
real(dp), dimension(:, :), intent(in), pointer  featarr2d 
)
private
Parameters
[in]nrowsrows read this period
[in]ifno_mapPERIOD row -> feature index
[in]auxname_cstAUX column names, indexed 1..naux
[in]featarr2dpermanent dbl2d (AUX) target

Definition at line 1554 of file StructArray.f90.

1556  class(StructArrayType), intent(inout) :: this
1557  integer(I4B), intent(in) :: icol
1558  type(TimeSeriesManagerType), pointer, intent(inout) :: tsmanager
1559  character(len=*), intent(in) :: subcomp_name
1560  integer(I4B), intent(in) :: iprpak
1561  integer(I4B), intent(in) :: nrows !< rows read this period
1562  integer(I4B), dimension(:), intent(in) :: ifno_map !< PERIOD row -> feature index
1563  type(CharacterStringType), dimension(:), pointer, intent(in) :: auxname_cst !< AUX column names, indexed 1..naux
1564  real(DP), dimension(:, :), pointer, intent(in) :: featarr2d !< permanent dbl2d (AUX) target
1565  character(len=LENVARNAME) :: names(size(auxname_cst))
1566  integer(I4B) :: j
1567 
1568  do j = 1, size(auxname_cst)
1569  names(j) = auxname_cst(j)
1570  end do
1571  call this%ts_update_dedup(icol, tsmanager, subcomp_name, iprpak, &
1572  nrows, ifno_map, 'AUX', names, featarr2d, &
1573  this%struct_vectors(icol)%dbl2d)

◆ ts_update_dedup()

subroutine structarraymodule::ts_update_dedup ( class(structarraytype), intent(inout)  this,
integer(i4b), intent(in)  icol,
type(timeseriesmanagertype), intent(inout), pointer  tsmanager,
character(len=*), intent(in)  subcomp_name,
integer(i4b), intent(in)  iprpak,
integer(i4b), intent(in)  nrows,
integer(i4b), dimension(:), intent(in)  addr_map,
character(len=*), intent(in)  category,
character(len=lenvarname), dimension(:), intent(in)  names,
real(dp), dimension(:, :), intent(in), pointer  featarr2d,
real(dp), dimension(:, :), intent(in), pointer  raw2d 
)
private
Parameters
[in]category'AUX' or 'BND'
[in]nrowsrows read this period
[in]addr_mapPERIOD row -> feature index
[in]namessize naux
[in]featarr2d(naux, nfeatures) permanent target
[in]raw2d(naux, nrows) raw column source

Definition at line 1494 of file StructArray.f90.

1497  class(StructArrayType), intent(inout) :: this
1498  integer(I4B), intent(in) :: icol
1499  type(TimeSeriesManagerType), pointer, intent(inout) :: tsmanager
1500  character(len=*), intent(in) :: subcomp_name
1501  character(len=*), intent(in) :: category !< 'AUX' or 'BND'
1502  integer(I4B), intent(in) :: iprpak
1503  integer(I4B), intent(in) :: nrows !< rows read this period
1504  integer(I4B), dimension(:), intent(in) :: addr_map !< PERIOD row -> feature index
1505  character(len=LENVARNAME), dimension(:), intent(in) :: names !< size naux
1506  real(DP), dimension(:, :), pointer, intent(in) :: featarr2d !< (naux, nfeatures) permanent target
1507  real(DP), dimension(:, :), pointer, intent(in) :: raw2d !< (naux, nrows) raw column source
1508  type(TSStringLocType), pointer :: ts_strloc
1509  real(DP), pointer :: bndElem
1510  logical(LGP) :: found
1511  integer(I4B) :: n, j, k, nts, i, naux
1512  logical(LGP), dimension(:, :), allocatable :: handled2
1513 
1514  naux = size(names)
1515  allocate (handled2(naux, nrows))
1516  handled2 = .false.
1517 
1518  ! time-series-linked rows: resolve via their preserved token
1519  nts = this%struct_vectors(icol)%ts_strlocs%count()
1520  do k = 1, nts
1521  ts_strloc => this%struct_vectors(icol)%get_ts_strloc(k)
1522  i = addr_map(ts_strloc%row)
1523  if (i < 1 .or. i > size(featarr2d, 2)) cycle
1524  bndelem => featarr2d(ts_strloc%col, i)
1525  call read_value_or_time_series_adv( &
1526  ts_strloc%token, i, ts_strloc%col, bndelem, subcomp_name, &
1527  category, tsmanager, iprpak, trim(names(ts_strloc%col)))
1528  handled2(ts_strloc%col, ts_strloc%row) = .true.
1529  end do
1530 
1531  ! literal rows: clear any stale link, then assign; DNODATA means
1532  ! unset this row -- leave the value and any link untouched
1533  do n = 1, nrows
1534  i = addr_map(n)
1535  if (i < 1 .or. i > size(featarr2d, 2)) cycle
1536  do j = 1, naux
1537  if (handled2(j, n)) cycle
1538  if (raw2d(j, n) == dnodata) cycle
1539  found = remove_existing_link(tsmanager, i, j, subcomp_name, &
1540  category, trim(names(j)))
1541  featarr2d(j, i) = raw2d(j, n)
1542  end do
1543  end do
1544  deallocate (handled2)
1545 
1546  ! clear strlocs so a later period's parse (different row indexing)
1547  ! doesn't reprocess these against a mismatched addr_map
1548  call this%struct_vectors(icol)%clear()
Here is the call graph for this function:

◆ ts_update_indexed()

subroutine structarraymodule::ts_update_indexed ( class(structarraytype), intent(inout)  this,
integer(i4b), intent(in)  icol,
type(timeseriesmanagertype), intent(inout), pointer  tsmanager,
character(len=*), intent(in)  subcomp_name,
integer(i4b), intent(in)  iprpak,
integer(i4b), intent(in)  nrows,
integer(i4b), dimension(:), intent(in)  row_addr,
character(len=*), intent(in)  varname,
real(dp), dimension(:), intent(in), pointer, contiguous  featarr 
)
private
Parameters
[in]nrowsrows to process this period

Definition at line 1581 of file StructArray.f90.

1583  class(StructArrayType), intent(inout) :: this
1584  integer(I4B), intent(in) :: icol
1585  type(TimeSeriesManagerType), pointer, intent(inout) :: tsmanager
1586  character(len=*), intent(in) :: subcomp_name
1587  integer(I4B), intent(in) :: iprpak
1588  integer(I4B), intent(in) :: nrows !< rows to process this period
1589  integer(I4B), dimension(:), intent(in) :: row_addr
1590  character(len=*), intent(in) :: varname
1591  real(DP), dimension(:), pointer, contiguous, intent(in) :: featarr
1592  real(DP), dimension(:, :), pointer :: featarr2d, raw2d
1593  character(len=LENVARNAME) :: names(1)
1594 
1595  ! naux=1 rank remaps onto the shared 2D core; neither is a copy
1596  featarr2d(1:1, 1:size(featarr)) => featarr
1597  raw2d(1:1, 1:nrows) => this%struct_vectors(icol)%dbl1d(1:nrows)
1598  names(1) = varname
1599  call this%ts_update_dedup(icol, tsmanager, subcomp_name, iprpak, &
1600  nrows, row_addr, 'BND', names, featarr2d, &
1601  raw2d)