17 integer(I4B),
public :: inunit
19 character(len=10),
public :: grid_type
20 integer(I4B),
public :: version
22 integer(I4B) :: lentxt
28 integer(I4B),
allocatable :: shp(:)
29 character(len=10),
allocatable,
public :: keys(:)
57 integer(I4B),
intent(in) :: iu
64 allocate (this%shp(0))
65 call this%read_header()
85 call this%read_header_meta()
86 call this%read_header_body()
94 character(len=50) :: line
95 integer(I4B) :: lloc, istart, istop
100 read (this%inunit) line
102 call urword(line, lloc, istart, istop, 1, ival, rval, 0, 0)
103 if (line(istart:istop) /=
'GRID')
then
104 call store_error(
'Binary grid file must begin with "GRID". '//&
105 &
'Found: '//line(istart:istop))
108 call urword(line, lloc, istart, istop, 1, ival, rval, 0, 0)
109 this%grid_type = line(istart:istop)
112 read (this%inunit) line
114 call urword(line, lloc, istart, istop, 0, ival, rval, 0, 0)
115 call urword(line, lloc, istart, istop, 2, ival, rval, 0, 0)
119 read (this%inunit) line
121 call urword(line, lloc, istart, istop, 0, ival, rval, 0, 0)
122 call urword(line, lloc, istart, istop, 2, ival, rval, 0, 0)
126 read (this%inunit) line
128 call urword(line, lloc, istart, istop, 0, ival, rval, 0, 0)
129 call urword(line, lloc, istart, istop, 2, ival, rval, 0, 0)
140 character(len=:),
allocatable :: body
141 character(len=:),
allocatable :: line
142 character(len=10) :: key, dtype
144 integer(I4B) :: i, lloc, istart, istop, ival, pos
145 integer(I4B) :: nvars, ndim, dim, ishp
146 integer(I4B),
allocatable :: shp(:)
148 allocate (this%keys(this%ntxt))
149 allocate (
character(len=this%lentxt*this%ntxt) :: body)
150 allocate (
character(len=this%lentxt) :: line)
153 read (this%inunit) body
154 inquire (this%inunit, pos=pos)
155 do i = 1, this%lentxt * this%ntxt, this%lentxt
156 line = body(i:i + this%lentxt - 1)
161 call urword(line, lloc, istart, istop, 1, ival, rval, 0, 0)
162 key = line(istart:istop)
164 this%keys(nvars) = key
167 call urword(line, lloc, istart, istop, 1, ival, rval, 0, 0)
168 dtype = line(istart:istop)
169 if (dtype ==
"INTEGER")
then
170 call this%typ%add(key, 1)
171 else if (dtype ==
"DOUBLE")
then
172 call this%typ%add(key, 2)
173 else if (dtype ==
"CHARACTER")
then
174 call this%typ%add(key, 3)
178 call urword(line, lloc, istart, istop, 0, ival, rval, 0, 0)
179 call urword(line, lloc, istart, istop, 2, ival, rval, 0, 0)
181 call this%dim%add(key, ndim)
184 if (
allocated(shp))
deallocate (shp)
188 call urword(line, lloc, istart, istop, 2, ival, rval, 0, 0)
191 ishp =
size(this%shp)
193 this%shp(ishp + 1:ishp + ndim) = shp
194 call this%shp_idx%add(key, ishp + 1)
198 call this%pos%add(key, pos)
200 if (dtype ==
"INTEGER")
then
202 else if (dtype ==
"DOUBLE")
then
206 if (dtype ==
"INTEGER")
then
207 pos = pos + (product(shp) * 4)
208 else if (dtype ==
"DOUBLE")
then
209 pos = pos + (product(shp) * 8)
210 else if (dtype ==
"CHARACTER")
then
211 pos = pos + (product(shp) * 8)
223 character(len=*),
intent(in) :: key
226 integer(I4B) :: ndim, pos, typ
227 character(len=:),
allocatable :: msg
229 msg =
'Variable '//trim(key)//
' is not an integer scalar'
230 ndim = this%dim%get(key)
235 typ = this%typ%get(key)
240 pos = this%pos%get(key)
241 read (this%inunit, pos=pos) v
249 character(len=*),
intent(in) :: key
252 integer(I4B) :: ndim, pos, typ
253 character(len=:),
allocatable :: msg
255 msg =
'Variable '//trim(key)//
' is not a double precision scalar'
256 ndim = this%dim%get(key)
261 typ = this%typ%get(key)
266 pos = this%pos%get(key)
267 read (this%inunit, pos=pos) v
277 character(len=*),
intent(in) :: key
278 integer(I4B),
allocatable :: v(:)
280 integer(I4B) :: idx, ndim, nvals, pos, typ
281 character(len=:),
allocatable :: msg
283 msg =
'Variable '//trim(key)//
' is not a 1D integer array'
284 ndim = this%dim%get(key)
289 typ = this%typ%get(key)
294 idx = this%shp_idx%get(key)
295 pos = this%pos%get(key)
296 nvals = this%shp(idx)
298 read (this%inunit, pos=pos) v
310 character(len=*),
intent(in) :: key
311 integer(I4B),
dimension(:),
intent(inout) :: v
313 integer(I4B) :: idx, ndim, nvals, pos, typ
314 character(len=:),
allocatable :: msg
316 msg =
'Variable '//trim(key)//
' is not a 1D integer array'
317 ndim = this%dim%get(key)
322 typ = this%typ%get(key)
327 idx = this%shp_idx%get(key)
328 pos = this%pos%get(key)
329 nvals = this%shp(idx)
331 if (
size(v) /= nvals)
then
332 write (
errmsg,
'(a,i0,a,i0)') &
333 'Array size mismatch for '//trim(key)//
': expected ', &
334 nvals,
', got ',
size(v)
337 read (this%inunit, pos=pos) v
347 character(len=*),
intent(in) :: key
348 real(dp),
allocatable :: v(:)
350 integer(I4B) :: idx, ndim, nvals, pos, typ
351 character(len=:),
allocatable :: msg
353 msg =
'Variable '//trim(key)//
' is not a 1D double array'
354 ndim = this%dim%get(key)
359 typ = this%typ%get(key)
364 idx = this%shp_idx%get(key)
365 pos = this%pos%get(key)
366 nvals = this%shp(idx)
368 read (this%inunit, pos=pos) v
380 character(len=*),
intent(in) :: key
381 real(DP),
dimension(:),
intent(inout) :: v
383 integer(I4B) :: idx, ndim, nvals, pos, typ
384 character(len=:),
allocatable :: msg
386 msg =
'Variable '//trim(key)//
' is not a 1D double array'
387 ndim = this%dim%get(key)
392 typ = this%typ%get(key)
397 idx = this%shp_idx%get(key)
398 pos = this%pos%get(key)
399 nvals = this%shp(idx)
401 if (
size(v) /= nvals)
then
402 write (
errmsg,
'(a,i0,a,i0)') &
403 'Array size mismatch for '//trim(key)//
': expected ', &
404 nvals,
', got ',
size(v)
407 read (this%inunit, pos=pos) v
417 character(len=*),
intent(in) :: key
418 character(len=:),
allocatable :: charstr
420 integer(I4B) :: idx, ndim, nvals, pos, typ
421 character(len=:),
allocatable :: msg
423 msg =
'Variable '//trim(key)//
' is not a character array'
424 ndim = this%dim%get(key)
429 typ = this%typ%get(key)
434 idx = this%shp_idx%get(key)
435 pos = this%pos%get(key)
436 nvals = this%shp(idx)
437 allocate (
character(nvals) :: charstr)
438 read (this%inunit, pos=pos) charstr
448 character(len=*),
intent(in) :: key
449 character(len=:),
allocatable,
intent(inout) :: charstr
451 integer(I4B) :: idx, ndim, nvals, pos, typ
452 character(len=:),
allocatable :: msg
454 msg =
'Variable '//trim(key)//
' is not a character array'
455 ndim = this%dim%get(key)
460 typ = this%typ%get(key)
465 idx = this%shp_idx%get(key)
466 pos = this%pos%get(key)
467 nvals = this%shp(idx)
469 if (
allocated(charstr))
then
470 if (len(charstr) /= nvals)
then
472 allocate (
character(nvals) :: charstr)
475 allocate (
character(nvals) :: charstr)
477 read (this%inunit, pos=pos) charstr
485 integer(I4B),
allocatable :: v(:)
487 select case (this%grid_type)
490 v(1) = this%read_int(
"NLAY")
491 v(2) = this%read_int(
"NROW")
492 v(3) = this%read_int(
"NCOL")
495 v(1) = this%read_int(
"NLAY")
496 v(2) = this%read_int(
"NCPL")
499 v(1) = this%read_int(
"NODES")
502 v(1) = this%read_int(
"NROW")
503 v(2) = this%read_int(
"NCOL")
506 v(1) = this%read_int(
"NODES")
509 v(1) = this%read_int(
"NCELLS")
516 character(len=*),
intent(in) :: key
517 logical(LGP),
allocatable :: has
519 has = this%dim%get(key) /= 0
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
subroutine initialize(this, iu)
@Brief Initialize the grid file reader.
subroutine read_header(this)
Read the file's self-describing header. Internal use only.
subroutine read_header_meta(this)
Read self-describing metadata (first four lines). Internal use only.
subroutine read_charstr_into(this, key, charstr)
Read a character string into a preallocated string.
integer(i4b) function read_int(this, key)
Read an integer scalar from a grid file.
subroutine read_header_body(this)
Read the header body section (text following first.
subroutine finalize(this)
Finalize the grid file reader.
real(dp) function, dimension(:), allocatable read_dbl_1d(this, key)
Read a 1D double array from a grid file.
character(len=:) function, allocatable read_charstr(this, key)
Read a character string from a grid file.
integer(i4b) function, dimension(:), allocatable read_int_1d(this, key)
Read a 1D integer array from a grid file.
real(dp) function read_dbl(this, key)
Read a double precision scalar from a grid file.
subroutine read_int_1d_into(this, key, v)
Read a 1D integer array into a preallocated array.
logical(lgp) function, allocatable has_variable(this, key)
subroutine read_dbl_1d_into(this, key, v)
Read a 1D double array into a preallocated array.
integer(i4b) function, dimension(:), allocatable read_grid_shape(this)
Read the grid shape from a grid file.
A chaining hash map for integers.
subroutine, public hash_table_cr(map)
Create a hash table.
subroutine, public hash_table_da(map)
Deallocate the hash table.
This module defines variable data types.
This module contains simulation methods.
subroutine, public store_error(msg, terminate)
Store an error message.
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string