MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
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
20 
21  implicit none
22  private
23  public :: input_load
25  public :: open_mf6file
26 
27  !> @brief MF6File static loader type
28  !<
30  contains
31  procedure :: init => static_init
32  procedure :: load => static_load
33  procedure :: destroy => static_destroy
35 
36  !> @brief MF6File dynamic loader type
37  !<
39  type(blockparsertype), pointer :: parser !< parser for MF6File period blocks
40  integer(I4B), pointer :: iper => null() !< memory managed variable, loader iper
41  integer(I4B), pointer :: ionper => null() !< memory managed variable, next load period
42  class(asciidynamicpkgloadbasetype), pointer :: rp_loader => null()
43  contains
44  procedure :: init => dynamic_init
45  procedure :: df => dynamic_df
46  procedure :: ad => dynamic_ad
47  procedure :: rp => dynamic_rp
48  procedure :: read_ionper => dynamic_read_ionper
49  procedure :: create_loader => dynamic_create_loader
50  procedure :: destroy => dynamic_destroy
52 
53 contains
54 
55  !> @brief input load for traditional mf6 simulation static input file
56  !<
57  subroutine input_load(filename, mf6_input, component_filename, iout)
59  character(len=*), intent(in) :: filename
60  type(modflowinputtype), intent(in) :: mf6_input
61  character(len=*), intent(in) :: component_filename !< component (e.g. model) filename
62  integer(I4B), intent(in) :: iout !< unit number for output
63  type(blockparsertype), allocatable, target :: parser !< block parser
64  type(loadmf6filetype) :: loader
65  integer(I4B) :: inunit
66  !
67  ! -- open input file
68  inunit = open_mf6file(mf6_input%pkgtype, filename, component_filename, iout)
69  !
70  ! -- allocate and initialize parser
71  allocate (parser)
72  call parser%Initialize(inunit, iout)
73  !
74  ! -- invoke the load routine
75  call loader%load(parser, mf6_input, filename, iout)
76  !
77  ! -- clear parser file handles
78  call parser%clear()
79  !
80  ! -- cleanup
81  deallocate (parser)
82  !
83  ! -- return
84  return
85  end subroutine input_load
86 
87  !> @brief static loader init
88  !<
89  subroutine static_init(this, mf6_input, component_name, component_input_name, &
90  input_name)
91  class(mf6filestaticpkgloadtype), intent(inout) :: this
92  type(modflowinputtype), intent(in) :: mf6_input
93  character(len=*), intent(in) :: component_name
94  character(len=*), intent(in) :: component_input_name
95  character(len=*), intent(in) :: input_name
96  !
97  ! -- initialize base type
98  call this%StaticPkgLoadType%init(mf6_input, component_name, &
99  component_input_name, input_name)
100  !
101  end subroutine static_init
102 
103  !> @brief load routine for static loader
104  !<
105  function static_load(this, iout) result(rp_loader)
106  class(mf6filestaticpkgloadtype), intent(inout) :: this
107  integer(I4B), intent(in) :: iout
108  class(dynamicpkgloadbasetype), pointer :: rp_loader
109  class(mf6filedynamicpkgloadtype), pointer :: mf6_loader
110  !
111  ! -- initialize return pointer
112  nullify (rp_loader)
113  !
114  ! -- load model package to input context
115  if (this%iperblock > 0) then
116  !
117  ! -- allocate dynamic loader
118  allocate (mf6_loader)
119  !
120  ! -- initialize dynamic loader
121  call mf6_loader%init(this%mf6_input, this%component_name, &
122  this%component_input_name, this%input_name, &
123  this%iperblock, iout)
124  !
125  ! -- set return pointer to base dynamic loader
126  rp_loader => mf6_loader
127  !
128  else
129  !
130  ! -- load static input
131  call input_load(this%input_name, this%mf6_input, &
132  this%component_input_name, iout)
133  end if
134  !
135  ! -- return
136  return
137  end function static_load
138 
139  !> @brief static loader destroy
140  !<
141  subroutine static_destroy(this)
142  class(mf6filestaticpkgloadtype), intent(inout) :: this
143  !
144  ! -- deallocate base type
145  call this%StaticPkgLoadType%destroy()
146  !
147  end subroutine static_destroy
148 
149  !> @brief dynamic loader init
150  !<
151  subroutine dynamic_init(this, mf6_input, component_name, component_input_name, &
152  input_name, iperblock, iout)
156  class(mf6filedynamicpkgloadtype), intent(inout) :: this
157  type(modflowinputtype), intent(in) :: mf6_input
158  character(len=*), intent(in) :: component_name
159  character(len=*), intent(in) :: component_input_name
160  character(len=*), intent(in) :: input_name
161  integer(I4B), intent(in) :: iperblock
162  integer(I4B), intent(in) :: iout
163  integer(I4B) :: inunit
164  !
165  ! -- initialize base loader
166  call this%DynamicPkgLoadType%init(mf6_input, component_name, &
167  component_input_name, input_name, &
168  iperblock, iout)
169  !
170  ! -- allocate scalars
171  call mem_allocate(this%iper, 'IPER', mf6_input%mempath)
172  call mem_allocate(this%ionper, 'IONPER', mf6_input%mempath)
173  !
174  ! -- initialize
175  this%iper = 0
176  this%ionper = 0
177  !
178  ! -- open input file
179  inunit = open_mf6file(mf6_input%pkgtype, input_name, &
180  component_input_name, iout)
181  !
182  ! -- allocate and initialize parser
183  allocate (this%parser)
184  call this%parser%Initialize(inunit, iout)
185  !
186  ! -- allocate and initialize loader
187  call this%create_loader()
188  !
189  ! -- return
190  return
191  end subroutine dynamic_init
192 
193  !> @brief define routine for dynamic loader
194  !<
195  subroutine dynamic_df(this)
196  class(mf6filedynamicpkgloadtype), intent(inout) :: this
197  !
198  ! -- invoke loader define
199  call this%rp_loader%df()
200  !
201  ! -- read first ionper
202  call this%read_ionper()
203  !
204  ! -- return
205  return
206  end subroutine dynamic_df
207 
208  !> @brief advance routine for dynamic loader
209  !<
210  subroutine dynamic_ad(this)
211  class(mf6filedynamicpkgloadtype), intent(inout) :: this
212  !
213  ! -- invoke loader advance
214  call this%rp_loader%ad()
215  !
216  ! -- return
217  return
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  !
245  ! -- return
246  return
247  end subroutine dynamic_rp
248 
249  !> @brief dynamic loader read ionper of next period block
250  !<
251  subroutine dynamic_read_ionper(this)
252  ! -- modules
253  use tdismodule, only: kper, nper
254  ! -- dummy
255  class(mf6filedynamicpkgloadtype), intent(inout) :: this
256  ! -- local
257  character(len=LINELENGTH) :: line
258  logical(LGP) :: isblockfound
259  integer(I4B) :: ierr
260  character(len=*), parameter :: fmtblkerr = &
261  &"('Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
262  !
263  call this%parser%GetBlock('PERIOD', isblockfound, ierr, &
264  supportopenclose=.true., &
265  blockrequired=.false.)
266  !
267  ! -- set first period block IPER
268  if (isblockfound) then
269  !
270  this%ionper = this%parser%GetInteger()
271  !
272  if (this%ionper <= this%iper) then
273  write (errmsg, '(a, i0, a, i0, a, i0, a)') &
274  'Error in stress period ', kper, &
275  '. Period numbers not increasing. Found ', this%ionper, &
276  ' but last period block was assigned ', this%iper, '.'
277  call store_error(errmsg)
278  call this%parser%StoreErrorUnit()
279  end if
280  !
281  else
282  !
283  ! -- PERIOD block not found
284  if (ierr < 0) then
285  ! -- End of file found; data applies for remainder of simulation.
286  this%ionper = nper + 1
287  else
288  ! -- Found invalid block
289  call this%parser%GetCurrentLine(line)
290  write (errmsg, fmtblkerr) adjustl(trim(line))
291  call store_error(errmsg)
292  call this%parser%StoreErrorUnit()
293  end if
294  end if
295  !
296  ! -- return
297  return
298  end subroutine dynamic_read_ionper
299 
300  !> @brief allocate a dynamic loader based on load context
301  !<
302  subroutine dynamic_create_loader(this)
305  ! -- dummy
306  class(mf6filedynamicpkgloadtype), intent(inout) :: this
307  class(boundlistinputtype), pointer :: bndlist_loader
308  class(boundgridinputtype), pointer :: bndgrid_loader
309  !
310  ! -- allocate and set loader
311  if (this%readasarrays) then
312  allocate (bndgrid_loader)
313  this%rp_loader => bndgrid_loader
314  else
315  allocate (bndlist_loader)
316  this%rp_loader => bndlist_loader
317  end if
318  !
319  ! -- initialize loader
320  call this%rp_loader%ainit(this%mf6_input, &
321  this%component_name, &
322  this%component_input_name, &
323  this%input_name, &
324  this%iperblock, &
325  this%parser, &
326  this%iout)
327  !
328  ! -- return
329  return
330  end subroutine dynamic_create_loader
331 
332  !> @brief dynamic loader destroy
333  !<
334  subroutine dynamic_destroy(this)
336  class(mf6filedynamicpkgloadtype), intent(inout) :: this
337  !
338  ! -- deallocate scalars
339  call mem_deallocate(this%iper)
340  call mem_deallocate(this%ionper)
341  !
342  ! -- deallocate loader
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  !
353  ! -- return
354  return
355  end subroutine dynamic_destroy
356 
357  !> @brief open a model package files
358  !<
359  function open_mf6file(filetype, filename, component_fname, iout) result(inunit)
360  ! -- modules
362  ! -- dummy
363  character(len=*), intent(in) :: filetype
364  character(len=*), intent(in) :: filename
365  character(len=*), intent(in) :: component_fname
366  integer(I4B), intent(in) :: iout
367  ! -- return
368  integer(I4B) :: inunit
369  ! -- local
370  !
371  ! -- initialize
372  inunit = 0
373  !
374  if (filename /= '') then
375  !
376  ! -- get unit number and open file
377  inunit = getunit()
378  call openfile(inunit, iout, trim(adjustl(filename)), filetype, &
379  'FORMATTED', 'SEQUENTIAL', 'OLD')
380  else
381  write (errmsg, '(a,a,a)') &
382  'File unspecified, cannot load model or package &
383  &type "', trim(filetype), '".'
384  call store_error(errmsg)
385  call store_error_filename(component_fname)
386  end if
387  !
388  ! -- return
389  return
390  end function open_mf6file
391 
392 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:44
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:196
subroutine, public input_load(filename, mf6_input, component_filename, iout)
input load for traditional mf6 simulation static input file
Definition: IdmMf6File.f90:58
integer(i4b) function, public open_mf6file(filetype, filename, component_fname, iout)
open a model package files
Definition: IdmMf6File.f90:360
subroutine dynamic_create_loader(this)
allocate a dynamic loader based on load context
Definition: IdmMf6File.f90:303
subroutine dynamic_destroy(this)
dynamic loader destroy
Definition: IdmMf6File.f90:335
subroutine dynamic_init(this, mf6_input, component_name, component_input_name, input_name, iperblock, iout)
dynamic loader init
Definition: IdmMf6File.f90:153
subroutine dynamic_ad(this)
advance routine for dynamic loader
Definition: IdmMf6File.f90:211
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:223
subroutine static_init(this, mf6_input, component_name, component_input_name, input_name)
static loader init
Definition: IdmMf6File.f90:91
subroutine dynamic_read_ionper(this)
dynamic loader read ionper of next period block
Definition: IdmMf6File.f90:252
class(dynamicpkgloadbasetype) function, pointer static_load(this, iout)
load routine for static loader
Definition: IdmMf6File.f90:106
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 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 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:38
Base abstract type for dynamic input loader.
Base abstract type for static input loader.
Static parser based input loader.
Definition: LoadMf6File.f90:47
Ascii grid based dynamic loader type.
derived type for storing input definition for a file