MODFLOW 6  version 6.6.0.dev0
USGS Modular Hydrologic Model
IdmMf6File.f90
Go to the documentation of this file.
1 !> @brief This module contains the IdmMf6FileModule
2 !!
3 !! This module contains high-level routines for loading
4 !! MODFLOW 6 ASCII source input. This module implements the
5 !! loader types that the IdmLoadModule creates and invokes.
6 !! It also creates and manages dynamic ASCII input loaders
7 !! for all supported types of MODFLOW 6 ASCII dynamic input.
8 !!
9 !<
11 
12  use kindmodule, only: dp, i4b, lgp
13  use simvariablesmodule, only: errmsg
14  use constantsmodule, only: linelength
21 
22  implicit none
23  private
24  public :: input_load
26  public :: open_mf6file
27 
28  !> @brief MF6File static loader type
29  !<
31  contains
32  procedure :: init => static_init
33  procedure :: load => static_load
34  procedure :: destroy => static_destroy
36 
37  !> @brief MF6File dynamic loader type
38  !<
40  type(blockparsertype), pointer :: parser !< parser for MF6File period blocks
41  integer(I4B), pointer :: iper => null() !< memory managed variable, loader iper
42  integer(I4B), pointer :: ionper => null() !< memory managed variable, next load period
43  class(asciidynamicpkgloadbasetype), pointer :: rp_loader => null()
44  contains
45  procedure :: init => dynamic_init
46  procedure :: df => dynamic_df
47  procedure :: ad => dynamic_ad
48  procedure :: rp => dynamic_rp
49  procedure :: read_ionper => dynamic_read_ionper
50  procedure :: create_loader => dynamic_create_loader
51  procedure :: destroy => dynamic_destroy
53 
54 contains
55 
56  !> @brief input load for traditional mf6 simulation static input file
57  !<
58  subroutine input_load(filename, mf6_input, component_filename, iout, nc_vars)
60  character(len=*), intent(in) :: filename
61  type(modflowinputtype), intent(in) :: mf6_input
62  character(len=*), intent(in) :: component_filename !< component (e.g. model) filename
63  integer(I4B), intent(in) :: iout !< unit number for output
64  type(ncpackagevarstype), pointer, optional, intent(in) :: nc_vars
65  type(blockparsertype), allocatable, target :: parser !< block parser
66  type(ncpackagevarstype), pointer :: netcdf_vars
67  type(loadmf6filetype) :: loader
68  integer(I4B) :: inunit
69 
70  if (present(nc_vars)) then
71  netcdf_vars => nc_vars
72  else
73  nullify (netcdf_vars)
74  end if
75 
76  ! open input file
77  inunit = open_mf6file(mf6_input%pkgtype, filename, component_filename, iout)
78 
79  ! allocate and initialize parser
80  allocate (parser)
81  call parser%Initialize(inunit, iout)
82 
83  ! invoke the load routine
84  call loader%load(parser, mf6_input, netcdf_vars, filename, iout)
85 
86  ! clear parser file handles
87  call parser%clear()
88 
89  ! cleanup
90  deallocate (parser)
91  end subroutine input_load
92 
93  !> @brief static loader init
94  !<
95  subroutine static_init(this, mf6_input, component_name, component_input_name, &
96  input_name)
97  class(mf6filestaticpkgloadtype), intent(inout) :: this
98  type(modflowinputtype), intent(in) :: mf6_input
99  character(len=*), intent(in) :: component_name
100  character(len=*), intent(in) :: component_input_name
101  character(len=*), intent(in) :: input_name
102  ! initialize base type
103  call this%StaticPkgLoadType%init(mf6_input, component_name, &
104  component_input_name, input_name)
105  end subroutine static_init
106 
107  !> @brief load routine for static loader
108  !<
109  function static_load(this, iout) result(rp_loader)
110  class(mf6filestaticpkgloadtype), intent(inout) :: this
111  integer(I4B), intent(in) :: iout
112  class(dynamicpkgloadbasetype), pointer :: rp_loader
113  class(mf6filedynamicpkgloadtype), pointer :: mf6_loader
114 
115  ! initialize return pointer
116  nullify (rp_loader)
117 
118  ! load model package to input context
119  if (this%iperblock > 0) then
120  ! allocate dynamic loader
121  allocate (mf6_loader)
122  ! point to nc_vars structure
123  mf6_loader%nc_vars => this%nc_vars
124  ! nullify nc_vars pointer so it isn't deallocated
125  nullify (this%nc_vars)
126  ! initialize dynamic loader
127  call mf6_loader%init(this%mf6_input, this%component_name, &
128  this%component_input_name, this%input_name, &
129  this%iperblock, iout)
130  ! set return pointer to base dynamic loader
131  rp_loader => mf6_loader
132  else
133  ! load static input
134  call input_load(this%input_name, this%mf6_input, &
135  this%component_input_name, iout, this%nc_vars)
136  end if
137  end function static_load
138 
139  !> @brief static loader destroy
140  !<
141  subroutine static_destroy(this)
142  class(mf6filestaticpkgloadtype), intent(inout) :: this
143  ! deallocate base type
144  call this%StaticPkgLoadType%destroy()
145  end subroutine static_destroy
146 
147  !> @brief dynamic loader init
148  !<
149  subroutine dynamic_init(this, mf6_input, component_name, component_input_name, &
150  input_name, iperblock, iout)
154  class(mf6filedynamicpkgloadtype), intent(inout) :: this
155  type(modflowinputtype), intent(in) :: mf6_input
156  character(len=*), intent(in) :: component_name
157  character(len=*), intent(in) :: component_input_name
158  character(len=*), intent(in) :: input_name
159  integer(I4B), intent(in) :: iperblock
160  integer(I4B), intent(in) :: iout
161  integer(I4B) :: inunit
162 
163  ! initialize base loader
164  call this%DynamicPkgLoadType%init(mf6_input, component_name, &
165  component_input_name, input_name, &
166  iperblock, iout)
167  ! allocate scalars
168  call mem_allocate(this%iper, 'IPER', mf6_input%mempath)
169  call mem_allocate(this%ionper, 'IONPER', mf6_input%mempath)
170 
171  ! initialize
172  this%iper = 0
173  this%ionper = 0
174 
175  ! open input file
176  inunit = open_mf6file(mf6_input%pkgtype, input_name, &
177  component_input_name, iout)
178 
179  ! allocate and initialize parser
180  allocate (this%parser)
181  call this%parser%Initialize(inunit, iout)
182 
183  ! allocate and initialize loader
184  call this%create_loader()
185  end subroutine dynamic_init
186 
187  !> @brief define routine for dynamic loader
188  !<
189  subroutine dynamic_df(this)
190  class(mf6filedynamicpkgloadtype), intent(inout) :: this
191  ! invoke loader define
192  call this%rp_loader%df()
193  ! read first ionper
194  call this%read_ionper()
195  end subroutine dynamic_df
196 
197  !> @brief advance routine for dynamic loader
198  !<
199  subroutine dynamic_ad(this)
200  class(mf6filedynamicpkgloadtype), intent(inout) :: this
201  ! invoke loader advance
202  call this%rp_loader%ad()
203  end subroutine dynamic_ad
204 
205  !> @brief read and prepare routine for dynamic loader
206  !<
207  subroutine dynamic_rp(this)
208  use tdismodule, only: kper, nper
209  class(mf6filedynamicpkgloadtype), intent(inout) :: this
210 
211  ! check if ready to load
212  if (this%ionper /= kper) return
213 
214  ! dynamic load
215  call this%rp_loader%rp(this%parser)
216 
217  ! update loaded iper
218  this%iper = kper
219 
220  ! read next iper
221  if (kper < nper) then
222  call this%read_ionper()
223  else
224  this%ionper = nper + 1
225  end if
226  end subroutine dynamic_rp
227 
228  !> @brief dynamic loader read ionper of next period block
229  !<
230  subroutine dynamic_read_ionper(this)
231  use tdismodule, only: kper, nper
232  class(mf6filedynamicpkgloadtype), intent(inout) :: this
233  character(len=LINELENGTH) :: line
234  logical(LGP) :: isblockfound
235  integer(I4B) :: ierr
236  character(len=*), parameter :: fmtblkerr = &
237  &"('Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
238 
239  call this%parser%GetBlock('PERIOD', isblockfound, ierr, &
240  supportopenclose=.true., &
241  blockrequired=.false.)
242  ! set first period block IPER
243  if (isblockfound) then
244  this%ionper = this%parser%GetInteger()
245  if (this%ionper <= this%iper) then
246  write (errmsg, '(a, i0, a, i0, a, i0, a)') &
247  'Error in stress period ', kper, &
248  '. Period numbers not increasing. Found ', this%ionper, &
249  ' but last period block was assigned ', this%iper, '.'
250  call store_error(errmsg)
251  call this%parser%StoreErrorUnit()
252  end if
253  else
254  ! PERIOD block not found
255  if (ierr < 0) then
256  ! End of file found; data applies for remainder of simulation.
257  this%ionper = nper + 1
258  else
259  ! Found invalid block
260  call this%parser%GetCurrentLine(line)
261  write (errmsg, fmtblkerr) adjustl(trim(line))
262  call store_error(errmsg)
263  call this%parser%StoreErrorUnit()
264  end if
265  end if
266  end subroutine dynamic_read_ionper
267 
268  !> @brief allocate a dynamic loader based on load context
269  !<
270  subroutine dynamic_create_loader(this)
274  class(mf6filedynamicpkgloadtype), intent(inout) :: this
275  class(boundlistinputtype), pointer :: bndlist_loader
276  class(boundgridinputtype), pointer :: bndgrid_loader
277  class(stoinputtype), pointer :: sto_loader
278 
279  ! allocate and set loader
280  if (this%mf6_input%subcomponent_type == 'STO') then
281  allocate (sto_loader)
282  this%rp_loader => sto_loader
283  else if (this%readasarrays) then
284  allocate (bndgrid_loader)
285  this%rp_loader => bndgrid_loader
286  else
287  allocate (bndlist_loader)
288  this%rp_loader => bndlist_loader
289  end if
290 
291  ! set nc_vars pointer
292  this%rp_loader%nc_vars => this%nc_vars
293 
294  ! initialize loader
295  call this%rp_loader%ainit(this%mf6_input, &
296  this%component_name, &
297  this%component_input_name, &
298  this%input_name, &
299  this%iperblock, &
300  this%parser, &
301  this%iout)
302  end subroutine dynamic_create_loader
303 
304  !> @brief dynamic loader destroy
305  !<
306  subroutine dynamic_destroy(this)
308  class(mf6filedynamicpkgloadtype), intent(inout) :: this
309 
310  ! deallocate scalars
311  call mem_deallocate(this%iper)
312  call mem_deallocate(this%ionper)
313 
314  ! deallocate loader
315  nullify (this%rp_loader%nc_vars)
316  call this%rp_loader%destroy()
317  deallocate (this%rp_loader)
318 
319  ! deallocate parser
320  call this%parser%clear()
321  deallocate (this%parser)
322 
323  ! deallocate input context
324  call this%DynamicPkgLoadType%destroy()
325  end subroutine dynamic_destroy
326 
327  !> @brief open a model package files
328  !<
329  function open_mf6file(filetype, filename, component_fname, iout) result(inunit)
331  character(len=*), intent(in) :: filetype
332  character(len=*), intent(in) :: filename
333  character(len=*), intent(in) :: component_fname
334  integer(I4B), intent(in) :: iout
335  integer(I4B) :: inunit
336 
337  ! initialize
338  inunit = 0
339 
340  if (filename /= '') then
341  ! get unit number and open file
342  inunit = getunit()
343  call openfile(inunit, iout, trim(adjustl(filename)), filetype, &
344  'FORMATTED', 'SEQUENTIAL', 'OLD')
345  else
346  write (errmsg, '(a,a,a)') &
347  'File unspecified, cannot load model or package &
348  &type "', trim(filetype), '".'
349  call store_error(errmsg)
350  call store_error_filename(component_fname)
351  end if
352  end function open_mf6file
353 
354 end module idmmf6filemodule
subroutine init()
Definition: GridSorting.f90:24
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
This module contains the DefinitionSelectModule.
type(inputparamdefinitiontype) function, pointer, public get_param_definition_type(input_definition_types, component_type, subcomponent_type, blockname, tagname, filename)
Return parameter definition.
This module contains the IdmMf6FileModule.
Definition: IdmMf6File.f90:10
subroutine dynamic_df(this)
define routine for dynamic loader
Definition: IdmMf6File.f90:190
integer(i4b) function, public open_mf6file(filetype, filename, component_fname, iout)
open a model package files
Definition: IdmMf6File.f90:330
subroutine dynamic_create_loader(this)
allocate a dynamic loader based on load context
Definition: IdmMf6File.f90:271
subroutine dynamic_destroy(this)
dynamic loader destroy
Definition: IdmMf6File.f90:307
subroutine dynamic_init(this, mf6_input, component_name, component_input_name, input_name, iperblock, iout)
dynamic loader init
Definition: IdmMf6File.f90:151
subroutine, public input_load(filename, mf6_input, component_filename, iout, nc_vars)
input load for traditional mf6 simulation static input file
Definition: IdmMf6File.f90:59
subroutine dynamic_ad(this)
advance routine for dynamic loader
Definition: IdmMf6File.f90:200
subroutine static_destroy(this)
static loader destroy
Definition: IdmMf6File.f90:142
subroutine dynamic_rp(this)
read and prepare routine for dynamic loader
Definition: IdmMf6File.f90:208
subroutine static_init(this, mf6_input, component_name, component_input_name, input_name)
static loader init
Definition: IdmMf6File.f90:97
subroutine dynamic_read_ionper(this)
dynamic loader read ionper of next period block
Definition: IdmMf6File.f90:231
class(dynamicpkgloadbasetype) function, pointer static_load(this, iout)
load routine for static loader
Definition: IdmMf6File.f90:110
This module contains the InputDefinitionModule.
This module contains the InputLoadTypeModule.
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
This module defines variable data types.
Definition: kind.f90:8
This module contains the LoadMf6FileModule.
Definition: LoadMf6File.f90:8
This module contains the Mf6FileGridInputModule.
This module contains the Mf6FileListInputModule.
This module contains the Mf6FileStoInputModule.
This module contains the ModflowInputModule.
Definition: ModflowInput.f90:9
type(modflowinputtype) function, public getmodflowinput(pkgtype, component_type, subcomponent_type, component_name, subcomponent_name, filename)
function to return ModflowInputType
This module contains the NCFileVarsModule.
Definition: NCFileVars.f90:7
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
Definition: Sim.f90:203
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23
integer(i4b), pointer, public nper
number of stress period
Definition: tdis.f90:21
base abstract type for ascii source dynamic load
MF6File dynamic loader type.
Definition: IdmMf6File.f90:39
Base abstract type for dynamic input loader.
Base abstract type for static input loader.
Static parser based input loader.
Definition: LoadMf6File.f90:48
Ascii grid based dynamic loader type.
derived type for storing input definition for a file
Type describing input variables for a package in NetCDF file.
Definition: NCFileVars.f90:22