46 character(len=LENFTYPE) ::
ftype =
'LAK'
47 character(len=LENPACKAGENAME) ::
text =
' LAK'
50 real(dp),
dimension(:),
pointer,
contiguous :: tabstage => null()
51 real(dp),
dimension(:),
pointer,
contiguous :: tabvolume => null()
52 real(dp),
dimension(:),
pointer,
contiguous :: tabsarea => null()
53 real(dp),
dimension(:),
pointer,
contiguous :: tabwarea => null()
64 integer(I4B),
pointer :: nbound => null()
65 integer(I4B),
dimension(:),
pointer,
contiguous :: ifno => null()
72 real(dp),
dimension(:),
pointer,
contiguous :: &
75 integer(I4B),
dimension(:),
pointer,
contiguous :: outletno => null()
76 real(dp),
dimension(:),
pointer,
contiguous :: outlets_invert => null()
77 real(dp),
dimension(:),
pointer,
contiguous :: outlets_width => null()
78 real(dp),
dimension(:),
pointer,
contiguous :: outlets_rough => null()
79 real(dp),
dimension(:),
pointer,
contiguous :: outlets_slope => null()
88 character(len=16),
dimension(:),
pointer,
contiguous :: clakbudget => null()
89 character(len=16),
dimension(:),
pointer,
contiguous :: cauxcbc => null()
92 integer(I4B),
pointer :: iprhed => null()
93 integer(I4B),
pointer :: istageout => null()
94 integer(I4B),
pointer :: ibudgetout => null()
95 integer(I4B),
pointer :: ibudcsv => null()
96 integer(I4B),
pointer :: ipakcsv => null()
97 character(len=:),
allocatable :: pakcsvfile
98 integer(I4B),
pointer :: cbcauxitems => null()
99 integer(I4B),
pointer :: nlakes => null()
100 integer(I4B),
pointer :: noutlets => null()
101 integer(I4B),
pointer :: ntables => null()
102 real(dp),
pointer :: convlength => null()
103 real(dp),
pointer :: convtime => null()
104 real(dp),
pointer :: outdmax => null()
105 integer(I4B),
pointer :: igwhcopt => null()
106 integer(I4B),
pointer :: iconvchk => null()
107 integer(I4B),
pointer :: maxlakit => null()
108 real(dp),
pointer :: surfdep => null()
109 real(dp),
pointer :: dmaxchg => null()
110 real(dp),
pointer :: delh => null()
111 integer(I4B),
pointer :: check_attr => null()
114 integer(I4B),
pointer :: iimplicit => null()
115 integer(I4B),
pointer :: iforceleg => null()
116 integer(I4B),
pointer :: iforceleglak => null()
118 integer(I4B),
pointer :: bditems => null()
121 integer(I4B),
dimension(:),
pointer,
contiguous :: nlakeconn => null()
122 integer(I4B),
dimension(:),
pointer,
contiguous :: idxlakeconn => null()
123 integer(I4B),
dimension(:),
pointer,
contiguous :: ntabrow => null()
124 real(dp),
dimension(:),
pointer,
contiguous :: strt => null()
125 real(dp),
dimension(:),
pointer,
contiguous :: laketop => null()
126 real(dp),
dimension(:),
pointer,
contiguous :: lakebot => null()
127 real(dp),
dimension(:),
pointer,
contiguous :: sareamax => null()
128 character(len=LENBOUNDNAME),
dimension(:),
pointer, &
129 contiguous :: lakename => null()
130 character(len=8),
dimension(:),
pointer,
contiguous :: status => null()
131 real(dp),
dimension(:),
pointer,
contiguous :: avail => null()
132 real(dp),
dimension(:),
pointer,
contiguous :: lkgwsink => null()
133 real(dp),
dimension(:),
pointer,
contiguous :: stage => null()
134 real(dp),
dimension(:),
pointer,
contiguous :: rainfall => null()
135 real(dp),
dimension(:),
pointer,
contiguous :: evaporation => null()
136 real(dp),
dimension(:),
pointer,
contiguous :: runoff => null()
137 real(dp),
dimension(:),
pointer,
contiguous :: inflow => null()
138 real(dp),
dimension(:),
pointer,
contiguous :: withdrawal => null()
141 integer(I4B),
dimension(:),
pointer,
contiguous :: ialaktab => null()
142 real(dp),
dimension(:),
pointer,
contiguous :: tabstage => null()
143 real(dp),
dimension(:),
pointer,
contiguous :: tabvolume => null()
144 real(dp),
dimension(:),
pointer,
contiguous :: tabsarea => null()
145 real(dp),
dimension(:),
pointer,
contiguous :: tabwarea => null()
148 integer(I4B),
dimension(:),
pointer,
contiguous :: ncncvr => null()
152 integer(I4B),
dimension(:),
pointer,
contiguous :: ilegacy => null()
153 integer(I4B),
dimension(:),
pointer,
contiguous :: nstuck => null()
154 real(dp),
dimension(:),
pointer,
contiguous :: surfin => null()
155 real(dp),
dimension(:),
pointer,
contiguous :: surfout => null()
156 real(dp),
dimension(:),
pointer,
contiguous :: surfout1 => null()
157 real(dp),
dimension(:),
pointer,
contiguous :: precip => null()
158 real(dp),
dimension(:),
pointer,
contiguous :: precip1 => null()
159 real(dp),
dimension(:),
pointer,
contiguous :: evap => null()
160 real(dp),
dimension(:),
pointer,
contiguous :: evap1 => null()
161 real(dp),
dimension(:),
pointer,
contiguous :: evapo => null()
162 real(dp),
dimension(:),
pointer,
contiguous :: withr => null()
163 real(dp),
dimension(:),
pointer,
contiguous :: withr1 => null()
164 real(dp),
dimension(:),
pointer,
contiguous :: flwin => null()
165 real(dp),
dimension(:),
pointer,
contiguous :: flwiter => null()
166 real(dp),
dimension(:),
pointer,
contiguous :: flwiter1 => null()
167 real(dp),
dimension(:),
pointer,
contiguous :: seep => null()
168 real(dp),
dimension(:),
pointer,
contiguous :: seep1 => null()
169 real(dp),
dimension(:),
pointer,
contiguous :: seep0 => null()
170 real(dp),
dimension(:),
pointer,
contiguous :: stageiter => null()
171 real(dp),
dimension(:),
pointer,
contiguous :: chterm => null()
174 integer(I4B),
dimension(:),
pointer,
contiguous :: iseepc => null()
175 integer(I4B),
dimension(:),
pointer,
contiguous :: idhc => null()
176 real(dp),
dimension(:),
pointer,
contiguous :: en1 => null()
177 real(dp),
dimension(:),
pointer,
contiguous :: en2 => null()
178 real(dp),
dimension(:),
pointer,
contiguous :: r1 => null()
179 real(dp),
dimension(:),
pointer,
contiguous :: r2 => null()
180 real(dp),
dimension(:),
pointer,
contiguous :: dh0 => null()
181 real(dp),
dimension(:),
pointer,
contiguous :: s0 => null()
182 real(dp),
dimension(:),
pointer,
contiguous :: qgwf0 => null()
184 integer(I4B),
dimension(:),
pointer,
contiguous :: idxlocnode => null()
185 integer(I4B),
dimension(:),
pointer,
contiguous :: idxdiag => null()
186 integer(I4B),
dimension(:),
pointer,
contiguous :: idxoffdglo => null()
187 integer(I4B),
dimension(:),
pointer,
contiguous :: idxsymdglo => null()
188 integer(I4B),
dimension(:),
pointer,
contiguous :: idxsymoffdglo => null()
191 integer(I4B),
dimension(:),
pointer,
contiguous :: imap => null()
192 integer(I4B),
dimension(:),
pointer,
contiguous :: gwfconn => null()
193 integer(I4B),
dimension(:),
pointer,
contiguous :: nodesontop => null()
194 integer(I4B),
dimension(:),
pointer,
contiguous :: ictype => null()
195 real(dp),
dimension(:),
pointer,
contiguous :: bedleak => null()
196 real(dp),
dimension(:),
pointer,
contiguous :: belev => null()
197 real(dp),
dimension(:),
pointer,
contiguous :: telev => null()
198 real(dp),
dimension(:),
pointer,
contiguous :: connlength => null()
199 real(dp),
dimension(:),
pointer,
contiguous :: connwidth => null()
200 real(dp),
dimension(:),
pointer,
contiguous :: sarea => null()
201 real(dp),
dimension(:),
pointer,
contiguous :: warea => null()
202 real(dp),
dimension(:),
pointer,
contiguous :: satcond => null()
203 real(dp),
dimension(:),
pointer,
contiguous :: simcond => null()
204 real(dp),
dimension(:),
pointer,
contiguous :: simlakgw => null()
207 integer(I4B),
dimension(:),
pointer,
contiguous :: lakein => null()
208 integer(I4B),
dimension(:),
pointer,
contiguous :: lakeout => null()
209 integer(I4B),
dimension(:),
pointer,
contiguous :: iouttype => null()
210 real(dp),
dimension(:),
pointer,
contiguous :: outrate => null()
211 real(dp),
dimension(:),
pointer,
contiguous :: outinvert => null()
212 real(dp),
dimension(:),
pointer,
contiguous :: outwidth => null()
213 real(dp),
dimension(:),
pointer,
contiguous :: outrough => null()
214 real(dp),
dimension(:),
pointer,
contiguous :: outslope => null()
215 real(dp),
dimension(:),
pointer,
contiguous :: simoutrate => null()
219 logical(LGP),
dimension(:),
pointer,
contiguous :: outlet_invert_set => null()
220 logical(LGP),
dimension(:),
pointer,
contiguous :: outlet_width_set => null()
221 logical(LGP),
dimension(:),
pointer,
contiguous :: outlet_rough_set => null()
222 logical(LGP),
dimension(:),
pointer,
contiguous :: outlet_slope_set => null()
225 real(dp),
dimension(:),
pointer,
contiguous :: qauxcbc => null()
226 real(dp),
dimension(:),
pointer,
contiguous :: dbuff => null()
227 real(dp),
dimension(:),
pointer,
contiguous :: qleak => null()
231 real(dp),
dimension(:),
pointer,
contiguous :: holdconn => null()
232 real(dp),
dimension(:),
pointer,
contiguous :: qsto => null()
235 integer(I4B),
pointer :: gwfiss => null()
236 real(dp),
dimension(:),
pointer,
contiguous :: gwfk11 => null()
237 real(dp),
dimension(:),
pointer,
contiguous :: gwfk33 => null()
238 real(dp),
dimension(:),
pointer,
contiguous :: gwfsat => null()
239 integer(I4B),
pointer :: gwfik33 => null()
242 integer(I4B),
dimension(:),
pointer,
contiguous :: iboundpak => null()
243 real(dp),
dimension(:),
pointer,
contiguous :: xnewpak => null()
244 real(dp),
dimension(:),
pointer,
contiguous :: xoldpak => null()
257 integer(I4B),
pointer :: idense
258 real(dp),
dimension(:, :),
pointer,
contiguous :: denseterms => null()
261 real(dp),
dimension(:, :),
pointer,
contiguous :: viscratios => null()
283 procedure,
private :: lak_set_legacy
284 procedure,
private :: lak_check_disconnected
338 procedure,
private :: lak_fc_implicit
339 procedure,
private :: lak_budget_nogwf
360 module subroutine lak_budget_nogwf(this, n, stage, b)
361 class(laktype),
intent(inout) :: this
362 integer(I4B),
intent(in) :: n
363 real(dp),
intent(in) :: stage
364 real(dp),
intent(inout) :: b
369 module subroutine lak_fc_implicit(this, rhs, matrix_sln)
370 class(laktype) :: this
371 real(dp),
dimension(:),
intent(inout) :: rhs
377 module subroutine lak_set_legacy(this, kiter, icnvgmod)
378 class(laktype),
intent(inout) :: this
379 integer(I4B),
intent(in) :: kiter
380 integer(I4B),
intent(in) :: icnvgmod
385 module subroutine lak_check_disconnected(this)
386 class(laktype),
intent(inout) :: this
394 subroutine lak_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
399 class(
bndtype),
pointer :: packobj
400 integer(I4B),
intent(in) :: id
401 integer(I4B),
intent(in) :: ibcnum
402 integer(I4B),
intent(in) :: inunit
403 integer(I4B),
intent(in) :: iout
404 character(len=*),
intent(in) :: namemodel
405 character(len=*),
intent(in) :: pakname
406 character(len=*),
intent(in) :: mempath
408 type(laktype),
pointer :: lakobj
415 call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
419 call lakobj%lak_allocate_scalars()
422 call packobj%pack_initialize()
424 packobj%inunit = inunit
427 packobj%ibcnum = ibcnum
432 end subroutine lak_create
436 subroutine lak_allocate_scalars(this)
438 class(laktype),
intent(inout) :: this
441 call this%BndExtType%allocate_scalars()
444 call mem_allocate(this%iprhed,
'IPRHED', this%memoryPath)
445 call mem_allocate(this%istageout,
'ISTAGEOUT', this%memoryPath)
446 call mem_allocate(this%ibudgetout,
'IBUDGETOUT', this%memoryPath)
447 call mem_allocate(this%ibudcsv,
'IBUDCSV', this%memoryPath)
448 call mem_allocate(this%ipakcsv,
'IPAKCSV', this%memoryPath)
449 call mem_allocate(this%nlakes,
'NLAKES', this%memoryPath)
450 call mem_allocate(this%noutlets,
'NOUTLETS', this%memoryPath)
451 call mem_allocate(this%ntables,
'NTABLES', this%memoryPath)
452 call mem_allocate(this%convlength,
'CONVLENGTH', this%memoryPath)
453 call mem_allocate(this%convtime,
'CONVTIME', this%memoryPath)
454 call mem_allocate(this%outdmax,
'OUTDMAX', this%memoryPath)
455 call mem_allocate(this%igwhcopt,
'IGWHCOPT', this%memoryPath)
456 call mem_allocate(this%iconvchk,
'ICONVCHK', this%memoryPath)
457 call mem_allocate(this%maxlakit,
'MAXLAKIT', this%memoryPath)
458 call mem_allocate(this%surfdep,
'SURFDEP', this%memoryPath)
459 call mem_allocate(this%dmaxchg,
'DMAXCHG', this%memoryPath)
461 call mem_allocate(this%check_attr,
'CHECK_ATTR', this%memoryPath)
462 call mem_allocate(this%iimplicit,
'IIMPLICIT', this%memoryPath)
463 call mem_allocate(this%iforceleg,
'IFORCELEG', this%memoryPath)
464 call mem_allocate(this%iforceleglak,
'IFORCELEGLAK', this%memoryPath)
465 call mem_allocate(this%bditems,
'BDITEMS', this%memoryPath)
466 call mem_allocate(this%cbcauxitems,
'CBCAUXITEMS', this%memoryPath)
467 call mem_allocate(this%idense,
'IDENSE', this%memoryPath)
478 this%convlength =
done
486 this%delh =
dp999 * this%dmaxchg
489 this%iforceleglak = 0
494 end subroutine lak_allocate_scalars
498 subroutine lak_allocate_arrays(this)
501 class(laktype),
intent(inout) :: this
506 call this%BndExtType%allocate_arrays()
509 call this%BndExtType%allocate_featureauxvar()
512 allocate (this%clakbudget(this%bditems))
515 this%clakbudget(1) =
' GWF'
516 this%clakbudget(2) =
' RAINFALL'
517 this%clakbudget(3) =
' EVAPORATION'
518 this%clakbudget(4) =
' RUNOFF'
519 this%clakbudget(5) =
' EXT-INFLOW'
520 this%clakbudget(6) =
' WITHDRAWAL'
521 this%clakbudget(7) =
' EXT-OUTFLOW'
522 this%clakbudget(8) =
' STORAGE'
523 this%clakbudget(9) =
' CONSTANT'
524 this%clakbudget(10) =
' FROM-MVR'
525 this%clakbudget(11) =
' TO-MVR'
528 if (this%istageout > 0)
then
529 call mem_allocate(this%dbuff, this%nlakes,
'DBUFF', this%memoryPath)
530 do i = 1, this%nlakes
531 this%dbuff(i) =
dzero
534 call mem_allocate(this%dbuff, 0,
'DBUFF', this%memoryPath)
538 allocate (this%cauxcbc(this%cbcauxitems))
541 call mem_allocate(this%qauxcbc, this%cbcauxitems,
'QAUXCBC', this%memoryPath)
542 do i = 1, this%cbcauxitems
543 this%qauxcbc(i) =
dzero
547 call mem_allocate(this%qleak, this%maxbound,
'QLEAK', this%memoryPath)
548 do i = 1, this%maxbound
549 this%qleak(i) =
dzero
553 if (this%iimplicit /= 0)
then
554 call mem_allocate(this%holdconn, this%maxbound,
'HOLDCONN', this%memoryPath)
555 do i = 1, this%maxbound
556 this%holdconn(i) =
dzero
559 call mem_allocate(this%holdconn, 0,
'HOLDCONN', this%memoryPath)
561 call mem_allocate(this%qsto, this%nlakes,
'QSTO', this%memoryPath)
562 do i = 1, this%nlakes
567 call mem_allocate(this%denseterms, 3, 0,
'DENSETERMS', this%memoryPath)
570 call mem_allocate(this%viscratios, 2, 0,
'VISCRATIOS', this%memoryPath)
571 end subroutine lak_allocate_arrays
575 subroutine lak_source_packagedata(this)
577 class(laktype),
intent(inout) :: this
580 integer(I4B) :: ilak, nconn
581 character(len=9) :: cno
582 character(len=LENBOUNDNAME) :: bndName
583 integer(I4B),
dimension(:),
pointer,
contiguous :: ifno => null()
584 real(DP),
dimension(:),
pointer,
contiguous :: strt => null()
585 integer(I4B),
dimension(:),
pointer,
contiguous :: nlakeconn => null()
587 boundname_cst => null()
588 integer(I4B),
allocatable :: nboundchk(:)
590 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text))// &
594 call mem_allocate(this%nlakeconn, this%nlakes,
'NLAKECONN', this%memoryPath)
595 call mem_allocate(this%idxlakeconn, this%nlakes + 1,
'IDXLAKECONN', &
597 call mem_allocate(this%ntabrow, this%nlakes,
'NTABROW', this%memoryPath)
598 call mem_allocate(this%strt, this%nlakes,
'STRT', this%memoryPath)
599 call mem_allocate(this%laketop, this%nlakes,
'LAKETOP', this%memoryPath)
600 call mem_allocate(this%lakebot, this%nlakes,
'LAKEBOT', this%memoryPath)
601 call mem_allocate(this%sareamax, this%nlakes,
'SAREAMAX', this%memoryPath)
604 call mem_setptr(this%stage,
'STAGE', this%input_mempath)
605 call mem_setptr(this%rainfall,
'RAINFALL', this%input_mempath)
606 call mem_setptr(this%evaporation,
'EVAPORATION', this%input_mempath)
607 call mem_setptr(this%runoff,
'RUNOFF', this%input_mempath)
608 call mem_setptr(this%inflow,
'INFLOW', this%input_mempath)
609 call mem_setptr(this%withdrawal,
'WITHDRAWAL', this%input_mempath)
610 call mem_allocate(this%avail, this%nlakes,
'AVAIL', this%memoryPath)
611 call mem_allocate(this%lkgwsink, this%nlakes,
'LKGWSINK', this%memoryPath)
612 call mem_allocate(this%ncncvr, this%nlakes,
'NCNCVR', this%memoryPath)
613 call mem_allocate(this%ilegacy, this%nlakes,
'ILEGACY', this%memoryPath)
614 call mem_allocate(this%nstuck, this%nlakes,
'NSTUCK', this%memoryPath)
615 call mem_allocate(this%surfin, this%nlakes,
'SURFIN', this%memoryPath)
616 call mem_allocate(this%surfout, this%nlakes,
'SURFOUT', this%memoryPath)
617 call mem_allocate(this%surfout1, this%nlakes,
'SURFOUT1', this%memoryPath)
618 call mem_allocate(this%precip, this%nlakes,
'PRECIP', this%memoryPath)
619 call mem_allocate(this%precip1, this%nlakes,
'PRECIP1', this%memoryPath)
620 call mem_allocate(this%evap, this%nlakes,
'EVAP', this%memoryPath)
621 call mem_allocate(this%evap1, this%nlakes,
'EVAP1', this%memoryPath)
622 call mem_allocate(this%evapo, this%nlakes,
'EVAPO', this%memoryPath)
623 call mem_allocate(this%withr, this%nlakes,
'WITHR', this%memoryPath)
624 call mem_allocate(this%withr1, this%nlakes,
'WITHR1', this%memoryPath)
625 call mem_allocate(this%flwin, this%nlakes,
'FLWIN', this%memoryPath)
626 call mem_allocate(this%flwiter, this%nlakes,
'FLWITER', this%memoryPath)
627 call mem_allocate(this%flwiter1, this%nlakes,
'FLWITER1', this%memoryPath)
628 call mem_allocate(this%seep, this%nlakes,
'SEEP', this%memoryPath)
629 call mem_allocate(this%seep1, this%nlakes,
'SEEP1', this%memoryPath)
630 call mem_allocate(this%seep0, this%nlakes,
'SEEP0', this%memoryPath)
631 call mem_allocate(this%stageiter, this%nlakes,
'STAGEITER', this%memoryPath)
632 call mem_allocate(this%chterm, this%nlakes,
'CHTERM', this%memoryPath)
638 if (this%iimplicit == 0)
then
639 call mem_allocate(this%iboundpak, this%nlakes,
'IBOUND', this%memoryPath)
640 call mem_allocate(this%xnewpak, this%nlakes,
'XNEWPAK', this%memoryPath)
642 call mem_allocate(this%xoldpak, this%nlakes,
'XOLDPAK', this%memoryPath)
645 call mem_allocate(this%iseepc, this%nlakes,
'ISEEPC', this%memoryPath)
646 call mem_allocate(this%idhc, this%nlakes,
'IDHC', this%memoryPath)
647 call mem_allocate(this%en1, this%nlakes,
'EN1', this%memoryPath)
648 call mem_allocate(this%en2, this%nlakes,
'EN2', this%memoryPath)
649 call mem_allocate(this%r1, this%nlakes,
'R1', this%memoryPath)
650 call mem_allocate(this%r2, this%nlakes,
'R2', this%memoryPath)
651 call mem_allocate(this%dh0, this%nlakes,
'DH0', this%memoryPath)
652 call mem_allocate(this%s0, this%nlakes,
'S0', this%memoryPath)
653 call mem_allocate(this%qgwf0, this%nlakes,
'QGWF0', this%memoryPath)
656 allocate (this%lakename(this%nlakes))
657 allocate (this%status(this%nlakes))
660 do n = 1, this%nlakes
662 this%status(n) =
'ACTIVE'
663 this%laketop(n) = -
dep20
664 this%lakebot(n) =
dep20
665 this%sareamax(n) =
dzero
670 if (this%iimplicit == 0)
then
671 this%iboundpak(n) = 1
672 this%xnewpak(n) =
dep20
674 this%xoldpak(n) =
dep20
675 this%rainfall(n) =
dzero
676 this%evaporation(n) =
dzero
677 this%runoff(n) =
dzero
678 this%inflow(n) =
dzero
679 this%withdrawal(n) =
dzero
685 call mem_setptr(ifno,
'PACKAGEDATA_IFNO', this%input_mempath)
686 call mem_setptr(strt,
'STRT', this%input_mempath)
687 call mem_setptr(nlakeconn,
'NLAKECONN', this%input_mempath)
688 if (this%inamedbound /= 0)
then
689 call mem_setptr(boundname_cst,
'BOUNDNAME', this%input_mempath)
693 allocate (nboundchk(this%nlakes))
698 do n = 1, this%nlakes
701 ilak = this%validate_ifno(ifno(n), this%nlakes, nboundchk, &
702 'lakeno',
'PACKAGEDATA')
706 this%strt(ilak) = strt(n)
709 if (nlakeconn(n) < 0)
then
710 write (
errmsg,
'(a,1x,i0)')
'nlakeconn MUST BE >= 0 for lake ', ilak
717 if (this%iimplicit /= 0 .and. nlakeconn(n) == 0)
then
718 write (
errmsg,
'(a,1x,i0,1x,a)') &
719 'lake', ilak,
'has no connections; the IMPLICIT option requires &
720 &each lake to have at least one GWF connection.'
724 nconn = nconn + nlakeconn(n)
725 this%nlakeconn(ilak) = nlakeconn(n)
728 write (cno,
'(i9.9)') ilak
729 bndname =
'Lake'//cno
732 if (this%inamedbound /= 0)
then
733 bndname = boundname_cst(n)
734 if (trim(bndname) ==
'')
then
735 write (cno,
'(i9.9)') ilak
736 bndname =
'Lake'//cno
739 this%lakename(ilak) = bndname
743 call this%report_ifno_coverage(nboundchk, this%nlakes,
'lake', &
746 write (this%iout,
'(1x,a)')
'END OF '//trim(adjustl(this%text))// &
755 this%MAXBOUND = nconn
756 write (this%iout,
'(//4x,a,i7)')
'MAXBOUND = ', this%maxbound
759 this%idxlakeconn(1) = 1
760 do n = 1, this%nlakes
761 this%idxlakeconn(n + 1) = this%idxlakeconn(n) + this%nlakeconn(n)
765 deallocate (nboundchk)
772 end subroutine lak_source_packagedata
776 subroutine lak_source_connectiondata(this)
778 class(laktype),
intent(inout) :: this
780 integer(I4B) :: n, j, ipos, nn
781 integer(I4B) :: ilak, iconn
782 integer(I4B) :: ipos0, icellid0, icellid, nn2
783 logical(LGP) :: is_lake_bed
784 character(len=LINELENGTH) :: cellid_str
785 character(len=LINELENGTH) :: ctypenm
786 character(len=LINELENGTH) :: cbleak
787 real(DP) :: top, bot, rval
788 integer(I4B),
dimension(:),
pointer,
contiguous :: ifno => null()
789 integer(I4B),
dimension(:),
pointer,
contiguous :: iconns => null()
790 integer(I4B),
dimension(:, :),
pointer,
contiguous :: cellid => null()
795 real(DP),
dimension(:),
pointer,
contiguous :: belev => null()
796 real(DP),
dimension(:),
pointer,
contiguous :: telev => null()
797 real(DP),
dimension(:),
pointer,
contiguous :: connlen => null()
798 real(DP),
dimension(:),
pointer,
contiguous :: connwidth => null()
799 integer(I4B),
allocatable :: nboundchk(:)
802 call mem_allocate(this%imap, this%MAXBOUND,
'IMAP', this%memoryPath)
803 call mem_allocate(this%gwfconn, this%MAXBOUND,
'GWFCONN', this%memoryPath)
804 call mem_allocate(this%nodesontop, this%MAXBOUND,
'NODESONTOP', &
806 call mem_allocate(this%ictype, this%MAXBOUND,
'ICTYPE', this%memoryPath)
807 call mem_allocate(this%bedleak, this%MAXBOUND,
'BEDLEAK', this%memoryPath)
808 call mem_allocate(this%belev, this%MAXBOUND,
'BELEV', this%memoryPath)
809 call mem_allocate(this%telev, this%MAXBOUND,
'TELEV', this%memoryPath)
810 call mem_allocate(this%connlength, this%MAXBOUND,
'CONNLENGTH', &
812 call mem_allocate(this%connwidth, this%MAXBOUND,
'CONNWIDTH', &
814 call mem_allocate(this%sarea, this%MAXBOUND,
'SAREA', this%memoryPath)
815 call mem_allocate(this%warea, this%MAXBOUND,
'WAREA', this%memoryPath)
816 call mem_allocate(this%satcond, this%MAXBOUND,
'SATCOND', this%memoryPath)
817 call mem_allocate(this%simcond, this%MAXBOUND,
'SIMCOND', this%memoryPath)
818 call mem_allocate(this%simlakgw, this%MAXBOUND,
'SIMLAKGW', this%memoryPath)
820 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text))// &
824 call mem_setptr(ifno,
'CONNDATA_IFNO', this%input_mempath)
825 call mem_setptr(iconns,
'ICONN', this%input_mempath)
826 call mem_setptr(cellid,
'CELLID', this%input_mempath)
827 call mem_setptr(claktype,
'CLAKTYPE', this%input_mempath)
828 call mem_setptr(bedleak,
'BEDLEAK', this%input_mempath)
829 call mem_setptr(belev,
'BELEV', this%input_mempath)
830 call mem_setptr(telev,
'TELEV', this%input_mempath)
831 call mem_setptr(connlen,
'CONNLEN', this%input_mempath)
832 call mem_setptr(connwidth,
'CONNWIDTH', this%input_mempath)
835 allocate (nboundchk(this%MAXBOUND))
838 do n = 1, this%MAXBOUND
843 if (ilak < 1 .or. ilak > this%nlakes)
then
844 write (
errmsg,
'(a,1x,i0)')
'lakeno MUST BE > 0 and <= ', this%nlakes
848 if (iconn < 1 .or. iconn > this%nlakeconn(ilak))
then
849 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
850 'iconn FOR LAKE ', ilak,
'MUST BE > 0 and <= ', this%nlakeconn(ilak)
855 ipos = this%idxlakeconn(ilak) + iconn - 1
856 this%imap(ipos) = ilak
857 nboundchk(ipos) = nboundchk(ipos) + 1
860 write (cellid_str,
'(10(i0,1x))') cellid(1:this%dis%ndim, n)
861 nn = this%dis%noder_from_cellid(cellid_str, this%inunit, this%iout)
863 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
864 'INVALID cellid FOR LAKE ', ilak,
'connection', iconn
867 this%gwfconn(ipos) = nn
868 this%nodesontop(ipos) = nn
871 ctypenm = claktype(n)
872 select case (trim(ctypenm))
874 this%ictype(ipos) = 0
876 this%ictype(ipos) = 1
878 this%ictype(ipos) = 2
880 this%ictype(ipos) = 3
882 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,a,a)') &
883 'UNKNOWN ctype FOR LAKE ', ilak,
'connection', iconn, &
884 '(', trim(ctypenm),
')'
890 select case (trim(cbleak))
892 is_lake_bed = .false.
894 write (
warnmsg,
'(2(a,1x,i0,1x),a,1pe8.1,a)') &
895 'BEDLEAK for connection', iconn,
'in lake', ilak, &
896 'is specified to be NONE. Lake connections where the lake-GWF '// &
897 'connection conductance is solely a function of aquifer '// &
898 'properties in the connected GWF cell should be specified '// &
899 'with a DNODATA (',
dnodata,
') value.'
903 read (cbleak, *) rval
905 is_lake_bed = .false.
910 this%bedleak(ipos) = rval
911 if (is_lake_bed .and. this%bedleak(ipos) <
dzero)
then
912 write (
errmsg,
'(a,1x,i0,1x,a)')
'bedleak FOR LAKE ', ilak, &
918 this%belev(ipos) = belev(n)
921 this%telev(ipos) = telev(n)
925 if (rval <=
dzero)
then
926 if (this%ictype(ipos) == 1 .or. this%ictype(ipos) == 2 .or. &
927 this%ictype(ipos) == 3)
then
928 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,a,1x,a)') &
929 'connection length (connlen) FOR LAKE ', ilak, &
930 ', CONNECTION NO.', iconn,
', MUST BE > 0 FOR SPECIFIED ', &
931 'connection type (ctype)', trim(ctypenm)
937 this%connlength(ipos) = rval
941 if (rval <
dzero)
then
942 if (this%ictype(ipos) == 1)
then
943 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a)') &
944 'cell width (connwidth) FOR LAKE ', ilak, &
945 ' HORIZONTAL CONNECTION ', iconn,
'MUST BE >= 0'
951 this%connwidth(ipos) = rval
954 write (this%iout,
'(1x,a)') &
955 'END OF '//trim(adjustl(this%text))//
' CONNECTIONDATA'
963 do n = 1, this%nlakes
965 do ipos = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
966 if (this%ictype(ipos) /= 2 .and. this%ictype(ipos) /= 3) cycle
969 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a)') &
970 'nlakeconn FOR LAKE', n,
'EMBEDDED CONNECTION', j,
' EXCEEDS 1.'
977 do n = 1, this%nlakes
978 ipos0 = this%idxlakeconn(n)
979 icellid0 = this%gwfconn(ipos0)
980 if (this%ictype(ipos0) /= 2 .and. this%ictype(ipos0) /= 3) cycle
981 do nn2 = 1, this%nlakes
984 do ipos = this%idxlakeconn(nn2), this%idxlakeconn(nn2 + 1) - 1
986 icellid = this%gwfconn(ipos)
987 if (icellid == icellid0)
then
988 if (this%ictype(ipos) == 0)
then
989 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
990 'EMBEDDED LAKE', n, &
991 'CANNOT COINCIDE WITH VERTICAL CONNECTION', j, &
1001 do n = 1, this%nlakes
1003 do ipos = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1005 nn = this%gwfconn(ipos)
1006 top = this%dis%top(nn)
1007 bot = this%dis%bot(nn)
1008 if (this%ictype(ipos) == 0)
then
1009 this%telev(ipos) = top + this%surfdep
1010 this%belev(ipos) = top
1011 this%lakebot(n) = min(this%belev(ipos), this%lakebot(n))
1012 else if (this%ictype(ipos) == 1)
then
1013 if (this%belev(ipos) == this%telev(ipos))
then
1014 this%telev(ipos) = top
1015 this%belev(ipos) = bot
1017 if (this%belev(ipos) >= this%telev(ipos))
then
1018 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a)') &
1019 'telev FOR LAKE ', n,
' HORIZONTAL CONNECTION ', j, &
1022 else if (this%belev(ipos) < bot)
then
1023 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.7,1x,a)') &
1024 'belev FOR LAKE ', n,
' HORIZONTAL CONNECTION ', j, &
1025 'MUST BE >= cell bottom (', bot,
')'
1027 else if (this%telev(ipos) > top)
then
1028 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.7,1x,a)') &
1029 'telev FOR LAKE ', n,
' HORIZONTAL CONNECTION ', j, &
1030 'MUST BE <= cell top (', top,
')'
1034 this%laketop(n) = max(this%telev(ipos), this%laketop(n))
1035 this%lakebot(n) = min(this%belev(ipos), this%lakebot(n))
1036 else if (this%ictype(ipos) == 2 .or. this%ictype(ipos) == 3)
then
1037 this%telev(ipos) = top
1038 this%belev(ipos) = bot
1039 this%lakebot(n) = bot
1043 if (nboundchk(ipos) == 0)
then
1044 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1045 'NO DATA SPECIFIED FOR LAKE', n,
'CONNECTION', j
1047 else if (nboundchk(ipos) > 1)
then
1048 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1049 'DATA FOR LAKE', n,
'CONNECTION', j, &
1050 'SPECIFIED', nboundchk(ipos),
'TIMES'
1054 if (this%laketop(n) == -
dep20)
then
1055 this%laketop(n) = this%lakebot(n) + 100.
1059 deallocate (nboundchk)
1075 end subroutine lak_source_connectiondata
1079 subroutine lak_source_tables(this)
1081 class(laktype),
intent(inout) :: this
1083 integer(I4B) :: n, ntabs
1084 integer(I4B) :: ilak, iconn
1085 character(len=LENMEMPATH) :: mempath
1086 integer(I4B),
dimension(:),
pointer,
contiguous :: ifno => null()
1088 laktab6_mempaths => null()
1089 type(laktabtype),
dimension(:),
allocatable :: laketables
1090 integer(I4B),
allocatable :: nboundchk(:)
1093 if (this%ntables < 1)
return
1096 call get_isize(
'TABLES_IFNO', this%input_mempath, ntabs)
1099 'NTABLES > 0 BUT A TABLES BLOCK WAS NOT FOUND IN THE LAK INPUT.'
1103 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text))// &
1107 call mem_setptr(ifno,
'TABLES_IFNO', this%input_mempath)
1108 call mem_setptr(laktab6_mempaths,
'LAKTAB6_MEMPATH', this%input_mempath)
1113 allocate (laketables(this%nlakes))
1114 allocate (nboundchk(this%nlakes))
1118 ilak = this%validate_ifno(ifno(n), this%nlakes, nboundchk, &
1120 if (ilak == 0) cycle
1121 mempath = laktab6_mempaths(n)
1122 call this%lak_source_table(ilak, mempath, laketables(ilak))
1125 write (this%iout,
'(1x,a)')
'END OF '//trim(adjustl(this%text))//
' TABLES'
1128 if (ntabs < this%ntables)
then
1129 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1130 'TABLE DATA ARE SPECIFIED', ntabs, &
1131 'TIMES BUT NTABLES IS SET TO', this%ntables
1135 do n = 1, this%nlakes
1136 if (this%ntabrow(n) == 0) nboundchk(n) = 0
1138 call this%report_ifno_coverage(nboundchk, this%nlakes,
'lakeno', &
1139 'TABLES', check_missing=.false.)
1141 deallocate (nboundchk)
1151 call this%laktables_to_vectors(laketables)
1154 do n = 1, this%nlakes
1155 if (this%ntabrow(n) > 0)
then
1156 deallocate (laketables(n)%tabstage)
1157 deallocate (laketables(n)%tabvolume)
1158 deallocate (laketables(n)%tabsarea)
1159 iconn = this%idxlakeconn(n)
1160 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1161 deallocate (laketables(n)%tabwarea)
1165 deallocate (laketables)
1166 end subroutine lak_source_tables
1171 subroutine laktables_to_vectors(this, laketables)
1172 class(laktype),
intent(inout) :: this
1173 type(laktabtype),
intent(in),
dimension(:),
contiguous :: laketables
1175 integer(I4B) :: ntabrows
1177 integer(I4B) :: ipos
1178 integer(I4B) :: iconn
1181 call mem_allocate(this%ialaktab, this%nlakes + 1,
'IALAKTAB', this%memoryPath)
1184 this%ialaktab(1) = 1
1185 do n = 1, this%nlakes
1187 this%ialaktab(n + 1) = this%ialaktab(n) + this%ntabrow(n)
1191 ntabrows = this%ialaktab(this%nlakes + 1) - 1
1192 call mem_allocate(this%tabstage, ntabrows,
'TABSTAGE', this%memoryPath)
1193 call mem_allocate(this%tabvolume, ntabrows,
'TABVOLUME', this%memoryPath)
1194 call mem_allocate(this%tabsarea, ntabrows,
'TABSAREA', this%memoryPath)
1195 call mem_allocate(this%tabwarea, ntabrows,
'TABWAREA', this%memoryPath)
1198 do n = 1, this%nlakes
1200 do ipos = this%ialaktab(n), this%ialaktab(n + 1) - 1
1201 this%tabstage(ipos) = laketables(n)%tabstage(j)
1202 this%tabvolume(ipos) = laketables(n)%tabvolume(j)
1203 this%tabsarea(ipos) = laketables(n)%tabsarea(j)
1204 iconn = this%idxlakeconn(n)
1205 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1208 this%tabwarea(ipos) = laketables(n)%tabwarea(j)
1210 this%tabwarea(ipos) =
dzero
1215 end subroutine laktables_to_vectors
1219 subroutine lak_source_table(this, ilak, mempath, laketable)
1221 class(laktype),
intent(inout) :: this
1222 integer(I4B),
intent(in) :: ilak
1223 character(len=*),
intent(in) :: mempath
1224 type(laktabtype),
intent(inout) :: laketable
1226 integer(I4B),
pointer :: nrow => null()
1227 integer(I4B),
pointer :: ncol => null()
1228 real(DP),
dimension(:),
pointer,
contiguous :: stage => null()
1229 real(DP),
dimension(:),
pointer,
contiguous :: volume => null()
1230 real(DP),
dimension(:),
pointer,
contiguous :: sarea => null()
1231 real(DP),
dimension(:),
pointer,
contiguous :: barea => null()
1232 character(len=:),
pointer :: tabfname => null()
1233 integer(I4B) :: jmin, iconn, n, nerr0
1234 real(DP) :: vol, sa, wa, v, v0
1236 character(len=*),
parameter :: fmttaberr = &
1237 &
'(a,1x,i0,1x,a,1x,g15.6,1x,a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.6,1x,a)'
1240 call mem_setptr(tabfname,
'INPUT_FNAME', mempath)
1248 write (
errmsg,
'(a,1x,i0)') &
1249 'LAKE TABLE NROW MUST BE > 0 FOR LAKE', ilak
1253 iconn = this%idxlakeconn(ilak)
1254 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1259 if (ncol < jmin)
then
1260 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1261 'LAKE TABLE NCOL MUST BE >=', jmin,
'FOR LAKE', ilak
1273 this%ntabrow(ilak) = nrow
1274 allocate (laketable%tabstage(nrow))
1275 allocate (laketable%tabvolume(nrow))
1276 allocate (laketable%tabsarea(nrow))
1280 laketable%tabstage = stage
1281 laketable%tabvolume = volume
1282 laketable%tabsarea = sarea
1283 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1284 allocate (laketable%tabwarea(nrow))
1286 laketable%tabwarea = barea
1290 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1291 do n = 1, this%ntabrow(ilak)
1292 vol = laketable%tabvolume(n)
1293 sa = laketable%tabsarea(n)
1294 wa = laketable%tabwarea(n)
1297 if (vol >
dzero)
exit
1299 this%lakebot(ilak) = laketable%tabstage(n)
1300 this%belev(ilak) = laketable%tabstage(n)
1303 n = this%ntabrow(ilak)
1304 this%sareamax(ilak) = laketable%tabsarea(n)
1308 do n = 2, this%ntabrow(ilak)
1309 v = laketable%tabstage(n)
1310 v0 = laketable%tabstage(n - 1)
1312 write (
errmsg, fmttaberr) &
1313 'TABLE STAGE ENTRY', n,
'(', laketable%tabstage(n),
') FOR LAKE ', &
1314 ilak,
'MUST BE GREATER THAN THE PREVIOUS STAGE ENTRY', &
1315 n - 1,
'(', laketable%tabstage(n - 1),
')'
1318 v = laketable%tabvolume(n)
1319 v0 = laketable%tabvolume(n - 1)
1321 write (
errmsg, fmttaberr) &
1322 'TABLE VOLUME ENTRY', n,
'(', laketable%tabvolume(n), &
1324 ilak,
'MUST BE GREATER THAN THE PREVIOUS VOLUME ENTRY', &
1325 n - 1,
'(', laketable%tabvolume(n - 1),
')'
1328 v = laketable%tabsarea(n)
1329 v0 = laketable%tabsarea(n - 1)
1331 write (
errmsg, fmttaberr) &
1332 'TABLE SURFACE AREA ENTRY', n,
'(', &
1333 laketable%tabsarea(n),
') FOR LAKE ', ilak, &
1334 'MUST BE GREATER THAN OR EQUAL TO THE PREVIOUS SURFACE AREA ENTRY', &
1335 n - 1,
'(', laketable%tabsarea(n - 1),
')'
1338 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1339 v = laketable%tabwarea(n)
1340 v0 = laketable%tabwarea(n - 1)
1342 write (
errmsg, fmttaberr) &
1343 'TABLE EXCHANGE AREA ENTRY', n,
'(', &
1344 laketable%tabwarea(n),
') FOR LAKE ', ilak, &
1345 'MUST BE GREATER THAN OR EQUAL TO THE PREVIOUS EXCHANGE AREA '// &
1346 'ENTRY', n - 1,
'(', laketable%tabwarea(n - 1),
')'
1362 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1366 end subroutine lak_source_table
1370 subroutine lak_source_outlets(this)
1372 class(laktype),
intent(inout) :: this
1374 integer(I4B) :: n, isize, ioutlet
1375 character(len=LINELENGTH) :: keyword
1376 integer(I4B),
dimension(:),
pointer,
contiguous :: outletno => null()
1377 integer(I4B),
dimension(:),
pointer,
contiguous :: lakein => null()
1378 integer(I4B),
dimension(:),
pointer,
contiguous :: lakeout => null()
1381 real(DP),
dimension(:),
pointer,
contiguous :: outlets_invert => null()
1382 real(DP),
dimension(:),
pointer,
contiguous :: outlets_width => null()
1383 real(DP),
dimension(:),
pointer,
contiguous :: outlets_rough => null()
1384 real(DP),
dimension(:),
pointer,
contiguous :: outlets_slope => null()
1385 integer(I4B),
allocatable :: nboundchk(:)
1388 if (this%noutlets < 1)
return
1391 call get_isize(
'OUTLETS_OUTLETNO', this%input_mempath, isize)
1394 'NOUTLETS > 0 BUT AN OUTLETS BLOCK WAS NOT FOUND IN THE LAK INPUT.'
1399 call mem_allocate(this%lakein, this%noutlets,
'LAKEIN', this%memoryPath)
1400 call mem_allocate(this%lakeout, this%noutlets,
'LAKEOUT', this%memoryPath)
1401 call mem_allocate(this%iouttype, this%noutlets,
'IOUTTYPE', this%memoryPath)
1404 call mem_setptr(this%outrate,
'RATE', this%input_mempath)
1405 call mem_setptr(this%outinvert,
'INVERT', this%input_mempath)
1406 call mem_setptr(this%outwidth,
'WIDTH', this%input_mempath)
1407 call mem_setptr(this%outrough,
'ROUGH', this%input_mempath)
1408 call mem_setptr(this%outslope,
'SLOPE', this%input_mempath)
1409 call mem_allocate(this%simoutrate, this%noutlets,
'SIMOUTRATE', &
1411 call mem_allocate(this%outlet_invert_set, this%noutlets, &
1412 'INVERT_SET', this%memoryPath)
1413 call mem_allocate(this%outlet_width_set, this%noutlets, &
1414 'WIDTH_SET', this%memoryPath)
1415 call mem_allocate(this%outlet_rough_set, this%noutlets, &
1416 'ROUGH_SET', this%memoryPath)
1417 call mem_allocate(this%outlet_slope_set, this%noutlets, &
1418 'SLOPE_SET', this%memoryPath)
1419 this%outlet_invert_set = .false.
1420 this%outlet_width_set = .false.
1421 this%outlet_rough_set = .false.
1422 this%outlet_slope_set = .false.
1424 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text))// &
1428 call mem_setptr(outletno,
'OUTLETS_OUTLETNO', this%input_mempath)
1429 call mem_setptr(lakein,
'LAKEIN', this%input_mempath)
1430 call mem_setptr(lakeout,
'LAKEOUT', this%input_mempath)
1431 call mem_setptr(couttype,
'COUTTYPE', this%input_mempath)
1432 call mem_setptr(outlets_invert,
'OUTLETS_INVERT', this%input_mempath)
1433 call mem_setptr(outlets_width,
'OUTLETS_WIDTH', this%input_mempath)
1434 call mem_setptr(outlets_rough,
'OUTLETS_ROUGH', this%input_mempath)
1435 call mem_setptr(outlets_slope,
'OUTLETS_SLOPE', this%input_mempath)
1437 allocate (nboundchk(this%noutlets))
1440 do n = 1,
size(outletno)
1441 ioutlet = this%validate_ifno(outletno(n), this%noutlets, &
1442 nboundchk,
'outletno',
'OUTLETS')
1443 if (ioutlet == 0) cycle
1446 if (lakein(n) < 1 .or. lakein(n) > this%nlakes)
then
1447 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1448 'lakein FOR OUTLET ', ioutlet,
'MUST BE > 0 and <= ', this%nlakes
1451 this%lakein(ioutlet) = lakein(n)
1454 if (lakeout(n) < 0 .or. lakeout(n) > this%nlakes)
then
1455 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1456 'lakeout FOR OUTLET ', ioutlet,
'MUST BE >= 0 and <= ', this%nlakes
1459 this%lakeout(ioutlet) = lakeout(n)
1462 keyword = couttype(n)
1463 select case (trim(keyword))
1465 this%iouttype(ioutlet) = 0
1467 this%iouttype(ioutlet) = 1
1469 this%iouttype(ioutlet) = 2
1471 write (
errmsg,
'(a,1x,i0,1x,a,a,a)') &
1472 'UNKNOWN couttype FOR OUTLET ', ioutlet,
'(', trim(keyword),
')'
1477 this%outinvert(ioutlet) = outlets_invert(n)
1478 this%outwidth(ioutlet) = outlets_width(n)
1479 this%outrough(ioutlet) = outlets_rough(n)
1480 this%outslope(ioutlet) = outlets_slope(n)
1483 write (this%iout,
'(1x,a)')
'END OF '//trim(adjustl(this%text))//
' OUTLETS'
1486 call this%report_ifno_coverage(nboundchk, this%noutlets,
'outlet', &
1489 deallocate (nboundchk)
1500 end subroutine lak_source_outlets
1504 subroutine lak_source_dimensions(this)
1506 class(laktype),
intent(inout) :: this
1514 write (this%iout,
'(/1x,a)') &
1515 'PROCESSING '//trim(adjustl(this%text))//
' DIMENSIONS'
1519 call mem_set_value(this%nlakes,
'NLAKES', this%input_mempath, &
1520 found%nlakes, release=.false.)
1521 if (found%nlakes)
write (this%iout,
'(4x,a,i7)')
'NLAKES = ', this%nlakes
1525 call mem_set_value(this%noutlets,
'NOUTLETS', this%input_mempath, &
1526 found%noutlets, release=.false.)
1527 if (found%noutlets)
write (this%iout,
'(4x,a,i7)') &
1528 'NOUTLETS = ', this%noutlets
1531 call mem_set_value(this%ntables,
'NTABLES', this%input_mempath, found%ntables)
1532 if (found%ntables)
write (this%iout,
'(4x,a,i7)')
'NTABLES = ', this%ntables
1534 write (this%iout,
'(1x,a)') &
1535 'END OF '//trim(adjustl(this%text))//
' DIMENSIONS'
1537 if (this%nlakes < 0)
then
1539 'NLAKES WAS NOT SPECIFIED OR WAS SPECIFIED INCORRECTLY.'
1545 if (this%iforceleglak /= 0)
then
1546 if (this%iforceleglak < 1 .or. this%iforceleglak > this%nlakes)
then
1547 write (
errmsg,
'(a,i0,a,i0,a)') &
1548 'DEV_FORCE_LEGACY_LAKE (', this%iforceleglak, &
1549 ') MUST BE BETWEEN 1 AND NLAKES (', this%nlakes,
').'
1557 call this%lak_source_packagedata()
1561 if (this%iimplicit /= 0)
then
1562 this%npakeq = this%nlakes
1571 call this%lak_source_connectiondata()
1574 call this%lak_source_tables()
1577 call this%lak_source_outlets()
1580 call this%define_listlabel()
1583 call this%lak_setup_budobj()
1586 call this%lak_setup_tableobj()
1587 end subroutine lak_source_dimensions
1591 subroutine lak_read_initial_attr(this)
1596 class(laktype),
intent(inout) :: this
1598 integer(I4B) :: j, n
1615 real(DP),
allocatable,
dimension(:) :: clb, caq
1616 character(len=14) :: cbedleak
1617 character(len=14) :: cbedcond
1618 character(len=10),
dimension(0:3) :: ctype
1619 character(len=15) :: nodestr
1621 data ctype(0)/
'VERTICAL '/
1622 data ctype(1)/
'HORIZONTAL'/
1623 data ctype(2)/
'EMBEDDEDH '/
1624 data ctype(3)/
'EMBEDDEDV '/
1627 do n = 1, this%nlakes
1628 this%xnewpak(n) = this%strt(n)
1629 this%stage(n) = this%strt(n)
1633 do n = 1, this%nlakes
1634 if (this%status(n) ==
'CONSTANT')
then
1635 this%iboundpak(n) = -1
1636 else if (this%status(n) ==
'INACTIVE')
then
1637 this%iboundpak(n) = 0
1638 else if (this%status(n) ==
'ACTIVE ')
then
1639 this%iboundpak(n) = 1
1644 if (this%inamedbound /= 0)
then
1645 do n = 1, this%nlakes
1646 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1647 this%boundname(j) = this%lakename(n)
1653 call this%copy_boundname()
1663 allocate (clb(this%MAXBOUND))
1664 allocate (caq(this%MAXBOUND))
1667 do n = 1, this%nlakes
1668 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1669 nn = this%gwfconn(j)
1670 top = this%dis%top(nn)
1671 bot = this%dis%bot(nn)
1673 if (this%ictype(j) == 0)
then
1674 area = this%dis%area(nn)
1675 this%sarea(j) = area
1676 this%warea(j) = area
1677 this%sareamax(n) = this%sareamax(n) + area
1678 if (this%gwfik33 == 0)
then
1683 length = dhalf * (top - bot)
1685 else if (this%ictype(j) == 1)
then
1686 area = (this%telev(j) - this%belev(j)) * this%connwidth(j)
1689 if (top == this%telev(j) .and. bot == this%belev(j))
then
1690 if (this%icelltype(nn) == 0)
then
1691 area = this%gwfsat(nn) * (top - bot) * this%connwidth(j)
1694 this%sarea(j) = dzero
1695 this%warea(j) = area
1696 this%sareamax(n) = this%sareamax(n) + dzero
1698 length = this%connlength(j)
1700 else if (this%ictype(j) == 2)
then
1702 this%sarea(j) = dzero
1703 this%warea(j) = area
1704 this%sareamax(n) = this%sareamax(n) + dzero
1706 length = this%connlength(j)
1708 else if (this%ictype(j) == 3)
then
1710 this%sarea(j) = dzero
1711 this%warea(j) = area
1712 this%sareamax(n) = this%sareamax(n) + dzero
1713 if (this%gwfik33 == 0)
then
1718 length = this%connlength(j)
1720 if (
is_close(this%bedleak(j), dnodata))
then
1722 else if (this%bedleak(j) > dzero)
then
1723 clb(j) = done / this%bedleak(j)
1732 if (
is_close(this%bedleak(j), dnodata))
then
1733 this%satcond(j) = area / caq(j)
1734 else if (clb(j) * caq(j) > dzero)
then
1735 this%satcond(j) = area / (clb(j) + caq(j))
1737 this%satcond(j) = dzero
1743 if (this%iprpak > 0)
then
1744 write (this%iout,
'(//,29x,a,/)') &
1745 'INTERFACE CONDUCTANCE BETWEEN LAKE AND AQUIFER CELLS'
1746 write (this%iout,
'(1x,a)') &
1747 &
' LAKE CONNECTION CONNECTION LAKEBED'// &
1748 &
' C O N D U C T A N C E S '
1749 write (this%iout,
'(1x,a)') &
1750 &
' NUMBER NUMBER CELLID DIRECTION LEAKANCE'// &
1751 &
' LAKEBED AQUIFER COMBINED'
1752 write (this%iout,
"(1x,108('-'))")
1753 do n = 1, this%nlakes
1755 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1758 if (this%ictype(j) == 1)
then
1759 fact = this%telev(j) - this%belev(j)
1760 if (abs(fact) > dzero)
then
1764 nn = this%gwfconn(j)
1765 area = this%warea(j)
1767 if (
is_close(clb(j), dnodata))
then
1770 else if (clb(j) > dzero)
then
1771 c1 = area * fact / clb(j)
1772 write (cbedleak,
'(g14.5)') this%bedleak(j)
1773 write (cbedcond,
'(g14.5)') c1
1775 write (cbedleak,
'(g14.5)') c1
1776 write (cbedcond,
'(g14.5)') c1
1779 if (caq(j) > dzero)
then
1780 c2 = area * fact / caq(j)
1782 call this%dis%noder_to_string(nn, nodestr)
1784 '(1x,i10,1x,i10,1x,a15,1x,a10,2(1x,a14),2(1x,g14.5))') &
1785 n, idx, nodestr, ctype(this%ictype(j)), cbedleak, &
1786 cbedcond, c2, this%satcond(j) * fact
1789 write (this%iout,
"(1x,108('-'))")
1790 write (this%iout,
'(1x,a)') &
1791 'IF VERTICAL CONNECTION, CONDUCTANCE (L^2/T) IS &
1792 &BETWEEN AQUIFER CELL AND OVERLYING LAKE CELL.'
1793 write (this%iout,
'(1x,a)') &
1794 'IF HORIZONTAL CONNECTION, CONDUCTANCES ARE PER &
1795 &UNIT SATURATED THICKNESS (L/T).'
1796 write (this%iout,
'(1x,a)') &
1797 'IF EMBEDDED CONNECTION, CONDUCTANCES ARE PER &
1798 &UNIT EXCHANGE AREA (1/T).'
1803 do n = 1, this%nlakes
1804 write (this%iout,
'(//1x,a,1x,i10)')
'STAGE/VOLUME RELATION FOR LAKE ', n
1805 write (this%iout,
'(/1x,5(a14))')
' STAGE',
' SURFACE AREA', &
1806 &
' WETTED AREA',
' CONDUCTANCE', &
1808 write (this%iout,
"(1x,70('-'))")
1809 dx = (this%laketop(n) - this%lakebot(n)) / 150.
1812 call this%lak_calculate_conductance(n, s, c)
1813 call this%lak_calculate_sarea(n, s, sa)
1814 call this%lak_calculate_warea(n, s, wa, s)
1815 call this%lak_calculate_vol(n, s, v)
1816 write (this%iout,
'(1x,5(E14.5))') s, sa, wa, c, v
1819 write (this%iout,
"(1x,70('-'))")
1821 write (this%iout,
'(//1x,a,1x,i10)')
'STAGE/VOLUME RELATION FOR LAKE ', n
1822 write (this%iout,
'(/1x,4(a14))')
' ',
' ', &
1823 &
' CALCULATED',
' STAGE'
1824 write (this%iout,
'(1x,4(a14))')
' STAGE',
' VOLUME', &
1825 &
' STAGE',
' DIFFERENCE'
1826 write (this%iout,
"(1x,56('-'))")
1827 s = this%lakebot(n) - dx
1829 call this%lak_calculate_vol(n, s, v)
1830 call this%lak_vol2stage(n, v, c)
1831 write (this%iout,
'(1x,4(E14.5))') s, v, c, s - c
1834 write (this%iout,
"(1x,56('-'))")
1839 this%gwfk11 => null()
1840 this%gwfk33 => null()
1841 this%gwfsat => null()
1842 this%gwfik33 => null()
1847 end subroutine lak_read_initial_attr
1853 subroutine lak_linear_interpolation(this, n, x, y, z, v)
1855 class(laktype),
intent(inout) :: this
1856 integer(I4B),
intent(in) :: n
1857 real(DP),
dimension(n),
intent(in) :: x
1858 real(DP),
dimension(n),
intent(in) :: y
1859 real(DP),
intent(in) :: z
1860 real(DP),
intent(inout) :: v
1863 real(DP) :: dx, dydx
1871 else if (z > x(n))
then
1872 dx = x(n) - x(n - 1)
1874 if (abs(dx) >
dzero)
then
1875 dydx = (y(n) - y(n - 1)) / dx
1878 v = y(n) + dydx * dx
1882 dx = x(i) - x(i - 1)
1884 if (z >= x(i - 1) .and. z <= x(i))
then
1885 if (abs(dx) >
dzero)
then
1886 dydx = (y(i) - y(i - 1)) / dx
1889 v = y(i - 1) + dydx * dx
1894 end subroutine lak_linear_interpolation
1898 subroutine lak_calculate_sarea(this, ilak, stage, sarea)
1900 class(laktype),
intent(inout) :: this
1901 integer(I4B),
intent(in) :: ilak
1902 real(DP),
intent(in) :: stage
1903 real(DP),
intent(inout) :: sarea
1906 integer(I4B) :: ifirst
1907 integer(I4B) :: ilast
1914 i = this%ntabrow(ilak)
1916 ifirst = this%ialaktab(ilak)
1917 ilast = this%ialaktab(ilak + 1) - 1
1918 if (stage <= this%tabstage(ifirst))
then
1919 sarea = this%tabsarea(ifirst)
1920 else if (stage >= this%tabstage(ilast))
then
1921 sarea = this%tabsarea(ilast)
1923 call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
1924 this%tabsarea(ifirst:ilast), &
1928 do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
1929 topl = this%telev(i)
1930 botl = this%belev(i)
1932 sa = sat * this%sarea(i)
1936 end subroutine lak_calculate_sarea
1940 subroutine lak_calculate_warea(this, ilak, stage, warea, hin)
1942 class(laktype),
intent(inout) :: this
1943 integer(I4B),
intent(in) :: ilak
1944 real(DP),
intent(in) :: stage
1945 real(DP),
intent(inout) :: warea
1946 real(DP),
optional,
intent(inout) :: hin
1949 integer(I4B) :: igwfnode
1954 do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
1955 if (
present(hin))
then
1958 igwfnode = this%gwfconn(i)
1959 head = this%xnew(igwfnode)
1961 call this%lak_calculate_conn_warea(ilak, i, stage, head, wa)
1964 end subroutine lak_calculate_warea
1968 subroutine lak_calculate_conn_warea(this, ilak, iconn, stage, head, wa)
1970 class(laktype),
intent(inout) :: this
1971 integer(I4B),
intent(in) :: ilak
1972 integer(I4B),
intent(in) :: iconn
1973 real(DP),
intent(in) :: stage
1974 real(DP),
intent(in) :: head
1975 real(DP),
intent(inout) :: wa
1978 integer(I4B) :: ifirst
1979 integer(I4B) :: ilast
1980 integer(I4B) :: node
1987 topl = this%telev(iconn)
1988 botl = this%belev(iconn)
1989 call this%lak_calculate_cond_head(iconn, stage, head, vv)
1990 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1991 if (vv > topl) vv = topl
1992 i = this%ntabrow(ilak)
1993 ifirst = this%ialaktab(ilak)
1994 ilast = this%ialaktab(ilak + 1) - 1
1995 if (vv <= this%tabstage(ifirst))
then
1996 wa = this%tabwarea(ifirst)
1997 else if (vv >= this%tabstage(ilast))
then
1998 wa = this%tabwarea(ilast)
2000 call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
2001 this%tabwarea(ifirst:ilast), &
2005 node = this%gwfconn(iconn)
2007 if (this%icelltype(node) == 0)
then
2013 wa = sat * this%warea(iconn)
2015 end subroutine lak_calculate_conn_warea
2019 subroutine lak_calculate_vol(this, ilak, stage, volume)
2021 class(laktype),
intent(inout) :: this
2022 integer(I4B),
intent(in) :: ilak
2023 real(DP),
intent(in) :: stage
2024 real(DP),
intent(inout) :: volume
2027 integer(I4B) :: ifirst
2028 integer(I4B) :: ilast
2037 i = this%ntabrow(ilak)
2039 ifirst = this%ialaktab(ilak)
2040 ilast = this%ialaktab(ilak + 1) - 1
2041 if (stage <= this%tabstage(ifirst))
then
2042 volume = this%tabvolume(ifirst)
2043 else if (stage >= this%tabstage(ilast))
then
2044 ds = stage - this%tabstage(ilast)
2045 sa = this%tabsarea(ilast)
2046 volume = this%tabvolume(ilast) + ds * sa
2048 call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
2049 this%tabvolume(ifirst:ilast), &
2053 do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2054 topl = this%telev(i)
2055 botl = this%belev(i)
2057 sa = sat * this%sarea(i)
2058 if (stage < botl)
then
2060 else if (stage > botl .and. stage < topl)
then
2061 v = sa * (stage - botl)
2063 v = sa * (topl - botl) + sa * (stage - topl)
2068 end subroutine lak_calculate_vol
2072 subroutine lak_calculate_conductance(this, ilak, stage, conductance)
2074 class(laktype),
intent(inout) :: this
2075 integer(I4B),
intent(in) :: ilak
2076 real(DP),
intent(in) :: stage
2077 real(DP),
intent(inout) :: conductance
2083 do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2084 call this%lak_calculate_conn_conductance(ilak, i, stage, stage, c)
2085 conductance = conductance + c
2087 end subroutine lak_calculate_conductance
2093 subroutine lak_calculate_cond_head(this, iconn, stage, head, vv)
2095 class(laktype),
intent(inout) :: this
2096 integer(I4B),
intent(in) :: iconn
2097 real(DP),
intent(in) :: stage
2098 real(DP),
intent(in) :: head
2099 real(DP),
intent(inout) :: vv
2106 topl = this%telev(iconn)
2107 botl = this%belev(iconn)
2108 ss = min(stage, topl)
2109 hh = min(head, topl)
2110 if (this%igwhcopt > 0)
then
2112 else if (this%inewton > 0)
then
2115 vv =
dhalf * (ss + hh)
2117 end subroutine lak_calculate_cond_head
2122 subroutine lak_calculate_conn_conductance(this, ilak, iconn, stage, head, cond)
2124 class(laktype),
intent(inout) :: this
2125 integer(I4B),
intent(in) :: ilak
2126 integer(I4B),
intent(in) :: iconn
2127 real(DP),
intent(in) :: stage
2128 real(DP),
intent(in) :: head
2129 real(DP),
intent(inout) :: cond
2131 integer(I4B) :: node
2139 real(DP) :: vscratio
2143 topl = this%telev(iconn)
2144 botl = this%belev(iconn)
2145 call this%lak_calculate_cond_head(iconn, stage, head, vv)
2150 if (this%ictype(iconn) == 0)
then
2151 if (abs(topl - botl) <
dprec)
then
2156 else if (this%ictype(iconn) == 1)
then
2157 node = this%gwfconn(iconn)
2158 if (this%icelltype(node) == 0)
then
2162 else if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
2163 node = this%gwfconn(iconn)
2164 if (this%icelltype(node) == 0)
then
2165 vv = this%telev(iconn)
2166 call this%lak_calculate_conn_warea(ilak, iconn, vv, vv, wa)
2168 call this%lak_calculate_conn_warea(ilak, iconn, stage, head, wa)
2174 if (this%ivsc == 1)
then
2176 if (stage > head)
then
2177 vscratio = this%viscratios(1, iconn)
2180 vscratio = this%viscratios(2, iconn)
2183 cond = sat * this%satcond(iconn) * vscratio
2184 end subroutine lak_calculate_conn_conductance
2188 subroutine lak_calculate_exchange(this, ilak, stage, totflow)
2190 class(laktype),
intent(inout) :: this
2191 integer(I4B),
intent(in) :: ilak
2192 real(DP),
intent(in) :: stage
2193 real(DP),
intent(inout) :: totflow
2196 integer(I4B) :: igwfnode
2201 do j = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2202 igwfnode = this%gwfconn(j)
2203 hgwf = this%xnew(igwfnode)
2204 call this%lak_calculate_conn_exchange(ilak, j, stage, hgwf, flow)
2205 totflow = totflow + flow
2207 end subroutine lak_calculate_exchange
2212 subroutine lak_calculate_conn_exchange(this, ilak, iconn, stage, head, flow, &
2215 class(laktype),
intent(inout) :: this
2216 integer(I4B),
intent(in) :: ilak
2217 integer(I4B),
intent(in) :: iconn
2218 real(DP),
intent(in) :: stage
2219 real(DP),
intent(in) :: head
2220 real(DP),
intent(inout) :: flow
2221 real(DP),
intent(inout),
optional :: gwfhcof
2222 real(DP),
intent(inout),
optional :: gwfrhs
2228 real(DP) :: gwfhcof0
2232 call this%lak_calculate_conn_conductance(ilak, iconn, stage, head, cond)
2233 botl = this%belev(iconn)
2236 if (stage >= botl)
then
2243 if (head >= botl)
then
2250 flow = cond * (hh - ss)
2253 if (head >= botl)
then
2255 gwfrhs0 = -cond * ss
2262 if (this%idense /= 0)
then
2263 call this%lak_calculate_density_exchange(iconn, stage, head, cond, botl, &
2264 flow, gwfhcof0, gwfrhs0)
2268 if (
present(gwfhcof)) gwfhcof = gwfhcof0
2269 if (
present(gwfrhs)) gwfrhs = gwfrhs0
2270 end subroutine lak_calculate_conn_exchange
2281 subroutine lak_calculate_conn_exchange_deriv(this, ilak, iconn, stage, &
2282 head, flow, dqds, dqdh)
2284 class(laktype),
intent(inout) :: this
2285 integer(I4B),
intent(in) :: ilak
2286 integer(I4B),
intent(in) :: iconn
2287 real(DP),
intent(in) :: stage
2288 real(DP),
intent(in) :: head
2289 real(DP),
intent(inout) :: flow
2290 real(DP),
intent(inout),
optional :: dqds
2291 real(DP),
intent(inout),
optional :: dqdh
2293 real(DP) :: cond, botl, dps, dph, ss, hh
2295 call this%lak_calculate_conn_conductance(ilak, iconn, stage, head, cond)
2296 botl = this%belev(iconn)
2297 if (stage >= botl)
then
2304 if (head >= botl)
then
2311 flow = cond * (hh - ss)
2312 if (
present(dqds)) dqds = -cond * dps
2313 if (
present(dqdh)) dqdh = cond * dph
2314 end subroutine lak_calculate_conn_exchange_deriv
2319 subroutine lak_estimate_conn_exchange(this, iflag, ilak, iconn, idry, stage, &
2320 head, flow, source, gwfhcof, gwfrhs)
2322 class(laktype),
intent(inout) :: this
2323 integer(I4B),
intent(in) :: iflag
2324 integer(I4B),
intent(in) :: ilak
2325 integer(I4B),
intent(in) :: iconn
2326 integer(I4B),
intent(inout) :: idry
2327 real(DP),
intent(in) :: stage
2328 real(DP),
intent(in) :: head
2329 real(DP),
intent(inout) :: flow
2330 real(DP),
intent(inout) :: source
2331 real(DP),
intent(inout),
optional :: gwfhcof
2332 real(DP),
intent(inout),
optional :: gwfrhs
2334 real(DP) :: gwfhcof0, gwfrhs0
2338 call this%lak_calculate_conn_exchange(ilak, iconn, stage, head, flow, &
2340 if (iflag == 1)
then
2341 if (flow >
dzero)
then
2342 source = source + flow
2344 else if (iflag == 2)
then
2345 if (-flow > source)
then
2349 else if (flow <
dzero)
then
2350 source = source + flow
2355 if (
present(gwfhcof)) gwfhcof = gwfhcof0
2356 if (
present(gwfrhs)) gwfrhs = gwfrhs0
2357 end subroutine lak_estimate_conn_exchange
2362 subroutine lak_calculate_storagechange(this, ilak, stage, stage0, delt, dvr)
2364 class(laktype),
intent(inout) :: this
2365 integer(I4B),
intent(in) :: ilak
2366 real(DP),
intent(in) :: stage
2367 real(DP),
intent(in) :: stage0
2368 real(DP),
intent(in) :: delt
2369 real(DP),
intent(inout) :: dvr
2375 if (this%gwfiss /= 1)
then
2376 call this%lak_calculate_vol(ilak, stage, v)
2377 call this%lak_calculate_vol(ilak, stage0, v0)
2378 dvr = (v0 - v) / delt
2380 end subroutine lak_calculate_storagechange
2384 subroutine lak_calculate_rainfall(this, ilak, stage, ra)
2386 class(laktype),
intent(inout) :: this
2387 integer(I4B),
intent(in) :: ilak
2388 real(DP),
intent(in) :: stage
2389 real(DP),
intent(inout) :: ra
2391 integer(I4B) :: iconn
2395 iconn = this%idxlakeconn(ilak)
2396 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
2397 sa = this%sareamax(ilak)
2399 call this%lak_calculate_sarea(ilak, stage, sa)
2401 ra = this%rainfall(ilak) * sa
2402 end subroutine lak_calculate_rainfall
2406 subroutine lak_calculate_runoff(this, ilak, ro)
2408 class(laktype),
intent(inout) :: this
2409 integer(I4B),
intent(in) :: ilak
2410 real(DP),
intent(inout) :: ro
2413 ro = this%runoff(ilak)
2414 end subroutine lak_calculate_runoff
2418 subroutine lak_calculate_inflow(this, ilak, qin)
2420 class(laktype),
intent(inout) :: this
2421 integer(I4B),
intent(in) :: ilak
2422 real(DP),
intent(inout) :: qin
2425 qin = this%inflow(ilak)
2426 end subroutine lak_calculate_inflow
2430 subroutine lak_calculate_external(this, ilak, ex)
2432 class(laktype),
intent(inout) :: this
2433 integer(I4B),
intent(in) :: ilak
2434 real(DP),
intent(inout) :: ex
2439 if (this%imover == 1)
then
2440 ex = this%pakmvrobj%get_qfrommvr(ilak)
2442 end subroutine lak_calculate_external
2446 subroutine lak_calculate_withdrawal(this, ilak, avail, wr)
2448 class(laktype),
intent(inout) :: this
2449 integer(I4B),
intent(in) :: ilak
2450 real(DP),
intent(inout) :: avail
2451 real(DP),
intent(inout) :: wr
2454 wr = this%withdrawal(ilak)
2455 if (wr > avail)
then
2458 if (wr >
dzero)
then
2463 end subroutine lak_calculate_withdrawal
2468 subroutine lak_calculate_evaporation(this, ilak, stage, avail, ev)
2470 class(laktype),
intent(inout) :: this
2471 integer(I4B),
intent(in) :: ilak
2472 real(DP),
intent(in) :: stage
2473 real(DP),
intent(inout) :: avail
2474 real(DP),
intent(inout) :: ev
2479 call this%lak_calculate_sarea(ilak, stage, sa)
2480 ev = sa * this%evaporation(ilak)
2481 if (ev > avail)
then
2491 end subroutine lak_calculate_evaporation
2495 subroutine lak_calculate_outlet_inflow(this, ilak, outinf)
2497 class(laktype),
intent(inout) :: this
2498 integer(I4B),
intent(in) :: ilak
2499 real(DP),
intent(inout) :: outinf
2504 do n = 1, this%noutlets
2505 if (this%lakeout(n) == ilak)
then
2506 outinf = outinf - this%simoutrate(n)
2507 if (this%imover == 1)
then
2508 outinf = outinf - this%pakmvrobj%get_qtomvr(n)
2512 end subroutine lak_calculate_outlet_inflow
2516 subroutine lak_calculate_outlet_outflow(this, ilak, stage, avail, outoutf)
2518 class(laktype),
intent(inout) :: this
2519 integer(I4B),
intent(in) :: ilak
2520 real(DP),
intent(in) :: stage
2521 real(DP),
intent(inout) :: avail
2522 real(DP),
intent(inout) :: outoutf
2532 do n = 1, this%noutlets
2533 if (this%lakein(n) == ilak)
then
2535 d = stage - this%outinvert(n)
2536 if (this%outdmax >
dzero)
then
2537 if (d > this%outdmax) d = this%outdmax
2539 g =
dgravity * this%convlength * this%convtime * this%convtime
2540 select case (this%iouttype(n))
2543 rate = this%outrate(n)
2544 if (-rate > avail)
then
2550 c = (this%convlength**
donethird) * this%convtime
2552 if (this%outrough(n) >
dzero)
then
2553 gsm =
done / this%outrough(n)
2555 rate = -c * gsm * this%outwidth(n) * (d**
dfivethirds) * &
2556 sqrt(this%outslope(n))
2565 this%simoutrate(n) = rate
2566 avail = avail + rate
2567 outoutf = outoutf + rate
2570 end subroutine lak_calculate_outlet_outflow
2580 subroutine lak_outlet_outflow_rate(this, ilak, stage, qout)
2582 class(laktype),
intent(inout) :: this
2583 integer(I4B),
intent(in) :: ilak
2584 real(DP),
intent(in) :: stage
2585 real(DP),
intent(inout) :: qout
2588 real(DP) :: g, d, c, gsm, rate
2591 do n = 1, this%noutlets
2592 if (this%lakein(n) /= ilak) cycle
2594 d = stage - this%outinvert(n)
2595 if (this%outdmax >
dzero .and. d > this%outdmax) d = this%outdmax
2596 g =
dgravity * this%convlength * this%convtime * this%convtime
2597 select case (this%iouttype(n))
2599 rate = this%outrate(n)
2602 c = (this%convlength**
donethird) * this%convtime
2604 if (this%outrough(n) >
dzero) gsm =
done / this%outrough(n)
2605 rate = -c * gsm * this%outwidth(n) * (d**
dfivethirds) * &
2606 sqrt(this%outslope(n))
2615 end subroutine lak_outlet_outflow_rate
2619 subroutine lak_get_internal_inlet(this, ilak, outinf)
2621 class(laktype),
intent(inout) :: this
2622 integer(I4B),
intent(in) :: ilak
2623 real(DP),
intent(inout) :: outinf
2628 do n = 1, this%noutlets
2629 if (this%lakeout(n) == ilak)
then
2630 outinf = outinf - this%simoutrate(n)
2631 if (this%imover == 1)
then
2632 outinf = outinf - this%pakmvrobj%get_qtomvr(n)
2636 end subroutine lak_get_internal_inlet
2640 subroutine lak_get_internal_outlet(this, ilak, outoutf)
2642 class(laktype),
intent(inout) :: this
2643 integer(I4B),
intent(in) :: ilak
2644 real(DP),
intent(inout) :: outoutf
2649 do n = 1, this%noutlets
2650 if (this%lakein(n) == ilak)
then
2651 if (this%lakeout(n) < 1) cycle
2652 outoutf = outoutf + this%simoutrate(n)
2655 end subroutine lak_get_internal_outlet
2659 subroutine lak_get_external_outlet(this, ilak, outoutf)
2661 class(laktype),
intent(inout) :: this
2662 integer(I4B),
intent(in) :: ilak
2663 real(DP),
intent(inout) :: outoutf
2668 do n = 1, this%noutlets
2669 if (this%lakein(n) == ilak)
then
2670 if (this%lakeout(n) > 0) cycle
2671 outoutf = outoutf + this%simoutrate(n)
2674 end subroutine lak_get_external_outlet
2678 subroutine lak_get_external_mover(this, ilak, outoutf)
2680 class(laktype),
intent(inout) :: this
2681 integer(I4B),
intent(in) :: ilak
2682 real(DP),
intent(inout) :: outoutf
2687 if (this%imover == 1)
then
2688 do n = 1, this%noutlets
2689 if (this%lakein(n) == ilak)
then
2690 if (this%lakeout(n) > 0) cycle
2691 outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2695 end subroutine lak_get_external_mover
2699 subroutine lak_get_internal_mover(this, ilak, outoutf)
2701 class(laktype),
intent(inout) :: this
2702 integer(I4B),
intent(in) :: ilak
2703 real(DP),
intent(inout) :: outoutf
2708 if (this%imover == 1)
then
2709 do n = 1, this%noutlets
2710 if (this%lakein(n) == ilak)
then
2711 if (this%lakeout(n) < 1) cycle
2712 outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2716 end subroutine lak_get_internal_mover
2720 subroutine lak_get_outlet_tomover(this, ilak, outoutf)
2722 class(laktype),
intent(inout) :: this
2723 integer(I4B),
intent(in) :: ilak
2724 real(DP),
intent(inout) :: outoutf
2729 if (this%imover == 1)
then
2730 do n = 1, this%noutlets
2731 if (this%lakein(n) == ilak)
then
2732 outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2736 end subroutine lak_get_outlet_tomover
2740 subroutine lak_vol2stage(this, ilak, vol, stage)
2742 class(laktype),
intent(inout) :: this
2743 integer(I4B),
intent(in) :: ilak
2744 real(DP),
intent(in) :: vol
2745 real(DP),
intent(inout) :: stage
2749 real(DP) :: s0, s1, sm
2750 real(DP) :: v0, v1, vm
2751 real(DP) :: f0, f1, fm
2753 real(DP) :: en0, en1
2757 s0 = this%lakebot(ilak)
2758 call this%lak_calculate_vol(ilak, s0, v0)
2759 s1 = this%laketop(ilak)
2760 call this%lak_calculate_vol(ilak, s1, v1)
2765 else if (vol >= v1)
then
2766 call this%lak_calculate_sarea(ilak, s1, sa)
2767 stage = s1 + (vol - v1) / sa
2778 secantbisection:
do i = 1, 150
2780 if (denom /=
dzero)
then
2781 ds = f1 * (s1 - s0) / denom
2789 if (sm < en0 .or. sm > en1) ibs = 13
2793 if (ds * ds0 <
dprec .or. abs(ds) > abs(ds0)) ibs = ibs + 1
2795 ds =
dhalf * (s1 - s0)
2799 if (abs(ds) <
dem6)
then
2800 exit secantbisection
2802 call this%lak_calculate_vol(ilak, sm, vm)
2809 end do secantbisection
2811 if (abs(ds) >=
dem6)
then
2812 write (this%iout,
'(1x,a,1x,i0,4(1x,a,1x,g15.6))') &
2813 &
'LAK_VOL2STAGE failed for lake', ilak,
'volume error =', fm, &
2814 &
'finding stage (', stage,
') for volume =', vol, &
2815 &
'final change in stage =', ds
2818 end subroutine lak_vol2stage
2821 function lak_check_valid(this, itemno)
result(ierr)
2825 integer(I4B) :: ierr
2827 class(laktype),
intent(inout) :: this
2828 integer(I4B),
intent(in) :: itemno
2830 integer(I4B) :: ival
2834 if (itemno > 0)
then
2835 if (ival < 1 .or. ival > this%nlakes)
then
2836 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,a)') &
2837 'LAKENO', itemno,
'must be greater than 0 and less than or equal to', &
2843 if (ival < 1 .or. ival > this%noutlets)
then
2844 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,a)') &
2845 'IOUTLET', itemno,
'must be greater than 0 and less than or equal to', &
2851 end function lak_check_valid
2854 subroutine lak_set_nonneg_value(this, n, itemno, setting, value_array, label)
2856 class(laktype),
intent(inout) :: this
2857 integer(I4B),
intent(in) :: n
2858 integer(I4B),
intent(in) :: itemno
2859 character(len=*),
intent(in) :: setting
2860 real(DP),
dimension(:),
intent(inout) :: value_array
2861 character(len=*),
intent(in) :: label
2863 integer(I4B) :: istat
2865 istat = this%lak_check_valid(itemno)
2866 if (istat /= 0)
return
2867 if (itemno < 1 .or. itemno > this%nlakes)
return
2868 if (value_array(itemno) <
dzero)
then
2869 write (
errmsg,
'(a,i0,a,g0,a)') &
2870 'Lake ', itemno,
' was assigned a '//trim(label)//
' value of ', &
2871 value_array(itemno),
'. Value must be positive.'
2874 end subroutine lak_set_nonneg_value
2878 subroutine lak_set_attribute_error(this, ilak, keyword, msg)
2882 class(laktype),
intent(inout) :: this
2883 integer(I4B),
intent(in) :: ilak
2884 character(len=*),
intent(in) :: keyword
2885 character(len=*),
intent(in) :: msg
2887 if (len(msg) == 0)
then
2888 write (
errmsg,
'(a,1x,a,1x,i0,1x,a)') &
2889 keyword,
' for LAKE', ilak,
'has already been set.'
2891 write (
errmsg,
'(a,1x,a,1x,i0,1x,a)') keyword,
' for LAKE', ilak, msg
2894 end subroutine lak_set_attribute_error
2898 subroutine lak_source_options(this)
2900 class(laktype),
intent(inout) :: this
2903 integer(I4B) :: isize
2904 character(len=LINELENGTH) :: fname
2906 character(len=*),
parameter :: fmtlengthconv = &
2907 &
"(4x, 'LENGTH CONVERSION VALUE (',g15.7,') SPECIFIED.')"
2908 character(len=*),
parameter :: fmttimeconv = &
2909 &
"(4x, 'TIME CONVERSION VALUE (',g15.7,') SPECIFIED.')"
2910 character(len=*),
parameter :: fmtlakeopt = &
2911 &
"(4x, 'LAKE ', a, ' VALUE (',g15.7,') SPECIFIED.')"
2912 character(len=*),
parameter :: fmtoutdmax = &
2913 &
"(4x, 'MAXIMUM OUTLET WATER DEPTH (',g15.7,') SPECIFIED.')"
2914 character(len=*),
parameter :: fmtlakbin = &
2915 "(4x, 'LAK ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', &
2916 &a, /4x, 'OPENED ON UNIT: ', I0)"
2917 character(len=*),
parameter :: fmtiter = &
2918 &
"(4x, 'MAXIMUM LAK ITERATION VALUE (',i0,') SPECIFIED.')"
2919 character(len=*),
parameter :: fmtdmaxchg = &
2920 &
"(4x, 'MAXIMUM STAGE CHANGE VALUE (',g0,') SPECIFIED.')"
2924 call this%BndExtType%source_options()
2926 write (this%iout,
'(1x,a)') &
2927 'PROCESSING '//trim(adjustl(this%text))//
' OPTIONS'
2930 call mem_set_value(this%iprhed,
'PRINT_STAGE', this%input_mempath, &
2932 if (found%print_stage)
then
2933 write (this%iout,
'(4x,a)') trim(adjustl(this%text))// &
2934 ' STAGES WILL BE PRINTED TO LISTING FILE.'
2938 call mem_set_value(fname,
'STAGEFILE', this%input_mempath, found%stagefile)
2939 if (found%stagefile)
then
2941 call openfile(this%istageout, this%iout, fname,
'DATA(BINARY)', &
2943 write (this%iout, fmtlakbin)
'STAGE', trim(adjustl(fname)), this%istageout
2947 call mem_set_value(fname,
'BUDGETFILE', this%input_mempath, found%budgetfile)
2948 if (found%budgetfile)
then
2949 call assign_iounit(this%ibudgetout, this%inunit,
'BUDGET fileout')
2950 call openfile(this%ibudgetout, this%iout, fname,
'DATA(BINARY)', &
2952 write (this%iout, fmtlakbin)
'BUDGET', trim(adjustl(fname)), this%ibudgetout
2956 call mem_set_value(fname,
'BUDGETCSVFILE', this%input_mempath, &
2957 found%budgetcsvfile)
2958 if (found%budgetcsvfile)
then
2959 call assign_iounit(this%ibudcsv, this%inunit,
'BUDGETCSV fileout')
2960 call openfile(this%ibudcsv, this%iout, fname,
'CSV', filstat_opt=
'REPLACE')
2961 write (this%iout, fmtlakbin)
'BUDGET CSV', trim(adjustl(fname)), &
2969 call mem_set_value(fname,
'PKGCONVFNAME', this%input_mempath, &
2971 if (found%pkgconvfname)
then
2972 this%pakcsvfile = trim(adjustl(fname))
2976 call mem_set_value(this%imover,
'MOVER', this%input_mempath, found%mover)
2977 if (found%mover)
then
2978 write (this%iout,
'(4x,A)')
'MOVER OPTION ENABLED'
2982 call mem_set_value(this%convlength,
'CONVLENGTH', this%input_mempath, &
2984 if (found%convlength)
write (this%iout, fmtlengthconv) this%convlength
2987 call mem_set_value(this%convtime,
'CONVTIME', this%input_mempath, &
2989 if (found%convtime)
write (this%iout, fmttimeconv) this%convtime
2992 call mem_set_value(this%surfdep,
'SURFDEP', this%input_mempath, found%surfdep)
2993 if (found%surfdep)
then
2994 if (this%surfdep <
dzero) this%surfdep =
dzero
2995 write (this%iout, fmtlakeopt)
'SURFDEP', this%surfdep
2999 call mem_set_value(this%maxlakit,
'MAXLAKIT', this%input_mempath, &
3001 if (found%maxlakit)
write (this%iout, fmtiter) this%maxlakit
3004 call mem_set_value(this%dmaxchg,
'DMAXCHG', this%input_mempath, found%dmaxchg)
3005 if (found%dmaxchg)
then
3006 this%delh =
dp999 * this%dmaxchg
3007 write (this%iout, fmtdmaxchg) this%dmaxchg
3011 call mem_set_value(this%igwhcopt,
'IGWHCOPT', this%input_mempath, &
3013 if (found%igwhcopt)
then
3014 write (this%iout,
'(4x,a)') &
3015 'CONDUCTANCE FOR HORIZONTAL CONNECTIONS WILL BE CALCULATED &
3016 &USING THE GROUNDWATER HEAD'
3020 call mem_set_value(this%iimplicit,
'IIMPLICIT', this%input_mempath, &
3022 if (found%iimplicit)
then
3023 write (this%iout,
'(4x,a)') &
3024 'LAKE STAGE WILL BE SOLVED AS AN UNKNOWN IN THE GROUNDWATER FLOW '// &
3025 'MATRIX (IMPLICIT FORMULATION)'
3029 call mem_set_value(this%iforceleg,
'IFORCELEG', this%input_mempath, &
3034 call mem_set_value(this%iforceleglak,
'IFORCELEGLAK', this%input_mempath, &
3037 if (found%iforceleg)
then
3038 write (this%iout,
'(4x,a)') &
3039 'EVERY ACTIVE LAKE WILL BE SOLVED WITH THE LEGACY SUBSTITUTION '// &
3040 'SOLVER UNDER THE IMPLICIT FORMULATION'
3041 if (this%iforceleglak /= 0)
then
3042 call store_error(
'DEV_FORCE_LEGACY and DEV_FORCE_LEGACY_LAKE '// &
3043 'cannot both be specified.')
3047 if (found%iforceleglak)
then
3048 write (this%iout,
'(4x,a,i0,a)')
'LAKE ', this%iforceleglak, &
3049 ' WILL BE SOLVED WITH THE LEGACY SUBSTITUTION SOLVER UNDER THE '// &
3050 'IMPLICIT FORMULATION'
3051 if (this%iforceleg /= 0)
then
3052 call store_error(
'DEV_FORCE_LEGACY and DEV_FORCE_LEGACY_LAKE '// &
3053 'cannot both be specified.')
3058 call get_isize(
'ICONVCHK', this%input_mempath, isize)
3061 write (this%iout,
'(4x,a)') &
3062 'A FINAL CONVERGENCE CHECK OF THE CHANGE IN LAKE STAGES &
3067 call mem_set_value(this%outdmax,
'OUTDMAX', this%input_mempath, found%outdmax)
3068 if (found%outdmax)
write (this%iout, fmtoutdmax) this%outdmax
3070 write (this%iout,
'(1x,a)')
'END OF '//trim(adjustl(this%text))//
' OPTIONS'
3071 end subroutine lak_source_options
3078 subroutine lak_input_init(this, mempath, naux, noutlets)
3081 class(lakinputtype),
intent(inout) :: this
3082 character(len=*),
intent(in) :: mempath
3083 integer(I4B),
intent(in) :: naux
3084 integer(I4B),
intent(in) :: noutlets
3087 call mem_setptr(this%nbound,
'NBOUND', mempath)
3089 call mem_setptr(this%setting,
'SETTING', mempath)
3090 call mem_setptr(this%status,
'STATUS', mempath)
3092 call mem_setptr(this%auxname,
'AUXNAME', mempath)
3093 call mem_setptr(this%auxval,
'AUXVAL', mempath)
3096 if (noutlets > 0)
then
3097 call mem_setptr(this%outletno,
'OUTLETS_OUTLETNO', mempath)
3098 call mem_setptr(this%outlets_invert,
'OUTLETS_INVERT', mempath)
3099 call mem_setptr(this%outlets_width,
'OUTLETS_WIDTH', mempath)
3100 call mem_setptr(this%outlets_rough,
'OUTLETS_ROUGH', mempath)
3101 call mem_setptr(this%outlets_slope,
'OUTLETS_SLOPE', mempath)
3103 end subroutine lak_input_init
3107 subroutine lak_input_destroy(this)
3109 class(lakinputtype),
intent(inout) :: this
3111 nullify (this%nbound)
3113 nullify (this%setting)
3114 nullify (this%status)
3115 nullify (this%auxname)
3116 nullify (this%auxval)
3117 nullify (this%outletno)
3118 nullify (this%outlets_invert)
3119 nullify (this%outlets_width)
3120 nullify (this%outlets_rough)
3121 nullify (this%outlets_slope)
3122 end subroutine lak_input_destroy
3128 subroutine lak_ar(this)
3133 class(laktype),
intent(inout) :: this
3135 character(len=*),
parameter :: fmtlakbin = &
3136 "(4x, 'LAK ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', &
3137 &a, /4x, 'OPENED ON UNIT: ', I0)"
3144 if (
allocated(this%pakcsvfile))
then
3145 if (this%iimplicit /= 0)
then
3147 'PACKAGE_CONVERGENCE output file "'//trim(this%pakcsvfile)// &
3148 '" is not written when the IMPLICIT option is active; the lake '// &
3149 'stage is part of the solver (IMS) convergence check.'
3153 call openfile(this%ipakcsv, this%iout, this%pakcsvfile,
'CSV', &
3154 filstat_opt=
'REPLACE', mode_opt=
mnormal)
3155 write (this%iout, fmtlakbin)
'PACKAGE_CONVERGENCE', &
3156 trim(this%pakcsvfile), this%ipakcsv
3158 deallocate (this%pakcsvfile)
3161 call this%obs%obs_ar()
3164 call this%lak_allocate_arrays()
3167 call this%read_initial_attr()
3170 call this%input%init(this%input_mempath, this%naux, this%noutlets)
3173 if (this%imover /= 0)
then
3174 allocate (this%pakmvrobj)
3175 call this%pakmvrobj%ar(this%noutlets, this%nlakes, this%memoryPath)
3177 end subroutine lak_ar
3181 subroutine lak_rp(this)
3186 class(laktype),
intent(inout) :: this
3188 character(len=LINELENGTH) :: str =
' '
3189 real(DP) :: auxvaldbl = dzero
3190 character(len=LINELENGTH) :: title
3191 character(len=LINELENGTH) :: text
3192 character(len=LENVARNAME) :: setting
3193 integer(I4B) :: node, n, j, itemno
3194 integer(I4B) :: istat
3196 character(len=*),
parameter :: fmtlsp = &
3197 &
"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
3200 this%nbound = this%maxbound
3203 if (this%iper ==
kper)
then
3208 if (this%iprpak /= 0)
then
3209 title = trim(adjustl(this%text))//
' PACKAGE ('// &
3210 trim(adjustl(this%packName))//
') DATA FOR PERIOD'
3211 write (title,
'(a,1x,i6)') trim(adjustl(title)),
kper
3212 call table_cr(this%inputtab, this%packName, title)
3213 call this%inputtab%table_df(1, 4, this%iout, finalize=.false.)
3215 call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
3217 call this%inputtab%initialize_column(text, 20, alignment=tableft)
3219 write (text,
'(a,1x,i6)')
'VALUE', n
3220 call this%inputtab%initialize_column(text, 15, alignment=tabcenter)
3225 do n = 1, this%input%nbound
3226 itemno = this%input%ifno(n)
3229 setting = this%input%setting(n)
3233 if (trim(setting) ==
'STATUS')
then
3234 str = this%input%status(n)
3235 istat = this%lak_check_valid(itemno)
3236 if (istat == 0 .and. itemno >= 1 .and. itemno <= this%nlakes)
then
3237 if (trim(str) ==
'CONSTANT')
then
3238 this%iboundpak(itemno) = -1
3239 else if (trim(str) ==
'INACTIVE')
then
3240 this%iboundpak(itemno) = 0
3241 else if (trim(str) ==
'ACTIVE')
then
3242 this%iboundpak(itemno) = 1
3244 write (
errmsg,
'(a,a)') &
3245 'Unknown '//trim(this%text)//
' STATUS keyword: ', &
3249 this%status(itemno) = trim(str)
3254 if (trim(setting) ==
'STAGE')
then
3255 istat = this%lak_check_valid(itemno)
3260 if (trim(setting) ==
'RAINFALL') &
3261 call this%lak_set_nonneg_value(n, itemno, setting, this%rainfall, &
3263 if (trim(setting) ==
'EVAPORATION') &
3264 call this%lak_set_nonneg_value(n, itemno, setting, &
3265 this%evaporation,
'evaporation')
3266 if (trim(setting) ==
'RUNOFF') &
3267 call this%lak_set_nonneg_value(n, itemno, setting, this%runoff, &
3269 if (trim(setting) ==
'INFLOW') &
3270 call this%lak_set_nonneg_value(n, itemno, setting, this%inflow, &
3272 if (trim(setting) ==
'WITHDRAWAL') &
3273 call this%lak_set_nonneg_value(n, itemno, setting, &
3274 this%withdrawal,
'withdrawal')
3278 if (trim(setting) ==
'RATE' .or. trim(setting) ==
'INVERT' .or. &
3279 trim(setting) ==
'WIDTH' .or. trim(setting) ==
'ROUGH' .or. &
3280 trim(setting) ==
'SLOPE')
then
3281 istat = this%lak_check_valid(-itemno)
3287 if (istat == 0 .and. itemno >= 1 .and. itemno <= this%noutlets)
then
3288 if (trim(setting) ==
'INVERT') this%outlet_invert_set(itemno) = .true.
3289 if (trim(setting) ==
'WIDTH') this%outlet_width_set(itemno) = .true.
3290 if (trim(setting) ==
'ROUGH') this%outlet_rough_set(itemno) = .true.
3291 if (trim(setting) ==
'SLOPE') this%outlet_slope_set(itemno) = .true.
3295 if (this%naux > 0)
then
3296 if (trim(setting) ==
'PERIOD_AUXILIARY')
then
3297 if (itemno >= 1 .and. itemno <= this%nlakes)
then
3298 str = this%input%auxname(n)
3299 auxvaldbl = this%input%auxval(n)
3305 if (this%iprpak /= 0)
then
3306 call this%inputtab%add_term(itemno)
3307 if (trim(setting) ==
'PERIOD_AUXILIARY')
then
3308 call this%inputtab%add_term(
'AUXILIARY')
3310 call this%inputtab%add_term(trim(setting))
3312 select case (trim(setting))
3314 call this%inputtab%add_term(trim(str))
3315 call this%inputtab%add_term(
' ')
3317 call this%inputtab%add_term(this%stage(itemno))
3318 call this%inputtab%add_term(
' ')
3320 call this%inputtab%add_term(this%rainfall(itemno))
3321 call this%inputtab%add_term(
' ')
3322 case (
'EVAPORATION')
3323 call this%inputtab%add_term(this%evaporation(itemno))
3324 call this%inputtab%add_term(
' ')
3326 call this%inputtab%add_term(this%runoff(itemno))
3327 call this%inputtab%add_term(
' ')
3329 call this%inputtab%add_term(this%inflow(itemno))
3330 call this%inputtab%add_term(
' ')
3332 call this%inputtab%add_term(this%withdrawal(itemno))
3333 call this%inputtab%add_term(
' ')
3335 call this%inputtab%add_term(this%outrate(itemno))
3336 call this%inputtab%add_term(
' ')
3338 call this%inputtab%add_term(this%outinvert(itemno))
3339 call this%inputtab%add_term(
' ')
3341 call this%inputtab%add_term(this%outwidth(itemno))
3342 call this%inputtab%add_term(
' ')
3344 call this%inputtab%add_term(this%outrough(itemno))
3345 call this%inputtab%add_term(
' ')
3347 call this%inputtab%add_term(this%outslope(itemno))
3348 call this%inputtab%add_term(
' ')
3349 case (
'PERIOD_AUXILIARY')
3350 call this%inputtab%add_term(trim(str))
3351 call this%inputtab%add_term(auxvaldbl)
3353 call this%inputtab%add_term(
' ')
3354 call this%inputtab%add_term(
' ')
3358 if (this%iprpak /= 0)
then
3359 call this%inputtab%finalize_table()
3368 do n = 1, this%nlakes
3369 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3370 node = this%gwfconn(j)
3371 this%nodelist(j) = node
3372 this%bound(1, j) = this%xnewpak(n)
3373 this%bound(2, j) = this%satcond(j)
3374 this%bound(3, j) = this%belev(j)
3379 if (this%imover == 1)
then
3380 do n = 1, this%noutlets
3381 this%pakmvrobj%iprmap(n) = this%lakein(n)
3385 write (this%iout, fmtlsp) trim(this%filtyp)
3391 do n = 1, this%nlakes
3392 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3393 this%nodelist(j) = this%gwfconn(j)
3394 this%bound(3, j) = this%belev(j)
3397 end subroutine lak_rp
3401 subroutine lak_ad(this)
3405 class(laktype) :: this
3409 integer(I4B) :: iaux
3410 integer(I4B) :: itemno
3414 call this%BndExtType%bnd_ad()
3420 if (this%ts_active .and. this%noutlets > 0)
then
3421 do n = 1,
size(this%input%outletno)
3422 itemno = this%input%outletno(n)
3423 if (itemno < 1 .or. itemno > this%noutlets) cycle
3424 if (.not. this%outlet_invert_set(itemno)) &
3425 this%outinvert(itemno) = this%input%outlets_invert(n)
3426 if (.not. this%outlet_width_set(itemno)) &
3427 this%outwidth(itemno) = this%input%outlets_width(n)
3428 if (.not. this%outlet_rough_set(itemno)) &
3429 this%outrough(itemno) = this%input%outlets_rough(n)
3430 if (.not. this%outlet_slope_set(itemno)) &
3431 this%outslope(itemno) = this%input%outlets_slope(n)
3436 if (this%naux > 0)
then
3437 do n = 1, this%nlakes
3438 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3439 do iaux = 1, this%naux
3440 if (this%noupdateauxvar(iaux) /= 0) cycle
3441 this%auxvar(iaux, j) = this%featureauxvar(iaux, n)
3452 do n = 1, this%nlakes
3453 this%xoldpak(n) = this%xnewpak(n)
3454 this%stageiter(n) = this%xnewpak(n)
3455 if (this%iboundpak(n) < 0)
then
3456 this%xnewpak(n) = this%stage(n)
3458 this%seep0(n) =
dzero
3464 do n = 1, this%nlakes
3465 this%xnewpak(n) = this%xoldpak(n)
3466 this%stageiter(n) = this%xnewpak(n)
3467 if (this%iboundpak(n) < 0)
then
3468 this%xnewpak(n) = this%stage(n)
3470 this%seep0(n) =
dzero
3475 if (this%imover == 1)
then
3476 call this%pakmvrobj%ad()
3478 end subroutine lak_ad
3484 subroutine lak_cf(this)
3486 class(laktype) :: this
3488 integer(I4B) :: j, n
3489 integer(I4B) :: igwfnode
3490 real(DP) :: hlak, bottom_lake
3493 do n = 1, this%nlakes
3494 this%seep0(n) = this%seep(n)
3498 do n = 1, this%nlakes
3499 this%s0(n) = this%xnewpak(n)
3500 call this%lak_calculate_exchange(n, this%s0(n), this%qgwf0(n))
3504 do n = 1, this%nlakes
3505 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3507 if (this%ictype(j) /= 0)
then
3510 igwfnode = this%nodesontop(j)
3511 if (this%ibound(igwfnode) == 0)
then
3512 call this%dis%highest_active(igwfnode, this%ibound)
3514 this%nodelist(j) = igwfnode
3515 this%gwfconn(j) = igwfnode
3522 do n = 1, this%nlakes
3524 hlak = this%xnewpak(n)
3527 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3530 igwfnode = this%gwfconn(j)
3533 if (this%ibound(igwfnode) < 1)
then
3538 if (this%ictype(j) /= 0)
then
3543 if (this%ictype(j) == 2 .or. this%ictype(j) == 3)
then
3548 bottom_lake = this%belev(j)
3549 if (hlak > bottom_lake .or. this%iboundpak(n) == 0)
then
3552 this%ibound(igwfnode) = 1
3560 call this%lak_bound_update()
3561 end subroutine lak_cf
3565 subroutine lak_fc(this, rhs, ia, idxglo, matrix_sln)
3567 class(laktype) :: this
3568 real(DP),
dimension(:),
intent(inout) :: rhs
3569 integer(I4B),
dimension(:),
intent(in) :: ia
3570 integer(I4B),
dimension(:),
intent(in) :: idxglo
3573 integer(I4B) :: j, n
3574 integer(I4B) :: igwfnode
3575 integer(I4B) :: ipossymd
3578 if (this%imover == 1)
then
3579 call this%pakmvrobj%fc()
3584 if (this%iimplicit /= 0)
then
3585 call this%lak_fc_implicit(rhs, matrix_sln)
3591 call this%lak_solve()
3592 do n = 1, this%nlakes
3593 if (this%iboundpak(n) == 0) cycle
3594 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3595 igwfnode = this%gwfconn(j)
3596 if (this%ibound(igwfnode) < 1) cycle
3597 ipossymd = idxglo(ia(igwfnode))
3598 call matrix_sln%add_value_pos(ipossymd, this%hcof(j))
3599 rhs(igwfnode) = rhs(igwfnode) + this%rhs(j)
3602 end subroutine lak_fc
3606 subroutine lak_fn(this, rhs, ia, idxglo, matrix_sln)
3608 class(laktype) :: this
3609 real(DP),
dimension(:),
intent(inout) :: rhs
3610 integer(I4B),
dimension(:),
intent(in) :: ia
3611 integer(I4B),
dimension(:),
intent(in) :: idxglo
3614 integer(I4B) :: j, n
3615 integer(I4B) :: ipos
3616 integer(I4B) :: igwfnode
3617 integer(I4B) :: idry
3634 if (this%iimplicit /= 0)
then
3638 do n = 1, this%nlakes
3639 if (this%iboundpak(n) == 0) cycle
3640 hlak = this%xnewpak(n)
3641 call this%lak_calculate_available(n, hlak, avail, &
3642 ra, ro, qinf, ex, this%delh)
3643 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3644 igwfnode = this%gwfconn(j)
3646 head = this%xnew(igwfnode)
3647 if (-this%hcof(j) >
dzero)
then
3648 if (this%ibound(igwfnode) > 0)
then
3652 call this%lak_estimate_conn_exchange(2, n, j, idry, hlak, &
3653 head + this%delh, q1, avail)
3656 q = this%hcof(j) * head - this%rhs(j)
3658 rterm = this%hcof(j) * head
3660 drterm = (q1 - q) / this%delh
3663 call matrix_sln%add_value_pos(idxglo(ipos), drterm - this%hcof(j))
3664 rhs(igwfnode) = rhs(igwfnode) - rterm + drterm * head
3669 end subroutine lak_fn
3679 subroutine lak_nur(this, neqpak, x, xtemp, dx, inewtonur, dxmax, locmax)
3681 class(laktype),
intent(inout) :: this
3682 integer(I4B),
intent(in) :: neqpak
3683 real(DP),
dimension(neqpak),
intent(inout) :: x
3684 real(DP),
dimension(neqpak),
intent(in) :: xtemp
3685 real(DP),
dimension(neqpak),
intent(inout) :: dx
3686 integer(I4B),
intent(inout) :: inewtonur
3687 real(DP),
intent(inout) :: dxmax
3688 integer(I4B),
intent(inout) :: locmax
3696 if (this%iimplicit == 0)
return
3699 do n = 1, this%nlakes
3700 if (this%iboundpak(n) < 1) cycle
3701 botl = this%lakebot(n)
3705 if (x(n) < botl)
then
3709 if (abs(dxx) > abs(dxmax))
then
3717 end subroutine lak_nur
3721 subroutine lak_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
3725 class(laktype),
intent(inout) :: this
3726 integer(I4B),
intent(in) :: innertot
3727 integer(I4B),
intent(in) :: kiter
3728 integer(I4B),
intent(in) :: iend
3729 integer(I4B),
intent(in) :: icnvgmod
3730 character(len=LENPAKLOC),
intent(inout) :: cpak
3731 integer(I4B),
intent(inout) :: ipak
3732 real(DP),
intent(inout) :: dpak
3734 character(len=LENPAKLOC) :: cloc
3735 character(len=LINELENGTH) :: tag
3736 integer(I4B) :: icheck
3737 integer(I4B) :: ipakfail
3738 integer(I4B) :: locdhmax
3739 integer(I4B) :: locresidmax
3740 integer(I4B) :: locdgwfmax
3741 integer(I4B) :: locdqoutmax
3742 integer(I4B) :: locdqfrommvrmax
3743 integer(I4B) :: ntabrows
3744 integer(I4B) :: ntabcols
3748 real(DP) :: qtolfact
3766 real(DP) :: residmax
3768 real(DP) :: dqoutmax
3769 real(DP) :: dqfrommvr
3770 real(DP) :: dqfrommvrmax
3772 call this%lak_set_legacy(kiter, icnvgmod)
3777 if (iend /= 0 .and. icnvgmod == 0)
then
3778 call this%lak_check_disconnected()
3784 if (this%iimplicit /= 0)
then
3789 icheck = this%iconvchk
3800 dqfrommvrmax =
dzero
3804 if (this%ipakcsv == 0)
then
3805 if (icnvgmod == 0)
then
3813 if (.not.
associated(this%pakcsvtab))
then
3818 if (this%noutlets > 0)
then
3819 ntabcols = ntabcols + 2
3821 if (this%imover == 1)
then
3822 ntabcols = ntabcols + 2
3826 call table_cr(this%pakcsvtab, this%packName,
'')
3827 call this%pakcsvtab%table_df(ntabrows, ntabcols, this%ipakcsv, &
3828 lineseparator=.false., separator=
',', &
3832 tag =
'total_inner_iterations'
3833 call this%pakcsvtab%initialize_column(tag, 10, alignment=
tableft)
3835 call this%pakcsvtab%initialize_column(tag, 10, alignment=
tableft)
3837 call this%pakcsvtab%initialize_column(tag, 10, alignment=
tableft)
3839 call this%pakcsvtab%initialize_column(tag, 10, alignment=
tableft)
3841 call this%pakcsvtab%initialize_column(tag, 10, alignment=
tableft)
3843 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
3845 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
3847 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
3848 tag =
'residmax_loc'
3849 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
3851 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
3853 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
3854 if (this%noutlets > 0)
then
3856 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
3857 tag =
'dqoutmax_loc'
3858 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
3860 if (this%imover == 1)
then
3861 tag =
'dqfrommvrmax'
3862 call this%pakcsvtab%initialize_column(tag, 15, alignment=
tableft)
3863 tag =
'dqfrommvrmax_loc'
3864 call this%pakcsvtab%initialize_column(tag, 16, alignment=
tableft)
3870 if (icheck /= 0)
then
3871 final_check:
do n = 1, this%nlakes
3872 if (this%iboundpak(n) < 1) cycle
3876 hlak = this%xnewpak(n)
3882 call this%lak_calculate_sarea(n, hlak, area)
3885 if (area >
dzero)
then
3886 qtolfact =
delt / area
3892 call this%lak_calculate_residual(n, hlak, resid)
3893 resid = resid * qtolfact
3897 if (area >
dzero)
then
3898 gwf0 = this%qgwf0(n)
3899 call this%lak_calculate_exchange(n, hlak, gwf)
3900 dgwf = (gwf0 - gwf) * qtolfact
3905 if (this%noutlets > 0)
then
3906 if (area >
dzero)
then
3907 call this%lak_calculate_available(n, hlak0, inf, ra, ro, qinf, ex)
3908 call this%lak_calculate_outlet_outflow(n, hlak0, inf, qout0)
3909 call this%lak_calculate_available(n, hlak, inf, ra, ro, qinf, ex)
3910 call this%lak_calculate_outlet_outflow(n, hlak, inf, qout)
3911 dqout = (qout0 - qout) * qtolfact
3917 if (this%imover == 1)
then
3918 q = this%pakmvrobj%get_qfrommvr(n)
3919 q0 = this%pakmvrobj%get_qfrommvr0(n)
3920 dqfrommvr = qtolfact * (q0 - q)
3933 dqfrommvrmax = dqfrommvr
3936 if (abs(dh) > abs(dhmax))
then
3940 if (abs(resid) > abs(residmax))
then
3944 if (abs(dgwf) > abs(dgwfmax))
then
3948 if (abs(dqout) > abs(dqoutmax))
then
3952 if (abs(dqfrommvr) > abs(dqfrommvrmax))
then
3953 dqfrommvrmax = dqfrommvr
3960 if (abs(dhmax) > abs(dpak))
then
3963 write (cloc,
"(a,'-',a)") &
3964 trim(this%packName),
'stage'
3967 if (abs(residmax) > abs(dpak))
then
3970 write (cloc,
"(a,'-',a)") &
3971 trim(this%packName),
'residual'
3974 if (abs(dgwfmax) > abs(dpak))
then
3977 write (cloc,
"(a,'-',a)") &
3978 trim(this%packName),
'gwf'
3981 if (this%noutlets > 0)
then
3982 if (abs(dqoutmax) > abs(dpak))
then
3985 write (cloc,
"(a,'-',a)") &
3986 trim(this%packName),
'outlet'
3990 if (this%imover == 1)
then
3991 if (abs(dqfrommvrmax) > abs(dpak))
then
3992 ipak = locdqfrommvrmax
3994 write (cloc,
"(a,'-',a)") trim(this%packName),
'qfrommvr'
4000 if (this%ipakcsv /= 0)
then
4003 call this%pakcsvtab%add_term(innertot)
4004 call this%pakcsvtab%add_term(
totim)
4005 call this%pakcsvtab%add_term(
kper)
4006 call this%pakcsvtab%add_term(
kstp)
4007 call this%pakcsvtab%add_term(kiter)
4008 call this%pakcsvtab%add_term(dhmax)
4009 call this%pakcsvtab%add_term(locdhmax)
4010 call this%pakcsvtab%add_term(residmax)
4011 call this%pakcsvtab%add_term(locresidmax)
4012 call this%pakcsvtab%add_term(dgwfmax)
4013 call this%pakcsvtab%add_term(locdgwfmax)
4014 if (this%noutlets > 0)
then
4015 call this%pakcsvtab%add_term(dqoutmax)
4016 call this%pakcsvtab%add_term(locdqoutmax)
4018 if (this%imover == 1)
then
4019 call this%pakcsvtab%add_term(dqfrommvrmax)
4020 call this%pakcsvtab%add_term(locdqfrommvrmax)
4025 call this%pakcsvtab%finalize_table()
4029 end subroutine lak_cc
4033 subroutine lak_cq(this, x, flowja, iadv)
4037 class(laktype),
intent(inout) :: this
4038 real(DP),
dimension(:),
intent(in) :: x
4039 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
4040 integer(I4B),
optional,
intent(in) :: iadv
4043 real(DP) :: chratin, chratout
4045 integer(I4B) :: j, n, igwfnode
4046 real(DP) :: hlak, head, flow, dqdh
4047 real(DP) :: v0, v1, sa, sf
4049 call this%lak_solve(update=.false.)
4058 if (this%iimplicit /= 0)
then
4059 do n = 1, this%nlakes
4060 if (this%iboundpak(n) < 1 .or. this%ilegacy(n) /= 0) cycle
4061 hlak = this%xnewpak(n)
4064 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4065 igwfnode = this%gwfconn(j)
4066 if (this%ibound(igwfnode) < 1) cycle
4067 head = this%xnew(igwfnode)
4068 call this%lak_calculate_conn_exchange_deriv(n, j, hlak, head, &
4070 this%hcof(j) = -dqdh
4071 this%rhs(j) = -dqdh * head + flow
4081 call this%lak_calculate_sarea(n, hlak, sa)
4083 if (this%surfdep >
dzero)
then
4085 this%lakebot(n), hlak)
4087 this%evap(n) = -this%evaporation(n) * sa * sf
4088 this%withr(n) = -this%withdrawal(n) * sf
4094 call this%BndType%bnd_cq(x, flowja, iadv=1)
4099 do n = 1, this%nlakes
4100 this%chterm(n) =
dzero
4101 if (this%iboundpak(n) == 0) cycle
4102 hlak = this%xnewpak(n)
4103 call this%lak_calculate_vol(n, hlak, v1)
4106 if (this%iboundpak(n) /= 0)
then
4109 rrate = this%precip(n)
4110 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4113 rrate = this%evap(n)
4114 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4117 rrate = this%runoff(n)
4118 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4121 rrate = this%inflow(n)
4122 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4125 rrate = this%withr(n)
4126 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4130 if (this%iboundpak(n) > 0)
then
4131 if (this%gwfiss /= 1)
then
4132 call this%lak_calculate_vol(n, this%xoldpak(n), v0)
4133 rrate = -(v1 - v0) /
delt
4134 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4137 this%qsto(n) = rrate
4140 call this%lak_get_external_outlet(n, rrate)
4141 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4144 if (this%imover == 1)
then
4145 if (this%iboundpak(n) /= 0)
then
4146 rrate = this%pakmvrobj%get_qfrommvr(n)
4150 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4156 do n = 1, this%nlakes
4158 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4162 rrate = -this%simvals(j)
4163 this%qleak(j) = rrate
4164 if (this%iboundpak(n) /= 0)
then
4165 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4171 call this%lak_fill_budobj()
4172 end subroutine lak_cq
4176 subroutine lak_ot_package_flows(this, icbcfl, ibudfl)
4178 class(laktype) :: this
4179 integer(I4B),
intent(in) :: icbcfl
4180 integer(I4B),
intent(in) :: ibudfl
4181 integer(I4B) :: ibinun
4185 if (this%ibudgetout /= 0)
then
4186 ibinun = this%ibudgetout
4188 if (icbcfl == 0) ibinun = 0
4189 if (ibinun > 0)
then
4190 call this%budobj%save_flows(this%dis, ibinun,
kstp,
kper,
delt, &
4195 if (ibudfl /= 0 .and. this%iprflow /= 0)
then
4196 call this%budobj%write_flowtable(this%dis,
kstp,
kper)
4198 end subroutine lak_ot_package_flows
4202 subroutine lak_ot_model_flows(this, icbcfl, ibudfl, icbcun, imap)
4203 class(laktype) :: this
4204 integer(I4B),
intent(in) :: icbcfl
4205 integer(I4B),
intent(in) :: ibudfl
4206 integer(I4B),
intent(in) :: icbcun
4207 integer(I4B),
dimension(:),
optional,
intent(in) :: imap
4210 call this%BndType%bnd_ot_model_flows(icbcfl, ibudfl, icbcun, this%imap)
4211 end subroutine lak_ot_model_flows
4215 subroutine lak_ot_dv(this, idvsave, idvprint)
4219 class(laktype) :: this
4220 integer(I4B),
intent(in) :: idvsave
4221 integer(I4B),
intent(in) :: idvprint
4222 integer(I4B) :: ibinun
4232 if (this%istageout /= 0)
then
4233 ibinun = this%istageout
4235 if (idvsave == 0) ibinun = 0
4238 if (ibinun > 0)
then
4239 do n = 1, this%nlakes
4241 d = v - this%lakebot(n)
4242 if (this%iboundpak(n) == 0)
then
4244 else if (d <= dzero)
then
4250 this%nlakes, 1, 1, ibinun)
4254 if (idvprint /= 0 .and. this%iprhed /= 0)
then
4257 call this%stagetab%set_kstpkper(
kstp,
kper)
4260 do n = 1, this%nlakes
4261 if (this%iboundpak(n) == 0)
then
4267 stage = this%xnewpak(n)
4268 call this%lak_calculate_sarea(n, stage, sa)
4269 call this%lak_calculate_warea(n, stage, wa)
4270 call this%lak_calculate_vol(n, stage, v)
4272 if (this%inamedbound == 1)
then
4273 call this%stagetab%add_term(this%lakename(n))
4275 call this%stagetab%add_term(n)
4276 call this%stagetab%add_term(stage)
4277 call this%stagetab%add_term(sa)
4278 call this%stagetab%add_term(wa)
4279 call this%stagetab%add_term(v)
4282 end subroutine lak_ot_dv
4286 subroutine lak_ot_bdsummary(this, kstp, kper, iout, ibudfl)
4290 class(laktype) :: this
4291 integer(I4B),
intent(in) :: kstp
4292 integer(I4B),
intent(in) :: kper
4293 integer(I4B),
intent(in) :: iout
4294 integer(I4B),
intent(in) :: ibudfl
4296 call this%budobj%write_budtable(kstp, kper, iout, ibudfl,
totim,
delt)
4297 end subroutine lak_ot_bdsummary
4301 subroutine lak_da(this)
4305 class(laktype) :: this
4308 call this%input%destroy()
4311 deallocate (this%lakename)
4312 deallocate (this%status)
4313 deallocate (this%clakbudget)
4315 deallocate (this%cauxcbc)
4324 if (this%ntables > 0)
then
4333 call this%budobj%budgetobject_da()
4334 deallocate (this%budobj)
4335 nullify (this%budobj)
4338 if (this%noutlets > 0)
then
4352 if (this%iprhed > 0)
then
4353 call this%stagetab%table_da()
4354 deallocate (this%stagetab)
4355 nullify (this%stagetab)
4359 if (this%ipakcsv > 0)
then
4360 if (
associated(this%pakcsvtab))
then
4361 call this%pakcsvtab%table_da()
4362 deallocate (this%pakcsvtab)
4363 nullify (this%pakcsvtab)
4373 if (
allocated(this%pakcsvfile))
deallocate (this%pakcsvfile)
4428 if (this%iimplicit == 0)
then
4473 nullify (this%gwfiss)
4476 call this%BndExtType%bnd_da()
4477 end subroutine lak_da
4482 subroutine define_listlabel(this)
4484 class(laktype),
intent(inout) :: this
4487 this%listlabel = trim(this%filtyp)//
' NO.'
4488 if (this%dis%ndim == 3)
then
4489 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'LAYER'
4490 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'ROW'
4491 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'COL'
4492 elseif (this%dis%ndim == 2)
then
4493 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'LAYER'
4494 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'CELL2D'
4496 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'NODE'
4498 write (this%listlabel,
'(a, a16)') trim(this%listlabel),
'STRESS RATE'
4499 if (this%inamedbound == 1)
then
4500 write (this%listlabel,
'(a, a16)') trim(this%listlabel),
'BOUNDARY NAME'
4502 end subroutine define_listlabel
4507 subroutine lak_set_pointers(this, neq, ibound, xnew, xold, flowja)
4511 class(laktype) :: this
4512 integer(I4B),
pointer :: neq
4513 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound
4514 real(DP),
dimension(:),
pointer,
contiguous :: xnew
4515 real(DP),
dimension(:),
pointer,
contiguous :: xold
4516 real(DP),
dimension(:),
pointer,
contiguous :: flowja
4519 integer(I4B) :: istart, iend
4522 call this%BndType%set_pointers(neq, ibound, xnew, xold, flowja)
4528 if (this%iimplicit /= 0)
then
4529 istart = this%dis%nodes + this%ioffset + 1
4530 iend = istart + this%nlakes - 1
4531 this%iboundpak => this%ibound(istart:iend)
4532 this%xnewpak => this%xnew(istart:iend)
4533 call mem_checkin(this%xnewpak,
'XNEWPAK', this%memoryPath,
'X', &
4534 this%memoryPathModel)
4537 do n = 1, this%nlakes
4538 this%xnewpak(n) =
dep20
4541 end subroutine lak_set_pointers
4549 subroutine lak_ac(this, moffset, sparse)
4552 class(laktype),
intent(inout) :: this
4553 integer(I4B),
intent(in) :: moffset
4556 integer(I4B) :: j, n
4558 integer(I4B) :: jglo
4559 integer(I4B) :: nglo
4562 if (this%iimplicit == 0)
return
4565 do n = 1, this%nlakes
4566 nglo = moffset + this%dis%nodes + this%ioffset + n
4567 call sparse%addconnection(nglo, nglo, 1)
4568 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4569 jj = this%gwfconn(j)
4571 call sparse%addconnection(nglo, jglo, 1)
4572 call sparse%addconnection(jglo, nglo, 1)
4575 end subroutine lak_ac
4583 subroutine lak_mc(this, moffset, matrix_sln)
4586 class(laktype),
intent(inout) :: this
4587 integer(I4B),
intent(in) :: moffset
4592 integer(I4B) :: iglo
4593 integer(I4B) :: jglo
4594 integer(I4B) :: ipos
4599 if (this%iimplicit == 0)
then
4600 call mem_allocate(this%idxlocnode, 0,
'IDXLOCNODE', this%memoryPath)
4601 call mem_allocate(this%idxdiag, 0,
'IDXDIAG', this%memoryPath)
4602 call mem_allocate(this%idxoffdglo, 0,
'IDXOFFDGLO', this%memoryPath)
4603 call mem_allocate(this%idxsymdglo, 0,
'IDXSYMDGLO', this%memoryPath)
4604 call mem_allocate(this%idxsymoffdglo, 0,
'IDXSYMOFFDGLO', this%memoryPath)
4607 call mem_allocate(this%idxlocnode, this%nlakes,
'IDXLOCNODE', &
4609 call mem_allocate(this%idxdiag, this%nlakes,
'IDXDIAG', this%memoryPath)
4610 call mem_allocate(this%idxoffdglo, this%maxbound,
'IDXOFFDGLO', &
4612 call mem_allocate(this%idxsymdglo, this%maxbound,
'IDXSYMDGLO', &
4614 call mem_allocate(this%idxsymoffdglo, this%maxbound,
'IDXSYMOFFDGLO', &
4621 do n = 1, this%nlakes
4622 iglo = moffset + this%dis%nodes + this%ioffset + n
4623 this%idxlocnode(n) = this%dis%nodes + this%ioffset + n
4624 this%idxdiag(n) = matrix_sln%get_position_diag(iglo)
4625 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4626 jglo = this%gwfconn(j) + moffset
4627 this%idxoffdglo(ipos) = matrix_sln%get_position(iglo, jglo)
4634 do n = 1, this%nlakes
4635 jglo = moffset + this%dis%nodes + this%ioffset + n
4636 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4637 iglo = this%gwfconn(j) + moffset
4638 this%idxsymdglo(ipos) = matrix_sln%get_position_diag(iglo)
4639 this%idxsymoffdglo(ipos) = matrix_sln%get_position(iglo, jglo)
4643 end subroutine lak_mc
4650 logical function lak_obs_supported(this)
4652 class(laktype) :: this
4654 lak_obs_supported = .true.
4655 end function lak_obs_supported
4660 subroutine lak_df_obs(this)
4662 class(laktype) :: this
4664 integer(I4B) :: indx
4668 call this%obs%StoreObsType(
'stage', .false., indx)
4669 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4673 call this%obs%StoreObsType(
'ext-inflow', .true., indx)
4674 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4678 call this%obs%StoreObsType(
'outlet-inflow', .true., indx)
4679 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4683 call this%obs%StoreObsType(
'inflow', .true., indx)
4684 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4688 call this%obs%StoreObsType(
'from-mvr', .true., indx)
4689 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4693 call this%obs%StoreObsType(
'rainfall', .true., indx)
4694 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4698 call this%obs%StoreObsType(
'runoff', .true., indx)
4699 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4703 call this%obs%StoreObsType(
'lak', .true., indx)
4704 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4708 call this%obs%StoreObsType(
'evaporation', .true., indx)
4709 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4713 call this%obs%StoreObsType(
'withdrawal', .true., indx)
4714 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4718 call this%obs%StoreObsType(
'ext-outflow', .true., indx)
4719 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4723 call this%obs%StoreObsType(
'to-mvr', .true., indx)
4724 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4728 call this%obs%StoreObsType(
'storage', .true., indx)
4729 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4733 call this%obs%StoreObsType(
'constant', .true., indx)
4734 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4738 call this%obs%StoreObsType(
'outlet', .true., indx)
4739 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4743 call this%obs%StoreObsType(
'volume', .true., indx)
4744 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4748 call this%obs%StoreObsType(
'surface-area', .true., indx)
4749 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4753 call this%obs%StoreObsType(
'wetted-area', .true., indx)
4754 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4758 call this%obs%StoreObsType(
'conductance', .true., indx)
4759 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4760 end subroutine lak_df_obs
4765 subroutine lak_bd_obs(this)
4767 class(laktype) :: this
4770 integer(I4B) :: igwfnode
4781 if (this%obs%npakobs > 0)
then
4782 call this%obs%obs_bd_clear()
4783 do i = 1, this%obs%npakobs
4784 obsrv => this%obs%pakobs(i)%obsrv
4785 do j = 1, obsrv%indxbnds_count
4787 jj = obsrv%indxbnds(j)
4788 select case (obsrv%ObsTypeId)
4790 if (this%iboundpak(jj) /= 0)
then
4791 v = this%xnewpak(jj)
4794 if (this%iboundpak(jj) /= 0)
then
4795 call this%lak_calculate_inflow(jj, v)
4797 case (
'OUTLET-INFLOW')
4798 if (this%iboundpak(jj) /= 0)
then
4799 call this%lak_calculate_outlet_inflow(jj, v)
4802 if (this%iboundpak(jj) /= 0)
then
4803 call this%lak_calculate_inflow(jj, v)
4804 call this%lak_calculate_outlet_inflow(jj, v2)
4808 if (this%iboundpak(jj) /= 0)
then
4809 if (this%imover == 1)
then
4810 v = this%pakmvrobj%get_qfrommvr(jj)
4814 if (this%iboundpak(jj) /= 0)
then
4818 if (this%iboundpak(jj) /= 0)
then
4823 if (this%iboundpak(n) /= 0)
then
4824 igwfnode = this%gwfconn(jj)
4825 hgwf = this%xnew(igwfnode)
4826 if (this%hcof(jj) /=
dzero)
then
4827 v = -(this%hcof(jj) * (this%xnewpak(n) - hgwf))
4832 case (
'EVAPORATION')
4833 if (this%iboundpak(jj) /= 0)
then
4837 if (this%iboundpak(jj) /= 0)
then
4840 case (
'EXT-OUTFLOW')
4842 if (this%iboundpak(n) /= 0)
then
4843 if (this%lakeout(jj) == 0)
then
4844 v = this%simoutrate(jj)
4846 if (this%imover == 1)
then
4847 v = v + this%pakmvrobj%get_qtomvr(jj)
4854 if (this%iboundpak(n) /= 0)
then
4855 if (this%imover == 1)
then
4856 v = this%pakmvrobj%get_qtomvr(jj)
4863 if (this%iboundpak(jj) /= 0)
then
4867 if (this%iboundpak(jj) /= 0)
then
4872 if (this%iboundpak(n) /= 0)
then
4873 v = this%simoutrate(jj)
4876 if (this%iboundpak(jj) /= 0)
then
4877 call this%lak_calculate_vol(jj, this%xnewpak(jj), v)
4879 case (
'SURFACE-AREA')
4880 if (this%iboundpak(jj) /= 0)
then
4881 hlak = this%xnewpak(jj)
4882 call this%lak_calculate_sarea(jj, hlak, v)
4884 case (
'WETTED-AREA')
4886 if (this%iboundpak(n) /= 0)
then
4887 hlak = this%xnewpak(n)
4888 igwfnode = this%gwfconn(jj)
4889 hgwf = this%xnew(igwfnode)
4890 call this%lak_calculate_conn_warea(n, jj, hlak, hgwf, v)
4892 case (
'CONDUCTANCE')
4894 if (this%iboundpak(n) /= 0)
then
4895 hlak = this%xnewpak(n)
4896 igwfnode = this%gwfconn(jj)
4897 hgwf = this%xnew(igwfnode)
4898 call this%lak_calculate_conn_conductance(n, jj, hlak, hgwf, v)
4901 errmsg =
'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
4904 call this%obs%SaveOneSimval(obsrv, v)
4913 end subroutine lak_bd_obs
4920 subroutine lak_rp_obs(this)
4923 class(laktype),
intent(inout) :: this
4930 character(len=LENBOUNDNAME) :: bname
4931 logical(LGP) :: jfound
4934 10
format(
'Boundary "', a,
'" for observation "', a, &
4935 '" is invalid in package "', a,
'"')
4941 do i = 1, this%obs%npakobs
4942 obsrv => this%obs%pakobs(i)%obsrv
4945 nn1 = obsrv%NodeNumber
4947 bname = obsrv%FeatureName
4948 if (bname /=
'')
then
4953 if (obsrv%ObsTypeId ==
'LAK' .or. &
4954 obsrv%ObsTypeId ==
'CONDUCTANCE' .or. &
4955 obsrv%ObsTypeId ==
'WETTED-AREA')
then
4956 do j = 1, this%nlakes
4957 do jj = this%idxlakeconn(j), this%idxlakeconn(j + 1) - 1
4958 if (this%boundname(jj) == bname)
then
4960 call obsrv%AddObsIndex(jj)
4964 else if (obsrv%ObsTypeId ==
'EXT-OUTFLOW' .or. &
4965 obsrv%ObsTypeId ==
'TO-MVR' .or. &
4966 obsrv%ObsTypeId ==
'OUTLET')
then
4967 do j = 1, this%noutlets
4969 if (this%lakename(jj) == bname)
then
4971 call obsrv%AddObsIndex(j)
4975 do j = 1, this%nlakes
4976 if (this%lakename(j) == bname)
then
4978 call obsrv%AddObsIndex(j)
4982 if (.not. jfound)
then
4984 trim(bname), trim(obsrv%Name), trim(this%packName)
4989 if (obsrv%indxbnds_count == 0)
then
4990 if (obsrv%ObsTypeId ==
'LAK' .or. &
4991 obsrv%ObsTypeId ==
'CONDUCTANCE' .or. &
4992 obsrv%ObsTypeId ==
'WETTED-AREA')
then
4993 nn2 = obsrv%NodeNumber2
4994 j = this%idxlakeconn(nn1) + nn2 - 1
4995 call obsrv%AddObsIndex(j)
4997 call obsrv%AddObsIndex(nn1)
5000 errmsg =
'Programming error in lak_rp_obs'
5007 if (obsrv%ObsTypeId ==
'STAGE')
then
5008 if (obsrv%indxbnds_count > 1)
then
5009 write (
errmsg,
'(a,3(1x,a))') &
5010 trim(adjustl(obsrv%ObsTypeId)), &
5011 'for observation', trim(adjustl(obsrv%Name)), &
5012 ' must be assigned to a lake with a unique boundname.'
5018 if (obsrv%ObsTypeId ==
'TO-MVR' .or. &
5019 obsrv%ObsTypeId ==
'EXT-OUTFLOW' .or. &
5020 obsrv%ObsTypeId ==
'OUTLET')
then
5021 do j = 1, obsrv%indxbnds_count
5022 nn1 = obsrv%indxbnds(j)
5023 if (nn1 < 1 .or. nn1 > this%noutlets)
then
5024 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5025 trim(adjustl(obsrv%ObsTypeId)), &
5026 ' outlet must be > 0 and <=', this%noutlets, &
5027 '(specified value is ', nn1,
')'
5031 else if (obsrv%ObsTypeId ==
'LAK' .or. &
5032 obsrv%ObsTypeId ==
'CONDUCTANCE' .or. &
5033 obsrv%ObsTypeId ==
'WETTED-AREA')
then
5034 do j = 1, obsrv%indxbnds_count
5035 nn1 = obsrv%indxbnds(j)
5036 if (nn1 < 1 .or. nn1 > this%maxbound)
then
5037 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5038 trim(adjustl(obsrv%ObsTypeId)), &
5039 'lake connection number must be > 0 and <=', this%maxbound, &
5040 '(specified value is ', nn1,
')'
5045 do j = 1, obsrv%indxbnds_count
5046 nn1 = obsrv%indxbnds(j)
5047 if (nn1 < 1 .or. nn1 > this%nlakes)
then
5048 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5049 trim(adjustl(obsrv%ObsTypeId)), &
5050 ' lake must be > 0 and <=', this%nlakes, &
5051 '(specified value is ', nn1,
')'
5063 end subroutine lak_rp_obs
5072 subroutine lak_process_obsid(obsrv, dis, inunitobs, iout)
5076 integer(I4B),
intent(in) :: inunitobs
5077 integer(I4B),
intent(in) :: iout
5079 integer(I4B) :: nn1, nn2
5080 integer(I4B) :: icol, istart, istop
5081 character(len=LINELENGTH) :: string
5082 character(len=LENBOUNDNAME) :: bndname
5084 string = obsrv%IDstring
5092 obsrv%FeatureName = bndname
5094 if (obsrv%ObsTypeId ==
'LAK' .or. obsrv%ObsTypeId ==
'CONDUCTANCE' .or. &
5095 obsrv%ObsTypeId ==
'WETTED-AREA')
then
5097 if (len_trim(bndname) < 1 .and. nn2 < 0)
then
5098 write (
errmsg,
'(a,1x,a,a,1x,a,1x,a)') &
5099 'For observation type', trim(adjustl(obsrv%ObsTypeId)), &
5100 ', ID given as an integer and not as boundname,', &
5101 'but ID2 (iconn) is missing. Either change ID to valid', &
5102 'boundname or supply valid entry for ID2.'
5106 obsrv%FeatureName = bndname
5110 obsrv%NodeNumber2 = nn2
5115 obsrv%NodeNumber = nn1
5116 end subroutine lak_process_obsid
5124 subroutine lak_accumulate_chterm(this, ilak, rrate, chratin, chratout)
5126 class(laktype) :: this
5127 integer(I4B),
intent(in) :: ilak
5128 real(DP),
intent(in) :: rrate
5129 real(DP),
intent(inout) :: chratin
5130 real(DP),
intent(inout) :: chratout
5135 if (this%iboundpak(ilak) < 0)
then
5137 this%chterm(ilak) = this%chterm(ilak) + q
5143 chratout = chratout - q
5147 chratin = chratin + q
5150 end subroutine lak_accumulate_chterm
5154 subroutine lak_bound_update(this)
5156 class(laktype),
intent(inout) :: this
5158 integer(I4B) :: j, n, node
5159 real(DP) :: hlak, head, clak
5162 if (this%nbound == 0)
return
5165 do n = 1, this%nlakes
5166 hlak = this%xnewpak(n)
5167 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5168 node = this%gwfconn(j)
5169 head = this%xnew(node)
5170 call this%lak_calculate_conn_conductance(n, j, hlak, head, clak)
5171 this%bound(1, j) = hlak
5172 this%bound(2, j) = clak
5175 end subroutine lak_bound_update
5185 subroutine lak_solve(this, update, only_legacy)
5189 class(laktype),
intent(inout) :: this
5190 logical(LGP),
intent(in),
optional :: update
5191 logical(LGP),
intent(in),
optional :: only_legacy
5193 logical(LGP) :: lupdate
5194 logical(LGP) :: legonly
5197 integer(I4B) :: iicnvg
5198 integer(I4B) :: iter
5199 integer(I4B) :: maxiter
5200 integer(I4B) :: ncnv
5212 if (
present(update))
then
5219 if (
present(only_legacy))
then
5220 legonly = only_legacy
5229 do n = 1, this%nlakes
5233 if (legonly .and. this%ilegacy(n) == 0)
then
5238 this%surfin(n) =
dzero
5239 this%surfout(n) =
dzero
5240 this%surfout1(n) =
dzero
5241 if (this%xnewpak(n) < this%lakebot(n))
then
5242 this%xnewpak(n) = this%lakebot(n)
5244 if (this%gwfiss /= 0)
then
5245 this%xoldpak(n) = this%xnewpak(n)
5250 this%en1(n) = this%lakebot(n)
5251 call this%lak_calculate_residual(n, this%en1(n), this%r1(n))
5252 this%en2(n) = this%laketop(n)
5253 call this%lak_calculate_residual(n, this%en2(n), this%r2(n))
5257 do n = 1, this%noutlets
5258 if (legonly .and. this%ilegacy(this%lakein(n)) == 0) cycle
5259 this%simoutrate(n) =
dzero
5263 do n = 1, this%nlakes
5264 call this%lak_calculate_outlet_inflow(n, this%surfin(n))
5269 do n = 1, this%nlakes
5270 hlak0 = this%xoldpak(n)
5271 hlak = this%xnewpak(n)
5272 call this%lak_calculate_runoff(n, ro)
5273 call this%lak_calculate_inflow(n, qinf)
5274 call this%lak_calculate_external(n, ex)
5275 call this%lak_calculate_vol(n, hlak0, v0)
5276 call this%lak_calculate_vol(n, hlak, v1)
5277 this%flwin(n) = this%surfin(n) + ro + qinf + ex + &
5282 do n = 1, this%nlakes
5283 call this%lak_calculate_outlet_inflow(n, outinf)
5284 this%flwin(n) = this%flwin(n) + outinf
5288 maxiter = this%maxlakit
5291 converge:
do iter = 1, maxiter
5293 do n = 1, this%nlakes
5294 if (this%ncncvr(n) == 0) ncnv = 1
5296 if (iter == maxiter) ncnv = 0
5297 if (ncnv == 0) iicnvg = 1
5300 do n = 1, this%nlakes
5301 this%evap(n) =
dzero
5302 this%precip(n) =
dzero
5303 this%precip1(n) =
dzero
5304 this%seep(n) =
dzero
5305 this%seep1(n) =
dzero
5306 this%evap(n) =
dzero
5307 this%evap1(n) =
dzero
5308 this%evapo(n) =
dzero
5309 this%withr(n) =
dzero
5310 this%withr1(n) =
dzero
5311 this%flwiter(n) = this%flwin(n)
5312 this%flwiter1(n) = this%flwin(n)
5313 if (this%gwfiss /= 0)
then
5314 this%flwiter(n) =
dep20
5315 this%flwiter1(n) =
dep20
5317 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5318 this%hcof(j) =
dzero
5323 do n = 1, this%nlakes
5324 if (legonly .and. this%ilegacy(n) == 0) cycle
5325 call this%lak_estimate_seepage_single(n, ncnv)
5328 laklevel:
do n = 1, this%nlakes
5329 if (legonly .and. this%ilegacy(n) == 0) cycle laklevel
5330 call this%lak_solve_single(n, iter, maxiter, ncnv, lupdate)
5333 if (iicnvg == 1)
exit converge
5342 if (this%imover == 1 .and. .not. legonly)
then
5343 do n = 1, this%noutlets
5344 call this%pakmvrobj%accumulate_qformvr(n, -this%simoutrate(n))
5347 end subroutine lak_solve
5357 subroutine lak_solve_single(this, n, iter, maxiter, ncnv, lupdate)
5361 class(laktype),
intent(inout) :: this
5362 integer(I4B),
intent(in) :: n
5363 integer(I4B),
intent(in) :: iter
5364 integer(I4B),
intent(in) :: maxiter
5365 integer(I4B),
intent(in) :: ncnv
5366 logical(LGP),
intent(in) :: lupdate
5368 integer(I4B) :: ibflg
5369 integer(I4B) :: idhp
5389 real(DP) :: qtolfact
5395 if (this%iboundpak(n) == 0)
then
5400 hlak = this%xnewpak(n)
5401 if (iter < maxiter)
then
5402 this%stageiter(n) = this%xnewpak(n)
5404 call this%lak_calculate_rainfall(n, hlak, ra)
5406 this%flwiter(n) = this%flwiter(n) + ra
5407 call this%lak_calculate_rainfall(n, hlak + delh, ra)
5408 this%precip1(n) = ra
5409 this%flwiter1(n) = this%flwiter1(n) + ra
5412 call this%lak_calculate_withdrawal(n, this%flwiter(n), wr)
5414 call this%lak_calculate_withdrawal(n, this%flwiter1(n), wr)
5418 call this%lak_calculate_evaporation(n, hlak, this%flwiter(n), ev)
5420 call this%lak_calculate_evaporation(n, hlak + delh, this%flwiter1(n), ev)
5424 call this%lak_calculate_outlet_outflow(n, hlak + delh, &
5427 call this%lak_calculate_outlet_outflow(n, hlak, this%flwiter(n), &
5431 call this%lak_calculate_outlet_inflow(n, this%surfin(n))
5435 if (this%iboundpak(n) > 0 .and. lupdate .eqv. .true.)
then
5438 hlak0 = this%xoldpak(n)
5439 hlak = this%xnewpak(n)
5440 call this%lak_calculate_vol(n, hlak0, v0)
5441 call this%lak_calculate_vol(n, hlak, v1)
5442 call this%lak_calculate_runoff(n, ro)
5443 call this%lak_calculate_inflow(n, qinf)
5444 call this%lak_calculate_external(n, ex)
5445 this%flwin(n) = this%surfin(n) + ro + qinf + ex + &
5449 resid = this%precip(n) + this%evap(n) + this%withr(n) + ro + &
5450 qinf + ex + this%surfin(n) + &
5451 this%surfout(n) + this%seep(n)
5452 resid1 = this%precip1(n) + this%evap1(n) + this%withr1(n) + ro + &
5453 qinf + ex + this%surfin(n) + &
5454 this%surfout1(n) + this%seep1(n)
5457 hlak = this%xnewpak(n)
5458 if (this%gwfiss /= 1)
then
5459 call this%lak_calculate_vol(n, hlak, v1)
5460 resid = resid + (v0 - v1) /
delt
5461 call this%lak_calculate_vol(n, hlak + delh, v1)
5462 resid1 = resid1 + (v0 - v1) /
delt
5466 if (abs(resid1 - resid) >
dzero)
then
5467 derv = (resid1 - resid) / delh
5469 if (abs(derv) >
dprec)
then
5473 if (resid <
dzero)
then
5476 call this%lak_vol2stage(n, resid, dh)
5483 if (iter == 1) this%dh0(n) = dh
5485 adh0 = abs(this%dh0(n))
5486 if ((ts >= this%en2(n)) .or. (ts < this%en1(n)))
then
5489 if ((adh > adh0) .or. (ts - this%lakebot(n)) <
dprec)
then
5491 call this%lak_bisection(n, ibflg, hlak, ts, dh, residb)
5497 this%seep0(n) = this%seep(n)
5501 if (this%seep(n) * this%seep0(n) <
dprec)
then
5502 this%iseepc(n) = this%iseepc(n) + 1
5508 if (dh * this%dh0(n) <
dprec) idhp = 1
5511 if (adh > adh0) idhp = 1
5514 this%idhc(n) = this%idhc(n) + 1
5519 if (ibflg == 1)
then
5520 if (this%iseepc(n) > 7 .or. this%idhc(n) > 12)
then
5521 call this%lak_bisection(n, ibflg, hlak, ts, dh, residb)
5530 if (hlak < this%lakebot(n))
then
5531 hlak = this%lakebot(n)
5535 call this%lak_calculate_sarea(n, hlak, area)
5538 if (area >
dzero)
then
5539 qtolfact =
delt / area
5545 call this%lak_calculate_residual(n, hlak, resid)
5549 if (abs(dh) < delh .and. abs(resid) * qtolfact < this%dmaxchg)
then
5552 this%xnewpak(n) = hlak
5555 this%seep0(n) = this%seep(n)
5558 end subroutine lak_solve_single
5571 subroutine lak_estimate_seepage_single(this, n, ncnv)
5573 class(laktype),
intent(inout) :: this
5574 integer(I4B),
intent(in) :: n
5575 integer(I4B),
intent(in) :: ncnv
5579 integer(I4B) :: igwfnode
5580 integer(I4B) :: idry
5581 integer(I4B) :: idry1
5593 if (this%iboundpak(n) == 0)
return
5595 estseep:
do i = 1, 2
5597 if (this%gwfiss /= 0)
then
5598 this%xoldpak(n) = this%xnewpak(n)
5600 hlak = this%xnewpak(n)
5601 calcconnseep:
do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5602 igwfnode = this%gwfconn(j)
5603 head = this%xnew(igwfnode)
5604 if (this%ncncvr(n) /= 2)
then
5605 if (this%ibound(igwfnode) > 0)
then
5606 call this%lak_estimate_conn_exchange(i, n, j, idry, hlak, &
5610 call this%lak_estimate_conn_exchange(i, n, j, idry1, &
5611 hlak + delh, head, qlakgw1, &
5615 if (ncnv == 0 .and. i == 2)
then
5616 if (j == this%maxbound)
then
5620 this%hcof(j) = gwfhcof
5621 this%rhs(j) = gwfrhs
5623 this%hcof(j) =
dzero
5624 this%rhs(j) = qlakgw
5628 this%seep(n) = this%seep(n) + qlakgw
5629 this%seep1(n) = this%seep1(n) + qlakgw1
5635 end subroutine lak_estimate_seepage_single
5641 subroutine lak_bisection(this, n, ibflg, hlak, temporary_stage, dh, residual)
5643 class(laktype),
intent(inout) :: this
5644 integer(I4B),
intent(in) :: n
5645 integer(I4B),
intent(inout) :: ibflg
5646 real(DP),
intent(in) :: hlak
5647 real(DP),
intent(inout) :: temporary_stage
5648 real(DP),
intent(inout) :: dh
5649 real(DP),
intent(inout) :: residual
5652 real(DP) :: temporary_stage0
5653 real(DP) :: residuala
5654 real(DP) :: endpoint1
5655 real(DP) :: endpoint2
5658 temporary_stage0 = hlak
5659 endpoint1 = this%en1(n)
5660 endpoint2 = this%en2(n)
5661 call this%lak_calculate_residual(n, temporary_stage, residuala)
5662 if (hlak > endpoint1 .and. hlak < endpoint2)
then
5665 do i = 1, this%maxlakit
5666 temporary_stage =
dhalf * (endpoint1 + endpoint2)
5667 call this%lak_calculate_residual(n, temporary_stage, residual)
5668 if (abs(residual) ==
dzero .or. &
5669 abs(temporary_stage0 - temporary_stage) < this%dmaxchg)
then
5672 call this%lak_calculate_residual(n, endpoint1, residuala)
5675 if (sign(
done, residuala) == sign(
done, residual))
then
5676 endpoint1 = temporary_stage
5679 endpoint2 = temporary_stage
5681 temporary_stage0 = temporary_stage
5683 dh = hlak - temporary_stage
5684 end subroutine lak_bisection
5689 subroutine lak_calculate_available(this, n, hlak, avail, &
5690 ra, ro, qinf, ex, headp)
5694 class(laktype),
intent(inout) :: this
5695 integer(I4B),
intent(in) :: n
5696 real(DP),
intent(in) :: hlak
5697 real(DP),
intent(inout) :: avail
5698 real(DP),
intent(inout) :: ra
5699 real(DP),
intent(inout) :: ro
5700 real(DP),
intent(inout) :: qinf
5701 real(DP),
intent(inout) :: ex
5702 real(DP),
intent(in),
optional :: headp
5705 integer(I4B) :: idry
5706 integer(I4B) :: igwfnode
5713 if (
present(headp))
then
5723 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5724 igwfnode = this%gwfconn(j)
5725 if (this%ibound(igwfnode) == 0) cycle
5726 head = this%xnew(igwfnode) + hp
5727 call this%lak_estimate_conn_exchange(1, n, j, idry, hlak, head, qlakgw, &
5732 call this%lak_calculate_rainfall(n, hlak, ra)
5736 call this%lak_calculate_runoff(n, ro)
5740 call this%lak_calculate_inflow(n, qinf)
5741 avail = avail + qinf
5744 call this%lak_calculate_external(n, ex)
5748 call this%lak_calculate_vol(n, this%xoldpak(n), v0)
5749 avail = avail + v0 /
delt
5750 end subroutine lak_calculate_available
5754 subroutine lak_calculate_residual(this, n, hlak, resid, headp)
5758 class(laktype),
intent(inout) :: this
5759 integer(I4B),
intent(in) :: n
5760 real(DP),
intent(in) :: hlak
5761 real(DP),
intent(inout) :: resid
5762 real(DP),
intent(in),
optional :: headp
5765 integer(I4B) :: idry
5766 integer(I4B) :: igwfnode
5785 if (
present(headp))
then
5797 call this%lak_calculate_available(n, hlak, avail, &
5798 ra, ro, qinf, ex, hp)
5801 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5802 igwfnode = this%gwfconn(j)
5803 if (this%ibound(igwfnode) == 0) cycle
5804 head = this%xnew(igwfnode) + hp
5805 call this%lak_estimate_conn_exchange(2, n, j, idry, hlak, head, qlakgw, &
5807 seep = seep + qlakgw
5811 call this%lak_calculate_withdrawal(n, avail, wr)
5814 call this%lak_calculate_evaporation(n, hlak, avail, ev)
5817 call this%lak_calculate_outlet_outflow(n, hlak, avail, sout)
5820 call this%lak_calculate_outlet_inflow(n, sin)
5823 resid = ra + ev + wr + ro + qinf + ex + sin + sout + seep
5826 if (this%gwfiss /= 1)
then
5827 hlak0 = this%xoldpak(n)
5828 call this%lak_calculate_vol(n, hlak0, v0)
5829 call this%lak_calculate_vol(n, hlak, v1)
5830 resid = resid + (v0 - v1) /
delt
5832 end subroutine lak_calculate_residual
5836 subroutine lak_setup_budobj(this)
5840 class(laktype) :: this
5842 integer(I4B) :: nbudterm
5843 integer(I4B) :: nlen
5844 integer(I4B) :: j, n, n1, n2
5845 integer(I4B) :: maxlist, naux
5848 character(len=LENBUDTXT) :: text
5849 character(len=LENBUDTXT),
dimension(1) :: auxtxt
5855 do n = 1, this%noutlets
5856 if (this%lakein(n) > 0 .and. this%lakeout(n) > 0)
then
5860 if (nlen > 0) nbudterm = nbudterm + 1
5861 if (this%imover == 1) nbudterm = nbudterm + 2
5862 if (this%naux > 0) nbudterm = nbudterm + 1
5866 call this%budobj%budgetobject_df(this%nlakes, nbudterm, 0, 0, &
5867 ibudcsv=this%ibudcsv)
5873 text =
' FLOW-JA-FACE'
5877 call this%budobj%budterm(idx)%initialize(text, &
5882 maxlist, .false., .false., &
5883 naux, ordered_id1=.false.)
5886 call this%budobj%budterm(idx)%reset(2 * nlen)
5888 do n = 1, this%noutlets
5890 n2 = this%lakeout(n)
5891 if (n1 > 0 .and. n2 > 0)
then
5892 call this%budobj%budterm(idx)%update_term(n1, n2, q)
5893 call this%budobj%budterm(idx)%update_term(n2, n1, -q)
5901 maxlist = this%maxbound
5903 auxtxt(1) =
' FLOW-AREA'
5904 call this%budobj%budterm(idx)%initialize(text, &
5909 maxlist, .false., .true., &
5911 call this%budobj%budterm(idx)%reset(this%maxbound)
5913 do n = 1, this%nlakes
5914 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5915 n2 = this%gwfconn(j)
5916 call this%budobj%budterm(idx)%update_term(n, n2, q)
5923 maxlist = this%nlakes
5925 call this%budobj%budterm(idx)%initialize(text, &
5930 maxlist, .false., .false., &
5934 text =
' EVAPORATION'
5936 maxlist = this%nlakes
5938 call this%budobj%budterm(idx)%initialize(text, &
5943 maxlist, .false., .false., &
5949 maxlist = this%nlakes
5951 call this%budobj%budterm(idx)%initialize(text, &
5956 maxlist, .false., .false., &
5960 text =
' EXT-INFLOW'
5962 maxlist = this%nlakes
5964 call this%budobj%budterm(idx)%initialize(text, &
5969 maxlist, .false., .false., &
5973 text =
' WITHDRAWAL'
5975 maxlist = this%nlakes
5977 call this%budobj%budterm(idx)%initialize(text, &
5982 maxlist, .false., .false., &
5986 text =
' EXT-OUTFLOW'
5988 maxlist = this%nlakes
5990 call this%budobj%budterm(idx)%initialize(text, &
5995 maxlist, .false., .false., &
6001 maxlist = this%nlakes
6003 auxtxt(1) =
' VOLUME'
6004 call this%budobj%budterm(idx)%initialize(text, &
6009 maxlist, .false., .false., &
6015 maxlist = this%nlakes
6017 call this%budobj%budterm(idx)%initialize(text, &
6022 maxlist, .false., .false., &
6026 if (this%imover == 1)
then
6031 maxlist = this%nlakes
6033 call this%budobj%budterm(idx)%initialize(text, &
6038 maxlist, .false., .false., &
6044 maxlist = this%noutlets
6046 call this%budobj%budterm(idx)%initialize(text, &
6051 maxlist, .false., .false., &
6052 naux, ordered_id1=.false.)
6055 call this%budobj%budterm(idx)%reset(this%noutlets)
6057 do n = 1, this%noutlets
6059 call this%budobj%budterm(idx)%update_term(n1, n1, q)
6070 maxlist = this%nlakes
6071 call this%budobj%budterm(idx)%initialize(text, &
6076 maxlist, .false., .false., &
6081 if (this%iprflow /= 0)
then
6082 call this%budobj%flowtable_df(this%iout)
6084 end subroutine lak_setup_budobj
6088 subroutine lak_fill_budobj(this)
6090 class(laktype) :: this
6092 integer(I4B) :: naux
6093 real(DP),
dimension(:),
allocatable :: auxvartmp
6102 integer(I4B) :: nlen
6105 real(DP) :: lkstg, gwhead, wa
6112 do n = 1, this%noutlets
6113 if (this%lakein(n) > 0 .and. this%lakeout(n) > 0)
then
6119 call this%budobj%budterm(idx)%reset(2 * nlen)
6120 do n = 1, this%noutlets
6122 n2 = this%lakeout(n)
6123 if (n1 > 0 .and. n2 > 0)
then
6124 q = this%simoutrate(n)
6125 if (this%imover == 1)
then
6126 q = q + this%pakmvrobj%get_qtomvr(n)
6128 call this%budobj%budterm(idx)%update_term(n1, n2, q)
6129 call this%budobj%budterm(idx)%update_term(n2, n1, -q)
6136 call this%budobj%budterm(idx)%reset(this%maxbound)
6137 do n = 1, this%nlakes
6138 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
6139 n2 = this%gwfconn(j)
6141 lkstg = this%xnewpak(n)
6145 gwhead = this%xnew(n2)
6146 call this%lak_calculate_conn_warea(n, j, lkstg, gwhead, wa)
6150 if (this%belev(j) > lkstg) wa =
dzero
6151 this%qauxcbc(1) = wa
6152 call this%budobj%budterm(idx)%update_term(n, n2, q, this%qauxcbc)
6158 call this%budobj%budterm(idx)%reset(this%nlakes)
6159 do n = 1, this%nlakes
6161 call this%budobj%budterm(idx)%update_term(n, n, q)
6166 call this%budobj%budterm(idx)%reset(this%nlakes)
6167 do n = 1, this%nlakes
6169 call this%budobj%budterm(idx)%update_term(n, n, q)
6174 call this%budobj%budterm(idx)%reset(this%nlakes)
6175 do n = 1, this%nlakes
6177 call this%budobj%budterm(idx)%update_term(n, n, q)
6182 call this%budobj%budterm(idx)%reset(this%nlakes)
6183 do n = 1, this%nlakes
6185 call this%budobj%budterm(idx)%update_term(n, n, q)
6190 call this%budobj%budterm(idx)%reset(this%nlakes)
6191 do n = 1, this%nlakes
6193 call this%budobj%budterm(idx)%update_term(n, n, q)
6198 call this%budobj%budterm(idx)%reset(this%nlakes)
6199 do n = 1, this%nlakes
6200 call this%lak_get_external_outlet(n, q)
6202 call this%lak_get_external_mover(n, v)
6204 call this%budobj%budterm(idx)%update_term(n, n, q)
6209 call this%budobj%budterm(idx)%reset(this%nlakes)
6210 do n = 1, this%nlakes
6211 call this%lak_calculate_vol(n, this%xnewpak(n), v1)
6213 this%qauxcbc(1) = v1
6214 call this%budobj%budterm(idx)%update_term(n, n, q, this%qauxcbc)
6219 call this%budobj%budterm(idx)%reset(this%nlakes)
6220 do n = 1, this%nlakes
6222 call this%budobj%budterm(idx)%update_term(n, n, q)
6226 if (this%imover == 1)
then
6230 call this%budobj%budterm(idx)%reset(this%nlakes)
6231 do n = 1, this%nlakes
6232 q = this%pakmvrobj%get_qfrommvr(n)
6233 call this%budobj%budterm(idx)%update_term(n, n, q)
6238 call this%budobj%budterm(idx)%reset(this%noutlets)
6239 do n = 1, this%noutlets
6241 q = this%pakmvrobj%get_qtomvr(n)
6245 call this%budobj%budterm(idx)%update_term(n1, n1, q)
6254 allocate (auxvartmp(naux))
6255 call this%budobj%budterm(idx)%reset(this%nlakes)
6256 do n = 1, this%nlakes
6260 auxvartmp(jj) = this%featureauxvar(jj, ii)
6262 call this%budobj%budterm(idx)%update_term(n, n, q, auxvartmp)
6264 deallocate (auxvartmp)
6268 call this%budobj%accumulate_terms()
6269 end subroutine lak_fill_budobj
6276 subroutine lak_setup_tableobj(this)
6280 class(laktype) :: this
6282 integer(I4B) :: nterms
6283 character(len=LINELENGTH) :: title
6284 character(len=LINELENGTH) :: text
6287 if (this%iprhed > 0)
then
6294 if (this%inamedbound == 1)
then
6299 title = trim(adjustl(this%text))//
' PACKAGE ('// &
6300 trim(adjustl(this%packName))//
') STAGES FOR EACH CONTROL VOLUME'
6303 call table_cr(this%stagetab, this%packName, title)
6304 call this%stagetab%table_df(this%nlakes, nterms, this%iout, &
6308 if (this%inamedbound == 1)
then
6310 call this%stagetab%initialize_column(text, 20, alignment=tableft)
6315 call this%stagetab%initialize_column(text, 10, alignment=tabcenter)
6319 call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6322 text =
'SURFACE AREA'
6323 call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6326 text =
'WETTED AREA'
6327 call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6331 call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6333 end subroutine lak_setup_tableobj
6337 subroutine lak_activate_density(this)
6339 class(laktype),
intent(inout) :: this
6341 integer(I4B) :: i, j
6344 if (this%iimplicit /= 0)
then
6346 'The IMPLICIT option cannot be used with the BUY package until the &
6347 &implicit formulation includes density terms. Remove the IMPLICIT &
6348 &option from LAK package '//trim(this%packName)//
' to simulate &
6356 call mem_reallocate(this%denseterms, 3, this%MAXBOUND,
'DENSETERMS', &
6358 do i = 1, this%maxbound
6360 this%denseterms(j, i) =
dzero
6363 write (this%iout,
'(/1x,a)')
'DENSITY TERMS HAVE BEEN ACTIVATED FOR LAKE &
6364 &PACKAGE: '//trim(adjustl(this%packName))
6365 end subroutine lak_activate_density
6371 subroutine lak_activate_viscosity(this)
6375 class(laktype),
intent(inout) :: this
6382 call mem_reallocate(this%viscratios, 2, this%MAXBOUND,
'VISCRATIOS', &
6384 do i = 1, this%maxbound
6386 this%viscratios(j, i) =
done
6389 write (this%iout,
'(/1x,a)')
'VISCOSITY HAS BEEN ACTIVATED FOR LAK &
6390 &PACKAGE: '//trim(adjustl(this%packName))
6391 end subroutine lak_activate_viscosity
6411 subroutine lak_calculate_density_exchange(this, iconn, stage, head, cond, &
6412 botl, flow, gwfhcof, gwfrhs)
6414 class(laktype),
intent(inout) :: this
6415 integer(I4B),
intent(in) :: iconn
6416 real(DP),
intent(in) :: stage
6417 real(DP),
intent(in) :: head
6418 real(DP),
intent(in) :: cond
6419 real(DP),
intent(in) :: botl
6420 real(DP),
intent(inout) :: flow
6421 real(DP),
intent(inout) :: gwfhcof
6422 real(DP),
intent(inout) :: gwfrhs
6427 real(DP) :: rdenselak
6428 real(DP) :: rdensegwf
6429 real(DP) :: rdenseavg
6435 logical(LGP) :: stage_below_bot
6436 logical(LGP) :: head_below_bot
6439 if (stage >= botl)
then
6441 stage_below_bot = .false.
6442 rdenselak = this%denseterms(1, iconn)
6445 stage_below_bot = .true.
6446 rdenselak = this%denseterms(2, iconn)
6450 if (head >= botl)
then
6452 head_below_bot = .false.
6453 rdensegwf = this%denseterms(2, iconn)
6456 head_below_bot = .true.
6457 rdensegwf = this%denseterms(1, iconn)
6461 if (rdensegwf ==
dzero)
return
6464 if (stage_below_bot .and. head_below_bot)
then
6471 rdenseavg =
dhalf * (rdenselak + rdensegwf)
6475 d1 = cond * (rdenseavg -
done)
6476 gwfhcof = gwfhcof - d1
6477 gwfrhs = gwfrhs - d1 * ss
6482 if (.not. stage_below_bot .and. .not. head_below_bot)
then
6486 elevgwf = this%denseterms(3, iconn)
6487 if (this%ictype(iconn) == 0 .or. this%ictype(iconn) == 3)
then
6494 elevavg =
dhalf * (elevlak + elevgwf)
6495 havg =
dhalf * (hh + ss)
6496 d2 = cond * (havg - elevavg) * (rdensegwf - rdenselak)
6497 gwfrhs = gwfrhs + d2
6501 end subroutine lak_calculate_density_exchange
This module contains the extended boundary package.
This module contains the base boundary package.
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
@ tabucstring
upper case string table data
@ tabstring
string table data
@ tabinteger
integer table data
integer(i4b), parameter lenpackagename
maximum length of the package name
real(dp), parameter dp9
real constant 9/10
integer(i4b), parameter iwetlake
integer constant for a dry lake
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 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 dem1
real constant 1e-1
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 dgravity
real constant gravitational acceleration (m/(s s))
real(dp), parameter dpi
real constant
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 dcd
real constant weir coefficient in SI units
real(dp), parameter dem5
real constant 1e-5
real(dp), parameter dten
real constant 10
real(dp), parameter dprec
real constant machine precision
real(dp), parameter dp7
real constant 7/10
real(dp), parameter dem9
real constant 1e-9
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 dthree
real constant 3
real(dp), parameter done
real constant 1
integer(i4b) function, public get_node(ilay, irow, icol, nlay, nrow, ncol)
Get node number, given layer, row, and column indices for a structured grid. If any argument is inval...
This module defines variable data types.
subroutine lak_activate_density(this)
Activate addition of density terms.
subroutine lak_cq(this, x, flowja, iadv)
Calculate flows.
subroutine lak_nur(this, neqpak, x, xtemp, dx, inewtonur, dxmax, locmax)
Apply Newton under-relaxation to the lake stage.
subroutine lak_vol2stage(this, ilak, vol, stage)
Determine the stage from a provided volume.
subroutine lak_calculate_outlet_outflow(this, ilak, stage, avail, outoutf)
Calculate the outlet outflow from a lake.
subroutine lak_calculate_sarea(this, ilak, stage, sarea)
Calculate the surface area of a lake at a given stage.
subroutine lak_fn(this, rhs, ia, idxglo, matrix_sln)
Fill newton terms.
subroutine lak_ac(this, moffset, sparse)
Add the lake rows and columns to the sparse matrix.
subroutine lak_source_dimensions(this)
Source DIMENSIONS block from input context and load static data.
subroutine lak_ot_package_flows(this, icbcfl, ibudfl)
Output LAK package flow terms.
subroutine lak_accumulate_chterm(this, ilak, rrate, chratin, chratout)
Accumulate constant head terms for budget.
subroutine lak_get_external_mover(this, ilak, outoutf)
Get the mover outflow from a lake to an external boundary.
subroutine lak_cf(this)
Formulate the HCOF and RHS terms.
subroutine lak_calculate_density_exchange(this, iconn, stage, head, cond, botl, flow, gwfhcof, gwfrhs)
Calculate the groundwater-lake density exchange terms.
subroutine lak_source_outlets(this)
Source OUTLETS block from input context.
subroutine lak_calculate_evaporation(this, ilak, stage, avail, ev)
Calculate the evaporation from a lake at a provided stage subject to an available volume.
subroutine lak_setup_budobj(this)
Set up the budget object that stores all the lake flows.
subroutine lak_calculate_external(this, ilak, ex)
Calculate the external flow terms to a lake.
subroutine lak_source_connectiondata(this)
Source CONNECTIONDATA block from input context.
subroutine lak_calculate_warea(this, ilak, stage, warea, hin)
Calculate the wetted area of a lake at a given stage.
subroutine lak_calculate_vol(this, ilak, stage, volume)
Calculate the volume of a lake at a given stage.
subroutine lak_da(this)
Deallocate objects.
subroutine lak_calculate_storagechange(this, ilak, stage, stage0, delt, dvr)
Calculate the storage change in a lake based on provided stages and a passed delt.
subroutine lak_get_internal_outlet(this, ilak, outoutf)
Get the outlet from a lake to another lake.
subroutine lak_calculate_conductance(this, ilak, stage, conductance)
Calculate the total conductance for a lake at a provided stage.
subroutine laktables_to_vectors(this, laketables)
Copy the laketables structure data into flattened vectors that are stored in the memory manager.
subroutine lak_calculate_residual(this, n, hlak, resid, headp)
Calculate the residual for a lake given a passed stage.
subroutine lak_get_outlet_tomover(this, ilak, outoutf)
Get the outlet to mover from a lake.
subroutine lak_allocate_arrays(this)
Allocate scalar members.
subroutine, public lak_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath)
Create a new LAK Package and point bndobj to the new package.
subroutine lak_source_options(this)
Source OPTIONS block from input context.
subroutine lak_calculate_available(this, n, hlak, avail, ra, ro, qinf, ex, headp)
Calculate the available volumetric rate for a lake given a passed stage.
logical function lak_obs_supported(this)
Procedures related to observations (type-bound)
subroutine lak_set_pointers(this, neq, ibound, xnew, xold, flowja)
Set pointers to model arrays and variables so that a package has access to these things.
subroutine lak_calculate_inflow(this, ilak, qin)
Calculate specified inflow to a lake.
subroutine lak_calculate_conn_exchange_deriv(this, ilak, iconn, stage, head, flow, dqds, dqdh)
Lakebed seepage and its derivatives for a connection (IMPLICIT)
character(len=lenpackagename) text
subroutine lak_mc(this, moffset, matrix_sln)
Find the matrix position of each lake row and connection.
subroutine lak_set_nonneg_value(this, n, itemno, setting, value_array, label)
Apply a PERIOD lake setting and require its value be non-negative.
subroutine lak_ot_model_flows(this, icbcfl, ibudfl, icbcun, imap)
Write flows to binary file and/or print flows to budget.
subroutine lak_rp_obs(this)
Process each observation.
subroutine lak_calculate_conn_conductance(this, ilak, iconn, stage, head, cond)
Calculate the conductance for a lake connection at a provided stage and groundwater head.
subroutine lak_calculate_exchange(this, ilak, stage, totflow)
Calculate the total groundwater-lake flow at a provided stage.
subroutine lak_linear_interpolation(this, n, x, y, z, v)
Perform linear interpolation of two vectors.
subroutine lak_input_destroy(this)
Nullify all LakInputType pointers.
subroutine lak_source_packagedata(this)
Source PACKAGEDATA block from input context.
subroutine lak_setup_tableobj(this)
Set up the table object that is used to write the lak stage data.
subroutine lak_ot_dv(this, idvsave, idvprint)
Save LAK-calculated values to binary file.
subroutine lak_get_external_outlet(this, ilak, outoutf)
Get the outlet outflow from a lake to an external boundary.
subroutine lak_calculate_rainfall(this, ilak, stage, ra)
Calculate the rainfall for a lake.
subroutine lak_get_internal_inlet(this, ilak, outinf)
Get the outlet inflow to a lake from another lake.
subroutine lak_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
Final convergence check for package.
subroutine lak_rp(this)
Read and prepare (stress period data)
subroutine lak_activate_viscosity(this)
Activate viscosity terms.
subroutine lak_read_initial_attr(this)
Read the initial parameters for this package.
integer(i4b) function lak_check_valid(this, itemno)
Determine if a valid lake or outlet number has been specified.
subroutine lak_bisection(this, n, ibflg, hlak, temporary_stage, dh, residual)
@ brief Lake package bisection method
subroutine lak_ad(this)
Add package connection to matrix.
character(len=lenftype) ftype
subroutine lak_fc(this, rhs, ia, idxglo, matrix_sln)
Copy rhs and hcof into solution rhs and amat.
subroutine lak_set_attribute_error(this, ilak, keyword, msg)
Issue a parameter error for lake ilak.
subroutine lak_calculate_runoff(this, ilak, ro)
Calculate runoff to a lake.
subroutine define_listlabel(this)
Define the list heading that is written to iout when PRINT_INPUT option is used.
subroutine lak_calculate_withdrawal(this, ilak, avail, wr)
Calculate the withdrawal from a lake subject to an available volume.
subroutine lak_calculate_conn_warea(this, ilak, iconn, stage, head, wa)
Calculate the wetted area of a lake connection at a given stage.
subroutine lak_solve(this, update, only_legacy)
Solve for lake stage.
subroutine lak_estimate_seepage_single(this, n, ncnv)
Estimate the lakebed seepage for a single lake.
subroutine lak_source_table(this, ilak, mempath, laketable)
Source one lake's table from its LAKTAB6 subpackage.
subroutine lak_df_obs(this)
Store observation type supported by LAK package. Overrides BndTypebnd_df_obs.
subroutine lak_allocate_scalars(this)
Allocate scalar members.
subroutine lak_bound_update(this)
Store the lake head and connection conductance in the bound array.
subroutine lak_calculate_cond_head(this, iconn, stage, head, vv)
Calculate the controlling lake stage or groundwater head used to calculate the conductance for a lake...
subroutine lak_ot_bdsummary(this, kstp, kper, iout, ibudfl)
Write LAK budget to listing file.
subroutine lak_bd_obs(this)
Calculate observations this time step and call ObsTypeSaveOneSimval for each LakType observation.
subroutine lak_estimate_conn_exchange(this, iflag, ilak, iconn, idry, stage, head, flow, source, gwfhcof, gwfrhs)
Calculate the groundwater-lake flow at a provided stage and groundwater head.
subroutine lak_fill_budobj(this)
Copy flow terms into thisbudobj.
subroutine lak_get_internal_mover(this, ilak, outoutf)
Get the mover outflow from a lake to another lake.
subroutine lak_calculate_outlet_inflow(this, ilak, outinf)
Calculate the outlet inflow to a lake.
subroutine lak_outlet_outflow_rate(this, ilak, stage, qout)
Total uncapped outlet outflow rate from a lake at a provided stage.
subroutine lak_calculate_conn_exchange(this, ilak, iconn, stage, head, flow, gwfhcof, gwfrhs)
Calculate the groundwater-lake flow at a provided stage and groundwater head.
subroutine lak_source_tables(this)
Source TABLES block from input context.
subroutine lak_ar(this)
Allocate and Read.
subroutine lak_input_init(this, mempath, naux, noutlets)
Bind LakInputType pointers.
subroutine lak_solve_single(this, n, iter, maxiter, ncnv, lupdate)
Advance one lake stage by a single substitution iteration.
pure logical function, public is_close(a, b, rtol, atol, symmetric)
Check if a real value is approximately equal to another.
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.
This module contains the derived type ObsType.
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
integer(i4b) ifailedstepretry
current retry for this time step
character(len=maxcharlen) warnmsg
warning message string
real(dp) function squadraticsaturation(top, bot, x, eps)
@ brief sQuadraticSaturation
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
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
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
This class is used to store a single deferred-length character string. It was designed to work in an ...