MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
Mf6FileList.f90
Go to the documentation of this file.
1 !> @brief This module contains the ListLoadModule
2 !!
3 !! This module contains the routines for reading period block
4 !! list based input.
5 !!
6 !<
8 
9  use kindmodule, only: i4b, dp, lgp
22 
23  implicit none
24  private
25  public :: listloadtype
26 
27  !> @brief list input loader for dynamic packages.
28  !!
29  !! Create and update input context for list based period blocks.
30  !!
31  !<
33  type(timeseriesmanagertype), pointer :: tsmanager => null()
34  type(structarraytype), pointer :: structarray => null()
35  type(loadcontexttype) :: ctx
36  type(loadmf6filetype) :: static_loader ! persistent static loader
37  logical(LGP) :: ts_active !< .true. if TS files are loaded
38  contains
39  procedure :: ainit
40  procedure :: df
41  procedure :: ts_advance
42  procedure :: reset
43  procedure :: rp
44  procedure :: destroy
45  procedure :: create_structarray
47  end type listloadtype
48 
49 contains
50 
51  subroutine ainit(this, mf6_input, component_name, component_input_name, &
52  input_name, iperblock, parser, iout)
53  use inputoutputmodule, only: getunit
57  class(listloadtype), intent(inout) :: this
58  type(modflowinputtype), intent(in) :: mf6_input
59  character(len=*), intent(in) :: component_name
60  character(len=*), intent(in) :: component_input_name
61  character(len=*), intent(in) :: input_name
62  integer(I4B), intent(in) :: iperblock
63  type(blockparsertype), pointer, intent(inout) :: parser
64  integer(I4B), intent(in) :: iout
65  type(characterstringtype), dimension(:), pointer, contiguous :: ts_fnames
66  character(len=LINELENGTH) :: fname
67  integer(I4B) :: ts6_size, n
68 
69  ! init loader
70  call this%DynamicPkgLoadType%init(mf6_input, component_name, &
71  component_input_name, input_name, &
72  iperblock, iout)
73  ! initialize scalars
74  this%ts_active = .false.
75 
76  ! create tsmanager
77  allocate (this%tsmanager)
78  call tsmanager_cr(this%tsmanager, iout)
79 
80  ! load static input (TS6_FILENAME tag sets static_loader%ts_active)
81  call this%static_loader%load(parser, mf6_input, this%nc_vars, &
82  this%input_name, iout)
83 
84  ! if TS files were declared, add them to our tsmanager now
85  if (this%static_loader%ts_active) then
86  this%ts_active = .true.
87  call get_isize('TS6_FILENAME', mf6_input%mempath, ts6_size)
88  if (ts6_size > 0) then
89  call mem_setptr(ts_fnames, 'TS6_FILENAME', mf6_input%mempath)
90  do n = 1, size(ts_fnames)
91  fname = ts_fnames(n)
92  call this%tsmanager%add_tsfile(fname, getunit())
93  end do
94  end if
95  end if
96 
97  ! initialize package input context
98  call this%ctx%init(mf6_input)
99 
100  ! set in-scope param names directly from context
101  this%param_names = this%ctx%params
102  this%nparam = size(this%ctx%params)
103  call this%ctx%check_developmode(this%input_name)
104 
105  ! construct and set up the struct array object
106  call this%create_structarray()
107 
108  ! finalize input context setup
109  call this%ctx%allocate_arrays()
110  end subroutine ainit
111 
112  subroutine df(this)
114  class(listloadtype), intent(inout) :: this
115  type(structarraytype), pointer :: sa
116  integer(I4B) :: n
117  ! define tsmanager (TDIS is now available)
118  call this%tsmanager%tsmanager_df()
119  ! link static TS strlocs; preserve for re-registration after reset()
120  do n = 1, this%static_loader%ts_sa_count()
121  sa => this%static_loader%get_ts_sa(n)
122  if (associated(sa)) then
123  call sa%ts_update(this%tsmanager, &
124  this%mf6_input%subcomponent_name, &
125  this%ctx%iprpak, this%input_name, &
126  this%ctx%auxname_cst, &
127  clear_strlocs=.false.)
128  end if
129  end do
130  end subroutine df
131 
132  subroutine ts_advance(this)
133  class(listloadtype), intent(inout) :: this
134  ! advance timeseries
135  call this%tsmanager%ad()
136  end subroutine ts_advance
137 
138  subroutine reset(this)
140  class(listloadtype), intent(inout) :: this
141  type(structarraytype), pointer :: sa
142  integer(I4B) :: n
143  ! clear TS links, unless persistent (unmentioned rows keep their link)
144  if (.not. this%ctx%is_advanced) then
145  call this%tsmanager%reset(this%mf6_input%subcomponent_name)
146  end if
147  ! re-register static TS links (strlocs preserved in df)
148  if (this%ts_active) then
149  do n = 1, this%static_loader%ts_sa_count()
150  sa => this%static_loader%get_ts_sa(n)
151  if (associated(sa)) then
152  call sa%ts_update(this%tsmanager, &
153  this%mf6_input%subcomponent_name, &
154  this%ctx%iprpak, this%input_name, &
155  this%ctx%auxname_cst, &
156  clear_strlocs=.false.)
157  end if
158  end do
159  end if
160  end subroutine reset
161 
162  subroutine rp(this, parser)
167  class(listloadtype), intent(inout) :: this
168  type(blockparsertype), pointer, intent(inout) :: parser
169  integer(I4B) :: ibinary
170  integer(I4B) :: oc_inunit
171 
172  call this%reset()
173  ibinary = read_control_record(parser, oc_inunit, this%iout)
174 
175  ! log lst file header
176  call idm_log_header(this%mf6_input%component_name, &
177  this%mf6_input%subcomponent_name, this%iout)
178 
179  if (ibinary == 1) then
180  this%ctx%nbound = &
181  this%structarray%read_from_binary(oc_inunit, this%iout)
182  call parser%terminateblock()
183  close (oc_inunit)
184  else
185  this%ctx%nbound = &
186  this%structarray%read_from_parser(parser, this%ts_active, this%iout, &
187  this%input_name)
188  end if
189 
190  ! must run before ts_update below, so AUX's ts_strlocs are claimed
191  ! by ts_update_adv first, not consumed into the transient array
192  call this%apply_persistent_settings()
193 
194  ! update ts links for all other columns
195  if (this%ts_active) then
196  call this%structarray%ts_update(this%tsmanager, &
197  this%mf6_input%subcomponent_name, &
198  this%ctx%iprpak, this%input_name, &
199  this%ctx%auxname_cst)
200  end if
201 
202  ! close logging statement
203  call idm_log_close(this%mf6_input%component_name, &
204  this%mf6_input%subcomponent_name, this%iout)
205  end subroutine rp
206 
207  subroutine destroy(this)
208  class(listloadtype), intent(inout) :: this
209  !
210  ! clean up saved static structarrays
211  call this%static_loader%cleanup()
212  !
213  ! deallocate tsmanager
214  call this%tsmanager%da()
215  deallocate (this%tsmanager)
216  nullify (this%tsmanager)
217  !
218  ! deallocate StructArray
219  call destructstructarray(this%structarray)
220  call this%ctx%destroy()
221  end subroutine destroy
222 
223  subroutine create_structarray(this)
226  class(listloadtype), intent(inout) :: this
227  type(inputparamdefinitiontype), pointer :: idt
228  real(DP), dimension(:), pointer, contiguous :: featarr
229  real(DP), dimension(:, :), pointer, contiguous :: featarr2d
230  integer(I4B), pointer :: naux
231  integer(I4B) :: icol, isize
232 
233  ! construct and set up the struct array object
234  this%structarray => constructstructarray(this%mf6_input, this%nparam, &
235  this%ctx%maxbound, 0, &
236  this%mf6_input%mempath, &
237  this%mf6_input%component_mempath)
238  ! set up struct array
239  do icol = 1, this%nparam
240  idt => get_param_definition_type(this%mf6_input%param_dfns, &
241  this%mf6_input%component_type, &
242  this%mf6_input%subcomponent_type, &
243  'PERIOD', &
244  this%param_names(icol), this%input_name)
245  ! persistent array allocated under mf6varname; raw column below
246  ! uses IDM's derived input name instead
247  if (this%ctx%is_advanced .and. idt%datatype == 'DOUBLE' .and. &
248  idt%timeseries) then
249  call get_isize(trim(idt%mf6varname), this%mf6_input%mempath, isize)
250  if (isize <= 0) then
251  call mem_allocate(featarr, this%ctx%maxbound, trim(idt%mf6varname), &
252  this%mf6_input%mempath)
253  featarr = dzero
254  end if
255  else if (this%ctx%is_advanced .and. idt%datatype == 'DOUBLE1D' .and. &
256  idt%timeseries) then
257  ! AUX is NAUX-gated, so its bare tag can't be reclaimed the
258  ! same way; it keeps its own synthetic tag
259  call get_isize(trim(idt%tagname)//'VAR', this%mf6_input%mempath, &
260  isize)
261  if (isize <= 0) then
262  call mem_setptr(naux, trim(idt%shape), this%mf6_input%mempath)
263  call mem_allocate(featarr2d, naux, this%ctx%maxbound, &
264  trim(idt%tagname)//'VAR', this%mf6_input%mempath)
265  featarr2d = dzero
266  end if
267  end if
268  ! allocate variable in memory manager
269  if (this%ctx%is_advanced .and. idt%datatype == 'DOUBLE' .and. &
270  idt%timeseries) then
271  call this%structarray%mem_create_vector(icol, idt, &
272  varname=idm_input_varname(idt))
273  else
274  call this%structarray%mem_create_vector(icol, idt)
275  end if
276  end do
277  end subroutine create_structarray
278 
279  !> @brief Resolve this period's rows for an advanced package's TS-capable
280  !! fields into their permanent, feature-indexed backing arrays.
281  !!
282  !! Every row's IFNO is validated against maxbound before use.
283  !<
284  subroutine apply_persistent_settings(this)
287  use simvariablesmodule, only: errmsg
288  class(listloadtype), intent(inout) :: this
289  type(inputparamdefinitiontype), pointer :: idt
290  integer(I4B), dimension(:), pointer, contiguous :: ifno
291  integer(I4B), dimension(:), allocatable :: row_ifno
292  real(DP), dimension(:), pointer, contiguous :: featarr
293  real(DP), dimension(:, :), pointer, contiguous :: featarr2d
294  integer(I4B), pointer :: naux
295  integer(I4B) :: icol, n, i, j, nfeatures
296 
297  if (.not. this%ctx%is_advanced) return
298 
299  ! leading column's own name/tag (e.g. IFNO), resolved from the
300  ! recarray definition rather than hardcoded
301  idt => get_param_definition_type(this%mf6_input%param_dfns, &
302  this%mf6_input%component_type, &
303  this%mf6_input%subcomponent_type, &
304  'PERIOD', this%param_names(1), &
305  this%input_name)
306  call mem_setptr(ifno, trim(idt%mf6varname), this%mf6_input%mempath)
307 
308  nfeatures = this%ctx%maxbound
309  allocate (row_ifno(this%ctx%nbound))
310  do n = 1, this%ctx%nbound
311  if (ifno(n) >= 1 .and. ifno(n) <= nfeatures) then
312  row_ifno(n) = ifno(n)
313  else
314  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,a)') &
315  trim(idt%tagname), ifno(n), 'on row', n, &
316  'must be greater than 0 and less than or equal to', nfeatures, '.'
317  call store_error(errmsg)
318  row_ifno(n) = 0
319  end if
320  end do
321 
322  if (count_errors() > 0) then
323  call store_error_filename(this%input_name)
324  end if
325 
326  do icol = 1, this%nparam
327  idt => get_param_definition_type(this%mf6_input%param_dfns, &
328  this%mf6_input%component_type, &
329  this%mf6_input%subcomponent_type, &
330  'PERIOD', &
331  this%param_names(icol), this%input_name)
332  if (idt%datatype == 'DOUBLE' .and. idt%timeseries) then
333  call mem_setptr(featarr, trim(idt%mf6varname), this%mf6_input%mempath)
334  if (this%ts_active) then
335  call this%structarray%ts_update_indexed( &
336  icol, this%tsmanager, this%mf6_input%subcomponent_name, &
337  this%ctx%iprpak, this%ctx%nbound, row_ifno, &
338  varname=trim(idt%tagname), featarr=featarr)
339  else
340  do n = 1, this%ctx%nbound
341  i = row_ifno(n)
342  if (i < 1) cycle
343  if (this%structarray%struct_vectors(icol)%dbl1d(n) == dnodata) cycle
344  featarr(i) = this%structarray%struct_vectors(icol)%dbl1d(n)
345  end do
346  end if
347  else if (idt%datatype == 'DOUBLE1D' .and. idt%timeseries) then
348  call mem_setptr(featarr2d, trim(idt%tagname)//'VAR', &
349  this%mf6_input%mempath)
350  if (this%ts_active) then
351  call this%structarray%ts_update_adv( &
352  icol, this%tsmanager, this%mf6_input%subcomponent_name, &
353  this%ctx%iprpak, this%ctx%nbound, row_ifno, &
354  auxname_cst=this%ctx%auxname_cst, featarr2d=featarr2d)
355  else
356  call mem_setptr(naux, trim(idt%shape), this%mf6_input%mempath)
357  do n = 1, this%ctx%nbound
358  i = row_ifno(n)
359  if (i < 1) cycle
360  do j = 1, naux
361  if (this%structarray%struct_vectors(icol)%dbl2d(j, n) == dnodata) &
362  cycle
363  featarr2d(j, i) = &
364  this%structarray%struct_vectors(icol)%dbl2d(j, n)
365  end do
366  end do
367  end if
368  end if
369  end do
370  deallocate (row_ifno)
371  end subroutine apply_persistent_settings
372 
373 end module listloadmodule
This module contains the AsciiInputLoadTypeModule.
This module contains block parser methods.
Definition: BlockParser.f90:7
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:95
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
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.
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
Input definition module.
integer(i4b) function, public getunit()
Get a free unit number.
This module defines variable data types.
Definition: kind.f90:8
This module contains the ListLoadModule.
Definition: Mf6FileList.f90:7
subroutine ainit(this, mf6_input, component_name, component_input_name, input_name, iperblock, parser, iout)
Definition: Mf6FileList.f90:53
subroutine apply_persistent_settings(this)
Resolve this period's rows for an advanced package's TS-capable fields into their permanent,...
subroutine ts_advance(this)
subroutine rp(this, parser)
subroutine destroy(this)
subroutine df(this)
subroutine reset(this)
subroutine create_structarray(this)
Load context for IDM generic dynamic loaders.
Definition: LoadContext.f90:10
This module contains the LoadMf6FileModule.
Definition: LoadMf6File.f90:8
integer(i4b) function, public read_control_record(parser, oc_inunit, iout)
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
This module contains the ModflowInputModule.
Definition: ModflowInput.f90:9
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
Definition: Sim.f90:204
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
This module contains the StructArrayModule.
Definition: StructArray.f90:8
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 und...
subroutine, public destructstructarray(struct_array)
destructor for a struct_array
type(structarraytype) function, pointer, public constructstructarray(mf6_input, ncol, nrow, blocknum, mempath, component_mempath, size_init)
constructor for a struct_array
Definition: StructArray.f90:90
This module contains the StructVectorModule.
Definition: StructVector.f90:7
subroutine, public read_value_or_time_series_adv(textInput, ii, jj, bndElem, pkgName, auxOrBnd, tsManager, iprpak, varName)
Call this subroutine from advanced packages to define timeseries link for a variable (varName).
subroutine, public tsmanager_cr(this, iout, removeTsLinksOnCompletion, extendTsToEndOfSimulation)
Create the tsmanager.
base abstract type for ascii source dynamic load
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
Input parameter definition. Describes an input parameter.
list input loader for dynamic packages.
Definition: Mf6FileList.f90:32
Input load context for generic dynamic loaders and StructArray based static loads....
Definition: LoadContext.f90:75
Static parser based input loader.
Definition: LoadMf6File.f90:54
derived type for storing input definition for a file
type for structured array
Definition: StructArray.f90:47
derived type for generic vector