MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
HeadFileReader.f90
Go to the documentation of this file.
2 
3  use kindmodule
6 
7  implicit none
8 
9  private
11 
13  character(len=16) :: text
14  integer(I4B) :: ncol, nrow, ilay
15  contains
16  procedure :: get_str
17  end type headfileheadertype
18 
20  integer(I4B) :: nlay
21  real(dp), dimension(:), allocatable :: head
22  contains
23  procedure :: initialize
24  procedure :: read_header
25  procedure :: read_record
26  procedure :: rewind
27  procedure :: finalize
28  end type headfilereadertype
29 
30 contains
31 
32  !< @brief initialize
33  !<
34  subroutine initialize(this, iu, iout)
35  ! -- dummy
36  class(headfilereadertype) :: this
37  integer(I4B), intent(in) :: iu
38  integer(I4B), intent(in) :: iout
39  ! -- local
40  integer(I4B) :: kstp_last, kper_last
41  logical :: success
42  !
43  this%inunit = iu
44  this%nlay = 0
45  call this%rewind()
46  !
47  ! -- Read the first head data record to set kstp_last, kstp_last
48  call this%read_record(success)
49  kstp_last = this%header%kstp
50  kper_last = this%header%kper
51  call this%rewind()
52  !
53  ! -- Determine number of records within a time step
54  if (iout > 0) &
55  write (iout, '(a)') &
56  'Reading binary file to determine number of records per time step.'
57  do
58  call this%read_record(success, iout)
59  if (.not. success) exit
60  if (kstp_last /= this%header%kstp .or. kper_last /= this%header%kper) exit
61  this%nlay = this%nlay + 1
62  end do
63  call this%rewind()
64  if (iout > 0) &
65  write (iout, '(a, i0, a)') 'Detected ', this%nlay, &
66  ' unique records in binary file.'
67  end subroutine initialize
68 
69  !< @brief read header only
70  !<
71  subroutine read_header(this, success, iout)
72  ! -- dummy
73  class(headfilereadertype), intent(inout) :: this
74  logical, intent(out) :: success
75  integer(I4B), intent(in), optional :: iout
76  ! -- local
77  integer(I4B) :: iostat
78  integer(I8B) :: pos
79  !
80  success = .true.
81  select type (h => this%header)
82  type is (headfileheadertype)
83  h%kstp = 0
84  h%kper = 0
85  h%text = ''
86  h%ncol = 0
87  h%nrow = 0
88  h%ilay = 0
89  inquire (unit=this%inunit, pos=h%pos)
90  read (this%inunit, iostat=iostat) h%kstp, h%kper, &
91  h%pertim, h%totim, h%text, h%ncol, h%nrow, h%ilay
92  if (iostat /= 0) then
93  success = .false.
94  if (iostat < 0) this%endoffile = .true.
95  return
96  end if
97  inquire (unit=this%inunit, pos=pos)
98  this%header%size = pos - this%header%pos
99  end select
100  end subroutine read_header
101 
102  !< @brief read record
103  !<
104  subroutine read_record(this, success, iout)
105  ! -- modules
107  ! -- dummy
108  class(headfilereadertype), intent(inout) :: this
109  logical, intent(out) :: success
110  integer(I4B), intent(in), optional :: iout
111  ! -- local
112  integer(I4B) :: iout_opt
113  integer(I4B) :: ncol, nrow
114  !
115  if (present(iout)) then
116  iout_opt = iout
117  else
118  iout_opt = 0
119  end if
120  !
121  call this%read_header(success, iout_opt)
122  if (.not. success) return
123  !
124  select type (h => this%header)
125  type is (headfileheadertype)
126  ncol = h%ncol
127  nrow = h%nrow
128  end select
129  !
130  ! -- allocate head to proper size
131  if (.not. allocated(this%head)) then
132  allocate (this%head(ncol * nrow))
133  else
134  if (size(this%head) /= ncol * nrow) then
135  deallocate (this%head)
136  allocate (this%head(ncol * nrow))
137  end if
138  end if
139  !
140  ! -- read the head array
141  read (this%inunit) this%head
142  !
143  call this%peek_record()
144  end subroutine read_record
145 
146  !< @brief finalize
147  !<
148  subroutine finalize(this)
149  class(headfilereadertype) :: this
150  close (this%inunit)
151  if (allocated(this%head)) deallocate (this%head)
152  if (allocated(this%header)) deallocate (this%header)
153  if (allocated(this%headernext)) deallocate (this%headernext)
154  end subroutine finalize
155 
156  !> @brief Get a string representation of the head file header.
157  function get_str(this) result(str)
158  class(headfileheadertype), intent(in) :: this
159  character(len=:), allocatable :: str
160  character(len=LENBIGLINE) :: temp
161 
162  write (temp, '(*(G0))') &
163  'Head file header (pos: ', this%pos, &
164  ', kper: ', this%kper, &
165  ', kstp: ', this%kstp, &
166  ', pertim: ', this%pertim, &
167  ', totim: ', this%totim, &
168  ', text: ', trim(this%text), &
169  ', ncol: ', this%ncol, &
170  ', nrow: ', this%nrow, &
171  ', ilay: ', this%ilay, &
172  ')'
173  str = trim(temp)
174  end function get_str
175 
176  subroutine rewind (this)
177  class(headfilereadertype), intent(inout) :: this
178 
179  rewind(this%inunit)
180  this%endoffile = .false.
181  if (allocated(this%header)) deallocate (this%header)
182  if (allocated(this%headernext)) deallocate (this%headernext)
183  allocate (headfileheadertype :: this%header)
184  allocate (headfileheadertype :: this%headernext)
185  this%header%pos = 1
186  this%headernext%pos = 1
187  end subroutine rewind
188 
189 end module headfilereadermodule
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 lenhugeline
maximum length of a huge line
Definition: Constants.f90:16
integer(i4b), parameter lenbigline
maximum length of a big line
Definition: Constants.f90:15
subroutine finalize(this)
subroutine read_record(this, success, iout)
subroutine initialize(this, iu, iout)
subroutine read_header(this, success, iout)
subroutine rewind(this)
character(len=:) function, allocatable get_str(this)
Get a string representation of the head file header.
subroutine, public fseek_stream(iu, offset, whence, status)
Move the file pointer.
This module defines variable data types.
Definition: kind.f90:8