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

Data Types

type  tspadvtype
 

Functions/Subroutines

subroutine, public adv_cr (advobj, name_model, inunit, iout, fmi, eqnsclfac)
 @ brief Create a new ADV object More...
 
subroutine adv_df (this, adv_options)
 Define ADV object. More...
 
subroutine adv_ar (this, dis, ibound)
 Allocate and read method for package. More...
 
subroutine adv_dt (this, dtmax, msg, thetam)
 Calculate maximum time step length. More...
 
subroutine adv_fc (this, nodes, matrix_sln, idxglo, cnew, rhs)
 Fill coefficient method for ADV package. More...
 
subroutine advtvd (this, n, cnew, rhs)
 Calculate TVD. More...
 
real(dp) function advqtvd (this, n, m, iposnm, cnew)
 Calculate TVD. More...
 
subroutine adv_cq (this, cnew, flowja)
 Calculate advection contribution to flowja. More...
 
subroutine advtvd_bd (this, cnew, flowja)
 Add TVD contribution to flowja. More...
 
subroutine adv_da (this)
 Deallocate memory. More...
 
subroutine allocate_scalars (this)
 Allocate scalars specific to the streamflow energy transport (SFE) package. More...
 
subroutine read_options (this)
 Read options. More...
 
real(dp) function adv_weight (this, iadvwt, ipos, n, m, qnm)
 @ brief Advection weight More...
 

Function/Subroutine Documentation

◆ adv_ar()

