21 integer(I4B),
public :: inunit
23 character(len=10),
public :: grid_type
24 integer(I4B),
public :: version
26 integer(I4B) :: lentxt
29 character(len=10),
allocatable,
public :: names(:)
30 integer(I4B),
allocatable :: ndims(:)
31 integer(I4B),
allocatable :: typs(:)
32 integer(I4B),
allocatable :: shp_start(:)
33 integer(I8B),
allocatable :: pos(:)
34 integer(I4B),
allocatable :: shp(:)
63 integer(I4B),
intent(in) :: iu
67 allocate (this%shp(0))
68 call this%read_header()
78 if (
allocated(this%names))
deallocate (this%names)
79 if (
allocated(this%ndims))
deallocate (this%ndims)
80 if (
allocated(this%typs))
deallocate (this%typs)
81 if (
allocated(this%shp_start))
deallocate (this%shp_start)
82 if (
allocated(this%pos))
deallocate (this%pos)
83 if (
allocated(this%shp))
deallocate (this%shp)
90 call this%read_header_meta()
91 call this%read_header_body()
99 character(len=50) :: line
100 integer(I4B) :: lloc, istart, istop
105 read (this%inunit) line
107 call urword(line, lloc, istart, istop, 1, ival, rval, 0, 0)
108 if (line(istart:istop) /=
'GRID')
then
109 call store_error(
'Binary grid file must begin with "GRID". '//&
110 &
'Found: '//line(istart:istop))
113 call urword(line, lloc, istart, istop, 1, ival, rval, 0, 0)
114 this%grid_type = line(istart:istop)
117 read (this%inunit) line
119 call urword(line, lloc, istart, istop, 0, ival, rval, 0, 0)
120 call urword(line, lloc, istart, istop, 2, ival, rval, 0, 0)
124 read (this%inunit) line
126 call urword(line, lloc, istart, istop, 0, ival, rval, 0, 0)
127 call urword(line, lloc, istart, istop, 2, ival, rval, 0, 0)
131 read (this%inunit) line
133 call urword(line, lloc, istart, istop, 0, ival, rval, 0, 0)
134 call urword(line, lloc, istart, istop, 2, ival, rval, 0, 0)
145 character(len=:),
allocatable :: body
146 character(len=:),
allocatable :: line
147 character(len=10) :: name, dtype
149 integer(I4B) :: i, lloc, istart, istop, ival
150 integer(I4B) :: ivar, ndim, dim, ishp, nbytes
153 allocate (this%names(this%ntxt))
154 allocate (this%ndims(this%ntxt))
155 allocate (this%typs(this%ntxt))
156 allocate (this%shp_start(this%ntxt))
157 allocate (this%pos(this%ntxt))
158 allocate (
character(len=this%lentxt*this%ntxt) :: body)
159 allocate (
character(len=this%lentxt) :: line)
161 read (this%inunit) body
162 inquire (this%inunit, pos=pos)
163 do ivar = 1, this%ntxt
164 i = (ivar - 1) * this%lentxt + 1
165 line = body(i:i + this%lentxt - 1)
169 call urword(line, lloc, istart, istop, 1, ival, rval, 0, 0)
170 name = line(istart:istop)
171 this%names(ivar) = name
172 call this%idx%add(name, ivar)
175 call urword(line, lloc, istart, istop, 1, ival, rval, 0, 0)
176 dtype = line(istart:istop)
193 call urword(line, lloc, istart, istop, 0, ival, rval, 0, 0)
194 call urword(line, lloc, istart, istop, 2, ival, rval, 0, 0)
196 this%ndims(ivar) = ndim
199 this%shp_start(ivar) = 0
201 ishp =
size(this%shp)
204 call urword(line, lloc, istart, istop, 2, ival, rval, 0, 0)
205 this%shp(ishp + dim) = ival
207 this%shp_start(ivar) = ishp + 1
215 ishp = this%shp_start(ivar)
216 pos = pos + product(int(this%shp(ishp:ishp + ndim - 1), i8b)) * nbytes
230 function lookup(this, name, ndim, typ, desc)
result(ivar)
232 character(len=*),
intent(in) :: name
233 integer(I4B),
intent(in) :: ndim
234 integer(I4B),
intent(in) :: typ
235 character(len=*),
intent(in) :: desc
238 ivar = this%idx%get(name)
240 write (
errmsg,
'(a)')
'Variable '//trim(name)//
' not found'
243 if (this%ndims(ivar) /= ndim .or. this%typs(ivar) /= typ)
then
244 write (
errmsg,
'(a)')
'Variable '//trim(name)//
' is not '//desc
252 character(len=*),
intent(in) :: name
257 ivar = this%lookup(name, 0,
typ_int,
'an integer scalar')
258 read (this%inunit, pos=this%pos(ivar)) v
265 character(len=*),
intent(in) :: name
270 ivar = this%lookup(name, 0,
typ_dbl,
'a double precision scalar')
271 read (this%inunit, pos=this%pos(ivar)) v
281 character(len=*),
intent(in) :: name
282 integer(I4B),
allocatable :: v(:)
284 integer(I4B) :: ivar, nvals
286 ivar = this%lookup(name, 1,
typ_int,
'a 1D integer array')
287 nvals = this%shp(this%shp_start(ivar))
289 read (this%inunit, pos=this%pos(ivar)) v
301 character(len=*),
intent(in) :: name
302 integer(I4B),
dimension(:),
intent(inout) :: v
304 integer(I4B) :: ivar, nvals
306 ivar = this%lookup(name, 1,
typ_int,
'a 1D integer array')
307 nvals = this%shp(this%shp_start(ivar))
308 if (
size(v) /= nvals)
then
309 write (
errmsg,
'(a,i0,a,i0)') &
310 'Array size mismatch for '//trim(name)//
': expected ', &
311 nvals,
', got ',
size(v)
314 read (this%inunit, pos=this%pos(ivar)) v
324 character(len=*),
intent(in) :: name
325 real(dp),
allocatable :: v(:)
327 integer(I4B) :: ivar, nvals
329 ivar = this%lookup(name, 1,
typ_dbl,
'a 1D double array')
330 nvals = this%shp(this%shp_start(ivar))
332 read (this%inunit, pos=this%pos(ivar)) v
344 character(len=*),
intent(in) :: name
345 real(DP),
dimension(:),
intent(inout) :: v
347 integer(I4B) :: ivar, nvals
349 ivar = this%lookup(name, 1,
typ_dbl,
'a 1D double array')
350 nvals = this%shp(this%shp_start(ivar))
351 if (
size(v) /= nvals)
then
352 write (
errmsg,
'(a,i0,a,i0)') &
353 'Array size mismatch for '//trim(name)//
': expected ', &
354 nvals,
', got ',
size(v)
357 read (this%inunit, pos=this%pos(ivar)) v
367 character(len=*),
intent(in) :: name
368 character(len=:),
allocatable :: charstr
370 integer(I4B) :: ivar, nvals
372 ivar = this%lookup(name, 1,
typ_chr,
'a character array')
373 nvals = this%shp(this%shp_start(ivar))
374 allocate (
character(nvals) :: charstr)
375 read (this%inunit, pos=this%pos(ivar)) charstr
386 character(len=*),
intent(in) :: name
387 character(len=:),
allocatable,
intent(inout) :: charstr
389 integer(I4B) :: ivar, nvals
391 ivar = this%lookup(name, 1,
typ_chr,
'a character array')
392 nvals = this%shp(this%shp_start(ivar))
393 if (
allocated(charstr))
then
394 if (len(charstr) /= nvals)
deallocate (charstr)
396 if (.not.
allocated(charstr))
allocate (
character(nvals) :: charstr)
397 read (this%inunit, pos=this%pos(ivar)) charstr
405 integer(I4B),
allocatable :: v(:)
407 select case (this%grid_type)
410 v(1) = this%read_int(
"NLAY")
411 v(2) = this%read_int(
"NROW")
412 v(3) = this%read_int(
"NCOL")
415 v(1) = this%read_int(
"NLAY")
416 v(2) = this%read_int(
"NCPL")
419 v(1) = this%read_int(
"NODES")
422 v(1) = this%read_int(
"NROW")
423 v(2) = this%read_int(
"NCOL")
426 v(1) = this%read_int(
"NODES")
429 v(1) = this%read_int(
"NCELLS")
437 character(len=*),
intent(in) :: name
440 has = this%idx%get(name) /= 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.
integer(i4b) function, dimension(:), allocatable read_int_1d(this, name)
Read a 1D integer array from a grid file.
integer(i4b), parameter typ_dbl
double precision variable type
subroutine read_int_1d_into(this, name, v)
Read a 1D integer array into a preallocated array.
subroutine read_header_meta(this)
Read self-describing metadata (first four lines). Internal use only.
integer(i4b), parameter typ_chr
character variable type
subroutine read_charstr_into(this, name, charstr)
Read a character string into a preallocated string.
subroutine read_header_body(this)
Read the header body section (text following first.
integer(i4b), parameter typ_int
integer variable type
subroutine finalize(this)
Finalize the grid file reader.
character(len=:) function, allocatable read_charstr(this, name)
Read a character string from a grid file.
integer(i4b) function read_int(this, name)
Read an integer scalar from a grid file.
real(dp) function read_dbl(this, name)
Read a double precision scalar from a grid file.
integer(i4b) function lookup(this, name, ndim, typ, desc)
Look up a variable and check its rank and type.
subroutine read_dbl_1d_into(this, name, v)
Read a 1D double array into a preallocated array.
logical(lgp) function has_variable(this, name)
Check whether the grid file contains a variable.
real(dp) function, dimension(:), allocatable read_dbl_1d(this, name)
Read a 1D double array from a grid file.
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