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