MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
ArrayReaders.f90
Go to the documentation of this file.
2 
5  dzero
9  use kindmodule, only: dp, i4b, lgp
10  use openspecmodule, only: access, form
12  use simvariablesmodule, only: errmsg
13 
14  implicit none
15 
16  private
17  public :: readarray
18  public :: read_binary_header
19  public :: check_binary_filesize
20  public :: binary_int_bytes
21  public :: binary_double_bytes
22  public :: binary_header_bytes
23 
24  integer(I4B), parameter :: binary_char_bytes = 1
25  integer(I4B), parameter :: binary_int_bytes = 4
26  integer(I4B), parameter :: binary_double_bytes = 8
27  integer(I4B), parameter :: binary_strlen = 16
28  integer(I4B), parameter :: binary_header_bytes = &
29  (5 * binary_int_bytes) + & !< kstp, kper, msize1, msize2, msize3
30  (2 * binary_double_bytes) + & !< pertim, totim
31  (binary_strlen * binary_char_bytes) !< array text
32 
33  interface readarray
34  module procedure &
45  end interface readarray
46 
47  ! Integer readers
48  ! read_array_int1d(iu, iarr, aname, ndim, jj, iout, k)
49  ! read_array_int1d_layered(iu, iarr, aname, ndim, ncol, nrow, nlay, nval, iout, k1, k2)
50  ! read_array_int2d(iu, iarr, aname, ndim, jj, ii, iout, k)
51  ! read_array_int3d(iu, iarr, aname, ndim, ncol, nrow, nlay, iout, k1, k2)
52  ! read_array_int3d_all(iu, iarr, aname, ndim, nvals, iout)
53  !
54  ! Floating-point readers
55  ! read_array_dbl1d(iu, darr, aname, ndim, jj, iout, k)
56  ! read_array_dbl1d_layered(iu, darr, aname, ndim, ncol, nrow, nlay, nval, iout, k1, k2)
57  ! read_array_dbl2d(iu, darr, aname, ndim, jj, ii, iout, k)
58  ! read_array_dbl3d(iu, darr, aname, ndim, ncol, nrow, nlay, iout, k1, k2)
59  ! read_array_dbl3d_all(iu, darr, aname, ndim, nvals, iout)
60 
61 contains
62 
63  ! -- Procedures that are part of ReadArray interface (integer data)
64 
65  subroutine read_array_int1d(iu, iarr, aname, ndim, jj, iout, k)
66  ! -- dummy
67  integer(I4B), intent(in) :: iu, iout
68  integer(I4B), intent(in) :: jj
69  integer(I4B), dimension(jj), intent(inout) :: iarr
70  character(len=*), intent(in) :: aname
71  integer(I4B), intent(in) :: ndim ! dis%ndim
72  integer(I4B), intent(in) :: k ! layer number; 0 to not print
73  ! -- local
74  logical(LGP) :: isok
75  integer(I4B) :: iclose, iconst, iprn, j, locat, ncpl, ndig
76  integer(I4B) :: nval, nvalt
77  logical :: prowcolnum
78  character(len=100) :: prfmt
79  integer(I4B) :: istat
80  character(len=30) :: arrname
81  character(len=MAXCHARLEN) :: ermsgr
82  ! -- formats
83 2 format(/, 1x, a, ' = ', i0, ' FOR LAYER ', i0)
84 3 format(/, 1x, a, ' = ', i0)
85  !
86  ! -- Read array control record.
87  call read_control_int(iu, iout, aname, locat, iconst, iclose, iprn)
88  !
89  ! -- Read or assign array data.
90  if (locat == 0) then
91  ! -- Assign constant
92  do j = 1, jj
93  iarr(j) = iconst
94  end do
95  if (iout > 0) then
96  if (k > 0) then
97  write (iout, 2) trim(aname), iconst, k
98  else
99  write (iout, 3) trim(aname), iconst
100  end if
101  end if
102  elseif (locat > 0) then
103  ! -- Read data as text
104  read (locat, *, iostat=istat, iomsg=ermsgr) (iarr(j), j=1, jj)
105  if (istat /= 0) then
106  arrname = adjustl(aname)
107  errmsg = "Error reading data for array '"//trim(arrname)// &
108  "'. "//trim(adjustl(ermsgr))
109  call store_error(errmsg)
110  call store_error_unit(locat)
111  end if
112  do j = 1, jj
113  iarr(j) = iarr(j) * iconst
114  end do
115  if (iclose == 1) then
116  close (locat)
117  end if
118  else
119  ! -- Read data as binary
120  locat = -locat
121  nvalt = 0
122  do
123  call read_binary_header(locat, iout, aname, nval)
124  isok = check_binary_size(nval, nvalt, size(iarr), aname, locat)
125  if (isok .EQV. .false.) exit
126  read (locat, iostat=istat, iomsg=ermsgr) &
127  (iarr(j), j=nvalt + 1, nvalt + nval)
128  if (istat /= 0) then
129  arrname = adjustl(aname)
130  errmsg = "Error reading data for array '"//trim(arrname)// &
131  "'. "//trim(adjustl(ermsgr))
132  call store_error(errmsg)
133  call store_error_unit(locat)
134  end if
135  nvalt = nvalt + nval
136  if (nvalt == size(iarr)) exit
137  end do
138  !
139  ! -- multiply array by constant
140  do j = 1, jj
141  iarr(j) = iarr(j) * iconst
142  end do
143  !
144  ! -- close the file
145  if (iclose == 1) then
146  close (locat)
147  end if
148  end if
149  !
150  ! -- Print array if requested.
151  if (iprn >= 0 .and. locat /= 0) then
152  prowcolnum = (ndim == 3)
153  call build_format_int(iprn, prfmt, prowcolnum, ncpl, ndig)
154  call print_array_int(iarr, aname, iout, jj, 1, k, prfmt, ncpl, ndig, &
155  prowcolnum)
156  end if
157  end subroutine read_array_int1d
158 
159  subroutine read_array_int2d(iu, iarr, aname, ndim, jj, ii, iout, k)
160  ! -- dummy
161  integer(I4B), intent(in) :: iu, iout
162  integer(I4B), intent(in) :: jj, ii
163  integer(I4B), dimension(jj, ii), intent(inout) :: iarr
164  character(len=*), intent(in) :: aname
165  integer(I4B), intent(in) :: ndim ! dis%ndim
166  integer(I4B), intent(in) :: k ! layer number; 0 to not print
167  ! -- local
168  logical(LGP) :: isok
169  integer(I4B) :: i, iclose, iconst, iprn, j, locat, ncpl, ndig
170  integer(I4B) :: nval
171  logical :: prowcolnum
172  character(len=100) :: prfmt
173  integer(I4B) :: istat
174  character(len=30) :: arrname
175  character(len=MAXCHARLEN) :: ermsgr
176  ! -- formats
177 2 format(/, 1x, a, ' = ', i0, ' FOR LAYER ', i0)
178 3 format(/, 1x, a, ' = ', i0)
179  !
180  ! -- Read array control record.
181  call read_control_int(iu, iout, aname, locat, iconst, iclose, iprn)
182  !
183  ! -- Read or assign array data.
184  if (locat == 0) then
185  ! -- Assign constant
186  do i = 1, ii
187  do j = 1, jj
188  iarr(j, i) = iconst
189  end do
190  end do
191  if (iout > 0) then
192  if (k > 0) then
193  write (iout, 2) trim(aname), iconst, k
194  else
195  write (iout, 3) trim(aname), iconst
196  end if
197  end if
198  elseif (locat > 0) then
199  ! -- Read data as text
200  do i = 1, ii
201  read (locat, *, iostat=istat, iomsg=ermsgr) (iarr(j, i), j=1, jj)
202  if (istat /= 0) then
203  arrname = adjustl(aname)
204  errmsg = "Error reading data for array '"//trim(arrname)// &
205  "'. "//trim(adjustl(ermsgr))
206  call store_error(errmsg)
207  call store_error_unit(locat)
208  end if
209  do j = 1, jj
210  iarr(j, i) = iarr(j, i) * iconst
211  end do
212  end do
213  if (iclose == 1) then
214  close (locat)
215  end if
216  else
217  ! -- Read data as binary
218  locat = -locat
219  call read_binary_header(locat, iout, aname, nval)
220  isok = check_binary_size(nval, 0, size(iarr), aname, locat)
221  if (isok) then
222  do i = 1, ii
223  read (locat, iostat=istat, iomsg=ermsgr) (iarr(j, i), j=1, jj)
224  if (istat /= 0) then
225  arrname = adjustl(aname)
226  errmsg = "Error reading data for array '"//trim(arrname)// &
227  "'. "//trim(adjustl(ermsgr))
228  call store_error(errmsg)
229  call store_error_unit(locat)
230  end if
231  do j = 1, jj
232  iarr(j, i) = iarr(j, i) * iconst
233  end do
234  end do
235  end if
236  if (iclose == 1) then
237  close (locat)
238  end if
239  end if
240  !
241  ! -- Print array if requested.
242  if (iprn >= 0 .and. locat /= 0) then
243  prowcolnum = (ndim == 3)
244  call build_format_int(iprn, prfmt, prowcolnum, ncpl, ndig)
245  call print_array_int(iarr, aname, iout, jj, ii, k, prfmt, ncpl, &
246  ndig, prowcolnum)
247  end if
248  end subroutine read_array_int2d
249 
250  subroutine read_array_int3d(iu, iarr, aname, ndim, ncol, nrow, nlay, iout, &
251  k1, k2)
252  integer(I4B), intent(in) :: iu
253  integer(I4B), intent(in) :: iout
254  integer(I4B), intent(in) :: ndim
255  integer(I4B), intent(in) :: ncol
256  integer(I4B), intent(in) :: nrow
257  integer(I4B), intent(in) :: nlay
258  integer(I4B), intent(in) :: k1, k2
259  integer(I4B), dimension(ncol, nrow, nlay), intent(inout) :: iarr
260  character(len=*), intent(in) :: aname
261  ! -- local
262  integer(I4B) :: k, kk
263  do k = k1, k2
264  if (k <= 0) then
265  kk = 1
266  else
267  kk = k
268  end if
269  call read_array_int2d(iu, iarr(:, :, kk), aname, ndim, ncol, nrow, iout, k)
270  end do
271  end subroutine read_array_int3d
272 
273  subroutine read_array_int3d_all(iu, iarr, aname, ndim, nvals, iout)
274  integer(I4B), intent(in) :: iu
275  integer(I4B), intent(in) :: iout
276  integer(I4B), intent(in) :: ndim
277  integer(I4B), intent(in) :: nvals
278  integer(I4B), dimension(nvals, 1, 1), intent(inout) :: iarr
279  character(len=*), intent(in) :: aname
280  ! -- local
281  !
282  call read_array_int1d(iu, iarr, aname, ndim, nvals, iout, 0)
283  end subroutine read_array_int3d_all
284 
285  subroutine read_array_int1d_layered(iu, iarr, aname, ndim, ncol, nrow, &
286  nlay, nval, iout, k1, k2)
287  ! -- dummy
288  integer(I4B), intent(in) :: iu, iout
289  integer(I4B), intent(in) :: ncol, nrow, nlay, nval
290  integer(I4B), dimension(nval), intent(inout) :: iarr
291  character(len=*), intent(in) :: aname
292  integer(I4B), intent(in) :: ndim ! dis%ndim
293  integer(I4B), intent(in) :: k1, k2
294  ! -- local
295  !
296  call read_array_int3d(iu, iarr, aname, ndim, ncol, nrow, nlay, iout, k1, k2)
297  end subroutine read_array_int1d_layered
298 
299  ! -- Procedures that are part of ReadArray interface (floating-point data)
300 
301  subroutine read_array_dbl1d(iu, darr, aname, ndim, jj, iout, k)
302  ! -- dummy
303  integer(I4B), intent(in) :: iu, iout
304  integer(I4B), intent(in) :: jj
305  real(DP), dimension(jj), intent(inout) :: darr
306  character(len=*), intent(in) :: aname
307  integer(I4B), intent(in) :: ndim ! dis%ndim
308  integer(I4B), intent(in) :: k ! layer number; 0 to not print
309  ! -- local
310  logical(LGP) :: isok
311  integer(I4B) :: j, iclose, iprn, locat, ncpl, ndig
312  real(DP) :: cnstnt
313  logical :: prowcolnum
314  character(len=100) :: prfmt
315  integer(I4B) :: istat
316  integer(I4B) :: nvalt, nval
317  character(len=30) :: arrname
318  character(len=MAXCHARLEN) :: ermsgr
319  ! -- formats
320 2 format(/, 1x, a, ' = ', g14.7, ' FOR LAYER ', i0)
321 3 format(/, 1x, a, ' = ', g14.7)
322  !
323  ! -- Read array control record.
324  call read_control_dbl(iu, iout, aname, locat, cnstnt, iclose, iprn)
325  !
326  ! -- Read or assign array data.
327  if (locat == 0) then
328  ! -- Assign constant
329  do j = 1, jj
330  darr(j) = cnstnt
331  end do
332  if (iout > 0) then
333  if (k > 0) then
334  write (iout, 2) trim(aname), cnstnt, k
335  else
336  write (iout, 3) trim(aname), cnstnt
337  end if
338  end if
339  elseif (locat > 0) then
340  ! -- Read data as text
341  read (locat, *, iostat=istat, iomsg=ermsgr) (darr(j), j=1, jj)
342  if (istat /= 0) then
343  arrname = adjustl(aname)
344  errmsg = "Error reading data for array '"// &
345  trim(adjustl(arrname))//"'. "//trim(adjustl(ermsgr))
346  call store_error(errmsg)
347  call store_error_unit(locat)
348  end if
349  do j = 1, jj
350  darr(j) = darr(j) * cnstnt
351  end do
352  if (iclose == 1) then
353  close (locat)
354  end if
355  else
356  ! -- Read data as binary
357  locat = -locat
358  nvalt = 0
359  do
360  call read_binary_header(locat, iout, aname, nval)
361  isok = check_binary_size(nval, nvalt, size(darr), aname, locat)
362  if (isok .EQV. .false.) exit
363  read (locat, iostat=istat, iomsg=ermsgr) &
364  (darr(j), j=nvalt + 1, nvalt + nval)
365  if (istat /= 0) then
366  arrname = adjustl(aname)
367  errmsg = "Error reading data for array '"// &
368  trim(adjustl(arrname))//"'. "//trim(adjustl(ermsgr))
369  call store_error(errmsg)
370  call store_error_unit(locat)
371  end if
372  nvalt = nvalt + nval
373  if (nvalt == size(darr)) exit
374  end do
375  !
376  ! -- multiply entire array by constant
377  do j = 1, jj
378  darr(j) = darr(j) * cnstnt
379  end do
380  !
381  ! -- close the file
382  if (iclose == 1) then
383  close (locat)
384  end if
385  end if
386  !
387  ! -- Print array if requested.
388  if (iprn >= 0 .and. locat /= 0) then
389  prowcolnum = (ndim == 3)
390  call build_format_dbl(iprn, prfmt, prowcolnum, ncpl, ndig)
391  call print_array_dbl(darr, aname, iout, jj, 1, k, prfmt, ncpl, ndig, &
392  prowcolnum)
393  end if
394  end subroutine read_array_dbl1d
395 
396  subroutine read_array_dbl2d(iu, darr, aname, ndim, jj, ii, iout, k)
397  ! -- dummy
398  integer(I4B), intent(in) :: iu, iout
399  integer(I4B), intent(in) :: jj, ii
400  real(DP), dimension(jj, ii), intent(inout) :: darr
401  character(len=*), intent(in) :: aname
402  integer(I4B), intent(in) :: ndim ! dis%ndim
403  integer(I4B), intent(in) :: k ! layer number; 0 to not print
404  ! -- local
405  logical(LGP) :: isok
406  integer(I4B) :: i, iclose, iprn, j, locat, ncpl, ndig
407  integer(I4B) :: nval
408  real(DP) :: cnstnt
409  logical :: prowcolnum
410  character(len=100) :: prfmt
411  integer(I4B) :: istat
412  character(len=30) :: arrname
413  character(len=MAXCHARLEN) :: ermsgr
414  ! -- formats
415 2 format(/, 1x, a, ' = ', g14.7, ' FOR LAYER ', i0)
416 3 format(/, 1x, a, ' = ', g14.7)
417  !
418  ! -- Read array control record.
419  call read_control_dbl(iu, iout, aname, locat, cnstnt, iclose, iprn)
420  !
421  ! -- Read or assign array data.
422  if (locat == 0) then
423  ! -- Assign constant
424  do i = 1, ii
425  do j = 1, jj
426  darr(j, i) = cnstnt
427  end do
428  end do
429  if (iout > 0) then
430  if (k > 0) then
431  write (iout, 2) trim(aname), cnstnt, k
432  else
433  write (iout, 3) trim(aname), cnstnt
434  end if
435  end if
436  elseif (locat > 0) then
437  ! -- Read data as text
438  do i = 1, ii
439  read (locat, *, iostat=istat, iomsg=ermsgr) (darr(j, i), j=1, jj)
440  if (istat /= 0) then
441  arrname = adjustl(aname)
442  errmsg = "Error reading data for array '"// &
443  trim(adjustl(arrname))//"'. "//trim(adjustl(ermsgr))
444  call store_error(errmsg)
445  call store_error_unit(locat)
446  end if
447  do j = 1, jj
448  darr(j, i) = darr(j, i) * cnstnt
449  end do
450  end do
451  if (iclose == 1) then
452  close (locat)
453  end if
454  else
455  ! -- Read data as binary
456  locat = -locat
457  call read_binary_header(locat, iout, aname, nval)
458  isok = check_binary_size(nval, 0, size(darr), aname, locat)
459  if (isok) then
460  do i = 1, ii
461  read (locat, iostat=istat, iomsg=ermsgr) (darr(j, i), j=1, jj)
462  if (istat /= 0) then
463  arrname = adjustl(aname)
464  errmsg = "Error reading data for array '"// &
465  trim(adjustl(arrname))//"'. "//trim(adjustl(ermsgr))
466  call store_error(errmsg)
467  call store_error_unit(locat)
468  end if
469  do j = 1, jj
470  darr(j, i) = darr(j, i) * cnstnt
471  end do
472  end do
473  end if
474  if (iclose == 1) then
475  close (locat)
476  end if
477  end if
478  !
479  ! -- Print array if requested.
480  if (iprn >= 0 .and. locat /= 0) then
481  prowcolnum = (ndim == 3)
482  call build_format_dbl(iprn, prfmt, prowcolnum, ncpl, ndig)
483  call print_array_dbl(darr, aname, iout, jj, ii, k, prfmt, ncpl, &
484  ndig, prowcolnum)
485  end if
486  end subroutine read_array_dbl2d
487 
488  subroutine read_array_dbl3d(iu, darr, aname, ndim, ncol, nrow, nlay, iout, &
489  k1, k2)
490  integer(I4B), intent(in) :: iu
491  integer(I4B), intent(in) :: iout
492  integer(I4B), intent(in) :: ndim
493  integer(I4B), intent(in) :: ncol
494  integer(I4B), intent(in) :: nrow
495  integer(I4B), intent(in) :: nlay
496  integer(I4B), intent(in) :: k1, k2
497  real(DP), dimension(ncol, nrow, nlay), intent(inout) :: darr
498  character(len=*), intent(in) :: aname
499  ! -- local
500  integer(I4B) :: k, kk
501  !
502  do k = k1, k2
503  if (k <= 0) then
504  kk = 1
505  else
506  kk = k
507  end if
508  call read_array_dbl2d(iu, darr(:, :, kk), aname, ndim, ncol, nrow, iout, k)
509  end do
510  end subroutine read_array_dbl3d
511 
512  subroutine read_array_dbl3d_all(iu, darr, aname, ndim, nvals, iout)
513  integer(I4B), intent(in) :: iu
514  integer(I4B), intent(in) :: iout
515  integer(I4B), intent(in) :: ndim
516  integer(I4B), intent(in) :: nvals
517  real(DP), dimension(nvals, 1, 1), intent(inout) :: darr
518  character(len=*), intent(in) :: aname
519  ! -- local
520  !
521  call read_array_dbl1d(iu, darr, aname, ndim, nvals, iout, 0)
522  end subroutine read_array_dbl3d_all
523 
524  subroutine read_array_dbl1d_layered(iu, darr, aname, ndim, ncol, nrow, &
525  nlay, nval, iout, k1, k2)
526  ! -- dummy
527  integer(I4B), intent(in) :: iu, iout
528  integer(I4B), intent(in) :: ncol, nrow, nlay, nval
529  real(DP), dimension(nval), intent(inout) :: darr
530  character(len=*), intent(in) :: aname
531  integer(I4B), intent(in) :: ndim ! dis%ndim
532  integer(I4B), intent(in) :: k1, k2
533  ! -- local
534  !
535  call read_array_dbl3d(iu, darr, aname, ndim, ncol, nrow, nlay, iout, k1, k2)
536  end subroutine read_array_dbl1d_layered
537 
538  ! -- Utility procedures
539 
540  subroutine read_control_int(iu, iout, aname, locat, iconst, &
541  iclose, iprn)
542  ! Read an array-control record for an integer array.
543  ! Open an input file if needed.
544  ! If CONSTANT is specified in input, locat is returned as 0.
545  ! If (BINARY) is specified, locat is returned as the negative of
546  ! the unit number opened for binary read.
547  ! If OPEN/CLOSE is specified, iclose is returned as 1, otherwise 0.
548  ! -- dummy
549  integer(I4B), intent(in) :: iu
550  integer(I4B), intent(in) :: iout
551  character(len=*), intent(in) :: aname
552  integer(I4B), intent(out) :: locat
553  integer(I4B), intent(out) :: iconst
554  integer(I4B), intent(out) :: iclose
555  integer(I4B), intent(out) :: iprn
556  ! -- local
557  integer(I4B) :: icol, icol1, istart, istop, n
558  real(DP) :: r
559  character(len=MAXCHARLEN) :: fname
560  character(len=:), allocatable :: line
561  !
562  ! -- Read CONSTANT, INTERNAL, or OPEN/CLOSE from array control record.
563  call read_control_1(iu, iout, aname, locat, iclose, line, icol, fname)
564  if (locat == 0) then
565  ! CONSTANT was found -- read value and return
566  call urword(line, icol, istart, istop, 2, iconst, r, iout, iu)
567  iprn = -1
568  return
569  end if
570  icol1 = icol
571  iconst = 1
572  !
573  ! -- Read FACTOR option from array control record.
574  call urword(line, icol, istart, istop, 1, n, r, iout, iu)
575  if (line(istart:istop) == 'FACTOR') then
576  call urword(line, icol, istart, istop, 2, iconst, r, iout, iu)
577  if (iconst == 0) iconst = 1
578  else
579  icol = icol1
580  end if
581  !
582  ! -- Read (BINARY) and IPRN options from array control record,
583  ! and open an OPEN/CLOSE file if specified.
584  call read_control_2(iu, iout, fname, line, icol, locat, iclose, iprn)
585  end subroutine read_control_int
586 
587  subroutine read_control_dbl(iu, iout, aname, locat, cnstnt, &
588  iclose, iprn)
589  ! Read an array-control record for a double-precision array.
590  ! Open an input file if needed.
591  ! If CONSTANT is specified in input, locat is returned as 0.
592  ! If (BINARY) is specified, locat is returned as the negative of
593  ! the unit number opened for binary read.
594  ! If OPEN/CLOSE is specified, iclose is returned as 1, otherwise 0.
595  ! -- dummy
596  integer(I4B), intent(in) :: iu
597  integer(I4B), intent(in) :: iout
598  character(len=*), intent(in) :: aname
599  integer(I4B), intent(out) :: locat
600  real(DP), intent(out) :: cnstnt
601  integer(I4B), intent(out) :: iclose
602  integer(I4B), intent(out) :: iprn
603  !
604  ! -- local
605  integer(I4B) :: icol, icol1, istart, istop, n
606  real(DP) :: r
607  character(len=MAXCHARLEN) :: fname
608  character(len=:), allocatable :: line
609  !
610  ! -- Read CONSTANT, INTERNAL, or OPEN/CLOSE from array control record.
611  call read_control_1(iu, iout, aname, locat, iclose, line, icol, fname)
612  if (locat == 0) then
613  ! CONSTANT was found -- read value and return
614  call urword(line, icol, istart, istop, 3, n, cnstnt, iout, iu)
615  iprn = -1
616  return
617  end if
618  icol1 = icol
619  cnstnt = done
620  !
621  ! -- Read FACTOR option from array control record.
622  call urword(line, icol, istart, istop, 1, n, r, iout, iu)
623  if (line(istart:istop) == 'FACTOR') then
624  call urword(line, icol, istart, istop, 3, n, cnstnt, iout, iu)
625  if (cnstnt == dzero) cnstnt = done
626  else
627  icol = icol1
628  end if
629  !
630  ! -- Read (BINARY) and IPRN options from array control record,
631  ! and open an OPEN/CLOSE file if specified.
632  call read_control_2(iu, iout, fname, line, icol, locat, iclose, iprn)
633  end subroutine read_control_dbl
634 
635  subroutine read_control_1(iu, iout, aname, locat, iclose, line, icol, fname)
636  use simmodule, only: ustop
637  ! -- Read CONSTANT, INTERNAL, or OPEN/CLOSE from array control record.
638  ! -- dummy
639  integer(I4B), intent(in) :: iu
640  integer(I4B), intent(in) :: iout
641  character(len=*), intent(in) :: aname
642  integer(I4B), intent(out) :: locat
643  integer(I4B), intent(out) :: iclose
644  character(len=:), allocatable, intent(inout) :: line
645  integer(I4B), intent(inout) :: icol
646  character(len=*), intent(inout) :: fname
647 
648  ! -- local
649  integer(I4B) :: istart, istop, n
650  integer(I4B) :: ierr
651  real(DP) :: r
652  !
653  ! -- Read array control record. Any future refactoring
654  ! should use the LongLineReader here instead of u9rdcom
655  call u9rdcom(iu, iout, line, ierr)
656  !
657  iclose = 0
658  icol = 1
659  ! -- Read first token of array control record.
660  call urword(line, icol, istart, istop, 1, n, r, iout, iu)
661  if (line(istart:istop) .eq. 'CONSTANT') then
662  locat = 0
663  elseif (line(istart:istop) .eq. 'INTERNAL') then
664  locat = iu
665  elseif (line(istart:istop) .eq. 'OPEN/CLOSE') then
666  call urword(line, icol, istart, istop, 0, n, r, iout, iu)
667  fname = line(istart:istop)
668  locat = -1
669  iclose = 1
670  else
671  errmsg = 'READING CONTROL RECORD FOR '// &
672  trim(adjustl(aname))//"'. "// &
673  'Use CONSTANT, INTERNAL, or OPEN/CLOSE.'
674  call store_error(errmsg)
675  call store_error_unit(iu)
676  end if
677  end subroutine read_control_1
678 
679  subroutine read_control_2(iu, iout, fname, line, icol, &
680  locat, iclose, iprn)
681  ! -- Read (BINARY) and IPRN options from array control record,
682  ! and open an OPEN/CLOSE file if specified.
683  ! -- dummy
684  integer(I4B), intent(in) :: iu, iout, iclose
685  character(len=*), intent(in) :: fname
686  character(len=*), intent(inout) :: line
687  integer(I4B), intent(inout) :: icol, iprn, locat
688  ! -- local
689  integer(I4B) :: i, n, istart, istop, lenkey
690  real(DP) :: r
691  character(len=MAXCHARLEN) :: keyword
692  logical :: binary
693  !
694  iprn = -1 ! Printing is turned off by default
695  binary = .false.
696  !
697  if (locat .ne. 0) then
698  ! -- CONSTANT has not been specified; array data will be read.
699  ! -- Read at most two options.
700  do i = 1, 2
701  call urword(line, icol, istart, istop, 1, n, r, iout, iu)
702  keyword = line(istart:istop)
703  lenkey = len_trim(keyword)
704  select case (keyword)
705  case ('(BINARY)')
706  if (iclose == 0) then
707  errmsg = '"(BINARY)" option for array input is valid only if'// &
708  ' OPEN/CLOSE is also specified.'
709  call store_error(errmsg)
710  call store_error_unit(iu)
711  end if
712  binary = .true.
713  case ('IPRN')
714  ! -- Read IPRN value
715  call urword(line, icol, istart, istop, 2, iprn, r, iout, iu)
716  exit
717  case ('')
718  exit
719  case default
720  errmsg = 'Invalid option found in array-control record: "' &
721  //trim(keyword)//'"'
722  call store_error(errmsg)
723  call store_error_unit(iu)
724  end select
725  end do
726  !
727  if (iclose == 0) then
728  ! -- Array data will be read from current input file.
729  locat = iu
730  else
731  ! -- Open the OPEN\CLOSE file
732  if (binary) then
733  call openfile(locat, iout, fname, 'OPEN/CLOSE', fmtarg_opt=form, &
734  accarg_opt=access)
735  locat = -locat
736  else
737  call openfile(locat, iout, fname, 'OPEN/CLOSE')
738  end if
739  end if
740  end if
741  end subroutine read_control_2
742 
743  subroutine build_format_int(iprn, prfmt, prowcolnum, ncpl, ndig)
744  ! -- Build a print format for integers based on IPRN.
745  ! -- dummy
746  integer(I4B), intent(inout) :: iprn
747  character(len=*), intent(out) :: prfmt
748  logical, intent(in) :: prowcolnum
749  integer(I4B), intent(out) :: ncpl, ndig
750  ! -- local
751  integer(I4B) :: nwidp
752  !
753  if (iprn < 0) then
754  prfmt = ''
755  return
756  end if
757  !
758  if (iprn > 9) iprn = 0
759  !
760  select case (iprn)
761  case (0)
762  ncpl = 10
763  nwidp = 11
764  case (1)
765  ncpl = 60
766  nwidp = 1
767  case (2)
768  ncpl = 40
769  nwidp = 2
770  case (3)
771  ncpl = 30
772  nwidp = 3
773  case (4)
774  ncpl = 25
775  nwidp = 4
776  case (5)
777  ncpl = 20
778  nwidp = 5
779  case (6)
780  ncpl = 10
781  nwidp = 11
782  case (7)
783  ncpl = 25
784  nwidp = 2
785  case (8)
786  ncpl = 15
787  nwidp = 4
788  case (9)
789  ncpl = 19
790  nwidp = 6
791  end select
792  !
793  call buildintformat(ncpl, nwidp, prfmt, prowcolnum)
794  ndig = nwidp + 1
795  end subroutine build_format_int
796 
797  subroutine build_format_dbl(iprn, prfmt, prowcolnum, ncpl, ndig)
798  ! -- Build a print format for reals based on IPRN.
799  ! -- dummy
800  integer(I4B), intent(inout) :: iprn
801  character(len=*), intent(out) :: prfmt
802  logical, intent(in) :: prowcolnum
803  integer(I4B), intent(out) :: ncpl, ndig
804  ! -- local
805  integer(I4B) :: nwidp
806  character(len=1) :: editdesc
807  !
808  if (iprn < 0) then
809  prfmt = ''
810  return
811  end if
812  !
813  if (iprn > 21) iprn = 0
814  !
815  select case (iprn)
816  case (0)
817  ncpl = 10
818  editdesc = 'G'
819  nwidp = 11
820  ndig = 4
821  case (1)
822  ncpl = 11
823  editdesc = 'G'
824  nwidp = 10
825  ndig = 3
826  case (2)
827  ncpl = 9
828  editdesc = 'G'
829  nwidp = 13
830  ndig = 6
831  case (3)
832  ncpl = 15
833  editdesc = 'F'
834  nwidp = 7
835  ndig = 1
836  case (4)
837  ncpl = 15
838  editdesc = 'F'
839  nwidp = 7
840  ndig = 2
841  case (5)
842  ncpl = 15
843  editdesc = 'F'
844  nwidp = 7
845  ndig = 3
846  case (6)
847  ncpl = 15
848  editdesc = 'F'
849  nwidp = 7
850  ndig = 4
851  case (7)
852  ncpl = 20
853  editdesc = 'F'
854  nwidp = 5
855  ndig = 0
856  case (8)
857  ncpl = 20
858  editdesc = 'F'
859  nwidp = 5
860  ndig = 1
861  case (9)
862  ncpl = 20
863  editdesc = 'F'
864  nwidp = 5
865  ndig = 2
866  case (10)
867  ncpl = 20
868  editdesc = 'F'
869  nwidp = 5
870  ndig = 3
871  case (11)
872  ncpl = 20
873  editdesc = 'F'
874  nwidp = 5
875  ndig = 4
876  case (12)
877  ncpl = 10
878  editdesc = 'G'
879  nwidp = 11
880  ndig = 4
881  case (13)
882  ncpl = 10
883  editdesc = 'F'
884  nwidp = 6
885  ndig = 0
886  case (14)
887  ncpl = 10
888  editdesc = 'F'
889  nwidp = 6
890  ndig = 1
891  case (15)
892  ncpl = 10
893  editdesc = 'F'
894  nwidp = 6
895  ndig = 2
896  case (16)
897  ncpl = 10
898  editdesc = 'F'
899  nwidp = 6
900  ndig = 3
901  case (17)
902  ncpl = 10
903  editdesc = 'F'
904  nwidp = 6
905  ndig = 4
906  case (18)
907  ncpl = 10
908  editdesc = 'F'
909  nwidp = 6
910  ndig = 5
911  case (19)
912  ncpl = 5
913  editdesc = 'G'
914  nwidp = 12
915  ndig = 5
916  case (20)
917  ncpl = 6
918  editdesc = 'G'
919  nwidp = 11
920  ndig = 4
921  case (21)
922  ncpl = 7
923  editdesc = 'G'
924  nwidp = 9
925  ndig = 2
926  end select
927  !
928  if (editdesc == 'F') then
929  call buildfixedformat(ncpl, nwidp, ndig, prfmt, prowcolnum)
930  else
931  call buildfloatformat(ncpl, nwidp, ndig, editdesc, prfmt, prowcolnum)
932  end if
933  !
934  ndig = nwidp + 1
935  end subroutine build_format_dbl
936 
937  subroutine print_array_int(iarr, aname, iout, jj, ii, k, prfmt, &
938  ncpl, ndig, prowcolnum)
939  ! -- dummy
940  integer(I4B), intent(in) :: iout, jj, ii, k
941  integer(I4B), intent(in) :: ncpl ! # values to print per line
942  integer(I4B), intent(in) :: ndig ! # characters in each field
943  integer(I4B), dimension(jj, ii), intent(in) :: iarr ! Integer array to be printed
944  character(len=*), intent(in) :: aname ! Array name
945  character(len=*), intent(in) :: prfmt ! Print format, no row #
946  logical, intent(in) :: prowcolnum ! Print row & column numbers
947  ! -- local
948  integer(I4B) :: i, j
949  ! -- formats
950 2 format(/, 1x, a, 1x, 'FOR LAYER ', i0)
951 3 format(/, 1x, a)
952  !
953  if (iout <= 0) return
954  !
955  ! -- Write name of array
956  if (k > 0) then
957  write (iout, 2) trim(aname), k
958  else
959  write (iout, 3) trim(aname)
960  end if
961  !
962  ! -- Write array
963  if (prowcolnum) then
964  ! -- Write column/node numbers
965  call ucolno(1, jj, 4, ncpl, ndig, iout)
966  !
967  ! -- Write array values, including row numbers
968  do i = 1, ii
969  write (iout, prfmt) i, (iarr(j, i), j=1, jj)
970  end do
971  else
972  if (ii > 1) then
973  errmsg = 'Program error printing array '//trim(aname)// &
974  ': ii > 1 when prowcolnum is false.'
975  call store_error(errmsg, terminate=.true.)
976  end if
977  !
978  ! -- Write array values, without row numbers
979  write (iout, prfmt) (iarr(j, 1), j=1, jj)
980  end if
981  end subroutine print_array_int
982 
983  subroutine print_array_dbl(darr, aname, iout, jj, ii, k, prfmt, &
984  ncpl, ndig, prowcolnum)
985  ! -- dummy
986  integer(I4B), intent(in) :: iout, jj, ii, k
987  integer(I4B), intent(in) :: ncpl ! # values to print per line
988  integer(I4B), intent(in) :: ndig ! # characters in each field
989  real(DP), dimension(jj, ii), intent(in) :: darr ! Real array to be printed
990  character(len=*), intent(in) :: aname ! Array name
991  character(len=*), intent(in) :: prfmt ! Print format, no row #
992  logical, intent(in) :: prowcolnum ! Print row & column numbers
993  ! -- local
994  integer(I4B) :: i, j
995  ! -- formats
996 2 format(/, 1x, a, 1x, 'FOR LAYER ', i0)
997 3 format(/, 1x, a)
998  !
999  if (iout <= 0) return
1000  !
1001  ! -- Write name of array
1002  if (k > 0) then
1003  write (iout, 2) trim(aname), k
1004  else
1005  write (iout, 3) trim(aname)
1006  end if
1007  !
1008  ! -- Write array
1009  if (prowcolnum) then
1010  ! -- Write column/node numbers
1011  call ucolno(1, jj, 4, ncpl, ndig, iout)
1012  !
1013  ! -- Write array values, including row numbers
1014  do i = 1, ii
1015  write (iout, prfmt) i, (darr(j, i), j=1, jj)
1016  end do
1017  else
1018  if (ii > 1) then
1019  errmsg = 'Program error printing array '//trim(aname)// &
1020  ': ii > 1 when prowcolnum is false.'
1021  call store_error(errmsg, terminate=.true.)
1022  end if
1023  !
1024  ! -- Write array values, without row numbers
1025  write (iout, prfmt) (darr(j, 1), j=1, jj)
1026  end if
1027  end subroutine print_array_dbl
1028 
1029  subroutine read_binary_header(locat, iout, arrname, nval)
1030  ! -- dummy
1031  integer(I4B), intent(in) :: locat
1032  integer(I4B), intent(in) :: iout
1033  character(len=*), intent(in) :: arrname
1034  integer, intent(out) :: nval
1035  ! -- local
1036  integer(I4B) :: istat
1037  integer(I4B) :: kstp, kper, m1, m2, m3
1038  real(dp) :: pertim, totim
1039  character(len=BINARY_STRLEN) :: text
1040  character(len=MAXCHARLEN) :: ermsgr
1041  character(len=*), parameter :: fmthdr = &
1042  "(/,1X,'HEADER FROM BINARY FILE HAS FOLLOWING ENTRIES',&
1043  &/,4X,'KSTP: ',I0,' KPER: ',I0,&
1044  &/,4x,'PERTIM: ',G0,' TOTIM: ',G0,&
1045  &/,4X,'TEXT: ',A,&
1046  &/,4X,'MSIZE 1: ',I0,' MSIZE 2: ',I0,' MSIZE 3: ',I0)"
1047  !
1048  ! -- Read the header line from the binary file
1049  read (locat, iostat=istat, iomsg=ermsgr) kstp, kper, pertim, totim, text, &
1050  m1, m2, m3
1051  !
1052  ! -- Check for errors
1053  if (istat /= 0) then
1054  errmsg = "Error reading data for array '"//adjustl(trim(arrname))// &
1055  "'. "//trim(adjustl(ermsgr))
1056  call store_error(errmsg)
1057  call store_error_unit(locat)
1058  end if
1059  !
1060  ! -- Write message about the binary header
1061  if (iout > 0) then
1062  write (iout, fmthdr) kstp, kper, pertim, totim, text, m1, m2, m3
1063  end if
1064  !
1065  ! -- Assign the number of values that follow the header
1066  nval = m1 * m2
1067  end subroutine read_binary_header
1068 
1069  subroutine check_binary_filesize(locat, expected_size, arrname)
1070  ! -- dummy
1071  integer(I4B), intent(in) :: locat
1072  integer(I4B), intent(in) :: expected_size
1073  character(len=*), intent(in) :: arrname
1074  ! -- local
1075  integer(I4B) :: file_size
1076  !
1077  inquire (unit=locat, size=file_size)
1078  !
1079  if (expected_size /= file_size) then
1080  write (errmsg, '(a,i0,a,i0,a)') &
1081  'Unexpected file size for binary input array '// &
1082  trim(arrname)//'. Expected=', expected_size, &
1083  '/Found=', file_size, ' bytes.'
1084  call store_error(errmsg)
1085  call store_error_unit(locat)
1086  end if
1087  end subroutine check_binary_filesize
1088 
1089  !> @ brief Check the binary data size
1090  !!
1091  !! Check the size of the binary data that will be read
1092  !! relative to the unfilled elements in the array .
1093  !!
1094  !<
1095  function check_binary_size(nval, nvalt, arrsize, aname, locat) result(isok)
1096  ! -- dummy
1097  integer(I4B), intent(in) :: nval !< number of array
1098  integer(I4B), intent(in) :: nvalt !< current data index
1099  integer(I4B), intent(in) :: arrsize !< size of the array
1100  character(len=*), intent(in) :: aname !< name of array
1101  integer(I4B), intent(in) :: locat !< binary file unit
1102  !
1103  ! -- local variables
1104  logical(LGP) :: isok
1105  !
1106  ! -- initialize isok
1107  isok = .true.
1108  !
1109  if (nvalt + nval > arrsize) then
1110  write (errmsg, '(a,i0,a,1x,a,1x,a,i0,a,1x,i0,3(1x,a))') &
1111  'The size of the data array calculated from the binary header (', &
1112  nval, ') will exceed the remainder of the', trim(adjustl(aname)), &
1113  'data array (', arrsize, ') array by', nvalt + nval - arrsize, &
1114  'elements. This is usually caused by incorrect assignment of', &
1115  '(m1,m2,m3) in the binary header. See the mf6io.pdf document', &
1116  'for information on assigning (m1,m2,m3).'
1117  call store_error(errmsg)
1118  call store_error_unit(locat)
1119  isok = .false.
1120  end if
1121  end function check_binary_size
1122 
1123 end module arrayreadersmodule
subroutine read_array_dbl1d_layered(iu, darr, aname, ndim, ncol, nrow, nlay, nval, iout, k1, k2)
subroutine read_control_2(iu, iout, fname, line, icol, locat, iclose, iprn)
subroutine read_control_1(iu, iout, aname, locat, iclose, line, icol, fname)
subroutine read_array_dbl3d_all(iu, darr, aname, ndim, nvals, iout)
subroutine, public read_binary_header(locat, iout, arrname, nval)
subroutine print_array_dbl(darr, aname, iout, jj, ii, k, prfmt, ncpl, ndig, prowcolnum)
subroutine read_array_int2d(iu, iarr, aname, ndim, jj, ii, iout, k)
subroutine read_array_int3d(iu, iarr, aname, ndim, ncol, nrow, nlay, iout, k1, k2)
integer(i4b), parameter binary_char_bytes
subroutine, public check_binary_filesize(locat, expected_size, arrname)
subroutine read_array_dbl2d(iu, darr, aname, ndim, jj, ii, iout, k)
subroutine read_control_dbl(iu, iout, aname, locat, cnstnt, iclose, iprn)
subroutine read_array_dbl1d(iu, darr, aname, ndim, jj, iout, k)
subroutine read_array_int1d(iu, iarr, aname, ndim, jj, iout, k)
integer(i4b), parameter binary_strlen
integer(i4b), parameter, public binary_int_bytes
subroutine build_format_int(iprn, prfmt, prowcolnum, ncpl, ndig)
logical(lgp) function check_binary_size(nval, nvalt, arrsize, aname, locat)
@ brief Check the binary data size
subroutine read_array_int1d_layered(iu, iarr, aname, ndim, ncol, nrow, nlay, nval, iout, k1, k2)
integer(i4b), parameter, public binary_header_bytes
array text
subroutine read_array_int3d_all(iu, iarr, aname, ndim, nvals, iout)
subroutine build_format_dbl(iprn, prfmt, prowcolnum, ncpl, ndig)
subroutine read_control_int(iu, iout, aname, locat, iconst, iclose, iprn)
subroutine read_array_dbl3d(iu, darr, aname, ndim, ncol, nrow, nlay, iout, k1, k2)
integer(i4b), parameter, public binary_double_bytes
subroutine print_array_int(iarr, aname, iout, jj, ii, k, prfmt, ncpl, ndig, prowcolnum)
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 namedboundflag
named bound flag
Definition: Constants.f90:49
integer(i4b), parameter lenbigline
maximum length of a big line
Definition: Constants.f90:15
integer(i4b), parameter lenboundname
maximum length of a bound name
Definition: Constants.f90:36
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
integer(i4b), parameter maxcharlen
maximum length of char string
Definition: Constants.f90:47
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
subroutine, public buildintformat(nvalsp, nwidp, outfmt, prowcolnum)
Build a format for printing or saving an integer array.
subroutine, public ucolno(nlbl1, nlbl2, nspace, ncpl, ndig, iout)
Output column numbers above a matrix printout.
subroutine, public ulaprw(buf, text, kstp, kper, ncol, nrow, ilay, iprn, iout)
Print 1 layer array.
subroutine, public buildfixedformat(nvalsp, nwidp, ndig, outfmt, prowcolnum)
Build a fixed format for printing or saving a real array.
subroutine, public buildfloatformat(nvalsp, nwidp, ndig, editdesc, outfmt, prowcolnum)
Build a floating-point format for printing or saving a real array.
subroutine, public u9rdcom(iin, iout, line, ierr)
Read until non-comment line found and then return line.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
subroutine, public urword(line, icol, istart, istop, ncode, n, r, iout, in)
Extract a word from a string.
This module defines variable data types.
Definition: kind.f90:8
character(len=20) access
Definition: OpenSpec.f90:7
character(len=20) form
Definition: OpenSpec.f90:7
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public ustop(stopmess, ioutlocal)
Stop the simulation.
Definition: Sim.f90:312
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
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string