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