50 character(len=LENFTYPE) ::
ftype =
'SFR'
51 character(len=LENPACKAGENAME) ::
text =
' SFR'
64 real(dp),
dimension(:),
pointer,
contiguous :: rhk => null()
65 real(dp),
dimension(:),
pointer,
contiguous :: man => null()
66 real(dp),
dimension(:),
pointer,
contiguous :: ustrf => null()
68 integer(I4B),
pointer :: nbound => null()
69 integer(I4B),
dimension(:),
pointer,
contiguous :: ifno => null()
71 contiguous :: status => null()
73 contiguous :: setting => null()
74 integer(I4B),
dimension(:),
pointer,
contiguous :: idv => null()
76 contiguous :: tab6_filename => null()
78 contiguous :: auxname => null()
79 real(dp),
dimension(:),
pointer,
contiguous :: auxval => null()
89 character(len=16),
dimension(:),
pointer,
contiguous :: csfrbudget => null()
90 character(len=16),
dimension(:),
pointer,
contiguous :: cauxcbc => null()
91 character(len=LENBOUNDNAME),
dimension(:),
pointer, &
92 contiguous :: sfrname => null()
94 integer(I4B),
pointer :: istorage => null()
95 integer(I4B),
pointer :: iprhed => null()
96 integer(I4B),
pointer :: istageout => null()
97 integer(I4B),
pointer :: ibudgetout => null()
98 integer(I4B),
pointer :: ibudcsv => null()
99 integer(I4B),
pointer :: ipakcsv => null()
100 integer(I4B),
pointer :: idiversions => null()
101 integer(I4B),
pointer :: nconn => null()
102 integer(I4B),
pointer :: maxsfrpicard => null()
103 integer(I4B),
pointer :: maxsfrit => null()
104 integer(I4B),
pointer :: bditems => null()
105 integer(I4B),
pointer :: cbcauxitems => null()
106 integer(I4B),
pointer :: icheck => null()
107 integer(I4B),
pointer :: iconvchk => null()
108 integer(I4B),
pointer :: gwfiss => null()
109 integer(I4B),
pointer :: ianynone => null()
111 real(dp),
pointer :: unitconv => null()
112 real(dp),
pointer :: lengthconv => null()
113 real(dp),
pointer :: timeconv => null()
114 real(dp),
pointer :: dmaxchg => null()
115 real(dp),
pointer :: deps => null()
116 real(dp),
pointer :: storage_weight => null()
118 integer(I4B),
dimension(:),
pointer,
contiguous :: isfrorder => null()
119 integer(I4B),
dimension(:),
pointer,
contiguous :: ia => null()
120 integer(I4B),
dimension(:),
pointer,
contiguous :: ja => null()
122 real(dp),
dimension(:),
pointer,
contiguous :: qoutflow => null()
123 real(dp),
dimension(:),
pointer,
contiguous :: qextoutflow => null()
124 real(dp),
dimension(:),
pointer,
contiguous :: qauxcbc => null()
125 real(dp),
dimension(:),
pointer,
contiguous :: dbuff => null()
136 integer(I4B),
dimension(:),
pointer,
contiguous :: iboundpak => null()
137 integer(I4B),
dimension(:),
pointer,
contiguous :: igwfnode => null()
138 integer(I4B),
dimension(:),
pointer,
contiguous :: igwftopnode => null()
139 real(dp),
dimension(:),
pointer,
contiguous :: length => null()
140 real(dp),
dimension(:),
pointer,
contiguous :: width => null()
141 real(dp),
dimension(:),
pointer,
contiguous :: strtop => null()
142 real(dp),
dimension(:),
pointer,
contiguous :: bthick => null()
143 real(dp),
dimension(:),
pointer,
contiguous :: hk => null()
144 real(dp),
dimension(:),
pointer,
contiguous :: slope => null()
145 integer(I4B),
dimension(:),
pointer,
contiguous :: nconnreach => null()
146 real(dp),
dimension(:),
pointer,
contiguous :: ustrf => null()
147 logical(LGP),
dimension(:),
pointer,
contiguous :: bedk_set => null()
148 logical(LGP),
dimension(:),
pointer,
contiguous :: manning_set => null()
149 logical(LGP),
dimension(:),
pointer,
contiguous :: ustrf_set => null()
150 real(dp),
dimension(:),
pointer,
contiguous :: ftotnd => null()
151 integer(I4B),
dimension(:),
pointer,
contiguous :: ndiv => null()
152 real(dp),
dimension(:),
pointer,
contiguous :: usflow => null()
153 real(dp),
dimension(:),
pointer,
contiguous :: dsflow => null()
154 real(dp),
dimension(:),
pointer,
contiguous :: dsflowold => null()
155 real(dp),
dimension(:),
pointer,
contiguous :: usinflow => null()
156 real(dp),
dimension(:),
pointer,
contiguous :: usinflowold => null()
157 real(dp),
pointer :: ats_courant => null()
158 integer(I4B),
dimension(:),
pointer,
contiguous :: itvd_upstream => null()
159 real(dp),
dimension(:),
pointer,
contiguous :: crmin => null()
160 real(dp),
dimension(:),
pointer,
contiguous :: crmax => null()
161 real(dp),
dimension(:),
pointer,
contiguous :: crsum => null()
162 integer(I4B),
dimension(:),
pointer,
contiguous :: crcnt => null()
163 real(dp),
dimension(:),
pointer,
contiguous :: depth => null()
164 real(dp),
dimension(:),
pointer,
contiguous :: stage => null()
165 real(dp),
dimension(:),
pointer,
contiguous :: stageold => null()
166 real(dp),
dimension(:),
pointer,
contiguous :: gwflow => null()
167 real(dp),
dimension(:),
pointer,
contiguous :: simevap => null()
168 real(dp),
dimension(:),
pointer,
contiguous :: simrunoff => null()
169 real(dp),
dimension(:),
pointer,
contiguous :: stage0 => null()
170 real(dp),
dimension(:),
pointer,
contiguous :: usflow0 => null()
171 real(dp),
dimension(:),
pointer,
contiguous :: storage => null()
173 integer(I4B),
pointer :: ncrossptstot => null()
174 integer(I4B),
dimension(:),
pointer,
contiguous :: ncrosspts => null()
175 integer(I4B),
dimension(:),
pointer,
contiguous :: iacross => null()
176 real(dp),
dimension(:),
pointer,
contiguous :: station => null()
177 real(dp),
dimension(:),
pointer,
contiguous :: xsheight => null()
178 real(dp),
dimension(:),
pointer,
contiguous :: xsrough => null()
180 integer(I4B),
dimension(:),
pointer,
contiguous :: idir => null()
181 integer(I4B),
dimension(:),
pointer,
contiguous :: idiv => null()
182 real(dp),
dimension(:),
pointer,
contiguous :: qconn => null()
184 real(dp),
dimension(:),
pointer,
contiguous :: rough => null()
185 real(dp),
dimension(:),
pointer,
contiguous :: rain => null()
186 real(dp),
dimension(:),
pointer,
contiguous :: evap => null()
187 real(dp),
dimension(:),
pointer,
contiguous :: inflow => null()
188 real(dp),
dimension(:),
pointer,
contiguous :: runoff => null()
189 real(dp),
dimension(:),
pointer,
contiguous :: sstage => null()
191 integer(I4B),
dimension(:),
pointer,
contiguous :: iadiv => null()
192 integer(I4B),
dimension(:),
pointer,
contiguous :: divreach => null()
193 character(len=10),
dimension(:),
pointer,
contiguous :: divcprior => null()
194 real(dp),
dimension(:),
pointer,
contiguous :: divflow => null()
195 real(dp),
dimension(:),
pointer,
contiguous :: divq => null()
198 integer(I4B),
pointer :: idense
199 real(dp),
dimension(:, :),
pointer,
contiguous :: denseterms => null()
202 real(dp),
dimension(:, :),
pointer,
contiguous :: viscratios => null()
238 procedure,
private :: sfr_calc_constant
239 procedure,
private :: sfr_calc_transient
240 procedure,
private :: sfr_calc_tvd
242 procedure,
private :: sfr_calc_steady
290 module subroutine sfr_calc_steady(this, n, d1, hgwf, &
291 qu, qi, qfrommvr, qr, qe, qro, &
293 class(sfrtype) :: this
294 integer(I4B),
intent(in) :: n
295 real(dp),
intent(inout) :: d1
296 real(dp),
intent(in) :: hgwf
297 real(dp),
intent(in) :: qu
298 real(dp),
intent(in) :: qi
299 real(dp),
intent(in) :: qfrommvr
300 real(dp),
intent(in) :: qr
301 real(dp),
intent(in) :: qe
302 real(dp),
intent(in) :: qro
303 real(dp),
intent(inout) :: qgwf
304 real(dp),
intent(inout) :: qd
309 module subroutine sfr_calc_transient(this, n, d1, hgwf, &
310 qu, qi, qfrommvr, qr, qe, qro, &
312 class(sfrtype) :: this
313 integer(I4B),
intent(in) :: n
314 real(dp),
intent(inout) :: d1
315 real(dp),
intent(in) :: hgwf
316 real(dp),
intent(in) :: qu
317 real(dp),
intent(in) :: qi
318 real(dp),
intent(in) :: qfrommvr
319 real(dp),
intent(in) :: qr
320 real(dp),
intent(in) :: qe
321 real(dp),
intent(in) :: qro
322 real(dp),
intent(inout) :: qgwf
323 real(dp),
intent(inout) :: qd
328 module subroutine sfr_calc_tvd(this, n, d1, hgwf, &
329 qu, qi, qfrommvr, qr, qe, qro, &
331 class(sfrtype) :: this
332 integer(I4B),
intent(in) :: n
333 real(dp),
intent(inout) :: d1
334 real(dp),
intent(in) :: hgwf
335 real(dp),
intent(in) :: qu
336 real(dp),
intent(in) :: qi
337 real(dp),
intent(in) :: qfrommvr
338 real(dp),
intent(in) :: qr
339 real(dp),
intent(in) :: qe
340 real(dp),
intent(in) :: qro
341 real(dp),
intent(inout) :: qgwf
342 real(dp),
intent(inout) :: qd
347 module subroutine sfr_calc_constant(this, n, d1, hgwf, qgwf, qd)
348 class(sfrtype) :: this
349 integer(I4B),
intent(in) :: n
350 real(dp),
intent(inout) :: d1
351 real(dp),
intent(in) :: hgwf
352 real(dp),
intent(inout) :: qgwf
353 real(dp),
intent(inout) :: qd
363 subroutine sfr_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
368 class(
bndtype),
pointer :: packobj
369 integer(I4B),
intent(in) :: id
370 integer(I4B),
intent(in) :: ibcnum
371 integer(I4B),
intent(in) :: inunit
372 integer(I4B),
intent(in) :: iout
373 character(len=*),
intent(in) :: namemodel
374 character(len=*),
intent(in) :: pakname
375 character(len=*),
intent(in) :: mempath
377 type(sfrtype),
pointer :: sfrobj
384 call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
388 call sfrobj%sfr_allocate_scalars()
391 call packobj%pack_initialize()
393 packobj%inunit = inunit
396 packobj%ibcnum = ibcnum
401 end subroutine sfr_create
408 subroutine sfr_allocate_scalars(this)
413 class(sfrtype),
intent(inout) :: this
416 call this%BndExtType%allocate_scalars()
419 call mem_allocate(this%istorage,
'ISTORAGE', this%memoryPath)
420 call mem_allocate(this%iprhed,
'IPRHED', this%memoryPath)
421 call mem_allocate(this%istageout,
'ISTAGEOUT', this%memoryPath)
422 call mem_allocate(this%ibudgetout,
'IBUDGETOUT', this%memoryPath)
423 call mem_allocate(this%ibudcsv,
'IBUDCSV', this%memoryPath)
424 call mem_allocate(this%ipakcsv,
'IPAKCSV', this%memoryPath)
425 call mem_allocate(this%idiversions,
'IDIVERSIONS', this%memoryPath)
426 call mem_allocate(this%maxsfrpicard,
'MAXSFRPICARD', this%memoryPath)
427 call mem_allocate(this%maxsfrit,
'MAXSFRIT', this%memoryPath)
428 call mem_allocate(this%bditems,
'BDITEMS', this%memoryPath)
429 call mem_allocate(this%cbcauxitems,
'CBCAUXITEMS', this%memoryPath)
430 call mem_allocate(this%unitconv,
'UNITCONV', this%memoryPath)
431 call mem_allocate(this%lengthconv,
'LENGTHCONV', this%memoryPath)
432 call mem_allocate(this%timeconv,
'TIMECONV', this%memoryPath)
433 call mem_allocate(this%dmaxchg,
'DMAXCHG', this%memoryPath)
435 call mem_allocate(this%storage_weight,
'STORAGE_WEIGHT', this%memoryPath)
436 call mem_allocate(this%ats_courant,
'ATS_COURANT', this%memoryPath)
438 call mem_allocate(this%icheck,
'ICHECK', this%memoryPath)
439 call mem_allocate(this%iconvchk,
'ICONVCHK', this%memoryPath)
440 call mem_allocate(this%idense,
'IDENSE', this%memoryPath)
441 call mem_allocate(this%ianynone,
'IANYNONE', this%memoryPath)
442 call mem_allocate(this%ncrossptstot,
'NCROSSPTSTOT', this%memoryPath)
455 this%maxsfrpicard = 100
463 this%deps =
dp999 * this%dmaxchg
472 this%ncrossptstot = 0
473 end subroutine sfr_allocate_scalars
479 subroutine sfr_allocate_arrays(this)
483 class(sfrtype),
intent(inout) :: this
488 allocate (this%csfrbudget(this%bditems))
490 'SFRNAME', this%memoryPath)
493 call mem_allocate(this%iboundpak, this%maxbound,
'IBOUNDPAK', &
495 call mem_allocate(this%igwfnode, this%maxbound,
'IGWFNODE', this%memoryPath)
496 call mem_allocate(this%igwftopnode, this%maxbound,
'IGWFTOPNODE', &
498 call mem_allocate(this%length, this%maxbound,
'LENGTH', this%memoryPath)
499 call mem_allocate(this%width, this%maxbound,
'WIDTH', this%memoryPath)
500 call mem_allocate(this%strtop, this%maxbound,
'STRTOP', this%memoryPath)
501 call mem_allocate(this%bthick, this%maxbound,
'BTHICK', this%memoryPath)
502 call mem_allocate(this%slope, this%maxbound,
'SLOPE', this%memoryPath)
503 call mem_allocate(this%nconnreach, this%maxbound,
'NCONNREACH', &
505 call mem_allocate(this%bedk_set, this%maxbound,
'BEDK_SET', this%memoryPath)
506 call mem_allocate(this%manning_set, this%maxbound,
'MANNING_SET', &
508 call mem_allocate(this%ustrf_set, this%maxbound,
'USTRF_SET', &
510 this%bedk_set = .false.
511 this%manning_set = .false.
512 this%ustrf_set = .false.
513 call mem_allocate(this%ftotnd, this%maxbound,
'FTOTND', this%memoryPath)
514 call mem_allocate(this%ndiv, this%maxbound,
'NDIV', this%memoryPath)
515 call mem_allocate(this%usflow, this%maxbound,
'USFLOW', this%memoryPath)
516 call mem_allocate(this%dsflow, this%maxbound,
'DSFLOW', this%memoryPath)
517 call mem_allocate(this%depth, this%maxbound,
'DEPTH', this%memoryPath)
518 call mem_allocate(this%stage, this%maxbound,
'STAGE', this%memoryPath)
519 call mem_allocate(this%gwflow, this%maxbound,
'GWFLOW', this%memoryPath)
520 call mem_allocate(this%simevap, this%maxbound,
'SIMEVAP', this%memoryPath)
521 call mem_allocate(this%simrunoff, this%maxbound,
'SIMRUNOFF', &
523 call mem_allocate(this%stage0, this%maxbound,
'STAGE0', this%memoryPath)
524 call mem_allocate(this%usflow0, this%maxbound,
'USFLOW0', this%memoryPath)
527 if (this%istorage == 1)
then
528 call mem_allocate(this%stageold, this%maxbound,
'STAGEOLD', &
530 call mem_allocate(this%usinflow, this%maxbound,
'USINFLOW', &
532 call mem_allocate(this%usinflowold, this%maxbound,
'USINFLOWOLD', &
534 call mem_allocate(this%dsflowold, this%maxbound,
'DSFLOWOLD', &
536 call mem_allocate(this%storage, this%maxbound,
'STORAGE', &
538 call mem_allocate(this%crmin, this%maxbound,
'CRMIN', this%memoryPath)
539 call mem_allocate(this%crmax, this%maxbound,
'CRMAX', this%memoryPath)
540 call mem_allocate(this%crsum, this%maxbound,
'CRSUM', this%memoryPath)
541 call mem_allocate(this%crcnt, this%maxbound,
'CRCNT', this%memoryPath)
542 if (this%ats_courant /=
dnodata)
then
544 'ITVD_UPSTREAM', this%memoryPath)
546 call mem_allocate(this%itvd_upstream, 0,
'ITVD_UPSTREAM', this%memoryPath)
551 call mem_allocate(this%isfrorder, this%maxbound,
'ISFRORDER', &
553 call mem_allocate(this%ia, this%maxbound + 1,
'IA', this%memoryPath)
555 call mem_allocate(this%idir, 0,
'IDIR', this%memoryPath)
556 call mem_allocate(this%idiv, 0,
'IDIV', this%memoryPath)
557 call mem_allocate(this%qconn, 0,
'QCONN', this%memoryPath)
561 call mem_setptr(this%rain,
'RAINFALL', this%input_mempath)
562 call mem_setptr(this%evap,
'EVAPORATION', this%input_mempath)
563 call mem_setptr(this%inflow,
'INFLOW', this%input_mempath)
564 call mem_setptr(this%runoff,
'RUNOFF', this%input_mempath)
565 call mem_setptr(this%sstage,
'STAGE', this%input_mempath)
566 call mem_setptr(this%hk,
'BEDK', this%input_mempath)
567 call mem_setptr(this%rough,
'MANNING', this%input_mempath)
568 call mem_setptr(this%ustrf,
'UPSTREAM_FRAC', this%input_mempath)
572 call mem_allocate(this%iadiv, this%maxbound + 1,
'IADIV', this%memoryPath)
573 call mem_allocate(this%divreach, 0,
'DIVREACH', this%memoryPath)
574 call mem_allocate(this%divq, 0,
'DIVQ', this%memoryPath)
577 call mem_allocate(this%ncrosspts, this%maxbound,
'NCROSSPTS', &
579 call mem_allocate(this%iacross, this%maxbound + 1,
'IACROSS', &
581 call mem_allocate(this%station, this%ncrossptstot,
'STATION', &
583 call mem_allocate(this%xsheight, this%ncrossptstot,
'XSHEIGHT', &
585 call mem_allocate(this%xsrough, this%ncrossptstot,
'XSROUGH', &
590 do i = 1, this%maxbound
591 this%iboundpak(i) = 1
593 this%igwftopnode(i) = 0
594 this%length(i) =
dzero
595 this%width(i) =
dzero
596 this%strtop(i) =
dzero
597 this%bthick(i) =
dzero
599 this%slope(i) =
dzero
600 this%nconnreach(i) = 0
601 this%ustrf(i) =
dzero
602 this%ftotnd(i) =
dzero
604 this%usflow(i) =
dzero
605 this%dsflow(i) =
dzero
606 this%depth(i) =
dzero
607 this%stage(i) =
dzero
608 this%gwflow(i) =
dzero
609 this%simevap(i) =
dzero
610 this%simrunoff(i) =
dzero
611 this%stage0(i) =
dzero
612 this%usflow0(i) =
dzero
615 if (this%istorage == 1)
then
616 this%stageold(i) =
dzero
617 this%usinflow(i) =
dzero
618 this%usinflowold(i) =
dzero
619 this%dsflowold(i) =
dzero
620 this%storage(i) =
dzero
621 this%crmin(i) =
dep20
622 this%crmax(i) = -
dep20
623 this%crsum(i) =
dzero
625 if (this%ats_courant /=
dnodata)
then
626 this%itvd_upstream(i) = 0
631 this%rough(i) =
dzero
635 this%ncrosspts(i) = 0
636 this%iacross(i + 1) = 0
640 do i = 1, this%ncrossptstot
641 this%station(i) =
dzero
642 this%xsheight(i) =
dzero
643 this%xsrough(i) =
dzero
647 this%csfrbudget(1) =
' RAINFALL'
648 this%csfrbudget(2) =
' EVAPORATION'
649 this%csfrbudget(3) =
' RUNOFF'
650 this%csfrbudget(4) =
' EXT-INFLOW'
651 this%csfrbudget(5) =
' GWF'
652 this%csfrbudget(6) =
' EXT-OUTFLOW'
653 this%csfrbudget(7) =
' FROM-MVR'
654 this%csfrbudget(8) =
' TO-MVR'
657 call mem_allocate(this%qoutflow, this%maxbound,
'QOUTFLOW', this%memoryPath)
658 call mem_allocate(this%qextoutflow, this%maxbound,
'QEXTOUTFLOW', &
660 do i = 1, this%maxbound
661 this%qoutflow(i) =
dzero
662 this%qextoutflow(i) =
dzero
666 if (this%istageout > 0)
then
667 call mem_allocate(this%dbuff, this%maxbound,
'DBUFF', this%memoryPath)
668 do i = 1, this%maxbound
669 this%dbuff(i) =
dzero
672 call mem_allocate(this%dbuff, 0,
'DBUFF', this%memoryPath)
676 allocate (this%cauxcbc(this%cbcauxitems))
679 call mem_allocate(this%qauxcbc, this%cbcauxitems,
'QAUXCBC', &
681 do i = 1, this%cbcauxitems
682 this%qauxcbc(i) =
dzero
686 this%cauxcbc(1) =
'FLOW-AREA '
689 call mem_allocate(this%denseterms, 3, 0,
'DENSETERMS', this%memoryPath)
692 call mem_allocate(this%viscratios, 2, 0,
'VISCRATIOS', this%memoryPath)
693 end subroutine sfr_allocate_arrays
697 subroutine sfr_source_options(this)
704 class(sfrtype),
intent(inout) :: this
706 character(len=LINELENGTH) :: fname
707 logical(LGP) :: found
709 character(len=*),
parameter :: fmtpicard = &
710 &
"(4x, 'MAXIMUM SFR PICARD ITERATION VALUE (',i0,') SPECIFIED.')"
711 character(len=*),
parameter :: fmtiter = &
712 &
"(4x, 'MAXIMUM SFR ITERATION VALUE (',i0,') SPECIFIED.')"
713 character(len=*),
parameter :: fmtdmaxchg = &
714 &
"(4x, 'MAXIMUM DEPTH CHANGE VALUE (',g0,') SPECIFIED.')"
715 character(len=*),
parameter :: fmtlengthconv = &
716 &
"(4x, 'LENGTH CONVERSION VALUE (',g0,') SPECIFIED.')"
717 character(len=*),
parameter :: fmttimeconv = &
718 &
"(4x, 'TIME CONVERSION VALUE (',g0,') SPECIFIED.')"
719 character(len=*),
parameter :: fmtstoweight = &
720 &
"(4x, 'KINEMATIC STORAGE WEIGHT (',g0,') SPECIFIED.')"
721 character(len=*),
parameter :: fmtsfrbin = &
722 "(4x, 'SFR ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', a, /4x, &
723 &'OPENED ON UNIT: ', I0)"
724 integer(I4B) :: isize
727 call this%BndExtType%source_options()
729 write (this%iout,
'(/1x,a)') &
730 'PROCESSING '//trim(adjustl(this%text))//
' OPTIONS'
733 call mem_set_value(this%istorage,
'STORAGE', this%input_mempath, found)
735 write (this%iout,
'(4x,a)') trim(adjustl(this%text))// &
736 ' REACH STORAGE IS ACTIVE.'
741 this%input_mempath, found)
743 if (this%ats_courant <=
dzero)
then
744 write (
errmsg,
'(a,g0,a)') &
745 "ATS_COURANT SPECIFIED TO BE '", this%ats_courant, &
746 "' BUT MUST BE GREATER THAN ZERO"
750 write (this%iout,
'(4x,a,1pg15.6)') &
751 'TARGET COURANT NUMBER FOR ADAPTIVE TIME STEPS: ', &
757 call mem_set_value(this%iprhed,
'PRINT_STAGE', this%input_mempath, found)
759 write (this%iout,
'(4x,a)') trim(adjustl(this%text))// &
760 ' STAGES WILL BE PRINTED TO LISTING FILE.'
764 call mem_set_value(fname,
'STAGEFILE', this%input_mempath, found)
767 call openfile(this%istageout, this%iout, fname,
'DATA(BINARY)', &
769 write (this%iout, fmtsfrbin)
'STAGE', trim(fname), this%istageout
773 call mem_set_value(fname,
'BUDGETFILE', this%input_mempath, found)
775 call assign_iounit(this%ibudgetout, this%inunit,
'BUDGET fileout')
776 call openfile(this%ibudgetout, this%iout, fname,
'DATA(BINARY)', &
778 write (this%iout, fmtsfrbin)
'BUDGET', trim(fname), this%ibudgetout
782 call mem_set_value(fname,
'BUDGETCSVFILE', this%input_mempath, found)
784 call assign_iounit(this%ibudcsv, this%inunit,
'BUDGETCSV fileout')
785 call openfile(this%ibudcsv, this%iout, fname,
'CSV', &
786 filstat_opt=
'REPLACE')
787 write (this%iout, fmtsfrbin)
'BUDGET CSV', trim(fname), this%ibudcsv
791 call mem_set_value(fname,
'PKGCONVFNAME', this%input_mempath, found)
794 call openfile(this%ipakcsv, this%iout, fname,
'CSV', &
795 filstat_opt=
'REPLACE', mode_opt=
mnormal)
796 write (this%iout, fmtsfrbin)
'PACKAGE_CONVERGENCE', trim(fname), &
801 call mem_set_value(this%imover,
'MOVER', this%input_mempath, found)
803 write (this%iout,
'(4x,A)')
'MOVER OPTION ENABLED'
808 this%input_mempath, found)
809 if (found)
write (this%iout, fmtpicard) this%maxsfrpicard
813 this%input_mempath, found)
814 if (found)
write (this%iout, fmtiter) this%maxsfrit
818 this%input_mempath, found)
820 this%deps =
dp999 * this%dmaxchg
821 write (this%iout, fmtdmaxchg) this%dmaxchg
826 this%input_mempath, found)
827 if (found)
write (this%iout, fmtlengthconv) this%lengthconv
831 this%input_mempath, found)
832 if (found)
write (this%iout, fmttimeconv) this%timeconv
836 this%input_mempath, found)
838 write (
warnmsg,
'(a)')
'SETTING UNIT_CONVERSION DIRECTLY'
845 this%input_mempath, found)
847 if (this%storage_weight <
dhalf .or. this%storage_weight >
done)
then
848 write (
errmsg,
'(a,g0,a)') &
849 "STORAGE_WEIGHT SPECIFIED TO BE '", this%storage_weight, &
850 "' BUT CANNOT BE LESS THAN 0.5 OR GREATER THAN 1.0"
854 write (this%iout, fmtstoweight) this%storage_weight
859 call get_isize(
'ICHECK', this%input_mempath, isize)
862 write (this%iout,
'(4x,a)') &
863 'REACH GEOMETRY AND PARAMETER CHECKS WILL NOT BE MADE'
867 call get_isize(
'ICONVCHK', this%input_mempath, isize)
870 write (this%iout,
'(4x,a)') &
871 'A FINAL CONVERGENCE CHECK OF THE CHANGE IN STREAM FLOW ROUTING '// &
872 'STAGES AND FLOWS WILL NOT BE MADE'
875 write (this%iout,
'(1x,a)') &
876 'END OF '//trim(adjustl(this%text))//
' OPTIONS'
877 end subroutine sfr_source_options
881 subroutine sfr_source_dimensions(this)
885 class(sfrtype),
intent(inout) :: this
887 logical(LGP) :: found
892 write (this%iout,
'(/1x,a)') &
893 'PROCESSING '//trim(adjustl(this%text))//
' DIMENSIONS'
896 call mem_set_value(this%maxbound,
'MAXBOUND', this%input_mempath, found, &
899 write (this%iout,
'(4x,a,i0)')
'NREACHES = ', this%maxbound
902 write (this%iout,
'(1x,a)') &
903 'END OF '//trim(adjustl(this%text))//
' DIMENSIONS'
905 if (this%maxbound < 1)
then
907 'NREACHES was not specified or was specified incorrectly.'
916 call this%define_listlabel()
919 this%ncrossptstot = this%maxbound
922 call this%sfr_allocate_arrays()
925 call this%sfr_source_packagedata()
928 call this%sfr_source_crosssections()
931 call this%sfr_source_connectiondata()
934 call this%sfr_source_diversions()
937 call this%sfr_source_initialstages()
940 call this%sfr_setup_budobj()
943 call this%sfr_setup_tableobj()
944 end subroutine sfr_source_dimensions
948 subroutine sfr_source_packagedata(this)
953 class(sfrtype),
intent(inout) :: this
955 integer(I4B) :: i, n, nconzero
957 character(len=10) :: cnum
958 character(len=LENBOUNDNAME) :: bndName
959 character(len=LINELENGTH) :: cellid_str
960 integer(I4B),
allocatable :: nboundchk(:)
961 integer(I4B),
dimension(:),
pointer,
contiguous :: ifno => null()
962 integer(I4B),
dimension(:, :),
pointer,
contiguous :: cellid => null()
963 real(DP),
dimension(:),
pointer,
contiguous :: rlen => null()
964 real(DP),
dimension(:),
pointer,
contiguous :: rwid => null()
965 real(DP),
dimension(:),
pointer,
contiguous :: rgrd => null()
966 real(DP),
dimension(:),
pointer,
contiguous :: rtp => null()
967 real(DP),
dimension(:),
pointer,
contiguous :: rbth => null()
968 integer(I4B),
dimension(:),
pointer,
contiguous :: ncon => null()
969 integer(I4B),
dimension(:),
pointer,
contiguous :: ndv => null()
973 write (this%iout,
'(/1x,a)') &
974 'PROCESSING '//trim(adjustl(this%text))//
' PACKAGEDATA'
977 call mem_setptr(ifno,
'PACKAGEDATA_IFNO', this%input_mempath)
978 call mem_setptr(cellid,
'CELLID', this%input_mempath)
979 call mem_setptr(rlen,
'RLEN', this%input_mempath)
980 call mem_setptr(rwid,
'RWID', this%input_mempath)
981 call mem_setptr(rgrd,
'RGRD', this%input_mempath)
982 call mem_setptr(rtp,
'RTP', this%input_mempath)
983 call mem_setptr(rbth,
'RBTH', this%input_mempath)
984 call mem_setptr(this%input%rhk,
'RHK', this%input_mempath)
985 call mem_setptr(this%input%man,
'MAN', this%input_mempath)
986 call mem_setptr(ncon,
'NCON', this%input_mempath)
987 call mem_setptr(this%input%ustrf,
'USTRF', this%input_mempath)
988 call mem_setptr(ndv,
'NDV', this%input_mempath)
989 if (this%inamedbound /= 0)
then
990 call mem_setptr(boundname,
'BOUNDNAME', this%input_mempath)
994 allocate (nboundchk(this%maxbound))
999 do i = 1, this%maxbound
1002 n = this%validate_ifno(n, this%maxbound, nboundchk, &
1003 'rno',
'PACKAGEDATA')
1008 if (all(cellid(1:this%dis%ndim, i) <= 0))
then
1009 this%igwfnode(n) = 0
1011 write (cellid_str,
'(10(i0,1x))') cellid(1:this%dis%ndim, i)
1012 this%igwfnode(n) = this%dis%noder_from_cellid(cellid_str, &
1013 this%inunit, this%iout, &
1014 flag_string=.false., &
1017 this%igwftopnode(n) = this%igwfnode(n)
1018 if (this%igwfnode(n) < 1) this%ianynone = this%ianynone + 1
1021 this%length(n) = rlen(i)
1022 this%width(n) = rwid(i)
1023 this%slope(n) = rgrd(i)
1024 this%strtop(n) = rtp(i)
1025 this%bthick(n) = rbth(i)
1028 this%nconnreach(n) = ncon(i)
1029 this%nconn = this%nconn + ncon(i)
1030 if (ncon(i) < 0)
then
1031 write (
errmsg,
'(a,1x,i0,1x,a,i0,a)') &
1032 'NCON for reach', n, &
1033 'must be greater than or equal to 0 (', ncon(i),
').'
1035 else if (ncon(i) == 0)
then
1036 nconzero = nconzero + 1
1040 this%ndiv(n) = ndv(i)
1041 if (ndv(i) > 0) this%idiversions = 1
1044 write (cnum,
'(i10.10)') n
1045 bndname =
'Reach'//cnum
1046 if (this%inamedbound /= 0)
then
1047 bndname = boundname(i)
1049 this%sfrname(n) = bndname
1053 this%hk(n) = this%input%rhk(i)
1054 this%rough(n) = this%input%man(i)
1055 this%ustrf(n) = this%input%ustrf(i)
1058 this%sstage(n) = this%strtop(n)
1061 write (this%iout,
'(1x,a)') &
1062 'END OF '//trim(adjustl(this%text))//
' PACKAGEDATA'
1065 call this%report_ifno_coverage(nboundchk, this%maxbound,
'reach', &
1067 deallocate (nboundchk)
1069 if (nconzero > 0)
then
1070 write (
warnmsg,
'(a,1x,a,1x,a,1x,i0,1x,a)') &
1071 'SFR Package', trim(this%packName), &
1072 'has', nconzero,
'reach(es) with zero connections.'
1082 this%iacross(1) = ipos
1083 do i = 1, this%maxbound
1084 this%ncrosspts(i) = 1
1085 this%station(ipos) = this%width(i)
1086 this%xsheight(ipos) =
dzero
1087 this%xsrough(ipos) =
done
1089 this%iacross(i + 1) = ipos
1103 end subroutine sfr_source_packagedata
1107 subroutine sfr_source_crosssections(this)
1114 class(sfrtype),
intent(inout) :: this
1116 integer(I4B),
dimension(:),
pointer,
contiguous :: ifno => null()
1118 tab6_filename => null()
1120 sfrtab6_mempaths => null()
1122 integer(I4B) :: i, n, ncrossptstot
1123 integer(I4B),
allocatable :: nboundchk(:)
1124 integer(I4B) :: isize
1125 character(len=LINELENGTH) :: tabfname
1126 character(len=LENMEMPATH) :: mempath
1129 call get_isize(
'CROSSSECT_IFNO', this%input_mempath, isize)
1130 if (isize < 1)
return
1132 write (this%iout,
'(/1x,a)') &
1133 'PROCESSING '//trim(adjustl(this%text))//
' CROSSSECTIONS'
1136 call mem_setptr(ifno,
'CROSSSECT_IFNO', this%input_mempath)
1137 call mem_setptr(tab6_filename,
'SFRTAB6_FILENAME', this%input_mempath)
1138 call mem_setptr(sfrtab6_mempaths,
'SFRTAB6_MEMPATH', this%input_mempath)
1142 call cross_data%initialize(this%ncrossptstot, this%ncrosspts, &
1143 this%iacross, this%station, this%xsheight, &
1146 allocate (nboundchk(this%maxbound))
1150 n = this%validate_ifno(ifno(i), this%maxbound, nboundchk, &
1151 'reach',
'CROSSSECTIONS')
1153 tabfname = tab6_filename(i)
1154 mempath = sfrtab6_mempaths(i)
1155 call cross_data%source_table(n, this%width(n), mempath, &
1156 trim(adjustl(tabfname)))
1159 write (this%iout,
'(1x,a)') &
1160 'END OF '//trim(adjustl(this%text))//
' CROSSSECTIONS'
1163 call this%report_ifno_coverage(nboundchk, this%maxbound,
'reach', &
1164 'CROSSSECTIONS', check_missing=.false.)
1165 deallocate (nboundchk)
1172 ncrossptstot = cross_data%get_ncrossptstot()
1173 if (ncrossptstot /= this%ncrossptstot)
then
1174 this%ncrossptstot = ncrossptstot
1175 call mem_reallocate(this%station, this%ncrossptstot,
'STATION', &
1177 call mem_reallocate(this%xsheight, this%ncrossptstot,
'XSHEIGHT', &
1179 call mem_reallocate(this%xsrough, this%ncrossptstot,
'XSROUGH', &
1183 call cross_data%output(this%width, this%rough)
1184 call cross_data%pack(this%ncrossptstot, this%ncrosspts, this%iacross, &
1185 this%station, this%xsheight, this%xsrough)
1186 call cross_data%destroy()
1187 deallocate (cross_data)
1188 nullify (cross_data)
1193 end subroutine sfr_source_crosssections
1197 subroutine sfr_source_connectiondata(this)
1202 class(sfrtype),
intent(inout) :: this
1204 integer(I4B),
dimension(:),
pointer,
contiguous :: cd_ifno => null()
1205 integer(I4B),
dimension(:),
pointer,
contiguous :: ic_flat => null()
1206 integer(I4B),
dimension(:),
pointer,
contiguous :: cd_ia => null()
1208 integer(I4B),
dimension(:),
pointer,
contiguous :: rowmaxnnz => null()
1209 integer(I4B),
allocatable :: nboundchk(:)
1210 integer(I4B),
allocatable :: iconndata(:, :)
1211 integer(I4B),
allocatable :: iup(:)
1212 integer(I4B),
allocatable :: order(:)
1213 type(
dag) :: sfr_dag
1214 integer(I4B) :: i, n, j, jj, jcol, jcol2, nja, nconnmax
1215 integer(I4B) :: ival, idir, nup, ipos, istat, ierr, jlocal, nread
1217 write (this%iout,
'(/1x,a)') &
1218 'PROCESSING '//trim(adjustl(this%text))//
' CONNECTIONDATA'
1221 call mem_setptr(cd_ifno,
'CONNDATA_IFNO', this%input_mempath)
1222 call mem_setptr(ic_flat,
'IC', this%input_mempath)
1223 call mem_setptr(cd_ia,
'IC_IA', this%input_mempath)
1226 allocate (nboundchk(this%maxbound))
1232 allocate (rowmaxnnz(this%maxbound))
1233 do n = 1, this%maxbound
1234 ival = this%nconnreach(n)
1235 if (ival < 0) ival = 0
1236 rowmaxnnz(n) = ival + 1
1237 nja = nja + ival + 1
1238 if (ival > nconnmax) nconnmax = ival
1251 allocate (iconndata(nconnmax, this%maxbound))
1255 call sparse%init(this%maxbound, this%maxbound, rowmaxnnz)
1258 do i = 1, this%maxbound
1259 n = this%validate_ifno(cd_ifno(i), this%maxbound, nboundchk, &
1260 'reach',
'CONNECTIONDATA')
1262 nread = cd_ia(i + 1) - cd_ia(i)
1263 if (nread /= this%nconnreach(n))
then
1264 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,a)') &
1265 'Reach', n,
'connectiondata specifies', nread, &
1266 'connections but NCON for this reach in packagedata is', &
1267 this%nconnreach(n),
'.'
1271 call sparse%addconnection(n, n, 1)
1273 do j = cd_ia(i), cd_ia(i + 1) - 1
1276 iconndata(jlocal, n) = ival
1280 else if (ival == 0)
then
1281 call store_error(
'Missing or zero connection reach in connectiondata.')
1286 if (ival > this%maxbound)
then
1287 call store_error(
'Reach number exceeds NREACHES in connectiondata.')
1290 call sparse%addconnection(n, ival, 1)
1294 write (this%iout,
'(1x,a)') &
1295 'END OF '//trim(adjustl(this%text))//
' CONNECTIONDATA'
1297 call this%report_ifno_coverage(nboundchk, this%maxbound,
'reach', &
1305 call sparse%filliaja(this%ia, this%ja, ierr, sort=.true.)
1307 write (
errmsg,
'(a,3(1x,a))') &
1308 'Could not fill', trim(this%packName), &
1309 'package IA and JA connection data.', &
1310 'Check connectivity data in connectiondata block.'
1315 do n = 1, this%maxbound
1316 do j = this%ia(n) + 1, this%ia(n + 1) - 1
1318 do jj = 1, this%nconnreach(n)
1319 jcol2 = iconndata(jj, n)
1320 if (abs(jcol2) == jcol)
then
1322 if (jcol2 < 0) idir = -1
1331 deallocate (rowmaxnnz)
1332 deallocate (nboundchk)
1333 deallocate (iconndata)
1334 call sparse%destroy()
1338 call sfr_dag%set_vertices(this%maxbound)
1339 fill_dag:
do n = 1, this%maxbound
1341 do j = this%ia(n) + 1, this%ia(n + 1) - 1
1342 if (this%idir(j) > 0) nup = nup + 1
1344 if (nup == 0) cycle fill_dag
1347 do j = this%ia(n) + 1, this%ia(n + 1) - 1
1348 if (this%idir(j) > 0)
then
1349 iup(ipos) = this%ja(j)
1353 call sfr_dag%set_edges(n, iup)
1356 call sfr_dag%toposort(order, istat)
1357 if (istat == -1)
then
1359 trim(adjustl(this%text))//
' PACKAGE ('// &
1360 trim(adjustl(this%packName))//
') cannot calculate a '// &
1361 'Directed Asyclic Graph for reach connectivity because '// &
1362 'of circular dependency. Using the reach number for '// &
1363 'solution ordering.'
1366 do n = 1, this%maxbound
1367 if (istat == 0)
then
1368 this%isfrorder(n) = order(n)
1370 this%isfrorder(n) = n
1373 call sfr_dag%destroy()
1374 if (istat == 0)
deallocate (order)
1380 end subroutine sfr_source_connectiondata
1384 subroutine sfr_source_diversions(this)
1389 class(sfrtype),
intent(inout) :: this
1391 integer(I4B),
dimension(:),
pointer,
contiguous :: d_ifno => null()
1392 integer(I4B),
dimension(:),
pointer,
contiguous :: d_idv => null()
1393 integer(I4B),
dimension(:),
pointer,
contiguous :: d_iconr => null()
1396 integer(I4B) :: i, n, idiv, ndiversions, i0, ipos, jpos
1397 integer(I4B) :: isize
1398 integer(I4B),
allocatable :: iachk(:), nboundchk(:)
1399 character(len=16) :: cval
1405 do n = 1, this%maxbound
1406 ndiversions = ndiversions + this%ndiv(n)
1407 i0 = i0 + this%ndiv(n)
1408 this%iadiv(n + 1) = i0
1412 if (ndiversions > 0)
then
1415 allocate (this%divcprior(ndiversions))
1416 call mem_setptr(this%divflow,
'DIVFLOW', this%input_mempath)
1417 call mem_reallocate(this%divq, ndiversions,
'DIVQ', this%memoryPath)
1422 call get_isize(
'DIVERSIONS_IFNO', this%input_mempath, isize)
1424 if (this%idiversions /= 0)
then
1425 call store_error(
'REQUIRED DIVERSIONS BLOCK NOT FOUND.')
1431 if (this%idiversions == 0)
then
1432 write (
errmsg,
'(a,1x,a)') &
1433 'A diversions block should not be', &
1434 'specified if diversions are not specified.'
1440 write (this%iout,
'(/1x,a)') &
1441 'PROCESSING '//trim(adjustl(this%text))//
' DIVERSIONS'
1444 call mem_setptr(d_ifno,
'DIVERSIONS_IFNO', this%input_mempath)
1445 call mem_setptr(d_idv,
'DIVERSIONS_IDV', this%input_mempath)
1446 call mem_setptr(d_iconr,
'ICONR', this%input_mempath)
1447 call mem_setptr(d_cprior,
'CPRIOR', this%input_mempath)
1450 allocate (iachk(this%maxbound + 1))
1451 allocate (nboundchk(ndiversions))
1454 do n = 1, this%maxbound
1455 iachk(n + 1) = iachk(n) + this%ndiv(n)
1460 if (n < 1 .or. n > this%maxbound)
then
1461 write (
errmsg,
'(a,i0,a)')
'Reach number should be between 1 and ', &
1466 if (this%ndiv(n) < 1)
then
1467 write (
errmsg,
'(a,i0)') &
1468 'Diversions cannot be specified for reach ', n
1473 if (idiv < 1 .or. idiv > this%ndiv(n))
then
1474 write (
errmsg,
'(a,i0,a,i0,a)') &
1475 'Reach ', n,
' diversion number should be between 1 and ', &
1480 ipos = iachk(n) + idiv - 1
1481 nboundchk(ipos) = nboundchk(ipos) + 1
1482 jpos = this%iadiv(n) + idiv - 1
1483 if (d_iconr(i) < 1 .or. d_iconr(i) > this%maxbound)
then
1484 write (
errmsg,
'(a,i0,a)') &
1485 'Diversion target reach number should be between 1 and ', &
1490 this%divreach(jpos) = d_iconr(i)
1492 select case (trim(cval))
1493 case (
'UPTO',
'THRESHOLD',
'FRACTION',
'EXCESS')
1495 errmsg =
'Invalid cprior type '//trim(cval)//
'.'
1498 this%divcprior(jpos) = trim(cval)
1501 write (this%iout,
'(1x,a)') &
1502 'END OF '//trim(adjustl(this%text))//
' DIVERSIONS'
1504 do n = 1, this%maxbound
1505 do idiv = 1, this%ndiv(n)
1506 ipos = iachk(n) + idiv - 1
1507 if (nboundchk(ipos) == 0)
then
1508 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1509 'No data specified for reach', n,
'diversion', idiv
1511 else if (nboundchk(ipos) > 1)
then
1512 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1513 'Data for reach', n,
'diversion', idiv, &
1514 'specified', nboundchk(ipos),
'times'
1520 deallocate (nboundchk)
1531 end subroutine sfr_source_diversions
1535 subroutine sfr_source_initialstages(this)
1539 class(sfrtype),
intent(inout) :: this
1541 integer(I4B),
dimension(:),
pointer,
contiguous :: is_ifno => null()
1542 real(DP),
dimension(:),
pointer,
contiguous :: is_stage => null()
1543 integer(I4B) :: i, n
1544 integer(I4B) :: isize
1545 integer(I4B),
allocatable :: nboundchk(:)
1549 call get_isize(
'INITSTAGE_IFNO', this%input_mempath, isize)
1552 if (this%istorage == 1)
then
1553 do n = 1, this%maxbound
1554 this%stage(n) = this%strtop(n)
1560 write (this%iout,
'(/1x,a)') &
1561 'PROCESSING '//trim(adjustl(this%text))//
' INITIALSTAGES'
1563 call mem_setptr(is_ifno,
'INITSTAGE_IFNO', this%input_mempath)
1564 call mem_setptr(is_stage,
'INITIALSTAGE', this%input_mempath)
1566 allocate (nboundchk(this%maxbound))
1570 n = this%validate_ifno(is_ifno(i), this%maxbound, nboundchk, &
1571 'reach',
'INITIALSTAGES')
1574 this%stage(n) = rval
1575 this%depth(n) = rval - this%strtop(n)
1576 if (rval < this%strtop(n))
then
1577 write (
errmsg,
'(a,g0,a,1x,i0,1x,a,g0,a)') &
1578 'Initial stage (', rval,
') for reach', n, &
1579 'is less than the reach top (', this%strtop(n),
').'
1584 write (this%iout,
'(1x,a)') &
1585 'END OF '//trim(adjustl(this%text))//
' INITIALSTAGES'
1587 call this%report_ifno_coverage(nboundchk, this%maxbound,
'reach', &
1589 deallocate (nboundchk)
1598 end subroutine sfr_source_initialstages
1604 subroutine sfr_ar(this)
1608 class(sfrtype),
intent(inout) :: this
1611 integer(I4B) :: ierr
1614 call this%obs%obs_ar()
1617 call this%BndExtType%allocate_arrays()
1621 call this%BndExtType%allocate_featureauxvar()
1625 call this%input%init(this%input_mempath, this%naux)
1628 if (this%inamedbound /= 0)
then
1629 do n = 1, this%maxbound
1630 this%boundname(n) = this%sfrname(n)
1635 call this%copy_boundname()
1638 do n = 1, this%maxbound
1639 this%nodelist(n) = this%igwfnode(n)
1643 call this%sfr_check_conversion()
1646 call this%sfr_check_storage_weight()
1649 if (this%ats_courant /=
dnodata .and. this%istorage /= 1)
then
1651 'ATS_COURANT OPTION REQUIRES STORAGE OPTION TO BE ACTIVE'
1658 'ATS_COURANT IS SPECIFIED IN THE SFR OPTIONS BLOCK BUT THE '// &
1659 'ATS PACKAGE IS NOT ACTIVE IN TDIS, SO THE TIME STEP IS NOT '// &
1660 'ADAPTED TO THE COURANT NUMBER. IF THE COURANT NUMBER EXCEEDS 1 '// &
1661 'THE EXPLICIT KINEMATIC-WAVE ROUTING MAY OSCILLATE WHILE STILL '// &
1662 'CLOSING THE BUDGET. ACTIVATE THE ATS PACKAGE OR USE A SMALLER '// &
1668 if (this%ats_courant /=
dnodata .and. this%istorage == 1)
then
1669 call this%sfr_precompute_tvd()
1673 call this%sfr_check_reaches()
1676 call this%sfr_check_connections()
1679 if (this%idiversions /= 0)
then
1680 call this%sfr_check_diversions()
1684 if (this%istorage == 1)
then
1685 call this%sfr_check_initialstages()
1695 if (this%imover /= 0)
then
1696 allocate (this%pakmvrobj)
1697 call this%pakmvrobj%ar(this%maxbound, this%maxbound, this%memoryPath)
1699 end subroutine sfr_ar
1705 subroutine sfr_rp(this)
1712 class(sfrtype),
intent(inout) :: this
1714 character(len=LINELENGTH) :: crossfile
1715 character(len=LINELENGTH) :: str
1716 real(DP) :: auxvaldbl
1717 character(len=LINELENGTH) :: title
1718 character(len=LINELENGTH) :: text
1719 character(len=LENVARNAME) :: setting
1720 character(len=10) :: cnum
1721 character(len=10) :: cp
1726 integer(I4B) :: idiv
1727 integer(I4B) :: ichkustrm
1728 integer(I4B) :: ncrossptstot
1731 character(len=*),
parameter :: fmtlsp = &
1732 &
"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
1741 this%nbound = this%maxbound
1744 if (this%iper ==
kper)
then
1748 call cross_data%initialize(this%ncrossptstot, this%ncrosspts, &
1750 this%station, this%xsheight, &
1754 if (this%iprpak /= 0)
then
1755 title = trim(adjustl(this%text))//
' PACKAGE ('// &
1756 trim(adjustl(this%packName))//
') DATA FOR PERIOD'
1757 write (title,
'(a,1x,i6)') trim(adjustl(title)),
kper
1758 call table_cr(this%inputtab, this%packName, title)
1759 call this%inputtab%table_df(1, 4, this%iout, finalize=.false.)
1761 call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
1763 call this%inputtab%initialize_column(text, 20, alignment=tableft)
1765 write (text,
'(a,1x,i6)')
'VALUE', jj
1766 call this%inputtab%initialize_column(text, 15, alignment=tabcenter)
1771 do i = 1, this%input%nbound
1772 n = this%input%ifno(i)
1773 if (n < 1 .or. n > this%maxbound)
then
1774 write (
errmsg,
'(a,1x,a,1x,i0,a)') &
1775 'Reach number (RNO) must be greater than 0 and', &
1776 'less than or equal to', this%maxbound,
'.'
1782 setting = this%input%setting(i)
1785 if (trim(setting) ==
'STATUS')
then
1786 str = this%input%status(i)
1788 if (str ==
'INACTIVE')
then
1789 this%iboundpak(n) = 0
1790 else if (str ==
'ACTIVE')
then
1791 this%iboundpak(n) = 1
1792 else if (str ==
'SIMPLE')
then
1793 this%iboundpak(n) = -1
1796 'Unknown '//trim(this%text)//
' sfr status keyword: ', trim(str)
1803 call this%sfr_set_period_value(i, n, setting)
1804 if (trim(setting) ==
'UPSTREAM_FRAC') ichkustrm = 1
1807 if (trim(setting) ==
'DIVERSION')
then
1808 if (this%ndiv(n) < 1)
then
1809 write (cnum,
'(i0)') n
1810 errmsg =
'diversions cannot be specified for reach '//trim(cnum)
1813 idiv = this%input%idv(i)
1814 if (idiv < 1 .or. idiv > this%ndiv(n))
then
1815 write (cnum,
'(i0)') n
1816 errmsg =
'Reach '//trim(cnum)
1817 write (cnum,
'(i0)') this%ndiv(n)
1818 errmsg = trim(
errmsg)//
' diversion number should be between 1 '// &
1819 'and '//trim(cnum)//
'.'
1822 ii = this%iadiv(n) + idiv - 1
1824 cp = this%divcprior(ii)
1825 if (cp ==
'FRACTION' .and. &
1826 (this%divflow(ii) < dzero .or. this%divflow(ii) > done))
then
1827 write (
errmsg,
'(a,1x,i0,a)') &
1828 'cprior is type FRACTION for diversion no.', ii, &
1829 ', but divflow not within the range 0.0 to 1.0'
1837 if (trim(setting) ==
'CROSS_SECTION')
then
1838 crossfile = this%input%tab6_filename(i)
1839 call cross_data%read_table(n, this%width(n), trim(adjustl(crossfile)))
1844 if (this%naux > 0)
then
1845 if (trim(setting) ==
'PERIOD_AUXILIARY')
then
1846 str = this%input%auxname(i)
1847 auxvaldbl = this%input%auxval(i)
1852 if (this%iprpak /= 0)
then
1853 call this%inputtab%add_term(n)
1854 if (trim(setting) ==
'PERIOD_AUXILIARY')
then
1855 call this%inputtab%add_term(
'AUXILIARY')
1857 call this%inputtab%add_term(trim(setting))
1859 select case (trim(setting))
1861 call this%inputtab%add_term(trim(str))
1862 call this%inputtab%add_term(
' ')
1864 call this%inputtab%add_term(this%hk(n))
1865 call this%inputtab%add_term(
' ')
1867 call this%inputtab%add_term(this%rough(n))
1868 call this%inputtab%add_term(
' ')
1870 call this%inputtab%add_term(this%sstage(n))
1871 call this%inputtab%add_term(
' ')
1873 call this%inputtab%add_term(this%inflow(n))
1874 call this%inputtab%add_term(
' ')
1876 call this%inputtab%add_term(this%rain(n))
1877 call this%inputtab%add_term(
' ')
1878 case (
'EVAPORATION')
1879 call this%inputtab%add_term(this%evap(n))
1880 call this%inputtab%add_term(
' ')
1882 call this%inputtab%add_term(this%runoff(n))
1883 call this%inputtab%add_term(
' ')
1884 case (
'UPSTREAM_FRAC')
1885 call this%inputtab%add_term(this%ustrf(n))
1886 call this%inputtab%add_term(
' ')
1888 call this%inputtab%add_term(idiv)
1889 call this%inputtab%add_term(this%divflow(ii))
1890 case (
'CROSS_SECTION')
1891 call this%inputtab%add_term(trim(crossfile))
1892 call this%inputtab%add_term(
' ')
1893 case (
'PERIOD_AUXILIARY')
1894 call this%inputtab%add_term(trim(str))
1895 call this%inputtab%add_term(auxvaldbl)
1897 call this%inputtab%add_term(
' ')
1898 call this%inputtab%add_term(
' ')
1902 if (this%iprpak /= 0)
then
1903 call this%inputtab%finalize_table()
1907 ncrossptstot = cross_data%get_ncrossptstot()
1910 if (ncrossptstot /= this%ncrossptstot)
then
1911 this%ncrossptstot = ncrossptstot
1912 call mem_reallocate(this%station, this%ncrossptstot,
'STATION', &
1914 call mem_reallocate(this%xsheight, this%ncrossptstot,
'XSHEIGHT', &
1916 call mem_reallocate(this%xsrough, this%ncrossptstot,
'XSROUGH', &
1921 call cross_data%output(this%width, this%rough, kstp=1,
kper=
kper)
1924 call cross_data%pack(this%ncrossptstot, this%ncrosspts, &
1931 call cross_data%destroy()
1932 deallocate (cross_data)
1933 nullify (cross_data)
1935 write (this%iout, fmtlsp) trim(this%filtyp)
1940 if (ichkustrm /= 0)
then
1941 call this%sfr_check_ustrf()
1948 end subroutine sfr_rp
1955 subroutine sfr_ad(this)
1959 class(sfrtype) :: this
1964 integer(I4B) :: idiv
1965 integer(I4B) :: iaux
1966 character(len=LENVARNAME) :: setting
1970 call this%BndExtType%bnd_ad()
1973 if (this%istorage == 1)
then
1974 do n = 1, this%maxbound
1975 this%stageold(n) = this%stage(n)
1976 this%usinflowold(n) = this%usinflow(n)
1977 this%dsflowold(n) = this%dsflow(n)
1983 if (this%ts_active)
then
1984 do i = 1, this%maxbound
1985 n = this%pkg_ifno(i)
1986 if (.not. this%bedk_set(n)) this%hk(n) = this%input%rhk(i)
1987 if (.not. this%manning_set(n)) this%rough(n) = this%input%man(i)
1988 if (.not. this%ustrf_set(n)) this%ustrf(n) = this%input%ustrf(i)
1991 if (this%input%nbound > 0)
then
1992 do i = 1, this%input%nbound
1993 n = this%input%ifno(i)
1994 if (n < 1 .or. n > this%maxbound) cycle
1996 setting = this%input%setting(i)
1997 call this%sfr_set_period_value(i, n, setting)
1999 if (trim(setting) ==
'DIVERSION')
then
2000 if (this%ndiv(n) >= 1)
then
2001 idiv = this%input%idv(i)
2002 if (idiv >= 1 .and. idiv <= this%ndiv(n))
then
2003 ii = this%iadiv(n) + idiv - 1
2013 if (this%ts_active)
call this%sfr_check_ustrf()
2018 if (this%naux > 0)
then
2019 do n = 1, this%maxbound
2020 do iaux = 1, this%naux
2021 if (this%noupdateauxvar(iaux) /= 0) cycle
2022 this%auxvar(iaux, n) = this%featureauxvar(iaux, n)
2028 do n = 1, this%maxbound
2029 this%usflow(n) = dzero
2030 if (this%iboundpak(n) < 0)
then
2031 this%stage(n) = this%sstage(n)
2036 if (this%imover == 1)
then
2037 call this%pakmvrobj%ad()
2039 end subroutine sfr_ad
2046 subroutine sfr_cf(this)
2048 class(sfrtype) :: this
2051 integer(I4B) :: igwfnode
2054 if (this%nbound == 0)
return
2057 do n = 1, this%nbound
2058 igwfnode = this%igwftopnode(n)
2059 if (igwfnode > 0)
then
2060 if (this%ibound(igwfnode) == 0)
then
2061 call this%dis%highest_active(igwfnode, this%ibound)
2064 this%igwfnode(n) = igwfnode
2065 this%nodelist(n) = igwfnode
2067 end subroutine sfr_cf
2074 subroutine sfr_fc(this, rhs, ia, idxglo, matrix_sln)
2076 class(sfrtype) :: this
2077 real(DP),
dimension(:),
intent(inout) :: rhs
2078 integer(I4B),
dimension(:),
intent(in) :: ia
2079 integer(I4B),
dimension(:),
intent(in) :: idxglo
2085 integer(I4B) :: ipos
2086 integer(I4B) :: node
2097 sfrpicard:
do i = 1, this%maxsfrpicard
2103 if (this%imover == 1)
then
2104 call this%pakmvrobj%fc()
2108 reachsolve:
do j = 1, this%nbound
2109 n = this%isfrorder(j)
2110 node = this%igwfnode(n)
2112 hgwf = this%xnew(node)
2119 this%stage0(n) = this%stage(n)
2120 this%usflow0(n) = this%usflow(n)
2127 if (this%iboundpak(n) /= 0)
then
2128 call this%sfr_solve(n, hgwf, hhcof, rrhs)
2130 this%depth(n) =
dzero
2131 this%stage(n) = this%strtop(n)
2133 call this%sfr_update_flows(n, v, v)
2139 this%hcof(n) = hhcof
2143 ds = s0 - this%stage(n)
2146 if (abs(ds) > abs(dsmax))
then
2153 if (abs(dsmax) <= this%dmaxchg)
then
2160 do n = 1, this%nbound
2161 node = this%nodelist(n)
2163 rhs(node) = rhs(node) + this%rhs(n)
2165 call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(n))
2167 end subroutine sfr_fc
2174 subroutine sfr_fn(this, rhs, ia, idxglo, matrix_sln)
2176 class(sfrtype) :: this
2177 real(DP),
dimension(:),
intent(inout) :: rhs
2178 integer(I4B),
dimension(:),
intent(in) :: ia
2179 integer(I4B),
dimension(:),
intent(in) :: idxglo
2185 integer(I4B) :: ipos
2195 do j = 1, this%nbound
2196 i = this%isfrorder(j)
2198 if (this%iboundpak(i) < 1) cycle
2200 n = this%nodelist(i)
2203 rterm = this%hcof(i) * this%xnew(n)
2205 hgwf = this%xnew(n) +
dem4
2206 call this%sfr_solve(i, hgwf, hcof1, rhs1, update=.false.)
2207 q1 = rhs1 - hcof1 * hgwf
2209 q2 = this%rhs(i) - this%hcof(i) * this%xnew(n)
2211 drterm = (q2 - q1) /
dem4
2214 call matrix_sln%add_value_pos(idxglo(ipos), drterm - this%hcof(i))
2215 rhs(n) = rhs(n) - rterm + drterm * this%xnew(n)
2217 end subroutine sfr_fn
2224 subroutine sfr_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
2228 class(sfrtype),
intent(inout) :: this
2229 integer(I4B),
intent(in) :: innertot
2230 integer(I4B),
intent(in) :: kiter
2231 integer(I4B),
intent(in) :: iend
2232 integer(I4B),
intent(in) :: icnvgmod
2233 character(len=LENPAKLOC),
intent(inout) :: cpak
2234 integer(I4B),
intent(inout) :: ipak
2235 real(DP),
intent(inout) :: dpak
2237 character(len=LENPAKLOC) :: cloc
2238 character(len=LINELENGTH) :: tag
2239 integer(I4B) :: icheck
2240 integer(I4B) :: ipakfail
2241 integer(I4B) :: locdhmax
2242 integer(I4B) :: locrmax
2243 integer(I4B) :: locdqfrommvrmax
2244 integer(I4B) :: ntabrows
2245 integer(I4B) :: ntabcols
2249 real(DP) :: qtolfact
2254 real(DP) :: dqfrommvr
2255 real(DP) :: dqfrommvrmax
2258 icheck = this%iconvchk
2266 dqfrommvrmax =
dzero
2270 if (this%ipakcsv == 0)
then
2271 if (icnvgmod == 0)
then
2279 if (.not.
associated(this%pakcsvtab))
then
2284 if (this%imover == 1)
then
2285 ntabcols = ntabcols + 2
2289 call table_cr(this%pakcsvtab, this%packName,
'')
2290 call this%pakcsvtab%table_df(ntabrows, ntabcols, this%ipakcsv, &
2291 lineseparator=.false., separator=
',', &
2295 tag =
'total_inner_iterations'
2296 call this%pakcsvtab%initialize_column(tag, 10, alignment=
tableft)
2298 call this%pakcsvtab%initialize_column(tag, 10, alignment=
tableft)
2300 call this%pakcsvtab%initialize_column(tag, 10, alignment=
tableft)
2302 call this%pakcsvtab%initialize_column(tag, 10, alignment=
tableft)
2304 call this%pakcsvtab%initialize_column(tag, 10, alignment=
tableft)
2306 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
2308 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
2310 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
2311 tag =
'dinflowmax_loc'
2312 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
2313 if (this%imover == 1)
then
2314 tag =
'dqfrommvrmax'
2315 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
2316 tag =
'dqfrommvrmax_loc'
2317 call this%pakcsvtab%initialize_column(tag, 16, alignment=
tableft)
2323 if (icheck /= 0)
then
2324 final_check:
do n = 1, this%maxbound
2325 if (this%iboundpak(n) == 0) cycle
2328 qtolfact =
delt / this%calc_surface_area(n)
2331 dh = this%stage0(n) - this%stage(n)
2334 if (this%gwfiss == 0)
then
2335 r = this%usflow0(n) - this%usflow(n)
2343 if (this%imover == 1)
then
2344 q = this%pakmvrobj%get_qfrommvr(n)
2345 q0 = this%pakmvrobj%get_qfrommvr0(n)
2346 dqfrommvr = qtolfact * (q0 - q)
2355 dqfrommvrmax = dqfrommvr
2358 if (abs(dh) > abs(dhmax))
then
2362 if (abs(r) > abs(rmax))
then
2366 if (abs(dqfrommvr) > abs(dqfrommvrmax))
then
2367 dqfrommvrmax = dqfrommvr
2374 if (abs(dhmax) > abs(dpak))
then
2377 write (cloc,
"(a,'-',a)") trim(this%packName),
'stage'
2380 if (abs(rmax) > abs(dpak))
then
2383 write (cloc,
"(a,'-',a)") trim(this%packName),
'inflow'
2386 if (this%imover == 1)
then
2387 if (abs(dqfrommvrmax) > abs(dpak))
then
2388 ipak = locdqfrommvrmax
2390 write (cloc,
"(a,'-',a)") trim(this%packName),
'qfrommvr'
2396 if (this%ipakcsv /= 0)
then
2399 call this%pakcsvtab%add_term(innertot)
2400 call this%pakcsvtab%add_term(
totim)
2401 call this%pakcsvtab%add_term(
kper)
2402 call this%pakcsvtab%add_term(
kstp)
2403 call this%pakcsvtab%add_term(kiter)
2404 call this%pakcsvtab%add_term(dhmax)
2405 call this%pakcsvtab%add_term(locdhmax)
2406 call this%pakcsvtab%add_term(rmax)
2407 call this%pakcsvtab%add_term(locrmax)
2408 if (this%imover == 1)
then
2409 call this%pakcsvtab%add_term(dqfrommvrmax)
2410 call this%pakcsvtab%add_term(locdqfrommvrmax)
2415 call this%pakcsvtab%finalize_table()
2419 end subroutine sfr_cc
2425 subroutine sfr_cq(this, x, flowja, iadv)
2429 class(sfrtype),
intent(inout) :: this
2430 real(DP),
dimension(:),
intent(in) :: x
2431 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
2432 integer(I4B),
optional,
intent(in) :: iadv
2439 real(DP) :: qoutflow
2440 real(DP) :: qfrommvr
2445 call this%BndType%bnd_cq(x, flowja, iadv=1)
2448 do n = 1, this%maxbound
2453 if (this%imover == 1)
then
2454 qfrommvr = this%pakmvrobj%get_qfrommvr(n)
2455 qtomvr = this%pakmvrobj%get_qtomvr(n)
2456 if (qtomvr >
dzero)
then
2462 qext = this%dsflow(n)
2464 if (qext >
dzero)
then
2467 do i = this%ia(n) + 1, this%ia(n + 1) - 1
2468 if (this%idir(i) > 0) cycle
2470 if (this%iboundpak(n2) == 0) cycle
2476 if (qext <
dzero)
then
2477 if (qtomvr <
dzero)
then
2478 qext = qext - qtomvr
2481 qoutflow = this%dsflow(n)
2482 if (qoutflow >
dzero)
then
2483 qoutflow = -qoutflow
2489 this%qextoutflow(n) = qext
2490 this%qoutflow(n) = qoutflow
2495 call this%sfr_fill_budobj()
2496 end subroutine sfr_cq
2502 subroutine sfr_ot_package_flows(this, icbcfl, ibudfl)
2506 class(sfrtype) :: this
2507 integer(I4B),
intent(in) :: icbcfl
2508 integer(I4B),
intent(in) :: ibudfl
2510 integer(I4B) :: ibinun
2511 character(len=20),
dimension(:),
allocatable :: cellidstr
2513 integer(I4B) :: node
2517 if (this%ibudgetout /= 0)
then
2518 ibinun = this%ibudgetout
2520 if (icbcfl == 0) ibinun = 0
2521 if (ibinun > 0)
then
2522 call this%budobj%save_flows(this%dis, ibinun,
kstp,
kper,
delt, &
2527 if (ibudfl /= 0 .and. this%iprflow /= 0)
then
2533 if (this%ianynone > 0)
then
2534 allocate (cellidstr(this%maxbound))
2535 do n = 1, this%maxbound
2536 node = this%igwfnode(n)
2538 call this%dis%noder_to_string(node, cellidstr(n))
2540 cellidstr(n) =
'NONE'
2543 call this%budobj%write_flowtable(this%dis,
kstp,
kper, cellidstr)
2544 deallocate (cellidstr)
2546 call this%budobj%write_flowtable(this%dis,
kstp,
kper)
2549 end subroutine sfr_ot_package_flows
2555 subroutine sfr_ot_dv(this, idvsave, idvprint)
2560 class(sfrtype) :: this
2561 integer(I4B),
intent(in) :: idvsave
2562 integer(I4B),
intent(in) :: idvprint
2564 character(len=20) :: cellid
2565 integer(I4B) :: ibinun
2567 integer(I4B) :: node
2580 if (this%istageout /= 0)
then
2581 ibinun = this%istageout
2583 if (idvsave == 0) ibinun = 0
2586 if (ibinun > 0)
then
2587 do n = 1, this%maxbound
2590 if (this%iboundpak(n) == 0)
then
2592 else if (d ==
dzero)
then
2598 this%maxbound, 1, 1, ibinun)
2602 if (idvprint /= 0 .and. this%iprhed /= 0)
then
2605 call this%stagetab%set_kstpkper(
kstp,
kper)
2608 do n = 1, this%maxbound
2609 node = this%igwfnode(n)
2611 call this%dis%noder_to_string(node, cellid)
2612 hgwf = this%xnew(node)
2616 if (this%inamedbound == 1)
then
2617 call this%stagetab%add_term(this%boundname(n))
2619 call this%stagetab%add_term(n)
2620 call this%stagetab%add_term(cellid)
2621 if (this%iboundpak(n) /= 0)
then
2622 depth = this%depth(n)
2623 stage = this%stage(n)
2624 w = this%calc_top_width_wet(n, depth)
2625 call this%sfr_calc_cond(n, depth, cond, stage, hgwf)
2632 if (depth ==
dzero)
then
2633 call this%stagetab%add_term(
dhdry)
2635 call this%stagetab%add_term(stage)
2637 call this%stagetab%add_term(depth)
2638 call this%stagetab%add_term(w)
2640 if (this%iboundpak(n) /= 0)
then
2641 sbot = this%strtop(n) - this%bthick(n)
2642 if (hgwf < sbot)
then
2647 grad = grad / this%bthick(n)
2651 call this%stagetab%add_term(hgwf)
2652 call this%stagetab%add_term(cond)
2653 call this%stagetab%add_term(grad)
2655 call this%stagetab%add_term(
'--')
2656 call this%stagetab%add_term(
'--')
2657 call this%stagetab%add_term(
'--')
2661 end subroutine sfr_ot_dv
2667 subroutine sfr_ot_bdsummary(this, kstp, kper, iout, ibudfl)
2671 class(sfrtype) :: this
2672 integer(I4B),
intent(in) :: kstp
2673 integer(I4B),
intent(in) :: kper
2674 integer(I4B),
intent(in) :: iout
2675 integer(I4B),
intent(in) :: ibudfl
2677 call this%budobj%write_budtable(kstp, kper, iout, ibudfl,
totim,
delt)
2678 end subroutine sfr_ot_bdsummary
2682 subroutine sfr_fp(this)
2684 class(sfrtype) :: this
2689 if (this%istorage == 1)
then
2690 do n = 1, this%maxbound
2691 if (this%inamedbound == 1)
then
2692 call this%couranttab%add_term(this%boundname(n))
2694 call this%couranttab%add_term(n)
2695 if (this%crmin(n) ==
dep20)
then
2696 call this%couranttab%add_term(
'--')
2698 call this%couranttab%add_term(this%crmin(n))
2700 if (this%crmax(n) <
dzero)
then
2701 call this%couranttab%add_term(
'--')
2703 call this%couranttab%add_term(this%crmax(n))
2705 if (this%crcnt(n) > 0)
then
2706 crmean = this%crsum(n) / real(this%crcnt(n), dp)
2707 call this%couranttab%add_term(crmean)
2709 call this%couranttab%add_term(
'--')
2713 end subroutine sfr_fp
2717 subroutine sfr_dt(this)
2721 class(sfrtype) :: this
2724 integer(I4B) :: nrmin
2725 real(DP) :: celerity
2728 character(len=LINELENGTH) :: msg
2730 if (this%ats_courant ==
dnodata)
return
2731 if (this%istorage /= 1)
return
2736 do n = 1, this%maxbound
2737 call this%sfr_calc_celerity(n, this%dsflow(n), celerity)
2738 if (celerity >
dzero)
then
2739 dt_n = this%ats_courant * this%length(n) / celerity
2740 if (dt_n < dtmin)
then
2748 write (msg,
'(a,i0)') trim(this%packName)//
'-REACH-', nrmin
2749 call ats%ats_submit_delt(
kstp,
kper, dtmin, trim(msg))
2751 end subroutine sfr_dt
2755 subroutine sfr_calc_celerity(this, n, q, celerity)
2757 class(sfrtype) :: this
2758 integer(I4B),
intent(in) :: n
2759 real(DP),
intent(in) :: q
2760 real(DP),
intent(out) :: celerity
2767 call this%sfr_calc_reach_depth(n, q, d)
2769 a = this%calc_area_wet(n, d)
2770 call this%sfr_calc_reach_depth(n, q + this%deps, d)
2771 a2 = this%calc_area_wet(n, d)
2773 celerity = this%deps / (a2 - a)
2776 end subroutine sfr_calc_celerity
2782 subroutine sfr_da(this)
2786 class(sfrtype) :: this
2791 deallocate (this%csfrbudget)
2794 deallocate (this%cauxcbc)
2822 if (this%istorage == 1)
then
2845 nullify (this%inflow)
2846 nullify (this%runoff)
2847 nullify (this%sstage)
2849 nullify (this%rough)
2850 nullify (this%ustrf)
2855 if (
associated(this%divcprior))
then
2856 deallocate (this%divcprior)
2858 nullify (this%divflow)
2870 call this%budobj%budgetobject_da()
2871 deallocate (this%budobj)
2872 nullify (this%budobj)
2875 if (this%iprhed > 0)
then
2876 call this%stagetab%table_da()
2877 deallocate (this%stagetab)
2878 nullify (this%stagetab)
2882 if (
associated(this%couranttab))
then
2883 call this%couranttab%table_da()
2884 deallocate (this%couranttab)
2885 nullify (this%couranttab)
2889 if (this%ipakcsv > 0)
then
2890 if (
associated(this%pakcsvtab))
then
2891 call this%pakcsvtab%table_da()
2892 deallocate (this%pakcsvtab)
2893 nullify (this%pakcsvtab)
2922 nullify (this%gwfiss)
2925 call this%input%destroy()
2928 call this%BndExtType%bnd_da()
2929 end subroutine sfr_da
2935 subroutine sfr_precompute_tvd(this)
2937 class(sfrtype),
intent(inout) :: this
2941 integer(I4B) :: iup_count
2944 do n = 1, this%maxbound
2947 do j = this%ia(n) + 1, this%ia(n + 1) - 1
2948 if (this%idir(j) > 0)
then
2949 iup_count = iup_count + 1
2953 if (iup_count == 1)
then
2954 this%itvd_upstream(n) = m
2956 this%itvd_upstream(n) = 0
2959 end subroutine sfr_precompute_tvd
2966 subroutine define_listlabel(this)
2968 class(sfrtype),
intent(inout) :: this
2971 this%listlabel = trim(this%filtyp)//
' NO.'
2972 if (this%dis%ndim == 3)
then
2973 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'LAYER'
2974 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'ROW'
2975 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'COL'
2976 elseif (this%dis%ndim == 2)
then
2977 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'LAYER'
2978 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'CELL2D'
2980 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'NODE'
2982 write (this%listlabel,
'(a, a16)') trim(this%listlabel),
'STRESS RATE'
2983 if (this%inamedbound == 1)
then
2984 write (this%listlabel,
'(a, a16)') trim(this%listlabel),
'BOUNDARY NAME'
2986 end subroutine define_listlabel
2998 logical function sfr_obs_supported(this)
3000 class(sfrtype) :: this
3003 sfr_obs_supported = .true.
3004 end function sfr_obs_supported
3010 subroutine sfr_df_obs(this)
3012 class(sfrtype) :: this
3014 integer(I4B) :: indx
3018 call this%obs%StoreObsType(
'stage', .false., indx)
3019 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3023 call this%obs%StoreObsType(
'inflow', .true., indx)
3024 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3028 call this%obs%StoreObsType(
'ext-inflow', .true., indx)
3029 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3033 call this%obs%StoreObsType(
'rainfall', .true., indx)
3034 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3038 call this%obs%StoreObsType(
'runoff', .true., indx)
3039 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3043 call this%obs%StoreObsType(
'evaporation', .true., indx)
3044 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3048 call this%obs%StoreObsType(
'outflow', .true., indx)
3049 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3053 call this%obs%StoreObsType(
'ext-outflow', .true., indx)
3054 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3058 call this%obs%StoreObsType(
'to-mvr', .true., indx)
3059 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3063 call this%obs%StoreObsType(
'from-mvr', .true., indx)
3064 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3068 call this%obs%StoreObsType(
'sfr', .true., indx)
3069 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3073 call this%obs%StoreObsType(
'upstream-flow', .true., indx)
3074 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3078 call this%obs%StoreObsType(
'downstream-flow', .true., indx)
3079 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3083 call this%obs%StoreObsType(
'depth', .false., indx)
3084 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3088 call this%obs%StoreObsType(
'wet-perimeter', .false., indx)
3089 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3093 call this%obs%StoreObsType(
'wet-area', .false., indx)
3094 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3098 call this%obs%StoreObsType(
'wet-width', .false., indx)
3099 this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3100 end subroutine sfr_df_obs
3106 subroutine sfr_bd_obs(this)
3108 class(sfrtype) :: this
3114 character(len=100) :: msg
3118 if (this%obs%npakobs > 0)
then
3119 call this%obs%obs_bd_clear()
3120 do i = 1, this%obs%npakobs
3121 obsrv => this%obs%pakobs(i)%obsrv
3122 do j = 1, obsrv%indxbnds_count
3123 n = obsrv%indxbnds(j)
3125 select case (obsrv%ObsTypeId)
3130 if (this%imover == 1)
then
3131 v = this%pakmvrobj%get_qtomvr(n)
3138 if (this%imover == 1)
then
3139 v = this%pakmvrobj%get_qfrommvr(n)
3146 v = this%qoutflow(n)
3147 case (
'EXT-OUTFLOW')
3148 v = this%qextoutflow(n)
3150 if (this%iboundpak(n) /= 0)
then
3156 v = this%simrunoff(n)
3157 case (
'EVAPORATION')
3161 case (
'UPSTREAM-FLOW')
3163 if (this%imover == 1)
then
3164 v = v + this%pakmvrobj%get_qfrommvr(n)
3166 case (
'DOWNSTREAM-FLOW')
3173 case (
'WET-PERIMETER')
3174 v = this%calc_perimeter_wet(n, this%depth(n))
3176 v = this%calc_area_wet(n, this%depth(n))
3178 v = this%calc_top_width_wet(n, this%depth(n))
3180 msg =
'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
3183 call this%obs%SaveOneSimval(obsrv, v)
3192 end subroutine sfr_bd_obs
3198 subroutine sfr_rp_obs(this)
3202 class(sfrtype),
intent(inout) :: this
3207 character(len=LENBOUNDNAME) :: bname
3208 logical(LGP) :: jfound
3211 10
format(
'Boundary "', a,
'" for observation "', a, &
3212 '" is invalid in package "', a,
'"')
3213 30
format(
'Boundary name not provided for observation "', a, &
3214 '" in package "', a,
'"')
3220 do i = 1, this%obs%npakobs
3221 obsrv => this%obs%pakobs(i)%obsrv
3224 nn1 = obsrv%NodeNumber
3226 bname = obsrv%FeatureName
3227 if (bname /=
'')
then
3232 do j = 1, this%maxbound
3233 if (this%boundname(j) == bname)
then
3235 call obsrv%AddObsIndex(j)
3238 if (.not. jfound)
then
3240 trim(bname), trim(obsrv%name), trim(this%packName)
3244 write (
errmsg, 30) trim(obsrv%name), trim(this%packName)
3247 else if (nn1 < 1 .or. nn1 > this%maxbound)
then
3248 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
3249 trim(adjustl(obsrv%ObsTypeId)), &
3250 'reach must be greater than 0 and less than or equal to', &
3251 this%maxbound,
'(specified value is ', nn1,
')'
3254 if (obsrv%indxbnds_count == 0)
then
3255 call obsrv%AddObsIndex(nn1)
3257 errmsg =
'Programming error in sfr_rp_obs'
3264 if (obsrv%ObsTypeId ==
'STAGE' .or. &
3265 obsrv%ObsTypeId ==
'DEPTH' .or. &
3266 obsrv%ObsTypeId ==
'WET-PERIMETER' .or. &
3267 obsrv%ObsTypeId ==
'WET-AREA' .or. &
3268 obsrv%ObsTypeId ==
'WET-WIDTH')
then
3269 nn1 = obsrv%NodeNumber
3271 if (obsrv%indxbnds_count > 1)
then
3272 write (
errmsg,
'(a,3(1x,a))') &
3273 trim(adjustl(obsrv%ObsTypeId)), &
3274 'for observation', trim(adjustl(obsrv%Name)), &
3275 ' must be assigned to a reach with a unique boundname.'
3282 do j = 1, obsrv%indxbnds_count
3283 nn1 = obsrv%indxbnds(j)
3284 if (nn1 < 1 .or. nn1 > this%maxbound)
then
3285 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
3286 trim(adjustl(obsrv%ObsTypeId)), &
3287 'reach must be greater than 0 and less than or equal to', &
3288 this%maxbound,
'(specified value is ', nn1,
')'
3299 end subroutine sfr_rp_obs
3308 subroutine sfr_process_obsid(obsrv, dis, inunitobs, iout)
3312 integer(I4B),
intent(in) :: inunitobs
3313 integer(I4B),
intent(in) :: iout
3316 integer(I4B) :: icol
3317 integer(I4B) :: istart
3318 integer(I4B) :: istop
3319 character(len=LINELENGTH) :: string
3320 character(len=LENBOUNDNAME) :: bndname
3323 string = obsrv%IDstring
3333 obsrv%FeatureName = bndname
3337 obsrv%NodeNumber = nn1
3338 end subroutine sfr_process_obsid
3344 subroutine sfr_solve(this, n, h, hcof, rhs, update)
3346 class(sfrtype) :: this
3347 integer(I4B),
intent(in) :: n
3348 real(DP),
intent(in) :: h
3349 real(DP),
intent(inout) :: hcof
3350 real(DP),
intent(inout) :: rhs
3351 logical(LGP),
intent(in),
optional :: update
3353 logical(LGP) :: lupdate
3366 real(DP) :: qfrommvr
3379 if (
present(update))
then
3389 if (this%iboundpak(n) == 0)
then
3390 this%depth(n) =
dzero
3392 this%usflow(n) =
dzero
3393 this%simevap(n) =
dzero
3394 this%simrunoff(n) =
dzero
3395 this%dsflow(n) =
dzero
3396 this%gwflow(n) =
dzero
3408 do i = this%ia(n) + 1, this%ia(n + 1) - 1
3409 if (this%idir(i) < 0) cycle
3411 do ii = this%ia(n2) + 1, this%ia(n2 + 1) - 1
3412 if (this%idir(ii) > 0) cycle
3413 if (this%ja(ii) /= n) cycle
3414 qu = qu + this%qconn(ii)
3420 sa = this%calc_surface_area(n)
3421 sa_wet = this%calc_surface_area_wet(n, this%depth(n))
3423 qr = this%rain(n) * sa
3424 qe = this%evap(n) * sa_wet
3425 qro = this%runoff(n)
3429 if (this%imover == 1)
then
3430 qfrommvr = this%pakmvrobj%get_qfrommvr(n)
3434 qsrc = qu + qi + qr - qe + qro + qfrommvr
3437 call this%sfr_adjust_ro_ev(qsrc, qu, qi, qr, qro, qe, qfrommvr)
3440 this%simevap(n) = qe
3441 this%simrunoff(n) = qro
3444 if (this%iboundpak(n) < 0)
then
3445 call this%sfr_calc_constant(n, d1, hgwf, qgwf, qd)
3447 if (this%gwfiss == 0 .and. this%istorage == 1)
then
3448 if (this%ats_courant /=
dnodata)
then
3449 call this%sfr_calc_tvd(n, d1, hgwf, qu, qi, &
3450 qfrommvr, qr, qe, qro, &
3453 call this%sfr_calc_transient(n, d1, hgwf, qu, qi, &
3454 qfrommvr, qr, qe, qro, &
3458 call this%sfr_calc_steady(n, d1, hgwf, qu, qi, &
3459 qfrommvr, qr, qe, qro, &
3466 bt = tp - this%bthick(n)
3473 this%stage(n) = hsfr
3475 call this%sfr_update_flows(n, qd, qgwf)
3481 if (this%gwfiss == 0)
then
3492 call this%sfr_calc_qgwf(n, d1, hgwf, qgwf, gwfhcof, gwfrhs)
3495 if (abs(sumleak) >
dzero)
then
3500 else if ((sumleak - qsrc) < -
dem30)
then
3501 if (this%gwfiss == 0)
then
3502 rhs = rhs + gwfrhs - sumrch
3509 if (this%gwfiss == 0)
then
3510 rhs = rhs - sumleak - sumrch
3517 else if (hgwf < bt)
then
3521 end subroutine sfr_solve
3528 subroutine sfr_update_flows(this, n, qd, qgwf)
3530 class(sfrtype),
intent(inout) :: this
3531 integer(I4B),
intent(in) :: n
3532 real(DP),
intent(inout) :: qd
3533 real(DP),
intent(in) :: qgwf
3537 integer(I4B) :: idiv
3538 integer(I4B) :: jpos
3548 this%gwflow(n) = qgwf
3551 if (qd >
dzero)
then
3554 do i = this%ia(n) + 1, this%ia(n + 1) - 1
3555 if (this%idir(i) > 0) cycle
3557 if (idiv == 0) cycle
3558 jpos = this%iadiv(n) + idiv - 1
3559 call this%sfr_calc_div(n, idiv, qd, qdiv)
3560 this%qconn(i) = qdiv
3561 this%divq(jpos) = qdiv
3567 if (this%imover == 1)
then
3568 call this%pakmvrobj%accumulate_qformvr(n, qd)
3569 qd = max(qd - this%pakmvrobj%get_qtomvr(n),
dzero)
3573 do i = this%ia(n) + 1, this%ia(n + 1) - 1
3574 if (this%idir(i) > 0) cycle
3575 if (this%idiv(i) > 0) cycle
3577 if (this%iboundpak(n2) == 0) cycle
3578 f = this%ustrf(n2) / this%ftotnd(n)
3579 this%qconn(i) = qd * f
3582 do i = this%ia(n) + 1, this%ia(n + 1) - 1
3583 if (this%idir(i) > 0) cycle
3584 this%qconn(i) =
dzero
3586 if (idiv == 0) cycle
3587 jpos = this%iadiv(n) + idiv - 1
3588 this%divq(jpos) =
dzero
3591 end subroutine sfr_update_flows
3598 subroutine sfr_adjust_ro_ev(this, qc, qu, qi, qr, qro, qe, qfrommvr)
3600 class(sfrtype) :: this
3601 real(DP),
intent(inout) :: qc
3602 real(DP),
intent(in) :: qu
3603 real(DP),
intent(in) :: qi
3604 real(DP),
intent(in) :: qr
3605 real(DP),
intent(inout) :: qro
3606 real(DP),
intent(inout) :: qe
3607 real(DP),
intent(in) :: qfrommvr
3612 if (qc <
dzero)
then
3615 qt = qu + qi + qr + qro + qfrommvr
3618 if (qt <
dzero)
then
3619 if (qro <
dzero)
then
3620 qro = -(qu + qi + qr + qfrommvr)
3626 if (qe >
dzero)
then
3627 qe = qu + qi + qr + qro + qfrommvr
3630 qc = qu + qi + qr - qe + qro + qfrommvr
3632 end subroutine sfr_adjust_ro_ev
3638 subroutine sfr_calc_qd(this, n, depth, hgwf, qgwf, qd)
3640 class(sfrtype) :: this
3641 integer(I4B),
intent(in) :: n
3642 real(DP),
intent(in) :: depth
3643 real(DP),
intent(in) :: hgwf
3644 real(DP),
intent(inout) :: qgwf
3645 real(DP),
intent(inout) :: qd
3653 call this%sfr_calc_qsource(n, depth, qsrc)
3656 call this%sfr_calc_qgwf(n, depth, hgwf, qgwf)
3657 if (-qgwf > qsrc) qgwf = -qsrc
3664 end subroutine sfr_calc_qd
3671 subroutine sfr_calc_qsource(this, n, depth, qsrc)
3673 class(sfrtype) :: this
3674 integer(I4B),
intent(in) :: n
3675 real(DP),
intent(in) :: depth
3676 real(DP),
intent(inout) :: qsrc
3683 real(DP) :: qfrommvr
3693 qro = this%runoff(n)
3696 a = this%calc_surface_area(n)
3697 ae = this%calc_surface_area_wet(n, depth)
3698 qr = this%rain(n) * a
3699 qe = this%evap(n) * ae
3703 if (this%imover == 1)
then
3704 qfrommvr = this%pakmvrobj%get_qfrommvr(n)
3708 qsrc = qu + qi + qr - qe + qro + qfrommvr
3711 call this%sfr_adjust_ro_ev(qsrc, qu, qi, qr, qro, qe, qfrommvr)
3712 end subroutine sfr_calc_qsource
3719 subroutine sfr_calc_qman(this, n, depth, qman)
3721 class(sfrtype) :: this
3722 integer(I4B),
intent(in) :: n
3723 real(DP),
intent(in) :: depth
3724 real(DP),
intent(inout) :: qman
3726 integer(I4B) :: npts
3741 if (depth >
dzero)
then
3742 npts = this%ncrosspts(n)
3753 i0 = this%iacross(n)
3754 i1 = this%iacross(n + 1) - 1
3759 this%station(i0:i1), &
3760 this%xsheight(i0:i1), &
3761 this%xsrough(i0:i1), &
3768 aw = this%calc_area_wet(n, depth)
3769 wp = this%calc_perimeter_wet(n, depth)
3770 if (wp >
dzero)
then
3775 qman = this%unitconv * aw * (rh**
dtwothirds) * sqrt(s) / r
3781 end subroutine sfr_calc_qman
3789 subroutine sfr_calc_qgwf(this, n, depth, hgwf, qgwf, gwfhcof, gwfrhs)
3791 class(sfrtype) :: this
3792 integer(I4B),
intent(in) :: n
3793 real(DP),
intent(in) :: depth
3794 real(DP),
intent(in) :: hgwf
3795 real(DP),
intent(inout) :: qgwf
3796 real(DP),
intent(inout),
optional :: gwfhcof
3797 real(DP),
intent(inout),
optional :: gwfrhs
3799 integer(I4B) :: node
3807 real(DP) :: gwfhcof0
3814 node = this%igwfnode(n)
3815 if (node < 1)
return
3818 if (this%ibound(node) == 0)
return
3825 bt = tp - this%bthick(n)
3828 if (h_temp < bt)
then
3833 call this%sfr_calc_cond(n, depth, cond, hsfr, h_temp)
3836 qgwf = sat * cond * (h_temp - hsfr)
3837 gwfrhs0 = -sat * cond * hsfr
3838 gwfhcof0 = -sat * cond
3841 if (this%idense /= 0)
then
3842 call this%sfr_calculate_density_exchange(n, hsfr, hgwf, cond, tp, &
3843 qgwf, gwfhcof0, gwfrhs0)
3847 if (
present(gwfhcof)) gwfhcof = gwfhcof0
3848 if (
present(gwfrhs)) gwfrhs = gwfrhs0
3849 end subroutine sfr_calc_qgwf
3856 function sfr_gwf_conn(this, n)
3858 integer(I4B) :: sfr_gwf_conn
3860 class(sfrtype) :: this
3861 integer(I4B),
intent(in) :: n
3863 integer(I4B) :: node
3866 node = this%igwfnode(n)
3867 if (node > 0 .and. this%hk(n) >
dzero)
then
3870 end function sfr_gwf_conn
3876 subroutine sfr_calc_cond(this, n, depth, cond, hsfr, h_temp)
3878 class(sfrtype) :: this
3879 integer(I4B),
intent(in) :: n
3880 real(DP),
intent(in) :: depth
3881 real(DP),
intent(inout) :: cond
3882 real(DP),
intent(in),
optional :: hsfr
3883 real(DP),
intent(in),
optional :: h_temp
3885 integer(I4B) :: node
3887 real(DP) :: vscratio
3897 node = this%igwfnode(n)
3899 if (this%ibound(node) > 0)
then
3902 if (this%ivsc == 1)
then
3903 if (hsfr > h_temp)
then
3905 vscratio = this%viscratios(1, n)
3907 vscratio = this%viscratios(2, n)
3910 wp = this%calc_perimeter_wet(n, depth)
3911 cond = this%hk(n) * vscratio * this%length(n) * wp / this%bthick(n)
3914 end subroutine sfr_calc_cond
3923 subroutine sfr_calc_div(this, n, i, qd, qdiv)
3925 class(sfrtype) :: this
3926 integer(I4B),
intent(in) :: n
3927 integer(I4B),
intent(in) :: i
3928 real(DP),
intent(inout) :: qd
3929 real(DP),
intent(inout) :: qdiv
3931 character(len=10) :: cp
3932 integer(I4B) :: jpos
3937 jpos = this%iadiv(n) + i - 1
3938 n2 = this%divreach(jpos)
3939 cp = this%divcprior(jpos)
3940 v = this%divflow(jpos)
3971 end subroutine sfr_calc_div
3977 subroutine sfr_calc_reach_depth(this, n, q1, d1)
3979 class(sfrtype) :: this
3980 integer(I4B),
intent(in) :: n
3981 real(DP),
intent(in) :: q1
3982 real(DP),
intent(inout) :: d1
3994 if (q1 >
dzero)
then
3995 if (this%ncrosspts(n) > 1)
then
3996 call this%sfr_calc_xs_depth(n, q1, d1)
3998 w = this%station(this%iacross(n))
3999 qconst = this%unitconv * w * sqrt(s) / r
4000 d1 = (q1 / qconst)**
dp6
4005 end subroutine sfr_calc_reach_depth
4012 subroutine sfr_calc_xs_depth(this, n, qrch, d)
4014 class(sfrtype) :: this
4015 integer(I4B),
intent(in) :: n
4016 real(DP),
intent(in) :: qrch
4017 real(DP),
intent(inout) :: d
4019 integer(I4B) :: iter
4020 real(DP) :: perturbation
4026 real(DP) :: residual
4029 perturbation = this%deps *
dtwo
4032 residual = q0 - qrch
4035 nriter:
do iter = 1, this%maxsfrit
4036 call this%sfr_calc_qman(n, d + perturbation, q1)
4038 if (dq /=
dzero)
then
4039 derv = perturbation / (q1 - q0)
4043 dd = derv * residual
4045 call this%sfr_calc_qman(n, d, q0)
4046 residual = q0 - qrch
4049 if (abs(dd) < this%dmaxchg)
then
4053 end subroutine sfr_calc_xs_depth
4060 subroutine sfr_check_conversion(this)
4062 class(sfrtype) :: this
4065 character(len=*),
parameter :: fmtunitconv_error = &
4066 &
"('SFR (',a,') UNIT_CONVERSION SPECIFIED VALUE (',g0,') AND', &
4067 &1x,'LENGTH_CONVERSION OR TIME_CONVERSION SPECIFIED.')"
4068 character(len=*),
parameter :: fmtunitconv = &
4069 &
"(1x,'SFR PACKAGE (',a,') CONVERSION DATA',&
4070 &/4x,'UNIT CONVERSION VALUE (',g0,').',/)"
4073 if (this%lengthconv /=
dnodata .or. this%timeconv /=
dnodata)
then
4074 if (this%unitconv /=
done)
then
4075 write (
errmsg, fmtunitconv_error) &
4076 trim(adjustl(this%packName)), this%unitconv
4079 if (this%lengthconv /=
dnodata)
then
4080 this%unitconv = this%unitconv * this%lengthconv**
donethird
4082 if (this%timeconv /=
dnodata)
then
4083 this%unitconv = this%unitconv * this%timeconv
4085 write (this%iout, fmtunitconv) &
4086 trim(adjustl(this%packName)), this%unitconv
4089 end subroutine sfr_check_conversion
4097 subroutine sfr_check_storage_weight(this)
4099 class(sfrtype) :: this
4101 character(len=*),
parameter :: fmtweight = &
4102 &
"(1x,'SFR PACKAGE (',a,') SETTING DEFAULT',&
4103 &/4x,'STORAGE_WEIGHT VALUE (',g0,').',/)"
4106 if (this%istorage == 1)
then
4107 if (this%storage_weight ==
dnodata)
then
4108 this%storage_weight =
done
4109 write (this%iout, fmtweight) &
4110 trim(adjustl(this%packName)), this%storage_weight
4113 end subroutine sfr_check_storage_weight
4121 subroutine sfr_check_reaches(this)
4123 class(sfrtype) :: this
4125 character(len=5) :: crch
4126 character(len=10) :: cval
4127 character(len=30) :: nodestr
4128 character(len=LINELENGTH) :: title
4129 character(len=LINELENGTH) :: text
4136 if (this%iprpak /= 0)
then
4137 title = trim(adjustl(this%text))//
' PACKAGE ('// &
4138 trim(adjustl(this%packName))//
') STATIC REACH DATA'
4139 call table_cr(this%inputtab, this%packName, title)
4140 call this%inputtab%table_df(this%maxbound, 10, this%iout)
4142 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4144 call this%inputtab%initialize_column(text, 20, alignment=
tableft)
4146 call this%inputtab%initialize_column(text, 12, alignment=
tabcenter)
4148 call this%inputtab%initialize_column(text, 12, alignment=
tabcenter)
4150 call this%inputtab%initialize_column(text, 12, alignment=
tabcenter)
4152 call this%inputtab%initialize_column(text, 12, alignment=
tabcenter)
4154 call this%inputtab%initialize_column(text, 12, alignment=
tabcenter)
4156 call this%inputtab%initialize_column(text, 12, alignment=
tabcenter)
4158 call this%inputtab%initialize_column(text, 12, alignment=
tabcenter)
4159 text =
'UPSTREAM FRACTION'
4160 call this%inputtab%initialize_column(text, 12, alignment=
tabcenter)
4164 do n = 1, this%maxbound
4165 write (crch,
'(i5)') n
4166 nn = this%igwfnode(n)
4168 btgwf = this%dis%bot(nn)
4169 call this%dis%noder_to_string(nn, nodestr)
4174 if (this%length(n) <=
dzero)
then
4175 errmsg =
'Reach '//crch//
' length must be greater than 0.0.'
4179 if (this%width(n) <=
dzero)
then
4180 errmsg =
'Reach '//crch//
' width must be greater than 0.0.'
4184 if (this%slope(n) <=
dzero)
then
4185 errmsg =
'Reach '//crch//
' slope must be greater than 0.0.'
4190 bt = this%strtop(n) - this%bthick(n)
4191 if (bt <= btgwf .and. this%icheck /= 0)
then
4192 write (cval,
'(f10.4)') bt
4193 errmsg =
'Reach '//crch//
' bed bottom (rtp-rbth ='// &
4194 cval//
') must be greater than the bottom of cell ('// &
4196 write (cval,
'(f10.4)') btgwf
4200 if (this%hk(n) <
dzero)
then
4201 errmsg =
'Reach '//crch//
' hk must be greater than or equal to 0.0.'
4206 if (this%rough(n) <=
dzero)
then
4207 errmsg =
'Reach '//crch//
" Manning's roughness "// &
4208 'coefficient must be greater than 0.0.'
4212 if (this%ustrf(n) <
dzero)
then
4213 errmsg =
'Reach '//crch//
' upstream fraction must be greater '// &
4214 'than or equal to 0.0.'
4218 if (this%iprpak /= 0)
then
4219 call this%inputtab%add_term(n)
4220 call this%inputtab%add_term(nodestr)
4221 call this%inputtab%add_term(this%length(n))
4222 call this%inputtab%add_term(this%width(n))
4223 call this%inputtab%add_term(this%slope(n))
4224 call this%inputtab%add_term(this%strtop(n))
4225 call this%inputtab%add_term(this%bthick(n))
4226 call this%inputtab%add_term(this%hk(n))
4227 call this%inputtab%add_term(this%rough(n))
4228 call this%inputtab%add_term(this%ustrf(n))
4231 end subroutine sfr_check_reaches
4239 subroutine sfr_check_connections(this)
4241 class(sfrtype) :: this
4243 logical(LGP) :: lreorder
4244 character(len=5) :: crch
4245 character(len=5) :: crch2
4246 character(len=LINELENGTH) :: text
4247 character(len=LINELENGTH) :: title
4254 integer(I4B) :: ifound
4255 integer(I4B) :: ierr
4256 integer(I4B) :: maxconn
4257 integer(I4B) :: ntabcol
4261 do j = 1, this%MAXBOUND
4262 n = this%isfrorder(j)
4271 write (this%iout,
'(/,1x,a)') &
4272 trim(adjustl(this%text))//
' PACKAGE ('// &
4273 trim(adjustl(this%packName))//
') REACH SOLUTION HAS BEEN '// &
4274 'REORDERED USING A DAG'
4277 if (this%iprpak /= 0)
then
4281 title = trim(adjustl(this%text))//
' PACKAGE ('// &
4282 trim(adjustl(this%packName))//
') REACH SOLUTION ORDER'
4283 call table_cr(this%inputtab, this%packName, title)
4284 call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4286 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4288 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4291 do j = 1, this%maxbound
4292 n = this%isfrorder(j)
4293 call this%inputtab%add_term(j)
4294 call this%inputtab%add_term(n)
4300 if (this%iprpak /= 0)
then
4304 do n = 1, this%maxbound
4305 maxconn = max(maxconn, this%nconnreach(n))
4307 ntabcol = 1 + maxconn
4310 title = trim(adjustl(this%text))//
' PACKAGE ('// &
4311 trim(adjustl(this%packName))//
') STATIC REACH CONNECTION DATA'
4312 call table_cr(this%inputtab, this%packName, title)
4313 call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4315 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4317 write (text,
'(a,1x,i6)')
'CONN', n
4318 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4324 do n = 1, this%MAXBOUND
4325 write (crch,
'(i5)') n
4326 eachconn:
do i = this%ia(n) + 1, this%ia(n + 1) - 1
4328 write (crch2,
'(i5)') nn
4330 connreach:
do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4337 if (ifound /= 1)
then
4338 errmsg =
'Reach '//crch//
' is connected to '// &
4339 'reach '//crch2//
' but reach '//crch2// &
4340 ' is not connected to reach '//crch//
'.'
4346 if (this%iprpak /= 0)
then
4347 call this%inputtab%add_term(n)
4348 do i = this%ia(n) + 1, this%ia(n + 1) - 1
4349 call this%inputtab%add_term(this%ja(i))
4351 nn = maxconn - this%nconnreach(n)
4353 call this%inputtab%add_term(
' ')
4361 do n = 1, this%maxbound
4362 write (crch,
'(i5)') n
4363 eachconnv:
do i = this%ia(n) + 1, this%ia(n + 1) - 1
4366 if (this%idir(i) < 0) cycle eachconnv
4368 write (crch2,
'(i5)') nn
4369 connreachv:
do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4371 if (this%idir(ii) < 0) cycle connreachv
4378 errmsg =
'Reach '//crch//
' is connected to '// &
4379 'reach '//crch2//
' but streamflow from reach '// &
4380 crch//
' to reach '//crch2//
' is not permitted.'
4395 do n = 1, this%maxbound
4396 write (crch,
'(i5)') n
4397 eachconnds:
do i = this%ia(n) + 1, this%ia(n + 1) - 1
4399 if (this%idir(i) > 0) cycle eachconnds
4400 write (crch2,
'(i5)') nn
4402 connreachds:
do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4405 if (this%idir(i) /= this%idir(ii))
then
4411 if (ifound /= 1)
then
4412 errmsg =
'Reach '//crch//
' downstream connected reach '// &
4413 'is reach '//crch2//
' but reach '//crch//
' is not'// &
4414 ' the upstream connected reach for reach '//crch2//
'.'
4421 if (this%iprpak /= 0)
then
4425 do n = 1, this%maxbound
4427 do i = this%ia(n) + 1, this%ia(n + 1) - 1
4428 if (this%idir(i) > 0)
then
4432 maxconn = max(maxconn, ii)
4434 ntabcol = 1 + maxconn
4437 title = trim(adjustl(this%text))//
' PACKAGE ('// &
4438 trim(adjustl(this%packName))//
') STATIC UPSTREAM REACH '// &
4440 call table_cr(this%inputtab, this%packName, title)
4441 call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4443 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4445 write (text,
'(a,1x,i6)')
'UPSTREAM CONN', n
4446 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4450 do n = 1, this%maxbound
4451 call this%inputtab%add_term(n)
4453 do i = this%ia(n) + 1, this%ia(n + 1) - 1
4454 if (this%idir(i) > 0)
then
4455 call this%inputtab%add_term(this%ja(i))
4461 call this%inputtab%add_term(
' ')
4467 do n = 1, this%maxbound
4469 do i = this%ia(n) + 1, this%ia(n + 1) - 1
4470 if (this%idir(i) < 0)
then
4474 maxconn = max(maxconn, ii)
4476 ntabcol = 1 + maxconn
4479 title = trim(adjustl(this%text))//
' PACKAGE ('// &
4480 trim(adjustl(this%packName))//
') STATIC DOWNSTREAM '// &
4481 'REACH CONNECTION DATA'
4482 call table_cr(this%inputtab, this%packName, title)
4483 call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4485 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4487 write (text,
'(a,1x,i6)')
'DOWNSTREAM CONN', n
4488 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4492 do n = 1, this%maxbound
4493 call this%inputtab%add_term(n)
4495 do i = this%ia(n) + 1, this%ia(n + 1) - 1
4496 if (this%idir(i) < 0)
then
4497 call this%inputtab%add_term(this%ja(i))
4503 call this%inputtab%add_term(
' ')
4507 end subroutine sfr_check_connections
4515 subroutine sfr_check_diversions(this)
4517 class(sfrtype) :: this
4519 character(len=LINELENGTH) :: title
4520 character(len=LINELENGTH) :: text
4521 character(len=5) :: crch
4522 character(len=5) :: cdiv
4523 character(len=5) :: crch2
4524 character(len=10) :: cprior
4525 integer(I4B) :: maxdiv
4530 integer(I4B) :: idiv
4531 integer(I4B) :: ifound
4532 integer(I4B) :: jpos
4534 10
format(
'Diversion ', i0,
' of reach ', i0, &
4535 ' is invalid or has not been defined.')
4538 if (this%iprpak /= 0)
then
4542 do n = 1, this%maxbound
4543 maxdiv = maxdiv + this%ndiv(n)
4547 title = trim(adjustl(this%text))//
' PACKAGE ('// &
4548 trim(adjustl(this%packName))//
') REACH DIVERSION DATA'
4549 call table_cr(this%inputtab, this%packName, title)
4550 call this%inputtab%table_df(maxdiv, 4, this%iout)
4552 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4554 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4556 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4558 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4562 do n = 1, this%maxbound
4563 if (this%ndiv(n) < 1) cycle
4564 write (crch,
'(i5)') n
4566 do idiv = 1, this%ndiv(n)
4569 jpos = this%iadiv(n) + idiv - 1
4572 write (cdiv,
'(i5)') idiv
4575 nn = this%divreach(jpos)
4576 write (crch2,
'(i5)') nn
4580 if (nn < 1 .or. nn > this%maxbound)
then
4581 write (
errmsg, 10) idiv, n
4585 connreach:
do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4588 if (this%idir(ii) > 0)
then
4594 if (ifound /= 1)
then
4595 errmsg =
'Reach '//crch//
' is not a upstream reach for '// &
4596 'reach '//crch2//
' as a result diversion '//cdiv// &
4597 ' from reach '//crch//
' to reach '//crch2// &
4598 ' is not possible. Check reach connectivity.'
4602 cprior = this%divcprior(jpos)
4605 if (this%iprpak /= 0)
then
4606 call this%inputtab%add_term(n)
4607 call this%inputtab%add_term(idiv)
4608 call this%inputtab%add_term(nn)
4609 call this%inputtab%add_term(cprior)
4613 end subroutine sfr_check_diversions
4622 subroutine sfr_check_initialstages(this)
4623 class(sfrtype) :: this
4625 character(len=LINELENGTH) :: title
4626 character(len=LINELENGTH) :: text
4627 character(len=5) :: crch
4632 if (this%istorage == 0)
return
4635 if (this%iprpak /= 0)
then
4638 title = trim(adjustl(this%text))//
' PACKAGE ('// &
4639 trim(adjustl(this%packName))//
') REACH INITIAL STAGE DATA'
4640 call table_cr(this%inputtab, this%packName, title)
4641 call this%inputtab%table_df(this%maxbound, 4, this%iout)
4643 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4644 text =
'INITIAL STAGE'
4645 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4646 text =
'INITIAL DEPTH'
4647 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4648 text =
'INITIAL FLOW'
4649 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4653 do n = 1, this%maxbound
4654 write (crch,
'(i5)') n
4657 call this%sfr_calc_qman(n, this%depth(n), qman)
4658 this%usinflow(n) = qman
4659 this%dsflow(n) = qman
4662 if (this%iprpak /= 0)
then
4663 call this%inputtab%add_term(n)
4664 call this%inputtab%add_term(this%stage(n))
4665 call this%inputtab%add_term(this%depth(n))
4666 call this%inputtab%add_term(qman)
4669 end subroutine sfr_check_initialstages
4677 subroutine sfr_check_ustrf(this)
4679 class(sfrtype) :: this
4681 character(len=LINELENGTH) :: title
4682 character(len=LINELENGTH) :: text
4683 logical(LGP) :: lcycle
4684 logical(LGP) :: ladd
4685 character(len=5) :: crch
4686 character(len=5) :: crch2
4687 character(len=10) :: cval
4688 integer(I4B) :: maxcols
4689 integer(I4B) :: npairs
4690 integer(I4B) :: ipair
4694 integer(I4B) :: idiv
4697 integer(I4B) :: jpos
4703 if (this%iprpak /= 0)
then
4707 do n = 1, this%maxbound
4709 ec:
do i = this%ia(n) + 1, this%ia(n + 1) - 1
4712 if (this%idir(i) > 0) cycle ec
4716 if (this%iboundpak(n2) == 0) cycle ec
4720 npairs = max(npairs, ipair)
4723 maxcols = 1 + npairs * 2
4726 title = trim(adjustl(this%text))//
' PACKAGE ('// &
4727 trim(adjustl(this%packName))//
') CONNECTED REACH UPSTREAM '// &
4729 call table_cr(this%inputtab, this%packName, title)
4730 call this%inputtab%table_df(this%maxbound, maxcols, this%iout)
4732 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4734 write (cval,
'(i10)') i
4735 text =
'DOWNSTREAM REACH '//trim(adjustl(cval))
4736 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
4737 text =
'FRACTION '//trim(adjustl(cval))
4738 call this%inputtab%initialize_column(text, 12, alignment=
tabcenter)
4743 do n = 1, this%maxbound
4744 do idiv = 1, this%ndiv(n)
4746 i1 = this%iadiv(n + 1) - 1
4748 do i = this%ia(n) + 1, this%ia(n + 1) - 1
4750 if (this%divreach(jpos) == n2)
then
4751 this%idiv(i) = jpos - i0 + 1
4761 do n = 1, this%maxbound
4765 do i = this%ia(n) + 1, this%ia(n + 1) - 1
4766 if (this%idir(i) < 0)
then
4772 do idiv = 1, this%ndiv(n)
4773 jpos = this%iadiv(n) + idiv - 1
4774 n2 = this%divreach(jpos)
4776 if (f /=
dzero)
then
4777 write (
errmsg,
'(a,2(1x,i0,1x,a),1x,a,g0,a,2(1x,a))') &
4778 'Reach', n,
'is connected to reach', n2,
'by a diversion', &
4779 'but the upstream fraction is not equal to zero (', f,
'). Check', &
4780 trim(this%packName),
'package diversion and package data.'
4784 write (
warnmsg,
'(a,3(1x,a))') &
4786 'A warning instead of an error is issued because', &
4787 'the reach is only connected to the diversion reach in the ', &
4788 'downstream direction.'
4798 do n = 1, this%maxbound
4802 write (crch,
'(i5)') n
4803 if (this%iprpak /= 0)
then
4804 call this%inputtab%add_term(n)
4807 eachconn:
do i = this%ia(n) + 1, this%ia(n + 1) - 1
4811 this%qconn(i) =
dzero
4814 if (this%idir(i) > 0)
then
4820 if (this%iboundpak(n2) == 0)
then
4827 write (crch2,
'(i5)') n2
4830 f = f + this%ustrf(n2)
4831 write (cval,
'(f10.4)') this%ustrf(n2)
4834 if (this%iprpak /= 0)
then
4835 call this%inputtab%add_term(n2)
4836 call this%inputtab%add_term(this%ustrf(n2))
4838 eachdiv:
do idiv = 1, this%ndiv(n)
4839 jpos = this%iadiv(n) + idiv - 1
4840 if (this%divreach(jpos) == n2)
then
4846 rval = rval + this%ustrf(n2)
4849 this%ftotnd(n) = rval
4852 if (this%iprpak /= 0)
then
4854 do i = ipair, npairs
4855 call this%inputtab%add_term(
' ')
4856 call this%inputtab%add_term(
' ')
4864 write (
errmsg,
'(a,1x,i0,1x,a,g0,a,3(1x,a))') &
4865 'Upstream fractions for reach ', n,
'is not equal to one (', f, &
4866 '). Check', trim(this%packName),
'package reach connectivity and', &
4872 end subroutine sfr_check_ustrf
4879 subroutine sfr_set_period_value(this, i, n, setting)
4881 class(sfrtype),
intent(inout) :: this
4882 integer(I4B),
intent(in) :: i
4883 integer(I4B),
intent(in) :: n
4884 character(len=*),
intent(in) :: setting
4886 select case (trim(setting))
4888 this%bedk_set(n) = .true.
4890 this%manning_set(n) = .true.
4891 case (
'UPSTREAM_FRAC')
4892 this%ustrf_set(n) = .true.
4894 end subroutine sfr_set_period_value
4902 subroutine sfr_setup_budobj(this)
4904 class(sfrtype) :: this
4906 integer(I4B) :: nbudterm
4911 integer(I4B) :: maxlist
4912 integer(I4B) :: naux
4915 character(len=LENBUDTXT) :: text
4916 character(len=LENBUDTXT),
dimension(1) :: auxtxt
4923 if (this%imover == 1) nbudterm = nbudterm + 2
4924 if (this%naux > 0) nbudterm = nbudterm + 1
4928 call this%budobj%budgetobject_df(this%maxbound, nbudterm, 0, 0, &
4929 ibudcsv=this%ibudcsv)
4933 text =
' FLOW-JA-FACE'
4935 maxlist = this%nconn
4937 auxtxt(1) =
' FLOW-AREA'
4938 call this%budobj%budterm(idx)%initialize(text, &
4943 maxlist, .false., .false., &
4947 call this%budobj%budterm(idx)%reset(this%nconn)
4949 do n = 1, this%maxbound
4951 do i = this%ia(n) + 1, this%ia(n + 1) - 1
4953 call this%budobj%budterm(idx)%update_term(n1, n2, q)
4960 maxlist = this%maxbound - this%ianynone
4962 auxtxt(1) =
' FLOW-AREA'
4963 call this%budobj%budterm(idx)%initialize(text, &
4968 maxlist, .false., .true., &
4970 call this%budobj%budterm(idx)%reset(maxlist)
4972 do n = 1, this%maxbound
4973 n2 = this%igwfnode(n)
4975 call this%budobj%budterm(idx)%update_term(n, n2, q)
4982 maxlist = this%maxbound
4984 call this%budobj%budterm(idx)%initialize(text, &
4989 maxlist, .false., .false., &
4993 text =
' EVAPORATION'
4995 maxlist = this%maxbound
4997 call this%budobj%budterm(idx)%initialize(text, &
5002 maxlist, .false., .false., &
5008 maxlist = this%maxbound
5010 call this%budobj%budterm(idx)%initialize(text, &
5015 maxlist, .false., .false., &
5019 text =
' EXT-INFLOW'
5021 maxlist = this%maxbound
5023 call this%budobj%budterm(idx)%initialize(text, &
5028 maxlist, .false., .false., &
5032 text =
' EXT-OUTFLOW'
5034 maxlist = this%maxbound
5036 call this%budobj%budterm(idx)%initialize(text, &
5041 maxlist, .false., .false., &
5047 maxlist = this%maxbound
5049 auxtxt(1) =
' VOLUME'
5050 call this%budobj%budterm(idx)%initialize(text, &
5055 maxlist, .false., .false., &
5059 if (this%imover == 1)
then
5064 maxlist = this%maxbound
5066 call this%budobj%budterm(idx)%initialize(text, &
5071 maxlist, .false., .false., &
5077 maxlist = this%maxbound
5079 call this%budobj%budterm(idx)%initialize(text, &
5084 maxlist, .false., .false., &
5095 maxlist = this%maxbound
5096 call this%budobj%budterm(idx)%initialize(text, &
5101 maxlist, .false., .false., &
5106 if (this%iprflow /= 0)
then
5107 call this%budobj%flowtable_df(this%iout, cellids=
'GWF')
5109 end subroutine sfr_setup_budobj
5117 subroutine sfr_fill_budobj(this)
5119 class(sfrtype) :: this
5121 integer(I4B) :: naux
5128 integer(I4B) :: idiv
5129 integer(I4B) :: jpos
5143 call this%budobj%budterm(idx)%reset(this%nconn)
5144 do n = 1, this%maxbound
5148 do i = this%ia(n) + 1, this%ia(n + 1) - 1
5150 if (this%iboundpak(n) /= 0)
then
5152 if (this%idir(i) < 0)
then
5158 do ii = this%ia(n2) + 1, this%ia(n2 + 1) - 1
5159 if (this%idir(ii) > 0) cycle
5160 if (this%ja(ii) /= n) cycle
5166 call this%sfr_calc_reach_depth(n, qt, d)
5167 ca = this%calc_area_wet(n, d)
5172 this%qauxcbc(1) = ca
5173 call this%budobj%budterm(idx)%update_term(n1, n2, q, this%qauxcbc)
5179 call this%budobj%budterm(idx)%reset(this%maxbound - this%ianynone)
5180 do n = 1, this%maxbound
5181 n2 = this%igwfnode(n)
5183 if (this%iboundpak(n) /= 0)
then
5185 if (this%depth(n) >
dzero)
then
5186 wp = this%calc_perimeter_wet(n, this%depth(n))
5195 this%qauxcbc(1) =
dzero
5198 call this%budobj%budterm(idx)%update_term(n, n2, q, this%qauxcbc)
5204 call this%budobj%budterm(idx)%reset(this%maxbound)
5205 do n = 1, this%maxbound
5206 if (this%iboundpak(n) /= 0)
then
5207 a = this%calc_surface_area(n)
5208 q = this%rain(n) * a
5212 call this%budobj%budterm(idx)%update_term(n, n, q)
5217 call this%budobj%budterm(idx)%reset(this%maxbound)
5218 do n = 1, this%maxbound
5219 if (this%iboundpak(n) /= 0)
then
5220 q = -this%simevap(n)
5224 call this%budobj%budterm(idx)%update_term(n, n, q)
5229 call this%budobj%budterm(idx)%reset(this%maxbound)
5230 do n = 1, this%maxbound
5231 if (this%iboundpak(n) /= 0)
then
5232 q = this%simrunoff(n)
5236 call this%budobj%budterm(idx)%update_term(n, n, q)
5241 call this%budobj%budterm(idx)%reset(this%maxbound)
5242 do n = 1, this%maxbound
5243 if (this%iboundpak(n) /= 0)
then
5248 call this%budobj%budterm(idx)%update_term(n, n, q)
5253 call this%budobj%budterm(idx)%reset(this%maxbound)
5254 do n = 1, this%maxbound
5256 if (this%iboundpak(n) /= 0)
then
5257 do i = this%ia(n) + 1, this%ia(n + 1) - 1
5258 if (this%idir(i) > 0) cycle
5261 jpos = this%iadiv(n) + idiv - 1
5262 q = q + this%divq(jpos)
5264 q = q + this%qconn(i)
5267 q = q - this%dsflow(n)
5268 if (this%imover == 1)
then
5269 q = q + this%pakmvrobj%get_qtomvr(n)
5272 if (this%imover == 1)
then
5273 q = this%pakmvrobj%get_qfrommvr(n)
5276 call this%budobj%budterm(idx)%update_term(n, n, q)
5281 call this%budobj%budterm(idx)%reset(this%maxbound)
5282 do n = 1, this%maxbound
5284 if (this%iboundpak(n) /= 0)
then
5286 a = this%calc_surface_area_wet(n, d)
5287 this%qauxcbc(1) = a * d
5288 if (this%gwfiss == 0 .and. this%istorage == 1)
then
5293 this%qauxcbc(1) =
dzero
5295 call this%budobj%budterm(idx)%update_term(n, n, q, this%qauxcbc)
5299 if (this%imover == 1)
then
5303 call this%budobj%budterm(idx)%reset(this%maxbound)
5304 do n = 1, this%maxbound
5306 if (this%iboundpak(n) /= 0)
then
5307 q = this%pakmvrobj%get_qfrommvr(n)
5309 call this%budobj%budterm(idx)%update_term(n, n, q)
5314 call this%budobj%budterm(idx)%reset(this%maxbound)
5315 do n = 1, this%maxbound
5316 if (this%iboundpak(n) /= 0)
then
5317 q = this%pakmvrobj%get_qtomvr(n)
5324 call this%budobj%budterm(idx)%update_term(n, n, q)
5332 call this%budobj%budterm(idx)%reset(this%maxbound)
5333 do n = 1, this%maxbound
5335 call this%budobj%budterm(idx)%update_term(n, n, q, this%auxvar(:, n))
5340 call this%budobj%accumulate_terms()
5341 end subroutine sfr_fill_budobj
5349 subroutine sfr_setup_tableobj(this)
5351 class(sfrtype) :: this
5353 integer(I4B) :: nterms
5354 character(len=LINELENGTH) :: title
5355 character(len=LINELENGTH) :: text
5358 if (this%iprhed > 0)
then
5365 if (this%inamedbound == 1)
then
5370 title = trim(adjustl(this%text))//
' PACKAGE ('// &
5371 trim(adjustl(this%packName))//
') STAGES FOR EACH CONTROL VOLUME'
5374 call table_cr(this%stagetab, this%packName, title)
5375 call this%stagetab%table_df(this%maxbound, nterms, this%iout, &
5379 if (this%inamedbound == 1)
then
5381 call this%stagetab%initialize_column(text,
lenboundname, &
5387 call this%stagetab%initialize_column(text, 10, alignment=
tabcenter)
5391 call this%stagetab%initialize_column(text, 20, alignment=
tableft)
5395 call this%stagetab%initialize_column(text, 12, alignment=
tabcenter)
5399 call this%stagetab%initialize_column(text, 12, alignment=
tabcenter)
5403 call this%stagetab%initialize_column(text, 12, alignment=
tabcenter)
5407 call this%stagetab%initialize_column(text, 12, alignment=
tabcenter)
5410 text =
'STREAMBED CONDUCTANCE'
5411 call this%stagetab%initialize_column(text, 12, alignment=
tabcenter)
5414 text =
'STREAMBED GRADIENT'
5415 call this%stagetab%initialize_column(text, 12, alignment=
tabcenter)
5419 if (this%istorage == 1)
then
5421 if (this%inamedbound == 1)
then
5426 title = trim(adjustl(this%text))//
' PACKAGE ('// &
5427 trim(adjustl(this%packName))//
') COURANT NUMBER FOR EACH REACH'
5430 call table_cr(this%couranttab, this%packName, title)
5431 call this%couranttab%table_df(this%maxbound, nterms, this%iout)
5433 if (this%inamedbound == 1)
then
5435 call this%couranttab%initialize_column(text,
lenboundname, &
5441 call this%couranttab%initialize_column(text, 10, alignment=
tabcenter)
5445 call this%couranttab%initialize_column(text, 16, alignment=
tabcenter)
5449 call this%couranttab%initialize_column(text, 16, alignment=
tabcenter)
5453 call this%couranttab%initialize_column(text, 16, alignment=
tabcenter)
5455 end subroutine sfr_setup_tableobj
5463 function calc_area_wet(this, n, depth)
5465 real(dp) :: calc_area_wet
5467 class(sfrtype) :: this
5468 integer(I4B),
intent(in) :: n
5469 real(dp),
intent(in) :: depth
5471 integer(I4B) :: npts
5476 npts = this%ncrosspts(n)
5477 i0 = this%iacross(n)
5478 i1 = this%iacross(n + 1) - 1
5481 this%xsheight(i0:i1), depth)
5483 calc_area_wet = this%station(i0) * depth
5485 end function calc_area_wet
5491 function calc_perimeter_wet(this, n, depth)
5493 real(dp) :: calc_perimeter_wet
5495 class(sfrtype) :: this
5496 integer(I4B),
intent(in) :: n
5497 real(dp),
intent(in) :: depth
5499 integer(I4B) :: npts
5504 npts = this%ncrosspts(n)
5505 i0 = this%iacross(n)
5506 i1 = this%iacross(n + 1) - 1
5509 this%xsheight(i0:i1), depth)
5511 calc_perimeter_wet = this%station(i0)
5513 end function calc_perimeter_wet
5519 function calc_surface_area(this, n)
5521 real(dp) :: calc_surface_area
5523 class(sfrtype) :: this
5524 integer(I4B),
intent(in) :: n
5526 integer(I4B) :: npts
5529 real(dp) :: top_width
5532 npts = this%ncrosspts(n)
5533 i0 = this%iacross(n)
5534 i1 = this%iacross(n + 1) - 1
5538 top_width = this%station(i0)
5540 calc_surface_area = top_width * this%length(n)
5541 end function calc_surface_area
5547 function calc_surface_area_wet(this, n, depth)
5549 real(dp) :: calc_surface_area_wet
5551 class(sfrtype) :: this
5552 integer(I4B),
intent(in) :: n
5553 real(dp),
intent(in) :: depth
5555 real(dp) :: top_width
5558 top_width = this%calc_top_width_wet(n, depth)
5559 calc_surface_area_wet = top_width * this%length(n)
5560 end function calc_surface_area_wet
5566 function calc_top_width_wet(this, n, depth)
5568 real(dp) :: calc_top_width_wet
5570 class(sfrtype) :: this
5571 integer(I4B),
intent(in) :: n
5572 real(dp),
intent(in) :: depth
5574 integer(I4B) :: npts
5580 npts = this%ncrosspts(n)
5581 i0 = this%iacross(n)
5582 i1 = this%iacross(n + 1) - 1
5586 this%station(i0:i1), &
5587 this%xsheight(i0:i1), &
5590 calc_top_width_wet = sat * this%station(i0)
5592 end function calc_top_width_wet
5598 subroutine sfr_activate_density(this)
5602 class(sfrtype),
intent(inout) :: this
5609 call mem_reallocate(this%denseterms, 3, this%MAXBOUND,
'DENSETERMS', &
5611 do i = 1, this%maxbound
5613 this%denseterms(j, i) =
dzero
5616 write (this%iout,
'(/1x,a)')
'DENSITY TERMS HAVE BEEN ACTIVATED FOR SFR &
5617 &PACKAGE: '//trim(adjustl(this%packName))
5618 end subroutine sfr_activate_density
5625 subroutine sfr_activate_viscosity(this)
5629 class(sfrtype),
intent(inout) :: this
5636 call mem_reallocate(this%viscratios, 2, this%MAXBOUND,
'VISCRATIOS', &
5638 do i = 1, this%maxbound
5640 this%viscratios(j, i) =
done
5643 write (this%iout,
'(/1x,a)')
'VISCOSITY HAS BEEN ACTIVATED FOR SFR &
5644 &PACKAGE: '//trim(adjustl(this%packName))
5645 end subroutine sfr_activate_viscosity
5658 subroutine sfr_calculate_density_exchange(this, n, stage, head, cond, &
5659 tops, flow, gwfhcof, gwfrhs)
5661 class(sfrtype),
intent(inout) :: this
5662 integer(I4B),
intent(in) :: n
5663 real(DP),
intent(in) :: stage
5664 real(DP),
intent(in) :: head
5665 real(DP),
intent(in) :: cond
5666 real(DP),
intent(in) :: tops
5667 real(DP),
intent(inout) :: flow
5668 real(DP),
intent(inout) :: gwfhcof
5669 real(DP),
intent(inout) :: gwfrhs
5674 real(DP) :: rdensesfr
5675 real(DP) :: rdensegwf
5676 real(DP) :: rdenseavg
5682 logical(LGP) :: stage_below_bot
5683 logical(LGP) :: head_below_bot
5686 if (stage >= tops)
then
5688 stage_below_bot = .false.
5689 rdensesfr = this%denseterms(1, n)
5692 stage_below_bot = .true.
5693 rdensesfr = this%denseterms(2, n)
5697 if (head >= tops)
then
5699 head_below_bot = .false.
5700 rdensegwf = this%denseterms(2, n)
5703 head_below_bot = .true.
5704 rdensegwf = this%denseterms(1, n)
5708 if (rdensegwf ==
dzero)
return
5711 if (stage_below_bot .and. head_below_bot)
then
5718 rdenseavg =
dhalf * (rdensesfr + rdensegwf)
5722 d1 = cond * (rdenseavg -
done)
5723 gwfhcof = gwfhcof - d1
5724 gwfrhs = gwfrhs - d1 * ss
5729 if (.not. stage_below_bot .and. .not. head_below_bot)
then
5733 elevgwf = this%denseterms(3, n)
5735 elevavg =
dhalf * (elevsfr + elevgwf)
5736 havg =
dhalf * (hh + ss)
5737 d2 = cond * (havg - elevavg) * (rdensegwf - rdensesfr)
5738 gwfrhs = gwfrhs + d2
5742 end subroutine sfr_calculate_density_exchange
5749 subroutine sfr_input_init(this, mempath, naux)
5751 class(sfrinputtype),
intent(inout) :: this
5752 character(len=*),
intent(in) :: mempath
5753 integer(I4B),
intent(in) :: naux
5754 call mem_setptr(this%nbound,
'NBOUND', mempath)
5756 call mem_setptr(this%setting,
'SETTING', mempath)
5757 call mem_setptr(this%status,
'STATUS', mempath)
5759 call mem_setptr(this%tab6_filename,
'TAB6_FILENAME', mempath)
5761 call mem_setptr(this%auxname,
'AUXNAME', mempath)
5762 call mem_setptr(this%auxval,
'AUXVAL', mempath)
5764 end subroutine sfr_input_init
5768 subroutine sfr_input_destroy(this)
5769 class(sfrinputtype),
intent(inout) :: this
5772 nullify (this%ustrf)
5773 nullify (this%nbound)
5775 nullify (this%status)
5776 nullify (this%setting)
5778 nullify (this%tab6_filename)
5779 nullify (this%auxname)
5780 nullify (this%auxval)
5781 end subroutine sfr_input_destroy
This module contains the extended boundary package.
This module contains the base boundary package.
This module contains the BudgetModule.
subroutine, public budgetobject_cr(this, name)
Create a new budget object.
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
real(dp), parameter dhdry
real dry cell constant
@ tabcenter
centered table column
@ tabright
right justified table column
@ tableft
left justified table column
@ mnormal
normal output mode
real(dp), parameter dtwothirds
real constant 2/3
integer(i4b), parameter lenpackagename
maximum length of the package name
real(dp), parameter dp9
real constant 9/10
real(dp), parameter deight
real constant 8
real(dp), parameter dfivethirds
real constant 5/3
real(dp), parameter dp999
real constant 999/1000
integer(i4b), parameter namedboundflag
named bound flag
real(dp), parameter donethird
real constant 1/3
real(dp), parameter dnodata
real no data constant
real(dp), parameter d1p1
real constant 1.1
real(dp), parameter dhnoflo
real no flow constant
real(dp), parameter dhundred
real constant 100
integer(i4b), parameter lenpakloc
maximum length of a package location
real(dp), parameter dep20
real constant 1e20
real(dp), parameter dp6
real constant 3/5
integer(i4b), parameter maxadpit
maximum advanced package Newton-Raphson iterations
integer(i4b), parameter lenvarname
maximum length of a variable name
real(dp), parameter dhalf
real constant 1/2
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
real(dp), parameter dpi
real constant
real(dp), parameter dp99
real constant 99/100
integer(i4b), parameter lenboundname
maximum length of a bound name
real(dp), parameter dem4
real constant 1e-4
real(dp), parameter dem30
real constant 1e-30
real(dp), parameter dem6
real constant 1e-6
real(dp), parameter dzero
real constant zero
real(dp), parameter dem5
real constant 1e-5
real(dp), parameter dprec
real constant machine precision
integer(i4b), parameter maxcharlen
maximum length of char string
real(dp), parameter dp7
real constant 7/10
real(dp), parameter dem2
real constant 1e-2
real(dp), parameter dtwo
real constant 2
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
integer(i4b), parameter lenmempath
maximum length of the memory path
real(dp), parameter done
real constant 1
This module contains stateless sfr subroutines and functions.
real(dp) function, public get_wetted_topwidth(npts, stations, heights, d)
Calculate the wetted top width for a reach.
real(dp) function, public get_wetted_perimeter(npts, stations, heights, d)
Calculate the wetted perimeter for a reach.
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_saturated_topwidth(npts, stations)
Calculate the saturated top width for a reach.
real(dp) function, public get_mannings_section(npts, stations, heights, roughfracs, roughness, conv_fact, slope, d)
Calculate the manning's discharge for a reach.
This module defines variable data types.
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
subroutine, public memorystore_release(varname, memory_path)
Release a single variable from the memory store.
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
This module contains the derived types ObserveType and ObsDataType.
subroutine, public cross_section_cr(this, iout, iprpak, nreaches)
Create a cross-section object.
This module contains the SFR package methods.
subroutine sfr_source_connectiondata(this)
Source CONNECTIONDATA block from input context.
subroutine sfr_source_initialstages(this)
Source INITIALSTAGES block from input context.
subroutine sfr_calc_celerity(this, n, q, celerity)
Kinematic-wave celerity from a flow perturbation (0 if dry)
real(dp) function calc_top_width_wet(this, n, depth)
Calculate wetted top width.
subroutine sfr_precompute_tvd(this)
Pre-compute the single upstream reach index for the TVD limiter.
subroutine sfr_setup_tableobj(this)
Setup stage table object for package.
subroutine sfr_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
@ brief Convergence check for package.
subroutine sfr_cq(this, x, flowja, iadv)
@ brief Calculate package flows.
subroutine sfr_ot_package_flows(this, icbcfl, ibudfl)
@ brief Output package flow terms.
subroutine sfr_activate_viscosity(this)
Activate viscosity terms.
subroutine sfr_da(this)
@ brief Deallocate package memory
subroutine sfr_calc_reach_depth(this, n, q1, d1)
Calculate the depth at the midpoint.
real(dp) function calc_surface_area(this, n)
Calculate maximum surface area.
subroutine sfr_check_ustrf(this)
Check upstream fraction data.
subroutine sfr_source_packagedata(this)
Source PACKAGEDATA block from input context.
subroutine sfr_calc_xs_depth(this, n, qrch, d)
Calculate the depth at the midpoint of a irregular cross-section.
subroutine sfr_check_diversions(this)
Check diversions data.
subroutine sfr_ot_dv(this, idvsave, idvprint)
@ brief Output package dependent-variable terms.
subroutine, public sfr_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath)
@ brief Create a new package object
subroutine sfr_dt(this)
Submit the ATS time step for the most Courant-constraining reach.
subroutine sfr_fc(this, rhs, ia, idxglo, matrix_sln)
@ brief Copy hcof and rhs terms into solution.
subroutine sfr_fn(this, rhs, ia, idxglo, matrix_sln)
@ brief Add Newton-Raphson terms for package into solution.
subroutine define_listlabel(this)
@ brief Define the list label for the package
subroutine sfr_df_obs(this)
Define the observation types available in the package.
subroutine sfr_calc_cond(this, n, depth, cond, hsfr, h_temp)
Calculate reach-aquifer conductance.
subroutine sfr_check_connections(this)
Check connection data.
subroutine sfr_source_options(this)
Source OPTIONS from input context.
subroutine sfr_input_destroy(this)
Nullify all SfrInputType pointers.
subroutine sfr_allocate_arrays(this)
@ brief Allocate arrays
subroutine sfr_bd_obs(this)
Save observations for the package.
subroutine sfr_source_crosssections(this)
Source CROSSSECTIONS block from input context.
subroutine sfr_setup_budobj(this)
Setup budget object for package.
subroutine sfr_check_initialstages(this)
Check initial stage data.
subroutine sfr_rp(this)
@ brief Read and prepare period data for package
subroutine sfr_input_init(this, mempath, naux)
Bind SfrInputType PERIOD pointers to input context arrays.
subroutine sfr_ar(this)
@ brief Allocate and read method for package
subroutine sfr_calc_qman(this, n, depth, qman)
Calculate streamflow.
subroutine sfr_fp(this)
Write the Courant-number summary table to the listing file.
subroutine sfr_check_reaches(this)
Check reach data.
real(dp) function calc_perimeter_wet(this, n, depth)
Calculate wetted perimeter.
subroutine sfr_update_flows(this, n, qd, qgwf)
Update flow terms.
subroutine sfr_calc_qd(this, n, depth, hgwf, qgwf, qd)
Calculate downstream flow term.
subroutine sfr_fill_budobj(this)
Copy flow terms into budget object for package.
subroutine sfr_cf(this)
@ brief Formulate the package hcof and rhs terms.
subroutine sfr_ot_bdsummary(this, kstp, kper, iout, ibudfl)
@ brief Output advanced package budget summary.
subroutine sfr_calc_div(this, n, i, qd, qdiv)
Calculate diversion flow.
subroutine sfr_calc_qgwf(this, n, depth, hgwf, qgwf, gwfhcof, gwfrhs)
Calculate reach-aquifer exchange.
character(len=lenftype) ftype
package ftype string
subroutine sfr_calculate_density_exchange(this, n, stage, head, cond, tops, flow, gwfhcof, gwfrhs)
Calculate density terms.
subroutine sfr_source_dimensions(this)
Source DIMENSIONS block from input context and load static data.
character(len=lenpackagename) text
package budget string
subroutine sfr_set_period_value(this, i, n, setting)
Apply a PERIOD setting value to reach n.
subroutine sfr_calc_qsource(this, n, depth, qsrc)
Calculate sum of sources.
subroutine sfr_allocate_scalars(this)
@ brief Allocate scalars
logical function sfr_obs_supported(this)
Determine if observations are supported.
subroutine sfr_source_diversions(this)
Source DIVERSIONS block from input context.
subroutine sfr_check_storage_weight(this)
Check storage weight.
subroutine sfr_solve(this, n, h, hcof, rhs, update)
Solve reach continuity equation.
real(dp) function calc_area_wet(this, n, depth)
Calculate wetted area.
subroutine sfr_rp_obs(this)
Read and prepare observations for a package.
subroutine sfr_activate_density(this)
Activate density terms.
subroutine sfr_adjust_ro_ev(this, qc, qu, qi, qr, qro, qe, qfrommvr)
Adjust runoff and evaporation.
subroutine sfr_check_conversion(this)
Check unit conversion data.
real(dp) function calc_surface_area_wet(this, n, depth)
Calculate wetted surface area.
integer(i4b) function sfr_gwf_conn(this, n)
Determine if a reach is connected to a gwf cell.
subroutine sfr_ad(this)
@ brief Advance the package
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 deprecation_warning(cblock, cvar, cver, endmsg, iunit)
Store deprecation warning message.
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
character(len=maxcharlen) warnmsg
warning message string
real(dp) function squadraticsaturation(top, bot, x, eps)
@ brief sQuadraticSaturation
real(dp) function scubicsaturation(top, bot, x, eps)
@ brief sCubicSaturation
real(dp) function squadraticsaturationderivative(top, bot, x, eps)
@ brief Derivative of the quadratic saturation function
real(dp) function sqsaturationderivative(top, bot, x, c1, c2)
@ brief sQSaturationDerivative
subroutine schsmooth(d, smooth, dwdh)
@ brief sChSmooth
real(dp) function sqsaturation(top, bot, x, c1, c2)
@ brief sQSaturation
subroutine, public table_cr(this, name, title)
real(dp), pointer, public pertim
time relative to start of stress period
real(dp), pointer, public totim
time relative to start of simulation
class(atstype), pointer, public ats
integer(i4b), pointer, public inats
flag indicating ats active for simulation
integer(i4b), pointer, public kstp
current time step number
integer(i4b), pointer, public kper
current stress period number
real(dp), pointer, public delt
length of the current time step
Derived type for the Budget object.
This class is used to store a single deferred-length character string. It was designed to work in an ...