MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
BudgetFileReader.f90
Go to the documentation of this file.
2 
3  use kindmodule
5  use constantsmodule, only: linelength
6 
7  implicit none
8 
9  private
10  public :: budgetfilereadertype
11 
13 
14  logical :: hasimeth1flowja = .false.
15  integer(I4B) :: inunit
16  integer(I4B) :: nbudterms
17  integer(I4B) :: kstp
18  integer(I4B) :: kper
19  integer(I4B) :: kstpnext
20  integer(I4B) :: kpernext
21  logical :: endoffile
22  character(len=16) :: budtxt
23  character(len=16), dimension(:), allocatable :: budtxtarray
24  integer(I4B) :: nval
25  integer(I4B) :: idum1
26  integer(I4B) :: idum2
27  integer(I4B) :: imeth
28  integer(I4B), dimension(:), allocatable :: imetharray
29  real(dp) :: delt
30  real(dp) :: pertim
31  real(dp) :: totim
32  character(len=16) :: srcmodelname
33  character(len=16) :: srcpackagename
34  integer(I4B) :: ndat
35  integer(I4B) :: naux
36  integer(I4B), dimension(:), allocatable :: nauxarray
37  character(len=16), dimension(:), allocatable :: auxtxt
38  character(len=16), dimension(:, :), allocatable :: auxtxtarray
39  integer(I4B) :: nlist
40  real(dp), dimension(:), allocatable :: flowja
41  integer(I4B), dimension(:), allocatable :: nodesrc
42  integer(I4B), dimension(:), allocatable :: nodedst
43  real(dp), dimension(:), allocatable :: flow
44  real(dp), dimension(:, :), allocatable :: auxvar
45  character(len=16) :: dstmodelname
46  character(len=16) :: dstpackagename
47  character(len=16), dimension(:), allocatable :: dstpackagenamearray
48 
49  contains
50 
51  procedure :: initialize
52  procedure :: read_record
53  procedure :: finalize
54 
55  end type budgetfilereadertype
56 
57 contains
58 
59  !< @brief initialize
60  !<
61  subroutine initialize(this, iu, iout, ncrbud)
62  ! -- dummy
63  class(budgetfilereadertype) :: this
64  integer(I4B), intent(in) :: iu
65  integer(I4B), intent(in) :: iout
66  integer(I4B), intent(out) :: ncrbud
67  ! -- local
68  integer(I4B) :: ibudterm
69  integer(I4B) :: kstp_last, kper_last
70  integer(I4B) :: maxaux
71  logical :: success
72  this%inunit = iu
73  this%endoffile = .false.
74  this%nbudterms = 0
75  ncrbud = 0
76  maxaux = 0
77  !
78  ! -- Determine number of budget terms within a time step
79  if (iout > 0) &
80  write (iout, '(a)') &
81  'Reading budget file to determine number of terms per time step.'
82  !
83  ! -- Read through the first set of data for time step 1 and stress period 1
84  do
85  call this%read_record(success)
86  if (.not. success) exit
87  this%nbudterms = this%nbudterms + 1
88  if (this%naux > maxaux) maxaux = this%naux
89  if (this%kstp /= this%kstpnext .or. this%kper /= this%kpernext) &
90  exit
91  end do
92  kstp_last = this%kstp
93  kper_last = this%kper
94  allocate (this%budtxtarray(this%nbudterms))
95  allocate (this%imetharray(this%nbudterms))
96  allocate (this%dstpackagenamearray(this%nbudterms))
97  allocate (this%nauxarray(this%nbudterms))
98  allocate (this%auxtxtarray(maxaux, this%nbudterms))
99  this%auxtxtarray(:, :) = ''
100  rewind(this%inunit)
101  !
102  ! -- Now read through again and store budget text names
103  do ibudterm = 1, this%nbudterms
104  call this%read_record(success, iout)
105  if (.not. success) exit
106  this%budtxtarray(ibudterm) = this%budtxt
107  this%imetharray(ibudterm) = this%imeth
108  this%dstpackagenamearray(ibudterm) = this%dstpackagename
109  this%nauxarray(ibudterm) = this%naux
110  if (this%naux > 0) then
111  this%auxtxtarray(1:this%naux, ibudterm) = this%auxtxt(:)
112  end if
113  if (this%srcmodelname == this%dstmodelname) then
114  if (allocated(this%nodesrc)) ncrbud = max(ncrbud, maxval(this%nodesrc))
115  end if
116  end do
117  rewind(this%inunit)
118  if (iout > 0) &
119  write (iout, '(a, i0, a)') 'Detected ', this%nbudterms, &
120  ' unique flow terms in budget file.'
121  end subroutine initialize
122 
123  !< @brief read record
124  !<
125  subroutine read_record(this, success, iout_opt)
126  ! -- modules
128  ! -- dummy
129  class(budgetfilereadertype) :: this
130  logical, intent(out) :: success
131  integer(I4B), intent(in), optional :: iout_opt
132  ! -- local
133  integer(I4B) :: i, n, iostat, iout
134  character(len=LINELENGTH) :: errmsg
135  !
136  if (present(iout_opt)) then
137  iout = iout_opt
138  else
139  iout = 0
140  end if
141  !
142  this%kstp = 0
143  this%kper = 0
144  this%budtxt = ''
145  this%nval = 0
146  this%naux = 0
147  this%idum1 = 0
148  this%idum2 = 0
149  this%srcmodelname = ''
150  this%srcpackagename = ''
151  this%dstmodelname = ''
152  this%dstpackagename = ''
153 
154  success = .true.
155  this%kstpnext = 0
156  this%kpernext = 0
157  read (this%inunit, iostat=iostat) this%kstp, this%kper, this%budtxt, &
158  this%nval, this%idum1, this%idum2
159  if (iostat /= 0) then
160  success = .false.
161  if (iostat < 0) this%endoffile = .true.
162  return
163  end if
164  read (this%inunit) this%imeth, this%delt, this%pertim, this%totim
165  if (this%imeth == 1) then
166  if (trim(adjustl(this%budtxt)) == 'FLOW-JA-FACE') then
167  if (allocated(this%flowja)) deallocate (this%flowja)
168  allocate (this%flowja(this%nval))
169  read (this%inunit) this%flowja
170  this%hasimeth1flowja = .true.
171  else
172  this%nval = this%nval * this%idum1 * abs(this%idum2)
173  if (allocated(this%flow)) deallocate (this%flow)
174  allocate (this%flow(this%nval))
175  if (allocated(this%nodesrc)) deallocate (this%nodesrc)
176  allocate (this%nodesrc(this%nval))
177  read (this%inunit) this%flow
178  do i = 1, this%nval
179  this%nodesrc(i) = i
180  end do
181  end if
182  elseif (this%imeth == 6) then
183  ! -- method code 6
184  read (this%inunit) this%srcmodelname
185  read (this%inunit) this%srcpackagename
186  read (this%inunit) this%dstmodelname
187  read (this%inunit) this%dstpackagename
188  read (this%inunit) this%ndat
189  this%naux = this%ndat - 1
190  if (allocated(this%auxtxt)) deallocate (this%auxtxt)
191  allocate (this%auxtxt(this%naux))
192  read (this%inunit) this%auxtxt
193  read (this%inunit) this%nlist
194  if (allocated(this%nodesrc)) deallocate (this%nodesrc)
195  allocate (this%nodesrc(this%nlist))
196  if (allocated(this%nodedst)) deallocate (this%nodedst)
197  allocate (this%nodedst(this%nlist))
198  if (allocated(this%flow)) deallocate (this%flow)
199  allocate (this%flow(this%nlist))
200  if (allocated(this%auxvar)) deallocate (this%auxvar)
201  allocate (this%auxvar(this%naux, this%nlist))
202  read (this%inunit) (this%nodesrc(n), this%nodedst(n), this%flow(n), &
203  (this%auxvar(i, n), i=1, this%naux), n=1, this%nlist)
204  else
205  write (errmsg, '(a, a)') 'ERROR READING: ', trim(this%budtxt)
206  call store_error(errmsg)
207  write (errmsg, '(a, i0)') 'INVALID METHOD CODE DETECTED: ', this%imeth
208  call store_error(errmsg)
209  call store_error_unit(this%inunit)
210  end if
211  if (iout > 0) then
212  write (iout, '(1pg15.6, a, 1x, a)') this%totim, this%budtxt, &
213  this%dstpackagename
214  end if
215  !
216  ! -- look ahead to next kstp and kper, then backup if read successfully
217  if (.not. this%endoffile) then
218  read (this%inunit, iostat=iostat) this%kstpnext, this%kpernext
219  if (iostat == 0) then
220  call fseek_stream(this%inunit, -2 * i4b, 1, iostat)
221  else if (iostat < 0) then
222  this%endoffile = .true.
223  end if
224  end if
225  end subroutine read_record
226 
227  !< @brief finalize
228  !<
229  subroutine finalize(this)
230  class(budgetfilereadertype) :: this
231  close (this%inunit)
232  if (allocated(this%auxtxt)) deallocate (this%auxtxt)
233  if (allocated(this%flowja)) deallocate (this%flowja)
234  if (allocated(this%nodesrc)) deallocate (this%nodesrc)
235  if (allocated(this%nodedst)) deallocate (this%nodedst)
236  if (allocated(this%flow)) deallocate (this%flow)
237  if (allocated(this%auxvar)) deallocate (this%auxvar)
238  end subroutine finalize
239 
240 end module budgetfilereadermodule
subroutine read_record(this, success, iout_opt)
subroutine initialize(this, iu, iout, ncrbud)
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
subroutine, public fseek_stream(iu, offset, whence, status)
Move the file pointer.
This module defines variable data types.
Definition: kind.f90:8
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_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168