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) :: lfallback
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)
104 if (this%imover == 1)
then
105 do n = 1, this%noutlets
106 call this%pakmvrobj%accumulate_qformvr(n, -this%simoutrate(n))
113 if (this%iforcefb /= 0)
then
114 do n = 1, this%nlakes
115 if (this%iboundpak(n) > 0) this%ifallback(n) = 1
125 do n = 1, this%nlakes
126 if (this%ifallback(n) /= 0)
then
132 call this%lak_solve(only_fallback=.true.)
136 do n = 1, this%nlakes
137 iloc = this%idxlocnode(n)
138 hlak = this%xnewpak(n)
139 if (this%ifallback(n) /= 0 .and. this%iboundpak(n) > 0)
then
145 call matrix_sln%add_value_pos(this%idxdiag(n), done)
147 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
149 igwfnode = this%cellid(j)
150 if (this%ibound(igwfnode) < 1) cycle
151 call matrix_sln%add_value_pos(this%idxsymdglo(ipos), this%hcof(j))
152 rhs(igwfnode) = rhs(igwfnode) + this%rhs(j)
154 else if (this%iboundpak(n) > 0)
then
159 call this%lak_budget_nogwf(n, hlak, b0)
160 call this%lak_budget_nogwf(n, hlak + this%delh, b1)
161 dbds = (b1 - b0) / this%delh
162 call matrix_sln%add_value_pos(this%idxdiag(n), dbds)
163 rhs(iloc) = rhs(iloc) + dbds * hlak - b0
166 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
168 igwfnode = this%cellid(j)
169 if (this%ibound(igwfnode) < 1) cycle
170 head = this%xnew(igwfnode)
179 call this%lak_calculate_conn_exchange_deriv(n, j, hlak, head, flow, &
181 call matrix_sln%add_value_pos(this%idxdiag(n), dqds)
182 call matrix_sln%add_value_pos(this%idxoffdglo(ipos), dqdh)
183 call matrix_sln%add_value_pos(this%idxsymdglo(ipos), -dqdh)
184 call matrix_sln%add_value_pos(this%idxsymoffdglo(ipos), -dqds)
185 rhs(iloc) = rhs(iloc) + dqds * hlak + dqdh * head - flow
186 rhs(igwfnode) = rhs(igwfnode) - dqdh * head - dqds * hlak + flow
195 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
196 csum = csum + this%satcond(j)
198 deps = dem9 * csum + dprec
199 if (abs(adiag) < deps)
then
200 call matrix_sln%add_value_pos(this%idxdiag(n), -deps)
201 rhs(iloc) = rhs(iloc) - deps * hlak
203 else if (this%iboundpak(n) < 0)
then
208 call matrix_sln%add_value_pos(this%idxdiag(n), done)
210 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
212 igwfnode = this%cellid(j)
213 if (this%ibound(igwfnode) < 1) cycle
214 head = this%xnew(igwfnode)
215 call this%lak_calculate_conn_exchange(n, j, hlak, head, flow, &
217 call matrix_sln%add_value_pos(this%idxsymdglo(ipos), gwfhcof)
218 rhs(igwfnode) = rhs(igwfnode) + gwfrhs
229 call matrix_sln%add_value_pos(this%idxdiag(n), done)
231 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
236 end procedure lak_fc_implicit
255 module procedure lak_set_fallback
257 integer(I4B) :: n, j, igwfnode
258 real(DP) :: dstage, dhead
267 real(DP),
parameter :: headratio = dten
268 integer(I4B),
parameter :: nstuckmax = 5
270 if (this%iimplicit == 0)
return
277 do n = 1, this%nlakes
278 this%ifallback(n) = 0
280 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
281 igwfnode = this%cellid(j)
282 if (this%ibound(igwfnode) >= 1)
then
283 this%holdconn(j) = this%xnew(igwfnode)
291 if (icnvgmod /= 0)
return
292 do n = 1, this%nlakes
293 if (this%iboundpak(n) < 1) cycle
297 dstage = abs(this%xnewpak(n) - this%s0(n))
299 do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
300 igwfnode = this%cellid(j)
301 if (this%ibound(igwfnode) >= 1)
then
302 dhead = max(dhead, abs(this%xnew(igwfnode) - this%holdconn(j)))
303 this%holdconn(j) = this%xnew(igwfnode)
306 if (this%ifallback(n) /= 0) cycle
310 if (dstage > this%dmaxchg .and. dstage > headratio * dhead)
then
311 this%nstuck(n) = this%nstuck(n) + 1
315 if (this%nstuck(n) > nstuckmax)
then
316 this%ifallback(n) = 1
319 end procedure lak_set_fallback
332 module procedure lak_check_disconnected
334 character(len=LINELENGTH) :: warnmsg
336 logical(LGP) :: hasfallback
339 if (this%iimplicit == 0)
return
343 hasfallback = .false.
344 do n = 1, this%nlakes
345 if (this%ifallback(n) /= 0)
then
350 if (.not. hasfallback)
return
353 write (warnmsg,
'(a)') &
354 "IMPLICIT lake option in package '"//trim(this%packName)//
"' did not "// &
355 "converge even after switching a stalled lake to the substitution "// &
356 "solver. The default solver needs fewer outer iterations for such a "// &
357 "lake; consider omitting IMPLICIT, adding an outlet, increasing the "// &
358 "leakance, or running transient."
359 call store_warning(warnmsg, substring=warnmsg(:40))
360 end procedure lak_check_disconnected
362 end submodule lakmoduleimplicit
real(dp), pointer, public delt
length of the current time step