MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
gwe-ctp.f90
Go to the documentation of this file.
2  !
3  use kindmodule, only: dp, i4b
6  use simvariablesmodule, only: errmsg
9  use bndmodule, only: bndtype
10  use bndextmodule, only: bndexttype
11  use observemodule, only: observetype
15  !
16  implicit none
17  !
18  private
19  public :: ctp_create
20  !
21  character(len=LENFTYPE) :: ftype = 'CTP'
22  character(len=LENPACKAGENAME) :: text = ' CTP'
23  !
24  type, extends(bndexttype) :: gwectptype
25 
26  real(dp), dimension(:), pointer, contiguous :: tspvar => null() !< constant temperature array
27  real(dp), dimension(:), pointer, contiguous :: ratectpin => null() !< simulated flows into constant temperature (excluding other CNTs)
28  real(dp), dimension(:), pointer, contiguous :: ratectpout => null() !< simulated flows out of constant temperature (excluding to other CNTs)
29  character(len=LENVARNAME) :: depvartype = '' !< stores string of dependent variable type, depending on model type
30  contains
31  procedure :: bnd_rp => ctp_rp
32  procedure :: bnd_ad => ctp_ad
33  procedure :: bnd_ck => ctp_ck
34  procedure :: bnd_fc => ctp_fc
35  procedure :: bnd_cq => ctp_cq
36  procedure :: bnd_bd => ctp_bd
37  procedure :: bnd_da => ctp_da
38  procedure :: allocate_arrays => ctp_allocate_arrays
39  procedure :: define_listlabel
40  procedure :: bound_value => ctp_bound_value
41  procedure :: temp_mult
42  ! -- methods for observations
43  procedure, public :: bnd_obs_supported => ctp_obs_supported
44  procedure, public :: bnd_df_obs => ctp_df_obs
45  ! -- method for time series
46  procedure, public :: bnd_rp_ts => ctp_rp_ts
47  end type gwectptype
48 
49 contains
50 
51  !> @brief Create a new constant temperature package
52  !!
53  !! Routine points packobj to the newly created package
54  !<
55  subroutine ctp_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
56  depvartype, mempath)
57  ! -- dummy
58  class(bndtype), pointer :: packobj
59  integer(I4B), intent(in) :: id
60  integer(I4B), intent(in) :: ibcnum
61  integer(I4B), intent(in) :: inunit
62  integer(I4B), intent(in) :: iout
63  character(len=*), intent(in) :: namemodel
64  character(len=*), intent(in) :: pakname
65  character(len=LENVARNAME), intent(in) :: depvartype
66  character(len=*), intent(in) :: mempath
67  ! -- local
68  type(gwectptype), pointer :: ctpobj
69  !
70  ! -- allocate the object and assign values to object variables
71  allocate (ctpobj)
72  packobj => ctpobj
73  !
74  ! -- create name and memory path
75  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
76  packobj%text = text
77  !
78  ! -- allocate scalars
79  call ctpobj%allocate_scalars()
80  !
81  ! -- initialize package
82  call packobj%pack_initialize()
83  !
84  ! -- store values
85  packobj%inunit = inunit
86  packobj%iout = iout
87  packobj%id = id
88  packobj%ibcnum = ibcnum
89  packobj%ncolbnd = 1
90  packobj%iscloc = 1
91  !
92  ! -- Store the appropriate label based on the dependent variable
93  ctpobj%depvartype = depvartype
94  end subroutine ctp_create
95 
96  !> @brief Allocate arrays specific to the constant temperature package
97  !<
98  subroutine ctp_allocate_arrays(this, nodelist, auxvar)
99  ! -- modules
101  ! -- dummy
102  class(gwectptype) :: this
103  integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist
104  real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar
105  ! -- local
106  integer(I4B) :: i
107  !
108  ! -- call standard BndType allocate scalars
109  call this%BndExtType%allocate_arrays(nodelist, auxvar)
110  !
111  ! -- allocate ratectpex
112  call mem_allocate(this%ratectpin, this%maxbound, 'RATECTPIN', this%memoryPath)
113  call mem_allocate(this%ratectpout, this%maxbound, 'RATECTPOUT', &
114  this%memoryPath)
115  do i = 1, this%maxbound
116  this%ratectpin(i) = dzero
117  this%ratectpout(i) = dzero
118  end do
119  ! -- set constant head array input context pointer
120  call mem_setptr(this%tspvar, 'TSPVAR', this%input_mempath)
121  !
122  ! -- checkin constant head array input context pointer
123  call mem_checkin(this%tspvar, 'TSPVAR', this%memoryPath, &
124  'TSPVAR', this%input_mempath)
125  !
126  end subroutine ctp_allocate_arrays
127 
128  !> @brief Constant temperature read and prepare (rp) routine
129  !<
130  subroutine ctp_rp(this)
131  ! -- modules
132  use simmodule, only: store_error
133  use inputoutputmodule, only: lowcase
134  implicit none
135  ! -- dummy
136  class(gwectptype), intent(inout) :: this
137  ! -- local
138  integer(I4B) :: i, node, ibd, ierr
139  character(len=30) :: nodestr
140  character(len=LENVARNAME) :: dvtype
141  !
142  ! -- Reset previous CTPs to active cell
143  do i = 1, this%nbound
144  node = this%nodelist(i)
145  this%ibound(node) = this%ibcnum
146  end do
147  !
148  ! -- Call the parent class read and prepare
149  call this%BndExtType%bnd_rp()
150  !
151  ! -- Set ibound to -(ibcnum + 1) for constant temperature cells
152  ierr = 0
153  do i = 1, this%nbound
154  node = this%nodelist(i)
155  ibd = this%ibound(node)
156  if (ibd < 0) then
157  call this%dis%noder_to_string(node, nodestr)
158  dvtype = trim(this%depvartype)
159  call lowcase(dvtype)
160  call store_error('Cell is already a constant ' &
161  //dvtype//': '//trim(adjustl(nodestr)))
162  ierr = ierr + 1
163  else
164  this%ibound(node) = -this%ibcnum
165  end if
166  end do
167  !
168  ! -- Stop if errors detected
169  if (ierr > 0) then
170  call store_error_filename(this%input_fname)
171  end if
172  end subroutine ctp_rp
173 
174  !> @brief Constant temperature package advance routine
175  !!
176  !! Add package connections to matrix
177  !<
178  subroutine ctp_ad(this)
179  ! -- dummy
180  class(gwectptype) :: this
181  ! -- local
182  integer(I4B) :: i, node
183  real(DP) :: cb
184  !
185  ! -- Advance the time series
186  call this%TsManager%ad()
187  !
188  ! -- Process each entry in the constant temperature cell list
189  do i = 1, this%nbound
190  node = this%nodelist(i)
191  cb = this%temp_mult(i)
192  !
193  this%xnew(node) = cb
194  this%xold(node) = this%xnew(node)
195  end do
196  !
197  ! -- For each observation, push simulated value and corresponding
198  ! simulation time from "current" to "preceding" and reset
199  ! "current" value.
200  call this%obs%obs_ad()
201  end subroutine ctp_ad
202 
203  !> @brief Check constant temperature boundary condition data
204  !<
205  subroutine ctp_ck(this)
206  ! -- dummy
207  class(gwectptype), intent(inout) :: this
208  ! -- local
209  character(len=30) :: nodestr
210  integer(I4B) :: i
211  integer(I4B) :: node
212  ! -- formats
213  character(len=*), parameter :: fmtctperr = &
214  &"('Specified dependent variable boundary ',i0, &
215  &' temperature (',g0,') is less than zero for cell', a)"
216  !
217  ! -- check stress period data
218  do i = 1, this%nbound
219  node = this%nodelist(i)
220  ! -- accumulate errors
221  if (this%temp_mult(i) < dzero) then
222  call this%dis%noder_to_string(node, nodestr)
223  write (errmsg, fmt=fmtctperr) i, this%tspvar(i), trim(nodestr)
224  call store_error(errmsg)
225  end if
226  end do
227  !
228  ! -- write summary of ctp package error messages
229  if (count_errors() > 0) then
230  call store_error_filename(this%input_fname)
231  end if
232  end subroutine ctp_ck
233 
234  !> @brief Override bnd_fc and do nothing
235  !!
236  !! For constant temperature boundary type, the call to bnd_fc needs to be
237  !! overwritten to prevent logic found in bnd from being executed
238  !<
239  subroutine ctp_fc(this, rhs, ia, idxglo, matrix_sln)
240  ! -- dummy
241  class(gwectptype) :: this
242  real(DP), dimension(:), intent(inout) :: rhs
243  integer(I4B), dimension(:), intent(in) :: ia
244  integer(I4B), dimension(:), intent(in) :: idxglo
245  class(matrixbasetype), pointer :: matrix_sln
246  end subroutine ctp_fc
247 
248  !> @brief Calculate flow associated with constant temperature boundary
249  !!
250  !! This method overrides bnd_cq()
251  !<
252  subroutine ctp_cq(this, x, flowja, iadv)
253  ! -- dummy
254  class(gwectptype), intent(inout) :: this
255  real(DP), dimension(:), intent(in) :: x
256  real(DP), dimension(:), contiguous, intent(inout) :: flowja
257  integer(I4B), optional, intent(in) :: iadv
258  ! -- local
259  integer(I4B) :: i
260  integer(I4B) :: ipos
261  integer(I4B) :: node
262  integer(I4B) :: n2
263  integer(I4B) :: idiag
264  real(DP) :: rate
265  real(DP) :: ratein, rateout
266  real(DP) :: q
267  !
268  ! -- If no boundaries, skip flow calculations.
269  if (this%nbound > 0) then
270  !
271  ! -- Loop through each boundary calculating flow.
272  do i = 1, this%nbound
273  node = this%nodelist(i)
274  idiag = this%dis%con%ia(node)
275  rate = dzero
276  ratein = dzero
277  rateout = dzero
278  !
279  ! -- Calculate the flow rate into the cell.
280  do ipos = this%dis%con%ia(node) + 1, &
281  this%dis%con%ia(node + 1) - 1
282  q = flowja(ipos)
283  rate = rate - q
284  ! -- Only accumulate chin and chout for active
285  ! connected cells
286  n2 = this%dis%con%ja(ipos)
287  if (this%ibound(n2) > 0) then
288  if (q < dzero) then
289  ratein = ratein - q
290  else
291  rateout = rateout + q
292  end if
293  end if
294  end do
295  !
296  ! -- For CTP, store total flow in rhs so it is available for other
297  ! calculations
298  this%rhs(i) = -rate
299  this%hcof(i) = dzero
300  !
301  ! -- Save simulated value to simvals array.
302  this%simvals(i) = rate
303  this%ratectpin(i) = ratein
304  this%ratectpout(i) = rateout
305  flowja(idiag) = flowja(idiag) + rate
306  !
307  end do
308  !
309  end if
310  end subroutine ctp_cq
311 
312  !> @brief Add package ratin/ratout to model budget
313  !<
314  subroutine ctp_bd(this, model_budget)
315  ! -- modules
316  use tdismodule, only: delt
318  ! -- dummy
319  class(gwectptype) :: this
320  ! -- local
321  type(budgettype), intent(inout) :: model_budget
322  real(DP) :: ratin
323  real(DP) :: ratout
324  real(DP) :: dum
325  integer(I4B) :: isuppress_output
326  !
327  isuppress_output = 0
328  call rate_accumulator(this%ratectpin(1:this%nbound), ratin, dum)
329  call rate_accumulator(this%ratectpout(1:this%nbound), ratout, dum)
330  call model_budget%addentry(ratin, ratout, delt, this%text, &
331  isuppress_output, this%packName)
332  end subroutine ctp_bd
333 
334  !> @brief Deallocate memory
335  !!
336  !! Method to deallocate memory for the package.
337  !<
338  subroutine ctp_da(this)
339  ! -- modules
341  ! -- dummy
342  class(gwectptype) :: this
343  !
344  ! -- Deallocate parent package
345  call this%BndExtType%bnd_da()
346  !
347  ! -- arrays
348  call mem_deallocate(this%ratectpin)
349  call mem_deallocate(this%ratectpout)
350  call mem_deallocate(this%tspvar, 'TSPVAR', this%memoryPath)
351  end subroutine ctp_da
352 
353  !> @brief Define labels used in list file
354  !!
355  !! Define the list heading that is written to iout when PRINT_INPUT option
356  !! is used.
357  !<
358  subroutine define_listlabel(this)
359  ! -- dummy
360  class(gwectptype), intent(inout) :: this
361  !
362  ! -- create the header list label
363  this%listlabel = trim(this%filtyp)//' NO.'
364  if (this%dis%ndim == 3) then
365  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
366  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
367  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
368  elseif (this%dis%ndim == 2) then
369  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
370  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
371  else
372  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
373  end if
374  write (this%listlabel, '(a, a16)') trim(this%listlabel), &
375  trim(this%depvartype)
376  if (this%inamedbound == 1) then
377  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
378  end if
379  end subroutine define_listlabel
380 
381  !> @brief Procedure related to observation processing
382  !!
383  !! This routine:
384  !! - returns true because the SDV package supports observations,
385  !! - overrides packagetype%_obs_supported()
386  logical function ctp_obs_supported(this)
387  ! -- dummy
388  class(gwectptype) :: this
389  !
390  ctp_obs_supported = .true.
391  end function ctp_obs_supported
392 
393  !> @brief Procedure related to observation processing
394  !!
395  !! This routine:
396  !! - defines observations
397  !! - stores observation types supported by either of the SDV packages
398  !! (CTP or CTP),
399  !! - overrides BndExtType%bnd_df_obs
400  !<
401  subroutine ctp_df_obs(this)
402  ! -- dummy
403  class(gwectptype) :: this
404  ! -- local
405  integer(I4B) :: indx
406  !
407  call this%obs%StoreObsType(this%filtyp, .true., indx)
408  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
409  end subroutine ctp_df_obs
410 
411  ! -- Procedure related to time series
412 
413  !> @brief Procedure related to time series
414  !!
415  !! Assign tsLink%Text appropriately for all time series in use by package.
416  !! For the constant temperature packages, the dependent variable can also be
417  !! controlled by a time series.
418  !<
419  subroutine ctp_rp_ts(this)
420  ! -- dummy
421  class(gwectptype), intent(inout) :: this
422  ! -- local
423  integer(I4B) :: i, nlinks
424  type(timeserieslinktype), pointer :: tslink => null()
425  !
426  nlinks = this%TsManager%boundtslinks%Count()
427  do i = 1, nlinks
428  tslink => gettimeserieslinkfromlist(this%TsManager%boundtslinks, i)
429  if (associated(tslink)) then
430  select case (tslink%JCol)
431  case (1)
432  tslink%Text = trim(this%depvartype)
433  end select
434  end if
435  end do
436  end subroutine ctp_rp_ts
437 
438  !> @brief Apply auxiliary multiplier to specified temperature if
439  !< appropriate
440  function temp_mult(this, row) result(temp)
441  ! -- modules
442  use constantsmodule, only: dzero
443  ! -- dummy
444  class(gwectptype), intent(inout) :: this
445  integer(I4B), intent(in) :: row
446  ! -- result
447  real(dp) :: temp
448  !
449  if (this%iauxmultcol > 0) then
450  temp = this%tspvar(row) * this%auxvar(this%iauxmultcol, row)
451  else
452  temp = this%tspvar(row)
453  end if
454  end function temp_mult
455 
456  !> @ brief Return a bound value
457  !!
458  !! Return a bound value associated with an ncolbnd index and row.
459  !<
460  function ctp_bound_value(this, col, row) result(bndval)
461  ! -- modules
462  use constantsmodule, only: dzero
463  ! -- dummy variables
464  class(gwectptype), intent(inout) :: this
465  integer(I4B), intent(in) :: col
466  integer(I4B), intent(in) :: row
467  ! -- result
468  real(dp) :: bndval
469  !
470  select case (col)
471  case (1)
472  bndval = this%temp_mult(row)
473  case default
474  write (errmsg, '(3a)') 'Programming error. ', &
475  & adjustl(trim(this%filtyp)), ' bound value requested column '&
476  &'outside range of ncolbnd (1).'
477  call store_error(errmsg)
478  call store_error_filename(this%input_fname)
479  end select
480  end function ctp_bound_value
481 
482 end module gwectpmodule
This module contains the extended boundary package.
This module contains the base boundary package.
This module contains the BudgetModule.
Definition: Budget.f90:20
subroutine, public rate_accumulator(flow, rin, rout)
@ brief Rate accumulator subroutine
Definition: Budget.f90:632
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:23
integer(i4b), parameter namedboundflag
named bound flag
Definition: Constants.f90:49
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
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
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
subroutine ctp_bd(this, model_budget)
Add package ratin/ratout to model budget.
Definition: gwe-ctp.f90:315
character(len=lenpackagename) text
Definition: gwe-ctp.f90:22
subroutine ctp_cq(this, x, flowja, iadv)
Calculate flow associated with constant temperature boundary.
Definition: gwe-ctp.f90:253
real(dp) function temp_mult(this, row)
Apply auxiliary multiplier to specified temperature if.
Definition: gwe-ctp.f90:441
subroutine ctp_rp(this)
Constant temperature read and prepare (rp) routine.
Definition: gwe-ctp.f90:131
real(dp) function ctp_bound_value(this, col, row)
@ brief Return a bound value
Definition: gwe-ctp.f90:461
subroutine ctp_rp_ts(this)
Procedure related to time series.
Definition: gwe-ctp.f90:420
logical function ctp_obs_supported(this)
Procedure related to observation processing.
Definition: gwe-ctp.f90:387
subroutine ctp_df_obs(this)
Procedure related to observation processing.
Definition: gwe-ctp.f90:402
subroutine ctp_da(this)
Deallocate memory.
Definition: gwe-ctp.f90:339
subroutine define_listlabel(this)
Define labels used in list file.
Definition: gwe-ctp.f90:359
subroutine ctp_allocate_arrays(this, nodelist, auxvar)
Allocate arrays specific to the constant temperature package.
Definition: gwe-ctp.f90:99
character(len=lenftype) ftype
Definition: gwe-ctp.f90:21
subroutine ctp_fc(this, rhs, ia, idxglo, matrix_sln)
Override bnd_fc and do nothing.
Definition: gwe-ctp.f90:240
subroutine ctp_ad(this)
Constant temperature package advance routine.
Definition: gwe-ctp.f90:179
subroutine ctp_ck(this)
Check constant temperature boundary condition data.
Definition: gwe-ctp.f90:206
subroutine, public ctp_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, depvartype, mempath)
Create a new constant temperature package.
Definition: gwe-ctp.f90:57
subroutine, public lowcase(word)
Convert to lower case.
This module defines variable data types.
Definition: kind.f90:8
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
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
Definition: Sim.f90:203
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:29
type(timeserieslinktype) function, pointer, public gettimeserieslinkfromlist(list, indx)
Get time series link from a list.
@ brief BndType
Derived type for the Budget object.
Definition: Budget.f90:39