MODFLOW 6  version 6.8.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 :: ts_advance => 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)
153  class(mf6filedynamicpkgloadtype), intent(inout) :: this
154  type(modflowinputtype), intent(in) :: mf6_input
155  character(len=*), intent(in) :: component_name
156  character(len=*), intent(in) :: component_input_name
157  character(len=*), intent(in) :: input_name
158  integer(I4B), intent(in) :: iperblock
159  integer(I4B), intent(in) :: iout
160  integer(I4B) :: inunit
161 
162  ! initialize base loader
163  call this%DynamicPkgLoadType%init(mf6_input, component_name, &
164  component_input_name, input_name, &
165  iperblock, iout)
166  ! allocate scalars
167  call mem_allocate(this%iper, 'IPER', mf6_input%mempath)
168  call mem_allocate(this%ionper, 'IONPER', mf6_input%mempath)
169 
170  ! initialize
171  this%iper = 0
172  this%ionper = 0
173 
174  ! open input file
175  inunit = open_mf6file(mf6_input%pkgtype, input_name, &
176  component_input_name, iout)
177 
178  ! allocate and initialize parser
179  allocate (this%parser)
180  call this%parser%Initialize(inunit, iout)
181 
182  ! allocate and initialize loader
183  call this%create_loader()
184  end subroutine dynamic_init
185 
186  !> @brief define routine for dynamic loader
187  !<
188  subroutine dynamic_df(this)
189  class(mf6filedynamicpkgloadtype), intent(inout) :: this
190  ! invoke loader define
191  call this%rp_loader%df()
192  ! read first ionper
193  call this%read_ionper()
194  end subroutine dynamic_df
195 
196  !> @brief advance routine for dynamic loader
197  !<
198  subroutine dynamic_ad(this)
199  class(mf6filedynamicpkgloadtype), intent(inout) :: this
200  ! invoke loader advance
201  call this%rp_loader%ts_advance()
202  end subroutine dynamic_ad
203 
204  !> @brief read and prepare routine for dynamic loader
205  !<
206  subroutine dynamic_rp(this)
207  use tdismodule, only: kper, nper
208  class(mf6filedynamicpkgloadtype), intent(inout) :: this
209 
210  ! check if ready to load
211  if (this%ionper /= kper) return
212 
213  ! dynamic load
214  call this%rp_loader%rp(this%parser)
215 
216  ! update loaded iper
217  this%iper = kper
218 
219  ! read next iper
220  if (kper < nper) then
221  call this%read_ionper()
222  else
223  this%ionper = nper + 1
224  end if
225  end subroutine dynamic_rp
226 
227  !> @brief dynamic loader read ionper of next period block
228  !<
229  subroutine dynamic_read_ionper(this)
230  use tdismodule, only: kper, nper
231  class(mf6filedynamicpkgloadtype), intent(inout) :: this
232  character(len=LINELENGTH) :: line
233  logical(LGP) :: isblockfound
234  integer(I4B) :: ierr
235  character(len=*), parameter :: fmtblkerr = &
236  &"('Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
237 
238  call this%parser%GetBlock('PERIOD', isblockfound, ierr, &
239  supportopenclose=.true., &
240  blockrequired=.false.)
241  ! set first period block IPER
242  if (isblockfound) then
243  this%ionper = this%parser%GetInteger()
244  if (this%ionper <= this%iper) then
245  write (errmsg, '(a, i0, a, i0, a, i0, a)') &
246  'Error in stress period ', kper, &
247  '. Period numbers not increasing. Found ', this%ionper, &
248  ' but last period block was assigned ', this%iper, '.'
249  call store_error(errmsg)
250  call this%parser%StoreErrorUnit()
251  end if
252  else
253  ! PERIOD block not found
254  if (ierr < 0) then
255  ! End of file found; data applies for remainder of simulation.
256  this%ionper = nper + 1
257  else
258  ! Found invalid block
259  call this%parser%GetCurrentLine(line)
260  write (errmsg, fmtblkerr) adjustl(trim(line))
261  call store_error(errmsg)
262  call this%parser%StoreErrorUnit()
263  end if
264  end if
265  end subroutine dynamic_read_ionper
266 
267  !> @brief allocate a dynamic loader based on load context
268  !<
269  subroutine dynamic_create_loader(this)
272  use listloadmodule, only: listloadtype
276  class(mf6filedynamicpkgloadtype), intent(inout) :: this
277  class(listloadtype), pointer :: list_loader
278  class(gridarrayloadtype), pointer :: arrgrid_loader
279  class(layerarrayloadtype), pointer :: arrlayer_loader
280  class(settingloadtype), pointer :: setting_loader
281  class(keystringloadtype), pointer :: keystring_loader
282  class(stoinputtype), pointer :: sto_loader
283 
284  ! allocate and set loader
285  if (this%mf6_input%subcomponent_type == 'STO') then
286  allocate (sto_loader)
287  this%rp_loader => sto_loader
288  else if (this%mf6_input%subcomponent_type == 'OC' .or. &
289  this%mf6_input%subcomponent_type == 'PRP') then
290  allocate (setting_loader)
291  this%rp_loader => setting_loader
292  else if (this%has_keystring) then
293  allocate (keystring_loader)
294  this%rp_loader => keystring_loader
295  else if (this%readasarrays) then
296  allocate (arrlayer_loader)
297  this%rp_loader => arrlayer_loader
298  else if (this%readarraygrid) then
299  allocate (arrgrid_loader)
300  this%rp_loader => arrgrid_loader
301  else
302  allocate (list_loader)
303  this%rp_loader => list_loader
304  end if
305 
306  ! set nc_vars pointer
307  this%rp_loader%nc_vars => this%nc_vars
308 
309  ! initialize loader
310  call this%rp_loader%ainit(this%mf6_input, &
311  this%component_name, &
312  this%component_input_name, &
313  this%input_name, &
314  this%iperblock, &
315  this%parser, &
316  this%iout)
317  end subroutine dynamic_create_loader
318 
319  !> @brief dynamic loader destroy
320  !<
321  subroutine dynamic_destroy(this)
323  class(mf6filedynamicpkgloadtype), intent(inout) :: this
324 
325  ! deallocate scalars
326  call mem_deallocate(this%iper)
327  call mem_deallocate(this%ionper)
328 
329  ! deallocate loader
330  nullify (this%rp_loader%nc_vars)
331  call this%rp_loader%destroy()
332  deallocate (this%rp_loader)
333 
334  ! deallocate parser
335  call this%parser%clear()
336  deallocate (this%parser)
337 
338  ! deallocate input context
339  call this%DynamicPkgLoadType%destroy()
340  end subroutine dynamic_destroy
341 
342  !> @brief open a model package files
343  !<
344  function open_mf6file(filetype, filename, component_fname, iout) result(inunit)
346  character(len=*), intent(in) :: filetype
347  character(len=*), intent(in) :: filename
348  character(len=*), intent(in) :: component_fname
349  integer(I4B), intent(in) :: iout
350  integer(I4B) :: inunit
351 
352  ! initialize
353  inunit = 0
354 
355  if (filename /= '') then
356  ! get unit number and open file
357  inunit = getunit()
358  call openfile(inunit, iout, trim(adjustl(filename)), filetype, &
359  'FORMATTED', 'SEQUENTIAL', 'OLD')
360  else
361  write (errmsg, '(a,a,a)') &
362  'File unspecified, cannot load model or package &
363  &type "', trim(filetype), '".'
364  call store_error(errmsg)
365  call store_error_filename(component_fname)
366  end if
367  end function open_mf6file
368 
369 end module idmmf6filemodule
subroutine init()
Definition: GridSorting.f90:25
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 GridArrayLoadModule.
This module contains the IdmMf6FileModule.
Definition: IdmMf6File.f90:10
subroutine dynamic_df(this)
define routine for dynamic loader
Definition: IdmMf6File.f90:189
integer(i4b) function, public open_mf6file(filetype, filename, component_fname, iout)
open a model package files
Definition: IdmMf6File.f90:345
subroutine dynamic_create_loader(this)
allocate a dynamic loader based on load context
Definition: IdmMf6File.f90:270
subroutine dynamic_destroy(this)
dynamic loader destroy
Definition: IdmMf6File.f90:322
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:199
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:207
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:230
class(dynamicpkgloadbasetype) function, pointer static_load(this, iout)
load routine for static loader
Definition: IdmMf6File.f90:110
Input definition module.
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 LayerArrayLoadModule.
This module contains the ListLoadModule.
Definition: Mf6FileList.f90:7
This module contains the LoadMf6FileModule.
Definition: LoadMf6File.f90:8
Period block keystring-based input loader.
This module contains the Mf6FileSettingLoadModule.
This module contains the Mf6FileStoInputModule.
This module contains the ModflowInputModule.
Definition: ModflowInput.f90:9
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:26
integer(i4b), pointer, public nper
number of stress period
Definition: tdis.f90:24
base abstract type for ascii source dynamic load
Ascii grid based dynamic loader type.
MF6File dynamic loader type.
Definition: IdmMf6File.f90:39
Input parameter definition. Describes an input parameter.
Base abstract type for dynamic input loader.
Base abstract type for static input loader.
Ascii array layer dynamic loader type.
list input loader for dynamic packages.
Definition: Mf6FileList.f90:31
Static parser based input loader.
Definition: LoadMf6File.f90:54
derived type for storing input definition for a file
Type describing input variables for a package in NetCDF file.
Definition: NCFileVars.f90:22