14 module procedure lak_budget_nogwf
18 real(DP) :: ra, ro, qin, ex, surfin, sa, v0, v1, qout, sf
20 call this%lak_calculate_rainfall(n, stage, ra)
21 call this%lak_calculate_runoff(n, ro)
22 call this%lak_calculate_inflow(n, qin)
23 call this%lak_calculate_external(n, ex)
24 call this%lak_calculate_outlet_inflow(n, surfin)
25 call this%lak_outlet_outflow_rate(n, stage, qout)
26 call this%lak_calculate_sarea(n, stage, sa)
35 if (this%surfdep > dzero)
then
36 sf = squadraticsaturation(this%lakebot(n) + this%surfdep, &
37 this%lakebot(n), stage)
43 b = ra + ro + qin + ex + surfin &
44 + (qout - this%evaporation(n) * sa - this%withdrawal(n)) * sf
47 if (this%gwfiss /= 1)
then
48 call this%lak_calculate_vol(n, this%xoldpak(n), v0)
49 call this%lak_calculate_vol(n, stage, v1)
50 b = b + (v0 - v1) /
delt
52 end procedure lak_budget_nogwf
83 module procedure lak_fc_implicit
85 integer(I4B) :: n, j, ipos, iloc, igwfnode
86 logical(LGP) :: llegacy
87 real(DP) :: hlak, head, flow, gwfhcof, gwfrhs
88 real(DP) :: b0, b1, dbds, avail, sout, csum, deps, adiag
89 real(DP) :: dqds, dqdh
95 if (this%noutlets > 0)
then
97 if (this%iboundpak(n) < 1) cycle
99 call this%lak_calculate_outlet_outflow(n, this%xnewpak(n), avail, sout)
105 if (this%iforceleg /= 0)
then
106 do n = 1, this%nlakes
107 if (this%iboundpak(n) > 0) this%ilegacy(n) = 1
110 n = this%iforceleglak
112 if (this%iboundpak(n) > 0) this%ilegacy(n) = 1
121 do n = 1, this%nlakes
122 if (this%ilegacy(n) /= 0)
then
128 call this%lak_solve(only_legacy=.true.)
134 if (this%noutlets > 0 .and. this%imover == 1)
then
135 do n = 1, this%noutlets
136 call this%pakmvrobj%accumulate_qformvr(n, -this%simoutrate(n))
141 do n = 1, this%nlakes
142 iloc = this%idxlocnode(n)
143 hlak = this%xnewpak(n)
144 if (this%ilegacy(n) /= 0 .and. this%iboundpak(n) > 0)
then
150 call matrix_sln%add_value_pos(this%idxdiag(n), done)
152 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
154 igwfnode = this%gwfconn(j)
155 if (this%ibound(igwfnode) < 1) cycle
156 call matrix_sln%add_value_pos(this%idxsymdglo(ipos), this%hcof(j))
157 rhs(igwfnode) = rhs(igwfnode) + this%rhs(j)
159 else if (this%iboundpak(n) > 0)
then
164 call this%lak_budget_nogwf(n, hlak, b0)
165 call this%lak_budget_nogwf(n, hlak + this%delh, b1)
166 dbds = (b1 - b0) / this%delh
167 call matrix_sln%add_value_pos(this%idxdiag(n), dbds)
168 rhs(iloc) = rhs(iloc) + dbds * hlak - b0
171 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
173 igwfnode = this%gwfconn(j)
174 if (this%ibound(igwfnode) < 1) cycle
175 head = this%xnew(igwfnode)
184 call this%lak_calculate_conn_exchange_deriv(n, j, hlak, head, flow, &
186 call matrix_sln%add_value_pos(this%idxdiag(n), dqds)
187 call matrix_sln%add_value_pos(this%idxoffdglo(ipos), dqdh)
188 call matrix_sln%add_value_pos(this%idxsymdglo(ipos), -dqdh)
189 call matrix_sln%add_value_pos(this%idxsymoffdglo(ipos), -dqds)
190 rhs(iloc) = rhs(iloc) + dqds * hlak + dqdh * head - flow
191 rhs(igwfnode) = rhs(igwfnode) - dqdh * head - dqds * hlak + flow
200 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
201 csum = csum + this%satcond(j)
203 deps = dem9 * csum + dprec
204 if (abs(adiag) < deps)
then
205 call matrix_sln%add_value_pos(this%idxdiag(n), -deps)
206 rhs(iloc) = rhs(iloc) - deps * hlak
208 else if (this%iboundpak(n) < 0)
then
213 call matrix_sln%add_value_pos(this%idxdiag(n), done)
215 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
217 igwfnode = this%gwfconn(j)
218 if (this%ibound(igwfnode) < 1) cycle
219 head = this%xnew(igwfnode)
220 call this%lak_calculate_conn_exchange(n, j, hlak, head, flow, &
222 call matrix_sln%add_value_pos(this%idxsymdglo(ipos), gwfhcof)
223 rhs(igwfnode) = rhs(igwfnode) + gwfrhs
234 call matrix_sln%add_value_pos(this%idxdiag(n), done)
236 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
241 end procedure lak_fc_implicit
260 module procedure lak_set_legacy
262 integer(I4B) :: n, j, igwfnode
263 real(DP) :: dstage, dhead
272 real(DP),
parameter :: headratio = dten
273 integer(I4B),
parameter :: nstuckmax = 5
275 if (this%iimplicit == 0)
return
282 do n = 1, this%nlakes
285 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
286 igwfnode = this%gwfconn(j)
287 if (this%ibound(igwfnode) >= 1)
then
288 this%holdconn(j) = this%xnew(igwfnode)
296 if (icnvgmod /= 0)
return
297 do n = 1, this%nlakes
298 if (this%iboundpak(n) < 1) cycle
302 dstage = abs(this%xnewpak(n) - this%s0(n))
304 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
305 igwfnode = this%gwfconn(j)
306 if (this%ibound(igwfnode) >= 1)
then
307 dhead = max(dhead, abs(this%xnew(igwfnode) - this%holdconn(j)))
308 this%holdconn(j) = this%xnew(igwfnode)
311 if (this%ilegacy(n) /= 0) cycle
315 if (dstage > this%dmaxchg .and. dstage > headratio * dhead)
then
316 this%nstuck(n) = this%nstuck(n) + 1
320 if (this%nstuck(n) > nstuckmax)
then
324 end procedure lak_set_legacy
337 module procedure lak_check_disconnected
339 character(len=LINELENGTH) :: warnmsg
341 logical(LGP) :: haslegacy
344 if (this%iimplicit == 0)
return
349 do n = 1, this%nlakes
350 if (this%ilegacy(n) /= 0)
then
355 if (.not. haslegacy)
return
358 write (warnmsg,
'(a)') &
359 "IMPLICIT lake option in package '"//trim(this%packName)//
"' did not "// &
360 "converge even after switching a stalled lake to the substitution "// &
361 "solver. The default solver needs fewer outer iterations for such a "// &
362 "lake; consider omitting IMPLICIT, adding an outlet, increasing the "// &
363 "leakance, or running transient."
364 call store_warning(warnmsg, substring=warnmsg(:40))
365 end procedure lak_check_disconnected
367 end submodule lakmoduleimplicit
real(dp), pointer, public delt
length of the current time step