@@ -83,7 +83,10 @@ module LoadContextModule
8383 real (DP), dimension (:, :), pointer , &
8484 contiguous :: auxvar = > null () ! < auxiliary variable array
8585 integer (I4B), dimension (:), pointer , contiguous :: mshape = > null () ! < model shape
86- character (len= LINELENGTH), dimension (:), allocatable :: params ! < in scope param tags
86+ character (len= LINELENGTH), dimension (:), allocatable :: params ! < in scope param tags; leading cols + member names for keystring/advanced
87+ integer (I4B), allocatable :: member_nsubs(:) ! < nsub per member (1..nmembers): 0=direct dispatch, N=compound keyword with N sub-members
88+ logical (LGP) :: has_setting_col = .false. ! < .true. if SETTING column is present (ADVANCED packages)
89+ type (InputParamDefinitionType), pointer :: setting_idt = > null () ! < synthetic idt for SETTING column
8790 type (ModflowInputType) :: mf6_input ! < description of input
8891 contains
8992 procedure :: init
@@ -207,7 +210,8 @@ subroutine init(this, mf6_input, blockname, named_bound)
207210 end do
208211 end if
209212
210- ! set in scope params for load
213+ ! set in scope params for load; also populates member_nsubs, has_setting_col,
214+ ! setting_idt for keystring/advanced packages
211215 call this% set_params()
212216
213217 ! allocate load context scalars
@@ -530,6 +534,8 @@ function in_scope(this, mf6_input, blockname, tagname)
530534 end if
531535 case (' NAM' )
532536 in_scope = .true.
537+ case (' SFR' )
538+ if (tagname == ' IC' ) in_scope = .true.
533539 case (' SSM' )
534540 if (tagname == ' MIXED' ) in_scope = .true.
535541 case (' SPC' , ' SPCA' )
@@ -557,12 +563,14 @@ subroutine set_params(this)
557563 use ArrayHandlersModule, only: expandarray
558564 use DefinitionSelectModule, only: get_param_definition_type, &
559565 get_aggregate_definition_type, &
560- idt_parse_rectype
566+ idt_parse_rectype, idt_default
561567 class(LoadContextType) :: this
562568 type (InputParamDefinitionType), pointer :: idt, aidt
563569 character (len= LINELENGTH), dimension (:), allocatable :: tags
564570 character (len= LINELENGTH), dimension (:), allocatable :: cols
565- integer (I4B) :: keepcnt, iparam, nparam
571+ character (len= LINELENGTH), allocatable :: member_names_work(:)
572+ integer (I4B), allocatable :: member_nsubs_work(:)
573+ integer (I4B) :: keepcnt, iparam, nparam, nmembers_work, n
566574 logical (LGP) :: keep, tag_found
567575
568576 ! initialize
@@ -614,19 +622,39 @@ subroutine set_params(this)
614622 end if
615623 end do
616624
617- ! update nparam
618- nparam = keepcnt
619-
620- ! for LIST/KEYSTRING/ADVANCED packages record the leading-column count;
621- ! this is the count of aggregate columns before the keystring placeholder
625+ ! record leading-column count before member expansion
622626 if (this% loadtype == LIST .or. &
623627 this% loadtype == KEYSTRING .or. &
624- this% loadtype == ADVANCED) this% nleading = nparam
628+ this% loadtype == ADVANCED) this% nleading = keepcnt
629+
630+ ! for keystring/advanced: append member names and store associated metadata
631+ this% has_setting_col = .false.
632+ if (this% loadtype == KEYSTRING .or. this% loadtype == ADVANCED) then
633+ call this% keystring_member_names(member_names_work, member_nsubs_work, &
634+ nmembers_work)
635+ do n = 1 , nmembers_work
636+ keepcnt = keepcnt + 1
637+ call expandarray(tags)
638+ tags(keepcnt) = trim (member_names_work(n))
639+ end do
640+ if (allocated (this% member_nsubs)) deallocate (this% member_nsubs)
641+ if (nmembers_work > 0 ) then
642+ allocate (this% member_nsubs(nmembers_work))
643+ this% member_nsubs = member_nsubs_work
644+ end if
645+ if (this% loadtype == ADVANCED) then
646+ this% has_setting_col = .true.
647+ this% setting_idt = > idt_default(this% mf6_input% component_type, &
648+ this% mf6_input% subcomponent_type, &
649+ ' PERIOD' , ' SETTING' , ' SETTING' , ' STRING' )
650+ end if
651+ end if
625652
626- ! allocate filtcols
627- allocate (this % params( nparam))
653+ ! update nparam to total (leading + members)
654+ nparam = keepcnt
628655
629- ! set filtcols
656+ ! allocate and fill params
657+ allocate (this% params(nparam))
630658 do iparam = 1 , nparam
631659 this% params(iparam) = trim (tags(iparam))
632660 end do
@@ -663,6 +691,11 @@ subroutine destroy(this)
663691 class(LoadContextType) :: this
664692
665693 if (allocated (this% named_bound)) deallocate (this% named_bound)
694+ if (allocated (this% member_nsubs)) deallocate (this% member_nsubs)
695+ if (associated (this% setting_idt)) then
696+ deallocate (this% setting_idt)
697+ nullify (this% setting_idt)
698+ end if
666699
667700 if (this% ctxtype == EXCHANGE .or. &
668701 this% ctxtype == STRESSPKG) then
@@ -784,27 +817,30 @@ function is_keystring_period(mf6_input) result(res)
784817 if (allocated (cols)) deallocate (cols)
785818 end function is_keystring_period
786819
787- ! > @brief Return keystring member column names for the PERIOD block
820+ ! > @brief Return keystring member column names and nsub counts.
788821 ! !
789- ! ! Column order follows the KEYSTRING aggregate definition token list,
790- ! ! which is the single authoritative source of order — independent of
791- ! ! the order in which individual params appear in param_dfns .
822+ ! ! Private helper called from set_params. Results are returned via
823+ ! ! output parameters; the caller is responsible for storing them.
824+ ! ! Column order follows the KEYSTRING aggregate definition token list .
792825 ! ! For each token in the aggregate:
793- ! ! - RECORD compound group: sub-members are expanded in RECORD type order
794- ! ! - direct-dispatch param: appended as-is
826+ ! ! - RECORD compound group: sub-members expanded in RECORD order;
827+ ! ! first entry (KEYWORD dispatch header) gets nsub = sub-member count,
828+ ! ! remaining entries get nsub = 0.
829+ ! ! - direct-dispatch param: appended with nsub = 0.
795830 ! <
796- subroutine keystring_member_names (this , member_names , nmembers )
831+ subroutine keystring_member_names (this , member_names , member_nsubs , nmembers )
797832 use InputOutputModule, only: upcase
798833 use ArrayHandlersModule, only: expandarray
799834 use DefinitionSelectModule, only: idt_parse_rectype, idt_datatype, &
800835 get_aggregate_definition_type
801836 class(LoadContextType) :: this
802837 character (len= LINELENGTH), allocatable , intent (out ) :: member_names(:)
838+ integer (I4B), allocatable , intent (out ) :: member_nsubs(:)
803839 integer (I4B), intent (out ) :: nmembers
804840 type (InputParamDefinitionType), pointer :: aidt, ks_aidt, idt
805841 character (len= LINELENGTH), allocatable :: rec_cols(:), ks_cols(:)
806842 character (len= LINELENGTH) :: rec_token, tagname
807- integer (I4B) :: m, n, nrec_col, nks_col
843+ integer (I4B) :: m, n, nrec_col, nks_col, nmembers_before, k
808844
809845 nmembers = 0
810846
@@ -838,13 +874,25 @@ subroutine keystring_member_names(this, member_names, nmembers)
838874 idt = > this% mf6_input% param_dfns(n)
839875 if (idt_datatype(idt) == ' RECORD' ) then
840876 ! compound group: expand sub-members in RECORD type order
877+ nmembers_before = nmembers
841878 call expand_record_submembers(this% mf6_input, idt, member_names, &
842879 nmembers)
880+ ! first added entry is the KEYWORD header; remaining are sub-members
881+ do k = nmembers_before + 1 , nmembers
882+ call expandarray(member_nsubs)
883+ if (k == nmembers_before + 1 ) then
884+ member_nsubs(k) = nmembers - nmembers_before - 1
885+ else
886+ member_nsubs(k) = 0
887+ end if
888+ end do
843889 else
844890 ! direct-dispatch param
845891 nmembers = nmembers + 1
846892 call expandarray(member_names)
847893 member_names(nmembers) = trim (this% mf6_input% param_dfns(n)% tagname)
894+ call expandarray(member_nsubs)
895+ member_nsubs(nmembers) = 0
848896 end if
849897 exit
850898 end do
0 commit comments