subroutine tspadvmodule::adv_ar ( class(tspadvtype this,
class(disbasetype), intent(in), pointer  dis,
integer(i4b), dimension(:), intent(in), pointer, contiguous  ibound 
)
private

Method to allocate and read static data for the ADV package.

Definition at line 110 of file tsp-adv.f90.

111  ! -- modules
112  ! -- dummy
113  class(TspAdvType) :: this
114  class(DisBaseType), pointer, intent(in) :: dis
115  integer(I4B), dimension(:), pointer, contiguous, intent(in) :: ibound
116  ! -- local
117  ! -- formats
118  !
119  ! -- adv pointers to arguments that were passed in
120  this%dis => dis
121  this%ibound => ibound

◆ adv_cq()

subroutine tspadvmodule::adv_cq ( class(tspadvtype this,
real(dp), dimension(:), intent(in)  cnew,
real(dp), dimension(:), intent(inout)  flowja 
)

Definition at line 329 of file tsp-adv.f90.

330  ! -- modules
331  ! -- dummy
332  class(TspAdvType) :: this
333  real(DP), intent(in), dimension(:) :: cnew
334  real(DP), intent(inout), dimension(:) :: flowja
335  ! -- local
336  integer(I4B) :: nodes
337  integer(I4B) :: n, m, idiag, ipos
338  real(DP) :: omega, qnm
339  !
340  ! -- Calculate advection and add to flowja. qnm is the volumetric flow
341  ! rate and has dimensions of L^/T.
342  nodes = this%dis%nodes
343  do n = 1, nodes
344  if (this%ibound(n) == 0) cycle
345  idiag = this%dis%con%ia(n)
346  do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
347  m = this%dis%con%ja(ipos)
348  if (this%ibound(m) == 0) cycle
349  qnm = this%fmi%gwfflowja(ipos) * this%eqnsclfac
350  omega = this%adv_weight(this%iadvwt, ipos, n, m, qnm)
351  flowja(ipos) = flowja(ipos) + qnm * omega * cnew(n) + &
352  qnm * (done - omega) * cnew(m)
353  end do
354  end do
355  !
356  ! -- TVD
357  if (this%iadvwt == 2) call this%advtvd_bd(cnew, flowja)

◆ adv_cr()

subroutine, public tspadvmodule::adv_cr ( type(tspadvtype), pointer  advobj,
character(len=*), intent(in)  name_model,
integer(i4b), intent(in)  inunit,
integer(i4b), intent(in)  iout,
type(tspfmitype), intent(in), target  fmi,
real(dp), intent(in), pointer  eqnsclfac 
)

Create a new ADV package

Parameters
[in]eqnsclfacgoverning equation scale factor

Definition at line 49 of file tsp-adv.f90.

50  ! -- dummy
51  type(TspAdvType), pointer :: advobj
52  character(len=*), intent(in) :: name_model
53  integer(I4B), intent(in) :: inunit
54  integer(I4B), intent(in) :: iout
55  type(TspFmiType), intent(in), target :: fmi
56  real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor
57  !
58  ! -- Create the object
59  allocate (advobj)
60  !
61  ! -- create name and memory path
62  call advobj%set_names(1, name_model, 'ADV', 'ADV')
63  !
64  ! -- Allocate scalars
65  call advobj%allocate_scalars()
66  !
67  ! -- Set variables
68  advobj%inunit = inunit
69  advobj%iout = iout
70  advobj%fmi => fmi
71  advobj%eqnsclfac => eqnsclfac
Here is the caller graph for this function:

◆ adv_da()

subroutine tspadvmodule::adv_da ( class(tspadvtype this)
private

Definition at line 387 of file tsp-adv.f90.

388  ! -- modules
390  ! -- dummy
391  class(TspAdvType) :: this
392  !
393  ! -- Deallocate arrays if package was active
394  if (this%inunit > 0) then
395  end if
396  !
397  ! -- nullify pointers
398  this%ibound => null()
399  !
400  ! -- Scalars
401  call mem_deallocate(this%iadvwt)
402  call mem_deallocate(this%ats_percel)
403  !
404  ! -- deallocate parent
405  call this%NumericalPackageType%da()

◆ adv_df()

subroutine tspadvmodule::adv_df ( class(tspadvtype this,
type(tspadvoptionstype), intent(in), optional  adv_options 
)
private

Define the ADV package

Parameters
[in]adv_optionsthe optional options, for when not constructing from file

Definition at line 78 of file tsp-adv.f90.

79  ! -- dummy
80  class(TspAdvType) :: this
81  type(TspAdvOptionsType), optional, intent(in) :: adv_options !< the optional options, for when not constructing from file
82  ! -- local
83  character(len=*), parameter :: fmtadv = &
84  "(1x,/1x,'ADV-- ADVECTION PACKAGE, VERSION 1, 8/25/2017', &
85  &' INPUT READ FROM UNIT ', i0, //)"
86  !
87  ! -- Read or set advection options
88  if (.not. present(adv_options)) then
89  !
90  ! -- Initialize block parser (adv has no define, so it's
91  ! not done until here)
92  call this%parser%Initialize(this%inunit, this%iout)
93  !
94  ! --print a message identifying the advection package.
95  write (this%iout, fmtadv) this%inunit
96  !
97  ! --read options from file
98  call this%read_options()
99  else
100  !
101  ! --set options from input arg
102  this%iadvwt = adv_options%iAdvScheme
103  end if

◆ adv_dt()

subroutine tspadvmodule::adv_dt ( class(tspadvtype this,
real(dp), intent(out)  dtmax,
character(len=*), intent(inout)  msg,
real(dp), dimension(:), intent(in)  thetam 
)
private

Return the largest time step that meets stability constraints

Parameters
thisthis instance
[out]dtmaxmaximum allowable dt subject to stability constraint
[in,out]msgpackage/cell dt constraint message
[in]thetamporosity

Definition at line 128 of file tsp-adv.f90.

129  ! dummy
130  class(TspAdvType) :: this !< this instance
131  real(DP), intent(out) :: dtmax !< maximum allowable dt subject to stability constraint
132  character(len=*), intent(inout) :: msg !< package/cell dt constraint message
133  real(DP), dimension(:), intent(in) :: thetam !< porosity
134  ! local
135  integer(I4B) :: n
136  integer(I4B) :: m
137  integer(I4B) :: ipos
138  integer(I4B) :: nrmax
139  character(len=LINELENGTH) :: cellstr
140  real(DP) :: dt
141  real(DP) :: flowmax
142  real(DP) :: flowsumpos
143  real(DP) :: flowsumneg
144  real(DP) :: flownm
145  real(DP) :: cell_volume
146  dtmax = dnodata
147  nrmax = 0
148  msg = ''
149 
150  ! If ats_percel not specified by user, then return without making
151  ! the courant time step calculation
152  if (this%ats_percel == dnodata) then
153  return
154  end if
155 
156  ! Calculate time step lengths based on stability constraint for each cell
157  ! and store the smallest one
158  do n = 1, this%dis%nodes
159  if (this%ibound(n) == 0) cycle
160  flowsumneg = dzero
161  flowsumpos = dzero
162  do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
163  if (this%dis%con%mask(ipos) == 0) cycle
164  m = this%dis%con%ja(ipos)
165  if (this%ibound(m) == 0) cycle
166  flownm = this%fmi%gwfflowja(ipos)
167  if (flownm < dzero) then
168  flowsumneg = flowsumneg - flownm
169  else
170  flowsumpos = flowsumpos + flownm
171  end if
172  end do
173  flowmax = max(flowsumneg, flowsumpos)
174  if (flowmax < dprec) cycle
175  cell_volume = this%dis%get_cell_volume(n, this%dis%top(n))
176  dt = cell_volume * this%fmi%gwfsat(n) * thetam(n) / flowmax
177  dt = dt * this%ats_percel
178  if (dt < dtmax) then
179  dtmax = dt
180  nrmax = n
181  end if
182  end do
183  if (nrmax > 0) then
184  call this%dis%noder_to_string(nrmax, cellstr)
185  write (msg, *) adjustl(trim(this%memoryPath))//'-'//trim(cellstr)
186  end if

◆ adv_fc()

subroutine tspadvmodule::adv_fc ( class(tspadvtype this,
integer, intent(in)  nodes,
class(matrixbasetype), pointer  matrix_sln,
integer(i4b), dimension(:), intent(in)  idxglo,
real(dp), dimension(:), intent(in)  cnew,
real(dp), dimension(:), intent(inout)  rhs 
)
private

Method to calculate coefficients and fill amat and rhs.

Definition at line 193 of file tsp-adv.f90.

194  ! -- modules
195  ! -- dummy
196  class(TspAdvType) :: this
197  integer, intent(in) :: nodes
198  class(MatrixBaseType), pointer :: matrix_sln
199  integer(I4B), intent(in), dimension(:) :: idxglo
200  real(DP), intent(in), dimension(:) :: cnew
201  real(DP), dimension(:), intent(inout) :: rhs
202  ! -- local
203  integer(I4B) :: n, m, idiag, ipos
204  real(DP) :: omega, qnm
205  !
206  ! -- Calculate advection terms and add to solution rhs and hcof. qnm
207  ! is the volumetric flow rate and has dimensions of L^/T.
208  do n = 1, nodes
209  if (this%ibound(n) == 0) cycle
210  idiag = this%dis%con%ia(n)
211  do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
212  if (this%dis%con%mask(ipos) == 0) cycle
213  m = this%dis%con%ja(ipos)
214  if (this%ibound(m) == 0) cycle
215  qnm = this%fmi%gwfflowja(ipos) * this%eqnsclfac
216  omega = this%adv_weight(this%iadvwt, ipos, n, m, qnm)
217  call matrix_sln%add_value_pos(idxglo(ipos), qnm * (done - omega))
218  call matrix_sln%add_value_pos(idxglo(idiag), qnm * omega)
219  end do
220  end do
221  !
222  ! -- TVD
223  if (this%iadvwt == 2) then
224  do n = 1, nodes
225  if (this%ibound(n) == 0) cycle
226  call this%advtvd(n, cnew, rhs)
227  end do
228  end if

◆ adv_weight()

real(dp) function tspadvmodule::adv_weight ( class(tspadvtype this,
integer, intent(in)  iadvwt,
integer, intent(in)  ipos,
integer, intent(in)  n,
integer, intent(in)  m,
real(dp), intent(in)  qnm 
)

Calculate the advection weight

Definition at line 504 of file tsp-adv.f90.

505  ! -- return
506  real(DP) :: omega
507  ! -- dummy
508  class(TspAdvType) :: this
509  integer, intent(in) :: iadvwt
510  integer, intent(in) :: ipos
511  integer, intent(in) :: n
512  integer, intent(in) :: m
513  real(DP), intent(in) :: qnm
514  ! -- local
515  real(DP) :: lnm, lmn
516 
517  select case (iadvwt)
518  case (1)
519  ! -- calculate weight based on distances between nodes and the shared
520  ! face of the connection
521  if (this%dis%con%ihc(this%dis%con%jas(ipos)) == 0) then
522  ! -- vertical connection; assume cell is fully saturated
523  lnm = dhalf * (this%dis%top(n) - this%dis%bot(n))
524  lmn = dhalf * (this%dis%top(m) - this%dis%bot(m))
525  else
526  ! -- horizontal connection
527  lnm = this%dis%con%cl1(this%dis%con%jas(ipos))
528  lmn = this%dis%con%cl2(this%dis%con%jas(ipos))
529  end if
530  omega = lmn / (lnm + lmn)
531  case (0, 2)
532  ! -- use upstream weighting for upstream and tvd schemes
533  if (qnm > dzero) then
534  omega = dzero
535  else
536  omega = done
537  end if
538  end select

◆ advqtvd()

real(dp) function tspadvmodule::advqtvd ( class(tspadvtype this,
integer(i4b), intent(in)  n,
integer(i4b), intent(in)  m,
integer(i4b), intent(in)  iposnm,
real(dp), dimension(:), intent(in)  cnew 
)
private

Use explicit scheme to calculate the advective component of transport. TVD is an acronym for Total-Variation Diminishing

Definition at line 264 of file tsp-adv.f90.

265  ! -- modules
266  use constantsmodule, only: dprec
267  ! -- return
268  real(DP) :: qtvd
269  ! -- dummy
270  class(TspAdvType) :: this
271  integer(I4B), intent(in) :: n
272  integer(I4B), intent(in) :: m
273  integer(I4B), intent(in) :: iposnm
274  real(DP), dimension(:), intent(in) :: cnew
275  ! -- local
276  integer(I4B) :: ipos, isympos, iup, idn, i2up, j
277  real(DP) :: qnm, qmax, qupj, elupdn, elup2up
278  real(DP) :: smooth, cdiff, alimiter
279  !
280  ! -- initialize
281  qtvd = dzero
282  !
283  ! -- Find upstream node
284  isympos = this%dis%con%jas(iposnm)
285  qnm = this%fmi%gwfflowja(iposnm)
286  if (qnm > dzero) then
287  ! -- positive flow into n means m is upstream
288  iup = m
289  idn = n
290  else
291  iup = n
292  idn = m
293  end if
294  elupdn = this%dis%con%cl1(isympos) + this%dis%con%cl2(isympos)
295  !
296  ! -- Find second node upstream to iup
297  i2up = 0
298  qmax = dzero
299  do ipos = this%dis%con%ia(iup) + 1, this%dis%con%ia(iup + 1) - 1
300  j = this%dis%con%ja(ipos)
301  if (this%ibound(j) == 0) cycle
302  qupj = this%fmi%gwfflowja(ipos)
303  isympos = this%dis%con%jas(ipos)
304  if (qupj > qmax) then
305  qmax = qupj
306  i2up = j
307  elup2up = this%dis%con%cl1(isympos) + this%dis%con%cl2(isympos)
308  end if
309  end do
310  !
311  ! -- Calculate flux limiting term
312  if (i2up > 0) then
313  smooth = dzero
314  cdiff = abs(cnew(idn) - cnew(iup))
315  if (cdiff > dprec) then
316  smooth = (cnew(iup) - cnew(i2up)) / elup2up * &
317  elupdn / (cnew(idn) - cnew(iup))
318  end if
319  if (smooth > dzero) then
320  alimiter = dtwo * smooth / (done + smooth)
321  qtvd = dhalf * alimiter * qnm * (cnew(idn) - cnew(iup))
322  qtvd = qtvd * this%eqnsclfac
323  end if
324  end if
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dprec
real constant machine precision
Definition: Constants.f90:120

◆ advtvd()

subroutine tspadvmodule::advtvd ( class(tspadvtype this,
integer(i4b), intent(in)  n,
real(dp), dimension(:), intent(in)  cnew,
real(dp), dimension(:), intent(inout)  rhs 
)
private

Use explicit scheme to calculate the advective component of transport. TVD is an acronym for Total-Variation Diminishing

Definition at line 236 of file tsp-adv.f90.

237  ! -- modules
238  ! -- dummy
239  class(TspAdvType) :: this
240  integer(I4B), intent(in) :: n
241  real(DP), dimension(:), intent(in) :: cnew
242  real(DP), dimension(:), intent(inout) :: rhs
243  ! -- local
244  real(DP) :: qtvd
245  integer(I4B) :: m, ipos
246  !
247  ! -- Loop through each n connection. This will
248  do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
249  if (this%dis%con%mask(ipos) == 0) cycle
250  m = this%dis%con%ja(ipos)
251  if (m > n .and. this%ibound(m) /= 0) then
252  qtvd = this%advqtvd(n, m, ipos, cnew)
253  rhs(n) = rhs(n) - qtvd
254  rhs(m) = rhs(m) + qtvd
255  end if
256  end do

◆ advtvd_bd()

subroutine tspadvmodule::advtvd_bd ( class(tspadvtype this,
real(dp), dimension(:), intent(in)  cnew,
real(dp), dimension(:), intent(inout)  flowja 
)
private

Definition at line 361 of file tsp-adv.f90.

362  ! -- modules
363  ! -- dummy
364  class(TspAdvType) :: this
365  real(DP), dimension(:), intent(in) :: cnew
366  real(DP), dimension(:), intent(inout) :: flowja
367  ! -- local
368  real(DP) :: qtvd, qnm
369  integer(I4B) :: nodes, n, m, ipos
370  !
371  nodes = this%dis%nodes
372  do n = 1, nodes
373  if (this%ibound(n) == 0) cycle
374  do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
375  m = this%dis%con%ja(ipos)
376  if (this%ibound(m) /= 0) then
377  qnm = this%fmi%gwfflowja(ipos)
378  qtvd = this%advqtvd(n, m, ipos, cnew)
379  flowja(ipos) = flowja(ipos) + qtvd
380  end if
381  end do
382  end do

◆ allocate_scalars()

subroutine tspadvmodule::allocate_scalars ( class(tspadvtype this)

Definition at line 411 of file tsp-adv.f90.

412  ! -- modules
414  ! -- dummy
415  class(TspAdvType) :: this
416  ! -- local
417  !
418  ! -- allocate scalars in NumericalPackageType
419  call this%NumericalPackageType%allocate_scalars()
420  !
421  ! -- Allocate
422  call mem_allocate(this%iadvwt, 'IADVWT', this%memoryPath)
423  call mem_allocate(this%ats_percel, 'ATS_PERCEL', this%memoryPath)
424  !
425  ! -- Initialize
426  this%iadvwt = 0
427  this%ats_percel = dnodata
428  !
429  ! -- Advection creates an asymmetric coefficient matrix
430  this%iasym = 1

◆ read_options()

subroutine tspadvmodule::read_options ( class(tspadvtype this)

Read the options block

Definition at line 437 of file tsp-adv.f90.

438  ! -- modules
439  use constantsmodule, only: linelength
440  use simmodule, only: store_error
441  ! -- dummy
442  class(TspAdvType) :: this
443  ! -- local
444  character(len=LINELENGTH) :: errmsg, keyword
445  integer(I4B) :: ierr
446  logical :: isfound, endOfBlock
447  ! -- formats
448  character(len=*), parameter :: fmtiadvwt = &
449  &"(4x,'ADVECTION WEIGHTING SCHEME HAS BEEN SET TO: ', a)"
450  !
451  ! -- get options block
452  call this%parser%GetBlock('OPTIONS', isfound, ierr, blockrequired=.false., &
453  supportopenclose=.true.)
454  !
455  ! -- parse options block if detected
456  if (isfound) then
457  write (this%iout, '(1x,a)') 'PROCESSING ADVECTION OPTIONS'
458  do
459  call this%parser%GetNextLine(endofblock)
460  if (endofblock) exit
461  call this%parser%GetStringCaps(keyword)
462  select case (keyword)
463  case ('SCHEME')
464  call this%parser%GetStringCaps(keyword)
465  select case (keyword)
466  case ('UPSTREAM')
467  this%iadvwt = 0
468  write (this%iout, fmtiadvwt) 'UPSTREAM'
469  case ('CENTRAL')
470  this%iadvwt = 1
471  write (this%iout, fmtiadvwt) 'CENTRAL'
472  case ('TVD')
473  this%iadvwt = 2
474  write (this%iout, fmtiadvwt) 'TVD'
475  case default
476  write (errmsg, '(a, a)') &
477  'Unknown scheme: ', trim(keyword)
478  call store_error(errmsg)
479  write (errmsg, '(a, a)') &
480  'Scheme must be "UPSTREAM", "CENTRAL" or "TVD"'
481  call store_error(errmsg)
482  call this%parser%StoreErrorUnit()
483  end select
484  case ('ATS_PERCEL')
485  this%ats_percel = this%parser%GetDouble()
486  if (this%ats_percel == dzero) this%ats_percel = dnodata
487  write (this%iout, '(4x,a,1pg15.6)') &
488  'User-specified fractional cell distance for adaptive time &
489  &steps: ', this%ats_percel
490  case default
491  write (errmsg, '(a,a)') 'Unknown ADVECTION option: ', &
492  trim(keyword)
493  call store_error(errmsg, terminate=.true.)
494  end select
495  end do
496  write (this%iout, '(1x,a)') 'END OF ADVECTION OPTIONS'
497  end if
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
Here is the call graph for this function: