MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
FlowModelInterface.f90
Go to the documentation of this file.
2 
3  use kindmodule, only: dp, i4b, lgp
8  use simvariablesmodule, only: errmsg
10  use basedismodule, only: disbasetype
11  use listmodule, only: listtype
18 
19  implicit none
20  private
21  public :: flowmodelinterfacetype
22 
24 
25  character(len=LENPACKAGENAME) :: text = '' !< text string for package
26  logical, pointer :: flows_from_file => null() !< if .false., then flows come from GWF through GWF-Model exg
27  type(listtype), pointer :: gwfbndlist => null() !< list of gwf stress packages
28  integer(I4B), pointer :: iflowsupdated => null() !< flows were updated for this time step
29  integer(I4B), dimension(:), pointer, contiguous :: ibound => null() !< pointer to this model ibound
30  real(dp), dimension(:), pointer, contiguous :: gwfflowja => null() !< pointer to the GWF flowja array
31  real(dp), dimension(:, :), pointer, contiguous :: gwfspdis => null() !< pointer to npf specific discharge array
32  real(dp), dimension(:), pointer, contiguous :: gwfhead => null() !< pointer to the GWF head array
33  real(dp), dimension(:), pointer, contiguous :: gwfsat => null() !< pointer to the GWF saturation array
34  integer(I4B), dimension(:), pointer, contiguous :: ibdgwfsat0 => null() !< mark cells with saturation = 0 to exclude from dispersion
35  integer(I4B), pointer :: idryinactive => null() !< mark cells with an additional flag to exclude from deactivation (gwe will simulate conduction through dry cells)
36  real(dp), dimension(:), pointer, contiguous :: gwfstrgss => null() !< pointer to flow model QSTOSS
37  real(dp), dimension(:), pointer, contiguous :: gwfstrgsy => null() !< pointer to flow model QSTOSY
38  integer(I4B), dimension(:), pointer, contiguous :: gwfceltyp => null() !< pointer to flow model NPF icelltype
39  integer(I4B), pointer :: igwfspdis => null() !< indicates if gwfspdis is available
40  integer(I4B), pointer :: igwfstrgss => null() !< indicates if gwfstrgss is available
41  integer(I4B), pointer :: igwfstrgsy => null() !< indicates if gwfstrgsy is available
42  integer(I4B), pointer :: igwfceltyp => null() !< indicates if gwfceltyp is available
43  integer(I4B), pointer :: iubud => null() !< unit number GWF budget file
44  integer(I4B), pointer :: iuhds => null() !< unit number GWF head file
45  integer(I4B), pointer :: iumvr => null() !< unit number GWF mover budget file
46  integer(I4B), pointer :: iugrb => null() !< unit number binary grid file
47  integer(I4B), pointer :: nflowpack => null() !< number of GWF flow packages
48  integer(I4B), dimension(:), pointer, contiguous :: igwfmvrterm => null() !< flag to indicate that gwf package is a mover term
49  type(budgetfilereadertype) :: bfr !< budget file reader
50  type(headfilereadertype) :: hfr !< head file reader
51  type(gridfilereadertype) :: gfr !< grid file reader
52  type(packagebudgettype), dimension(:), allocatable :: gwfpackages !< used to get flows between a package and gwf
53  type(budgetobjecttype), pointer :: mvrbudobj => null() !< pointer to the mover budget object
54  character(len=16), dimension(:), allocatable :: flowpacknamearray !< array of boundary package names (e.g. LAK-1, SFR-3, etc.)
55  character(len=LENVARNAME) :: depvartype = ''
56 
57  contains
58 
59  procedure :: advance_bfr
60  procedure :: advance_hfr
61  procedure :: allocate_arrays
62  procedure :: allocate_gwfpackages
63  procedure :: allocate_scalars
65  procedure :: finalize_bfr
66  procedure :: finalize_hfr
67  procedure :: fmi_ar
68  procedure :: fmi_da
69  procedure :: fmi_df
70  procedure :: get_package_index
71  procedure :: initialize_bfr
74  procedure :: initialize_hfr
75  procedure :: source_options
76  procedure :: source_packagedata
77  procedure :: read_grid
78 
79  end type flowmodelinterfacetype
80 
81 contains
82 
83  !> @brief Define the flow model interface
84  !<
85  subroutine fmi_df(this, dis, idryinactive)
86  ! -- modules
87  ! -- dummy
88  class(flowmodelinterfacetype) :: this
89  class(disbasetype), pointer, intent(in) :: dis
90  integer(I4B), intent(in) :: idryinactive
91  ! -- formats
92  character(len=*), parameter :: fmtfmi = &
93  "(1x,/1x,'FMI -- FLOW MODEL INTERFACE, VERSION 2, 8/17/2023', &
94  &' INPUT READ FROM MEMPATH: ', A, //)"
95  character(len=*), parameter :: fmtfmi0 = &
96  "(1x,/1x,'FMI -- FLOW MODEL INTERFACE,'&
97  &' VERSION 2, 8/17/2023')"
98  !
99  ! --print a message identifying the FMI package.
100  if (this%iout > 0) then
101  if (this%inunit /= 0) then
102  write (this%iout, fmtfmi) this%input_mempath
103  else
104  write (this%iout, fmtfmi0)
105  if (this%flows_from_file) then
106  write (this%iout, '(a)') ' FLOWS ARE ASSUMED TO BE ZERO.'
107  else
108  write (this%iout, '(a)') ' FLOWS PROVIDED BY A GWF MODEL IN THIS &
109  &SIMULATION'
110  end if
111  end if
112  end if
113  !
114  ! -- Store pointers
115  this%dis => dis
116  !
117  ! -- Read fmi options
118  if (this%inunit /= 0) then
119  call this%source_options()
120  end if
121  !
122  ! -- Read packagedata options
123  if (this%inunit /= 0 .and. this%flows_from_file) then
124  call this%source_packagedata()
125  call this%initialize_gwfterms_from_bfr()
126  end if
127  !
128  ! -- If GWF-Model exchange is active, setup flow terms
129  if (.not. this%flows_from_file) then
130  call this%initialize_gwfterms_from_gwfbndlist()
131  end if
132  !
133  ! -- Set flag that stops dry flows from being deactivated in a GWE
134  ! transport model since conduction will still be simulated.
135  ! 0: GWE (skip deactivation step); 1: GWT (default: use existing code)
136  this%idryinactive = idryinactive
137  end subroutine fmi_df
138 
139  !> @brief Allocate the package
140  !<
141  subroutine fmi_ar(this, ibound)
142  ! -- modules
143  ! -- dummy
144  class(flowmodelinterfacetype) :: this
145  integer(I4B), dimension(:), pointer, contiguous :: ibound
146  !
147  ! -- store pointers to arguments that were passed in
148  this%ibound => ibound
149  !
150  ! -- Allocate arrays
151  call this%allocate_arrays(this%dis%nodes)
152  end subroutine fmi_ar
153 
154  !> @brief Deallocate variables
155  !<
156  subroutine fmi_da(this)
157  ! -- modules
159  ! -- dummy
160  class(flowmodelinterfacetype) :: this
161  ! -- todo: finalize hfr and bfr either here or in a finalize routine
162  !
163  ! -- deallocate any memory stored with gwfpackages
164  call this%deallocate_gwfpackages()
165  !
166  ! -- deallocate fmi arrays
167  deallocate (this%gwfpackages)
168  deallocate (this%flowpacknamearray)
169  call mem_deallocate(this%igwfmvrterm)
170  call mem_deallocate(this%ibdgwfsat0)
171  !
172  if (this%flows_from_file) then
173  call mem_deallocate(this%gwfstrgss)
174  call mem_deallocate(this%gwfstrgsy)
175  call mem_deallocate(this%gwfceltyp)
176  end if
177  !
178  ! -- special treatment, these could be from mem_checkin
179  call mem_deallocate(this%gwfhead, 'GWFHEAD', this%memoryPath)
180  call mem_deallocate(this%gwfsat, 'GWFSAT', this%memoryPath)
181  call mem_deallocate(this%gwfspdis, 'GWFSPDIS', this%memoryPath)
182  call mem_deallocate(this%gwfflowja, 'GWFFLOWJA', this%memoryPath)
183  !
184  ! -- deallocate scalars
185  call mem_deallocate(this%flows_from_file)
186  call mem_deallocate(this%iflowsupdated)
187  call mem_deallocate(this%igwfspdis)
188  call mem_deallocate(this%igwfstrgss)
189  call mem_deallocate(this%igwfstrgsy)
190  call mem_deallocate(this%igwfceltyp)
191  call mem_deallocate(this%iubud)
192  call mem_deallocate(this%iuhds)
193  call mem_deallocate(this%iumvr)
194  call mem_deallocate(this%iugrb)
195  call mem_deallocate(this%nflowpack)
196  call mem_deallocate(this%idryinactive)
197  !
198  ! -- deallocate parent
199  call this%NumericalPackageType%da()
200  end subroutine fmi_da
201 
202  !> @brief Allocate scalars
203  !<
204  subroutine allocate_scalars(this)
205  ! -- modules
208  ! -- dummy
209  class(flowmodelinterfacetype) :: this
210  ! -- local
211  !
212  ! -- allocate scalars in NumericalPackageType
213  call this%NumericalPackageType%allocate_scalars()
214  !
215  ! -- Allocate
216  call mem_allocate(this%flows_from_file, 'FLOWS_FROM_FILE', this%memoryPath)
217  call mem_allocate(this%iflowsupdated, 'IFLOWSUPDATED', this%memoryPath)
218  call mem_allocate(this%igwfspdis, 'IGWFSPDIS', this%memoryPath)
219  call mem_allocate(this%igwfstrgss, 'IGWFSTRGSS', this%memoryPath)
220  call mem_allocate(this%igwfstrgsy, 'IGWFSTRGSY', this%memoryPath)
221  call mem_allocate(this%igwfceltyp, 'IGWFCELTYP', this%memoryPath)
222  call mem_allocate(this%iubud, 'IUBUD', this%memoryPath)
223  call mem_allocate(this%iuhds, 'IUHDS', this%memoryPath)
224  call mem_allocate(this%iumvr, 'IUMVR', this%memoryPath)
225  call mem_allocate(this%iugrb, 'IUGRB', this%memoryPath)
226  call mem_allocate(this%nflowpack, 'NFLOWPACK', this%memoryPath)
227  call mem_allocate(this%idryinactive, "IDRYINACTIVE", this%memoryPath)
228  !
229  ! !
230  ! -- Initialize
231  this%flows_from_file = .true.
232  this%iflowsupdated = 1
233  this%igwfspdis = 0
234  this%igwfstrgss = 0
235  this%igwfstrgsy = 0
236  this%igwfceltyp = 0
237  this%iubud = 0
238  this%iuhds = 0
239  this%iumvr = 0
240  this%iugrb = 0
241  this%nflowpack = 0
242  this%idryinactive = 1
243  end subroutine allocate_scalars
244 
245  !> @brief Allocate arrays
246  !<
247  subroutine allocate_arrays(this, nodes)
249  !modules
250  use constantsmodule, only: dzero
251  ! -- dummy
252  class(flowmodelinterfacetype) :: this
253  integer(I4B), intent(in) :: nodes
254  ! -- local
255  integer(I4B) :: n
256  !
257  ! -- Allocate ibdgwfsat0, which is an indicator array marking cells with
258  ! saturation greater than 0.0 with a value of 1
259  call mem_allocate(this%ibdgwfsat0, nodes, 'IBDGWFSAT0', this%memoryPath)
260  do n = 1, nodes
261  this%ibdgwfsat0(n) = 1
262  end do
263  !
264  ! -- Allocate differently depending on whether or not flows are
265  ! being read from a file.
266  if (this%flows_from_file) then
267  call mem_allocate(this%gwfflowja, this%dis%con%nja, &
268  'GWFFLOWJA', this%memoryPath)
269  call mem_allocate(this%gwfsat, nodes, 'GWFSAT', this%memoryPath)
270  call mem_allocate(this%gwfhead, nodes, 'GWFHEAD', this%memoryPath)
271  call mem_allocate(this%gwfspdis, 3, nodes, 'GWFSPDIS', this%memoryPath)
272  do n = 1, nodes
273  this%gwfsat(n) = done
274  this%gwfhead(n) = dzero
275  this%gwfspdis(:, n) = dzero
276  end do
277  do n = 1, size(this%gwfflowja)
278  this%gwfflowja(n) = dzero
279  end do
280  !
281  ! -- allocate and initialize storage arrays
282  if (this%igwfstrgss == 0) then
283  call mem_allocate(this%gwfstrgss, 1, 'GWFSTRGSS', this%memoryPath)
284  else
285  call mem_allocate(this%gwfstrgss, nodes, 'GWFSTRGSS', this%memoryPath)
286  end if
287  if (this%igwfstrgsy == 0) then
288  call mem_allocate(this%gwfstrgsy, 1, 'GWFSTRGSY', this%memoryPath)
289  else
290  call mem_allocate(this%gwfstrgsy, nodes, 'GWFSTRGSY', this%memoryPath)
291  end if
292  do n = 1, size(this%gwfstrgss)
293  this%gwfstrgss(n) = dzero
294  end do
295  do n = 1, size(this%gwfstrgsy)
296  this%gwfstrgsy(n) = dzero
297  end do
298  ! allocate and initialize cell type array. if the FMI is in a separate
299  ! simulation from the GWF model, we expect cell type to have been read
300  ! already if the binary grid file was provided to FMI. otherwise don't
301  ! initialize the cell type array to any default; unless it is received
302  ! from GWF NPF by an EXG it's undefined as indicated by igwfceltyp = 0
303  ! (this is because some coupled models need cell type, but some don't)
304  if (this%igwfceltyp == 0) &
305  call mem_allocate(this%gwfceltyp, nodes, 'GWFCELTYP', this%memoryPath)
306  !
307  ! -- If there is no fmi package, then there are no flows at all or a
308  ! connected GWF model, so allocate gwfpackages to zero
309  if (this%inunit == 0) call this%allocate_gwfpackages(this%nflowpack)
310  end if
311  end subroutine allocate_arrays
312 
313  !> @ brief Source input options for package
314  !<
315  subroutine source_options(this)
316  ! -- modules
318  ! -- dummy
319  class(flowmodelinterfacetype) :: this
320  ! -- local
321  logical(LGP) :: found_ipakcb
322  character(len=*), parameter :: fmtisvflow = &
323  "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
324  &WHENEVER ICBCFL IS NOT ZERO AND FLOW IMBALANCE CORRECTION ACTIVE.')"
325 
326  ! -- source package input
327  call mem_set_value(this%ipakcb, 'SAVE_FLOWS', this%input_mempath, &
328  found_ipakcb)
329 
330  write (this%iout, '(1x,a)') 'PROCESSING FMI OPTIONS'
331 
332  if (found_ipakcb) then
333  this%ipakcb = -1
334  write (this%iout, fmtisvflow)
335  end if
336 
337  write (this%iout, '(1x,a)') 'END OF FMI OPTIONS'
338  end subroutine source_options
339 
340  !> @ brief Source input options for package
341  !<
342  subroutine source_packagedata(this)
343  ! -- modules
347  use openspecmodule, only: access, form
350  ! -- dummy
351  class(flowmodelinterfacetype) :: this
352  ! -- local
353  type(characterstringtype), dimension(:), contiguous, &
354  pointer :: flowtypes
355  type(characterstringtype), dimension(:), contiguous, &
356  pointer :: fileops
357  type(characterstringtype), dimension(:), contiguous, &
358  pointer :: fnames
359  character(len=LINELENGTH) :: flowtype, fileop, fname
360  integer(I4B) :: inunit, n
361  logical(LGP) :: exist
362 
363  call mem_setptr(flowtypes, 'FLOWTYPE', this%input_mempath)
364  call mem_setptr(fileops, 'FILEIN', this%input_mempath)
365  call mem_setptr(fnames, 'FNAME', this%input_mempath)
366 
367  write (this%iout, '(1x,a)') 'PROCESSING FMI PACKAGEDATA'
368 
369  do n = 1, size(flowtypes)
370  flowtype = flowtypes(n)
371  fileop = fileops(n)
372  fname = fnames(n)
373 
374  inquire (file=trim(fname), exist=exist)
375  if (.not. exist) then
376  call store_error('Could not find file '//trim(fname))
377  cycle
378  end if
379 
380  if (fileop /= 'FILEIN') then
381  call store_error('Unexpected packagedata input keyword read: "' &
382  //trim(fileop)//'".')
383  cycle
384  end if
385 
386  select case (flowtype)
387  case ('GWFBUDGET')
388  inunit = getunit()
389  call openfile(inunit, this%iout, fname, 'DATA(BINARY)', form, &
390  access, 'UNKNOWN')
391  this%iubud = inunit
392  call this%initialize_bfr()
393  case ('GWFHEAD')
394  inunit = getunit()
395  call openfile(inunit, this%iout, fname, 'DATA(BINARY)', form, &
396  access, 'UNKNOWN')
397  this%iuhds = inunit
398  call this%initialize_hfr()
399  case ('GWFMOVER')
400  inunit = getunit()
401  call openfile(inunit, this%iout, fname, 'DATA(BINARY)', form, &
402  access, 'UNKNOWN')
403  this%iumvr = inunit
404  call budgetobject_cr_bfr(this%mvrbudobj, 'MVT', this%iumvr, &
405  this%iout)
406  call this%mvrbudobj%fill_from_bfr(this%dis, this%iout)
407  case ('GWFGRID')
408  inunit = getunit()
409  call openfile(inunit, this%iout, fname, 'DATA(BINARY)', &
410  form, access, 'UNKNOWN')
411  this%iugrb = inunit
412  call this%read_grid()
413  case default
414  write (errmsg, '(a,3(1x,a))') &
415  'UNKNOWN', trim(adjustl(this%text)), 'PACKAGEDATA:', trim(flowtype)
416  call store_error(errmsg)
417  end select
418  end do
419 
420  write (this%iout, '(1x,a)') 'END OF FMI PACKAGEDATA'
421 
422  if (count_errors() > 0) then
423  call store_error_filename(this%input_fname)
424  end if
425 
426  call memorystore_release('FLOWTYPE', this%input_mempath)
427  call memorystore_release('FILEIN', this%input_mempath)
428  call memorystore_release('FNAME', this%input_mempath)
429  end subroutine source_packagedata
430 
431  !> @brief Read/validate flow model grid
432  !<
433  subroutine read_grid(this)
434  ! -- modules
435  use dismodule, only: distype
436  use disvmodule, only: disvtype
437  use disumodule, only: disutype
438  use dis2dmodule, only: dis2dtype
439  use disv2dmodule, only: disv2dtype
440  use disv1dmodule, only: disv1dtype
441  ! -- dummy
442  class(flowmodelinterfacetype) :: this
443  ! -- local
444  integer(I4B) :: user_nodes
445  integer(I4B), allocatable :: idomain1d(:), idomain2d(:, :), idomain3d(:, :, :)
446  ! -- formats
447  character(len=*), parameter :: fmticterr = &
448  &"('Error in ',a,': Binary grid file does not contain ICELLTYPE.')"
449  character(len=*), parameter :: fmtdiserr = &
450  "('Error in ',a,': Models do not have the same discretization. &
451  &GWF model has ', i0, ' user nodes, this model has ', i0, '. &
452  &Ensure discretization packages, including IDOMAIN, are identical.')"
453  character(len=*), parameter :: fmtidomerr = &
454  "('Error in ',a,': models do not have the same discretization. &
455  &Models have different IDOMAIN arrays. &
456  &Ensure discretization packages, including IDOMAIN, are identical.')"
457 
458  call this%gfr%initialize(this%iugrb)
459 
460  ! load icelltype array
461  if (.not. this%gfr%has_variable("ICELLTYPE")) then
462  write (errmsg, fmticterr) trim(this%text)
463  call store_error(errmsg, terminate=.true.)
464  end if
465  this%igwfceltyp = 1
466  call mem_allocate(this%gwfceltyp, this%dis%nodesuser, &
467  'GWFCELTYP', this%memoryPath)
468  call this%gfr%read_int_1d_into("ICELLTYPE", this%gwfceltyp)
469 
470  ! check grid equivalence
471  select case (this%gfr%grid_type)
472  case ('DIS')
473  select type (dis => this%dis)
474  type is (distype)
475  user_nodes = this%gfr%read_int("NCELLS")
476  if (user_nodes /= this%dis%nodesuser) then
477  write (errmsg, fmtdiserr) &
478  trim(this%text), user_nodes, this%dis%nodesuser
479  call store_error(errmsg, terminate=.true.)
480  end if
481  idomain1d = this%gfr%read_int_1d("IDOMAIN")
482  idomain3d = reshape(idomain1d, [ &
483  this%gfr%read_int("NCOL"), &
484  this%gfr%read_int("NROW"), &
485  this%gfr%read_int("NLAY") &
486  ])
487  if (.not. all(dis%idomain == idomain3d)) then
488  write (errmsg, fmtidomerr) trim(this%text)
489  call store_error(errmsg, terminate=.true.)
490  end if
491  end select
492  case ('DISV')
493  select type (dis => this%dis)
494  type is (disvtype)
495  user_nodes = this%gfr%read_int("NCELLS")
496  if (user_nodes /= this%dis%nodesuser) then
497  write (errmsg, fmtdiserr) &
498  trim(this%text), user_nodes, this%dis%nodesuser
499  call store_error(errmsg, terminate=.true.)
500  end if
501  idomain1d = this%gfr%read_int_1d("IDOMAIN")
502  idomain2d = reshape(idomain1d, [ &
503  this%gfr%read_int("NCPL"), &
504  this%gfr%read_int("NLAY") &
505  ])
506  if (.not. all(dis%idomain == idomain2d)) then
507  write (errmsg, fmtidomerr) trim(this%text)
508  call store_error(errmsg, terminate=.true.)
509  end if
510  end select
511  case ('DISU')
512  select type (dis => this%dis)
513  type is (disutype)
514  user_nodes = this%gfr%read_int("NODES")
515  if (user_nodes /= this%dis%nodesuser) then
516  write (errmsg, fmtdiserr) &
517  trim(this%text), user_nodes, this%dis%nodesuser
518  call store_error(errmsg, terminate=.true.)
519  end if
520  idomain1d = this%gfr%read_int_1d("IDOMAIN")
521  if (.not. all(dis%idomain == idomain1d)) then
522  write (errmsg, fmtidomerr) trim(this%text)
523  call store_error(errmsg, terminate=.true.)
524  end if
525  end select
526  case ('DIS2D')
527  select type (dis => this%dis)
528  type is (dis2dtype)
529  user_nodes = this%gfr%read_int("NCELLS")
530  if (user_nodes /= this%dis%nodesuser) then
531  write (errmsg, fmtdiserr) &
532  trim(this%text), user_nodes, this%dis%nodesuser
533  call store_error(errmsg, terminate=.true.)
534  end if
535  idomain1d = this%gfr%read_int_1d("IDOMAIN")
536  idomain2d = reshape(idomain1d, [ &
537  this%gfr%read_int("NCOL"), &
538  this%gfr%read_int("NROW") &
539  ])
540  if (.not. all(dis%idomain == idomain2d)) then
541  write (errmsg, fmtidomerr) trim(this%text)
542  call store_error(errmsg, terminate=.true.)
543  end if
544  end select
545  case ('DISV2D')
546  select type (dis => this%dis)
547  type is (disv2dtype)
548  user_nodes = this%gfr%read_int("NODES")
549  if (user_nodes /= this%dis%nodesuser) then
550  write (errmsg, fmtdiserr) &
551  trim(this%text), user_nodes, this%dis%nodesuser
552  call store_error(errmsg, terminate=.true.)
553  end if
554  idomain1d = this%gfr%read_int_1d("IDOMAIN")
555  if (.not. all(dis%idomain == idomain1d)) then
556  write (errmsg, fmtidomerr) trim(this%text)
557  call store_error(errmsg, terminate=.true.)
558  end if
559  end select
560  case ('DISV1D')
561  select type (dis => this%dis)
562  type is (disv1dtype)
563  user_nodes = this%gfr%read_int("NCELLS")
564  if (user_nodes /= this%dis%nodesuser) then
565  write (errmsg, fmtdiserr) &
566  trim(this%text), user_nodes, this%dis%nodesuser
567  call store_error(errmsg, terminate=.true.)
568  end if
569  idomain1d = this%gfr%read_int_1d("IDOMAIN")
570  if (.not. all(dis%idomain == idomain1d)) then
571  write (errmsg, fmtidomerr) trim(this%text)
572  call store_error(errmsg, terminate=.true.)
573  end if
574  end select
575  end select
576 
577  if (allocated(idomain3d)) deallocate (idomain3d)
578  if (allocated(idomain2d)) deallocate (idomain2d)
579  if (allocated(idomain1d)) deallocate (idomain1d)
580 
581  call this%gfr%finalize()
582  end subroutine read_grid
583 
584  !> @brief Initialize the budget file reader
585  subroutine initialize_bfr(this)
586  class(flowmodelinterfacetype) :: this
587  integer(I4B) :: ncrbud
588  call this%bfr%initialize(this%iubud, this%iout, ncrbud)
589  ! todo: need to run through the budget terms
590  ! and do some checking
591  end subroutine initialize_bfr
592 
593  !> @brief Advance the budget file reader
594  !!
595  !! Advance the budget file reader by reading the next chunk
596  !! of information for the current time step and stress period.
597  !<
598  subroutine advance_bfr(this)
599  ! -- modules
600  use tdismodule, only: kstp, kper, endofsimulation
601  ! -- dummy
602  class(flowmodelinterfacetype) :: this
603  ! -- local
604  logical :: success
605  integer(I4B) :: n
606  integer(I4B) :: ipos
607  integer(I4B) :: nu, nr
608  integer(I4B) :: ip, i
609  logical :: readnext
610  ! -- format
611  character(len=*), parameter :: fmtkstpkper = &
612  "(1x,/1x,'FMI READING BUDGET TERMS &
613  &FOR KSTP ', i0, ' KPER ', i0)"
614  character(len=*), parameter :: fmtbudkstpkper = &
615  "(1x,/1x, 'FMI SETTING BUDGET TERMS &
616  &FOR KSTP ', i0, ' AND KPER ', &
617  &i0, ' TO BUDGET FILE TERMS FROM &
618  &KSTP ', i0, ' AND KPER ', i0)"
619  character(len=*), parameter :: fmtbadtdis = &
620  "(4x, 'TIME DISCRETIZATION IN BUDGET FILE &
621  &IS INCOMPATIBLE WITH TIME DISCRETIZATION IN COUPLED MODEL. &
622  &IF THERE IS MORE THAN ONE TIME STEP IN THE BUDGET FILE FOR A &
623  &GIVEN STRESS PERIOD, BUDGET FILE TIME STEPS MUST MATCH THE &
624  &COUPLED MODEL TIME STEPS ONE-FOR-ONE IN THAT STRESS PERIOD.')"
625  !
626  ! -- If the latest record read from the budget file is from a stress
627  ! -- period with only one time step, reuse that record (do not read a
628  ! -- new record) if the running model is still in that same stress period,
629  ! -- or if that record is the last one in the budget file.
630  readnext = .true.
631  if (kstp * kper > 1) then
632  if (this%bfr%header%kstp == 1) then
633  if (this%bfr%endoffile) then
634  readnext = .false.
635  else if (this%bfr%headernext%kper == kper + 1) then
636  readnext = .false.
637  end if
638  else if (this%bfr%endoffile) then
639  write (errmsg, '(4x,a)') 'REACHED END OF GWF BUDGET &
640  &FILE BEFORE READING SUFFICIENT BUDGET INFORMATION FOR THIS &
641  &GWT SIMULATION.'
642  call store_error(errmsg)
643  call store_error_unit(this%iubud)
644  end if
645  end if
646  !
647  ! -- Read the next record
648  if (readnext) then
649  !
650  ! -- Write the current time step and stress period
651  write (this%iout, fmtkstpkper) kstp, kper
652  !
653  ! -- loop through the budget terms for this stress period
654  ! i is the counter for gwf flow packages
655  ip = 1
656  do n = 1, this%bfr%nbudterms
657  call this%bfr%read_record(success, this%iout)
658  if (.not. success) then
659  write (errmsg, '(4x,a)') 'GWF BUDGET READ NOT SUCCESSFUL'
660  call store_error(errmsg)
661  call store_error_unit(this%iubud)
662  end if
663  !
664  ! -- Ensure kper is same between model and budget file
665  if (kper /= this%bfr%header%kper) then
666  write (errmsg, fmtbadtdis)
667  call store_error(errmsg)
668  call store_error_unit(this%iubud)
669  end if
670  !
671  ! -- if budget file kstp > 1, then kstp must match
672  if (this%bfr%header%kstp > 1 .and. (kstp /= this%bfr%header%kstp)) then
673  write (errmsg, fmtbadtdis)
674  call store_error(errmsg)
675  call store_error_unit(this%iubud)
676  end if
677  !
678  ! -- parse based on the type of data, and compress all user node
679  ! numbers into reduced node numbers
680  select type (h => this%bfr%header)
681  type is (budgetfileheadertype)
682  select case (trim(adjustl(h%budtxt)))
683  case ('FLOW-JA-FACE')
684  !
685  ! -- bfr%flowja contains only reduced connections so there is
686  ! a one-to-one match with this%gwfflowja
687  do ipos = 1, size(this%bfr%flowja)
688  this%gwfflowja(ipos) = this%bfr%flowja(ipos)
689  end do
690  case ('DATA-SPDIS')
691  do i = 1, h%nlist
692  nu = this%bfr%nodesrc(i)
693  nr = this%dis%get_nodenumber(nu, 0)
694  if (nr <= 0) cycle
695  this%gwfspdis(1, nr) = this%bfr%auxvar(1, i)
696  this%gwfspdis(2, nr) = this%bfr%auxvar(2, i)
697  this%gwfspdis(3, nr) = this%bfr%auxvar(3, i)
698  end do
699  case ('DATA-SAT')
700  do i = 1, h%nlist
701  nu = this%bfr%nodesrc(i)
702  nr = this%dis%get_nodenumber(nu, 0)
703  if (nr <= 0) cycle
704  this%gwfsat(nr) = this%bfr%auxvar(1, i)
705  end do
706  case ('STO-SS')
707  do nu = 1, this%dis%nodesuser
708  nr = this%dis%get_nodenumber(nu, 0)
709  if (nr <= 0) cycle
710  this%gwfstrgss(nr) = this%bfr%flow(nu)
711  end do
712  case ('STO-SY')
713  do nu = 1, this%dis%nodesuser
714  nr = this%dis%get_nodenumber(nu, 0)
715  if (nr <= 0) cycle
716  this%gwfstrgsy(nr) = this%bfr%flow(nu)
717  end do
718  case default
719  call this%gwfpackages(ip)%copy_values( &
720  h%nlist, &
721  this%bfr%nodesrc, &
722  this%bfr%flow, &
723  this%bfr%auxvar)
724  do i = 1, this%gwfpackages(ip)%nbound
725  nu = this%gwfpackages(ip)%nodelist(i)
726  nr = this%dis%get_nodenumber(nu, 0)
727  this%gwfpackages(ip)%nodelist(i) = nr
728  end do
729  ip = ip + 1
730  end select
731  end select
732  end do
733 
734  ! If this is the final time step, make sure no records
735  ! for this period are being skipped in the budget file.
736  if (endofsimulation .and. .not. this%bfr%endoffile) then
737  if (this%bfr%headernext%kper == kper) then
738  write (errmsg, fmtbadtdis)
739  call store_error(errmsg)
740  call store_error_unit(this%iubud)
741  end if
742  end if
743  else
744  !
745  ! -- write message to indicate that flows are being reused
746  write (this%iout, fmtbudkstpkper) kstp, kper, &
747  this%bfr%header%kstp, this%bfr%header%kper
748  !
749  ! -- set the flag to indicate that flows were not updated
750  this%iflowsupdated = 0
751  end if
752  end subroutine advance_bfr
753 
754  !> @brief Finalize the budget file reader
755  subroutine finalize_bfr(this)
756  class(flowmodelinterfacetype) :: this
757  call this%bfr%finalize()
758  end subroutine finalize_bfr
759 
760  !> @brief Initialize the head file reader
761  subroutine initialize_hfr(this)
762  class(flowmodelinterfacetype) :: this
763  call this%hfr%initialize(this%iuhds, this%iout)
764  ! todo: need to run through the head terms
765  ! and do some checking
766  end subroutine initialize_hfr
767 
768  !> @brief Advance the head file reader
769  subroutine advance_hfr(this)
770  ! modules
771  use tdismodule, only: kstp, kper
772  class(flowmodelinterfacetype) :: this
773  integer(I4B) :: nu, nr, i, ilay
774  integer(I4B) :: ncpl
775  real(DP) :: val
776  logical :: readnext
777  logical :: success
778  character(len=*), parameter :: fmtkstpkper = &
779  "(1x,/1x,'FMI READING HEAD FOR &
780  &KSTP ', i0, ' KPER ', i0)"
781  character(len=*), parameter :: fmthdskstpkper = &
782  "(1x,/1x, 'FMI SETTING HEAD FOR KSTP ', i0, ' AND KPER ', &
783  &i0, ' TO BINARY FILE HEADS FROM KSTP ', i0, ' AND KPER ', i0)"
784  !
785  ! -- If the latest record read from the head file is from a stress
786  ! -- period with only one time step, reuse that record (do not read a
787  ! -- new record) if the running model is still in that same stress period,
788  ! -- or if that record is the last one in the head file.
789  readnext = .true.
790  if (kstp * kper > 1) then
791  if (this%hfr%header%kstp == 1) then
792  if (this%hfr%endoffile) then
793  readnext = .false.
794  else if (this%hfr%headernext%kper == kper + 1) then
795  readnext = .false.
796  end if
797  else if (this%hfr%endoffile) then
798  write (errmsg, '(4x,a)') 'REACHED END OF GWF HEAD &
799  &FILE BEFORE READING SUFFICIENT HEAD INFORMATION FOR THIS &
800  &GWT SIMULATION.'
801  call store_error(errmsg)
802  call store_error_unit(this%iuhds)
803  end if
804  end if
805  !
806  ! -- Read the next record
807  if (readnext) then
808  !
809  ! -- write to list file that heads are being read
810  write (this%iout, fmtkstpkper) kstp, kper
811  !
812  ! -- loop through the layered heads for this time step
813  do ilay = 1, this%hfr%nlay
814  !
815  ! -- read next head chunk
816  call this%hfr%read_record(success, this%iout)
817  if (.not. success) then
818  write (errmsg, '(4x,a)') 'GWF HEAD READ NOT SUCCESSFUL'
819  call store_error(errmsg)
820  call store_error_unit(this%iuhds)
821  end if
822  !
823  ! -- Ensure kper is same between model and head file
824  if (kper /= this%hfr%header%kper) then
825  write (errmsg, '(4x,a)') 'PERIOD NUMBER IN HEAD FILE &
826  &DOES NOT MATCH PERIOD NUMBER IN TRANSPORT MODEL. IF THERE &
827  &IS MORE THAN ONE TIME STEP IN THE HEAD FILE FOR A GIVEN STRESS &
828  &PERIOD, HEAD FILE TIME STEPS MUST MATCH GWT MODEL TIME STEPS &
829  &ONE-FOR-ONE IN THAT STRESS PERIOD.'
830  call store_error(errmsg)
831  call store_error_unit(this%iuhds)
832  end if
833  !
834  ! -- if head file kstp > 1, then kstp must match
835  if (this%hfr%header%kstp > 1 .and. (kstp /= this%hfr%header%kstp)) then
836  write (errmsg, '(4x,a)') 'TIME STEP NUMBER IN HEAD FILE &
837  &DOES NOT MATCH TIME STEP NUMBER IN TRANSPORT MODEL. IF THERE &
838  &IS MORE THAN ONE TIME STEP IN THE HEAD FILE FOR A GIVEN STRESS &
839  &PERIOD, HEAD FILE TIME STEPS MUST MATCH GWT MODEL TIME STEPS &
840  &ONE-FOR-ONE IN THAT STRESS PERIOD.'
841  call store_error(errmsg)
842  call store_error_unit(this%iuhds)
843  end if
844  !
845  ! -- fill the head array for this layer and
846  ! compress into reduced form
847  ncpl = size(this%hfr%head)
848  do i = 1, ncpl
849  nu = (ilay - 1) * ncpl + i
850  nr = this%dis%get_nodenumber(nu, 0)
851  val = this%hfr%head(i)
852  if (nr > 0) this%gwfhead(nr) = val
853  end do
854  end do
855  else
856  write (this%iout, fmthdskstpkper) kstp, kper, &
857  this%hfr%header%kstp, this%hfr%header%kper
858  end if
859  end subroutine advance_hfr
860 
861  !> @brief Finalize the head file reader
862  subroutine finalize_hfr(this)
863  class(flowmodelinterfacetype) :: this
864  close (this%iuhds)
865  end subroutine finalize_hfr
866 
867  !> @brief Initialize gwf terms from budget file
868  !!
869  !! initialize terms and figure out how many
870  !! different terms and packages are contained within the file
871  !<
873  ! -- dummy
874  class(flowmodelinterfacetype) :: this
875  ! -- local
876  integer(I4B) :: nflowpack
877  integer(I4B) :: i, ip
878  integer(I4B) :: naux
879  logical :: found_flowja
880  logical :: found_dataspdis
881  logical :: found_datasat
882  logical :: found_stoss
883  logical :: found_stosy
884  integer(I4B), dimension(:), allocatable :: imap
885  !
886  ! -- Calculate the number of gwf flow packages
887  allocate (imap(this%bfr%nbudterms))
888  imap(:) = 0
889  nflowpack = 0
890  found_flowja = .false.
891  found_dataspdis = .false.
892  found_datasat = .false.
893  found_stoss = .false.
894  found_stosy = .false.
895  do i = 1, this%bfr%nbudterms
896  select case (trim(adjustl(this%bfr%budtxtarray(i))))
897  case ('FLOW-JA-FACE')
898  found_flowja = .true.
899  case ('DATA-SPDIS')
900  found_dataspdis = .true.
901  this%igwfspdis = 1
902  case ('DATA-SAT')
903  found_datasat = .true.
904  case ('STO-SS')
905  found_stoss = .true.
906  this%igwfstrgss = 1
907  case ('STO-SY')
908  found_stosy = .true.
909  this%igwfstrgsy = 1
910  case default
911  nflowpack = nflowpack + 1
912  imap(i) = 1
913  end select
914  end do
915  !
916  ! -- allocate gwfpackage arrays
917  call this%allocate_gwfpackages(nflowpack)
918  !
919  ! -- Copy the package name and aux names from budget file reader
920  ! to the gwfpackages derived-type variable
921  ip = 1
922  do i = 1, this%bfr%nbudterms
923  if (imap(i) == 0) cycle
924  call this%gwfpackages(ip)%set_name(this%bfr%dstpackagenamearray(i), &
925  this%bfr%budtxtarray(i))
926  naux = this%bfr%nauxarray(i)
927  call this%gwfpackages(ip)%set_auxname(naux, this%bfr%auxtxtarray(1:naux, i))
928  ip = ip + 1
929  end do
930  !
931  ! -- Copy just the package names for the boundary packages into
932  ! the flowpacknamearray
933  ip = 1
934  do i = 1, size(imap)
935  if (imap(i) == 1) then
936  this%flowpacknamearray(ip) = this%bfr%dstpackagenamearray(i)
937  ip = ip + 1
938  end if
939  end do
940  !
941  ! -- Error if specific discharge, saturation or flowja not found
942  if (.not. found_dataspdis) then
943  write (errmsg, '(4x,a)') 'SPECIFIC DISCHARGE NOT FOUND IN &
944  &BUDGET FILE. SAVE_SPECIFIC_DISCHARGE AND &
945  &SAVE_FLOWS MUST BE ACTIVATED IN THE NPF PACKAGE.'
946  call store_error(errmsg)
947  end if
948  if (.not. found_datasat) then
949  write (errmsg, '(4x,a)') 'SATURATION NOT FOUND IN &
950  &BUDGET FILE. SAVE_SATURATION AND &
951  &SAVE_FLOWS MUST BE ACTIVATED IN THE NPF PACKAGE.'
952  call store_error(errmsg)
953  end if
954  if (.not. found_flowja) then
955  write (errmsg, '(4x,a)') 'FLOWJA NOT FOUND IN &
956  &BUDGET FILE. SAVE_FLOWS MUST &
957  &BE ACTIVATED IN THE NPF PACKAGE.'
958  call store_error(errmsg)
959  end if
960  if (count_errors() > 0) then
961  call store_error_filename(this%input_fname)
962  end if
963  end subroutine initialize_gwfterms_from_bfr
964 
965  !> @brief Initialize gwf terms from a GWF exchange
967  ! -- modules
968  use bndmodule, only: bndtype, getbndfromlist
969  ! -- dummy
970  class(flowmodelinterfacetype) :: this
971  ! -- local
972  integer(I4B) :: ngwfpack
973  integer(I4B) :: ngwfterms
974  integer(I4B) :: ip
975  integer(I4B) :: imover
976  integer(I4B) :: ntomvr
977  integer(I4B) :: iterm
978  character(len=LENPACKAGENAME) :: budtxt
979  class(bndtype), pointer :: packobj => null()
980  !
981  ! -- determine size of gwf terms
982  ngwfpack = this%gwfbndlist%Count()
983  !
984  ! -- Count number of to-mvr terms, but do not include advanced packages
985  ! as those mover terms are not losses from the cell, but rather flows
986  ! within the advanced package
987  ntomvr = 0
988  do ip = 1, ngwfpack
989  packobj => getbndfromlist(this%gwfbndlist, ip)
990  imover = packobj%imover
991  if (packobj%isadvpak /= 0) imover = 0
992  if (imover /= 0) then
993  ntomvr = ntomvr + 1
994  end if
995  end do
996  !
997  ! -- Allocate arrays in fmi of size ngwfterms, which is the number of
998  ! packages plus the number of packages with mover terms.
999  ngwfterms = ngwfpack + ntomvr
1000  call this%allocate_gwfpackages(ngwfterms)
1001  !
1002  ! -- Assign values in the fmi package
1003  iterm = 1
1004  do ip = 1, ngwfpack
1005  !
1006  ! -- set and store names
1007  packobj => getbndfromlist(this%gwfbndlist, ip)
1008  budtxt = adjustl(packobj%text)
1009  call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
1010  this%flowpacknamearray(iterm) = packobj%packName
1011  iterm = iterm + 1
1012  !
1013  ! -- if this package has a mover associated with it, then add another
1014  ! term that corresponds to the mover flows
1015  imover = packobj%imover
1016  if (packobj%isadvpak /= 0) imover = 0
1017  if (imover /= 0) then
1018  budtxt = trim(adjustl(packobj%text))//'-TO-MVR'
1019  call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
1020  this%flowpacknamearray(iterm) = packobj%packName
1021  this%igwfmvrterm(iterm) = 1
1022  iterm = iterm + 1
1023  end if
1024  end do
1026 
1027  !> @brief Allocate budget packages
1028  !!
1029  !! gwfpackages is an array of PackageBudget objects.
1030  !! This routine allocates gwfpackages to the proper size and initializes some
1031  !! member variables.
1032  !<
1033  subroutine allocate_gwfpackages(this, ngwfterms)
1034  ! -- modules
1035  use constantsmodule, only: lenmempath
1037  ! -- dummy
1038  class(flowmodelinterfacetype) :: this
1039  integer(I4B), intent(in) :: ngwfterms
1040  ! -- local
1041  integer(I4B) :: n
1042  character(len=LENMEMPATH) :: memPath
1043  !
1044  ! -- direct allocate
1045  allocate (this%gwfpackages(ngwfterms))
1046  allocate (this%flowpacknamearray(ngwfterms))
1047  !
1048  ! -- mem_allocate
1049  call mem_allocate(this%igwfmvrterm, ngwfterms, 'IGWFMVRTERM', this%memoryPath)
1050  !
1051  ! -- initialize
1052  this%nflowpack = ngwfterms
1053  do n = 1, this%nflowpack
1054  this%igwfmvrterm(n) = 0
1055  this%flowpacknamearray(n) = ''
1056  !
1057  ! -- Create a mempath for each individual flow package data set
1058  ! of the form, MODELNAME/FMI-FTn
1059  write (mempath, '(a, i0)') trim(this%memoryPath)//'-FT', n
1060  call this%gwfpackages(n)%initialize(mempath)
1061  end do
1062  end subroutine allocate_gwfpackages
1063 
1064  !> @brief Deallocate memory in the gwfpackages array
1065  subroutine deallocate_gwfpackages(this)
1066  class(flowmodelinterfacetype) :: this
1067  integer(I4B) :: n
1068 
1069  do n = 1, this%nflowpack
1070  call this%gwfpackages(n)%da()
1071  end do
1072  end subroutine deallocate_gwfpackages
1073 
1074  !> @brief Find the package index for the package with the given name
1075  subroutine get_package_index(this, name, idx)
1076  use bndmodule, only: bndtype, getbndfromlist
1077  class(flowmodelinterfacetype) :: this
1078  character(len=*), intent(in) :: name
1079  integer(I4B), intent(inout) :: idx
1080  ! -- local
1081  integer(I4B) :: ip
1082  !
1083  ! -- Look through all the packages and return the index with name
1084  idx = 0
1085  do ip = 1, size(this%flowpacknamearray)
1086  if (this%flowpacknamearray(ip) == name) then
1087  idx = ip
1088  exit
1089  end if
1090  end do
1091  if (idx == 0) then
1092  call store_error('Error in get_package_index. Could not find '//name, &
1093  terminate=.true.)
1094  end if
1095  end subroutine get_package_index
1096 
1097 end module flowmodelinterfacemodule
This module contains the base boundary package.
class(bndtype) function, pointer, public getbndfromlist(list, idx)
Get boundary from package list.
subroutine, public budgetobject_cr_bfr(this, name, ibinun, iout, colconv1, colconv2)
Create a new budget object from a binary flow file.
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:23
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
real(dp), parameter dhalf
real constant 1/2
Definition: Constants.f90:68
real(dp), parameter dem6
real constant 1e-6
Definition: Constants.f90:109
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
Definition: Constants.f90:37
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
Definition: Dis.f90:1
subroutine allocate_scalars(this)
Allocate scalars.
subroutine fmi_ar(this, ibound)
Allocate the package.
subroutine allocate_gwfpackages(this, ngwfterms)
Allocate budget packages.
subroutine read_grid(this)
Read/validate flow model grid.
subroutine deallocate_gwfpackages(this)
Deallocate memory in the gwfpackages array.
subroutine finalize_hfr(this)
Finalize the head file reader.
subroutine fmi_df(this, dis, idryinactive)
Define the flow model interface.
subroutine get_package_index(this, name, idx)
Find the package index for the package with the given name.
subroutine advance_bfr(this)
Advance the budget file reader.
subroutine initialize_gwfterms_from_gwfbndlist(this)
Initialize gwf terms from a GWF exchange.
subroutine initialize_hfr(this)
Initialize the head file reader.
subroutine source_options(this)
@ brief Source input options for package
subroutine fmi_da(this)
Deallocate variables.
subroutine source_packagedata(this)
@ brief Source input options for package
subroutine advance_hfr(this)
Advance the head file reader.
subroutine initialize_gwfterms_from_bfr(this)
Initialize gwf terms from budget file.
subroutine finalize_bfr(this)
Finalize the budget file reader.
subroutine allocate_arrays(this, nodes)
Allocate arrays.
subroutine initialize_bfr(this)
Initialize the budget file reader.
subroutine, public urdaux(naux, inunit, iout, lloc, istart, istop, auxname, line, text)
Read auxiliary variables from an input line.
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
subroutine, public memorystore_release(varname, memory_path)
Release a single variable from the memory store.
This module contains the base numerical package type.
character(len=20) access
Definition: OpenSpec.f90:7
character(len=20) form
Definition: OpenSpec.f90:7
This module contains the PackageBudgetModule Module.
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:203
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
logical(lgp), pointer, public endofsimulation
flag indicating end of simulation
Definition: tdis.f90:31
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:27
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:26
@ brief BndType
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
Structured grid discretization.
Definition: Dis2d.f90:23
Structured grid discretization.
Definition: Dis.f90:23
Unstructured grid discretization.
Definition: Disu.f90:29
Vertex grid discretization.
Definition: Disv2d.f90:25
Vertex grid discretization.
Definition: Disv.f90:25
A generic heterogeneous doubly-linked list.
Definition: List.f90:14
Derived type for storing flows.