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  !
103  ! -- initialize base type
104  call this%StaticPkgLoadType%init(mf6_input, component_name, &
105  component_input_name, input_name)
106  !
107  end subroutine static_init
108 
109  !> @brief load routine for static loader
110  !<
111  function static_load(this, iout) result(rp_loader)
112  class(mf6filestaticpkgloadtype), intent(inout) :: this
113  integer(I4B), intent(in) :: iout
114  class(dynamicpkgloadbasetype), pointer :: rp_loader
115  class(mf6filedynamicpkgloadtype), pointer :: mf6_loader
116  !
117  ! -- initialize return pointer
118  nullify (rp_loader)
119  !
120  ! -- load model package to input context
121  if (this%iperblock > 0) then
122  !
123  ! -- allocate dynamic loader
124  allocate (mf6_loader)
125  !
126  ! -- point to nc_vars structure
127  mf6_loader%nc_vars => this%nc_vars
128  !
129  ! -- nullify nc_vars pointer so it isn't deallocated
130  nullify (this%nc_vars)
131  !
132  ! -- initialize dynamic loader
133  call mf6_loader%init(this%mf6_input, this%component_name, &
134  this%component_input_name, this%input_name, &
135  this%iperblock, iout)
136  !
137  ! -- set return pointer to base dynamic loader
138  rp_loader => mf6_loader
139  !
140  else
141  !
142  ! -- load static input
143  call input_load(this%input_name, this%mf6_input, &
144  this%component_input_name, iout, this%nc_vars)
145  end if
146  end function static_load
147 
148  !> @brief static loader destroy
149  !<
150  subroutine static_destroy(this)
151  class(mf6filestaticpkgloadtype), intent(inout) :: this
152  !
153  ! -- deallocate base type
154  call this%StaticPkgLoadType%destroy()
155  !
156  end subroutine static_destroy
157 
158  !> @brief dynamic loader init
159  !<
160  subroutine dynamic_init(this, mf6_input, component_name, component_input_name, &
161  input_name, iperblock, iout)
165  class(mf6filedynamicpkgloadtype), intent(inout) :: this
166  type(modflowinputtype), intent(in) :: mf6_input
167  character(len=*), intent(in) :: component_name
168  character(len=*), intent(in) :: component_input_name
169  character(len=*), intent(in) :: input_name
170  integer(I4B), intent(in) :: iperblock
171  integer(I4B), intent(in) :: iout
172  integer(I4B) :: inunit
173  !
174  ! -- initialize base loader
175  call this%DynamicPkgLoadType%init(mf6_input, component_name, &
176  component_input_name, input_name, &
177  iperblock, iout)
178  !
179  ! -- allocate scalars
180  call mem_allocate(this%iper, 'IPER', mf6_input%mempath)
181  call mem_allocate(this%ionper, 'IONPER', mf6_input%mempath)
182  !
183  ! -- initialize
184  this%iper = 0
185  this%ionper = 0
186  !
187  ! -- open input file
188  inunit = open_mf6file(mf6_input%pkgtype, input_name, &
189  component_input_name, iout)
190  !
191  ! -- allocate and initialize parser
192  allocate (this%parser)
193  call this%parser%Initialize(inunit, iout)
194  !
195  ! -- allocate and initialize loader
196  call this%create_loader()
197  end subroutine dynamic_init
198 
199  !> @brief define routine for dynamic loader
200  !<
201  subroutine dynamic_df(this)
202  class(mf6filedynamicpkgloadtype), intent(inout) :: this
203  !
204  ! -- invoke loader define
205  call this%rp_loader%df()
206  !
207  ! -- read first ionper
208  call this%read_ionper()
209  end subroutine dynamic_df
210 
211  !> @brief advance routine for dynamic loader
212  !<
213  subroutine dynamic_ad(this)
214  class(mf6filedynamicpkgloadtype), intent(inout) :: this
215  !
216  ! -- invoke loader advance
217  call this%rp_loader%ad()
218  end subroutine dynamic_ad
219 
220  !> @brief read and prepare routine for dynamic loader
221  !<
222  subroutine dynamic_rp(this)
223  ! -- modules
224  use tdismodule, only: kper, nper
225  ! -- dummy
226  class(mf6filedynamicpkgloadtype), intent(inout) :: this
227  ! -- local
228  !
229  ! -- check if ready to load
230  if (this%ionper /= kper) return
231  !
232  ! -- dynamic load
233  call this%rp_loader%rp(this%parser)
234  !
235  ! -- update loaded iper
236  this%iper = kper
237  !
238  ! -- read next iper
239  if (kper < nper) then
240  call this%read_ionper()
241  else
242  this%ionper = nper + 1
243  end if
244  end subroutine dynamic_rp
245 
246  !> @brief dynamic loader read ionper of next period block
247  !<
248  subroutine dynamic_read_ionper(this)
249  ! -- modules
250  use tdismodule, only: kper, nper
251  ! -- dummy
252  class(mf6filedynamicpkgloadtype), intent(inout) :: this
253  ! -- local
254  character(len=LINELENGTH) :: line
255  logical(LGP) :: isblockfound
256  integer(I4B) :: ierr
257  character(len=*), parameter :: fmtblkerr = &
258  &"('Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
259  !
260  call this%parser%GetBlock('PERIOD', isblockfound, ierr, &
261  supportopenclose=.true., &
262  blockrequired=.false.)
263  !
264  ! -- set first period block IPER
265  if (isblockfound) then
266  !
267  this%ionper = this%parser%GetInteger()
268  !
269  if (this%ionper <= this%iper) then
270  write (errmsg, '(a, i0, a, i0, a, i0, a)') &
271  'Error in stress period ', kper, &
272  '. Period numbers not increasing. Found ', this%ionper, &
273  ' but last period block was assigned ', this%iper, '.'
274  call store_error(errmsg)
275  call this%parser%StoreErrorUnit()
276  end if
277  !
278  else
279  !
280  ! -- PERIOD block not found
281  if (ierr < 0) then
282  ! -- End of file found; data applies for remainder of simulation.
283  this%ionper = nper + 1
284  else
285  ! -- Found invalid block
286  call this%parser%GetCurrentLine(line)
287  write (errmsg, fmtblkerr) adjustl(trim(line))
288  call store_error(errmsg)
289  call this%parser%StoreErrorUnit()
290  end if
291  end if
292  end subroutine dynamic_read_ionper
293 
294  !> @brief allocate a dynamic loader based on load context
295  !<
296  subroutine dynamic_create_loader(this)
300  ! -- dummy
301  class(mf6filedynamicpkgloadtype), intent(inout) :: this
302  class(boundlistinputtype), pointer :: bndlist_loader
303  class(boundgridinputtype), pointer :: bndgrid_loader
304  class(stoinputtype), pointer :: sto_loader
305  !
306  ! -- allocate and set loader
307  if (this%mf6_input%subcomponent_type == 'STO') then
308  allocate (sto_loader)
309  this%rp_loader => sto_loader
310  else if (this%readasarrays) then
311  allocate (bndgrid_loader)
312  this%rp_loader => bndgrid_loader
313  else
314  allocate (bndlist_loader)
315  this%rp_loader => bndlist_loader
316  end if
317  !
318  ! -- set nc_vars pointer
319  this%rp_loader%nc_vars => this%nc_vars
320  !
321  ! -- initialize loader
322  call this%rp_loader%ainit(this%mf6_input, &
323  this%component_name, &
324  this%component_input_name, &
325  this%input_name, &
326  this%iperblock, &
327  this%parser, &
328  this%iout)
329  end subroutine dynamic_create_loader
330 
331  !> @brief dynamic loader destroy
332  !<
333  subroutine dynamic_destroy(this)
335  class(mf6filedynamicpkgloadtype), intent(inout) :: this
336  !
337  ! -- deallocate scalars
338  call mem_deallocate(this%iper)
339  call mem_deallocate(this%ionper)
340  !
341  ! -- deallocate loader
342  nullify (this%rp_loader%nc_vars)
343  call this%rp_loader%destroy()
344  deallocate (this%rp_loader)
345  !
346  ! -- deallocate parser
347  call this%parser%clear()
348  deallocate (this%parser)
349  !
350  ! -- deallocate input context
351  call this%DynamicPkgLoadType%destroy()
352  end subroutine dynamic_destroy
353 
354  !> @brief open a model package files
355  !<
356  function open_mf6file(filetype, filename, component_fname, iout) result(inunit)
357  ! -- modules
359  ! -- dummy
360  character(len=*), intent(in) :: filetype
361  character(len=*), intent(in) :: filename
362  character(len=*), intent(in) :: component_fname
363  integer(I4B), intent(in) :: iout
364  ! -- return
365  integer(I4B) :: inunit
366  ! -- local
367  !
368  ! -- initialize
369  inunit = 0
370  !
371  if (filename /= '') then
372  !
373  ! -- get unit number and open file
374  inunit = getunit()
375  call openfile(inunit, iout, trim(adjustl(filename)), filetype, &
376  'FORMATTED', 'SEQUENTIAL', 'OLD')
377  else
378  write (errmsg, '(a,a,a)') &
379  'File unspecified, cannot load model or package &
380  &type "', trim(filetype), '".'
381  call store_error(errmsg)
382  call store_error_filename(component_fname)
383  end if
384  end function open_mf6file
385 
386 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:202
integer(i4b) function, public open_mf6file(filetype, filename, component_fname, iout)
open a model package files
Definition: IdmMf6File.f90:357
subroutine dynamic_create_loader(this)
allocate a dynamic loader based on load context
Definition: IdmMf6File.f90:297
subroutine dynamic_destroy(this)
dynamic loader destroy
Definition: IdmMf6File.f90:334
subroutine dynamic_init(this, mf6_input, component_name, component_input_name, input_name, iperblock, iout)
dynamic loader init
Definition: IdmMf6File.f90:162
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:214
subroutine static_destroy(this)
static loader destroy
Definition: IdmMf6File.f90:151
subroutine dynamic_rp(this)
read and prepare routine for dynamic loader
Definition: IdmMf6File.f90:223
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:249
class(dynamicpkgloadbasetype) function, pointer static_load(this, iout)
load routine for static loader
Definition: IdmMf6File.f90:112
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