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