MODFLOW 6 version 6.9.0.dev0
USGS Modular Hydrologic Model
Loading...
Searching...
No Matches
swf-zdg.f90
Go to the documentation of this file.
1!> @brief This module contains the ZDG package methods
2!!
3!! This module can be used to represent outflow from streams using
4!! a zero-depth-gradient boundary.
5!!
6!<
8 ! -- modules
9 use kindmodule, only: dp, i4b
11 use simvariablesmodule, only: errmsg
14 use bndmodule, only: bndtype
15 use bndextmodule, only: bndexttype
17 use observemodule, only: observetype
21 use basedismodule, only: disbasetype
22 use disv1dmodule, only: disv1dtype
23 use swfcxsmodule, only: swfcxstype
24 !
25 implicit none
26 !
27 private
28 public :: zdg_create
29 !
30 character(len=LENFTYPE) :: ftype = 'ZDG' !< package ftype
31 character(len=16) :: text = ' ZDG' !< package flow text string
32 !
33 type, extends(bndexttype) :: swfzdgtype
34
35 integer(I4B), dimension(:), pointer, contiguous :: idcxs => null() !< cross section id
36 real(dp), dimension(:), pointer, contiguous :: width => null() !< channel width
37 real(dp), dimension(:), pointer, contiguous :: slope => null() !< channel slope
38 real(dp), dimension(:), pointer, contiguous :: rough => null() !< channel roughness
39 real(dp), pointer :: unitconv => null() !< conversion factor for roughness to length and time units of meters and seconds
40
41 ! -- pointers other objects
42 type(disv1dtype), pointer :: disv1d
43 type(swfcxstype), pointer :: cxs
44
45 contains
49 procedure :: log_zdg_options
50 procedure :: bnd_cf => zdg_cf
51 procedure :: bnd_fc => zdg_fc
52 procedure :: bnd_da => zdg_da
53 procedure :: define_listlabel
55 ! -- methods for observations
56 procedure, public :: bnd_obs_supported => zdg_obs_supported
57 procedure, public :: bnd_df_obs => zdg_df_obs
58 procedure, public :: bnd_bd_obs => zdg_bd_obs
59 ! -- methods for time series
60 procedure, public :: bnd_rp_ts => zdg_rp_ts
61 ! -- private
62 procedure, private :: qcalc
63 end type swfzdgtype
64
65contains
66
67 !> @ brief Create a new package object
68 !!
69 !! Create a new ZDG Package object
70 !!
71 !<
72 subroutine zdg_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
73 mempath, dis, cxs, unitconv)
74 ! -- dummy variables
75 class(bndtype), pointer :: packobj !< pointer to default package type
76 integer(I4B), intent(in) :: id !< package id
77 integer(I4B), intent(in) :: ibcnum !< boundary condition number
78 integer(I4B), intent(in) :: inunit !< unit number of ZDG package input file
79 integer(I4B), intent(in) :: iout !< unit number of model listing file
80 character(len=*), intent(in) :: namemodel !< model name
81 character(len=*), intent(in) :: pakname !< package name
82 character(len=*), intent(in) :: mempath !< input mempath
83 class(disbasetype), pointer, intent(inout) :: dis !< the pointer to the discretization
84 type(swfcxstype), pointer, intent(in) :: cxs !< the pointer to the cxs package
85 real(dp), intent(in) :: unitconv !< unit conversion for roughness
86 ! -- local variables
87 type(swfzdgtype), pointer :: zdgobj
88 !
89 ! -- allocate the object and assign values to object variables
90 allocate (zdgobj)
91 packobj => zdgobj
92 !
93 ! -- create name and memory path
94 call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
95 packobj%text = text
96 !
97 ! -- allocate scalars
98 call zdgobj%allocate_scalars()
99 !
100 ! -- initialize package
101 call packobj%pack_initialize()
102
103 packobj%inunit = inunit
104 packobj%iout = iout
105 packobj%id = id
106 packobj%ibcnum = ibcnum
107 packobj%ncolbnd = 1
108 packobj%iscloc = 1
109 packobj%ictMemPath = create_mem_path(namemodel, 'DFW')
110 !
111 ! -- store pointer to disv1d
112 select type (dis)
113 type is (disv1dtype)
114 zdgobj%disv1d => dis
115 end select
116 !
117 ! -- store pointer to cxs
118 zdgobj%cxs => cxs
119 !
120 ! -- store unit conversion
121 zdgobj%unitconv = unitconv
122 end subroutine zdg_create
123
124 !> @ brief Allocate scalars
125 !!
126 !! Allocate and initialize scalars for the ZDG package. The base model
127 !! allocate scalars method is also called.
128 !!
129 !<
130 subroutine zdg_allocate_scalars(this)
131 ! -- modules
133 ! -- dummy variables
134 class(swfzdgtype) :: this !< SwfZdgType object
135 !
136 ! -- call base type allocate scalars
137 call this%BndExtType%allocate_scalars()
138 !
139 ! -- allocate the object and assign values to object variables
140 call mem_allocate(this%unitconv, 'UNITCONV', this%memoryPath)
141 !
142 ! -- Set values
143 this%unitconv = dzero
144 end subroutine zdg_allocate_scalars
145
146 !> @ brief Allocate arrays
147 !!
148 !! Allocate and initialize arrays for the SWF package
149 !!
150 !<
151 subroutine zdg_allocate_arrays(this, nodelist, auxvar)
152 ! -- modules
154 ! -- dummy
155 class(swfzdgtype) :: this
156 integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist
157 real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar
158 ! -- local
159 !
160 ! -- call BndExtType allocate scalars
161 call this%BndExtType%allocate_arrays(nodelist, auxvar)
162 !
163 ! -- set array input context pointer
164 call mem_setptr(this%idcxs, 'IDCXS', this%input_mempath)
165 call mem_setptr(this%width, 'WIDTH', this%input_mempath)
166 call mem_setptr(this%slope, 'SLOPE', this%input_mempath)
167 call mem_setptr(this%rough, 'ROUGH', this%input_mempath)
168 !
169 ! -- checkin array input context pointer
170 call mem_checkin(this%idcxs, 'IDCXS', this%memoryPath, &
171 'IDCXS', this%input_mempath)
172 call mem_checkin(this%width, 'WIDTH', this%memoryPath, &
173 'WIDTH', this%input_mempath)
174 call mem_checkin(this%slope, 'SLOPE', this%memoryPath, &
175 'SLOPE', this%input_mempath)
176 call mem_checkin(this%rough, 'ROUGH', this%memoryPath, &
177 'ROUGH', this%input_mempath)
178 end subroutine zdg_allocate_arrays
179
180 !> @ brief Deallocate package memory
181 !!
182 !! Deallocate SWF package scalars and arrays.
183 !!
184 !<
185 subroutine zdg_da(this)
186 ! -- modules
188 ! -- dummy variables
189 class(swfzdgtype) :: this !< SwfZdgType object
190 !
191 ! -- Deallocate parent package
192 call this%BndExtType%bnd_da()
193 !
194 ! -- arrays
195 call mem_deallocate(this%idcxs, 'IDCXS', this%memoryPath)
196 call mem_deallocate(this%width, 'WIDTH', this%memoryPath)
197 call mem_deallocate(this%slope, 'SLOPE', this%memoryPath)
198 call mem_deallocate(this%rough, 'ROUGH', this%memoryPath)
199 !
200 ! -- scalars
201 call mem_deallocate(this%unitconv)
202 end subroutine zdg_da
203
204 !> @ brief Source additional options for package
205 !!
206 !! Source additional options for SWF package.
207 !!
208 !<
209 subroutine zdg_options(this)
210 ! -- modules
211 use inputoutputmodule, only: urword
213 ! -- dummy variables
214 class(swfzdgtype), intent(inout) :: this !< SwfZdgType object
215 ! -- formats
216 !
217 ! -- source base BndExtType options
218 call this%BndExtType%source_options()
219 !
220 ! -- source options from input context
221 ! none
222 !
223 ! -- log SWF specific options
224 call this%log_zdg_options()
225 end subroutine zdg_options
226
227 !> @ brief Log SWF specific package options
228 !<
229 subroutine log_zdg_options(this)
230 ! -- dummy variables
231 class(swfzdgtype), intent(inout) :: this
232 ! -- local variables
233 ! -- format
234 !
235 ! -- log found options
236 write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text)) &
237 //' OPTIONS'
238 !
239 ! -- close logging block
240 write (this%iout, '(1x,a)') &
241 'END OF '//trim(adjustl(this%text))//' OPTIONS'
242 end subroutine log_zdg_options
243
244 !> @ brief Formulate the package hcof and rhs terms.
245 !!
246 !! Formulate the hcof and rhs terms for the ZDG package that will be
247 !! added to the coefficient matrix and right-hand side vector.
248 !!
249 !<
250 subroutine zdg_cf(this)
251 ! modules
253 use smoothingmodule, only: squadratic
254 ! dummy variables
255 class(swfzdgtype) :: this !< SwfZdgType object
256 ! local variables
257 integer(I4B) :: i, node
258 real(DP) :: q
259 real(DP) :: qeps
260 real(DP) :: absdhdxsq
261 real(DP) :: depth
262 real(DP) :: derv
263 real(DP) :: eps
264 real(DP) :: range = 1.d-6
265 real(DP) :: dydx
266 real(DP) :: smooth_factor
267 !
268 ! -- Return if no inflows
269 if (this%nbound == 0) return
270 !
271 ! -- Calculate hcof and rhs for each zdg entry
272 do i = 1, this%nbound
273
274 node = this%nodelist(i)
275 if (this%ibound(node) <= 0) then
276 this%hcof(i) = dzero
277 this%rhs(i) = dzero
278 cycle
279 end if
280
281 ! -- calculate terms and add to hcof and rhs
282 absdhdxsq = this%slope(i)**dhalf
283 depth = this%xnew(node) - this%dis%bot(node)
284
285 ! smooth the depth
286 call squadratic(depth, range, dydx, smooth_factor)
287 depth = depth * smooth_factor
288
289 ! -- calculate unperturbed q
290 q = -this%qcalc(i, depth, this%unitconv)
291
292 ! -- calculate perturbed q
293 eps = get_perturbation(depth)
294 qeps = -this%qcalc(i, depth + eps, this%unitconv)
295
296 ! -- calculate derivative
297 derv = (qeps - q) / eps
298
299 ! -- add terms to hcof and rhs
300 this%hcof(i) = derv
301 this%rhs(i) = -q + derv * this%xnew(node)
302
303 end do
304 end subroutine zdg_cf
305
306 ! !> @brief Calculate flow
307 !!
308 !! Calculate volumetric flow rate for the zero-depth gradient
309 !! condition. Flow is positive.
310 ! !<
311 function qcalc(this, i, depth, unitconv) result(q)
312 ! dummy
313 class(swfzdgtype) :: this
314 integer(I4B), intent(in) :: i !< boundary number
315 real(dp), intent(in) :: depth !< simulated depth (stage - elevation) in reach n for this iteration
316 real(dp), intent(in) :: unitconv !< conversion factor for roughness to length and time units of meters and seconds
317 ! return
318 real(dp) :: q
319 ! local
320 integer(I4B) :: idcxs
321 real(dp) :: width
322 real(dp) :: rough
323 real(dp) :: slope
324 real(dp) :: conveyance
325
326 idcxs = this%idcxs(i)
327 width = this%width(i)
328 rough = this%rough(i)
329 slope = this%slope(i)
330 conveyance = this%cxs%get_conveyance(idcxs, width, depth, rough)
331 q = conveyance * slope**dhalf * unitconv
332
333 end function qcalc
334
335 !> @ brief Copy hcof and rhs terms into solution.
336 !!
337 !! Add the hcof and rhs terms for the ZDG package to the
338 !! coefficient matrix and right-hand side vector.
339 !!
340 !<
341 subroutine zdg_fc(this, rhs, ia, idxglo, matrix_sln)
342 ! -- dummy variables
343 class(swfzdgtype) :: this !< SwfZdgType object
344 real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
345 integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
346 integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
347 class(matrixbasetype), pointer :: matrix_sln !< solution coefficient matrix
348 ! -- local variables
349 integer(I4B) :: i
350 integer(I4B) :: n
351 integer(I4B) :: ipos
352 !
353 ! -- pakmvrobj fc
354 if (this%imover == 1) then
355 call this%pakmvrobj%fc()
356 end if
357 !
358 ! -- Copy package rhs and hcof into solution rhs and amat
359 do i = 1, this%nbound
360 n = this%nodelist(i)
361 rhs(n) = rhs(n) + this%rhs(i)
362 ipos = ia(n)
363 call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
364 !
365 ! -- If mover is active and this zdg item is discharging,
366 ! store available water (as positive value).
367 if (this%imover == 1 .and. this%rhs(i) > dzero) then
368 call this%pakmvrobj%accumulate_qformvr(i, this%rhs(i))
369 end if
370 end do
371 end subroutine zdg_fc
372
373 !> @ brief Define the list label for the package
374 !!
375 !! Method defined the list label for the ZDG package. The list label is
376 !! the heading that is written to iout when PRINT_INPUT option is used.
377 !!
378 !<
379 subroutine define_listlabel(this)
380 ! -- dummy variables
381 class(swfzdgtype), intent(inout) :: this !< SwfZdgType object
382 !
383 ! -- create the header list label
384 this%listlabel = trim(this%filtyp)//' NO.'
385 if (this%dis%ndim == 3) then
386 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
387 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
388 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
389 elseif (this%dis%ndim == 2) then
390 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
391 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
392 else
393 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
394 end if
395 write (this%listlabel, '(a, a16)') trim(this%listlabel), 'FLOW RATE'
396 if (this%inamedbound == 1) then
397 write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
398 end if
399 end subroutine define_listlabel
400
401 ! -- Procedures related to observations
402
403 !> @brief Determine if observations are supported.
404 !!
405 !! Function to determine if observations are supported by the ZDG package.
406 !! Observations are supported by the ZDG package.
407 !!
408 !! @return zdg_obs_supported boolean indicating if observations are supported
409 !!
410 !<
411 logical function zdg_obs_supported(this)
412 ! -- dummy variables
413 class(swfzdgtype) :: this !< SwfZdgType object
414 !
415 ! -- set boolean
416 zdg_obs_supported = .true.
417 end function zdg_obs_supported
418
419 !> @brief Define the observation types available in the package
420 !!
421 !! Method to define the observation types available in the ZDG package.
422 !!
423 !<
424 subroutine zdg_df_obs(this)
425 ! -- dummy variables
426 class(swfzdgtype) :: this !< SwfZdgType object
427 ! -- local variables
428 integer(I4B) :: indx
429 !
430 ! -- initialize observations
431 call this%obs%StoreObsType('zdg', .true., indx)
432 this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
433 !
434 ! -- Store obs type and assign procedure pointer
435 ! for to-mvr observation type.
436 call this%obs%StoreObsType('to-mvr', .true., indx)
437 this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
438 end subroutine zdg_df_obs
439
440 !> @brief Save observations for the package
441 !!
442 !! Method to save simulated values for the ZDG package.
443 !!
444 !<
445 subroutine zdg_bd_obs(this)
446 ! -- dummy variables
447 class(swfzdgtype) :: this !< SwfZdgType object
448 ! -- local variables
449 integer(I4B) :: i
450 integer(I4B) :: n
451 integer(I4B) :: jj
452 real(DP) :: v
453 type(observetype), pointer :: obsrv => null()
454 !
455 ! -- clear the observations
456 call this%obs%obs_bd_clear()
457 !
458 ! -- Save simulated values for all of package's observations.
459 do i = 1, this%obs%npakobs
460 obsrv => this%obs%pakobs(i)%obsrv
461 if (obsrv%BndFound) then
462 do n = 1, obsrv%indxbnds_count
463 v = dnodata
464 jj = obsrv%indxbnds(n)
465 select case (obsrv%ObsTypeId)
466 case ('TO-MVR')
467 if (this%imover == 1) then
468 v = this%pakmvrobj%get_qtomvr(jj)
469 if (v > dzero) then
470 v = -v
471 end if
472 end if
473 case ('ZDG')
474 v = this%simvals(jj)
475 case default
476 errmsg = 'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
477 call store_error(errmsg)
478 end select
479 call this%obs%SaveOneSimval(obsrv, v)
480 end do
481 else
482 call this%obs%SaveOneSimval(obsrv, dnodata)
483 end if
484 end do
485 end subroutine zdg_bd_obs
486
487 ! -- Procedure related to time series
488
489 !> @brief Assign time series links for the package
490 !!
491 !! Assign the time series links for the ZDG package. Only
492 !! the Q variable can be defined with time series.
493 !!
494 !<
495 subroutine zdg_rp_ts(this)
496 ! -- dummy variables
497 class(swfzdgtype), intent(inout) :: this !< SwfZdgType object
498 ! -- local variables
499 integer(I4B) :: i, nlinks
500 type(timeserieslinktype), pointer :: tslink => null()
501 !
502 ! -- set up the time series links
503 nlinks = this%TsManager%boundtslinks%Count()
504 do i = 1, nlinks
505 tslink => gettimeserieslinkfromlist(this%TsManager%boundtslinks, i)
506 if (associated(tslink)) then
507 if (tslink%JCol == 1) then
508 tslink%Text = 'Q'
509 end if
510 end if
511 end do
512 end subroutine zdg_rp_ts
513
514 !> @ brief Return a bound value
515 !!
516 !! Return a bound value associated with an ncolbnd index
517 !! and row.
518 !!
519 !<
520 function zdg_bound_value(this, col, row) result(bndval)
521 ! -- modules
522 use constantsmodule, only: dzero
523 ! -- dummy variables
524 class(swfzdgtype), intent(inout) :: this
525 integer(I4B), intent(in) :: col
526 integer(I4B), intent(in) :: row
527 ! -- result
528 real(dp) :: bndval
529 !
530 select case (col)
531 case (1)
532 bndval = this%idcxs(row)
533 case (2)
534 bndval = this%width(row)
535 case (3)
536 bndval = this%slope(row)
537 case (4)
538 bndval = this%rough(row)
539 case default
540 errmsg = 'Programming error. ZDG bound value requested column '&
541 &'outside range of ncolbnd (1).'
542 call store_error(errmsg)
543 call store_error_filename(this%input_fname)
544 end select
545 end function zdg_bound_value
546
547end module swfzdgmodule
This module contains the extended boundary package.
real(dp) function bound_value(this, col, row)
@ brief Return a bound value
This module contains the base boundary package.
logical(lgp) function bnd_obs_supported(this)
Determine if observations are supported.
subroutine bnd_rp_ts(this)
Assign time series links for the package.
subroutine bnd_bd_obs(this)
Save observations for the package.
subroutine bnd_da(this)
@ brief Deallocate package memory
subroutine bnd_fc(this, rhs, ia, idxglo, matrix_sln)
@ brief Copy hcof and rhs terms into solution.
subroutine bnd_df_obs(this)
Define the observation types available in the package.
subroutine bnd_cf(this)
@ brief Formulate the package hcof and rhs terms.
subroutine define_listlabel(this)
@ brief Define the list label for the package
This module contains simulation constants.
Definition Constants.f90:9
real(dp), parameter dnodata
real no data constant
Definition Constants.f90:95
@ dis
DIS6 discretization.
@ disv1d
DISV1D6 discretization.
real(dp), parameter dhalf
real constant 1/2
Definition Constants.f90:68
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
Definition Constants.f90:39
real(dp), parameter dzero
real constant zero
Definition Constants.f90:65
subroutine allocate_scalars(this, name_model, input_mempath)
Allocate scalar variables.
Definition Disv1d.f90:232
subroutine allocate_arrays(this)
Definition Disv1d.f90:796
subroutine source_options(this)
Copy options from IDM into package.
Definition Disv1d.f90:272
subroutine, public urword(line, icol, istart, istop, ncode, n, r, iout, in)
Extract a word from a string.
This module defines variable data types.
Definition kind.f90:8
real(dp) function, public get_perturbation(x)
Calculate a numerical perturbation given the value of x.
Definition MathUtil.f90:372
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
This module contains the derived types ObserveType and ObsDataType.
Definition Observe.f90:15
This module contains the derived type ObsType.
Definition Obs.f90:127
subroutine, public defaultobsidprocessor(obsrv, dis, inunitobs, iout)
@ brief Process IDstring provided for each observation
Definition Obs.f90:246
This module contains simulation methods.
Definition Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition Sim.f90:92
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
Definition Sim.f90:204
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
integer(i4b) iout
file unit number for simulation output
subroutine squadratic(x, range, dydx, y)
@ brief sQuadratic
This module contains the ZDG package methods.
Definition swf-zdg.f90:7
subroutine zdg_allocate_scalars(this)
@ brief Allocate scalars
Definition swf-zdg.f90:131
logical function zdg_obs_supported(this)
Determine if observations are supported.
Definition swf-zdg.f90:412
subroutine zdg_cf(this)
@ brief Formulate the package hcof and rhs terms.
Definition swf-zdg.f90:251
subroutine zdg_fc(this, rhs, ia, idxglo, matrix_sln)
@ brief Copy hcof and rhs terms into solution.
Definition swf-zdg.f90:342
real(dp) function zdg_bound_value(this, col, row)
@ brief Return a bound value
Definition swf-zdg.f90:521
subroutine, public zdg_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath, dis, cxs, unitconv)
@ brief Create a new package object
Definition swf-zdg.f90:74
subroutine zdg_rp_ts(this)
Assign time series links for the package.
Definition swf-zdg.f90:496
character(len=16) text
package flow text string
Definition swf-zdg.f90:31
subroutine zdg_da(this)
@ brief Deallocate package memory
Definition swf-zdg.f90:186
subroutine zdg_options(this)
@ brief Source additional options for package
Definition swf-zdg.f90:210
character(len=lenftype) ftype
package ftype
Definition swf-zdg.f90:30
subroutine zdg_allocate_arrays(this, nodelist, auxvar)
@ brief Allocate arrays
Definition swf-zdg.f90:152
subroutine log_zdg_options(this)
@ brief Log SWF specific package options
Definition swf-zdg.f90:230
subroutine zdg_bd_obs(this)
Save observations for the package.
Definition swf-zdg.f90:446
real(dp) function qcalc(this, i, depth, unitconv)
Definition swf-zdg.f90:312
subroutine zdg_df_obs(this)
Define the observation types available in the package.
Definition swf-zdg.f90:425
type(timeserieslinktype) function, pointer, public gettimeserieslinkfromlist(list, indx)
Get time series link from a list.