MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
swfevpmodule Module Reference

This module contains the evaporation (EVP) package methods. More...

Data Types

type  swfevptype
 

Functions/Subroutines

subroutine, public evp_create (packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath, dis, dfw, cxs)
 Create a Evaporation Package. More...
 
subroutine evp_allocate_scalars (this)
 Allocate scalar members. More...
 
subroutine evp_allocate_arrays (this, nodelist, auxvar)
 Allocate package arrays. More...
 
subroutine evp_source_options (this)
 Source options specific to EVPType. More...
 
subroutine log_evp_options (this, found_readasarrays)
 Log options specific to SwfEvpType. More...
 
subroutine evp_source_dimensions (this)
 Source the dimensions for this package. More...
 
subroutine evp_read_initial_attr (this)
 Part of allocate and read. More...
 
subroutine evp_rp (this)
 Read and Prepare. More...
 
subroutine evp_ck (this)
 Ensure evaporation is positive. More...
 
subroutine evp_cf (this)
 Formulate the HCOF and RHS terms. More...
 
real(dp) function get_qevp (this, node, rlen, snew, sold, evaporation)
 Calculate qevp. More...
 
real(dp) function get_evap_reduce_mult (this, stage, bottom)
 Calculate multiplier to reduce evap as depth goes to zero. More...
 
subroutine evp_fc (this, rhs, ia, idxglo, matrix_sln)
 Copy rhs and hcof into solution rhs and amat. More...
 
subroutine evp_da (this)
 Deallocate memory. More...
 
subroutine evp_define_listlabel (this)
 Define the list heading that is written to iout when PRINT_INPUT option is used. More...
 
subroutine default_nodelist (this)
 Assign default nodelist when READASARRAYS is specified. More...
 
logical function evp_obs_supported (this)
 Overrides BndTypebnd_obs_supported() More...
 
subroutine evp_df_obs (this)
 Implements bnd_df_obs. More...
 
real(dp) function evp_bound_value (this, col, row)
 Return requested boundary value. More...
 
real(dp) function, dimension(:), pointer reach_length_pointer (this)
 

Variables

character(len=lenftype) ftype = 'EVP'
 
character(len=lenpackagename) text = ' EVP'
 

Detailed Description

This module can be used to represent evaporation onto streams and overland flow cells.

Function/Subroutine Documentation

◆ default_nodelist()

