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()
80 integer(I4B),
dimension(:),
pointer :: invert_tslink => null()
81 integer(I4B),
dimension(:),
pointer :: width_tslink => null()
82 integer(I4B),
dimension(:),
pointer :: rough_tslink => null()
83 integer(I4B),
dimension(:),
pointer :: slope_tslink => null()
92 character(len=16),
dimension(:),
pointer,
contiguous :: clakbudget => null()
93 character(len=16),
dimension(:),
pointer,
contiguous :: cauxcbc => null()
96 integer(I4B),
pointer :: iprhed => null()
97 integer(I4B),
pointer :: istageout => null()
98 integer(I4B),
pointer :: ibudgetout => null()
99 integer(I4B),
pointer :: ibudcsv => null()
100 integer(I4B),
pointer :: ipakcsv => null()
101 character(len=:),
allocatable :: pakcsvfile
102 integer(I4B),
pointer :: cbcauxitems => null()
103 integer(I4B),
pointer :: nlakes => null()
104 integer(I4B),
pointer :: noutlets => null()
105 integer(I4B),
pointer :: ntables => null()
106 real(dp),
pointer :: convlength => null()
107 real(dp),
pointer :: convtime => null()
108 real(dp),
pointer :: outdmax => null()
109 integer(I4B),
pointer :: igwhcopt => null()
110 integer(I4B),
pointer :: iconvchk => null()
111 integer(I4B),
pointer :: maxlakit => null()
112 real(dp),
pointer :: surfdep => null()
113 real(dp),
pointer :: dmaxchg => null()
114 real(dp),
pointer :: delh => null()
115 integer(I4B),
pointer :: check_attr => null()
118 integer(I4B),
pointer :: iimplicit => null()
119 integer(I4B),
pointer :: iforceleg => null()
120 integer(I4B),
pointer :: iforceleglak => null()
122 integer(I4B),
pointer :: bditems => null()
125 integer(I4B),
dimension(:),
pointer,
contiguous :: nlakeconn => null()
126 integer(I4B),
dimension(:),
pointer,
contiguous :: idxlakeconn => null()
127 integer(I4B),
dimension(:),
pointer,
contiguous :: ntabrow => null()
128 real(dp),
dimension(:),
pointer,
contiguous :: strt => null()
129 real(dp),
dimension(:),
pointer,
contiguous :: laketop => null()
130 real(dp),
dimension(:),
pointer,
contiguous :: lakebot => null()
131 real(dp),
dimension(:),
pointer,
contiguous :: sareamax => null()
132 character(len=LENBOUNDNAME),
dimension(:),
pointer, &
133 contiguous :: lakename => null()
134 character(len=8),
dimension(:),
pointer,
contiguous :: status => null()
135 real(dp),
dimension(:),
pointer,
contiguous :: avail => null()
136 real(dp),
dimension(:),
pointer,
contiguous :: lkgwsink => null()
137 real(dp),
dimension(:),
pointer,
contiguous :: stage => null()
138 real(dp),
dimension(:),
pointer,
contiguous :: rainfall => null()
139 real(dp),
dimension(:),
pointer,
contiguous :: evaporation => null()
140 real(dp),
dimension(:),
pointer,
contiguous :: runoff => null()
141 real(dp),
dimension(:),
pointer,
contiguous :: inflow => null()
142 real(dp),
dimension(:),
pointer,
contiguous :: withdrawal => null()
145 integer(I4B),
dimension(:),
pointer,
contiguous :: ialaktab => null()
146 real(dp),
dimension(:),
pointer,
contiguous :: tabstage => null()
147 real(dp),
dimension(:),
pointer,
contiguous :: tabvolume => null()
148 real(dp),
dimension(:),
pointer,
contiguous :: tabsarea => null()
149 real(dp),
dimension(:),
pointer,
contiguous :: tabwarea => null()
152 integer(I4B),
dimension(:),
pointer,
contiguous :: ncncvr => null()
156 integer(I4B),
dimension(:),
pointer,
contiguous :: ilegacy => null()
157 integer(I4B),
dimension(:),
pointer,
contiguous :: nstuck => null()
158 real(dp),
dimension(:),
pointer,
contiguous :: surfin => null()
159 real(dp),
dimension(:),
pointer,
contiguous :: surfout => null()
160 real(dp),
dimension(:),
pointer,
contiguous :: surfout1 => null()
161 real(dp),
dimension(:),
pointer,
contiguous :: precip => null()
162 real(dp),
dimension(:),
pointer,
contiguous :: precip1 => null()
163 real(dp),
dimension(:),
pointer,
contiguous :: evap => null()
164 real(dp),
dimension(:),
pointer,
contiguous :: evap1 => null()
165 real(dp),
dimension(:),
pointer,
contiguous :: evapo => null()
166 real(dp),
dimension(:),
pointer,
contiguous :: withr => null()
167 real(dp),
dimension(:),
pointer,
contiguous :: withr1 => null()
168 real(dp),
dimension(:),
pointer,
contiguous :: flwin => null()
169 real(dp),
dimension(:),
pointer,
contiguous :: flwiter => null()
170 real(dp),
dimension(:),
pointer,
contiguous :: flwiter1 => null()
171 real(dp),
dimension(:),
pointer,
contiguous :: seep => null()
172 real(dp),
dimension(:),
pointer,
contiguous :: seep1 => null()
173 real(dp),
dimension(:),
pointer,
contiguous :: seep0 => null()
174 real(dp),
dimension(:),
pointer,
contiguous :: stageiter => null()
175 real(dp),
dimension(:),
pointer,
contiguous :: chterm => null()
178 integer(I4B),
dimension(:),
pointer,
contiguous :: iseepc => null()
179 integer(I4B),
dimension(:),
pointer,
contiguous :: idhc => null()
180 real(dp),
dimension(:),
pointer,
contiguous :: en1 => null()
181 real(dp),
dimension(:),
pointer,
contiguous :: en2 => null()
182 real(dp),
dimension(:),
pointer,
contiguous :: r1 => null()
183 real(dp),
dimension(:),
pointer,
contiguous :: r2 => null()
184 real(dp),
dimension(:),
pointer,
contiguous :: dh0 => null()
185 real(dp),
dimension(:),
pointer,
contiguous :: s0 => null()
186 real(dp),
dimension(:),
pointer,
contiguous :: qgwf0 => null()
188 integer(I4B),
dimension(:),
pointer,
contiguous :: idxlocnode => null()
189 integer(I4B),
dimension(:),
pointer,
contiguous :: idxdiag => null()
190 integer(I4B),
dimension(:),
pointer,
contiguous :: idxoffdglo => null()
191 integer(I4B),
dimension(:),
pointer,
contiguous :: idxsymdglo => null()
192 integer(I4B),
dimension(:),
pointer,
contiguous :: idxsymoffdglo => null()
195 integer(I4B),
dimension(:),
pointer,
contiguous :: imap => null()
196 integer(I4B),
dimension(:),
pointer,
contiguous :: gwfconn => null()
197 integer(I4B),
dimension(:),
pointer,
contiguous :: nodesontop => null()
198 integer(I4B),
dimension(:),
pointer,
contiguous :: ictype => null()
199 real(dp),
dimension(:),
pointer,
contiguous :: bedleak => null()
200 real(dp),
dimension(:),
pointer,
contiguous :: belev => null()
201 real(dp),
dimension(:),
pointer,
contiguous :: telev => null()
202 real(dp),
dimension(:),
pointer,
contiguous :: connlength => null()
203 real(dp),
dimension(:),
pointer,
contiguous :: connwidth => null()
204 real(dp),
dimension(:),
pointer,
contiguous :: sarea => null()
205 real(dp),
dimension(:),
pointer,
contiguous :: warea => null()
206 real(dp),
dimension(:),
pointer,
contiguous :: satcond => null()
207 real(dp),
dimension(:),
pointer,
contiguous :: simcond => null()
208 real(dp),
dimension(:),
pointer,
contiguous :: simlakgw => null()
211 integer(I4B),
dimension(:),
pointer,
contiguous :: lakein => null()
212 integer(I4B),
dimension(:),
pointer,
contiguous :: lakeout => null()
213 integer(I4B),
dimension(:),
pointer,
contiguous :: iouttype => null()
214 real(dp),
dimension(:),
pointer,
contiguous :: outrate => null()
215 real(dp),
dimension(:),
pointer,
contiguous :: outinvert => null()
216 real(dp),
dimension(:),
pointer,
contiguous :: outwidth => null()
217 real(dp),
dimension(:),
pointer,
contiguous :: outrough => null()
218 real(dp),
dimension(:),
pointer,
contiguous :: outslope => null()
219 real(dp),
dimension(:),
pointer,
contiguous :: simoutrate => null()
223 logical(LGP),
dimension(:),
pointer,
contiguous :: outlet_invert_set => null()
224 logical(LGP),
dimension(:),
pointer,
contiguous :: outlet_width_set => null()
225 logical(LGP),
dimension(:),
pointer,
contiguous :: outlet_rough_set => null()
226 logical(LGP),
dimension(:),
pointer,
contiguous :: outlet_slope_set => null()
229 real(dp),
dimension(:),
pointer,
contiguous :: qauxcbc => null()
230 real(dp),
dimension(:),
pointer,
contiguous :: dbuff => null()
231 real(dp),
dimension(:),
pointer,
contiguous :: qleak => null()
235 real(dp),
dimension(:),
pointer,
contiguous :: holdconn => null()
236 real(dp),
dimension(:),
pointer,
contiguous :: qsto => null()
239 integer(I4B),
pointer :: gwfiss => null()
240 real(dp),
dimension(:),
pointer,
contiguous :: gwfk11 => null()
241 real(dp),
dimension(:),
pointer,
contiguous :: gwfk33 => null()
242 real(dp),
dimension(:),
pointer,
contiguous :: gwfsat => null()
243 integer(I4B),
pointer :: gwfik33 => null()
246 integer(I4B),
dimension(:),
pointer,
contiguous :: iboundpak => null()
247 real(dp),
dimension(:),
pointer,
contiguous :: xnewpak => null()
248 real(dp),
dimension(:),
pointer,
contiguous :: xoldpak => null()
261 integer(I4B),
pointer :: idense
262 real(dp),
dimension(:, :),
pointer,
contiguous :: denseterms => null()
265 real(dp),
dimension(:, :),
pointer,
contiguous :: viscratios => null()
288 procedure,
private :: lak_set_legacy
289 procedure,
private :: lak_check_disconnected
343 procedure,
private :: lak_fc_implicit
344 procedure,
private :: lak_budget_nogwf
365 module subroutine lak_budget_nogwf(this, n, stage, b)
366 class(laktype),
intent(inout) :: this
367 integer(I4B),
intent(in) :: n
368 real(dp),
intent(in) :: stage
369 real(dp),
intent(inout) :: b
374 module subroutine lak_fc_implicit(this, rhs, matrix_sln)
375 class(laktype) :: this
376 real(dp),
dimension(:),
intent(inout) :: rhs
382 module subroutine lak_set_legacy(this, kiter, icnvgmod)
383 class(laktype),
intent(inout) :: this
384 integer(I4B),
intent(in) :: kiter
385 integer(I4B),
intent(in) :: icnvgmod
390 module subroutine lak_check_disconnected(this)
391 class(laktype),
intent(inout) :: this
399 subroutine lak_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
404 class(
bndtype),
pointer :: packobj
405 integer(I4B),
intent(in) :: id
406 integer(I4B),
intent(in) :: ibcnum
407 integer(I4B),
intent(in) :: inunit
408 integer(I4B),
intent(in) ::
iout
409 character(len=*),
intent(in) :: namemodel
410 character(len=*),
intent(in) :: pakname
411 character(len=*),
intent(in) :: mempath
413 type(laktype),
pointer :: lakobj
420 call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
424 call lakobj%lak_allocate_scalars()
427 call packobj%pack_initialize()
429 packobj%inunit = inunit
432 packobj%ibcnum = ibcnum
437 end subroutine lak_create
441 subroutine lak_allocate_scalars(this)
443 class(laktype),
intent(inout) :: this
446 call this%BndExtType%allocate_scalars()
449 call mem_allocate(this%iprhed,
'IPRHED', this%memoryPath)
450 call mem_allocate(this%istageout,
'ISTAGEOUT', this%memoryPath)
451 call mem_allocate(this%ibudgetout,
'IBUDGETOUT', this%memoryPath)
452 call mem_allocate(this%ibudcsv,
'IBUDCSV', this%memoryPath)
453 call mem_allocate(this%ipakcsv,
'IPAKCSV', this%memoryPath)
454 call mem_allocate(this%nlakes,
'NLAKES', this%memoryPath)
455 call mem_allocate(this%noutlets,
'NOUTLETS', this%memoryPath)
456 call mem_allocate(this%ntables,
'NTABLES', this%memoryPath)
457 call mem_allocate(this%convlength,
'CONVLENGTH', this%memoryPath)
458 call mem_allocate(this%convtime,
'CONVTIME', this%memoryPath)
459 call mem_allocate(this%outdmax,
'OUTDMAX', this%memoryPath)
460 call mem_allocate(this%igwhcopt,
'IGWHCOPT', this%memoryPath)
461 call mem_allocate(this%iconvchk,
'ICONVCHK', this%memoryPath)
462 call mem_allocate(this%maxlakit,
'MAXLAKIT', this%memoryPath)
463 call mem_allocate(this%surfdep,
'SURFDEP', this%memoryPath)
464 call mem_allocate(this%dmaxchg,
'DMAXCHG', this%memoryPath)
466 call mem_allocate(this%check_attr,
'CHECK_ATTR', this%memoryPath)
467 call mem_allocate(this%iimplicit,
'IIMPLICIT', this%memoryPath)
468 call mem_allocate(this%iforceleg,
'IFORCELEG', this%memoryPath)
469 call mem_allocate(this%iforceleglak,
'IFORCELEGLAK', this%memoryPath)
470 call mem_allocate(this%bditems,
'BDITEMS', this%memoryPath)
471 call mem_allocate(this%cbcauxitems,
'CBCAUXITEMS', this%memoryPath)
472 call mem_allocate(this%idense,
'IDENSE', this%memoryPath)
483 this%convlength =
done
491 this%delh =
dp999 * this%dmaxchg
494 this%iforceleglak = 0
499 end subroutine lak_allocate_scalars
503 subroutine lak_allocate_arrays(this)
506 class(laktype),
intent(inout) :: this
511 call this%BndExtType%allocate_arrays()
514 call this%BndExtType%allocate_featureauxvar()
517 allocate (this%clakbudget(this%bditems))
520 this%clakbudget(1) =
' GWF'
521 this%clakbudget(2) =
' RAINFALL'
522 this%clakbudget(3) =
' EVAPORATION'
523 this%clakbudget(4) =
' RUNOFF'
524 this%clakbudget(5) =
' EXT-INFLOW'
525 this%clakbudget(6) =
' WITHDRAWAL'
526 this%clakbudget(7) =
' EXT-OUTFLOW'
527 this%clakbudget(8) =
' STORAGE'
528 this%clakbudget(9) =
' CONSTANT'
529 this%clakbudget(10) =
' FROM-MVR'
530 this%clakbudget(11) =
' TO-MVR'
533 if (this%istageout > 0)
then
534 call mem_allocate(this%dbuff, this%nlakes,
'DBUFF', this%memoryPath)
535 do i = 1, this%nlakes
536 this%dbuff(i) =
dzero
539 call mem_allocate(this%dbuff, 0,
'DBUFF', this%memoryPath)
543 allocate (this%cauxcbc(this%cbcauxitems))
546 call mem_allocate(this%qauxcbc, this%cbcauxitems,
'QAUXCBC', this%memoryPath)
547 do i = 1, this%cbcauxitems
548 this%qauxcbc(i) =
dzero
552 call mem_allocate(this%qleak, this%maxbound,
'QLEAK', this%memoryPath)
553 do i = 1, this%maxbound
554 this%qleak(i) =
dzero
558 if (this%iimplicit /= 0)
then
559 call mem_allocate(this%holdconn, this%maxbound,
'HOLDCONN', this%memoryPath)
560 do i = 1, this%maxbound
561 this%holdconn(i) =
dzero
564 call mem_allocate(this%holdconn, 0,
'HOLDCONN', this%memoryPath)
566 call mem_allocate(this%qsto, this%nlakes,
'QSTO', this%memoryPath)
567 do i = 1, this%nlakes
572 call mem_allocate(this%denseterms, 3, 0,
'DENSETERMS', this%memoryPath)
575 call mem_allocate(this%viscratios, 2, 0,
'VISCRATIOS', this%memoryPath)
576 end subroutine lak_allocate_arrays
588 subroutine lak_checkin_deprecated_names(this)
593 class(laktype),
intent(inout) :: this
595 real(DP),
dimension(:, :),
pointer,
contiguous :: aux => null()
596 integer(I4B) :: isize
601 'STAGE', this%input_mempath,
'6.8.2')
603 'RAINFALL', this%input_mempath,
'6.8.2')
605 this%memoryPath,
'EVAPORATION', &
606 this%input_mempath,
'6.8.2')
608 'RUNOFF', this%input_mempath,
'6.8.2')
610 'INFLOW', this%input_mempath,
'6.8.2')
612 'WITHDRAWAL', this%input_mempath,
'6.8.2')
616 'RATE', this%input_mempath,
'6.8.2')
618 'INVERT', this%input_mempath,
'6.8.2')
620 'WIDTH', this%input_mempath,
'6.8.2')
622 'SLOPE', this%input_mempath,
'6.8.2')
624 'ROUGH', this%input_mempath,
'6.8.2')
627 call get_isize(
'AUX', this%input_mempath, isize)
629 call mem_setptr(aux,
'AUX', this%input_mempath)
631 'AUX', this%input_mempath,
'6.8.2')
637 'GWFCONN', this%memoryPath,
'6.8.2')
639 'ILEGACY', this%memoryPath,
'6.8.2')
641 'IFORCELEG', this%memoryPath,
'6.8.2')
642 end subroutine lak_checkin_deprecated_names
646 subroutine lak_source_packagedata(this)
648 class(laktype),
intent(inout) :: this
651 integer(I4B) :: ilak, nconn
652 character(len=9) :: cno
653 character(len=LENBOUNDNAME) :: bndName
654 integer(I4B),
dimension(:),
pointer,
contiguous :: ifno => null()
655 real(DP),
dimension(:),
pointer,
contiguous :: strt => null()
656 integer(I4B),
dimension(:),
pointer,
contiguous :: nlakeconn => null()
658 boundname_cst => null()
659 integer(I4B),
allocatable :: nboundchk(:)
661 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text))// &
665 call mem_allocate(this%nlakeconn, this%nlakes,
'NLAKECONN', this%memoryPath)
666 call mem_allocate(this%idxlakeconn, this%nlakes + 1,
'IDXLAKECONN', &
668 call mem_allocate(this%ntabrow, this%nlakes,
'NTABROW', this%memoryPath)
669 call mem_allocate(this%strt, this%nlakes,
'STRT', this%memoryPath)
670 call mem_allocate(this%laketop, this%nlakes,
'LAKETOP', this%memoryPath)
671 call mem_allocate(this%lakebot, this%nlakes,
'LAKEBOT', this%memoryPath)
672 call mem_allocate(this%sareamax, this%nlakes,
'SAREAMAX', this%memoryPath)
675 call mem_setptr(this%stage,
'STAGE', this%input_mempath)
676 call mem_setptr(this%rainfall,
'RAINFALL', this%input_mempath)
677 call mem_setptr(this%evaporation,
'EVAPORATION', this%input_mempath)
678 call mem_setptr(this%runoff,
'RUNOFF', this%input_mempath)
679 call mem_setptr(this%inflow,
'INFLOW', this%input_mempath)
680 call mem_setptr(this%withdrawal,
'WITHDRAWAL', this%input_mempath)
681 call mem_allocate(this%avail, this%nlakes,
'AVAIL', this%memoryPath)
682 call mem_allocate(this%lkgwsink, this%nlakes,
'LKGWSINK', this%memoryPath)
683 call mem_allocate(this%ncncvr, this%nlakes,
'NCNCVR', this%memoryPath)
684 call mem_allocate(this%ilegacy, this%nlakes,
'ILEGACY', this%memoryPath)
685 call mem_allocate(this%nstuck, this%nlakes,
'NSTUCK', this%memoryPath)
686 call mem_allocate(this%surfin, this%nlakes,
'SURFIN', this%memoryPath)
687 call mem_allocate(this%surfout, this%nlakes,
'SURFOUT', this%memoryPath)
688 call mem_allocate(this%surfout1, this%nlakes,
'SURFOUT1', this%memoryPath)
689 call mem_allocate(this%precip, this%nlakes,
'PRECIP', this%memoryPath)
690 call mem_allocate(this%precip1, this%nlakes,
'PRECIP1', this%memoryPath)
691 call mem_allocate(this%evap, this%nlakes,
'EVAP', this%memoryPath)
692 call mem_allocate(this%evap1, this%nlakes,
'EVAP1', this%memoryPath)
693 call mem_allocate(this%evapo, this%nlakes,
'EVAPO', this%memoryPath)
694 call mem_allocate(this%withr, this%nlakes,
'WITHR', this%memoryPath)
695 call mem_allocate(this%withr1, this%nlakes,
'WITHR1', this%memoryPath)
696 call mem_allocate(this%flwin, this%nlakes,
'FLWIN', this%memoryPath)
697 call mem_allocate(this%flwiter, this%nlakes,
'FLWITER', this%memoryPath)
698 call mem_allocate(this%flwiter1, this%nlakes,
'FLWITER1', this%memoryPath)
699 call mem_allocate(this%seep, this%nlakes,
'SEEP', this%memoryPath)
700 call mem_allocate(this%seep1, this%nlakes,
'SEEP1', this%memoryPath)
701 call mem_allocate(this%seep0, this%nlakes,
'SEEP0', this%memoryPath)
702 call mem_allocate(this%stageiter, this%nlakes,
'STAGEITER', this%memoryPath)
703 call mem_allocate(this%chterm, this%nlakes,
'CHTERM', this%memoryPath)
709 if (this%iimplicit == 0)
then
710 call mem_allocate(this%iboundpak, this%nlakes,
'IBOUND', this%memoryPath)
711 call mem_allocate(this%xnewpak, this%nlakes,
'XNEWPAK', this%memoryPath)
713 call mem_allocate(this%xoldpak, this%nlakes,
'XOLDPAK', this%memoryPath)
716 call mem_allocate(this%iseepc, this%nlakes,
'ISEEPC', this%memoryPath)
717 call mem_allocate(this%idhc, this%nlakes,
'IDHC', this%memoryPath)
718 call mem_allocate(this%en1, this%nlakes,
'EN1', this%memoryPath)
719 call mem_allocate(this%en2, this%nlakes,
'EN2', this%memoryPath)
720 call mem_allocate(this%r1, this%nlakes,
'R1', this%memoryPath)
721 call mem_allocate(this%r2, this%nlakes,
'R2', this%memoryPath)
722 call mem_allocate(this%dh0, this%nlakes,
'DH0', this%memoryPath)
723 call mem_allocate(this%s0, this%nlakes,
'S0', this%memoryPath)
724 call mem_allocate(this%qgwf0, this%nlakes,
'QGWF0', this%memoryPath)
727 allocate (this%lakename(this%nlakes))
728 allocate (this%status(this%nlakes))
731 do n = 1, this%nlakes
733 this%status(n) =
'ACTIVE'
734 this%laketop(n) = -
dep20
735 this%lakebot(n) =
dep20
736 this%sareamax(n) =
dzero
741 if (this%iimplicit == 0)
then
742 this%iboundpak(n) = 1
743 this%xnewpak(n) =
dep20
745 this%xoldpak(n) =
dep20
746 this%rainfall(n) =
dzero
747 this%evaporation(n) =
dzero
748 this%runoff(n) =
dzero
749 this%inflow(n) =
dzero
750 this%withdrawal(n) =
dzero
756 call mem_setptr(ifno,
'PACKAGEDATA_IFNO', this%input_mempath)
757 call mem_setptr(strt,
'STRT', this%input_mempath)
758 call mem_setptr(nlakeconn,
'NLAKECONN', this%input_mempath)
759 if (this%inamedbound /= 0)
then
760 call mem_setptr(boundname_cst,
'BOUNDNAME', this%input_mempath)
764 allocate (nboundchk(this%nlakes))
769 do n = 1, this%nlakes
772 ilak = this%validate_ifno(ifno(n), this%nlakes, nboundchk, &
773 'lakeno',
'PACKAGEDATA')
777 this%strt(ilak) = strt(n)
780 if (nlakeconn(n) < 0)
then
781 write (
errmsg,
'(a,1x,i0)')
'nlakeconn MUST BE >= 0 for lake ', ilak
788 if (this%iimplicit /= 0 .and. nlakeconn(n) == 0)
then
789 write (
errmsg,
'(a,1x,i0,1x,a)') &
790 'lake', ilak,
'has no connections; the IMPLICIT option requires &
791 &each lake to have at least one GWF connection.'
795 nconn = nconn + nlakeconn(n)
796 this%nlakeconn(ilak) = nlakeconn(n)
799 write (cno,
'(i9.9)') ilak
800 bndname =
'Lake'//cno
803 if (this%inamedbound /= 0)
then
804 bndname = boundname_cst(n)
805 if (trim(bndname) ==
'')
then
806 write (cno,
'(i9.9)') ilak
807 bndname =
'Lake'//cno
810 this%lakename(ilak) = bndname
814 call this%report_ifno_coverage(nboundchk, this%nlakes,
'lake', &
817 write (this%iout,
'(1x,a)')
'END OF '//trim(adjustl(this%text))// &
826 this%MAXBOUND = nconn
827 write (this%iout,
'(//4x,a,i7)')
'MAXBOUND = ', this%maxbound
830 this%idxlakeconn(1) = 1
831 do n = 1, this%nlakes
832 this%idxlakeconn(n + 1) = this%idxlakeconn(n) + this%nlakeconn(n)
836 deallocate (nboundchk)
843 end subroutine lak_source_packagedata
847 subroutine lak_source_connectiondata(this)
849 class(laktype),
intent(inout) :: this
851 integer(I4B) :: n, j, ipos, nn
852 integer(I4B) :: ilak, iconn
853 integer(I4B) :: ipos0, icellid0, icellid, nn2
854 logical(LGP) :: is_lake_bed
855 character(len=LINELENGTH) :: cellid_str
856 character(len=LINELENGTH) :: ctypenm
857 character(len=LINELENGTH) :: cbleak
858 real(DP) :: top, bot, rval
859 integer(I4B),
dimension(:),
pointer,
contiguous :: ifno => null()
860 integer(I4B),
dimension(:),
pointer,
contiguous :: iconns => null()
861 integer(I4B),
dimension(:, :),
pointer,
contiguous :: cellid => null()
866 real(DP),
dimension(:),
pointer,
contiguous :: belev => null()
867 real(DP),
dimension(:),
pointer,
contiguous :: telev => null()
868 real(DP),
dimension(:),
pointer,
contiguous :: connlen => null()
869 real(DP),
dimension(:),
pointer,
contiguous :: connwidth => null()
870 integer(I4B),
allocatable :: nboundchk(:)
873 call mem_allocate(this%imap, this%MAXBOUND,
'IMAP', this%memoryPath)
874 call mem_allocate(this%gwfconn, this%MAXBOUND,
'GWFCONN', this%memoryPath)
875 call mem_allocate(this%nodesontop, this%MAXBOUND,
'NODESONTOP', &
877 call mem_allocate(this%ictype, this%MAXBOUND,
'ICTYPE', this%memoryPath)
878 call mem_allocate(this%bedleak, this%MAXBOUND,
'BEDLEAK', this%memoryPath)
879 call mem_allocate(this%belev, this%MAXBOUND,
'BELEV', this%memoryPath)
880 call mem_allocate(this%telev, this%MAXBOUND,
'TELEV', this%memoryPath)
881 call mem_allocate(this%connlength, this%MAXBOUND,
'CONNLENGTH', &
883 call mem_allocate(this%connwidth, this%MAXBOUND,
'CONNWIDTH', &
885 call mem_allocate(this%sarea, this%MAXBOUND,
'SAREA', this%memoryPath)
886 call mem_allocate(this%warea, this%MAXBOUND,
'WAREA', this%memoryPath)
887 call mem_allocate(this%satcond, this%MAXBOUND,
'SATCOND', this%memoryPath)
888 call mem_allocate(this%simcond, this%MAXBOUND,
'SIMCOND', this%memoryPath)
889 call mem_allocate(this%simlakgw, this%MAXBOUND,
'SIMLAKGW', this%memoryPath)
891 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text))// &
895 call mem_setptr(ifno,
'CONNDATA_IFNO', this%input_mempath)
896 call mem_setptr(iconns,
'ICONN', this%input_mempath)
897 call mem_setptr(cellid,
'CELLID', this%input_mempath)
898 call mem_setptr(claktype,
'CLAKTYPE', this%input_mempath)
899 call mem_setptr(bedleak,
'BEDLEAK', this%input_mempath)
900 call mem_setptr(belev,
'BELEV', this%input_mempath)
901 call mem_setptr(telev,
'TELEV', this%input_mempath)
902 call mem_setptr(connlen,
'CONNLEN', this%input_mempath)
903 call mem_setptr(connwidth,
'CONNWIDTH', this%input_mempath)
906 allocate (nboundchk(this%MAXBOUND))
909 do n = 1, this%MAXBOUND
914 if (ilak < 1 .or. ilak > this%nlakes)
then
915 write (
errmsg,
'(a,1x,i0)')
'lakeno MUST BE > 0 and <= ', this%nlakes
919 if (iconn < 1 .or. iconn > this%nlakeconn(ilak))
then
920 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
921 'iconn FOR LAKE ', ilak,
'MUST BE > 0 and <= ', this%nlakeconn(ilak)
926 ipos = this%idxlakeconn(ilak) + iconn - 1
927 this%imap(ipos) = ilak
928 nboundchk(ipos) = nboundchk(ipos) + 1
931 write (cellid_str,
'(10(i0,1x))') cellid(1:this%dis%ndim, n)
932 nn = this%dis%noder_from_cellid(cellid_str, this%inunit, this%iout)
934 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
935 'INVALID cellid FOR LAKE ', ilak,
'connection', iconn
938 this%gwfconn(ipos) = nn
939 this%nodesontop(ipos) = nn
942 ctypenm = claktype(n)
943 select case (trim(ctypenm))
945 this%ictype(ipos) = 0
947 this%ictype(ipos) = 1
949 this%ictype(ipos) = 2
951 this%ictype(ipos) = 3
953 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,a,a)') &
954 'UNKNOWN ctype FOR LAKE ', ilak,
'connection', iconn, &
955 '(', trim(ctypenm),
')'
961 select case (trim(cbleak))
963 is_lake_bed = .false.
965 write (
warnmsg,
'(2(a,1x,i0,1x),a,1pe8.1,a)') &
966 'BEDLEAK for connection', iconn,
'in lake', ilak, &
967 'is specified to be NONE. Lake connections where the lake-GWF '// &
968 'connection conductance is solely a function of aquifer '// &
969 'properties in the connected GWF cell should be specified '// &
970 'with a DNODATA (',
dnodata,
') value.'
974 read (cbleak, *) rval
976 is_lake_bed = .false.
981 this%bedleak(ipos) = rval
982 if (is_lake_bed .and. this%bedleak(ipos) <
dzero)
then
983 write (
errmsg,
'(a,1x,i0,1x,a)')
'bedleak FOR LAKE ', ilak, &
989 this%belev(ipos) = belev(n)
992 this%telev(ipos) = telev(n)
996 if (rval <=
dzero)
then
997 if (this%ictype(ipos) == 1 .or. this%ictype(ipos) == 2 .or. &
998 this%ictype(ipos) == 3)
then
999 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,a,1x,a)') &
1000 'connection length (connlen) FOR LAKE ', ilak, &
1001 ', CONNECTION NO.', iconn,
', MUST BE > 0 FOR SPECIFIED ', &
1002 'connection type (ctype)', trim(ctypenm)
1008 this%connlength(ipos) = rval
1012 if (rval <
dzero)
then
1013 if (this%ictype(ipos) == 1)
then
1014 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a)') &
1015 'cell width (connwidth) FOR LAKE ', ilak, &
1016 ' HORIZONTAL CONNECTION ', iconn,
'MUST BE >= 0'
1022 this%connwidth(ipos) = rval
1025 write (this%iout,
'(1x,a)') &
1026 'END OF '//trim(adjustl(this%text))//
' CONNECTIONDATA'
1034 do n = 1, this%nlakes
1036 do ipos = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1037 if (this%ictype(ipos) /= 2 .and. this%ictype(ipos) /= 3) cycle
1040 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a)') &
1041 'nlakeconn FOR LAKE', n,
'EMBEDDED CONNECTION', j,
' EXCEEDS 1.'
1048 do n = 1, this%nlakes
1049 ipos0 = this%idxlakeconn(n)
1050 icellid0 = this%gwfconn(ipos0)
1051 if (this%ictype(ipos0) /= 2 .and. this%ictype(ipos0) /= 3) cycle
1052 do nn2 = 1, this%nlakes
1055 do ipos = this%idxlakeconn(nn2), this%idxlakeconn(nn2 + 1) - 1
1057 icellid = this%gwfconn(ipos)
1058 if (icellid == icellid0)
then
1059 if (this%ictype(ipos) == 0)
then
1060 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1061 'EMBEDDED LAKE', n, &
1062 'CANNOT COINCIDE WITH VERTICAL CONNECTION', j, &
1072 do n = 1, this%nlakes
1074 do ipos = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1076 nn = this%gwfconn(ipos)
1077 top = this%dis%top(nn)
1078 bot = this%dis%bot(nn)
1079 if (this%ictype(ipos) == 0)
then
1080 this%telev(ipos) = top + this%surfdep
1081 this%belev(ipos) = top
1082 this%lakebot(n) = min(this%belev(ipos), this%lakebot(n))
1083 else if (this%ictype(ipos) == 1)
then
1084 if (this%belev(ipos) == this%telev(ipos))
then
1085 this%telev(ipos) = top
1086 this%belev(ipos) = bot
1088 if (this%belev(ipos) >= this%telev(ipos))
then
1089 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a)') &
1090 'telev FOR LAKE ', n,
' HORIZONTAL CONNECTION ', j, &
1093 else if (this%belev(ipos) < bot)
then
1094 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.7,1x,a)') &
1095 'belev FOR LAKE ', n,
' HORIZONTAL CONNECTION ', j, &
1096 'MUST BE >= cell bottom (', bot,
')'
1098 else if (this%telev(ipos) > top)
then
1099 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.7,1x,a)') &
1100 'telev FOR LAKE ', n,
' HORIZONTAL CONNECTION ', j, &
1101 'MUST BE <= cell top (', top,
')'
1105 this%laketop(n) = max(this%telev(ipos), this%laketop(n))
1106 this%lakebot(n) = min(this%belev(ipos), this%lakebot(n))
1107 else if (this%ictype(ipos) == 2 .or. this%ictype(ipos) == 3)
then
1108 this%telev(ipos) = top
1109 this%belev(ipos) = bot
1110 this%lakebot(n) = bot
1114 if (nboundchk(ipos) == 0)
then
1115 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1116 'NO DATA SPECIFIED FOR LAKE', n,
'CONNECTION', j
1118 else if (nboundchk(ipos) > 1)
then
1119 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1120 'DATA FOR LAKE', n,
'CONNECTION', j, &
1121 'SPECIFIED', nboundchk(ipos),
'TIMES'
1125 if (this%laketop(n) == -
dep20)
then
1126 this%laketop(n) = this%lakebot(n) + 100.
1130 deallocate (nboundchk)
1146 end subroutine lak_source_connectiondata
1150 subroutine lak_source_tables(this)
1152 class(laktype),
intent(inout) :: this
1154 integer(I4B) :: n, ntabs
1155 integer(I4B) :: ilak, iconn
1156 character(len=LENMEMPATH) :: mempath
1157 integer(I4B),
dimension(:),
pointer,
contiguous :: ifno => null()
1159 laktab6_mempaths => null()
1160 type(laktabtype),
dimension(:),
allocatable :: laketables
1161 integer(I4B),
allocatable :: nboundchk(:)
1164 if (this%ntables < 1)
return
1167 call get_isize(
'TABLES_IFNO', this%input_mempath, ntabs)
1170 'NTABLES > 0 BUT A TABLES BLOCK WAS NOT FOUND IN THE LAK INPUT.'
1174 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text))// &
1178 call mem_setptr(ifno,
'TABLES_IFNO', this%input_mempath)
1179 call mem_setptr(laktab6_mempaths,
'LAKTAB6_MEMPATH', this%input_mempath)
1184 allocate (laketables(this%nlakes))
1185 allocate (nboundchk(this%nlakes))
1189 ilak = this%validate_ifno(ifno(n), this%nlakes, nboundchk, &
1191 if (ilak == 0) cycle
1192 mempath = laktab6_mempaths(n)
1193 call this%lak_source_table(ilak, mempath, laketables(ilak))
1196 write (this%iout,
'(1x,a)')
'END OF '//trim(adjustl(this%text))//
' TABLES'
1199 if (ntabs < this%ntables)
then
1200 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1201 'TABLE DATA ARE SPECIFIED', ntabs, &
1202 'TIMES BUT NTABLES IS SET TO', this%ntables
1206 do n = 1, this%nlakes
1207 if (this%ntabrow(n) == 0) nboundchk(n) = 0
1209 call this%report_ifno_coverage(nboundchk, this%nlakes,
'lakeno', &
1210 'TABLES', check_missing=.false.)
1212 deallocate (nboundchk)
1222 call this%laktables_to_vectors(laketables)
1225 do n = 1, this%nlakes
1226 if (this%ntabrow(n) > 0)
then
1227 deallocate (laketables(n)%tabstage)
1228 deallocate (laketables(n)%tabvolume)
1229 deallocate (laketables(n)%tabsarea)
1230 iconn = this%idxlakeconn(n)
1231 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1232 deallocate (laketables(n)%tabwarea)
1236 deallocate (laketables)
1237 end subroutine lak_source_tables
1242 subroutine laktables_to_vectors(this, laketables)
1243 class(laktype),
intent(inout) :: this
1244 type(laktabtype),
intent(in),
dimension(:),
contiguous :: laketables
1246 integer(I4B) :: ntabrows
1248 integer(I4B) :: ipos
1249 integer(I4B) :: iconn
1252 call mem_allocate(this%ialaktab, this%nlakes + 1,
'IALAKTAB', this%memoryPath)
1255 this%ialaktab(1) = 1
1256 do n = 1, this%nlakes
1258 this%ialaktab(n + 1) = this%ialaktab(n) + this%ntabrow(n)
1262 ntabrows = this%ialaktab(this%nlakes + 1) - 1
1263 call mem_allocate(this%tabstage, ntabrows,
'TABSTAGE', this%memoryPath)
1264 call mem_allocate(this%tabvolume, ntabrows,
'TABVOLUME', this%memoryPath)
1265 call mem_allocate(this%tabsarea, ntabrows,
'TABSAREA', this%memoryPath)
1266 call mem_allocate(this%tabwarea, ntabrows,
'TABWAREA', this%memoryPath)
1269 do n = 1, this%nlakes
1271 do ipos = this%ialaktab(n), this%ialaktab(n + 1) - 1
1272 this%tabstage(ipos) = laketables(n)%tabstage(j)
1273 this%tabvolume(ipos) = laketables(n)%tabvolume(j)
1274 this%tabsarea(ipos) = laketables(n)%tabsarea(j)
1275 iconn = this%idxlakeconn(n)
1276 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1279 this%tabwarea(ipos) = laketables(n)%tabwarea(j)
1281 this%tabwarea(ipos) =
dzero
1286 end subroutine laktables_to_vectors
1290 subroutine lak_source_table(this, ilak, mempath, laketable)
1292 class(laktype),
intent(inout) :: this
1293 integer(I4B),
intent(in) :: ilak
1294 character(len=*),
intent(in) :: mempath
1295 type(laktabtype),
intent(inout) :: laketable
1297 integer(I4B),
pointer :: nrow => null()
1298 integer(I4B),
pointer :: ncol => null()
1299 real(DP),
dimension(:),
pointer,
contiguous :: stage => null()
1300 real(DP),
dimension(:),
pointer,
contiguous :: volume => null()
1301 real(DP),
dimension(:),
pointer,
contiguous :: sarea => null()
1302 real(DP),
dimension(:),
pointer,
contiguous :: barea => null()
1303 character(len=:),
pointer :: tabfname => null()
1304 integer(I4B) :: jmin, iconn, n, nerr0
1305 real(DP) :: vol, sa, wa, v, v0
1307 character(len=*),
parameter :: fmttaberr = &
1308 &
'(a,1x,i0,1x,a,1x,g15.6,1x,a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.6,1x,a)'
1311 call mem_setptr(tabfname,
'INPUT_FNAME', mempath)
1312 call mem_setptr(nrow,
'NROW', mempath)
1313 call mem_setptr(ncol,
'NCOL', mempath)
1319 write (
errmsg,
'(a,1x,i0)') &
1320 'LAKE TABLE NROW MUST BE > 0 FOR LAKE', ilak
1324 iconn = this%idxlakeconn(ilak)
1325 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1330 if (ncol < jmin)
then
1331 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1332 'LAKE TABLE NCOL MUST BE >=', jmin,
'FOR LAKE', ilak
1344 this%ntabrow(ilak) = nrow
1345 allocate (laketable%tabstage(nrow))
1346 allocate (laketable%tabvolume(nrow))
1347 allocate (laketable%tabsarea(nrow))
1348 call mem_setptr(stage,
'STAGE', mempath)
1349 call mem_setptr(volume,
'VOLUME', mempath)
1350 call mem_setptr(sarea,
'SAREA', mempath)
1351 laketable%tabstage = stage
1352 laketable%tabvolume = volume
1353 laketable%tabsarea = sarea
1354 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1355 allocate (laketable%tabwarea(nrow))
1356 call mem_setptr(barea,
'BAREA', mempath)
1357 laketable%tabwarea = barea
1361 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1362 do n = 1, this%ntabrow(ilak)
1363 vol = laketable%tabvolume(n)
1364 sa = laketable%tabsarea(n)
1365 wa = laketable%tabwarea(n)
1368 if (vol >
dzero)
exit
1370 this%lakebot(ilak) = laketable%tabstage(n)
1371 this%belev(ilak) = laketable%tabstage(n)
1374 n = this%ntabrow(ilak)
1375 this%sareamax(ilak) = laketable%tabsarea(n)
1379 do n = 2, this%ntabrow(ilak)
1380 v = laketable%tabstage(n)
1381 v0 = laketable%tabstage(n - 1)
1383 write (
errmsg, fmttaberr) &
1384 'TABLE STAGE ENTRY', n,
'(', laketable%tabstage(n),
') FOR LAKE ', &
1385 ilak,
'MUST BE GREATER THAN THE PREVIOUS STAGE ENTRY', &
1386 n - 1,
'(', laketable%tabstage(n - 1),
')'
1389 v = laketable%tabvolume(n)
1390 v0 = laketable%tabvolume(n - 1)
1392 write (
errmsg, fmttaberr) &
1393 'TABLE VOLUME ENTRY', n,
'(', laketable%tabvolume(n), &
1395 ilak,
'MUST BE GREATER THAN THE PREVIOUS VOLUME ENTRY', &
1396 n - 1,
'(', laketable%tabvolume(n - 1),
')'
1399 v = laketable%tabsarea(n)
1400 v0 = laketable%tabsarea(n - 1)
1402 write (
errmsg, fmttaberr) &
1403 'TABLE SURFACE AREA ENTRY', n,
'(', &
1404 laketable%tabsarea(n),
') FOR LAKE ', ilak, &
1405 'MUST BE GREATER THAN OR EQUAL TO THE PREVIOUS SURFACE AREA ENTRY', &
1406 n - 1,
'(', laketable%tabsarea(n - 1),
')'
1409 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1410 v = laketable%tabwarea(n)
1411 v0 = laketable%tabwarea(n - 1)
1413 write (
errmsg, fmttaberr) &
1414 'TABLE EXCHANGE AREA ENTRY', n,
'(', &
1415 laketable%tabwarea(n),
') FOR LAKE ', ilak, &
1416 'MUST BE GREATER THAN OR EQUAL TO THE PREVIOUS EXCHANGE AREA '// &
1417 'ENTRY', n - 1,
'(', laketable%tabwarea(n - 1),
')'
1433 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
1437 end subroutine lak_source_table
1441 subroutine lak_source_outlets(this)
1443 class(laktype),
intent(inout) :: this
1445 integer(I4B) :: n, isize, ioutlet
1446 character(len=LINELENGTH) :: keyword
1447 integer(I4B),
dimension(:),
pointer,
contiguous :: outletno => null()
1448 integer(I4B),
dimension(:),
pointer,
contiguous :: lakein => null()
1449 integer(I4B),
dimension(:),
pointer,
contiguous :: lakeout => null()
1452 real(DP),
dimension(:),
pointer,
contiguous :: outlets_invert => null()
1453 real(DP),
dimension(:),
pointer,
contiguous :: outlets_width => null()
1454 real(DP),
dimension(:),
pointer,
contiguous :: outlets_rough => null()
1455 real(DP),
dimension(:),
pointer,
contiguous :: outlets_slope => null()
1456 integer(I4B),
allocatable :: nboundchk(:)
1459 if (this%noutlets < 1)
return
1462 call get_isize(
'OUTLETS_OUTLETNO', this%input_mempath, isize)
1465 'NOUTLETS > 0 BUT AN OUTLETS BLOCK WAS NOT FOUND IN THE LAK INPUT.'
1470 call mem_allocate(this%lakein, this%noutlets,
'LAKEIN', this%memoryPath)
1471 call mem_allocate(this%lakeout, this%noutlets,
'LAKEOUT', this%memoryPath)
1472 call mem_allocate(this%iouttype, this%noutlets,
'IOUTTYPE', this%memoryPath)
1475 call mem_setptr(this%outrate,
'RATE', this%input_mempath)
1476 call mem_setptr(this%outinvert,
'INVERT', this%input_mempath)
1477 call mem_setptr(this%outwidth,
'WIDTH', this%input_mempath)
1478 call mem_setptr(this%outrough,
'ROUGH', this%input_mempath)
1479 call mem_setptr(this%outslope,
'SLOPE', this%input_mempath)
1480 call mem_allocate(this%simoutrate, this%noutlets,
'SIMOUTRATE', &
1482 call mem_allocate(this%outlet_invert_set, this%noutlets, &
1483 'INVERT_SET', this%memoryPath)
1484 call mem_allocate(this%outlet_width_set, this%noutlets, &
1485 'WIDTH_SET', this%memoryPath)
1486 call mem_allocate(this%outlet_rough_set, this%noutlets, &
1487 'ROUGH_SET', this%memoryPath)
1488 call mem_allocate(this%outlet_slope_set, this%noutlets, &
1489 'SLOPE_SET', this%memoryPath)
1490 this%outlet_invert_set = .false.
1491 this%outlet_width_set = .false.
1492 this%outlet_rough_set = .false.
1493 this%outlet_slope_set = .false.
1495 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text))// &
1499 call mem_setptr(outletno,
'OUTLETS_OUTLETNO', this%input_mempath)
1500 call mem_setptr(lakein,
'LAKEIN', this%input_mempath)
1501 call mem_setptr(lakeout,
'LAKEOUT', this%input_mempath)
1502 call mem_setptr(couttype,
'COUTTYPE', this%input_mempath)
1503 call mem_setptr(outlets_invert,
'OUTLETS_INVERT', this%input_mempath)
1504 call mem_setptr(outlets_width,
'OUTLETS_WIDTH', this%input_mempath)
1505 call mem_setptr(outlets_rough,
'OUTLETS_ROUGH', this%input_mempath)
1506 call mem_setptr(outlets_slope,
'OUTLETS_SLOPE', this%input_mempath)
1508 allocate (nboundchk(this%noutlets))
1511 do n = 1,
size(outletno)
1512 ioutlet = this%validate_ifno(outletno(n), this%noutlets, &
1513 nboundchk,
'outletno',
'OUTLETS')
1514 if (ioutlet == 0) cycle
1517 if (lakein(n) < 1 .or. lakein(n) > this%nlakes)
then
1518 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1519 'lakein FOR OUTLET ', ioutlet,
'MUST BE > 0 and <= ', this%nlakes
1522 this%lakein(ioutlet) = lakein(n)
1525 if (lakeout(n) < 0 .or. lakeout(n) > this%nlakes)
then
1526 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0)') &
1527 'lakeout FOR OUTLET ', ioutlet,
'MUST BE >= 0 and <= ', this%nlakes
1530 this%lakeout(ioutlet) = lakeout(n)
1533 keyword = couttype(n)
1534 select case (trim(keyword))
1536 this%iouttype(ioutlet) = 0
1538 this%iouttype(ioutlet) = 1
1540 this%iouttype(ioutlet) = 2
1542 write (
errmsg,
'(a,1x,i0,1x,a,a,a)') &
1543 'UNKNOWN couttype FOR OUTLET ', ioutlet,
'(', trim(keyword),
')'
1548 this%outinvert(ioutlet) = outlets_invert(n)
1549 this%outwidth(ioutlet) = outlets_width(n)
1550 this%outrough(ioutlet) = outlets_rough(n)
1551 this%outslope(ioutlet) = outlets_slope(n)
1554 write (this%iout,
'(1x,a)')
'END OF '//trim(adjustl(this%text))//
' OUTLETS'
1557 call this%report_ifno_coverage(nboundchk, this%noutlets,
'outlet', &
1560 deallocate (nboundchk)
1571 end subroutine lak_source_outlets
1575 subroutine lak_source_dimensions(this)
1577 class(laktype),
intent(inout) :: this
1585 write (this%iout,
'(/1x,a)') &
1586 'PROCESSING '//trim(adjustl(this%text))//
' DIMENSIONS'
1590 call mem_set_value(this%nlakes,
'NLAKES', this%input_mempath, &
1591 found%nlakes, release=.false.)
1592 if (found%nlakes)
write (this%iout,
'(4x,a,i7)')
'NLAKES = ', this%nlakes
1596 call mem_set_value(this%noutlets,
'NOUTLETS', this%input_mempath, &
1597 found%noutlets, release=.false.)
1598 if (found%noutlets)
write (this%iout,
'(4x,a,i7)') &
1599 'NOUTLETS = ', this%noutlets
1602 call mem_set_value(this%ntables,
'NTABLES', this%input_mempath, found%ntables)
1603 if (found%ntables)
write (this%iout,
'(4x,a,i7)')
'NTABLES = ', this%ntables
1605 write (this%iout,
'(1x,a)') &
1606 'END OF '//trim(adjustl(this%text))//
' DIMENSIONS'
1608 if (this%nlakes < 0)
then
1610 'NLAKES WAS NOT SPECIFIED OR WAS SPECIFIED INCORRECTLY.'
1616 if (this%iforceleglak /= 0)
then
1617 if (this%iforceleglak < 1 .or. this%iforceleglak > this%nlakes)
then
1618 write (
errmsg,
'(a,i0,a,i0,a)') &
1619 'DEV_FORCE_LEGACY_LAKE (', this%iforceleglak, &
1620 ') MUST BE BETWEEN 1 AND NLAKES (', this%nlakes,
').'
1628 call this%lak_source_packagedata()
1632 if (this%iimplicit /= 0)
then
1633 this%npakeq = this%nlakes
1642 call this%lak_source_connectiondata()
1645 call this%lak_source_tables()
1648 call this%lak_source_outlets()
1651 call this%lak_checkin_deprecated_names()
1654 call this%define_listlabel()
1657 call this%lak_setup_budobj()
1660 call this%lak_setup_tableobj()
1661 end subroutine lak_source_dimensions
1665 subroutine lak_read_initial_attr(this)
1670 class(laktype),
intent(inout) :: this
1672 integer(I4B) :: j, n
1689 real(DP),
allocatable,
dimension(:) :: clb, caq
1690 character(len=14) :: cbedleak
1691 character(len=14) :: cbedcond
1692 character(len=10),
dimension(0:3) :: ctype
1693 character(len=15) :: nodestr
1695 data ctype(0)/
'VERTICAL '/
1696 data ctype(1)/
'HORIZONTAL'/
1697 data ctype(2)/
'EMBEDDEDH '/
1698 data ctype(3)/
'EMBEDDEDV '/
1701 do n = 1, this%nlakes
1702 this%xnewpak(n) = this%strt(n)
1703 this%stage(n) = this%strt(n)
1707 do n = 1, this%nlakes
1708 if (this%status(n) ==
'CONSTANT')
then
1709 this%iboundpak(n) = -1
1710 else if (this%status(n) ==
'INACTIVE')
then
1711 this%iboundpak(n) = 0
1712 else if (this%status(n) ==
'ACTIVE ')
then
1713 this%iboundpak(n) = 1
1718 if (this%inamedbound /= 0)
then
1719 do n = 1, this%nlakes
1720 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1721 this%boundname(j) = this%lakename(n)
1727 call this%copy_boundname()
1731 call mem_setptr(this%gwfk11,
'K11',
create_mem_path(this%name_model,
'NPF'))
1732 call mem_setptr(this%gwfk33,
'K33',
create_mem_path(this%name_model,
'NPF'))
1733 call mem_setptr(this%gwfik33,
'IK33',
create_mem_path(this%name_model,
'NPF'))
1734 call mem_setptr(this%gwfsat,
'SAT',
create_mem_path(this%name_model,
'NPF'))
1737 allocate (clb(this%MAXBOUND))
1738 allocate (caq(this%MAXBOUND))
1741 do n = 1, this%nlakes
1742 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1743 nn = this%gwfconn(j)
1744 top = this%dis%top(nn)
1745 bot = this%dis%bot(nn)
1747 if (this%ictype(j) == 0)
then
1748 area = this%dis%area(nn)
1749 this%sarea(j) = area
1750 this%warea(j) = area
1751 this%sareamax(n) = this%sareamax(n) + area
1752 if (this%gwfik33 == 0)
then
1757 length =
dhalf * (top - bot)
1759 else if (this%ictype(j) == 1)
then
1760 area = (this%telev(j) - this%belev(j)) * this%connwidth(j)
1763 if (top == this%telev(j) .and. bot == this%belev(j))
then
1764 if (this%icelltype(nn) == 0)
then
1765 area = this%gwfsat(nn) * (top - bot) * this%connwidth(j)
1768 this%sarea(j) =
dzero
1769 this%warea(j) = area
1770 this%sareamax(n) = this%sareamax(n) +
dzero
1772 length = this%connlength(j)
1774 else if (this%ictype(j) == 2)
then
1776 this%sarea(j) =
dzero
1777 this%warea(j) = area
1778 this%sareamax(n) = this%sareamax(n) +
dzero
1780 length = this%connlength(j)
1782 else if (this%ictype(j) == 3)
then
1784 this%sarea(j) =
dzero
1785 this%warea(j) = area
1786 this%sareamax(n) = this%sareamax(n) +
dzero
1787 if (this%gwfik33 == 0)
then
1792 length = this%connlength(j)
1796 else if (this%bedleak(j) >
dzero)
then
1797 clb(j) =
done / this%bedleak(j)
1807 this%satcond(j) = area / caq(j)
1808 else if (clb(j) * caq(j) >
dzero)
then
1809 this%satcond(j) = area / (clb(j) + caq(j))
1811 this%satcond(j) =
dzero
1817 if (this%iprpak > 0)
then
1818 write (this%iout,
'(//,29x,a,/)') &
1819 'INTERFACE CONDUCTANCE BETWEEN LAKE AND AQUIFER CELLS'
1820 write (this%iout,
'(1x,a)') &
1821 &
' LAKE CONNECTION CONNECTION LAKEBED'// &
1822 &
' C O N D U C T A N C E S '
1823 write (this%iout,
'(1x,a)') &
1824 &
' NUMBER NUMBER CELLID DIRECTION LEAKANCE'// &
1825 &
' LAKEBED AQUIFER COMBINED'
1826 write (this%iout,
"(1x,108('-'))")
1827 do n = 1, this%nlakes
1829 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1832 if (this%ictype(j) == 1)
then
1833 fact = this%telev(j) - this%belev(j)
1834 if (abs(fact) >
dzero)
then
1838 nn = this%gwfconn(j)
1839 area = this%warea(j)
1844 else if (clb(j) >
dzero)
then
1845 c1 = area * fact / clb(j)
1846 write (cbedleak,
'(g14.5)') this%bedleak(j)
1847 write (cbedcond,
'(g14.5)') c1
1849 write (cbedleak,
'(g14.5)') c1
1850 write (cbedcond,
'(g14.5)') c1
1853 if (caq(j) >
dzero)
then
1854 c2 = area * fact / caq(j)
1856 call this%dis%noder_to_string(nn, nodestr)
1858 '(1x,i10,1x,i10,1x,a15,1x,a10,2(1x,a14),2(1x,g14.5))') &
1859 n, idx, nodestr, ctype(this%ictype(j)), cbedleak, &
1860 cbedcond, c2, this%satcond(j) * fact
1863 write (this%iout,
"(1x,108('-'))")
1864 write (this%iout,
'(1x,a)') &
1865 'IF VERTICAL CONNECTION, CONDUCTANCE (L^2/T) IS &
1866 &BETWEEN AQUIFER CELL AND OVERLYING LAKE CELL.'
1867 write (this%iout,
'(1x,a)') &
1868 'IF HORIZONTAL CONNECTION, CONDUCTANCES ARE PER &
1869 &UNIT SATURATED THICKNESS (L/T).'
1870 write (this%iout,
'(1x,a)') &
1871 'IF EMBEDDED CONNECTION, CONDUCTANCES ARE PER &
1872 &UNIT EXCHANGE AREA (1/T).'
1877 do n = 1, this%nlakes
1878 write (this%iout,
'(//1x,a,1x,i10)')
'STAGE/VOLUME RELATION FOR LAKE ', n
1879 write (this%iout,
'(/1x,5(a14))')
' STAGE',
' SURFACE AREA', &
1880 &
' WETTED AREA',
' CONDUCTANCE', &
1882 write (this%iout,
"(1x,70('-'))")
1883 dx = (this%laketop(n) - this%lakebot(n)) / 150.
1886 call this%lak_calculate_conductance(n, s, c)
1887 call this%lak_calculate_sarea(n, s, sa)
1888 call this%lak_calculate_warea(n, s, wa, s)
1889 call this%lak_calculate_vol(n, s, v)
1890 write (this%iout,
'(1x,5(E14.5))') s, sa, wa, c, v
1893 write (this%iout,
"(1x,70('-'))")
1895 write (this%iout,
'(//1x,a,1x,i10)')
'STAGE/VOLUME RELATION FOR LAKE ', n
1896 write (this%iout,
'(/1x,4(a14))')
' ',
' ', &
1897 &
' CALCULATED',
' STAGE'
1898 write (this%iout,
'(1x,4(a14))')
' STAGE',
' VOLUME', &
1899 &
' STAGE',
' DIFFERENCE'
1900 write (this%iout,
"(1x,56('-'))")
1901 s = this%lakebot(n) - dx
1903 call this%lak_calculate_vol(n, s, v)
1904 call this%lak_vol2stage(n, v, c)
1905 write (this%iout,
'(1x,4(E14.5))') s, v, c, s - c
1908 write (this%iout,
"(1x,56('-'))")
1913 this%gwfk11 => null()
1914 this%gwfk33 => null()
1915 this%gwfsat => null()
1916 this%gwfik33 => null()
1921 end subroutine lak_read_initial_attr
1927 subroutine lak_linear_interpolation(this, n, x, y, z, v)
1929 class(laktype),
intent(inout) :: this
1930 integer(I4B),
intent(in) :: n
1931 real(DP),
dimension(n),
intent(in) :: x
1932 real(DP),
dimension(n),
intent(in) :: y
1933 real(DP),
intent(in) :: z
1934 real(DP),
intent(inout) :: v
1937 real(DP) :: dx, dydx
1945 else if (z > x(n))
then
1946 dx = x(n) - x(n - 1)
1948 if (abs(dx) > dzero)
then
1949 dydx = (y(n) - y(n - 1)) / dx
1952 v = y(n) + dydx * dx
1956 dx = x(i) - x(i - 1)
1958 if (z >= x(i - 1) .and. z <= x(i))
then
1959 if (abs(dx) > dzero)
then
1960 dydx = (y(i) - y(i - 1)) / dx
1963 v = y(i - 1) + dydx * dx
1968 end subroutine lak_linear_interpolation
1972 subroutine lak_calculate_sarea(this, ilak, stage, sarea)
1974 class(laktype),
intent(inout) :: this
1975 integer(I4B),
intent(in) :: ilak
1976 real(DP),
intent(in) :: stage
1977 real(DP),
intent(inout) :: sarea
1980 integer(I4B) :: ifirst
1981 integer(I4B) :: ilast
1988 i = this%ntabrow(ilak)
1990 ifirst = this%ialaktab(ilak)
1991 ilast = this%ialaktab(ilak + 1) - 1
1992 if (stage <= this%tabstage(ifirst))
then
1993 sarea = this%tabsarea(ifirst)
1994 else if (stage >= this%tabstage(ilast))
then
1995 sarea = this%tabsarea(ilast)
1997 call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
1998 this%tabsarea(ifirst:ilast), &
2002 do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2003 topl = this%telev(i)
2004 botl = this%belev(i)
2006 sa = sat * this%sarea(i)
2010 end subroutine lak_calculate_sarea
2014 subroutine lak_calculate_warea(this, ilak, stage, warea, hin)
2016 class(laktype),
intent(inout) :: this
2017 integer(I4B),
intent(in) :: ilak
2018 real(DP),
intent(in) :: stage
2019 real(DP),
intent(inout) :: warea
2020 real(DP),
optional,
intent(inout) :: hin
2023 integer(I4B) :: igwfnode
2028 do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2029 if (
present(hin))
then
2032 igwfnode = this%gwfconn(i)
2033 head = this%xnew(igwfnode)
2035 call this%lak_calculate_conn_warea(ilak, i, stage, head, wa)
2038 end subroutine lak_calculate_warea
2042 subroutine lak_calculate_conn_warea(this, ilak, iconn, stage, head, wa)
2044 class(laktype),
intent(inout) :: this
2045 integer(I4B),
intent(in) :: ilak
2046 integer(I4B),
intent(in) :: iconn
2047 real(DP),
intent(in) :: stage
2048 real(DP),
intent(in) :: head
2049 real(DP),
intent(inout) :: wa
2052 integer(I4B) :: ifirst
2053 integer(I4B) :: ilast
2054 integer(I4B) :: node
2061 topl = this%telev(iconn)
2062 botl = this%belev(iconn)
2063 call this%lak_calculate_cond_head(iconn, stage, head, vv)
2064 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
2065 if (vv > topl) vv = topl
2066 i = this%ntabrow(ilak)
2067 ifirst = this%ialaktab(ilak)
2068 ilast = this%ialaktab(ilak + 1) - 1
2069 if (vv <= this%tabstage(ifirst))
then
2070 wa = this%tabwarea(ifirst)
2071 else if (vv >= this%tabstage(ilast))
then
2072 wa = this%tabwarea(ilast)
2074 call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
2075 this%tabwarea(ifirst:ilast), &
2079 node = this%gwfconn(iconn)
2081 if (this%icelltype(node) == 0)
then
2087 wa = sat * this%warea(iconn)
2089 end subroutine lak_calculate_conn_warea
2093 subroutine lak_calculate_vol(this, ilak, stage, volume)
2095 class(laktype),
intent(inout) :: this
2096 integer(I4B),
intent(in) :: ilak
2097 real(DP),
intent(in) :: stage
2098 real(DP),
intent(inout) :: volume
2101 integer(I4B) :: ifirst
2102 integer(I4B) :: ilast
2111 i = this%ntabrow(ilak)
2113 ifirst = this%ialaktab(ilak)
2114 ilast = this%ialaktab(ilak + 1) - 1
2115 if (stage <= this%tabstage(ifirst))
then
2116 volume = this%tabvolume(ifirst)
2117 else if (stage >= this%tabstage(ilast))
then
2118 ds = stage - this%tabstage(ilast)
2119 sa = this%tabsarea(ilast)
2120 volume = this%tabvolume(ilast) + ds * sa
2122 call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
2123 this%tabvolume(ifirst:ilast), &
2127 do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2128 topl = this%telev(i)
2129 botl = this%belev(i)
2131 sa = sat * this%sarea(i)
2132 if (stage < botl)
then
2134 else if (stage > botl .and. stage < topl)
then
2135 v = sa * (stage - botl)
2137 v = sa * (topl - botl) + sa * (stage - topl)
2142 end subroutine lak_calculate_vol
2146 subroutine lak_calculate_conductance(this, ilak, stage, conductance)
2148 class(laktype),
intent(inout) :: this
2149 integer(I4B),
intent(in) :: ilak
2150 real(DP),
intent(in) :: stage
2151 real(DP),
intent(inout) :: conductance
2157 do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2158 call this%lak_calculate_conn_conductance(ilak, i, stage, stage, c)
2159 conductance = conductance + c
2161 end subroutine lak_calculate_conductance
2167 subroutine lak_calculate_cond_head(this, iconn, stage, head, vv)
2169 class(laktype),
intent(inout) :: this
2170 integer(I4B),
intent(in) :: iconn
2171 real(DP),
intent(in) :: stage
2172 real(DP),
intent(in) :: head
2173 real(DP),
intent(inout) :: vv
2180 topl = this%telev(iconn)
2181 botl = this%belev(iconn)
2182 ss = min(stage, topl)
2183 hh = min(head, topl)
2184 if (this%igwhcopt > 0)
then
2186 else if (this%inewton > 0)
then
2189 vv = dhalf * (ss + hh)
2191 end subroutine lak_calculate_cond_head
2196 subroutine lak_calculate_conn_conductance(this, ilak, iconn, stage, head, cond)
2198 class(laktype),
intent(inout) :: this
2199 integer(I4B),
intent(in) :: ilak
2200 integer(I4B),
intent(in) :: iconn
2201 real(DP),
intent(in) :: stage
2202 real(DP),
intent(in) :: head
2203 real(DP),
intent(inout) :: cond
2205 integer(I4B) :: node
2213 real(DP) :: vscratio
2217 topl = this%telev(iconn)
2218 botl = this%belev(iconn)
2219 call this%lak_calculate_cond_head(iconn, stage, head, vv)
2224 if (this%ictype(iconn) == 0)
then
2225 if (abs(topl - botl) < dprec)
then
2230 else if (this%ictype(iconn) == 1)
then
2231 node = this%gwfconn(iconn)
2232 if (this%icelltype(node) == 0)
then
2236 else if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
2237 node = this%gwfconn(iconn)
2238 if (this%icelltype(node) == 0)
then
2239 vv = this%telev(iconn)
2240 call this%lak_calculate_conn_warea(ilak, iconn, vv, vv, wa)
2242 call this%lak_calculate_conn_warea(ilak, iconn, stage, head, wa)
2248 if (this%ivsc == 1)
then
2250 if (stage > head)
then
2251 vscratio = this%viscratios(1, iconn)
2254 vscratio = this%viscratios(2, iconn)
2257 cond = sat * this%satcond(iconn) * vscratio
2258 end subroutine lak_calculate_conn_conductance
2262 subroutine lak_calculate_exchange(this, ilak, stage, totflow)
2264 class(laktype),
intent(inout) :: this
2265 integer(I4B),
intent(in) :: ilak
2266 real(DP),
intent(in) :: stage
2267 real(DP),
intent(inout) :: totflow
2270 integer(I4B) :: igwfnode
2275 do j = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2276 igwfnode = this%gwfconn(j)
2277 hgwf = this%xnew(igwfnode)
2278 call this%lak_calculate_conn_exchange(ilak, j, stage, hgwf, flow)
2279 totflow = totflow + flow
2281 end subroutine lak_calculate_exchange
2286 subroutine lak_calculate_conn_exchange(this, ilak, iconn, stage, head, flow, &
2289 class(laktype),
intent(inout) :: this
2290 integer(I4B),
intent(in) :: ilak
2291 integer(I4B),
intent(in) :: iconn
2292 real(DP),
intent(in) :: stage
2293 real(DP),
intent(in) :: head
2294 real(DP),
intent(inout) :: flow
2295 real(DP),
intent(inout),
optional :: gwfhcof
2296 real(DP),
intent(inout),
optional :: gwfrhs
2302 real(DP) :: gwfhcof0
2306 call this%lak_calculate_conn_conductance(ilak, iconn, stage, head, cond)
2307 botl = this%belev(iconn)
2310 if (stage >= botl)
then
2317 if (head >= botl)
then
2324 flow = cond * (hh - ss)
2327 if (head >= botl)
then
2329 gwfrhs0 = -cond * ss
2336 if (this%idense /= 0)
then
2337 call this%lak_calculate_density_exchange(iconn, stage, head, cond, botl, &
2338 flow, gwfhcof0, gwfrhs0)
2342 if (
present(gwfhcof)) gwfhcof = gwfhcof0
2343 if (
present(gwfrhs)) gwfrhs = gwfrhs0
2344 end subroutine lak_calculate_conn_exchange
2355 subroutine lak_calculate_conn_exchange_deriv(this, ilak, iconn, stage, &
2356 head, flow, dqds, dqdh)
2358 class(laktype),
intent(inout) :: this
2359 integer(I4B),
intent(in) :: ilak
2360 integer(I4B),
intent(in) :: iconn
2361 real(DP),
intent(in) :: stage
2362 real(DP),
intent(in) :: head
2363 real(DP),
intent(inout) :: flow
2364 real(DP),
intent(inout),
optional :: dqds
2365 real(DP),
intent(inout),
optional :: dqdh
2367 real(DP) :: cond, botl, dps, dph, ss, hh
2369 call this%lak_calculate_conn_conductance(ilak, iconn, stage, head, cond)
2370 botl = this%belev(iconn)
2371 if (stage >= botl)
then
2378 if (head >= botl)
then
2385 flow = cond * (hh - ss)
2386 if (
present(dqds)) dqds = -cond * dps
2387 if (
present(dqdh)) dqdh = cond * dph
2388 end subroutine lak_calculate_conn_exchange_deriv
2393 subroutine lak_estimate_conn_exchange(this, iflag, ilak, iconn, idry, stage, &
2394 head, flow, source, gwfhcof, gwfrhs)
2396 class(laktype),
intent(inout) :: this
2397 integer(I4B),
intent(in) :: iflag
2398 integer(I4B),
intent(in) :: ilak
2399 integer(I4B),
intent(in) :: iconn
2400 integer(I4B),
intent(inout) :: idry
2401 real(DP),
intent(in) :: stage
2402 real(DP),
intent(in) :: head
2403 real(DP),
intent(inout) :: flow
2404 real(DP),
intent(inout) :: source
2405 real(DP),
intent(inout),
optional :: gwfhcof
2406 real(DP),
intent(inout),
optional :: gwfrhs
2408 real(DP) :: gwfhcof0, gwfrhs0
2412 call this%lak_calculate_conn_exchange(ilak, iconn, stage, head, flow, &
2414 if (iflag == 1)
then
2415 if (flow > dzero)
then
2416 source = source + flow
2418 else if (iflag == 2)
then
2419 if (-flow > source)
then
2423 else if (flow < dzero)
then
2424 source = source + flow
2429 if (
present(gwfhcof)) gwfhcof = gwfhcof0
2430 if (
present(gwfrhs)) gwfrhs = gwfrhs0
2431 end subroutine lak_estimate_conn_exchange
2436 subroutine lak_calculate_storagechange(this, ilak, stage, stage0, delt, dvr)
2438 class(laktype),
intent(inout) :: this
2439 integer(I4B),
intent(in) :: ilak
2440 real(DP),
intent(in) :: stage
2441 real(DP),
intent(in) :: stage0
2442 real(DP),
intent(in) :: delt
2443 real(DP),
intent(inout) :: dvr
2449 if (this%gwfiss /= 1)
then
2450 call this%lak_calculate_vol(ilak, stage, v)
2451 call this%lak_calculate_vol(ilak, stage0, v0)
2452 dvr = (v0 - v) / delt
2454 end subroutine lak_calculate_storagechange
2458 subroutine lak_calculate_rainfall(this, ilak, stage, ra)
2460 class(laktype),
intent(inout) :: this
2461 integer(I4B),
intent(in) :: ilak
2462 real(DP),
intent(in) :: stage
2463 real(DP),
intent(inout) :: ra
2465 integer(I4B) :: iconn
2469 iconn = this%idxlakeconn(ilak)
2470 if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3)
then
2471 sa = this%sareamax(ilak)
2473 call this%lak_calculate_sarea(ilak, stage, sa)
2475 ra = this%rainfall(ilak) * sa
2476 end subroutine lak_calculate_rainfall
2480 subroutine lak_calculate_runoff(this, ilak, ro)
2482 class(laktype),
intent(inout) :: this
2483 integer(I4B),
intent(in) :: ilak
2484 real(DP),
intent(inout) :: ro
2487 ro = this%runoff(ilak)
2488 end subroutine lak_calculate_runoff
2492 subroutine lak_calculate_inflow(this, ilak, qin)
2494 class(laktype),
intent(inout) :: this
2495 integer(I4B),
intent(in) :: ilak
2496 real(DP),
intent(inout) :: qin
2499 qin = this%inflow(ilak)
2500 end subroutine lak_calculate_inflow
2504 subroutine lak_calculate_external(this, ilak, ex)
2506 class(laktype),
intent(inout) :: this
2507 integer(I4B),
intent(in) :: ilak
2508 real(DP),
intent(inout) :: ex
2513 if (this%imover == 1)
then
2514 ex = this%pakmvrobj%get_qfrommvr(ilak)
2516 end subroutine lak_calculate_external
2520 subroutine lak_calculate_withdrawal(this, ilak, avail, wr)
2522 class(laktype),
intent(inout) :: this
2523 integer(I4B),
intent(in) :: ilak
2524 real(DP),
intent(inout) :: avail
2525 real(DP),
intent(inout) :: wr
2528 wr = this%withdrawal(ilak)
2529 if (wr > avail)
then
2532 if (wr > dzero)
then
2537 end subroutine lak_calculate_withdrawal
2542 subroutine lak_calculate_evaporation(this, ilak, stage, avail, ev)
2544 class(laktype),
intent(inout) :: this
2545 integer(I4B),
intent(in) :: ilak
2546 real(DP),
intent(in) :: stage
2547 real(DP),
intent(inout) :: avail
2548 real(DP),
intent(inout) :: ev
2553 call this%lak_calculate_sarea(ilak, stage, sa)
2554 ev = sa * this%evaporation(ilak)
2555 if (ev > avail)
then
2565 end subroutine lak_calculate_evaporation
2569 subroutine lak_calculate_outlet_inflow(this, ilak, outinf)
2571 class(laktype),
intent(inout) :: this
2572 integer(I4B),
intent(in) :: ilak
2573 real(DP),
intent(inout) :: outinf
2578 do n = 1, this%noutlets
2579 if (this%lakeout(n) == ilak)
then
2580 outinf = outinf - this%simoutrate(n)
2581 if (this%imover == 1)
then
2582 outinf = outinf - this%pakmvrobj%get_qtomvr(n)
2586 end subroutine lak_calculate_outlet_inflow
2590 subroutine lak_calculate_outlet_outflow(this, ilak, stage, avail, outoutf)
2592 class(laktype),
intent(inout) :: this
2593 integer(I4B),
intent(in) :: ilak
2594 real(DP),
intent(in) :: stage
2595 real(DP),
intent(inout) :: avail
2596 real(DP),
intent(inout) :: outoutf
2606 do n = 1, this%noutlets
2607 if (this%lakein(n) == ilak)
then
2609 d = stage - this%outinvert(n)
2610 if (this%outdmax > dzero)
then
2611 if (d > this%outdmax) d = this%outdmax
2613 g = dgravity * this%convlength * this%convtime * this%convtime
2614 select case (this%iouttype(n))
2617 rate = this%outrate(n)
2618 if (-rate > avail)
then
2624 c = (this%convlength**donethird) * this%convtime
2626 if (this%outrough(n) > dzero)
then
2627 gsm = done / this%outrough(n)
2629 rate = -c * gsm * this%outwidth(n) * (d**dfivethirds) * &
2630 sqrt(this%outslope(n))
2635 rate = -dtwothirds * dcd * this%outwidth(n) * d * &
2639 this%simoutrate(n) = rate
2640 avail = avail + rate
2641 outoutf = outoutf + rate
2644 end subroutine lak_calculate_outlet_outflow
2654 subroutine lak_outlet_outflow_rate(this, ilak, stage, qout)
2656 class(laktype),
intent(inout) :: this
2657 integer(I4B),
intent(in) :: ilak
2658 real(DP),
intent(in) :: stage
2659 real(DP),
intent(inout) :: qout
2662 real(DP) :: g, d, c, gsm, rate
2665 do n = 1, this%noutlets
2666 if (this%lakein(n) /= ilak) cycle
2668 d = stage - this%outinvert(n)
2669 if (this%outdmax > dzero .and. d > this%outdmax) d = this%outdmax
2670 g = dgravity * this%convlength * this%convtime * this%convtime
2671 select case (this%iouttype(n))
2673 rate = this%outrate(n)
2676 c = (this%convlength**donethird) * this%convtime
2678 if (this%outrough(n) > dzero) gsm = done / this%outrough(n)
2679 rate = -c * gsm * this%outwidth(n) * (d**dfivethirds) * &
2680 sqrt(this%outslope(n))
2684 rate = -dtwothirds * dcd * this%outwidth(n) * d * sqrt(dtwo * g * d)
2689 end subroutine lak_outlet_outflow_rate
2693 subroutine lak_get_internal_inlet(this, ilak, outinf)
2695 class(laktype),
intent(inout) :: this
2696 integer(I4B),
intent(in) :: ilak
2697 real(DP),
intent(inout) :: outinf
2702 do n = 1, this%noutlets
2703 if (this%lakeout(n) == ilak)
then
2704 outinf = outinf - this%simoutrate(n)
2705 if (this%imover == 1)
then
2706 outinf = outinf - this%pakmvrobj%get_qtomvr(n)
2710 end subroutine lak_get_internal_inlet
2714 subroutine lak_get_internal_outlet(this, ilak, outoutf)
2716 class(laktype),
intent(inout) :: this
2717 integer(I4B),
intent(in) :: ilak
2718 real(DP),
intent(inout) :: outoutf
2723 do n = 1, this%noutlets
2724 if (this%lakein(n) == ilak)
then
2725 if (this%lakeout(n) < 1) cycle
2726 outoutf = outoutf + this%simoutrate(n)
2729 end subroutine lak_get_internal_outlet
2733 subroutine lak_get_external_outlet(this, ilak, outoutf)
2735 class(laktype),
intent(inout) :: this
2736 integer(I4B),
intent(in) :: ilak
2737 real(DP),
intent(inout) :: outoutf
2742 do n = 1, this%noutlets
2743 if (this%lakein(n) == ilak)
then
2744 if (this%lakeout(n) > 0) cycle
2745 outoutf = outoutf + this%simoutrate(n)
2748 end subroutine lak_get_external_outlet
2752 subroutine lak_get_external_mover(this, ilak, outoutf)
2754 class(laktype),
intent(inout) :: this
2755 integer(I4B),
intent(in) :: ilak
2756 real(DP),
intent(inout) :: outoutf
2761 if (this%imover == 1)
then
2762 do n = 1, this%noutlets
2763 if (this%lakein(n) == ilak)
then
2764 if (this%lakeout(n) > 0) cycle
2765 outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2769 end subroutine lak_get_external_mover
2773 subroutine lak_get_internal_mover(this, ilak, outoutf)
2775 class(laktype),
intent(inout) :: this
2776 integer(I4B),
intent(in) :: ilak
2777 real(DP),
intent(inout) :: outoutf
2782 if (this%imover == 1)
then
2783 do n = 1, this%noutlets
2784 if (this%lakein(n) == ilak)
then
2785 if (this%lakeout(n) < 1) cycle
2786 outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2790 end subroutine lak_get_internal_mover
2794 subroutine lak_get_outlet_tomover(this, ilak, outoutf)
2796 class(laktype),
intent(inout) :: this
2797 integer(I4B),
intent(in) :: ilak
2798 real(DP),
intent(inout) :: outoutf
2803 if (this%imover == 1)
then
2804 do n = 1, this%noutlets
2805 if (this%lakein(n) == ilak)
then
2806 outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2810 end subroutine lak_get_outlet_tomover
2814 subroutine lak_vol2stage(this, ilak, vol, stage)
2816 class(laktype),
intent(inout) :: this
2817 integer(I4B),
intent(in) :: ilak
2818 real(DP),
intent(in) :: vol
2819 real(DP),
intent(inout) :: stage
2823 real(DP) :: s0, s1, sm
2824 real(DP) :: v0, v1, vm
2825 real(DP) :: f0, f1, fm
2827 real(DP) :: en0, en1
2831 s0 = this%lakebot(ilak)
2832 call this%lak_calculate_vol(ilak, s0, v0)
2833 s1 = this%laketop(ilak)
2834 call this%lak_calculate_vol(ilak, s1, v1)
2839 else if (vol >= v1)
then
2840 call this%lak_calculate_sarea(ilak, s1, sa)
2841 stage = s1 + (vol - v1) / sa
2852 secantbisection:
do i = 1, 150
2854 if (denom /= dzero)
then
2855 ds = f1 * (s1 - s0) / denom
2863 if (sm < en0 .or. sm > en1) ibs = 13
2867 if (ds * ds0 < dprec .or. abs(ds) > abs(ds0)) ibs = ibs + 1
2869 ds = dhalf * (s1 - s0)
2873 if (abs(ds) < dem6)
then
2874 exit secantbisection
2876 call this%lak_calculate_vol(ilak, sm, vm)
2883 end do secantbisection
2885 if (abs(ds) >= dem6)
then
2886 write (this%iout,
'(1x,a,1x,i0,4(1x,a,1x,g15.6))') &
2887 &
'LAK_VOL2STAGE failed for lake', ilak,
'volume error =', fm, &
2888 &
'finding stage (', stage,
') for volume =', vol, &
2889 &
'final change in stage =', ds
2892 end subroutine lak_vol2stage
2895 function lak_check_valid(this, itemno)
result(ierr)
2899 integer(I4B) :: ierr
2901 class(laktype),
intent(inout) :: this
2902 integer(I4B),
intent(in) :: itemno
2904 integer(I4B) :: ival
2908 if (itemno > 0)
then
2909 if (ival < 1 .or. ival > this%nlakes)
then
2910 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,a)') &
2911 'LAKENO', itemno,
'must be greater than 0 and less than or equal to', &
2917 if (ival < 1 .or. ival > this%noutlets)
then
2918 write (
errmsg,
'(a,1x,i0,1x,a,1x,i0,a)') &
2919 'IOUTLET', itemno,
'must be greater than 0 and less than or equal to', &
2925 end function lak_check_valid
2928 subroutine lak_set_nonneg_value(this, n, itemno, setting, value_array, label)
2930 class(laktype),
intent(inout) :: this
2931 integer(I4B),
intent(in) :: n
2932 integer(I4B),
intent(in) :: itemno
2933 character(len=*),
intent(in) :: setting
2934 real(DP),
dimension(:),
intent(inout) :: value_array
2935 character(len=*),
intent(in) :: label
2937 integer(I4B) :: istat
2939 istat = this%lak_check_valid(itemno)
2940 if (istat /= 0)
return
2941 if (itemno < 1 .or. itemno > this%nlakes)
return
2942 if (value_array(itemno) < dzero)
then
2943 write (
errmsg,
'(a,i0,a,g0,a)') &
2944 'Lake ', itemno,
' was assigned a '//trim(label)//
' value of ', &
2945 value_array(itemno),
'. Value must be positive.'
2948 end subroutine lak_set_nonneg_value
2952 subroutine lak_set_attribute_error(this, ilak, keyword, msg)
2956 class(laktype),
intent(inout) :: this
2957 integer(I4B),
intent(in) :: ilak
2958 character(len=*),
intent(in) :: keyword
2959 character(len=*),
intent(in) :: msg
2961 if (len(msg) == 0)
then
2962 write (
errmsg,
'(a,1x,a,1x,i0,1x,a)') &
2963 keyword,
' for LAKE', ilak,
'has already been set.'
2965 write (
errmsg,
'(a,1x,a,1x,i0,1x,a)') keyword,
' for LAKE', ilak, msg
2968 end subroutine lak_set_attribute_error
2972 subroutine lak_source_options(this)
2974 class(laktype),
intent(inout) :: this
2977 integer(I4B) :: isize
2978 character(len=LINELENGTH) :: fname
2980 character(len=*),
parameter :: fmtlengthconv = &
2981 &
"(4x, 'LENGTH CONVERSION VALUE (',g15.7,') SPECIFIED.')"
2982 character(len=*),
parameter :: fmttimeconv = &
2983 &
"(4x, 'TIME CONVERSION VALUE (',g15.7,') SPECIFIED.')"
2984 character(len=*),
parameter :: fmtlakeopt = &
2985 &
"(4x, 'LAKE ', a, ' VALUE (',g15.7,') SPECIFIED.')"
2986 character(len=*),
parameter :: fmtoutdmax = &
2987 &
"(4x, 'MAXIMUM OUTLET WATER DEPTH (',g15.7,') SPECIFIED.')"
2988 character(len=*),
parameter :: fmtlakbin = &
2989 "(4x, 'LAK ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', &
2990 &a, /4x, 'OPENED ON UNIT: ', I0)"
2991 character(len=*),
parameter :: fmtiter = &
2992 &
"(4x, 'MAXIMUM LAK ITERATION VALUE (',i0,') SPECIFIED.')"
2993 character(len=*),
parameter :: fmtdmaxchg = &
2994 &
"(4x, 'MAXIMUM STAGE CHANGE VALUE (',g0,') SPECIFIED.')"
2998 call this%BndExtType%source_options()
3000 write (this%iout,
'(1x,a)') &
3001 'PROCESSING '//trim(adjustl(this%text))//
' OPTIONS'
3004 call mem_set_value(this%iprhed,
'PRINT_STAGE', this%input_mempath, &
3006 if (found%print_stage)
then
3007 write (this%iout,
'(4x,a)') trim(adjustl(this%text))// &
3008 ' STAGES WILL BE PRINTED TO LISTING FILE.'
3012 call mem_set_value(fname,
'STAGEFILE', this%input_mempath, found%stagefile)
3013 if (found%stagefile)
then
3015 call openfile(this%istageout, this%iout, fname,
'DATA(BINARY)', &
3017 write (this%iout, fmtlakbin)
'STAGE', trim(adjustl(fname)), this%istageout
3021 call mem_set_value(fname,
'BUDGETFILE', this%input_mempath, found%budgetfile)
3022 if (found%budgetfile)
then
3023 call assign_iounit(this%ibudgetout, this%inunit,
'BUDGET fileout')
3024 call openfile(this%ibudgetout, this%iout, fname,
'DATA(BINARY)', &
3026 write (this%iout, fmtlakbin)
'BUDGET', trim(adjustl(fname)), this%ibudgetout
3030 call mem_set_value(fname,
'BUDGETCSVFILE', this%input_mempath, &
3031 found%budgetcsvfile)
3032 if (found%budgetcsvfile)
then
3033 call assign_iounit(this%ibudcsv, this%inunit,
'BUDGETCSV fileout')
3034 call openfile(this%ibudcsv, this%iout, fname,
'CSV', filstat_opt=
'REPLACE')
3035 write (this%iout, fmtlakbin)
'BUDGET CSV', trim(adjustl(fname)), &
3043 call mem_set_value(fname,
'PKGCONVFNAME', this%input_mempath, &
3045 if (found%pkgconvfname)
then
3046 this%pakcsvfile = trim(adjustl(fname))
3050 call mem_set_value(this%imover,
'MOVER', this%input_mempath, found%mover)
3051 if (found%mover)
then
3052 write (this%iout,
'(4x,A)')
'MOVER OPTION ENABLED'
3056 call mem_set_value(this%convlength,
'CONVLENGTH', this%input_mempath, &
3058 if (found%convlength)
write (this%iout, fmtlengthconv) this%convlength
3061 call mem_set_value(this%convtime,
'CONVTIME', this%input_mempath, &
3063 if (found%convtime)
write (this%iout, fmttimeconv) this%convtime
3066 call mem_set_value(this%surfdep,
'SURFDEP', this%input_mempath, found%surfdep)
3067 if (found%surfdep)
then
3068 if (this%surfdep < dzero) this%surfdep = dzero
3069 write (this%iout, fmtlakeopt)
'SURFDEP', this%surfdep
3073 call mem_set_value(this%maxlakit,
'MAXLAKIT', this%input_mempath, &
3075 if (found%maxlakit)
write (this%iout, fmtiter) this%maxlakit
3078 call mem_set_value(this%dmaxchg,
'DMAXCHG', this%input_mempath, found%dmaxchg)
3079 if (found%dmaxchg)
then
3080 this%delh = dp999 * this%dmaxchg
3081 write (this%iout, fmtdmaxchg) this%dmaxchg
3085 call mem_set_value(this%igwhcopt,
'IGWHCOPT', this%input_mempath, &
3087 if (found%igwhcopt)
then
3088 write (this%iout,
'(4x,a)') &
3089 'CONDUCTANCE FOR HORIZONTAL CONNECTIONS WILL BE CALCULATED &
3090 &USING THE GROUNDWATER HEAD'
3094 call mem_set_value(this%iimplicit,
'IIMPLICIT', this%input_mempath, &
3096 if (found%iimplicit)
then
3097 write (this%iout,
'(4x,a)') &
3098 'LAKE STAGE WILL BE SOLVED AS AN UNKNOWN IN THE GROUNDWATER FLOW '// &
3099 'MATRIX (IMPLICIT FORMULATION)'
3103 call mem_set_value(this%iforceleg,
'IFORCELEG', this%input_mempath, &
3108 call mem_set_value(this%iforceleglak,
'IFORCELEGLAK', this%input_mempath, &
3111 if (found%iforceleg)
then
3112 write (this%iout,
'(4x,a)') &
3113 'EVERY ACTIVE LAKE WILL BE SOLVED WITH THE LEGACY SUBSTITUTION '// &
3114 'SOLVER UNDER THE IMPLICIT FORMULATION'
3115 if (this%iforceleglak /= 0)
then
3116 call store_error(
'DEV_FORCE_LEGACY and DEV_FORCE_LEGACY_LAKE '// &
3117 'cannot both be specified.')
3121 if (found%iforceleglak)
then
3122 write (this%iout,
'(4x,a,i0,a)')
'LAKE ', this%iforceleglak, &
3123 ' WILL BE SOLVED WITH THE LEGACY SUBSTITUTION SOLVER UNDER THE '// &
3124 'IMPLICIT FORMULATION'
3125 if (this%iforceleg /= 0)
then
3126 call store_error(
'DEV_FORCE_LEGACY and DEV_FORCE_LEGACY_LAKE '// &
3127 'cannot both be specified.')
3132 call get_isize(
'ICONVCHK', this%input_mempath, isize)
3135 write (this%iout,
'(4x,a)') &
3136 'A FINAL CONVERGENCE CHECK OF THE CHANGE IN LAKE STAGES &
3141 call mem_set_value(this%outdmax,
'OUTDMAX', this%input_mempath, found%outdmax)
3142 if (found%outdmax)
write (this%iout, fmtoutdmax) this%outdmax
3144 write (this%iout,
'(1x,a)')
'END OF '//trim(adjustl(this%text))//
' OPTIONS'
3145 end subroutine lak_source_options
3152 subroutine lak_input_init(this, mempath, naux, noutlets)
3155 class(lakinputtype),
intent(inout) :: this
3156 character(len=*),
intent(in) :: mempath
3157 integer(I4B),
intent(in) :: naux
3158 integer(I4B),
intent(in) :: noutlets
3160 integer(I4B),
dimension(:, :),
pointer,
contiguous :: tslink => null()
3162 tslinkvars => null()
3166 call mem_setptr(this%nbound,
'NBOUND', mempath)
3168 call mem_setptr(this%setting,
'SETTING', mempath)
3169 call mem_setptr(this%status,
'STATUS', mempath)
3171 call mem_setptr(this%auxname,
'AUXNAME', mempath)
3172 call mem_setptr(this%auxval,
'AUXVAL', mempath)
3175 if (noutlets > 0)
then
3176 call mem_setptr(this%outletno,
'OUTLETS_OUTLETNO', mempath)
3177 call mem_setptr(this%outlets_invert,
'OUTLETS_INVERT', mempath)
3178 call mem_setptr(this%outlets_width,
'OUTLETS_WIDTH', mempath)
3179 call mem_setptr(this%outlets_rough,
'OUTLETS_ROUGH', mempath)
3180 call mem_setptr(this%outlets_slope,
'OUTLETS_SLOPE', mempath)
3181 call mem_setptr(tslink,
'TSLINK_OL', mempath)
3182 call mem_setptr(tslinkvars,
'TSLINKVARS_OL', mempath)
3183 do n = 1,
size(tslinkvars)
3184 if (tslinkvars(n) ==
'OUTLETS_INVERT') &
3185 this%invert_tslink => tslink(n, :)
3186 if (tslinkvars(n) ==
'OUTLETS_WIDTH') this%width_tslink => tslink(n, :)
3187 if (tslinkvars(n) ==
'OUTLETS_ROUGH') this%rough_tslink => tslink(n, :)
3188 if (tslinkvars(n) ==
'OUTLETS_SLOPE') this%slope_tslink => tslink(n, :)
3191 end subroutine lak_input_init
3195 subroutine lak_input_destroy(this)
3197 class(lakinputtype),
intent(inout) :: this
3199 nullify (this%nbound)
3201 nullify (this%setting)
3202 nullify (this%status)
3203 nullify (this%auxname)
3204 nullify (this%auxval)
3205 nullify (this%outletno)
3206 nullify (this%outlets_invert)
3207 nullify (this%outlets_width)
3208 nullify (this%outlets_rough)
3209 nullify (this%outlets_slope)
3210 nullify (this%invert_tslink)
3211 nullify (this%width_tslink)
3212 nullify (this%rough_tslink)
3213 nullify (this%slope_tslink)
3214 end subroutine lak_input_destroy
3220 subroutine lak_ar(this)
3225 class(laktype),
intent(inout) :: this
3227 character(len=*),
parameter :: fmtlakbin = &
3228 "(4x, 'LAK ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', &
3229 &a, /4x, 'OPENED ON UNIT: ', I0)"
3236 if (
allocated(this%pakcsvfile))
then
3237 if (this%iimplicit /= 0)
then
3239 'PACKAGE_CONVERGENCE output file "'//trim(this%pakcsvfile)// &
3240 '" is not written when the IMPLICIT option is active; the lake '// &
3241 'stage is part of the solver (IMS) convergence check.'
3245 call openfile(this%ipakcsv, this%iout, this%pakcsvfile,
'CSV', &
3246 filstat_opt=
'REPLACE', mode_opt=
mnormal)
3247 write (this%iout, fmtlakbin)
'PACKAGE_CONVERGENCE', &
3248 trim(this%pakcsvfile), this%ipakcsv
3250 deallocate (this%pakcsvfile)
3253 call this%obs%obs_ar()
3256 call this%lak_allocate_arrays()
3259 call this%read_initial_attr()
3262 call this%input%init(this%input_mempath, this%naux, this%noutlets)
3263 if (this%noutlets > 0)
then
3264 if (.not. (
associated(this%input%invert_tslink) .and. &
3265 associated(this%input%width_tslink) .and. &
3266 associated(this%input%rough_tslink) .and. &
3267 associated(this%input%slope_tslink)))
then
3268 call store_error(
'Time series links for OUTLETS not found in input.')
3269 call store_error_filename(this%input_fname)
3274 if (this%imover /= 0)
then
3275 allocate (this%pakmvrobj)
3276 call this%pakmvrobj%ar(this%noutlets, this%nlakes, this%memoryPath)
3278 end subroutine lak_ar
3282 subroutine lak_rp(this)
3287 class(laktype),
intent(inout) :: this
3289 character(len=LINELENGTH) :: str =
' '
3290 real(DP) :: auxvaldbl =
dzero
3291 character(len=LINELENGTH) :: title
3292 character(len=LINELENGTH) :: text
3293 character(len=LENVARNAME) :: setting
3294 integer(I4B) :: node, n, j, itemno
3295 integer(I4B) :: istat
3297 character(len=*),
parameter :: fmtlsp = &
3298 &
"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
3301 this%nbound = this%maxbound
3304 if (this%iper ==
kper)
then
3309 if (this%iprpak /= 0)
then
3310 title = trim(adjustl(this%text))//
' PACKAGE ('// &
3311 trim(adjustl(this%packName))//
') DATA FOR PERIOD'
3312 write (title,
'(a,1x,i6)') trim(adjustl(title)),
kper
3313 call table_cr(this%inputtab, this%packName, title)
3314 call this%inputtab%table_df(1, 4, this%iout,
finalize=.false.)
3316 call this%inputtab%initialize_column(text, 10, alignment=
tabcenter)
3318 call this%inputtab%initialize_column(text, 20, alignment=
tableft)
3320 write (text,
'(a,1x,i6)')
'VALUE', n
3321 call this%inputtab%initialize_column(text, 15, alignment=
tabcenter)
3326 do n = 1, this%input%nbound
3327 itemno = this%input%ifno(n)
3330 setting = this%input%setting(n)
3334 if (trim(setting) ==
'STATUS')
then
3335 str = this%input%status(n)
3336 istat = this%lak_check_valid(itemno)
3337 if (istat == 0 .and. itemno >= 1 .and. itemno <= this%nlakes)
then
3338 if (trim(str) ==
'CONSTANT')
then
3339 this%iboundpak(itemno) = -1
3340 else if (trim(str) ==
'INACTIVE')
then
3341 this%iboundpak(itemno) = 0
3342 else if (trim(str) ==
'ACTIVE')
then
3343 this%iboundpak(itemno) = 1
3345 write (
errmsg,
'(a,a)') &
3346 'Unknown '//trim(this%text)//
' STATUS keyword: ', &
3350 this%status(itemno) = trim(str)
3355 if (trim(setting) ==
'STAGE')
then
3356 istat = this%lak_check_valid(itemno)
3361 if (trim(setting) ==
'RAINFALL') &
3362 call this%lak_set_nonneg_value(n, itemno, setting, this%rainfall, &
3364 if (trim(setting) ==
'EVAPORATION') &
3365 call this%lak_set_nonneg_value(n, itemno, setting, &
3366 this%evaporation,
'evaporation')
3367 if (trim(setting) ==
'RUNOFF') &
3368 call this%lak_set_nonneg_value(n, itemno, setting, this%runoff, &
3370 if (trim(setting) ==
'INFLOW') &
3371 call this%lak_set_nonneg_value(n, itemno, setting, this%inflow, &
3373 if (trim(setting) ==
'WITHDRAWAL') &
3374 call this%lak_set_nonneg_value(n, itemno, setting, &
3375 this%withdrawal,
'withdrawal')
3379 if (trim(setting) ==
'RATE' .or. trim(setting) ==
'INVERT' .or. &
3380 trim(setting) ==
'WIDTH' .or. trim(setting) ==
'ROUGH' .or. &
3381 trim(setting) ==
'SLOPE')
then
3382 istat = this%lak_check_valid(-itemno)
3388 if (istat == 0 .and. itemno >= 1 .and. itemno <= this%noutlets)
then
3389 if (trim(setting) ==
'INVERT') this%outlet_invert_set(itemno) = .true.
3390 if (trim(setting) ==
'WIDTH') this%outlet_width_set(itemno) = .true.
3391 if (trim(setting) ==
'ROUGH') this%outlet_rough_set(itemno) = .true.
3392 if (trim(setting) ==
'SLOPE') this%outlet_slope_set(itemno) = .true.
3396 if (this%naux > 0)
then
3397 if (trim(setting) ==
'PERIOD_AUXILIARY')
then
3398 if (itemno >= 1 .and. itemno <= this%nlakes)
then
3399 str = this%input%auxname(n)
3400 auxvaldbl = this%input%auxval(n)
3406 if (this%iprpak /= 0)
then
3407 call this%inputtab%add_term(itemno)
3408 if (trim(setting) ==
'PERIOD_AUXILIARY')
then
3409 call this%inputtab%add_term(
'AUXILIARY')
3411 call this%inputtab%add_term(trim(setting))
3413 select case (trim(setting))
3415 call this%inputtab%add_term(trim(str))
3416 call this%inputtab%add_term(
' ')
3418 call this%inputtab%add_term(this%stage(itemno))
3419 call this%inputtab%add_term(
' ')
3421 call this%inputtab%add_term(this%rainfall(itemno))
3422 call this%inputtab%add_term(
' ')
3423 case (
'EVAPORATION')
3424 call this%inputtab%add_term(this%evaporation(itemno))
3425 call this%inputtab%add_term(
' ')
3427 call this%inputtab%add_term(this%runoff(itemno))
3428 call this%inputtab%add_term(
' ')
3430 call this%inputtab%add_term(this%inflow(itemno))
3431 call this%inputtab%add_term(
' ')
3433 call this%inputtab%add_term(this%withdrawal(itemno))
3434 call this%inputtab%add_term(
' ')
3436 call this%inputtab%add_term(this%outrate(itemno))
3437 call this%inputtab%add_term(
' ')
3439 call this%inputtab%add_term(this%outinvert(itemno))
3440 call this%inputtab%add_term(
' ')
3442 call this%inputtab%add_term(this%outwidth(itemno))
3443 call this%inputtab%add_term(
' ')
3445 call this%inputtab%add_term(this%outrough(itemno))
3446 call this%inputtab%add_term(
' ')
3448 call this%inputtab%add_term(this%outslope(itemno))
3449 call this%inputtab%add_term(
' ')
3450 case (
'PERIOD_AUXILIARY')
3451 call this%inputtab%add_term(trim(str))
3452 call this%inputtab%add_term(auxvaldbl)
3454 call this%inputtab%add_term(
' ')
3455 call this%inputtab%add_term(
' ')
3459 if (this%iprpak /= 0)
then
3460 call this%inputtab%finalize_table()
3464 if (count_errors() > 0)
then
3465 call store_error_filename(this%input_fname)
3469 do n = 1, this%nlakes
3470 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3471 node = this%gwfconn(j)
3472 this%nodelist(j) = node
3473 this%bound(1, j) = this%xnewpak(n)
3474 this%bound(2, j) = this%satcond(j)
3475 this%bound(3, j) = this%belev(j)
3480 if (this%imover == 1)
then
3481 do n = 1, this%noutlets
3482 this%pakmvrobj%iprmap(n) = this%lakein(n)
3486 write (this%iout, fmtlsp) trim(this%filtyp)
3492 do n = 1, this%nlakes
3493 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3494 this%nodelist(j) = this%gwfconn(j)
3495 this%bound(3, j) = this%belev(j)
3498 end subroutine lak_rp
3502 subroutine lak_ad(this)
3506 class(laktype) :: this
3510 integer(I4B) :: iaux
3511 integer(I4B) :: itemno
3515 call this%BndExtType%bnd_ad()
3521 if (this%ts_active .and. this%noutlets > 0)
then
3522 do n = 1,
size(this%input%outletno)
3523 itemno = this%input%outletno(n)
3524 if (itemno < 1 .or. itemno > this%noutlets) cycle
3525 if (.not. this%outlet_invert_set(itemno) .and. &
3526 this%input%invert_tslink(n) /= 0) &
3527 this%outinvert(itemno) = this%input%outlets_invert(n)
3528 if (.not. this%outlet_width_set(itemno) .and. &
3529 this%input%width_tslink(n) /= 0) &
3530 this%outwidth(itemno) = this%input%outlets_width(n)
3531 if (.not. this%outlet_rough_set(itemno) .and. &
3532 this%input%rough_tslink(n) /= 0) &
3533 this%outrough(itemno) = this%input%outlets_rough(n)
3534 if (.not. this%outlet_slope_set(itemno) .and. &
3535 this%input%slope_tslink(n) /= 0) &
3536 this%outslope(itemno) = this%input%outlets_slope(n)
3541 if (this%naux > 0)
then
3542 do n = 1, this%nlakes
3543 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3544 do iaux = 1, this%naux
3545 if (this%noupdateauxvar(iaux) /= 0) cycle
3546 this%auxvar(iaux, j) = this%featureauxvar(iaux, n)
3557 do n = 1, this%nlakes
3558 this%xoldpak(n) = this%xnewpak(n)
3559 this%stageiter(n) = this%xnewpak(n)
3560 if (this%iboundpak(n) < 0)
then
3561 this%xnewpak(n) = this%stage(n)
3563 this%seep0(n) = dzero
3569 do n = 1, this%nlakes
3570 this%xnewpak(n) = this%xoldpak(n)
3571 this%stageiter(n) = this%xnewpak(n)
3572 if (this%iboundpak(n) < 0)
then
3573 this%xnewpak(n) = this%stage(n)
3575 this%seep0(n) = dzero
3580 if (this%imover == 1)
then
3581 call this%pakmvrobj%ad()
3583 end subroutine lak_ad
3589 subroutine lak_cf(this)
3591 class(laktype) :: this
3593 integer(I4B) :: j, n
3594 integer(I4B) :: igwfnode
3595 real(DP) :: hlak, bottom_lake
3598 do n = 1, this%nlakes
3599 this%seep0(n) = this%seep(n)
3603 do n = 1, this%nlakes
3604 this%s0(n) = this%xnewpak(n)
3605 call this%lak_calculate_exchange(n, this%s0(n), this%qgwf0(n))
3609 do n = 1, this%nlakes
3610 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3612 if (this%ictype(j) /= 0)
then
3615 igwfnode = this%nodesontop(j)
3616 if (this%ibound(igwfnode) == 0)
then
3617 call this%dis%highest_active(igwfnode, this%ibound)
3619 this%nodelist(j) = igwfnode
3620 this%gwfconn(j) = igwfnode
3627 do n = 1, this%nlakes
3629 hlak = this%xnewpak(n)
3632 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3635 igwfnode = this%gwfconn(j)
3638 if (this%ibound(igwfnode) < 1)
then
3643 if (this%ictype(j) /= 0)
then
3648 if (this%ictype(j) == 2 .or. this%ictype(j) == 3)
then
3653 bottom_lake = this%belev(j)
3654 if (hlak > bottom_lake .or. this%iboundpak(n) == 0)
then
3655 this%ibound(igwfnode) = iwetlake
3657 this%ibound(igwfnode) = 1
3665 call this%lak_bound_update()
3666 end subroutine lak_cf
3670 subroutine lak_fc(this, rhs, ia, idxglo, matrix_sln)
3672 class(laktype) :: this
3673 real(DP),
dimension(:),
intent(inout) :: rhs
3674 integer(I4B),
dimension(:),
intent(in) :: ia
3675 integer(I4B),
dimension(:),
intent(in) :: idxglo
3678 integer(I4B) :: j, n
3679 integer(I4B) :: igwfnode
3680 integer(I4B) :: ipossymd
3683 if (this%imover == 1)
then
3684 call this%pakmvrobj%fc()
3689 if (this%iimplicit /= 0)
then
3690 call this%lak_fc_implicit(rhs, matrix_sln)
3696 call this%lak_solve()
3697 do n = 1, this%nlakes
3698 if (this%iboundpak(n) == 0) cycle
3699 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3700 igwfnode = this%gwfconn(j)
3701 if (this%ibound(igwfnode) < 1) cycle
3702 ipossymd = idxglo(ia(igwfnode))
3703 call matrix_sln%add_value_pos(ipossymd, this%hcof(j))
3704 rhs(igwfnode) = rhs(igwfnode) + this%rhs(j)
3707 end subroutine lak_fc
3711 subroutine lak_fn(this, rhs, ia, idxglo, matrix_sln)
3713 class(laktype) :: this
3714 real(DP),
dimension(:),
intent(inout) :: rhs
3715 integer(I4B),
dimension(:),
intent(in) :: ia
3716 integer(I4B),
dimension(:),
intent(in) :: idxglo
3719 integer(I4B) :: j, n
3720 integer(I4B) :: ipos
3721 integer(I4B) :: igwfnode
3722 integer(I4B) :: idry
3739 if (this%iimplicit /= 0)
then
3743 do n = 1, this%nlakes
3744 if (this%iboundpak(n) == 0) cycle
3745 hlak = this%xnewpak(n)
3746 call this%lak_calculate_available(n, hlak, avail, &
3747 ra, ro, qinf, ex, this%delh)
3748 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3749 igwfnode = this%gwfconn(j)
3751 head = this%xnew(igwfnode)
3752 if (-this%hcof(j) > dzero)
then
3753 if (this%ibound(igwfnode) > 0)
then
3757 call this%lak_estimate_conn_exchange(2, n, j, idry, hlak, &
3758 head + this%delh, q1, avail)
3761 q = this%hcof(j) * head - this%rhs(j)
3763 rterm = this%hcof(j) * head
3765 drterm = (q1 - q) / this%delh
3768 call matrix_sln%add_value_pos(idxglo(ipos), drterm - this%hcof(j))
3769 rhs(igwfnode) = rhs(igwfnode) - rterm + drterm * head
3774 end subroutine lak_fn
3784 subroutine lak_nur(this, neqpak, x, xtemp, dx, inewtonur, dxmax, locmax)
3786 class(laktype),
intent(inout) :: this
3787 integer(I4B),
intent(in) :: neqpak
3788 real(DP),
dimension(neqpak),
intent(inout) :: x
3789 real(DP),
dimension(neqpak),
intent(in) :: xtemp
3790 real(DP),
dimension(neqpak),
intent(inout) :: dx
3791 integer(I4B),
intent(inout) :: inewtonur
3792 real(DP),
intent(inout) :: dxmax
3793 integer(I4B),
intent(inout) :: locmax
3801 if (this%iimplicit == 0)
return
3804 do n = 1, this%nlakes
3805 if (this%iboundpak(n) < 1) cycle
3806 botl = this%lakebot(n)
3810 if (x(n) < botl)
then
3812 xx = xtemp(n) * (done - dp9) + botl * dp9
3814 if (abs(dxx) > abs(dxmax))
then
3822 end subroutine lak_nur
3826 subroutine lak_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
3830 class(laktype),
intent(inout) :: this
3831 integer(I4B),
intent(in) :: innertot
3832 integer(I4B),
intent(in) :: kiter
3833 integer(I4B),
intent(in) :: iend
3834 integer(I4B),
intent(in) :: icnvgmod
3835 character(len=LENPAKLOC),
intent(inout) :: cpak
3836 integer(I4B),
intent(inout) :: ipak
3837 real(DP),
intent(inout) :: dpak
3839 character(len=LENPAKLOC) :: cloc
3840 character(len=LINELENGTH) :: tag
3841 integer(I4B) :: icheck
3842 integer(I4B) :: ipakfail
3843 integer(I4B) :: locdhmax
3844 integer(I4B) :: locresidmax
3845 integer(I4B) :: locdgwfmax
3846 integer(I4B) :: locdqoutmax
3847 integer(I4B) :: locdqfrommvrmax
3848 integer(I4B) :: ntabrows
3849 integer(I4B) :: ntabcols
3853 real(DP) :: qtolfact
3871 real(DP) :: residmax
3873 real(DP) :: dqoutmax
3874 real(DP) :: dqfrommvr
3875 real(DP) :: dqfrommvrmax
3877 call this%lak_set_legacy(kiter, icnvgmod)
3882 if (iend /= 0 .and. icnvgmod == 0)
then
3883 call this%lak_check_disconnected()
3889 if (this%iimplicit /= 0)
then
3894 icheck = this%iconvchk
3905 dqfrommvrmax = dzero
3909 if (this%ipakcsv == 0)
then
3910 if (icnvgmod == 0)
then
3918 if (.not.
associated(this%pakcsvtab))
then
3923 if (this%noutlets > 0)
then
3924 ntabcols = ntabcols + 2
3926 if (this%imover == 1)
then
3927 ntabcols = ntabcols + 2
3931 call table_cr(this%pakcsvtab, this%packName,
'')
3932 call this%pakcsvtab%table_df(ntabrows, ntabcols, this%ipakcsv, &
3933 lineseparator=.false., separator=
',', &
3937 tag =
'total_inner_iterations'
3938 call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3940 call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3942 call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3944 call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3946 call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3948 call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3950 call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3952 call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3953 tag =
'residmax_loc'
3954 call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3956 call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3958 call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3959 if (this%noutlets > 0)
then
3961 call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3962 tag =
'dqoutmax_loc'
3963 call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3965 if (this%imover == 1)
then
3966 tag =
'dqfrommvrmax'
3967 call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3968 tag =
'dqfrommvrmax_loc'
3969 call this%pakcsvtab%initialize_column(tag, 16, alignment=tableft)
3975 if (icheck /= 0)
then
3976 final_check:
do n = 1, this%nlakes
3977 if (this%iboundpak(n) < 1) cycle
3981 hlak = this%xnewpak(n)
3987 call this%lak_calculate_sarea(n, hlak, area)
3990 if (area > dzero)
then
3991 qtolfact =
delt / area
3997 call this%lak_calculate_residual(n, hlak, resid)
3998 resid = resid * qtolfact
4002 if (area > dzero)
then
4003 gwf0 = this%qgwf0(n)
4004 call this%lak_calculate_exchange(n, hlak, gwf)
4005 dgwf = (gwf0 - gwf) * qtolfact
4010 if (this%noutlets > 0)
then
4011 if (area > dzero)
then
4012 call this%lak_calculate_available(n, hlak0, inf, ra, ro, qinf, ex)
4013 call this%lak_calculate_outlet_outflow(n, hlak0, inf, qout0)
4014 call this%lak_calculate_available(n, hlak, inf, ra, ro, qinf, ex)
4015 call this%lak_calculate_outlet_outflow(n, hlak, inf, qout)
4016 dqout = (qout0 - qout) * qtolfact
4022 if (this%imover == 1)
then
4023 q = this%pakmvrobj%get_qfrommvr(n)
4024 q0 = this%pakmvrobj%get_qfrommvr0(n)
4025 dqfrommvr = qtolfact * (q0 - q)
4038 dqfrommvrmax = dqfrommvr
4041 if (abs(dh) > abs(dhmax))
then
4045 if (abs(resid) > abs(residmax))
then
4049 if (abs(dgwf) > abs(dgwfmax))
then
4053 if (abs(dqout) > abs(dqoutmax))
then
4057 if (abs(dqfrommvr) > abs(dqfrommvrmax))
then
4058 dqfrommvrmax = dqfrommvr
4065 if (abs(dhmax) > abs(dpak))
then
4068 write (cloc,
"(a,'-',a)") &
4069 trim(this%packName),
'stage'
4072 if (abs(residmax) > abs(dpak))
then
4075 write (cloc,
"(a,'-',a)") &
4076 trim(this%packName),
'residual'
4079 if (abs(dgwfmax) > abs(dpak))
then
4082 write (cloc,
"(a,'-',a)") &
4083 trim(this%packName),
'gwf'
4086 if (this%noutlets > 0)
then
4087 if (abs(dqoutmax) > abs(dpak))
then
4090 write (cloc,
"(a,'-',a)") &
4091 trim(this%packName),
'outlet'
4095 if (this%imover == 1)
then
4096 if (abs(dqfrommvrmax) > abs(dpak))
then
4097 ipak = locdqfrommvrmax
4099 write (cloc,
"(a,'-',a)") trim(this%packName),
'qfrommvr'
4105 if (this%ipakcsv /= 0)
then
4108 call this%pakcsvtab%add_term(innertot)
4109 call this%pakcsvtab%add_term(
totim)
4110 call this%pakcsvtab%add_term(
kper)
4111 call this%pakcsvtab%add_term(
kstp)
4112 call this%pakcsvtab%add_term(kiter)
4113 call this%pakcsvtab%add_term(dhmax)
4114 call this%pakcsvtab%add_term(locdhmax)
4115 call this%pakcsvtab%add_term(residmax)
4116 call this%pakcsvtab%add_term(locresidmax)
4117 call this%pakcsvtab%add_term(dgwfmax)
4118 call this%pakcsvtab%add_term(locdgwfmax)
4119 if (this%noutlets > 0)
then
4120 call this%pakcsvtab%add_term(dqoutmax)
4121 call this%pakcsvtab%add_term(locdqoutmax)
4123 if (this%imover == 1)
then
4124 call this%pakcsvtab%add_term(dqfrommvrmax)
4125 call this%pakcsvtab%add_term(locdqfrommvrmax)
4130 call this%pakcsvtab%finalize_table()
4134 end subroutine lak_cc
4138 subroutine lak_cq(this, x, flowja, iadv)
4142 class(laktype),
intent(inout) :: this
4143 real(DP),
dimension(:),
intent(in) :: x
4144 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
4145 integer(I4B),
optional,
intent(in) :: iadv
4148 real(DP) :: chratin, chratout
4150 integer(I4B) :: j, n, igwfnode
4151 real(DP) :: hlak, head, flow, dqdh
4152 real(DP) :: v0, v1, sa, sf
4154 call this%lak_solve(update=.false.)
4163 if (this%iimplicit /= 0)
then
4164 do n = 1, this%nlakes
4165 if (this%iboundpak(n) < 1 .or. this%ilegacy(n) /= 0) cycle
4166 hlak = this%xnewpak(n)
4169 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4170 igwfnode = this%gwfconn(j)
4171 if (this%ibound(igwfnode) < 1) cycle
4172 head = this%xnew(igwfnode)
4173 call this%lak_calculate_conn_exchange_deriv(n, j, hlak, head, &
4175 this%hcof(j) = -dqdh
4176 this%rhs(j) = -dqdh * head + flow
4186 call this%lak_calculate_sarea(n, hlak, sa)
4188 if (this%surfdep > dzero)
then
4190 this%lakebot(n), hlak)
4192 this%evap(n) = -this%evaporation(n) * sa * sf
4193 this%withr(n) = -this%withdrawal(n) * sf
4199 call this%BndType%bnd_cq(x, flowja, iadv=1)
4204 do n = 1, this%nlakes
4205 this%chterm(n) = dzero
4206 if (this%iboundpak(n) == 0) cycle
4207 hlak = this%xnewpak(n)
4208 call this%lak_calculate_vol(n, hlak, v1)
4211 if (this%iboundpak(n) /= 0)
then
4214 rrate = this%precip(n)
4215 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4218 rrate = this%evap(n)
4219 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4222 rrate = this%runoff(n)
4223 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4226 rrate = this%inflow(n)
4227 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4230 rrate = this%withr(n)
4231 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4235 if (this%iboundpak(n) > 0)
then
4236 if (this%gwfiss /= 1)
then
4237 call this%lak_calculate_vol(n, this%xoldpak(n), v0)
4238 rrate = -(v1 - v0) /
delt
4239 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4242 this%qsto(n) = rrate
4245 call this%lak_get_external_outlet(n, rrate)
4246 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4249 if (this%imover == 1)
then
4250 if (this%iboundpak(n) /= 0)
then
4251 rrate = this%pakmvrobj%get_qfrommvr(n)
4255 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4261 do n = 1, this%nlakes
4263 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4267 rrate = -this%simvals(j)
4268 this%qleak(j) = rrate
4269 if (this%iboundpak(n) /= 0)
then
4270 call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4276 call this%lak_fill_budobj()
4277 end subroutine lak_cq
4281 subroutine lak_ot_package_flows(this, icbcfl, ibudfl)
4283 class(laktype) :: this
4284 integer(I4B),
intent(in) :: icbcfl
4285 integer(I4B),
intent(in) :: ibudfl
4286 integer(I4B) :: ibinun
4290 if (this%ibudgetout /= 0)
then
4291 ibinun = this%ibudgetout
4293 if (icbcfl == 0) ibinun = 0
4294 if (ibinun > 0)
then
4295 call this%budobj%save_flows(this%dis, ibinun,
kstp,
kper,
delt, &
4300 if (ibudfl /= 0 .and. this%iprflow /= 0)
then
4301 call this%budobj%write_flowtable(this%dis,
kstp,
kper)
4303 end subroutine lak_ot_package_flows
4307 subroutine lak_ot_model_flows(this, icbcfl, ibudfl, icbcun, imap)
4308 class(laktype) :: this
4309 integer(I4B),
intent(in) :: icbcfl
4310 integer(I4B),
intent(in) :: ibudfl
4311 integer(I4B),
intent(in) :: icbcun
4312 integer(I4B),
dimension(:),
optional,
intent(in) :: imap
4315 call this%BndType%bnd_ot_model_flows(icbcfl, ibudfl, icbcun, this%imap)
4316 end subroutine lak_ot_model_flows
4320 subroutine lak_ot_dv(this, idvsave, idvprint)
4324 class(laktype) :: this
4325 integer(I4B),
intent(in) :: idvsave
4326 integer(I4B),
intent(in) :: idvprint
4327 integer(I4B) :: ibinun
4337 if (this%istageout /= 0)
then
4338 ibinun = this%istageout
4340 if (idvsave == 0) ibinun = 0
4343 if (ibinun > 0)
then
4344 do n = 1, this%nlakes
4346 d = v - this%lakebot(n)
4347 if (this%iboundpak(n) == 0)
then
4349 else if (d <=
dzero)
then
4355 this%nlakes, 1, 1, ibinun)
4359 if (idvprint /= 0 .and. this%iprhed /= 0)
then
4362 call this%stagetab%set_kstpkper(
kstp,
kper)
4365 do n = 1, this%nlakes
4366 if (this%iboundpak(n) == 0)
then
4372 stage = this%xnewpak(n)
4373 call this%lak_calculate_sarea(n, stage, sa)
4374 call this%lak_calculate_warea(n, stage, wa)
4375 call this%lak_calculate_vol(n, stage, v)
4377 if (this%inamedbound == 1)
then
4378 call this%stagetab%add_term(this%lakename(n))
4380 call this%stagetab%add_term(n)
4381 call this%stagetab%add_term(stage)
4382 call this%stagetab%add_term(sa)
4383 call this%stagetab%add_term(wa)
4384 call this%stagetab%add_term(v)
4387 end subroutine lak_ot_dv
4391 subroutine lak_ot_bdsummary(this, kstp, kper, iout, ibudfl)
4395 class(laktype) :: this
4396 integer(I4B),
intent(in) :: kstp
4397 integer(I4B),
intent(in) :: kper
4398 integer(I4B),
intent(in) :: iout
4399 integer(I4B),
intent(in) :: ibudfl
4401 call this%budobj%write_budtable(kstp, kper, iout, ibudfl,
totim,
delt)
4402 end subroutine lak_ot_bdsummary
4406 subroutine lak_da(this)
4410 class(laktype) :: this
4413 call this%input%destroy()
4416 deallocate (this%lakename)
4417 deallocate (this%status)
4418 deallocate (this%clakbudget)
4420 deallocate (this%cauxcbc)
4429 if (this%ntables > 0)
then
4438 call this%budobj%budgetobject_da()
4439 deallocate (this%budobj)
4440 nullify (this%budobj)
4443 if (this%noutlets > 0)
then
4457 if (this%iprhed > 0)
then
4458 call this%stagetab%table_da()
4459 deallocate (this%stagetab)
4460 nullify (this%stagetab)
4464 if (this%ipakcsv > 0)
then
4465 if (
associated(this%pakcsvtab))
then
4466 call this%pakcsvtab%table_da()
4467 deallocate (this%pakcsvtab)
4468 nullify (this%pakcsvtab)
4478 if (
allocated(this%pakcsvfile))
deallocate (this%pakcsvfile)
4533 if (this%iimplicit == 0)
then
4578 nullify (this%gwfiss)
4581 call this%BndExtType%bnd_da()
4582 end subroutine lak_da
4589 class(laktype),
intent(inout) :: this
4592 this%listlabel = trim(this%filtyp)//
' NO.'
4593 if (this%dis%ndim == 3)
then
4594 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'LAYER'
4595 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'ROW'
4596 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'COL'
4597 elseif (this%dis%ndim == 2)
then
4598 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'LAYER'
4599 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'CELL2D'
4601 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'NODE'
4603 write (this%listlabel,
'(a, a16)') trim(this%listlabel),
'STRESS RATE'
4604 if (this%inamedbound == 1)
then
4605 write (this%listlabel,
'(a, a16)') trim(this%listlabel),
'BOUNDARY NAME'
4612 subroutine lak_set_pointers(this, neq, ibound, xnew, xold, flowja)
4616 class(laktype) :: this
4617 integer(I4B),
pointer :: neq
4618 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound
4619 real(DP),
dimension(:),
pointer,
contiguous :: xnew
4620 real(DP),
dimension(:),
pointer,
contiguous :: xold
4621 real(DP),
dimension(:),
pointer,
contiguous :: flowja
4624 integer(I4B) :: istart, iend
4627 call this%BndType%set_pointers(neq, ibound, xnew, xold, flowja)
4633 if (this%iimplicit /= 0)
then
4634 istart = this%dis%nodes + this%ioffset + 1
4635 iend = istart + this%nlakes - 1
4636 this%iboundpak => this%ibound(istart:iend)
4637 this%xnewpak => this%xnew(istart:iend)
4638 call mem_checkin(this%xnewpak,
'XNEWPAK', this%memoryPath,
'X', &
4639 this%memoryPathModel)
4642 do n = 1, this%nlakes
4643 this%xnewpak(n) = dep20
4646 end subroutine lak_set_pointers
4654 subroutine lak_ac(this, moffset, sparse)
4657 class(laktype),
intent(inout) :: this
4658 integer(I4B),
intent(in) :: moffset
4661 integer(I4B) :: j, n
4663 integer(I4B) :: jglo
4664 integer(I4B) :: nglo
4667 if (this%iimplicit == 0)
return
4670 do n = 1, this%nlakes
4671 nglo = moffset + this%dis%nodes + this%ioffset + n
4672 call sparse%addconnection(nglo, nglo, 1)
4673 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4674 jj = this%gwfconn(j)
4676 call sparse%addconnection(nglo, jglo, 1)
4677 call sparse%addconnection(jglo, nglo, 1)
4680 end subroutine lak_ac
4688 subroutine lak_mc(this, moffset, matrix_sln)
4691 class(laktype),
intent(inout) :: this
4692 integer(I4B),
intent(in) :: moffset
4697 integer(I4B) :: iglo
4698 integer(I4B) :: jglo
4699 integer(I4B) :: ipos
4704 if (this%iimplicit == 0)
then
4705 call mem_allocate(this%idxlocnode, 0,
'IDXLOCNODE', this%memoryPath)
4706 call mem_allocate(this%idxdiag, 0,
'IDXDIAG', this%memoryPath)
4707 call mem_allocate(this%idxoffdglo, 0,
'IDXOFFDGLO', this%memoryPath)
4708 call mem_allocate(this%idxsymdglo, 0,
'IDXSYMDGLO', this%memoryPath)
4709 call mem_allocate(this%idxsymoffdglo, 0,
'IDXSYMOFFDGLO', this%memoryPath)
4712 call mem_allocate(this%idxlocnode, this%nlakes,
'IDXLOCNODE', &
4714 call mem_allocate(this%idxdiag, this%nlakes,
'IDXDIAG', this%memoryPath)
4715 call mem_allocate(this%idxoffdglo, this%maxbound,
'IDXOFFDGLO', &
4717 call mem_allocate(this%idxsymdglo, this%maxbound,
'IDXSYMDGLO', &
4719 call mem_allocate(this%idxsymoffdglo, this%maxbound,
'IDXSYMOFFDGLO', &
4726 do n = 1, this%nlakes
4727 iglo = moffset + this%dis%nodes + this%ioffset + n
4728 this%idxlocnode(n) = this%dis%nodes + this%ioffset + n
4729 this%idxdiag(n) = matrix_sln%get_position_diag(iglo)
4730 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4731 jglo = this%gwfconn(j) + moffset
4732 this%idxoffdglo(ipos) = matrix_sln%get_position(iglo, jglo)
4739 do n = 1, this%nlakes
4740 jglo = moffset + this%dis%nodes + this%ioffset + n
4741 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4742 iglo = this%gwfconn(j) + moffset
4743 this%idxsymdglo(ipos) = matrix_sln%get_position_diag(iglo)
4744 this%idxsymoffdglo(ipos) = matrix_sln%get_position(iglo, jglo)
4748 end subroutine lak_mc
4755 logical function lak_obs_supported(this)
4757 class(laktype) :: this
4759 lak_obs_supported = .true.
4760 end function lak_obs_supported
4765 subroutine lak_df_obs(this)
4767 class(laktype) :: this
4769 integer(I4B) :: indx
4773 call this%obs%StoreObsType(
'stage', .false., indx)
4774 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4778 call this%obs%StoreObsType(
'ext-inflow', .true., indx)
4779 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4783 call this%obs%StoreObsType(
'outlet-inflow', .true., indx)
4784 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4788 call this%obs%StoreObsType(
'inflow', .true., indx)
4789 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4793 call this%obs%StoreObsType(
'from-mvr', .true., indx)
4794 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4798 call this%obs%StoreObsType(
'rainfall', .true., indx)
4799 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4803 call this%obs%StoreObsType(
'runoff', .true., indx)
4804 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4808 call this%obs%StoreObsType(
'lak', .true., indx)
4809 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4813 call this%obs%StoreObsType(
'evaporation', .true., indx)
4814 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4818 call this%obs%StoreObsType(
'withdrawal', .true., indx)
4819 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4823 call this%obs%StoreObsType(
'ext-outflow', .true., indx)
4824 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4828 call this%obs%StoreObsType(
'to-mvr', .true., indx)
4829 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4833 call this%obs%StoreObsType(
'storage', .true., indx)
4834 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4838 call this%obs%StoreObsType(
'constant', .true., indx)
4839 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4843 call this%obs%StoreObsType(
'outlet', .true., indx)
4844 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4848 call this%obs%StoreObsType(
'volume', .true., indx)
4849 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4853 call this%obs%StoreObsType(
'surface-area', .true., indx)
4854 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4858 call this%obs%StoreObsType(
'wetted-area', .true., indx)
4859 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4863 call this%obs%StoreObsType(
'conductance', .true., indx)
4864 this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4865 end subroutine lak_df_obs
4870 subroutine lak_bd_obs(this)
4872 class(laktype) :: this
4875 integer(I4B) :: igwfnode
4886 if (this%obs%npakobs > 0)
then
4887 call this%obs%obs_bd_clear()
4888 do i = 1, this%obs%npakobs
4889 obsrv => this%obs%pakobs(i)%obsrv
4890 do j = 1, obsrv%indxbnds_count
4892 jj = obsrv%indxbnds(j)
4893 select case (obsrv%ObsTypeId)
4895 if (this%iboundpak(jj) /= 0)
then
4896 v = this%xnewpak(jj)
4899 if (this%iboundpak(jj) /= 0)
then
4900 call this%lak_calculate_inflow(jj, v)
4902 case (
'OUTLET-INFLOW')
4903 if (this%iboundpak(jj) /= 0)
then
4904 call this%lak_calculate_outlet_inflow(jj, v)
4907 if (this%iboundpak(jj) /= 0)
then
4908 call this%lak_calculate_inflow(jj, v)
4909 call this%lak_calculate_outlet_inflow(jj, v2)
4913 if (this%iboundpak(jj) /= 0)
then
4914 if (this%imover == 1)
then
4915 v = this%pakmvrobj%get_qfrommvr(jj)
4919 if (this%iboundpak(jj) /= 0)
then
4923 if (this%iboundpak(jj) /= 0)
then
4928 if (this%iboundpak(n) /= 0)
then
4929 igwfnode = this%gwfconn(jj)
4930 hgwf = this%xnew(igwfnode)
4931 if (this%hcof(jj) /= dzero)
then
4932 v = -(this%hcof(jj) * (this%xnewpak(n) - hgwf))
4937 case (
'EVAPORATION')
4938 if (this%iboundpak(jj) /= 0)
then
4942 if (this%iboundpak(jj) /= 0)
then
4945 case (
'EXT-OUTFLOW')
4947 if (this%iboundpak(n) /= 0)
then
4948 if (this%lakeout(jj) == 0)
then
4949 v = this%simoutrate(jj)
4951 if (this%imover == 1)
then
4952 v = v + this%pakmvrobj%get_qtomvr(jj)
4959 if (this%iboundpak(n) /= 0)
then
4960 if (this%imover == 1)
then
4961 v = this%pakmvrobj%get_qtomvr(jj)
4968 if (this%iboundpak(jj) /= 0)
then
4972 if (this%iboundpak(jj) /= 0)
then
4977 if (this%iboundpak(n) /= 0)
then
4978 v = this%simoutrate(jj)
4981 if (this%iboundpak(jj) /= 0)
then
4982 call this%lak_calculate_vol(jj, this%xnewpak(jj), v)
4984 case (
'SURFACE-AREA')
4985 if (this%iboundpak(jj) /= 0)
then
4986 hlak = this%xnewpak(jj)
4987 call this%lak_calculate_sarea(jj, hlak, v)
4989 case (
'WETTED-AREA')
4991 if (this%iboundpak(n) /= 0)
then
4992 hlak = this%xnewpak(n)
4993 igwfnode = this%gwfconn(jj)
4994 hgwf = this%xnew(igwfnode)
4995 call this%lak_calculate_conn_warea(n, jj, hlak, hgwf, v)
4997 case (
'CONDUCTANCE')
4999 if (this%iboundpak(n) /= 0)
then
5000 hlak = this%xnewpak(n)
5001 igwfnode = this%gwfconn(jj)
5002 hgwf = this%xnew(igwfnode)
5003 call this%lak_calculate_conn_conductance(n, jj, hlak, hgwf, v)
5006 errmsg =
'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
5007 call store_error(errmsg)
5009 call this%obs%SaveOneSimval(obsrv, v)
5014 if (count_errors() > 0)
then
5015 call store_error_filename(this%input_fname)
5018 end subroutine lak_bd_obs
5025 subroutine lak_rp_obs(this)
5028 class(laktype),
intent(inout) :: this
5035 character(len=LENBOUNDNAME) :: bname
5036 logical(LGP) :: jfound
503910
format(
'Boundary "', a,
'" for observation "', a, &
5040 '" is invalid in package "', a,
'"')
5046 do i = 1, this%obs%npakobs
5047 obsrv => this%obs%pakobs(i)%obsrv
5050 nn1 = obsrv%NodeNumber
5051 if (nn1 == namedboundflag)
then
5052 bname = obsrv%FeatureName
5053 if (bname /=
'')
then
5058 if (obsrv%ObsTypeId ==
'LAK' .or. &
5059 obsrv%ObsTypeId ==
'CONDUCTANCE' .or. &
5060 obsrv%ObsTypeId ==
'WETTED-AREA')
then
5061 if (this%inamedbound /= 0)
then
5062 do j = 1, this%nlakes
5063 do jj = this%idxlakeconn(j), this%idxlakeconn(j + 1) - 1
5064 if (this%boundname(jj) == bname)
then
5066 call obsrv%AddObsIndex(jj)
5071 else if (obsrv%ObsTypeId ==
'EXT-OUTFLOW' .or. &
5072 obsrv%ObsTypeId ==
'TO-MVR' .or. &
5073 obsrv%ObsTypeId ==
'OUTLET')
then
5074 do j = 1, this%noutlets
5076 if (this%lakename(jj) == bname)
then
5078 call obsrv%AddObsIndex(j)
5082 do j = 1, this%nlakes
5083 if (this%lakename(j) == bname)
then
5085 call obsrv%AddObsIndex(j)
5089 if (.not. jfound)
then
5090 write (errmsg, 10) &
5091 trim(bname), trim(obsrv%Name), trim(this%packName)
5092 call store_error(errmsg)
5096 if (obsrv%indxbnds_count == 0)
then
5097 if (obsrv%ObsTypeId ==
'LAK' .or. &
5098 obsrv%ObsTypeId ==
'CONDUCTANCE' .or. &
5099 obsrv%ObsTypeId ==
'WETTED-AREA')
then
5100 nn2 = obsrv%NodeNumber2
5101 if (nn1 < 1 .or. nn1 > this%nlakes)
then
5102 write (errmsg,
'(5a,i0,a,i0,a)') &
5103 'Observation ', trim(obsrv%Name),
' of type ', &
5104 trim(adjustl(obsrv%ObsTypeId)),
' was assigned lake ', &
5105 nn1,
'. Lake must be >= 1 and <= ', this%nlakes,
'.'
5106 call store_error(errmsg)
5107 else if (nn2 < 1 .or. nn2 > this%nlakeconn(nn1))
then
5108 write (errmsg,
'(5a,i0,a,i0,a,i0,a)') &
5109 'Observation ', trim(obsrv%Name),
' of type ', &
5110 trim(adjustl(obsrv%ObsTypeId)), &
5111 ' was assigned connection ', nn2,
' of lake ', nn1, &
5112 '. Connection must be >= 1 and <= ', &
5113 this%nlakeconn(nn1),
'.'
5114 call store_error(errmsg)
5116 j = this%idxlakeconn(nn1) + nn2 - 1
5117 call obsrv%AddObsIndex(j)
5120 call obsrv%AddObsIndex(nn1)
5123 errmsg =
'Programming error in lak_rp_obs'
5124 call store_error(errmsg)
5130 if (obsrv%ObsTypeId ==
'STAGE')
then
5131 if (obsrv%indxbnds_count > 1)
then
5132 write (errmsg,
'(a,3(1x,a))') &
5133 trim(adjustl(obsrv%ObsTypeId)), &
5134 'for observation', trim(adjustl(obsrv%Name)), &
5135 ' must be assigned to a lake with a unique boundname.'
5136 call store_error(errmsg)
5141 if (obsrv%ObsTypeId ==
'TO-MVR' .or. &
5142 obsrv%ObsTypeId ==
'EXT-OUTFLOW' .or. &
5143 obsrv%ObsTypeId ==
'OUTLET')
then
5144 do j = 1, obsrv%indxbnds_count
5145 nn1 = obsrv%indxbnds(j)
5146 if (nn1 < 1 .or. nn1 > this%noutlets)
then
5147 write (errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5148 trim(adjustl(obsrv%ObsTypeId)), &
5149 ' outlet must be > 0 and <=', this%noutlets, &
5150 '(specified value is ', nn1,
')'
5151 call store_error(errmsg)
5154 else if (obsrv%ObsTypeId ==
'LAK' .or. &
5155 obsrv%ObsTypeId ==
'CONDUCTANCE' .or. &
5156 obsrv%ObsTypeId ==
'WETTED-AREA')
then
5157 do j = 1, obsrv%indxbnds_count
5158 nn1 = obsrv%indxbnds(j)
5159 if (nn1 < 1 .or. nn1 > this%maxbound)
then
5160 write (errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5161 trim(adjustl(obsrv%ObsTypeId)), &
5162 'lake connection number must be > 0 and <=', this%maxbound, &
5163 '(specified value is ', nn1,
')'
5164 call store_error(errmsg)
5168 do j = 1, obsrv%indxbnds_count
5169 nn1 = obsrv%indxbnds(j)
5170 if (nn1 < 1 .or. nn1 > this%nlakes)
then
5171 write (errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5172 trim(adjustl(obsrv%ObsTypeId)), &
5173 ' lake must be > 0 and <=', this%nlakes, &
5174 '(specified value is ', nn1,
')'
5175 call store_error(errmsg)
5182 if (count_errors() > 0)
then
5183 call store_error_filename(this%input_fname)
5186 end subroutine lak_rp_obs
5195 subroutine lak_process_obsid(obsrv, dis, inunitobs, iout)
5199 integer(I4B),
intent(in) :: inunitobs
5200 integer(I4B),
intent(in) :: iout
5202 integer(I4B) :: nn1, nn2
5203 integer(I4B) :: icol, istart, istop
5204 character(len=LINELENGTH) :: string
5205 character(len=LENBOUNDNAME) :: bndname
5207 string = obsrv%IDstring
5213 call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname)
5214 if (nn1 == namedboundflag)
then
5215 obsrv%FeatureName = bndname
5217 if (obsrv%ObsTypeId ==
'LAK' .or. obsrv%ObsTypeId ==
'CONDUCTANCE' .or. &
5218 obsrv%ObsTypeId ==
'WETTED-AREA')
then
5219 call extract_idnum_or_bndname(string, icol, istart, istop, nn2, bndname)
5220 if (len_trim(bndname) < 1 .and. nn2 < 0)
then
5221 write (errmsg,
'(a,1x,a,a,1x,a,1x,a)') &
5222 'For observation type', trim(adjustl(obsrv%ObsTypeId)), &
5223 ', ID given as an integer and not as boundname,', &
5224 'but ID2 (iconn) is missing. Either change ID to valid', &
5225 'boundname or supply valid entry for ID2.'
5226 call store_error(errmsg)
5228 if (nn2 == namedboundflag)
then
5229 obsrv%FeatureName = bndname
5233 obsrv%NodeNumber2 = nn2
5238 obsrv%NodeNumber = nn1
5239 end subroutine lak_process_obsid
5247 subroutine lak_accumulate_chterm(this, ilak, rrate, chratin, chratout)
5249 class(laktype) :: this
5250 integer(I4B),
intent(in) :: ilak
5251 real(DP),
intent(in) :: rrate
5252 real(DP),
intent(inout) :: chratin
5253 real(DP),
intent(inout) :: chratout
5258 if (this%iboundpak(ilak) < 0)
then
5260 this%chterm(ilak) = this%chterm(ilak) + q
5266 chratout = chratout - q
5270 chratin = chratin + q
5273 end subroutine lak_accumulate_chterm
5277 subroutine lak_bound_update(this)
5279 class(laktype),
intent(inout) :: this
5281 integer(I4B) :: j, n, node
5282 real(DP) :: hlak, head, clak
5285 if (this%nbound == 0)
return
5288 do n = 1, this%nlakes
5289 hlak = this%xnewpak(n)
5290 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5291 node = this%gwfconn(j)
5292 head = this%xnew(node)
5293 call this%lak_calculate_conn_conductance(n, j, hlak, head, clak)
5294 this%bound(1, j) = hlak
5295 this%bound(2, j) = clak
5298 end subroutine lak_bound_update
5308 subroutine lak_solve(this, update, only_legacy)
5312 class(laktype),
intent(inout) :: this
5313 logical(LGP),
intent(in),
optional :: update
5314 logical(LGP),
intent(in),
optional :: only_legacy
5316 logical(LGP) :: lupdate
5317 logical(LGP) :: legonly
5320 integer(I4B) :: iicnvg
5321 integer(I4B) :: iter
5322 integer(I4B) :: maxiter
5323 integer(I4B) :: ncnv
5335 if (
present(update))
then
5342 if (
present(only_legacy))
then
5343 legonly = only_legacy
5352 do n = 1, this%nlakes
5356 if (legonly .and. this%ilegacy(n) == 0)
then
5361 this%surfin(n) = dzero
5362 this%surfout(n) = dzero
5363 this%surfout1(n) = dzero
5364 if (this%xnewpak(n) < this%lakebot(n))
then
5365 this%xnewpak(n) = this%lakebot(n)
5367 if (this%gwfiss /= 0)
then
5368 this%xoldpak(n) = this%xnewpak(n)
5373 this%en1(n) = this%lakebot(n)
5374 call this%lak_calculate_residual(n, this%en1(n), this%r1(n))
5375 this%en2(n) = this%laketop(n)
5376 call this%lak_calculate_residual(n, this%en2(n), this%r2(n))
5380 do n = 1, this%noutlets
5381 if (legonly .and. this%ilegacy(this%lakein(n)) == 0) cycle
5382 this%simoutrate(n) = dzero
5386 do n = 1, this%nlakes
5387 call this%lak_calculate_outlet_inflow(n, this%surfin(n))
5392 do n = 1, this%nlakes
5393 hlak0 = this%xoldpak(n)
5394 hlak = this%xnewpak(n)
5395 call this%lak_calculate_runoff(n, ro)
5396 call this%lak_calculate_inflow(n, qinf)
5397 call this%lak_calculate_external(n, ex)
5398 call this%lak_calculate_vol(n, hlak0, v0)
5399 call this%lak_calculate_vol(n, hlak, v1)
5400 this%flwin(n) = this%surfin(n) + ro + qinf + ex + &
5405 do n = 1, this%nlakes
5406 call this%lak_calculate_outlet_inflow(n, outinf)
5407 this%flwin(n) = this%flwin(n) + outinf
5411 maxiter = this%maxlakit
5414 converge:
do iter = 1, maxiter
5416 do n = 1, this%nlakes
5417 if (this%ncncvr(n) == 0) ncnv = 1
5419 if (iter == maxiter) ncnv = 0
5420 if (ncnv == 0) iicnvg = 1
5423 do n = 1, this%nlakes
5424 this%evap(n) = dzero
5425 this%precip(n) = dzero
5426 this%precip1(n) = dzero
5427 this%seep(n) = dzero
5428 this%seep1(n) = dzero
5429 this%evap(n) = dzero
5430 this%evap1(n) = dzero
5431 this%evapo(n) = dzero
5432 this%withr(n) = dzero
5433 this%withr1(n) = dzero
5434 this%flwiter(n) = this%flwin(n)
5435 this%flwiter1(n) = this%flwin(n)
5436 if (this%gwfiss /= 0)
then
5437 this%flwiter(n) = dep20
5438 this%flwiter1(n) = dep20
5440 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5441 this%hcof(j) = dzero
5446 do n = 1, this%nlakes
5447 if (legonly .and. this%ilegacy(n) == 0) cycle
5448 call this%lak_estimate_seepage_single(n, ncnv)
5451 laklevel:
do n = 1, this%nlakes
5452 if (legonly .and. this%ilegacy(n) == 0) cycle laklevel
5453 call this%lak_solve_single(n, iter, maxiter, ncnv, lupdate)
5456 if (iicnvg == 1)
exit converge
5465 if (this%imover == 1 .and. .not. legonly)
then
5466 do n = 1, this%noutlets
5467 call this%pakmvrobj%accumulate_qformvr(n, -this%simoutrate(n))
5470 end subroutine lak_solve
5480 subroutine lak_solve_single(this, n, iter, maxiter, ncnv, lupdate)
5484 class(laktype),
intent(inout) :: this
5485 integer(I4B),
intent(in) :: n
5486 integer(I4B),
intent(in) :: iter
5487 integer(I4B),
intent(in) :: maxiter
5488 integer(I4B),
intent(in) :: ncnv
5489 logical(LGP),
intent(in) :: lupdate
5491 integer(I4B) :: ibflg
5492 integer(I4B) :: idhp
5512 real(DP) :: qtolfact
5518 if (this%iboundpak(n) == 0)
then
5523 hlak = this%xnewpak(n)
5524 if (iter < maxiter)
then
5525 this%stageiter(n) = this%xnewpak(n)
5527 call this%lak_calculate_rainfall(n, hlak, ra)
5529 this%flwiter(n) = this%flwiter(n) + ra
5530 call this%lak_calculate_rainfall(n, hlak + delh, ra)
5531 this%precip1(n) = ra
5532 this%flwiter1(n) = this%flwiter1(n) + ra
5535 call this%lak_calculate_withdrawal(n, this%flwiter(n), wr)
5537 call this%lak_calculate_withdrawal(n, this%flwiter1(n), wr)
5541 call this%lak_calculate_evaporation(n, hlak, this%flwiter(n), ev)
5543 call this%lak_calculate_evaporation(n, hlak + delh, this%flwiter1(n), ev)
5547 call this%lak_calculate_outlet_outflow(n, hlak + delh, &
5550 call this%lak_calculate_outlet_outflow(n, hlak, this%flwiter(n), &
5554 call this%lak_calculate_outlet_inflow(n, this%surfin(n))
5558 if (this%iboundpak(n) > 0 .and. lupdate .eqv. .true.)
then
5561 hlak0 = this%xoldpak(n)
5562 hlak = this%xnewpak(n)
5563 call this%lak_calculate_vol(n, hlak0, v0)
5564 call this%lak_calculate_vol(n, hlak, v1)
5565 call this%lak_calculate_runoff(n, ro)
5566 call this%lak_calculate_inflow(n, qinf)
5567 call this%lak_calculate_external(n, ex)
5568 this%flwin(n) = this%surfin(n) + ro + qinf + ex + &
5572 resid = this%precip(n) + this%evap(n) + this%withr(n) + ro + &
5573 qinf + ex + this%surfin(n) + &
5574 this%surfout(n) + this%seep(n)
5575 resid1 = this%precip1(n) + this%evap1(n) + this%withr1(n) + ro + &
5576 qinf + ex + this%surfin(n) + &
5577 this%surfout1(n) + this%seep1(n)
5580 hlak = this%xnewpak(n)
5581 if (this%gwfiss /= 1)
then
5582 call this%lak_calculate_vol(n, hlak, v1)
5583 resid = resid + (v0 - v1) /
delt
5584 call this%lak_calculate_vol(n, hlak + delh, v1)
5585 resid1 = resid1 + (v0 - v1) /
delt
5589 if (abs(resid1 - resid) > dzero)
then
5590 derv = (resid1 - resid) / delh
5592 if (abs(derv) > dprec)
then
5596 if (resid < dzero)
then
5599 call this%lak_vol2stage(n, resid, dh)
5606 if (iter == 1) this%dh0(n) = dh
5608 adh0 = abs(this%dh0(n))
5609 if ((ts >= this%en2(n)) .or. (ts < this%en1(n)))
then
5612 if ((adh > adh0) .or. (ts - this%lakebot(n)) < dprec)
then
5614 call this%lak_bisection(n, ibflg, hlak, ts, dh, residb)
5620 this%seep0(n) = this%seep(n)
5624 if (this%seep(n) * this%seep0(n) < dprec)
then
5625 this%iseepc(n) = this%iseepc(n) + 1
5631 if (dh * this%dh0(n) < dprec) idhp = 1
5634 if (adh > adh0) idhp = 1
5637 this%idhc(n) = this%idhc(n) + 1
5642 if (ibflg == 1)
then
5643 if (this%iseepc(n) > 7 .or. this%idhc(n) > 12)
then
5644 call this%lak_bisection(n, ibflg, hlak, ts, dh, residb)
5653 if (hlak < this%lakebot(n))
then
5654 hlak = this%lakebot(n)
5658 call this%lak_calculate_sarea(n, hlak, area)
5661 if (area > dzero)
then
5662 qtolfact =
delt / area
5668 call this%lak_calculate_residual(n, hlak, resid)
5672 if (abs(dh) < delh .and. abs(resid) * qtolfact < this%dmaxchg)
then
5675 this%xnewpak(n) = hlak
5678 this%seep0(n) = this%seep(n)
5681 end subroutine lak_solve_single
5694 subroutine lak_estimate_seepage_single(this, n, ncnv)
5696 class(laktype),
intent(inout) :: this
5697 integer(I4B),
intent(in) :: n
5698 integer(I4B),
intent(in) :: ncnv
5702 integer(I4B) :: igwfnode
5703 integer(I4B) :: idry
5704 integer(I4B) :: idry1
5716 if (this%iboundpak(n) == 0)
return
5718 estseep:
do i = 1, 2
5720 if (this%gwfiss /= 0)
then
5721 this%xoldpak(n) = this%xnewpak(n)
5723 hlak = this%xnewpak(n)
5724 calcconnseep:
do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5725 igwfnode = this%gwfconn(j)
5726 head = this%xnew(igwfnode)
5727 if (this%ncncvr(n) /= 2)
then
5728 if (this%ibound(igwfnode) > 0)
then
5729 call this%lak_estimate_conn_exchange(i, n, j, idry, hlak, &
5733 call this%lak_estimate_conn_exchange(i, n, j, idry1, &
5734 hlak + delh, head, qlakgw1, &
5738 if (ncnv == 0 .and. i == 2)
then
5739 if (j == this%maxbound)
then
5743 this%hcof(j) = gwfhcof
5744 this%rhs(j) = gwfrhs
5746 this%hcof(j) = dzero
5747 this%rhs(j) = qlakgw
5751 this%seep(n) = this%seep(n) + qlakgw
5752 this%seep1(n) = this%seep1(n) + qlakgw1
5758 end subroutine lak_estimate_seepage_single
5764 subroutine lak_bisection(this, n, ibflg, hlak, temporary_stage, dh, residual)
5766 class(laktype),
intent(inout) :: this
5767 integer(I4B),
intent(in) :: n
5768 integer(I4B),
intent(inout) :: ibflg
5769 real(DP),
intent(in) :: hlak
5770 real(DP),
intent(inout) :: temporary_stage
5771 real(DP),
intent(inout) :: dh
5772 real(DP),
intent(inout) :: residual
5775 real(DP) :: temporary_stage0
5776 real(DP) :: residuala
5777 real(DP) :: endpoint1
5778 real(DP) :: endpoint2
5781 temporary_stage0 = hlak
5782 endpoint1 = this%en1(n)
5783 endpoint2 = this%en2(n)
5784 call this%lak_calculate_residual(n, temporary_stage, residuala)
5785 if (hlak > endpoint1 .and. hlak < endpoint2)
then
5788 do i = 1, this%maxlakit
5789 temporary_stage = dhalf * (endpoint1 + endpoint2)
5790 call this%lak_calculate_residual(n, temporary_stage, residual)
5791 if (abs(residual) == dzero .or. &
5792 abs(temporary_stage0 - temporary_stage) < this%dmaxchg)
then
5795 call this%lak_calculate_residual(n, endpoint1, residuala)
5798 if (sign(done, residuala) == sign(done, residual))
then
5799 endpoint1 = temporary_stage
5802 endpoint2 = temporary_stage
5804 temporary_stage0 = temporary_stage
5806 dh = hlak - temporary_stage
5807 end subroutine lak_bisection
5812 subroutine lak_calculate_available(this, n, hlak, avail, &
5813 ra, ro, qinf, ex, headp)
5817 class(laktype),
intent(inout) :: this
5818 integer(I4B),
intent(in) :: n
5819 real(DP),
intent(in) :: hlak
5820 real(DP),
intent(inout) :: avail
5821 real(DP),
intent(inout) :: ra
5822 real(DP),
intent(inout) :: ro
5823 real(DP),
intent(inout) :: qinf
5824 real(DP),
intent(inout) :: ex
5825 real(DP),
intent(in),
optional :: headp
5828 integer(I4B) :: idry
5829 integer(I4B) :: igwfnode
5836 if (
present(headp))
then
5846 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5847 igwfnode = this%gwfconn(j)
5848 if (this%ibound(igwfnode) == 0) cycle
5849 head = this%xnew(igwfnode) + hp
5850 call this%lak_estimate_conn_exchange(1, n, j, idry, hlak, head, qlakgw, &
5855 call this%lak_calculate_rainfall(n, hlak, ra)
5859 call this%lak_calculate_runoff(n, ro)
5863 call this%lak_calculate_inflow(n, qinf)
5864 avail = avail + qinf
5867 call this%lak_calculate_external(n, ex)
5871 call this%lak_calculate_vol(n, this%xoldpak(n), v0)
5872 avail = avail + v0 /
delt
5873 end subroutine lak_calculate_available
5877 subroutine lak_calculate_residual(this, n, hlak, resid, headp)
5881 class(laktype),
intent(inout) :: this
5882 integer(I4B),
intent(in) :: n
5883 real(DP),
intent(in) :: hlak
5884 real(DP),
intent(inout) :: resid
5885 real(DP),
intent(in),
optional :: headp
5888 integer(I4B) :: idry
5889 integer(I4B) :: igwfnode
5908 if (
present(headp))
then
5920 call this%lak_calculate_available(n, hlak, avail, &
5921 ra, ro, qinf, ex, hp)
5924 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5925 igwfnode = this%gwfconn(j)
5926 if (this%ibound(igwfnode) == 0) cycle
5927 head = this%xnew(igwfnode) + hp
5928 call this%lak_estimate_conn_exchange(2, n, j, idry, hlak, head, qlakgw, &
5930 seep = seep + qlakgw
5934 call this%lak_calculate_withdrawal(n, avail, wr)
5937 call this%lak_calculate_evaporation(n, hlak, avail, ev)
5940 call this%lak_calculate_outlet_outflow(n, hlak, avail, sout)
5943 call this%lak_calculate_outlet_inflow(n, sin)
5946 resid = ra + ev + wr + ro + qinf + ex + sin + sout + seep
5949 if (this%gwfiss /= 1)
then
5950 hlak0 = this%xoldpak(n)
5951 call this%lak_calculate_vol(n, hlak0, v0)
5952 call this%lak_calculate_vol(n, hlak, v1)
5953 resid = resid + (v0 - v1) /
delt
5955 end subroutine lak_calculate_residual
5959 subroutine lak_setup_budobj(this)
5963 class(laktype) :: this
5965 integer(I4B) :: nbudterm
5966 integer(I4B) :: nlen
5967 integer(I4B) :: j, n, n1, n2
5968 integer(I4B) :: maxlist, naux
5971 character(len=LENBUDTXT) :: text
5972 character(len=LENBUDTXT),
dimension(1) :: auxtxt
5978 do n = 1, this%noutlets
5979 if (this%lakein(n) > 0 .and. this%lakeout(n) > 0)
then
5983 if (nlen > 0) nbudterm = nbudterm + 1
5984 if (this%imover == 1) nbudterm = nbudterm + 2
5985 if (this%naux > 0) nbudterm = nbudterm + 1
5989 call this%budobj%budgetobject_df(this%nlakes, nbudterm, 0, 0, &
5990 ibudcsv=this%ibudcsv)
5996 text =
' FLOW-JA-FACE'
6000 call this%budobj%budterm(idx)%initialize(text, &
6005 maxlist, .false., .false., &
6006 naux, ordered_id1=.false.)
6009 call this%budobj%budterm(idx)%reset(2 * nlen)
6011 do n = 1, this%noutlets
6013 n2 = this%lakeout(n)
6014 if (n1 > 0 .and. n2 > 0)
then
6015 call this%budobj%budterm(idx)%update_term(n1, n2, q)
6016 call this%budobj%budterm(idx)%update_term(n2, n1, -q)
6024 maxlist = this%maxbound
6026 auxtxt(1) =
' FLOW-AREA'
6027 call this%budobj%budterm(idx)%initialize(text, &
6032 maxlist, .false., .true., &
6034 call this%budobj%budterm(idx)%reset(this%maxbound)
6036 do n = 1, this%nlakes
6037 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
6038 n2 = this%gwfconn(j)
6039 call this%budobj%budterm(idx)%update_term(n, n2, q)
6046 maxlist = this%nlakes
6048 call this%budobj%budterm(idx)%initialize(text, &
6053 maxlist, .false., .false., &
6057 text =
' EVAPORATION'
6059 maxlist = this%nlakes
6061 call this%budobj%budterm(idx)%initialize(text, &
6066 maxlist, .false., .false., &
6072 maxlist = this%nlakes
6074 call this%budobj%budterm(idx)%initialize(text, &
6079 maxlist, .false., .false., &
6083 text =
' EXT-INFLOW'
6085 maxlist = this%nlakes
6087 call this%budobj%budterm(idx)%initialize(text, &
6092 maxlist, .false., .false., &
6096 text =
' WITHDRAWAL'
6098 maxlist = this%nlakes
6100 call this%budobj%budterm(idx)%initialize(text, &
6105 maxlist, .false., .false., &
6109 text =
' EXT-OUTFLOW'
6111 maxlist = this%nlakes
6113 call this%budobj%budterm(idx)%initialize(text, &
6118 maxlist, .false., .false., &
6124 maxlist = this%nlakes
6126 auxtxt(1) =
' VOLUME'
6127 call this%budobj%budterm(idx)%initialize(text, &
6132 maxlist, .false., .false., &
6138 maxlist = this%nlakes
6140 call this%budobj%budterm(idx)%initialize(text, &
6145 maxlist, .false., .false., &
6149 if (this%imover == 1)
then
6154 maxlist = this%nlakes
6156 call this%budobj%budterm(idx)%initialize(text, &
6161 maxlist, .false., .false., &
6167 maxlist = this%noutlets
6169 call this%budobj%budterm(idx)%initialize(text, &
6174 maxlist, .false., .false., &
6175 naux, ordered_id1=.false.)
6178 call this%budobj%budterm(idx)%reset(this%noutlets)
6180 do n = 1, this%noutlets
6182 call this%budobj%budterm(idx)%update_term(n1, n1, q)
6193 maxlist = this%nlakes
6194 call this%budobj%budterm(idx)%initialize(text, &
6199 maxlist, .false., .false., &
6204 if (this%iprflow /= 0)
then
6205 call this%budobj%flowtable_df(this%iout)
6207 end subroutine lak_setup_budobj
6211 subroutine lak_fill_budobj(this)
6213 class(laktype) :: this
6215 integer(I4B) :: naux
6216 real(DP),
dimension(:),
allocatable :: auxvartmp
6225 integer(I4B) :: nlen
6228 real(DP) :: lkstg, gwhead, wa
6235 do n = 1, this%noutlets
6236 if (this%lakein(n) > 0 .and. this%lakeout(n) > 0)
then
6242 call this%budobj%budterm(idx)%reset(2 * nlen)
6243 do n = 1, this%noutlets
6245 n2 = this%lakeout(n)
6246 if (n1 > 0 .and. n2 > 0)
then
6247 q = this%simoutrate(n)
6248 if (this%imover == 1)
then
6249 q = q + this%pakmvrobj%get_qtomvr(n)
6251 call this%budobj%budterm(idx)%update_term(n1, n2, q)
6252 call this%budobj%budterm(idx)%update_term(n2, n1, -q)
6259 call this%budobj%budterm(idx)%reset(this%maxbound)
6260 do n = 1, this%nlakes
6261 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
6262 n2 = this%gwfconn(j)
6264 lkstg = this%xnewpak(n)
6268 gwhead = this%xnew(n2)
6269 call this%lak_calculate_conn_warea(n, j, lkstg, gwhead, wa)
6273 if (this%belev(j) > lkstg) wa = dzero
6274 this%qauxcbc(1) = wa
6275 call this%budobj%budterm(idx)%update_term(n, n2, q, this%qauxcbc)
6281 call this%budobj%budterm(idx)%reset(this%nlakes)
6282 do n = 1, this%nlakes
6284 call this%budobj%budterm(idx)%update_term(n, n, q)
6289 call this%budobj%budterm(idx)%reset(this%nlakes)
6290 do n = 1, this%nlakes
6292 call this%budobj%budterm(idx)%update_term(n, n, q)
6297 call this%budobj%budterm(idx)%reset(this%nlakes)
6298 do n = 1, this%nlakes
6300 call this%budobj%budterm(idx)%update_term(n, n, q)
6305 call this%budobj%budterm(idx)%reset(this%nlakes)
6306 do n = 1, this%nlakes
6308 call this%budobj%budterm(idx)%update_term(n, n, q)
6313 call this%budobj%budterm(idx)%reset(this%nlakes)
6314 do n = 1, this%nlakes
6316 call this%budobj%budterm(idx)%update_term(n, n, q)
6321 call this%budobj%budterm(idx)%reset(this%nlakes)
6322 do n = 1, this%nlakes
6323 call this%lak_get_external_outlet(n, q)
6325 call this%lak_get_external_mover(n, v)
6327 call this%budobj%budterm(idx)%update_term(n, n, q)
6332 call this%budobj%budterm(idx)%reset(this%nlakes)
6333 do n = 1, this%nlakes
6334 call this%lak_calculate_vol(n, this%xnewpak(n), v1)
6336 this%qauxcbc(1) = v1
6337 call this%budobj%budterm(idx)%update_term(n, n, q, this%qauxcbc)
6342 call this%budobj%budterm(idx)%reset(this%nlakes)
6343 do n = 1, this%nlakes
6345 call this%budobj%budterm(idx)%update_term(n, n, q)
6349 if (this%imover == 1)
then
6353 call this%budobj%budterm(idx)%reset(this%nlakes)
6354 do n = 1, this%nlakes
6355 q = this%pakmvrobj%get_qfrommvr(n)
6356 call this%budobj%budterm(idx)%update_term(n, n, q)
6361 call this%budobj%budterm(idx)%reset(this%noutlets)
6362 do n = 1, this%noutlets
6364 q = this%pakmvrobj%get_qtomvr(n)
6368 call this%budobj%budterm(idx)%update_term(n1, n1, q)
6377 allocate (auxvartmp(naux))
6378 call this%budobj%budterm(idx)%reset(this%nlakes)
6379 do n = 1, this%nlakes
6383 auxvartmp(jj) = this%featureauxvar(jj, ii)
6385 call this%budobj%budterm(idx)%update_term(n, n, q, auxvartmp)
6387 deallocate (auxvartmp)
6391 call this%budobj%accumulate_terms()
6392 end subroutine lak_fill_budobj
6399 subroutine lak_setup_tableobj(this)
6403 class(laktype) :: this
6405 integer(I4B) :: nterms
6406 character(len=LINELENGTH) :: title
6407 character(len=LINELENGTH) :: text
6410 if (this%iprhed > 0)
then
6417 if (this%inamedbound == 1)
then
6422 title = trim(adjustl(this%text))//
' PACKAGE ('// &
6423 trim(adjustl(this%packName))//
') STAGES FOR EACH CONTROL VOLUME'
6426 call table_cr(this%stagetab, this%packName, title)
6427 call this%stagetab%table_df(this%nlakes, nterms, this%iout, &
6431 if (this%inamedbound == 1)
then
6433 call this%stagetab%initialize_column(text, 20, alignment=
tableft)
6438 call this%stagetab%initialize_column(text, 10, alignment=
tabcenter)
6442 call this%stagetab%initialize_column(text, 12, alignment=
tabcenter)
6445 text =
'SURFACE AREA'
6446 call this%stagetab%initialize_column(text, 12, alignment=
tabcenter)
6449 text =
'WETTED AREA'
6450 call this%stagetab%initialize_column(text, 12, alignment=
tabcenter)
6454 call this%stagetab%initialize_column(text, 12, alignment=
tabcenter)
6456 end subroutine lak_setup_tableobj
6460 subroutine lak_activate_density(this)
6462 class(laktype),
intent(inout) :: this
6464 integer(I4B) :: i, j
6467 if (this%iimplicit /= 0)
then
6468 write (errmsg,
'(a)') &
6469 'The IMPLICIT option cannot be used with the BUY package until the &
6470 &implicit formulation includes density terms. Remove the IMPLICIT &
6471 &option from LAK package '//trim(this%packName)//
' to simulate &
6473 call store_error(errmsg)
6474 call store_error_filename(this%input_fname)
6479 call mem_reallocate(this%denseterms, 3, this%MAXBOUND,
'DENSETERMS', &
6481 do i = 1, this%maxbound
6483 this%denseterms(j, i) = dzero
6486 write (this%iout,
'(/1x,a)')
'DENSITY TERMS HAVE BEEN ACTIVATED FOR LAKE &
6487 &PACKAGE: '//trim(adjustl(this%packName))
6488 end subroutine lak_activate_density
6494 subroutine lak_activate_viscosity(this)
6498 class(laktype),
intent(inout) :: this
6505 call mem_reallocate(this%viscratios, 2, this%MAXBOUND,
'VISCRATIOS', &
6507 do i = 1, this%maxbound
6509 this%viscratios(j, i) = done
6512 write (this%iout,
'(/1x,a)')
'VISCOSITY HAS BEEN ACTIVATED FOR LAK &
6513 &PACKAGE: '//trim(adjustl(this%packName))
6514 end subroutine lak_activate_viscosity
6534 subroutine lak_calculate_density_exchange(this, iconn, stage, head, cond, &
6535 botl, flow, gwfhcof, gwfrhs)
6537 class(laktype),
intent(inout) :: this
6538 integer(I4B),
intent(in) :: iconn
6539 real(DP),
intent(in) :: stage
6540 real(DP),
intent(in) :: head
6541 real(DP),
intent(in) :: cond
6542 real(DP),
intent(in) :: botl
6543 real(DP),
intent(inout) :: flow
6544 real(DP),
intent(inout) :: gwfhcof
6545 real(DP),
intent(inout) :: gwfrhs
6550 real(DP) :: rdenselak
6551 real(DP) :: rdensegwf
6552 real(DP) :: rdenseavg
6558 logical(LGP) :: stage_below_bot
6559 logical(LGP) :: head_below_bot
6562 if (stage >= botl)
then
6564 stage_below_bot = .false.
6565 rdenselak = this%denseterms(1, iconn)
6568 stage_below_bot = .true.
6569 rdenselak = this%denseterms(2, iconn)
6573 if (head >= botl)
then
6575 head_below_bot = .false.
6576 rdensegwf = this%denseterms(2, iconn)
6579 head_below_bot = .true.
6580 rdensegwf = this%denseterms(1, iconn)
6584 if (rdensegwf == dzero)
return
6587 if (stage_below_bot .and. head_below_bot)
then
6594 rdenseavg = dhalf * (rdenselak + rdensegwf)
6598 d1 = cond * (rdenseavg - done)
6599 gwfhcof = gwfhcof - d1
6600 gwfrhs = gwfrhs - d1 * ss
6605 if (.not. stage_below_bot .and. .not. head_below_bot)
then
6609 elevgwf = this%denseterms(3, iconn)
6610 if (this%ictype(iconn) == 0 .or. this%ictype(iconn) == 3)
then
6617 elevavg = dhalf * (elevlak + elevgwf)
6618 havg = dhalf * (hh + ss)
6619 d2 = cond * (havg - elevavg) * (rdensegwf - rdenselak)
6620 gwfrhs = gwfrhs + d2
6624 end subroutine lak_calculate_density_exchange
This module contains the extended boundary package.
subroutine source_dimensions(this)
@ brief Source package dimensions from input context
subroutine source_options(this)
@ brief Source package options from input context
This module contains the base boundary package.
logical(lgp) function bnd_obs_supported(this)
Determine if observations are supported.
subroutine bnd_ar(this)
@ brief Allocate and read method for boundary package
subroutine bnd_rp(this)
@ brief Allocate and read method for package
subroutine bnd_ot_dv(this, idvsave, idvprint)
@ brief Output advanced package dependent-variable terms.
subroutine bnd_nur(this, neqpak, x, xtemp, dx, inewtonur, dxmax, locmax)
@ brief Apply Newton-Raphson under-relaxation for package.
subroutine bnd_ot_package_flows(this, icbcfl, ibudfl)
@ brief Output advanced package flow terms.
subroutine bnd_ot_model_flows(this, icbcfl, ibudfl, icbcun, imap)
@ brief Output package flow terms.
subroutine bnd_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
@ brief Convergence check for package.
subroutine bnd_bd_obs(this)
Save observations for the package.
subroutine bnd_da(this)
@ brief Deallocate package memory
subroutine bnd_mc(this, moffset, matrix_sln)
@ brief Map boundary package connection to matrix
subroutine bnd_fc(this, rhs, ia, idxglo, matrix_sln)
@ brief Copy hcof and rhs terms into solution.
subroutine bnd_ac(this, moffset, sparse)
@ brief Add boundary package connection to matrix
subroutine bnd_ot_bdsummary(this, kstp, kper, iout, ibudfl)
@ brief Output advanced package budget summary.
subroutine bnd_df_obs(this)
Define the observation types available in the package.
subroutine set_pointers(this, neq, ibound, xnew, xold, flowja)
@ brief Set pointers to model variables
subroutine bnd_rp_obs(this)
Read and prepare observations for a package.
subroutine bnd_cf(this)
@ brief Formulate the package hcof and rhs terms.
subroutine bnd_fn(this, rhs, ia, idxglo, matrix_sln)
@ brief Add Newton-Raphson terms for package into solution.
subroutine bnd_ad(this)
@ brief Advance the boundary package
subroutine bnd_cq(this, x, flowja, iadv)
@ brief Calculate advanced package flows.
subroutine define_listlabel(this)
@ brief Define the list label for the 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_checkin_deprecated_names(this)
Alias deprecated LAK variable names to their current storage.
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.
Previous variable names checked in as deprecated aliases.
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.
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
integer(i4b) iout
file unit number for simulation output
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 finalize(this)
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 ...