16 integer(I4B),
pointer :: npoints
17 real(dp),
pointer,
dimension(:),
contiguous :: station => null()
18 real(dp),
pointer,
dimension(:),
contiguous :: height => null()
19 real(dp),
pointer,
dimension(:),
contiguous :: roughfraction => null()
20 logical(LGP),
pointer,
dimension(:),
contiguous :: valid => null()
24 integer(I4B),
pointer :: iout => null()
25 integer(I4B),
pointer :: iprpak => null()
26 integer(I4B),
pointer :: nreaches => null()
27 integer(I4B),
pointer :: invalid => null()
28 character(len=LINELENGTH),
dimension(:),
allocatable :: filenames
29 integer(I4B),
pointer,
dimension(:),
contiguous :: npoints => null()
31 pointer,
dimension(:),
contiguous :: cross_sections => null()
61 integer(I4B),
pointer,
intent(in) :: iout
62 integer(I4B),
pointer,
intent(in) :: iprpak
63 integer(I4B),
pointer,
intent(in) :: nreaches
66 if (
associated(this))
then
78 this%nreaches => nreaches
87 subroutine initialize(this, ncrossptstot, ncrosspts, iacross, &
88 station, height, roughfraction)
91 integer(I4B),
intent(in) :: ncrossptstot
92 integer(I4B),
dimension(this%nreaches),
intent(in) :: ncrosspts
93 integer(I4B),
dimension(this%nreaches + 1),
intent(in) :: iacross
94 real(DP),
dimension(ncrossptstot),
intent(in) :: station
95 real(DP),
dimension(ncrossptstot),
intent(in) :: height
96 real(DP),
dimension(ncrossptstot),
intent(in) :: roughfraction
100 integer(I4B) :: npoints
106 allocate (this%invalid)
112 allocate (this%filenames(this%nreaches))
113 allocate (this%npoints(this%nreaches))
114 allocate (this%cross_sections(this%nreaches))
115 do n = 1, this%nreaches
116 npoints = ncrosspts(n)
117 allocate (this%cross_sections(n)%npoints)
118 allocate (this%cross_sections(n)%station(npoints))
119 allocate (this%cross_sections(n)%height(npoints))
120 allocate (this%cross_sections(n)%roughfraction(npoints))
121 allocate (this%cross_sections(n)%valid(npoints))
125 do n = 1, this%nreaches
126 this%filenames(n) =
'NONE'
127 this%cross_sections(n)%npoints = ncrosspts(n)
128 this%npoints(n) = ncrosspts(n)
130 i1 = iacross(n + 1) - 1
133 this%cross_sections(n)%station(ipos) = station(i)
134 this%cross_sections(n)%height(ipos) = height(i)
135 this%cross_sections(n)%roughfraction(ipos) = roughfraction(i)
136 this%cross_sections(n)%valid(ipos) = .true.
150 integer(I4B),
intent(in) :: irch
151 real(DP),
intent(in) :: width
152 character(len=*),
intent(in) :: mempath
153 character(len=*),
intent(in) :: filename
155 integer(I4B),
pointer :: nrow => null()
156 integer(I4B),
pointer :: ncol => null()
157 real(DP),
dimension(:),
pointer,
contiguous :: xfraction => null()
158 real(DP),
dimension(:),
pointer,
contiguous :: height => null()
159 real(DP),
dimension(:),
pointer,
contiguous :: manfraction => null()
160 integer(I4B) :: n, nerr0
170 write (
errmsg,
'(a,1x,i0,3a)') &
171 'TABLE NROW MUST BE > 0 FOR REACH', irch,
" ('", &
172 trim(adjustl(filename)),
"')"
176 write (
errmsg,
'(a,1x,i0,3a)') &
177 'TABLE NCOL MUST BE >= 2 FOR REACH', irch,
" ('", &
178 trim(adjustl(filename)),
"')"
191 this%filenames(irch) = filename
192 this%npoints(irch) = nrow
193 deallocate (this%cross_sections(irch)%npoints)
194 deallocate (this%cross_sections(irch)%station)
195 deallocate (this%cross_sections(irch)%height)
196 deallocate (this%cross_sections(irch)%roughfraction)
197 deallocate (this%cross_sections(irch)%valid)
198 allocate (this%cross_sections(irch)%npoints)
199 allocate (this%cross_sections(irch)%station(nrow))
200 allocate (this%cross_sections(irch)%height(nrow))
201 allocate (this%cross_sections(irch)%roughfraction(nrow))
202 allocate (this%cross_sections(irch)%valid(nrow))
203 this%cross_sections(irch)%npoints = nrow
206 call mem_setptr(xfraction,
'XFRACTION', mempath)
209 this%cross_sections(irch)%station(n) = xfraction(n) * width
210 this%cross_sections(irch)%height(n) = height(n)
211 this%cross_sections(irch)%valid(n) = .true.
214 call mem_setptr(manfraction,
'MANFRACTION', mempath)
215 this%cross_sections(irch)%roughfraction = manfraction
217 this%cross_sections(irch)%roughfraction =
done
221 call this%validate(irch)
250 integer(I4B),
intent(in) :: irch
251 real(DP),
intent(in) :: width
252 character(len=*),
intent(in) :: filename
254 character(len=LINELENGTH) :: tag
255 character(len=LINELENGTH) :: keyword
258 logical :: endOfBlock
264 integer(I4B) :: nerr0
276 write (tag,
"('Reach',1x,i0,1x,'(',a, ')')") &
277 irch, trim(adjustl(filename))
281 call openfile(iu, this%iout, filename,
'SFR TABLE')
282 call parser%Initialize(iu, this%iout)
285 call parser%GetBlock(
'DIMENSIONS', isfound, ierr, supportopenclose=.true.)
291 if (this%iprpak /= 0)
then
292 write (this%iout,
'(/1x,a)') &
293 'PROCESSING '//trim(adjustl(tag))//
' DIMENSIONS'
296 call parser%GetNextLine(endofblock)
298 call parser%GetStringCaps(keyword)
299 select case (keyword)
301 n = parser%GetInteger()
303 write (
errmsg,
'(a,1x,a)') &
304 'TABLE NROW MUST BE > 0 FOR', trim(adjustl(tag))
308 j = parser%GetInteger()
311 write (
errmsg,
'(a,1x,i0,1x,a,1x,a)') &
312 'TABLE NCOL MUST BE >=', jmin,
'FOR', trim(adjustl(tag))
317 'UNKNOWN '//trim(adjustl(tag))//
' DIMENSIONS keyword: ', &
322 if (this%iprpak /= 0)
then
323 write (this%iout,
'(1x,a)') &
324 'END OF '//trim(adjustl(tag))//
' DIMENSIONS'
327 call store_error(
'Required DIMENSIONS block not found.')
333 'NROW not specified in the table DIMENSIONS block'
338 'NCOL not specified in the table DIMENSIONS block'
347 this%filenames(irch) = filename
348 this%npoints(irch) = n
351 deallocate (this%cross_sections(irch)%npoints)
352 deallocate (this%cross_sections(irch)%station)
353 deallocate (this%cross_sections(irch)%height)
354 deallocate (this%cross_sections(irch)%roughfraction)
355 deallocate (this%cross_sections(irch)%valid)
358 allocate (this%cross_sections(irch)%npoints)
359 allocate (this%cross_sections(irch)%station(n))
360 allocate (this%cross_sections(irch)%height(n))
361 allocate (this%cross_sections(irch)%roughfraction(n))
362 allocate (this%cross_sections(irch)%valid(n))
365 this%cross_sections(irch)%npoints = n
368 call parser%GetBlock(
'TABLE', isfound, ierr, supportopenclose=.true.)
374 if (this%iprpak /= 0)
then
375 write (this%iout,
'(/1x,a)') &
376 'PROCESSING '//trim(adjustl(tag))//
' TABLE'
380 call parser%GetNextLine(endofblock)
383 if (ipos > this%npoints(irch))
then
386 this%cross_sections(irch)%station(ipos) = parser%GetDouble() * width
387 this%cross_sections(irch)%height(ipos) = parser%GetDouble()
389 this%cross_sections(irch)%roughfraction(ipos) = parser%GetDouble()
391 this%cross_sections(irch)%roughfraction(ipos) = done
393 this%cross_sections(irch)%valid(ipos) = .true.
396 if (this%iprpak /= 0)
then
397 write (this%iout,
'(1x,a)') &
398 'END OF '//trim(adjustl(tag))//
' TABLE'
401 call store_error(
'Required TABLE block not found.')
405 if (ipos /= this%npoints(irch))
then
406 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a)') &
407 'NROW set to', this%npoints(irch),
'but', ipos,
'rows were read'
418 call this%validate(irch)
438 integer(I4B),
intent(in) :: irch
440 logical(LGP) :: station_error
441 logical(LGP) :: height_error
442 logical(LGP) :: height_zero_error
443 logical(LGP) :: roughness_error
444 character(len=LINELENGTH) :: filename
451 real(DP) :: roughfraction
456 real(DP),
dimension(:),
allocatable :: heights
457 real(DP),
dimension(:),
allocatable :: unique_heights
458 real(DP),
dimension(3) :: factor
461 station_error = .false.
462 height_error = .false.
463 height_zero_error = .true.
464 roughness_error = .false.
465 npts = this%npoints(irch)
469 station = this%cross_sections(irch)%station(n)
470 if (station < dzero)
then
471 station_error = .true.
473 height = this%cross_sections(irch)%height(n)
474 if (height < dzero)
then
475 height_error = .true.
476 else if (height == dzero)
then
477 height_zero_error = .false.
479 roughfraction = this%cross_sections(irch)%roughfraction(n)
480 if (roughfraction <= dzero)
then
481 roughness_error = .true.
483 if (station_error .and. height_error .and. &
484 roughness_error)
then
490 if (station_error .or. height_error .or. &
491 height_zero_error .or. roughness_error)
then
492 filename = this%filenames(irch)
493 if (station_error)
then
494 write (
errmsg,
'(3a,1x,i0,1x,a)') &
495 "All xfraction data in '", trim(adjustl(filename)), &
496 "' for reach", irch,
'must be greater than or equal to zero.'
499 if (height_error)
then
500 write (
errmsg,
'(3a,1x,i0,1x,a)') &
501 "All height data in '", trim(adjustl(filename)), &
502 "' for reach", irch,
'must be greater than or equal to zero.'
505 if (height_zero_error)
then
506 write (
errmsg,
'(3a,1x,i0,1x,a)') &
507 "At least one height data value in '", trim(adjustl(filename)), &
508 "' for reach", irch,
'must be equal to zero.'
511 if (roughness_error)
then
512 write (
errmsg,
'(3a,1x,i0,1x,a)') &
513 "All manfraction data in '", trim(adjustl(filename)), &
514 "' for reach", irch,
'must be greater than zero.'
520 allocate (heights(npts))
522 heights(n) = this%cross_sections(irch)%height(n)
530 do n = 1,
size(unique_heights)
531 if (unique_heights(n) <= dzero) cycle
534 height = unique_heights(n) + real(i, dp) *
dem6
536 this%cross_sections(irch)%height, height)
538 this%cross_sections(irch)%height, height)
544 dc0 = (factor(2) - factor(1)) /
dem6
545 dc1 = (factor(3) - factor(2)) /
dem6
548 if (dc0 < dzero .or. dc1 < dzero)
then
549 this%invalid = this%invalid + 1
550 height = unique_heights(n)
552 if (this%cross_sections(irch)%height(i) == height)
then
553 this%cross_sections(irch)%valid(i) = .false.
561 deallocate (unique_heights)
570 subroutine output(this, widths, roughs, kstp, kper)
575 real(DP),
dimension(this%nreaches),
intent(in) :: widths
576 real(DP),
dimension(this%nreaches),
intent(in) :: roughs
577 integer(I4B),
intent(in),
optional :: kstp
578 integer(I4B),
intent(in),
optional :: kper
580 character(len=LINELENGTH) :: title
581 character(len=LINELENGTH) :: text
582 character(len=LINELENGTH) :: filename
583 character(len=10) :: cvalid
584 logical(LGP) :: transient
585 integer(I4B) :: kkstp
586 integer(I4B) :: kkper
589 integer(I4B) :: ntabcols
590 integer(I4B) :: ninvalid_reaches
592 real(DP) :: xfraction
595 integer(I4B),
dimension(this%nreaches) :: reach_fail
602 if (
present(kstp))
then
605 if (
present(kper))
then
610 if (kkstp > 0 .and. kkper > 0)
then
617 do irch = 1, this%nreaches
618 filename = this%filenames(irch)
622 if (trim(adjustl(filename)) /=
'NONE')
then
623 do n = 1, this%npoints(irch)
624 if (.not. this%cross_sections(irch)%valid(n))
then
625 reach_fail(irch) = reach_fail(irch) + 1
632 do irch = 1, this%nreaches
633 filename = this%filenames(irch)
636 if (trim(adjustl(filename)) /=
'NONE')
then
640 if (this%iprpak > 0 .or. reach_fail(irch) > 0)
then
643 if (reach_fail(irch) > 0)
then
650 write (title,
'(a,1x,i0,1x,3a)') &
651 'CROSS_SECTION DATA FOR REACH', irch,
"FROM TAB6 FILE ('", &
652 trim(adjustl(filename)),
"')"
653 call table_cr(this%inputtab, trim(adjustl(filename)), title)
654 call this%inputtab%table_df(this%npoints(irch), ntabcols, &
655 this%iout, finalize=.false., &
658 call this%inputtab%set_kstpkper(kkstp, kkper)
661 call this%inputtab%initialize_column(text, 20, alignment=
tableft)
663 call this%inputtab%initialize_column(text, 20, alignment=
tableft)
665 call this%inputtab%initialize_column(text, 20, alignment=
tableft)
667 call this%inputtab%initialize_column(text, 20, alignment=
tableft)
668 text =
"MANNING'S ROUGHNESS COEFFICIENT"
669 call this%inputtab%initialize_column(text, 20, alignment=
tableft)
670 if (reach_fail(irch) > 0)
then
671 text =
'NEEDS ADJUSTMENT'
672 call this%inputtab%initialize_column(text, 10, alignment=
tableft)
680 do n = 1, this%npoints(irch)
681 xfraction = this%cross_sections(irch)%station(n) / width
682 r = this%cross_sections(irch)%roughfraction(n) * rough
683 call this%inputtab%add_term(xfraction)
684 call this%inputtab%add_term(this%cross_sections(irch)%station(n))
685 call this%inputtab%add_term(this%cross_sections(irch)%height(n))
686 call this%inputtab%add_term(&
687 &this%cross_sections(irch)%roughfraction(n))
688 call this%inputtab%add_term(r)
689 if (reach_fail(irch) > 0)
then
690 if (this%cross_sections(irch)%valid(n))
then
695 call this%inputtab%add_term(cvalid)
700 call this%inputtab%finalize_table()
706 if (this%invalid > 0)
then
708 do irch = 1, this%nreaches
709 if (reach_fail(irch) > 0)
then
710 ninvalid_reaches = ninvalid_reaches + 1
713 write (
warnmsg,
'(a,1x,i0,7(1x,a))') &
714 'Cross-section data for', ninvalid_reaches, &
715 'reaches include one or more points that result in a', &
716 'non-unique depth-conveyance relation. This occurs when', &
717 'there are horizontal sections at non-zero heights', &
718 '(for example, flat overbank sections). This can usually', &
719 'be resolved by adding a small slope to these flat', &
720 'sections. See the cross-section tables in the model', &
721 'listing file for more information.'
736 integer(I4B) :: nptstot
741 do n = 1, this%nreaches
742 nptstot = nptstot + this%npoints(n)
751 subroutine pack(this, ncrossptstot, ncrosspts, iacross, &
752 station, height, roughfraction)
755 integer(I4B),
intent(in) :: ncrossptstot
756 integer(I4B),
dimension(this%nreaches),
intent(inout) :: ncrosspts
757 integer(I4B),
dimension(this%nreaches + 1),
intent(inout) :: iacross
758 real(DP),
dimension(ncrossptstot),
intent(inout) :: station
759 real(DP),
dimension(ncrossptstot),
intent(inout) :: height
760 real(DP),
dimension(ncrossptstot),
intent(inout) :: roughfraction
764 integer(I4B) :: npoints
770 do n = 1, this%nreaches
771 npoints = this%npoints(n)
772 ncrosspts(n) = npoints
774 station(ipos) = this%cross_sections(n)%station(i)
775 height(ipos) = this%cross_sections(n)%height(i)
776 roughfraction(ipos) = this%cross_sections(n)%roughfraction(i)
779 iacross(n + 1) = ipos
795 deallocate (this%npoints)
796 nullify (this%npoints)
797 do n = 1, this%nreaches
798 deallocate (this%cross_sections(n)%npoints)
799 nullify (this%cross_sections(n)%npoints)
800 deallocate (this%cross_sections(n)%station)
801 nullify (this%cross_sections(n)%station)
802 deallocate (this%cross_sections(n)%height)
803 nullify (this%cross_sections(n)%height)
804 deallocate (this%cross_sections(n)%roughfraction)
805 nullify (this%cross_sections(n)%roughfraction)
806 deallocate (this%cross_sections(n)%valid)
807 nullify (this%cross_sections(n)%valid)
809 deallocate (this%cross_sections)
810 nullify (this%cross_sections)
813 if (
associated(this%inputtab))
then
814 call this%inputtab%table_da()
815 deallocate (this%inputtab)
816 nullify (this%inputtab)
820 deallocate (this%invalid)
821 nullify (this%invalid)
825 nullify (this%iprpak)
826 nullify (this%nreaches)
This module contains block parser methods.
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
@ tableft
left justified table column
real(dp), parameter dtwothirds
real constant 2/3
real(dp), parameter dem6
real constant 1e-6
real(dp), parameter dzero
real constant zero
integer(i4b), parameter iuoc
open/close file unit number
real(dp), parameter done
real constant 1
This module contains stateless sfr subroutines and functions.
real(dp) function, public get_cross_section_area(npts, stations, heights, d)
Calculate the cross-sectional area for a reach.
real(dp) function, public get_hydraulic_radius(npts, stations, heights, d)
Calculate the hydraulic radius for a reach.
This module defines variable data types.
subroutine, public memorystore_release(varname, memory_path)
Release a single variable from the memory store.
integer(i4b) function get_ncrossptstot(this)
Get the total number of cross-section points.
subroutine, public cross_section_cr(this, iout, iprpak, nreaches)
Create a cross-section object.
subroutine output(this, widths, roughs, kstp, kper)
Write cross-section tables.
subroutine destroy(this)
Deallocate the cross-section object.
subroutine read_table(this, irch, width, filename)
Read a cross-section table file for a reach.
subroutine validate(this, irch)
Validate cross-section tables.
subroutine source_table(this, irch, width, mempath, filename)
Source a reach's cross-section table from its SFRTAB6 subpackage.
subroutine initialize(this, ncrossptstot, ncrosspts, iacross, station, height, roughfraction)
Initialize a cross-section object.
subroutine pack(this, ncrossptstot, ncrosspts, iacross, station, height, roughfraction)
Pack the cross-section object.
This module contains simulation methods.
subroutine, public store_warning(msg, substring)
Store warning message.
subroutine, public store_error(msg, terminate)
Store an error message.
integer(i4b) function, public count_errors()
Return number of errors.
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
character(len=maxcharlen) warnmsg
warning message string
subroutine, public table_cr(this, name, title)