subroutine swfevpmodule::default_nodelist ( class(swfevptype this)
private

Definition at line 554 of file swf-evp.f90.

555  ! dummy
556  class(SwfEvpType) :: this
557  ! local
558  integer(I4B) :: nodeu, noder
559 
560  ! This is only called for readasarrays, so nodelist will be the size of
561  ! the user grid, and will have a value of 0 for any entries where idomain
562  ! is not 1
563  do nodeu = 1, this%maxbound
564  noder = this%dis%get_nodenumber(nodeu, 0)
565  this%nodelist(nodeu) = noder
566  end do
567 
568  ! Assign nbound
569  this%nbound = this%maxbound
570 

◆ evp_allocate_arrays()

subroutine swfevpmodule::evp_allocate_arrays ( class(swfevptype this,
integer(i4b), dimension(:), optional, pointer, contiguous  nodelist,
real(dp), dimension(:, :), optional, pointer, contiguous  auxvar 
)
private

Definition at line 147 of file swf-evp.f90.

148  ! modules
150  ! dummy
151  class(SwfEvpType) :: this
152  integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist
153  real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar
154 
155  ! allocate base arrays
156  call this%BndExtType%allocate_arrays(nodelist, auxvar)
157 
158  ! set input context pointers
159  call mem_setptr(this%evaporation, 'EVAPORATION', this%input_mempath)
160 
161  ! checkin input context pointers
162  call mem_checkin(this%evaporation, 'EVAPORATION', this%memoryPath, &
163  'EVAPORATION', this%input_mempath)

◆ evp_allocate_scalars()

subroutine swfevpmodule::evp_allocate_scalars ( class(swfevptype), intent(inout)  this)
private

Definition at line 127 of file swf-evp.f90.

128  ! dummy
129  class(SwfEvpType), intent(inout) :: this
130 
131  ! allocate base scalars
132  call this%BndExtType%allocate_scalars()
133 
134  ! allocate internal members
135  call mem_allocate(this%iflowred, 'IFLOWRED', this%memoryPath)
136  call mem_allocate(this%reduction_depth, 'REDUCTION_DEPTH', this%memoryPath)
137  allocate (this%read_as_arrays)
138 
139  ! Set values
140  this%iflowred = 1
141  this%reduction_depth = dem6
142  this%read_as_arrays = .false.

◆ evp_bound_value()

real(dp) function swfevpmodule::evp_bound_value ( class(swfevptype), intent(inout)  this,
integer(i4b), intent(in)  col,
integer(i4b), intent(in)  row 
)
private
Parameters
[in,out]thisBndExtType object

Definition at line 604 of file swf-evp.f90.

605  ! modules
606  use constantsmodule, only: dzero
607  ! dummy
608  class(SwfEvpType), intent(inout) :: this !< BndExtType object
609  integer(I4B), intent(in) :: col
610  integer(I4B), intent(in) :: row
611  ! result
612  real(DP) :: bndval
613 
614  select case (col)
615  case (1)
616  if (this%iauxmultcol > 0) then
617  bndval = this%evaporation(row) * this%auxvar(this%iauxmultcol, row)
618  else
619  bndval = this%evaporation(row)
620  end if
621  case default
622  errmsg = 'Programming error. EVP bound value requested column '&
623  &'outside range of ncolbnd (1).'
624  call store_error(errmsg)
625  call store_error_filename(this%input_fname)
626  end select
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
Here is the call graph for this function:

◆ evp_cf()

subroutine swfevpmodule::evp_cf ( class(swfevptype this)
private

Skip if no evaporation. Otherwise, calculate hcof and rhs

Definition at line 314 of file swf-evp.f90.

315  ! dummy
316  class(SwfEvpType) :: this
317  ! local
318  integer(I4B) :: i
319  integer(I4B) :: node
320  integer(I4B) :: inwt
321  real(DP) :: q
322  real(DP) :: qeps
323  real(DP) :: eps
324  real(DP) :: derv
325  real(DP) :: evap
326  real(DP) :: rlen
327  real(DP), dimension(:), pointer :: reach_length
328 
329  ! Return if no evaporation
330  if (this%nbound == 0) return
331 
332  ! Set pointer to reach_length for 1d
333  reach_length => this%reach_length_pointer()
334  rlen = dzero
335 
336  ! Calculate hcof and rhs for each evaporation entry
337  do i = 1, this%nbound
338 
339  ! Find the node number
340  node = this%nodelist(i)
341 
342  ! cycle if nonexistent bound
343  if (node <= 0) then
344  this%hcof(i) = dzero
345  this%rhs(i) = dzero
346  cycle
347  end if
348 
349  ! cycle if dry or constant head
350  if (this%ibound(node) <= 0) then
351  this%hcof(i) = dzero
352  this%rhs(i) = dzero
353  cycle
354  end if
355 
356  ! Initialize hcof
357  this%hcof(i) = dzero
358 
359  ! assign evap rate in length per time and multiply by auxvar
360  evap = this%evaporation(i)
361  if (this%iauxmultcol > 0) then
362  evap = evap * this%auxvar(this%iauxmultcol, i)
363  end if
364 
365  ! get reach length for 1d channel
366  if (this%dis%is_1d()) then
367  rlen = reach_length(node)
368  end if
369 
370  ! Calculate volumetric evaporation flow in L^3/Td and add to rhs
371  q = -this%get_qevp(node, rlen, this%xnew(node), this%xold(node), evap)
372  this%rhs(i) = -q
373 
374  ! Code for adding newton terms
375  inwt = 1
376  if (inwt == 1) then
377 
378  ! calculate perturbed q
379  eps = get_perturbation(this%xnew(node))
380  qeps = -this%get_qevp(node, rlen, this%xnew(node) + eps, &
381  this%xold(node), evap)
382 
383  ! calculate derivative
384  derv = (qeps - q) / eps
385 
386  ! add derivative to hcof and update rhs with derivate contribution
387  this%hcof(i) = derv
388  this%rhs(i) = this%rhs(i) + derv * this%xnew(node)
389  end if
390 
391  end do
Here is the call graph for this function:

◆ evp_ck()

subroutine swfevpmodule::evp_ck ( class(swfevptype), intent(inout)  this)

Definition at line 283 of file swf-evp.f90.

284  ! dummy
285  class(SwfEvpType), intent(inout) :: this
286  ! local
287  character(len=30) :: nodestr
288  integer(I4B) :: i, nr
289  character(len=*), parameter :: fmterr = &
290  &"('Specified stress ',i0, &
291  &' evaporation (',g0,') is less than zero for cell', a)"
292 
293  ! Ensure evaporation rates are positive
294  do i = 1, this%nbound
295  nr = this%nodelist(i)
296  if (nr <= 0) cycle
297  if (this%evaporation(i) < dzero) then
298  call this%dis%noder_to_string(nr, nodestr)
299  write (errmsg, fmt=fmterr) i, this%evaporation(i), trim(nodestr)
300  call store_error(errmsg)
301  end if
302  end do
303 
304  ! write summary of package error messages
305  if (count_errors() > 0) then
306  call store_error_filename(this%input_fname)
307  end if
Here is the call graph for this function:

◆ evp_create()

subroutine, public swfevpmodule::evp_create ( class(bndtype), pointer  packobj,
integer(i4b), intent(in)  id,
integer(i4b), intent(in)  ibcnum,
integer(i4b), intent(in)  inunit,
integer(i4b), intent(in)  iout,
character(len=*), intent(in)  namemodel,
character(len=*), intent(in)  pakname,
character(len=*), intent(in)  mempath,
class(disbasetype), intent(inout), pointer  dis,
type(swfdfwtype), intent(in), pointer  dfw,
type(swfcxstype), intent(in), pointer  cxs 
)
Parameters
packobjpointer to default package type
[in]idpackage id
[in]ibcnumboundary condition number
[in]inunitunit number of CDB package input file
[in]ioutunit number of model listing file
[in]namemodelmodel name
[in]paknamepackage name
[in]mempathinput mempath
[in,out]disthe pointer to the discretization
[in]dfwthe pointer to the dfw package
[in]cxsthe pointer to the cxs package

Definition at line 78 of file swf-evp.f90.

80  ! dummy
81  class(BndType), pointer :: packobj !< pointer to default package type
82  integer(I4B), intent(in) :: id !< package id
83  integer(I4B), intent(in) :: ibcnum !< boundary condition number
84  integer(I4B), intent(in) :: inunit !< unit number of CDB package input file
85  integer(I4B), intent(in) :: iout !< unit number of model listing file
86  character(len=*), intent(in) :: namemodel !< model name
87  character(len=*), intent(in) :: pakname !< package name
88  character(len=*), intent(in) :: mempath !< input mempath
89  class(DisBaseType), pointer, intent(inout) :: dis !< the pointer to the discretization
90  type(SwfDfwType), pointer, intent(in) :: dfw !< the pointer to the dfw package
91  type(SwfCxsType), pointer, intent(in) :: cxs !< the pointer to the cxs package
92  ! local
93  type(SwfEvpType), pointer :: evpobj
94 
95  ! allocate evaporation object and scalar variables
96  allocate (evpobj)
97  packobj => evpobj
98 
99  ! create name and memory path
100  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
101  packobj%text = text
102 
103  ! allocate scalars
104  call evpobj%evp_allocate_scalars()
105 
106  ! initialize package
107  call packobj%pack_initialize()
108 
109  packobj%inunit = inunit
110  packobj%iout = iout
111  packobj%id = id
112  packobj%ibcnum = ibcnum
113  packobj%ictMemPath = create_mem_path(namemodel, 'DFW')
114 
115  ! store pointer to dis
116  evpobj%dis => dis
117 
118  ! store pointer to dfw
119  evpobj%dfw => dfw
120 
121  ! store pointer to cxs
122  evpobj%cxs => cxs
Here is the call graph for this function:
Here is the caller graph for this function:

◆ evp_da()

subroutine swfevpmodule::evp_da ( class(swfevptype this)
private

Definition at line 503 of file swf-evp.f90.

504  ! modules
505  ! dummy
506  class(SwfEvpType) :: this
507 
508  ! Deallocate parent package
509  call this%BndExtType%bnd_da()
510 
511  ! scalars
512  call mem_deallocate(this%iflowred)
513  call mem_deallocate(this%reduction_depth)
514  deallocate (this%read_as_arrays)
515 
516  ! arrays
517  call mem_deallocate(this%evaporation, 'EVAPORATION', this%memoryPath)
518 
519  ! pointers
520  nullify (this%dis)
521  nullify (this%dfw)
522  nullify (this%cxs)

◆ evp_define_listlabel()

subroutine swfevpmodule::evp_define_listlabel ( class(swfevptype), intent(inout)  this)
private

Definition at line 528 of file swf-evp.f90.

529  ! dummy
530  class(SwfEvpType), intent(inout) :: this
531  !
532  ! create the header list label
533  this%listlabel = trim(this%filtyp)//' NO.'
534  if (this%dis%ndim == 3) then
535  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
536  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
537  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
538  elseif (this%dis%ndim == 2) then
539  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
540  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
541  else
542  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
543  end if
544  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'EVAPORATION'
545 ! if(this%multindex > 0) &
546 ! write(this%listlabel, '(a, a16)') trim(this%listlabel), 'MULTIPLIER'
547  if (this%inamedbound == 1) then
548  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
549  end if

◆ evp_df_obs()

subroutine swfevpmodule::evp_df_obs ( class(swfevptype this)
private

Store observation type supported by EVP package. Overrides BndTypebnd_df_obs

Definition at line 591 of file swf-evp.f90.

592  implicit none
593  ! dummy
594  class(SwfEvpType) :: this
595  ! local
596  integer(I4B) :: indx
597 
598  call this%obs%StoreObsType('evp', .true., indx)
599  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
Here is the call graph for this function:

◆ evp_fc()

subroutine swfevpmodule::evp_fc ( class(swfevptype this,
real(dp), dimension(:), intent(inout)  rhs,
integer(i4b), dimension(:), intent(in)  ia,
integer(i4b), dimension(:), intent(in)  idxglo,
class(matrixbasetype), pointer  matrix_sln 
)
private

Definition at line 481 of file swf-evp.f90.

482  ! dummy
483  class(SwfEvpType) :: this
484  real(DP), dimension(:), intent(inout) :: rhs
485  integer(I4B), dimension(:), intent(in) :: ia
486  integer(I4B), dimension(:), intent(in) :: idxglo
487  class(MatrixBaseType), pointer :: matrix_sln
488  ! local
489  integer(I4B) :: i, n, ipos
490 
491  ! Copy package rhs and hcof into solution rhs and amat
492  do i = 1, this%nbound
493  n = this%nodelist(i)
494  if (n <= 0) cycle
495  rhs(n) = rhs(n) + this%rhs(i)
496  ipos = ia(n)
497  call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
498  end do

◆ evp_obs_supported()

logical function swfevpmodule::evp_obs_supported ( class(swfevptype this)
private

Definition at line 579 of file swf-evp.f90.

580  implicit none
581  ! dummy
582  class(SwfEvpType) :: this
583  evp_obs_supported = .true.

◆ evp_read_initial_attr()

subroutine swfevpmodule::evp_read_initial_attr ( class(swfevptype), intent(inout)  this)
private

Definition at line 246 of file swf-evp.f90.

247  ! dummy
248  class(SwfEvpType), intent(inout) :: this
249 
250  if (this%read_as_arrays) then
251  call this%default_nodelist()
252  end if

◆ evp_rp()

subroutine swfevpmodule::evp_rp ( class(swfevptype), intent(inout)  this)
private

Read itmp and read new boundaries if itmp > 0

Definition at line 259 of file swf-evp.f90.

260  ! modules
261  use tdismodule, only: kper
262  implicit none
263  ! dummy
264  class(SwfEvpType), intent(inout) :: this
265 
266  if (this%iper /= kper) return
267 
268  if (this%read_as_arrays) then
269  ! no need to do anything because this%evaporation points directly to
270  ! the input context evaporation, which is automatically updated by idm
271  else
272  call this%BndExtType%bnd_rp()
273  end if
274 
275  ! Write the list to iout if requested
276  if (this%iprpak /= 0) then
277  call this%write_list()
278  end if
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23

◆ evp_source_dimensions()

subroutine swfevpmodule::evp_source_dimensions ( class(swfevptype), intent(inout)  this)
private

Definition at line 214 of file swf-evp.f90.

215  ! dummy
216  class(SwfEvpType), intent(inout) :: this
217 
218  if (this%read_as_arrays) then
219 
220  ! Set maxbound to the number of cells per layer, which is simply
221  ! nrow * ncol for a dis2d grid, and nodesuser for disv2d and disv1d
222  this%maxbound = this%dis%get_ncpl()
223 
224  ! verify dimensions were set
225  if (this%maxbound <= 0) then
226  write (errmsg, '(a)') &
227  'MAXBOUND must be an integer greater than zero.'
228  call store_error(errmsg)
229  call store_error_filename(this%input_fname)
230  end if
231 
232  else
233 
234  ! source maxbound
235  call this%BndExtType%source_dimensions()
236 
237  end if
238 
239  ! Call define_listlabel to construct the list label that is written
240  ! when PRINT_INPUT option is used.
241  call this%define_listlabel()
Here is the call graph for this function:

◆ evp_source_options()

subroutine swfevpmodule::evp_source_options ( class(swfevptype), intent(inout)  this)

Definition at line 168 of file swf-evp.f90.

169  ! modules
171  implicit none
172  ! dummy
173  class(SwfEvpType), intent(inout) :: this
174  ! local
175  logical(LGP) :: found_readasarrays = .false.
176 
177  ! source common bound options
178  call this%BndExtType%source_options()
179 
180  ! update defaults with idm sourced values
181  call mem_set_value(this%read_as_arrays, 'READASARRAYS', this%input_mempath, &
182  found_readasarrays)
183 
184  ! log evp params
185  call this%log_evp_options(found_readasarrays)

◆ get_evap_reduce_mult()

real(dp) function swfevpmodule::get_evap_reduce_mult ( class(swfevptype this,
real(dp), intent(in)  stage,
real(dp), intent(in)  bottom 
)
private

Definition at line 461 of file swf-evp.f90.

462  ! dummy
463  class(SwfEvpType) :: this
464  real(DP), intent(in) :: stage
465  real(DP), intent(in) :: bottom
466  ! return
467  real(DP) :: qmult
468  ! local
469  real(DP) :: tp
470 
471  qmult = done
472  if (this%iflowred == 1) then
473  tp = bottom + this%reduction_depth
474  qmult = sqsaturation(tp, bottom, stage)
475  end if
476 
Here is the call graph for this function:

◆ get_qevp()

real(dp) function swfevpmodule::get_qevp ( class(swfevptype this,
integer(i4b), intent(in)  node,
real(dp), intent(in)  rlen,
real(dp), intent(in)  snew,
real(dp), intent(in)  sold,
real(dp), intent(in)  evaporation 
)
private

Calculate qevp for both channel and overland flow grids. Approximate the average water surface width of the channel as wavg = delta A over delta h, and then multiply wavg by reach length to come up with surface water area for the channel. Reduce evaporation when depths are small and shut it off when there is no water in the cell.

Parameters
thisthis instance
[in]nodereduced node number
[in]rlenlength of reach
[in]snewcurrent stage in reach
[in]soldprevious stage in reach
[in]evaporationevaporation rate in length per time

Definition at line 403 of file swf-evp.f90.

404  ! dummy
405  class(SwfEvpType) :: this !< this instance
406  integer(I4B), intent(in) :: node !< reduced node number
407  real(DP), intent(in) :: rlen !< length of reach
408  real(DP), intent(in) :: snew !< current stage in reach
409  real(DP), intent(in) :: sold !< previous stage in reach
410  real(DP), intent(in) :: evaporation !< evaporation rate in length per time
411  ! return
412  real(DP) :: qevp
413  ! local
414  integer(I4B) :: idcxs
415  real(DP) :: depth
416  real(DP) :: bt
417  real(DP) :: area
418  real(DP) :: anew
419  real(DP) :: aold
420  real(DP) :: denom
421  real(DP) :: wavg
422  real(DP) :: width_channel
423  real(DP) :: dummy
424  real(DP) :: qmult
425 
426  ! calculate depth of water
427  bt = this%dis%bot(node)
428 
429  ! Determine the water surface area
430  if (this%dis%is_2d()) then
431  ! overland flow case
432  area = this%dis%get_area(node)
433  else if (this%dis%is_1d()) then
434  ! channel case
435  idcxs = this%dfw%idcxs(node)
436  call this%dis%get_flow_width(node, node, 0, width_channel, dummy)
437 
438  depth = snew - bt
439  anew = this%cxs%get_area(idcxs, width_channel, depth)
440  depth = sold - bt
441  aold = this%cxs%get_area(idcxs, width_channel, depth)
442  wavg = this%cxs%get_wetted_top_width(idcxs, width_channel, depth)
443  denom = snew - sold
444  if (abs(denom) > dprec) then
445  wavg = (anew - aold) / (snew - sold)
446  end if
447  area = rlen * wavg
448 
449  end if
450 
451  ! Reduce the evap rate as cell goes dry
452  qmult = this%get_evap_reduce_mult(snew, bt)
453 
454  ! calculate volumetric evaporation flow in L^3/T
455  qevp = evaporation * area * qmult
456 

◆ log_evp_options()

subroutine swfevpmodule::log_evp_options ( class(swfevptype), intent(inout)  this,
logical(lgp), intent(in)  found_readasarrays 
)

Definition at line 190 of file swf-evp.f90.

191  implicit none
192  ! dummy
193  class(SwfEvpType), intent(inout) :: this
194  logical(LGP), intent(in) :: found_readasarrays
195  ! formats
196  character(len=*), parameter :: fmtreadasarrays = &
197  &"(4x, 'EVAPORATION INPUT WILL BE READ AS ARRAY(S).')"
198 
199  ! log found options
200  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text)) &
201  //' OPTIONS'
202 
203  if (found_readasarrays) then
204  write (this%iout, fmtreadasarrays)
205  end if
206 
207  ! close logging block
208  write (this%iout, '(1x,a)') &
209  'END OF '//trim(adjustl(this%text))//' OPTIONS'

◆ reach_length_pointer()

real(dp) function, dimension(:), pointer swfevpmodule::reach_length_pointer ( class(swfevptype this)
Parameters
thisthis instance

Definition at line 629 of file swf-evp.f90.

630  ! dummy
631  class(SwfEvpType) :: this !< this instance
632  ! return
633  real(DP), dimension(:), pointer :: ptr
634  ! local
635  class(DisBaseType), pointer :: dis
636 
637  ptr => null()
638  dis => this%dis
639  select type (dis)
640  type is (disv1dtype)
641  ptr => dis%length
642  end select
643 

Variable Documentation

◆ ftype

character(len=lenftype) swfevpmodule::ftype = 'EVP'
private

Definition at line 35 of file swf-evp.f90.

35  character(len=LENFTYPE) :: ftype = 'EVP'

◆ text

character(len=lenpackagename) swfevpmodule::text = ' EVP'
private

Definition at line 36 of file swf-evp.f90.

36  character(len=LENPACKAGENAME) :: text = ' EVP'