MODFLOW 6  version 6.6.0.dev0
USGS Modular Hydrologic Model
gwf-csub.f90
Go to the documentation of this file.
1 !> @brief This module contains the CSUB package methods
2 !!
3 !! This module contains the methods used to add the effects of elastic
4 !! skeletal storage, compaction, and subsidence on the groundwater flow
5 !! equation. The contribution of elastic skelatal, inelastic and elastic
6 !! interbed storage and water compressibility can be represented.
7 !!
8 !<
10  use kindmodule, only: i4b, dp, lgp
11  use constantsmodule, only: dprec, dzero, dem20, dem15, dem10, dem8, dem7, &
12  dem6, dem4, dp9, dhalf, dem1, done, dtwo, dthree, &
17  lenlistlabel, &
21  use mathutilmodule, only: is_close
22  use messagemodule, only: write_message
25  squadratic0sp, &
28  use observemodule, only: observetype
29  use obsmodule, only: obstype, obs_cr
33  use geomutilmodule, only: get_node
35  use basedismodule, only: disbasetype
39  use sortmodule, only: qsort, selectn
40  !
43  use listmodule, only: listtype
44  use tablemodule, only: tabletype, table_cr
45  !
48  !
49  implicit none
50  !
51  private
52  public :: csub_cr
53  public :: gwfcsubtype
54  !
55  character(len=LENBUDTXT), dimension(4) :: budtxt = & !< text labels for budget terms
56  [' CSUB-CGELASTIC', &
57  ' CSUB-ELASTIC', &
58  ' CSUB-INELASTIC', &
59  ' CSUB-WATERCOMP']
60  character(len=LENBUDTXT), dimension(6) :: comptxt = & !< text labels for compaction terms
61  ['CSUB-COMPACTION', &
62  ' CSUB-INELASTIC', &
63  ' CSUB-ELASTIC', &
64  ' CSUB-INTERBED', &
65  ' CSUB-COARSE', &
66  ' CSUB-ZDISPLACE']
67 
68  !
69  ! -- local parameter
70  real(dp), parameter :: dlog10es = 0.4342942_dp !< derivative of the log of effective stress
71  !
72  ! CSUB type
74  ! -- characters scalars
75  character(len=LENLISTLABEL), pointer :: listlabel => null() !< title of table written for RP
76  character(len=LENMEMPATH), pointer :: stomempath => null() !< memory path of storage package
77  ! -- character arrays
78  character(len=LENBOUNDNAME), dimension(:), &
79  pointer, contiguous :: boundname => null() !< vector of boundnames
80  character(len=LENAUXNAME), dimension(:), &
81  pointer, contiguous :: auxname => null() !< vector of auxname
82  ! -- logical scalars
83  logical(LGP), pointer :: lhead_based => null() !< logical variable indicating if head-based solution
84  ! -- integer scalars
85  integer(I4B), pointer :: istounit => null() !< unit number of storage package
86  integer(I4B), pointer :: istrainib => null() !< unit number of interbed strain output
87  integer(I4B), pointer :: istrainsk => null() !< unit number of coarse-grained strain output
88  integer(I4B), pointer :: ioutcomp => null() !< unit number for cell-by-cell compaction output
89  integer(I4B), pointer :: ioutcompi => null() !< unit number for cell-by-cell inelastic compaction output
90  integer(I4B), pointer :: ioutcompe => null() !< unit number for cell-by-cell elastic compaction output
91  integer(I4B), pointer :: ioutcompib => null() !< unit number for cell-by-cell interbed compaction output
92  integer(I4B), pointer :: ioutcomps => null() !< unit number for cell-by-cell coarse-grained compaction output
93  integer(I4B), pointer :: ioutzdisp => null() !< unit number for z-displacement output
94  integer(I4B), pointer :: ipakcsv => null() !< unit number for csv output
95  integer(I4B), pointer :: iupdatematprop => null() !< flag indicating if material properties will be updated
96  integer(I4B), pointer :: istoragec => null() !< flag indicating specific storage coefficient will be specified
97  integer(I4B), pointer :: icellf => null() !< flag indicating cell fractions will be specified
98  integer(I4B), pointer :: ispecified_pcs => null() !< flag indicating preconsolidation state is specified (not relative)
99  integer(I4B), pointer :: ispecified_dbh => null() !< flag indicating delay bed head is specified (not relative)
100  integer(I4B), pointer :: inamedbound => null() !< flag to read boundnames
101  integer(I4B), pointer :: iconvchk => null() !< flag indicating if a final convergence check will be made
102  integer(I4B), pointer :: naux => null() !< number of auxiliary variables
103  integer(I4B), pointer :: ninterbeds => null() !< number of interbeds
104  integer(I4B), pointer :: maxsig0 => null() !< maximum number of cells with specified sig0 values
105  integer(I4B), pointer :: nbound => null() !< number of boundaries for current stress period
106  integer(I4B), pointer :: iscloc => null() !< bound column to scale with SFAC
107  integer(I4B), pointer :: iauxmultcol => null() !< column to use as multiplier for column iscloc
108  integer(I4B), pointer :: ndelaycells => null() !< number of cells in delay interbeds
109  integer(I4B), pointer :: ndelaybeds => null() !< number of delay interbeds
110  integer(I4B), pointer :: initialized => null() !< flag indicating if the initial stresses have been initialized
111  integer(I4B), pointer :: ieslag => null() !< flag indicating if the effective stress is lagged
112  integer(I4B), pointer :: ipch => null() !< flag indicating if initial precosolidation value is a head
113  integer(I4B), pointer :: iupdatestress => null() !< flag indicating if the geostatic stress is active
114  ! -- real scalars
115  real(dp), pointer :: epsilon => null() !< epsilon for stress smoothing
116  real(dp), pointer :: cc_crit => null() !< convergence criteria for csub-gwf convergence check
117  real(dp), pointer :: gammaw => null() !< product of fluid density, and gravity
118  real(dp), pointer :: beta => null() !< water compressibility
119  real(dp), pointer :: brg => null() !< product of gammaw and water compressibility
120  real(dp), pointer :: satomega => null() !< newton-raphson saturation omega
121  ! -- integer pointer to storage package variables
122  integer(I4B), pointer :: gwfiss => null() !< pointer to model iss flag
123  integer(I4B), pointer :: gwfiss0 => null() !< iss flag for last stress period
124  ! -- integer arrays
125  integer(I4B), dimension(:), pointer, contiguous :: ibound => null() !< pointer to model ibound
126  integer(I4B), dimension(:), pointer, contiguous :: stoiconv => null() !< pointer to iconvert in storage
127  ! -- real arrays
128  real(dp), dimension(:), pointer, contiguous :: stoss => null() !< pointer to ss in storage
129  real(dp), dimension(:), pointer, contiguous :: buff => null() !< buff array
130  real(dp), dimension(:), pointer, contiguous :: buffusr => null() !< buffusr array
131  integer, dimension(:), pointer, contiguous :: nodelist => null() !< reduced node that the interbed is attached to
132  integer, dimension(:), pointer, contiguous :: unodelist => null() !< user node that the interbed is attached to
133  !
134  ! -- coarse-grained storage variables
135  real(dp), dimension(:), pointer, contiguous :: sgm => null() !< specific gravity moist sediments
136  real(dp), dimension(:), pointer, contiguous :: sgs => null() !< specific gravity saturated sediments
137  real(dp), dimension(:), pointer, contiguous :: cg_ske_cr => null() !< coarse-grained specified storage
138  real(dp), dimension(:), pointer, contiguous :: cg_gs => null() !< geostatic stress for a cell
139  real(dp), dimension(:), pointer, contiguous :: cg_es => null() !< coarse-grained (aquifer) effective stress
140  real(dp), dimension(:), pointer, contiguous :: cg_es0 => null() !< coarse-grained (aquifer) effective stress for the previous time step
141  real(dp), dimension(:), pointer, contiguous :: cg_pcs => null() !< coarse-grained (aquifer) preconsolidation stress
142  real(dp), dimension(:), pointer, contiguous :: cg_comp => null() !< coarse-grained (aquifer) incremental compaction
143  real(dp), dimension(:), pointer, contiguous :: cg_tcomp => null() !< coarse-grained (aquifer) total compaction
144  real(dp), dimension(:), pointer, contiguous :: cg_stor => null() !< coarse-grained (aquifer) storage
145  real(dp), dimension(:), pointer, contiguous :: cg_ske => null() !< coarse-grained (aquifer) elastic storage coefficient
146  real(dp), dimension(:), pointer, contiguous :: cg_sk => null() !< coarse-grained (aquifer) first storage coefficient
147  real(dp), dimension(:), pointer, contiguous :: cg_thickini => null() !< initial coarse-grained (aquifer) thickness
148  real(dp), dimension(:), pointer, contiguous :: cg_thetaini => null() !< initial coarse-grained (aquifer) porosity
149  real(dp), dimension(:), pointer, contiguous :: cg_thick => null() !< current coarse-grained (aquifer) thickness
150  real(dp), dimension(:), pointer, contiguous :: cg_thick0 => null() !< previous coarse-grained (aquifer) thickness
151  real(dp), dimension(:), pointer, contiguous :: cg_theta => null() !< current coarse-grained (aquifer) porosity
152  real(dp), dimension(:), pointer, contiguous :: cg_theta0 => null() !< previous coarse-grained (aquifer) porosity
153  !
154  ! -- cell storage variables
155  real(dp), dimension(:), pointer, contiguous :: cell_wcstor => null() !< cell water compressibility storage
156  real(dp), dimension(:), pointer, contiguous :: cell_thick => null() !< cell compressible material thickness
157  !
158  ! -- interbed variables
159  integer(I4B), dimension(:), pointer, contiguous :: idelay => null() !< delay interbed flag - 0 = nodelay, > 0 = delay
160  integer(I4B), dimension(:), pointer, contiguous :: ielastic => null() !< elastic interbed equation - 0 = inelastic and elastic, > 0 = elastic
161  integer(I4B), dimension(:), pointer, contiguous :: iconvert => null() !< convertible cell flag - 0 = elastic, > 0 = inelastic
162  real(dp), dimension(:), pointer, contiguous :: ci => null() !< compression index
163  real(dp), dimension(:), pointer, contiguous :: rci => null() !< recompression index
164  real(dp), dimension(:), pointer, contiguous :: pcs => null() !< preconsolidation stress
165  real(dp), dimension(:), pointer, contiguous :: rnb => null() !< interbed system material factor
166  real(dp), dimension(:), pointer, contiguous :: kv => null() !< vertical hydraulic conductivity of interbed
167  real(dp), dimension(:), pointer, contiguous :: h0 => null() !< initial head in interbed
168  real(dp), dimension(:), pointer, contiguous :: comp => null() !< interbed incremental compaction
169  real(dp), dimension(:), pointer, contiguous :: tcomp => null() !< total interbed compaction
170  real(dp), dimension(:), pointer, contiguous :: tcompi => null() !< total inelastic interbed compaction
171  real(dp), dimension(:), pointer, contiguous :: tcompe => null() !< total elastic interbed compaction
172  real(dp), dimension(:), pointer, contiguous :: storagee => null() !< elastic storage
173  real(dp), dimension(:), pointer, contiguous :: storagei => null() !< inelastic storage
174  real(dp), dimension(:), pointer, contiguous :: ske => null() !< elastic storage coefficient
175  real(dp), dimension(:), pointer, contiguous :: sk => null() !< first storage coefficient
176  real(dp), dimension(:), pointer, contiguous :: thickini => null() !< initial interbed thickness
177  real(dp), dimension(:), pointer, contiguous :: thetaini => null() !< initial interbed theta
178  real(dp), dimension(:), pointer, contiguous :: thick => null() !< current interbed thickness
179  real(dp), dimension(:), pointer, contiguous :: thick0 => null() !< previous interbed thickness
180  real(dp), dimension(:), pointer, contiguous :: theta => null() !< current interbed porosity
181  real(dp), dimension(:), pointer, contiguous :: theta0 => null() !< previous interbed porosity
182  real(dp), dimension(:, :), pointer, contiguous :: auxvar => null() !< auxiliary variable array
183  !
184  ! -- delay interbed
185  integer(I4B), dimension(:), pointer, contiguous :: idb_nconv_count => null() !< non-convertible count of interbeds with heads below delay cell top
186  integer(I4B), dimension(:, :), pointer, contiguous :: idbconvert => null() !0 = elastic, > 0 = inelastic
187  real(dp), dimension(:), pointer, contiguous :: dbdhmax => null() !< delay bed maximum head change
188  real(dp), dimension(:, :), pointer, contiguous :: dbz => null() !< delay bed cell z
189  real(dp), dimension(:, :), pointer, contiguous :: dbrelz => null() !< delay bed cell z relative to znode
190  real(dp), dimension(:, :), pointer, contiguous :: dbh => null() !< delay bed cell h
191  real(dp), dimension(:, :), pointer, contiguous :: dbh0 => null() !< delay bed cell previous h
192  real(dp), dimension(:, :), pointer, contiguous :: dbgeo => null() !< delay bed cell geostatic stress
193  real(dp), dimension(:, :), pointer, contiguous :: dbes => null() !< delay bed cell effective stress
194  real(dp), dimension(:, :), pointer, contiguous :: dbes0 => null() !< delay bed cell previous effective stress
195  real(dp), dimension(:, :), pointer, contiguous :: dbpcs => null() !< delay bed cell preconsolidation stress
196  real(dp), dimension(:), pointer, contiguous :: dbflowtop => null() !< delay bed flow through interbed top
197  real(dp), dimension(:), pointer, contiguous :: dbflowbot => null() !< delay bed flow through interbed bottom
198  real(dp), dimension(:, :), pointer, contiguous :: dbdzini => null() !< initial delay bed cell thickness
199  real(dp), dimension(:, :), pointer, contiguous :: dbthetaini => null() !< initial delay bed cell porosity
200  real(dp), dimension(:, :), pointer, contiguous :: dbdz => null() !< delay bed dz
201  real(dp), dimension(:, :), pointer, contiguous :: dbdz0 => null() !< delay bed previous dz
202  real(dp), dimension(:, :), pointer, contiguous :: dbtheta => null() !< delay bed cell porosity
203  real(dp), dimension(:, :), pointer, contiguous :: dbtheta0 => null() !< delay bed cell previous porosity
204  real(dp), dimension(:, :), pointer, contiguous :: dbcomp => null() !< delay bed incremental compaction
205  real(dp), dimension(:, :), pointer, contiguous :: dbtcomp => null() !< delay bed total interbed compaction
206  !
207  ! -- delay interbed solution arrays
208  real(dp), dimension(:), pointer, contiguous :: dbal => null() !< delay bed lower diagonal
209  real(dp), dimension(:), pointer, contiguous :: dbad => null() !< delay bed diagonal
210  real(dp), dimension(:), pointer, contiguous :: dbau => null() !< delay bed upper diagonal
211  real(dp), dimension(:), pointer, contiguous :: dbrhs => null() !< delay bed right hand side
212  real(dp), dimension(:), pointer, contiguous :: dbdh => null() !< delay bed dh
213  real(dp), dimension(:), pointer, contiguous :: dbaw => null() !< delay bed work vector
214  !
215  ! -- period data
216  integer(I4B), dimension(:), pointer, contiguous :: nodelistsig0 => null() !< vector of reduced node numbers
217  real(dp), dimension(:), pointer, contiguous :: sig0 => null() !< array of package specific boundary numbers
218  !
219  ! -- timeseries
220  type(timeseriesmanagertype), pointer :: tsmanager => null() !< time series manager
221  !
222  ! -- observation data
223  integer(I4B), pointer :: inobspkg => null() !< unit number for obs package
224  type(obstype), pointer :: obs => null() !< observation package
225  !
226  ! -- table objects
227  type(tabletype), pointer :: inputtab => null() !< table for input variables
228  type(tabletype), pointer :: outputtab => null() !< table for output variables
229  type(tabletype), pointer :: pakcsvtab => null() !< table for csv output
230 
231  contains
232  procedure :: define_listlabel
233  procedure :: read_options
234  procedure :: csub_ar
235  procedure :: csub_da
236  procedure :: csub_rp
237  procedure :: csub_ad
238  procedure :: csub_fc
239  procedure :: csub_fn
240  procedure :: csub_cc
241  procedure :: csub_cq
242  procedure :: csub_bd
244  procedure :: csub_ot_dv
245  procedure :: csub_fp
246  procedure :: read_dimensions => csub_read_dimensions
247  procedure, private :: csub_allocate_scalars
248  procedure, private :: csub_allocate_arrays
249  procedure, private :: csub_read_packagedata
250  !
251  ! -- helper methods
252  procedure, private :: csub_calc_void_ratio
253  procedure, private :: csub_calc_theta
254  procedure, private :: csub_calc_znode
255  procedure, private :: csub_calc_adjes
256  procedure, private :: csub_calc_sat
257  procedure, private :: csub_calc_sat_derivative
258  procedure, private :: csub_calc_sfacts
259  procedure, private :: csub_adj_matprop
260  procedure, private :: csub_calc_interbed_thickness
261  procedure, private :: csub_calc_delay_flow
262  !
263  ! -- stress methods
264  procedure, private :: csub_cg_calc_stress
265  procedure, private :: csub_cg_chk_stress
266  !
267  ! -- initial states
268  procedure, private :: csub_set_initial_state
269  !
270  ! -- coarse-grained coarse-grained methods
271  procedure, private :: csub_cg_update
272  procedure, private :: csub_cg_calc_comp
273  procedure, private :: csub_cg_calc_sske
274  procedure, private :: csub_cg_fc
275  procedure, private :: csub_cg_fn
276  procedure, private :: csub_cg_wcomp_fc
277  procedure, private :: csub_cg_wcomp_fn
278  !
279  ! -- interbed methods
280  procedure, private :: csub_interbed_fc
281  procedure, private :: csub_interbed_fn
282  !
283  ! -- no-delay interbed methods
284  procedure, private :: csub_nodelay_update
285  procedure, private :: csub_nodelay_fc
286  procedure, private :: csub_nodelay_wcomp_fc
287  procedure, private :: csub_nodelay_wcomp_fn
288  procedure, private :: csub_nodelay_calc_comp
289  !
290  ! -- delay interbed methods
291  procedure, private :: csub_delay_calc_sat
292  procedure, private :: csub_delay_calc_sat_derivative
293  procedure, private :: csub_delay_init_zcell
294  procedure, private :: csub_delay_calc_stress
295  procedure, private :: csub_delay_calc_ssksske
296  procedure, private :: csub_delay_calc_comp
297  procedure, private :: csub_delay_update
298  procedure, private :: csub_delay_calc_dstor
299  procedure, private :: csub_delay_calc_wcomp
300  procedure, private :: csub_delay_fc
301  procedure, private :: csub_delay_sln
302  procedure, private :: csub_delay_assemble
303  procedure, private :: csub_delay_assemble_fc
304  procedure, private :: csub_delay_assemble_fn
305  procedure, private :: csub_delay_head_check
306 
307  ! methods for tables
308  procedure, private :: csub_initialize_tables
309  !
310  ! -- methods for observations
311  procedure, public :: csub_obs_supported
312  procedure, public :: csub_df_obs
313  procedure, private :: csub_rp_obs
314  procedure, public :: csub_bd_obs
315  end type gwfcsubtype
316 
317 contains
318 
319  !> @ brief Create a new package object
320  !!
321  !! Create a new CSUB object
322  !!
323  !<
324  subroutine csub_cr(csubobj, name_model, istounit, stoPckName, inunit, iout)
325  ! -- dummy variables
326  type(gwfcsubtype), pointer :: csubobj !< pointer to default package type
327  character(len=*), intent(in) :: name_model !< model name
328  integer(I4B), intent(in) :: inunit !< unit number of csub input file
329  integer(I4B), intent(in) :: istounit !< unit number of storage package
330  character(len=*), intent(in) :: stopckname !< name of the storage package
331  integer(I4B), intent(in) :: iout !< unit number of lst output file
332  ! -- local variables
333  !
334  ! -- allocate the object and assign values to object variables
335  allocate (csubobj)
336 
337  ! -- create name and memory path
338  call csubobj%set_names(1, name_model, 'CSUB', 'CSUB')
339  !
340  ! -- Allocate scalars
341  call csubobj%csub_allocate_scalars()
342  !
343  ! -- Create memory path to variables from STO package
344  csubobj%stoMemPath = create_mem_path(name_model, stopckname)
345  !
346  ! -- Set variables
347  csubobj%istounit = istounit
348  csubobj%inunit = inunit
349  csubobj%iout = iout
350  !
351  ! -- Initialize block parser
352  call csubobj%parser%Initialize(csubobj%inunit, csubobj%iout)
353  end subroutine csub_cr
354 
355  !> @ brief Allocate and read method for package
356  !!
357  !! Method to allocate and read static data for the CSUB package.
358  !!
359  !<
360  subroutine csub_ar(this, dis, ibound)
361  ! -- modules
363  use constantsmodule, only: linelength
364  use kindmodule, only: i4b
365  ! -- dummy variables
366  class(gwfcsubtype), intent(inout) :: this
367  class(disbasetype), pointer, intent(in) :: dis !< model discretization
368  integer(I4B), dimension(:), pointer, contiguous :: ibound !< model ibound array
369  ! -- local variables
370  logical(LGP) :: isfound, endOfBlock
371  character(len=:), allocatable :: line
372  character(len=LINELENGTH) :: keyword
373  character(len=20) :: cellid
374  integer(I4B) :: iske
375  integer(I4B) :: istheta
376  integer(I4B) :: isgm
377  integer(I4B) :: isgs
378  integer(I4B) :: idelay
379  integer(I4B) :: ierr
380  integer(I4B) :: lloc
381  integer(I4B) :: istart
382  integer(I4B) :: istop
383  integer(I4B) :: ib
384  integer(I4B) :: node
385  integer(I4B) :: istoerr
386  real(DP) :: top
387  real(DP) :: bot
388  real(DP) :: thick
389  real(DP) :: cg_ske_cr
390  real(DP) :: theta
391  real(DP) :: v
392  ! -- format
393  character(len=*), parameter :: fmtcsub = &
394  "(1x,/1x,'CSUB -- COMPACTION PACKAGE, VERSION 1, 12/15/2019', &
395  &' INPUT READ FROM UNIT ', i0, //)"
396  !
397  ! --print a message identifying the csub package.
398  write (this%iout, fmtcsub) this%inunit
399  !
400  ! -- store pointers to arguments that were passed in
401  this%dis => dis
402  this%ibound => ibound
403  !
404  ! -- Create time series managers
405  call tsmanager_cr(this%TsManager, this%iout)
406  !
407  ! -- create obs package
408  call obs_cr(this%obs, this%inobspkg)
409  !
410  ! -- Read csub options
411  call this%read_options()
412  !
413  ! -- Now that time series will have been read, need to call the df
414  ! routine to define the manager
415  call this%tsmanager%tsmanager_df()
416  !
417  ! -- Read the csub dimensions
418  call this%read_dimensions()
419  !
420  ! - observation data
421  call this%obs%obs_ar()
422 
423  ! setup tables
424  call this%csub_initialize_tables()
425  !
426  ! -- terminate if errors dimensions block data
427  if (count_errors() > 0) then
428  call this%parser%StoreErrorUnit()
429  end if
430 
431  ! -- Allocate arrays in
432  call this%csub_allocate_arrays()
433  !
434  ! -- initialize local variables
435  iske = 0
436  istheta = 0
437  isgm = 0
438  isgs = 0
439  !
440  ! -- read griddata block
441  call this%parser%GetBlock('GRIDDATA', isfound, ierr)
442  if (isfound) then
443  do
444  call this%parser%GetNextLine(endofblock)
445  if (endofblock) exit
446  call this%parser%GetStringCaps(keyword)
447  call this%parser%GetRemainingLine(line)
448  lloc = 1
449  select case (keyword)
450  case ('CG_SKE_CR')
451  call this%dis%read_grid_array(line, lloc, istart, istop, &
452  this%iout, this%parser%iuactive, &
453  this%cg_ske_cr, 'CG_SKE_CR')
454  iske = 1
455  case ('CG_THETA')
456  call this%dis%read_grid_array(line, lloc, istart, istop, &
457  this%iout, this%parser%iuactive, &
458  this%cg_thetaini, 'CG_THETA')
459  istheta = 1
460  case ('SGM')
461  call this%dis%read_grid_array(line, lloc, istart, istop, &
462  this%iout, this%parser%iuactive, &
463  this%sgm, 'SGM')
464  isgm = 1
465  case ('SGS')
466  call this%dis%read_grid_array(line, lloc, istart, istop, &
467  this%iout, this%parser%iuactive, &
468  this%sgs, 'SGS')
469  isgs = 1
470  case default
471  write (errmsg, '(a,1x,a,a)') &
472  "Unknown GRIDDATA tag '", trim(keyword), "'."
473  call store_error(errmsg)
474  end select
475  end do
476  else
477  call store_error('Required GRIDDATA block not found.')
478  end if
479  !
480  ! -- determine if cg_ske and cg_theta have been specified
481  if (iske == 0) then
482  write (errmsg, '(a)') 'CG_SKE GRIDDATA must be specified.'
483  call store_error(errmsg)
484  end if
485  if (istheta == 0) then
486  write (errmsg, '(a)') 'CG_THETA GRIDDATA must be specified.'
487  call store_error(errmsg)
488  end if
489  !
490  ! -- determine if sgm and sgs have been specified, if not assign default values
491  if (isgm == 0) then
492  do node = 1, this%dis%nodes
493  this%sgm(node) = 1.7d0
494  end do
495  end if
496  if (isgs == 0) then
497  do node = 1, this%dis%nodes
498  this%sgs(node) = 2.0d0
499  end do
500  end if
501  !
502  ! -- evaluate the coarse-grained material properties and if
503  ! non-zero specific storage values are specified in the
504  ! STO package
505  istoerr = 0
506  do node = 1, this%dis%nodes
507  call this%dis%noder_to_string(node, cellid)
508  cg_ske_cr = this%cg_ske_cr(node)
509  theta = this%cg_thetaini(node)
510  !
511  ! -- coarse-grained storage error condition
512  if (cg_ske_cr < dzero) then
513  write (errmsg, '(a,g0,a,1x,a,1x,a,a)') &
514  'Coarse-grained material CG_SKE_CR (', cg_ske_cr, ') is less', &
515  'than zero in cell', trim(adjustl(cellid)), '.'
516  end if
517  !
518  ! -- storage (STO) package error condition
519  if (this%stoss(node) /= dzero) then
520  istoerr = 1
521  end if
522  !
523  ! -- porosity error condition
524  if (theta > done .or. theta < dzero) then
525  write (errmsg, '(a,g0,a,1x,a,1x,a,a)') &
526  'Coarse-grained material THETA (', theta, ') is less', &
527  'than zero or greater than 1 in cell', trim(adjustl(cellid)), '.'
528  end if
529  end do
530  !
531  ! -- write single message if storage (STO) package has non-zero specific
532  ! storage values
533  if (istoerr /= 0) then
534  write (errmsg, '(a,3(1x,a))') &
535  'Specific storage values in the storage (STO) package must', &
536  'be zero in all active cells when using the', &
537  trim(adjustl(this%packName)), &
538  'package.'
539  call store_error(errmsg)
540  end if
541  !
542  ! -- read interbed data
543  if (this%ninterbeds > 0) then
544  call this%csub_read_packagedata()
545  end if
546  !
547  ! -- calculate the coarse-grained material thickness without the interbeds
548  do node = 1, this%dis%nodes
549  top = this%dis%top(node)
550  bot = this%dis%bot(node)
551  this%cg_thickini(node) = top - bot
552  this%cell_thick(node) = top - bot
553  end do
554  !
555  ! -- subtract the interbed thickness from aquifer thickness
556  do ib = 1, this%ninterbeds
557  node = this%nodelist(ib)
558  idelay = this%idelay(ib)
559  if (idelay == 0) then
560  v = this%thickini(ib)
561  else
562  v = this%rnb(ib) * this%thickini(ib)
563  end if
564  this%cg_thickini(node) = this%cg_thickini(node) - v
565  end do
566  !
567  ! -- evaluate if any cg_thick values are less than 0
568  do node = 1, this%dis%nodes
569  thick = this%cg_thickini(node)
570  if (thick < dzero) then
571  call this%dis%noder_to_string(node, cellid)
572  write (errmsg, '(a,g0,a,1x,a,a)') &
573  'Aquifer thickness is less than zero (', &
574  thick, ') in cell', trim(adjustl(cellid)), '.'
575  call store_error(errmsg)
576  end if
577  end do
578  !
579  ! -- terminate if errors griddata, packagedata blocks, TDIS, or STO data
580  if (count_errors() > 0) then
581  call this%parser%StoreErrorUnit()
582  end if
583  !
584  ! -- set current coarse-grained thickness (cg_thick) and
585  ! current coarse-grained porosity (cg_theta). Only needed
586  ! if updating material properties
587  if (this%iupdatematprop /= 0) then
588  do node = 1, this%dis%nodes
589  this%cg_thick(node) = this%cg_thickini(node)
590  this%cg_theta(node) = this%cg_thetaini(node)
591  end do
592  end if
593  end subroutine csub_ar
594 
595  !> @ brief Read options for package
596  !!
597  !! Read options block for CSUB package.
598  !!
599  !<
600  subroutine read_options(this)
601  ! -- modules
604  use openspecmodule, only: access, form
606  ! -- dummy variables
607  class(gwfcsubtype), intent(inout) :: this
608  ! -- local variables
609  character(len=LINELENGTH) :: keyword
610  character(len=:), allocatable :: line
611  character(len=MAXCHARLEN) :: fname
612  character(len=LENAUXNAME), dimension(:), allocatable :: caux
613  logical(LGP) :: isfound
614  logical(LGP) :: endOfBlock
615  integer(I4B) :: n
616  integer(I4B) :: lloc
617  integer(I4B) :: istart
618  integer(I4B) :: istop
619  integer(I4B) :: ierr
620  integer(I4B) :: inobs
621  integer(I4B) :: ibrg
622  integer(I4B) :: ieslag
623  integer(I4B) :: isetgamma
624  ! -- formats
625  character(len=*), parameter :: fmtts = &
626  &"(4x,'TIME-SERIES DATA WILL BE READ FROM FILE: ',a)"
627  character(len=*), parameter :: fmtflow = &
628  &"(4x,'FLOWS WILL BE SAVED TO FILE: ',a,/4x,'OPENED ON UNIT: ',I7)"
629  character(len=*), parameter :: fmtflow2 = &
630  &"(4x,'FLOWS WILL BE SAVED TO BUDGET FILE SPECIFIED IN OUTPUT CONTROL')"
631  character(len=*), parameter :: fmtssessv = &
632  &"(4x,'USING SSE AND SSV INSTEAD OF CR AND CC.')"
633  character(len=*), parameter :: fmtoffset = &
634  &"(4x,'INITIAL_STRESS TREATED AS AN OFFSET.')"
635  character(len=*), parameter :: fmtopt = &
636  &"(4x,A)"
637  character(len=*), parameter :: fmtopti = &
638  &"(4x,A,1X,I0)"
639  character(len=*), parameter :: fmtoptr = &
640  &"(4x,A,1X,G0)"
641  character(len=*), parameter :: fmtfileout = &
642  "(4x,'CSUB ',1x,a,1x,' WILL BE SAVED TO FILE: ',a,/4x,&
643  &'OPENED ON UNIT: ',I7)"
644  !
645  ! -- initialize variables
646  ibrg = 0
647  ieslag = 0
648  isetgamma = 0
649  !
650  ! -- get options block
651  call this%parser%GetBlock('OPTIONS', isfound, ierr, blockrequired=.false., &
652  supportopenclose=.true.)
653  !
654  ! -- parse options block if detected
655  if (isfound) then
656  write (this%iout, '(1x,a)') 'PROCESSING CSUB OPTIONS'
657  do
658  call this%parser%GetNextLine(endofblock)
659  if (endofblock) then
660  exit
661  end if
662  call this%parser%GetStringCaps(keyword)
663  select case (keyword)
664  case ('AUX', 'AUXILIARY')
665  call this%parser%GetRemainingLine(line)
666  lloc = 1
667  call urdaux(this%naux, this%parser%iuactive, this%iout, lloc, &
668  istart, istop, caux, line, this%packName)
669  call mem_reallocate(this%auxname, lenauxname, this%naux, &
670  'AUXNAME', this%memoryPath)
671  do n = 1, this%naux
672  this%auxname(n) = caux(n)
673  end do
674  deallocate (caux)
675  case ('SAVE_FLOWS')
676  this%ipakcb = -1
677  write (this%iout, fmtflow2)
678  case ('PRINT_INPUT')
679  this%iprpak = 1
680  write (this%iout, '(4x,a)') &
681  'LISTS OF '//trim(adjustl(this%packName))//' CELLS WILL BE PRINTED.'
682  case ('PRINT_FLOWS')
683  this%iprflow = 1
684  write (this%iout, '(4x,a)') trim(adjustl(this%packName))// &
685  ' FLOWS WILL BE PRINTED TO LISTING FILE.'
686  case ('BOUNDNAMES')
687  this%inamedbound = 1
688  write (this%iout, '(4x,a)') trim(adjustl(this%packName))// &
689  ' BOUNDARIES HAVE NAMES IN LAST COLUMN.' ! user specified boundnames
690  case ('TS6')
691  call this%parser%GetStringCaps(keyword)
692  if (trim(adjustl(keyword)) /= 'FILEIN') then
693  errmsg = 'TS6 keyword must be followed by "FILEIN" '// &
694  'then by filename.'
695  call store_error(errmsg)
696  call this%parser%StoreErrorUnit()
697  end if
698  call this%parser%GetString(fname)
699  write (this%iout, fmtts) trim(fname)
700  call this%TsManager%add_tsfile(fname, this%inunit)
701  case ('OBS6')
702  call this%parser%GetStringCaps(keyword)
703  if (trim(adjustl(keyword)) /= 'FILEIN') then
704  errmsg = 'OBS6 keyword must be followed by "FILEIN" '// &
705  'then by filename.'
706  call store_error(errmsg)
707  end if
708  if (this%obs%active) then
709  errmsg = 'Multiple OBS6 keywords detected in OPTIONS block. '// &
710  'Only one OBS6 entry allowed for a package.'
711  call store_error(errmsg)
712  end if
713  this%obs%active = .true.
714  call this%parser%GetString(this%obs%inputFilename)
715  inobs = getunit()
716  call openfile(inobs, this%iout, this%obs%inputFilename, 'OBS')
717  this%obs%inUnitObs = inobs
718  this%inobspkg = inobs
719 
720  call this%obs%obs_df(this%iout, this%packName, this%filtyp, this%dis)
721  call this%csub_df_obs()
722  !
723  ! -- CSUB specific options
724  case ('GAMMAW')
725  this%gammaw = this%parser%GetDouble()
726  ibrg = 1
727  case ('BETA')
728  this%beta = this%parser%GetDouble()
729  ibrg = 1
730  case ('HEAD_BASED')
731  this%ipch = 1
732  this%lhead_based = .true.
733  case ('INITIAL_PRECONSOLIDATION_HEAD')
734  this%ipch = 1
735  case ('NDELAYCELLS')
736  this%ndelaycells = this%parser%GetInteger()
737  !
738  ! -- compression indices (CR amd CC) will be specified instead of
739  ! storage coefficients (SSE and SSV)
740  case ('COMPRESSION_INDICES')
741  this%istoragec = 0
742  !
743  ! -- variable thickness and void ratio
744  case ('UPDATE_MATERIAL_PROPERTIES')
745  this%iupdatematprop = 1
746  !
747  ! -- cell fraction will be specified instead of interbed thickness
748  case ('CELL_FRACTION')
749  this%icellf = 1
750  !
751  ! -- specified initial pcs and delay bed heads
752  case ('SPECIFIED_INITIAL_INTERBED_STATE')
753  this%ispecified_pcs = 1
754  this%ispecified_dbh = 1
755  !
756  ! -- specified initial pcs
757  case ('SPECIFIED_INITIAL_PRECONSOLIDATION_STRESS')
758  this%ispecified_pcs = 1
759  !
760  ! -- specified initial delay bed heads
761  case ('SPECIFIED_INITIAL_DELAY_HEAD')
762  this%ispecified_dbh = 1
763  !
764  ! -- lag the effective stress used to calculate storage properties
765  case ('EFFECTIVE_STRESS_LAG')
766  ieslag = 1
767  !
768  ! -- strain table options
769  case ('STRAIN_CSV_INTERBED')
770  call this%parser%GetStringCaps(keyword)
771  if (keyword == 'FILEOUT') then
772  call this%parser%GetString(fname)
773  this%istrainib = getunit()
774  call openfile(this%istrainib, this%iout, fname, 'CSV_OUTPUT', &
775  filstat_opt='REPLACE', mode_opt=mnormal)
776  write (this%iout, fmtfileout) &
777  'INTERBED STRAIN CSV', fname, this%istrainib
778  else
779  errmsg = 'Optional STRAIN_CSV_INTERBED keyword must be '// &
780  'followed by FILEOUT.'
781  call store_error(errmsg)
782  end if
783  case ('STRAIN_CSV_COARSE')
784  call this%parser%GetStringCaps(keyword)
785  if (keyword == 'FILEOUT') then
786  call this%parser%GetString(fname)
787  this%istrainsk = getunit()
788  call openfile(this%istrainsk, this%iout, fname, 'CSV_OUTPUT', &
789  filstat_opt='REPLACE', mode_opt=mnormal)
790  write (this%iout, fmtfileout) &
791  'COARSE STRAIN CSV', fname, this%istrainsk
792  else
793  errmsg = 'Optional STRAIN_CSV_COARSE keyword must be '// &
794  'followed by fileout.'
795  call store_error(errmsg)
796  end if
797  !
798  ! -- compaction output
799  case ('COMPACTION')
800  call this%parser%GetStringCaps(keyword)
801  if (keyword == 'FILEOUT') then
802  call this%parser%GetString(fname)
803  this%ioutcomp = getunit()
804  call openfile(this%ioutcomp, this%iout, fname, 'DATA(BINARY)', &
805  form, access, 'REPLACE', mode_opt=mnormal)
806  write (this%iout, fmtfileout) &
807  'COMPACTION', fname, this%ioutcomp
808  else
809  errmsg = 'Optional COMPACTION keyword must be '// &
810  'followed by FILEOUT.'
811  call store_error(errmsg)
812  end if
813  case ('COMPACTION_INELASTIC')
814  call this%parser%GetStringCaps(keyword)
815  if (keyword == 'FILEOUT') then
816  call this%parser%GetString(fname)
817  this%ioutcompi = getunit()
818  call openfile(this%ioutcompi, this%iout, fname, &
819  'DATA(BINARY)', form, access, 'REPLACE', &
820  mode_opt=mnormal)
821  write (this%iout, fmtfileout) &
822  'COMPACTION_INELASTIC', fname, this%ioutcompi
823  else
824  errmsg = 'Optional COMPACTION_INELASTIC keyword must be '// &
825  'followed by fileout.'
826  call store_error(errmsg)
827  end if
828  case ('COMPACTION_ELASTIC')
829  call this%parser%GetStringCaps(keyword)
830  if (keyword == 'FILEOUT') then
831  call this%parser%GetString(fname)
832  this%ioutcompe = getunit()
833  call openfile(this%ioutcompe, this%iout, fname, &
834  'DATA(BINARY)', form, access, 'REPLACE', &
835  mode_opt=mnormal)
836  write (this%iout, fmtfileout) &
837  'COMPACTION_ELASTIC', fname, this%ioutcompe
838  else
839  errmsg = 'Optional COMPACTION_ELASTIC keyword must be '// &
840  'followed by FILEOUT.'
841  call store_error(errmsg)
842  end if
843  case ('COMPACTION_INTERBED')
844  call this%parser%GetStringCaps(keyword)
845  if (keyword == 'FILEOUT') then
846  call this%parser%GetString(fname)
847  this%ioutcompib = getunit()
848  call openfile(this%ioutcompib, this%iout, fname, &
849  'DATA(BINARY)', form, access, 'REPLACE', &
850  mode_opt=mnormal)
851  write (this%iout, fmtfileout) &
852  'COMPACTION_INTERBED', fname, this%ioutcompib
853  else
854  errmsg = 'Optional COMPACTION_INTERBED keyword must be '// &
855  'followed by FILEOUT.'
856  call store_error(errmsg)
857  end if
858  case ('COMPACTION_COARSE')
859  call this%parser%GetStringCaps(keyword)
860  if (keyword == 'FILEOUT') then
861  call this%parser%GetString(fname)
862  this%ioutcomps = getunit()
863  call openfile(this%ioutcomps, this%iout, fname, &
864  'DATA(BINARY)', form, access, 'REPLACE', &
865  mode_opt=mnormal)
866  write (this%iout, fmtfileout) &
867  'COMPACTION_COARSE', fname, this%ioutcomps
868  else
869  errmsg = 'Optional COMPACTION_COARSE keyword must be '// &
870  'followed by FILEOUT.'
871  call store_error(errmsg)
872  end if
873  !
874  ! -- zdisplacement output
875  case ('ZDISPLACEMENT')
876  call this%parser%GetStringCaps(keyword)
877  if (keyword == 'FILEOUT') then
878  call this%parser%GetString(fname)
879  this%ioutzdisp = getunit()
880  call openfile(this%ioutzdisp, this%iout, fname, &
881  'DATA(BINARY)', form, access, 'REPLACE', &
882  mode_opt=mnormal)
883  write (this%iout, fmtfileout) &
884  'ZDISPLACEMENT', fname, this%ioutzdisp
885  else
886  errmsg = 'Optional ZDISPLACEMENT keyword must be '// &
887  'followed by FILEOUT.'
888  call store_error(errmsg)
889  end if
890  ! -- package convergence
891  case ('PACKAGE_CONVERGENCE')
892  call this%parser%GetStringCaps(keyword)
893  if (keyword == 'FILEOUT') then
894  call this%parser%GetString(fname)
895  this%ipakcsv = getunit()
896  call openfile(this%ipakcsv, this%iout, fname, 'CSV', &
897  filstat_opt='REPLACE', mode_opt=mnormal)
898  write (this%iout, fmtfileout) &
899  'PACKAGE_CONVERGENCE', fname, this%ipakcsv
900  else
901  call store_error('Optional PACKAGE_CONVERGENCE keyword must be '// &
902  'followed by FILEOUT.')
903  end if
904  !
905  ! -- right now these are options that are only available in the
906  ! development version and are not included in the documentation.
907  ! These options are only available when IDEVELOPMODE in
908  ! constants module is set to 1
909  case ('DEV_NO_FINAL_CHECK')
910  call this%parser%DevOpt()
911  this%iconvchk = 0
912  write (this%iout, '(4x,a)') &
913  'A FINAL CONVERGENCE CHECK OF THE CHANGE IN DELAY INTERBED '// &
914  'HEADS AND FLOWS WILL NOT BE MADE'
915 
916  !
917  ! default case
918  case default
919  write (errmsg, '(a,3(1x,a),a)') &
920  'Unknown', trim(adjustl(this%packName)), "option '", &
921  trim(keyword), "'."
922  call store_error(errmsg)
923  end select
924  end do
925  write (this%iout, '(1x,a)') &
926  'END OF '//trim(adjustl(this%packName))//' OPTIONS'
927  end if
928  !
929  ! -- write messages for options
930  write (this%iout, '(//2(1X,A))') trim(adjustl(this%packName)), &
931  'PACKAGE SETTINGS'
932  write (this%iout, fmtopti) 'NUMBER OF DELAY CELLS =', &
933  this%ndelaycells
934  if (this%lhead_based .EQV. .true.) then
935  write (this%iout, '(4x,a)') &
936  'HEAD-BASED FORMULATION'
937  else
938  write (this%iout, '(4x,a)') &
939  'EFFECTIVE-STRESS FORMULATION'
940  end if
941  if (this%istoragec == 0) then
942  write (this%iout, '(4x,a,1(/,6x,a))') &
943  'COMPRESSION INDICES WILL BE SPECIFIED INSTEAD OF ELASTIC AND', &
944  'INELASTIC SPECIFIC STORAGE COEFFICIENTS'
945  else
946  write (this%iout, '(4x,a,1(/,6x,a))') &
947  'ELASTIC AND INELASTIC SPECIFIC STORAGE COEFFICIENTS WILL BE ', &
948  'SPECIFIED'
949  end if
950  if (this%iupdatematprop /= 1) then
951  write (this%iout, '(4x,a,1(/,6x,a))') &
952  'THICKNESS AND VOID RATIO WILL NOT BE ADJUSTED DURING THE', &
953  'SIMULATION'
954  else
955  write (this%iout, '(4x,a)') &
956  'THICKNESS AND VOID RATIO WILL BE ADJUSTED DURING THE SIMULATION'
957  end if
958  if (this%icellf /= 1) then
959  write (this%iout, '(4x,a)') &
960  'INTERBED THICKNESS WILL BE SPECIFIED AS A THICKNESS'
961  else
962  write (this%iout, '(4x,a,1(/,6x,a))') &
963  'INTERBED THICKNESS WILL BE SPECIFIED AS A AS A CELL FRACTION'
964  end if
965  if (this%ispecified_pcs /= 1) then
966  if (this%ipch /= 0) then
967  write (this%iout, '(4x,a,1(/,6x,a))') &
968  'PRECONSOLIDATION HEAD WILL BE SPECIFIED RELATIVE TO INITIAL', &
969  'STRESS CONDITIONS'
970  else
971  write (this%iout, '(4x,a,1(/,6x,a))') &
972  'PRECONSOLIDATION STRESS WILL BE SPECIFIED RELATIVE TO INITIAL', &
973  'STRESS CONDITIONS'
974  end if
975  else
976  if (this%ipch /= 0) then
977  write (this%iout, '(4x,a,1(/,6x,a))') &
978  'PRECONSOLIDATION HEAD WILL BE SPECIFIED AS ABSOLUTE VALUES', &
979  'INSTEAD OF RELATIVE TO INITIAL HEAD CONDITIONS'
980  else
981  write (this%iout, '(4x,a,1(/,6x,a))') &
982  'PRECONSOLIDATION STRESS WILL BE SPECIFIED AS ABSOLUTE VALUES', &
983  'INSTEAD OF RELATIVE TO INITIAL STRESS CONDITIONS'
984  end if
985  end if
986  if (this%ispecified_dbh /= 1) then
987  write (this%iout, '(4x,a,1(/,6x,a))') &
988  'DELAY INTERBED HEADS WILL BE SPECIFIED RELATIVE TO INITIAL ', &
989  'GWF HEADS'
990  else
991  write (this%iout, '(4x,a,1(/,6x,a))') &
992  'DELAY INTERBED HEADS WILL BE SPECIFIED AS ABSOLUTE VALUES INSTEAD', &
993  'OF RELATIVE TO INITIAL GWF HEADS'
994  end if
995  !
996  ! -- process effective_stress_lag, if effective stress formulation
997  if (this%lhead_based .EQV. .false.) then
998  if (ieslag /= 0) then
999  write (this%iout, '(4x,a,1(/,6x,a))') &
1000  'SPECIFIC STORAGE VALUES WILL BE CALCULATED USING THE EFFECTIVE', &
1001  'STRESS FROM THE PREVIOUS TIME STEP'
1002  else
1003  write (this%iout, '(4x,a,1(/,6x,a))') &
1004  'SPECIFIC STORAGE VALUES WILL BE CALCULATED USING THE CURRENT', &
1005  'EFFECTIVE STRESS'
1006  end if
1007  else
1008  if (ieslag /= 0) then
1009  ieslag = 0
1010  write (this%iout, '(4x,a,2(/,6x,a))') &
1011  'EFFECTIVE_STRESS_LAG HAS BEEN SPECIFIED BUT HAS NO EFFECT WHEN', &
1012  'USING THE HEAD-BASED FORMULATION (HEAD_BASED HAS BEEN SPECIFIED', &
1013  'IN THE OPTIONS BLOCK)'
1014  end if
1015  end if
1016  this%ieslag = ieslag
1017  !
1018  ! -- recalculate BRG if necessary and output
1019  ! water compressibility values
1020  if (ibrg /= 0) then
1021  this%brg = this%gammaw * this%beta
1022  end if
1023  write (this%iout, fmtoptr) 'GAMMAW =', this%gammaw
1024  write (this%iout, fmtoptr) 'BETA =', this%beta
1025  write (this%iout, fmtoptr) 'GAMMAW * BETA =', this%brg
1026  !
1027  ! -- terminate if errors encountered in reach block
1028  if (count_errors() > 0) then
1029  call this%parser%StoreErrorUnit()
1030  end if
1031  end subroutine read_options
1032 
1033  !> @ brief Read dimensions for package
1034  !!
1035  !! Read the number of interbeds and maximum number of cells with a specified
1036  !! overlying geostatic stress.
1037  !!
1038  !<
1039  subroutine csub_read_dimensions(this)
1040  ! -- modules
1042  use kindmodule, only: i4b
1043  ! -- dummy variables
1044  class(gwfcsubtype), intent(inout) :: this
1045  ! -- local variables
1046  character(len=LENBOUNDNAME) :: keyword
1047  integer(I4B) :: ierr
1048  logical(LGP) :: isfound, endOfBlock
1049  ! -- format
1050  !
1051  ! -- initialize dimensions to -1
1052  this%ninterbeds = -1
1053  !
1054  ! -- get dimensions block
1055  call this%parser%GetBlock('DIMENSIONS', isfound, ierr, &
1056  supportopenclose=.true.)
1057  !
1058  ! -- parse dimensions block if detected
1059  if (isfound) then
1060  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%packName))// &
1061  ' DIMENSIONS'
1062  do
1063  call this%parser%GetNextLine(endofblock)
1064  if (endofblock) exit
1065  call this%parser%GetStringCaps(keyword)
1066  select case (keyword)
1067  case ('NINTERBEDS')
1068  this%ninterbeds = this%parser%GetInteger()
1069  write (this%iout, '(4x,a,i0)') 'NINTERBEDS = ', this%ninterbeds
1070  case ('MAXSIG0')
1071  this%maxsig0 = this%parser%GetInteger()
1072  write (this%iout, '(4x,a,i0)') 'MAXSIG0 = ', this%maxsig0
1073  case default
1074  write (errmsg, '(a,3(1x,a),a)') &
1075  'Unknown', trim(this%packName), "dimension '", trim(keyword), "'."
1076  call store_error(errmsg)
1077  end select
1078  end do
1079  write (this%iout, '(1x,a)') &
1080  'END OF '//trim(adjustl(this%packName))//' DIMENSIONS'
1081  else
1082  call store_error('Required dimensions block not found.')
1083  end if
1084  !
1085  ! -- verify dimensions were set correctly
1086  if (this%ninterbeds < 0) then
1087  write (errmsg, '(a)') &
1088  'NINTERBEDS was not specified or was specified incorrectly.'
1089  call store_error(errmsg)
1090  end if
1091  !
1092  ! -- stop if errors were encountered in the DIMENSIONS block
1093  if (count_errors() > 0) then
1094  call this%parser%StoreErrorUnit()
1095  end if
1096 
1097  ! -- Call define_listlabel to construct the list label that is written
1098  ! when PRINT_INPUT option is used.
1099  call this%define_listlabel()
1100  end subroutine csub_read_dimensions
1101 
1102  !> @ brief Allocate scalars
1103  !!
1104  !! Allocate and initialize scalars for the CSUB package. The base model
1105  !! allocate scalars method is also called.
1106  !!
1107  !<
1108  subroutine csub_allocate_scalars(this)
1109  ! -- modules
1111  ! -- dummy variables
1112  class(gwfcsubtype), intent(inout) :: this
1113  !
1114  ! -- call standard NumericalPackageType allocate scalars
1115  call this%NumericalPackageType%allocate_scalars()
1116  !
1117  ! -- allocate character variables
1118  call mem_allocate(this%listlabel, lenlistlabel, 'LISTLABEL', this%memoryPath)
1119  call mem_allocate(this%stoMemPath, lenmempath, 'STONAME', this%memoryPath)
1120  !
1121  ! -- allocate the object and assign values to object variables
1122  call mem_allocate(this%istounit, 'ISTOUNIT', this%memoryPath)
1123  call mem_allocate(this%inobspkg, 'INOBSPKG', this%memoryPath)
1124  call mem_allocate(this%ninterbeds, 'NINTERBEDS', this%memoryPath)
1125  call mem_allocate(this%maxsig0, 'MAXSIG0', this%memoryPath)
1126  call mem_allocate(this%nbound, 'NBOUND', this%memoryPath)
1127  call mem_allocate(this%iscloc, 'ISCLOC', this%memoryPath)
1128  call mem_allocate(this%iauxmultcol, 'IAUXMULTCOL', this%memoryPath)
1129  call mem_allocate(this%ndelaycells, 'NDELAYCELLS', this%memoryPath)
1130  call mem_allocate(this%ndelaybeds, 'NDELAYBEDS', this%memoryPath)
1131  call mem_allocate(this%initialized, 'INITIALIZED', this%memoryPath)
1132  call mem_allocate(this%ieslag, 'IESLAG', this%memoryPath)
1133  call mem_allocate(this%ipch, 'IPCH', this%memoryPath)
1134  call mem_allocate(this%lhead_based, 'LHEAD_BASED', this%memoryPath)
1135  call mem_allocate(this%iupdatestress, 'IUPDATESTRESS', this%memoryPath)
1136  call mem_allocate(this%ispecified_pcs, 'ISPECIFIED_PCS', this%memoryPath)
1137  call mem_allocate(this%ispecified_dbh, 'ISPECIFIED_DBH', this%memoryPath)
1138  call mem_allocate(this%inamedbound, 'INAMEDBOUND', this%memoryPath)
1139  call mem_allocate(this%iconvchk, 'ICONVCHK', this%memoryPath)
1140  call mem_allocate(this%naux, 'NAUX', this%memoryPath)
1141  call mem_allocate(this%istoragec, 'ISTORAGEC', this%memoryPath)
1142  call mem_allocate(this%istrainib, 'ISTRAINIB', this%memoryPath)
1143  call mem_allocate(this%istrainsk, 'ISTRAINSK', this%memoryPath)
1144  call mem_allocate(this%ioutcomp, 'IOUTCOMP', this%memoryPath)
1145  call mem_allocate(this%ioutcompi, 'IOUTCOMPI', this%memoryPath)
1146  call mem_allocate(this%ioutcompe, 'IOUTCOMPE', this%memoryPath)
1147  call mem_allocate(this%ioutcompib, 'IOUTCOMPIB', this%memoryPath)
1148  call mem_allocate(this%ioutcomps, 'IOUTCOMPS', this%memoryPath)
1149  call mem_allocate(this%ioutzdisp, 'IOUTZDISP', this%memoryPath)
1150  call mem_allocate(this%ipakcsv, 'IPAKCSV', this%memoryPath)
1151  call mem_allocate(this%iupdatematprop, 'IUPDATEMATPROP', this%memoryPath)
1152  call mem_allocate(this%epsilon, 'EPSILON', this%memoryPath)
1153  call mem_allocate(this%cc_crit, 'CC_CRIT', this%memoryPath)
1154  call mem_allocate(this%gammaw, 'GAMMAW', this%memoryPath)
1155  call mem_allocate(this%beta, 'BETA', this%memoryPath)
1156  call mem_allocate(this%brg, 'BRG', this%memoryPath)
1157  call mem_allocate(this%satomega, 'SATOMEGA', this%memoryPath)
1158  call mem_allocate(this%icellf, 'ICELLF', this%memoryPath)
1159  call mem_allocate(this%gwfiss0, 'GWFISS0', this%memoryPath)
1160  !
1161  ! -- allocate TS object
1162  allocate (this%TsManager)
1163  !
1164  ! -- allocate text strings
1165  call mem_allocate(this%auxname, lenauxname, 0, 'AUXNAME', this%memoryPath)
1166  !
1167  ! -- initialize values
1168  this%istounit = 0
1169  this%inobspkg = 0
1170  this%ninterbeds = 0
1171  this%maxsig0 = 0
1172  this%nbound = 0
1173  this%iscloc = 0
1174  this%iauxmultcol = 0
1175  this%ndelaycells = 19
1176  this%ndelaybeds = 0
1177  this%initialized = 0
1178  this%ieslag = 0
1179  this%ipch = 0
1180  this%lhead_based = .false.
1181  this%iupdatestress = 1
1182  this%ispecified_pcs = 0
1183  this%ispecified_dbh = 0
1184  this%inamedbound = 0
1185  this%iconvchk = 1
1186  this%naux = 0
1187  this%istoragec = 1
1188  this%istrainib = 0
1189  this%istrainsk = 0
1190  this%ioutcomp = 0
1191  this%ioutcompi = 0
1192  this%ioutcompe = 0
1193  this%ioutcompib = 0
1194  this%ioutcomps = 0
1195  this%ioutzdisp = 0
1196  this%ipakcsv = 0
1197  this%iupdatematprop = 0
1198  this%epsilon = dzero
1199  this%cc_crit = dem7
1200  this%gammaw = dgravity * 1000._dp
1201  this%beta = 4.6512e-10_dp
1202  this%brg = this%gammaw * this%beta
1203  !
1204  ! -- set omega value used for saturation calculations
1205  if (this%inewton /= 0) then
1206  this%satomega = dem6
1207  this%epsilon = dhalf * dem6
1208  else
1209  this%satomega = dzero
1210  end if
1211  this%icellf = 0
1212  this%ninterbeds = 0
1213  this%gwfiss0 = 0
1214  end subroutine csub_allocate_scalars
1215 
1216  !> @ brief Allocate package arrays
1217  !!
1218  !! Allocate and initialize CSUB package arrays.
1219  !!
1220  !<
1221  subroutine csub_allocate_arrays(this)
1222  ! -- modules
1224  ! -- dummy variables
1225  class(gwfcsubtype), intent(inout) :: this
1226  ! -- local variables
1227  integer(I4B) :: j
1228  integer(I4B) :: n
1229  integer(I4B) :: iblen
1230  integer(I4B) :: ilen
1231  integer(I4B) :: naux
1232  !
1233  ! -- grid based data
1234  if (this%ioutcomp == 0 .and. this%ioutcompi == 0 .and. &
1235  this%ioutcompe == 0 .and. this%ioutcompib == 0 .and. &
1236  this%ioutcomps == 0 .and. this%ioutzdisp == 0) then
1237  call mem_allocate(this%buff, 1, 'BUFF', trim(this%memoryPath))
1238  else
1239  call mem_allocate(this%buff, this%dis%nodes, 'BUFF', trim(this%memoryPath))
1240  end if
1241  if (this%ioutcomp == 0 .and. this%ioutzdisp == 0) then
1242  call mem_allocate(this%buffusr, 1, 'BUFFUSR', trim(this%memoryPath))
1243  else
1244  call mem_allocate(this%buffusr, this%dis%nodesuser, 'BUFFUSR', &
1245  trim(this%memoryPath))
1246  end if
1247  call mem_allocate(this%sgm, this%dis%nodes, 'SGM', trim(this%memoryPath))
1248  call mem_allocate(this%sgs, this%dis%nodes, 'SGS', trim(this%memoryPath))
1249  call mem_allocate(this%cg_ske_cr, this%dis%nodes, 'CG_SKE_CR', &
1250  trim(this%memoryPath))
1251  call mem_allocate(this%cg_es, this%dis%nodes, 'CG_ES', &
1252  trim(this%memoryPath))
1253  call mem_allocate(this%cg_es0, this%dis%nodes, 'CG_ES0', &
1254  trim(this%memoryPath))
1255  call mem_allocate(this%cg_pcs, this%dis%nodes, 'CG_PCS', &
1256  trim(this%memoryPath))
1257  call mem_allocate(this%cg_comp, this%dis%nodes, 'CG_COMP', &
1258  trim(this%memoryPath))
1259  call mem_allocate(this%cg_tcomp, this%dis%nodes, 'CG_TCOMP', &
1260  trim(this%memoryPath))
1261  call mem_allocate(this%cg_stor, this%dis%nodes, 'CG_STOR', &
1262  trim(this%memoryPath))
1263  call mem_allocate(this%cg_ske, this%dis%nodes, 'CG_SKE', &
1264  trim(this%memoryPath))
1265  call mem_allocate(this%cg_sk, this%dis%nodes, 'CG_SK', &
1266  trim(this%memoryPath))
1267  call mem_allocate(this%cg_thickini, this%dis%nodes, 'CG_THICKINI', &
1268  trim(this%memoryPath))
1269  call mem_allocate(this%cg_thetaini, this%dis%nodes, 'CG_THETAINI', &
1270  trim(this%memoryPath))
1271  if (this%iupdatematprop == 0) then
1272  call mem_setptr(this%cg_thick, 'CG_THICKINI', trim(this%memoryPath))
1273  call mem_setptr(this%cg_thick0, 'CG_THICKINI', trim(this%memoryPath))
1274  call mem_setptr(this%cg_theta, 'CG_THETAINI', trim(this%memoryPath))
1275  call mem_setptr(this%cg_theta0, 'CG_THETAINI', trim(this%memoryPath))
1276  else
1277  call mem_allocate(this%cg_thick, this%dis%nodes, 'CG_THICK', &
1278  trim(this%memoryPath))
1279  call mem_allocate(this%cg_thick0, this%dis%nodes, 'CG_THICK0', &
1280  trim(this%memoryPath))
1281  call mem_allocate(this%cg_theta, this%dis%nodes, 'CG_THETA', &
1282  trim(this%memoryPath))
1283  call mem_allocate(this%cg_theta0, this%dis%nodes, 'CG_THETA0', &
1284  trim(this%memoryPath))
1285  end if
1286  !
1287  ! -- cell storage data
1288  call mem_allocate(this%cell_wcstor, this%dis%nodes, 'CELL_WCSTOR', &
1289  trim(this%memoryPath))
1290  call mem_allocate(this%cell_thick, this%dis%nodes, 'CELL_THICK', &
1291  trim(this%memoryPath))
1292  !
1293  ! -- interbed data
1294  iblen = 1
1295  if (this%ninterbeds > 0) then
1296  iblen = this%ninterbeds
1297  end if
1298  naux = 1
1299  if (this%naux > 0) then
1300  naux = this%naux
1301  end if
1302  call mem_allocate(this%auxvar, naux, iblen, 'AUXVAR', this%memoryPath)
1303  do n = 1, iblen
1304  do j = 1, naux
1305  this%auxvar(j, n) = dzero
1306  end do
1307  end do
1308  call mem_allocate(this%unodelist, iblen, 'UNODELIST', trim(this%memoryPath))
1309  call mem_allocate(this%nodelist, iblen, 'NODELIST', trim(this%memoryPath))
1310  call mem_allocate(this%cg_gs, this%dis%nodes, 'CG_GS', trim(this%memoryPath))
1311  call mem_allocate(this%pcs, iblen, 'PCS', trim(this%memoryPath))
1312  call mem_allocate(this%rnb, iblen, 'RNB', trim(this%memoryPath))
1313  call mem_allocate(this%kv, iblen, 'KV', trim(this%memoryPath))
1314  call mem_allocate(this%h0, iblen, 'H0', trim(this%memoryPath))
1315  call mem_allocate(this%ci, iblen, 'CI', trim(this%memoryPath))
1316  call mem_allocate(this%rci, iblen, 'RCI', trim(this%memoryPath))
1317  call mem_allocate(this%idelay, iblen, 'IDELAY', trim(this%memoryPath))
1318  call mem_allocate(this%ielastic, iblen, 'IELASTIC', trim(this%memoryPath))
1319  call mem_allocate(this%iconvert, iblen, 'ICONVERT', trim(this%memoryPath))
1320  call mem_allocate(this%comp, iblen, 'COMP', trim(this%memoryPath))
1321  call mem_allocate(this%tcomp, iblen, 'TCOMP', trim(this%memoryPath))
1322  call mem_allocate(this%tcompi, iblen, 'TCOMPI', trim(this%memoryPath))
1323  call mem_allocate(this%tcompe, iblen, 'TCOMPE', trim(this%memoryPath))
1324  call mem_allocate(this%storagee, iblen, 'STORAGEE', trim(this%memoryPath))
1325  call mem_allocate(this%storagei, iblen, 'STORAGEI', trim(this%memoryPath))
1326  call mem_allocate(this%ske, iblen, 'SKE', trim(this%memoryPath))
1327  call mem_allocate(this%sk, iblen, 'SK', trim(this%memoryPath))
1328  call mem_allocate(this%thickini, iblen, 'THICKINI', trim(this%memoryPath))
1329  call mem_allocate(this%thetaini, iblen, 'THETAINI', trim(this%memoryPath))
1330  if (this%iupdatematprop == 0) then
1331  call mem_setptr(this%thick, 'THICKINI', trim(this%memoryPath))
1332  call mem_setptr(this%thick0, 'THICKINI', trim(this%memoryPath))
1333  call mem_setptr(this%theta, 'THETAINI', trim(this%memoryPath))
1334  call mem_setptr(this%theta0, 'THETAINI', trim(this%memoryPath))
1335  else
1336  call mem_allocate(this%thick, iblen, 'THICK', trim(this%memoryPath))
1337  call mem_allocate(this%thick0, iblen, 'THICK0', trim(this%memoryPath))
1338  call mem_allocate(this%theta, iblen, 'THETA', trim(this%memoryPath))
1339  call mem_allocate(this%theta0, iblen, 'THETA0', trim(this%memoryPath))
1340  end if
1341  !
1342  ! -- delay bed storage - allocated in csub_read_packagedata
1343  ! after number of delay beds is defined
1344  !
1345  ! -- allocate boundname
1346  if (this%inamedbound /= 0) then
1347  call mem_allocate(this%boundname, lenboundname, this%ninterbeds, &
1348  'BOUNDNAME', trim(this%memoryPath))
1349  else
1350  call mem_allocate(this%boundname, lenboundname, 1, &
1351  'BOUNDNAME', trim(this%memoryPath))
1352 
1353  end if
1354  !
1355  ! -- allocate the nodelist and bound arrays
1356  if (this%maxsig0 > 0) then
1357  ilen = this%maxsig0
1358  else
1359  ilen = 1
1360  end if
1361  call mem_allocate(this%nodelistsig0, ilen, 'NODELISTSIG0', this%memoryPath)
1362  call mem_allocate(this%sig0, ilen, 'SIG0', this%memoryPath)
1363  !
1364  ! -- set pointers to gwf variables
1365  call mem_setptr(this%gwfiss, 'ISS', trim(this%name_model))
1366  !
1367  ! -- set pointers to variables in the storage package
1368  call mem_setptr(this%stoiconv, 'ICONVERT', this%stoMemPath)
1369  call mem_setptr(this%stoss, 'SS', this%stoMemPath)
1370  !
1371  ! -- initialize variables that are not specified by user
1372  do n = 1, this%dis%nodes
1373  this%cg_gs(n) = dzero
1374  this%cg_es(n) = dzero
1375  this%cg_comp(n) = dzero
1376  this%cg_tcomp(n) = dzero
1377  this%cell_wcstor(n) = dzero
1378  end do
1379  do n = 1, this%ninterbeds
1380  this%theta(n) = dzero
1381  this%tcomp(n) = dzero
1382  this%tcompi(n) = dzero
1383  this%tcompe(n) = dzero
1384  end do
1385  do n = 1, max(1, this%maxsig0)
1386  this%nodelistsig0(n) = 0
1387  this%sig0(n) = dzero
1388  end do
1389  end subroutine csub_allocate_arrays
1390 
1391  !> @ brief Read packagedata for package
1392  !!
1393  !! Read delay and no-delay interbed input data for the CSUB package. Method
1394  !! also validates interbed input data.
1395  !!
1396  !<
1397  subroutine csub_read_packagedata(this)
1398  ! -- modules
1399  use constantsmodule, only: linelength
1401  ! -- dummy variables
1402  class(gwfcsubtype), intent(inout) :: this
1403  ! -- local variables
1404  character(len=LINELENGTH) :: cellid
1405  character(len=LINELENGTH) :: title
1406  character(len=LINELENGTH) :: tag
1407  character(len=20) :: scellid
1408  character(len=10) :: text
1409  character(len=LENBOUNDNAME) :: bndName
1410  character(len=7) :: cdelay
1411  logical(LGP) :: isfound
1412  logical(LGP) :: endOfBlock
1413  integer(I4B) :: ival
1414  integer(I4B) :: n
1415  integer(I4B) :: nn
1416  integer(I4B) :: ib
1417  integer(I4B) :: itmp
1418  integer(I4B) :: ierr
1419  integer(I4B) :: ndelaybeds
1420  integer(I4B) :: idelay
1421  integer(I4B) :: ntabrows
1422  integer(I4B) :: ntabcols
1423  real(DP) :: rval
1424  real(DP) :: top
1425  real(DP) :: bot
1426  real(DP) :: baq
1427  real(DP) :: q
1428  integer, allocatable, dimension(:) :: nboundchk
1429  !
1430  ! -- initialize temporary variables
1431  ndelaybeds = 0
1432  !
1433  ! -- allocate temporary arrays
1434  allocate (nboundchk(this%ninterbeds))
1435  do n = 1, this%ninterbeds
1436  nboundchk(n) = 0
1437  end do
1438  !
1439  call this%parser%GetBlock('PACKAGEDATA', isfound, ierr, &
1440  supportopenclose=.true.)
1441  !
1442  ! -- parse locations block if detected
1443  if (isfound) then
1444  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%packName))// &
1445  ' PACKAGEDATA'
1446  do
1447  call this%parser%GetNextLine(endofblock)
1448  if (endofblock) then
1449  exit
1450  end if
1451  !
1452  ! -- get interbed number
1453  itmp = this%parser%GetInteger()
1454  !
1455  ! -- check for error condition
1456  if (itmp < 1 .or. itmp > this%ninterbeds) then
1457  write (errmsg, '(a,1x,i0,2(1x,a),1x,i0,a)') &
1458  'Interbed number (', itmp, ') must be greater than 0 and ', &
1459  'less than or equal to', this%ninterbeds, '.'
1460  call store_error(errmsg)
1461  cycle
1462  end if
1463  !
1464  ! -- increment nboundchk
1465  nboundchk(itmp) = nboundchk(itmp) + 1
1466  !
1467  ! -- read cellid
1468  call this%parser%GetCellid(this%dis%ndim, cellid)
1469  nn = this%dis%noder_from_cellid(cellid, &
1470  this%parser%iuactive, this%iout)
1471  n = this%dis%nodeu_from_cellid(cellid, &
1472  this%parser%iuactive, this%iout)
1473  top = this%dis%top(nn)
1474  bot = this%dis%bot(nn)
1475  baq = top - bot
1476  !
1477  ! -- determine if a valid cell location was provided
1478  if (nn < 1) then
1479  write (errmsg, '(a,1x,i0,a)') &
1480  'Invalid cellid for packagedata entry', itmp, '.'
1481  call store_error(errmsg)
1482  end if
1483  !
1484  ! -- set nodelist and unodelist
1485  this%nodelist(itmp) = nn
1486  this%unodelist(itmp) = n
1487  !
1488  ! -- get cdelay
1489  call this%parser%GetStringCaps(cdelay)
1490  select case (cdelay)
1491  case ('NODELAY')
1492  ival = 0
1493  case ('DELAY')
1494  ndelaybeds = ndelaybeds + 1
1495  ival = ndelaybeds
1496  case default
1497  write (errmsg, '(a,1x,a,1x,i0,1x,a)') &
1498  'Invalid CDELAY ', trim(adjustl(cdelay)), &
1499  'for packagedata entry', itmp, '.'
1500  call store_error(errmsg)
1501  cycle
1502  end select
1503  idelay = ival
1504  this%idelay(itmp) = ival
1505  !
1506  ! -- get initial preconsolidation stress
1507  this%pcs(itmp) = this%parser%GetDouble()
1508  !
1509  ! -- get thickness or cell fraction
1510  rval = this%parser%GetDouble()
1511  if (this%icellf == 0) then
1512  if (rval < dzero .or. rval > baq) then
1513  write (errmsg, '(a,g0,2(a,1x),g0,1x,a,1x,i0,a)') &
1514  'THICK (', rval, ') MUST BE greater than or equal to 0 ', &
1515  'and less than or equal to than', baq, &
1516  'for packagedata entry', itmp, '.'
1517  call store_error(errmsg)
1518  end if
1519  else
1520  if (rval < dzero .or. rval > done) then
1521  write (errmsg, '(a,1x,a,1x,i0,a)') &
1522  'FRAC MUST BE greater than 0 and less than or equal to 1', &
1523  'for packagedata entry', itmp, '.'
1524  call store_error(errmsg)
1525  end if
1526  rval = rval * baq
1527  end if
1528  this%thickini(itmp) = rval
1529  if (this%iupdatematprop /= 0) then
1530  this%thick(itmp) = rval
1531  end if
1532  !
1533  ! -- get rnb
1534  rval = this%parser%GetDouble()
1535  if (idelay > 0) then
1536  if (rval < done) then
1537  write (errmsg, '(a,g0,a,1x,a,1x,i0,a)') &
1538  'RNB (', rval, ') must be greater than or equal to 1', &
1539  'for packagedata entry', itmp, '.'
1540  call store_error(errmsg)
1541  end if
1542  else
1543  rval = done
1544  end if
1545  this%rnb(itmp) = rval
1546  !
1547  ! -- get skv or ci
1548  rval = this%parser%GetDouble()
1549  if (rval < dzero) then
1550  write (errmsg, '(2(a,1x),i0,a)') &
1551  '(SKV,CI) must be greater than or equal to 0', &
1552  'for packagedata entry', itmp, '.'
1553  call store_error(errmsg)
1554  end if
1555  this%ci(itmp) = rval
1556  !
1557  ! -- get ske or rci
1558  rval = this%parser%GetDouble()
1559  if (rval < dzero) then
1560  write (errmsg, '(2(a,1x),i0,a)') &
1561  '(SKE,RCI) must be greater than or equal to 0', &
1562  'for packagedata entry', itmp, '.'
1563  call store_error(errmsg)
1564  end if
1565  this%rci(itmp) = rval
1566  !
1567  ! -- set ielastic
1568  if (this%ci(itmp) == this%rci(itmp)) then
1569  this%ielastic(itmp) = 1
1570  else
1571  this%ielastic(itmp) = 0
1572  end if
1573  !
1574  ! -- get porosity
1575  rval = this%parser%GetDouble()
1576  this%thetaini(itmp) = rval
1577  if (this%iupdatematprop /= 0) then
1578  this%theta(itmp) = rval
1579  end if
1580  if (rval <= dzero .or. rval > done) then
1581  write (errmsg, '(a,1x,a,1x,i0,a)') &
1582  'THETA must be greater than 0 and less than or equal to 1', &
1583  'for packagedata entry', itmp, '.'
1584  call store_error(errmsg)
1585  end if
1586  !
1587  ! -- get kv
1588  rval = this%parser%GetDouble()
1589  if (idelay > 0) then
1590  if (rval <= 0.0) then
1591  write (errmsg, '(a,1x,i0,a)') &
1592  'KV must be greater than 0 for packagedata entry', itmp, '.'
1593  call store_error(errmsg)
1594  end if
1595  end if
1596  this%kv(itmp) = rval
1597  !
1598  ! -- get h0
1599  rval = this%parser%GetDouble()
1600  this%h0(itmp) = rval
1601  !
1602  ! -- get bound names
1603  if (this%inamedbound /= 0) then
1604  call this%parser%GetStringCaps(bndname)
1605  if (len_trim(bndname) < 1) then
1606  write (errmsg, '(a,1x,i0,a)') &
1607  'BOUNDNAME must be specified for packagedata entry', itmp, '.'
1608  call store_error(errmsg)
1609  else
1610  this%boundname(itmp) = bndname
1611  end if
1612  end if
1613  end do
1614 
1615  write (this%iout, '(1x,a)') &
1616  'END OF '//trim(adjustl(this%packName))//' PACKAGEDATA'
1617  end if
1618  !
1619  ! -- write summary of interbed data
1620  if (this%iprpak == 1) then
1621  ! -- set title
1622  title = trim(adjustl(this%packName))//' PACKAGE INTERBED DATA'
1623  !
1624  ! -- determine the number of columns and rows
1625  ntabrows = this%ninterbeds
1626  ntabcols = 11
1627  if (this%inamedbound /= 0) then
1628  ntabcols = ntabcols + 1
1629  end if
1630  !
1631  ! -- setup table
1632  call table_cr(this%inputtab, this%packName, title)
1633  call this%inputtab%table_df(ntabrows, ntabcols, this%iout)
1634  !
1635  ! add columns
1636  tag = 'INTERBED'
1637  call this%inputtab%initialize_column(tag, 10, alignment=tableft)
1638  tag = 'CELLID'
1639  call this%inputtab%initialize_column(tag, 20, alignment=tabcenter)
1640  tag = 'CDELAY'
1641  call this%inputtab%initialize_column(tag, 10, alignment=tabcenter)
1642  tag = 'PCS'
1643  call this%inputtab%initialize_column(tag, 10, alignment=tabcenter)
1644  tag = 'THICK'
1645  call this%inputtab%initialize_column(tag, 10, alignment=tabcenter)
1646  tag = 'RNB'
1647  call this%inputtab%initialize_column(tag, 10, alignment=tabcenter)
1648  tag = 'SSV_CC'
1649  call this%inputtab%initialize_column(tag, 10, alignment=tabcenter)
1650  tag = 'SSV_CR'
1651  call this%inputtab%initialize_column(tag, 10, alignment=tabcenter)
1652  tag = 'THETA'
1653  call this%inputtab%initialize_column(tag, 10, alignment=tabcenter)
1654  tag = 'KV'
1655  call this%inputtab%initialize_column(tag, 10, alignment=tabcenter)
1656  tag = 'H0'
1657  call this%inputtab%initialize_column(tag, 10, alignment=tabcenter)
1658  if (this%inamedbound /= 0) then
1659  tag = 'BOUNDNAME'
1660  call this%inputtab%initialize_column(tag, lenboundname, &
1661  alignment=tableft)
1662  end if
1663  !
1664  ! -- write the data
1665  do ib = 1, this%ninterbeds
1666  call this%dis%noder_to_string(this%nodelist(ib), scellid)
1667  if (this%idelay(ib) == 0) then
1668  text = 'NODELAY'
1669  else
1670  text = 'DELAY'
1671  end if
1672  call this%inputtab%add_term(ib)
1673  call this%inputtab%add_term(scellid)
1674  call this%inputtab%add_term(text)
1675  call this%inputtab%add_term(this%pcs(ib))
1676  call this%inputtab%add_term(this%thickini(ib))
1677  call this%inputtab%add_term(this%rnb(ib))
1678  call this%inputtab%add_term(this%ci(ib))
1679  call this%inputtab%add_term(this%rci(ib))
1680  call this%inputtab%add_term(this%thetaini(ib))
1681  if (this%idelay(ib) == 0) then
1682  call this%inputtab%add_term('-')
1683  call this%inputtab%add_term('-')
1684  else
1685  call this%inputtab%add_term(this%kv(ib))
1686  call this%inputtab%add_term(this%h0(ib))
1687  end if
1688  if (this%inamedbound /= 0) then
1689  call this%inputtab%add_term(this%boundname(ib))
1690  end if
1691  end do
1692  end if
1693  !
1694  ! -- Check to make sure that every interbed is specified and that no
1695  ! interbed is specified more than once.
1696  do ib = 1, this%ninterbeds
1697  if (nboundchk(ib) == 0) then
1698  write (errmsg, '(a,1x,i0,a)') &
1699  'Information for interbed', ib, 'not specified in packagedata block.'
1700  call store_error(errmsg)
1701  else if (nboundchk(ib) > 1) then
1702  write (errmsg, '(2(a,1x,i0),a)') &
1703  'Information specified', nboundchk(ib), 'times for interbed', ib, '.'
1704  call store_error(errmsg)
1705  end if
1706  end do
1707  deallocate (nboundchk)
1708  !
1709  ! -- set the number of delay interbeds
1710  this%ndelaybeds = ndelaybeds
1711  !
1712  ! -- process delay interbeds
1713  if (ndelaybeds > 0) then
1714  !
1715  ! -- reallocate and initialize delay interbed arrays
1716  if (ierr == 0) then
1717  call mem_allocate(this%idb_nconv_count, 2, &
1718  'IDB_NCONV_COUNT', trim(this%memoryPath))
1719  call mem_allocate(this%idbconvert, this%ndelaycells, ndelaybeds, &
1720  'IDBCONVERT', trim(this%memoryPath))
1721  call mem_allocate(this%dbdhmax, ndelaybeds, &
1722  'DBDHMAX', trim(this%memoryPath))
1723  call mem_allocate(this%dbz, this%ndelaycells, ndelaybeds, &
1724  'DBZ', trim(this%memoryPath))
1725  call mem_allocate(this%dbrelz, this%ndelaycells, ndelaybeds, &
1726  'DBRELZ', trim(this%memoryPath))
1727  call mem_allocate(this%dbh, this%ndelaycells, ndelaybeds, &
1728  'DBH', trim(this%memoryPath))
1729  call mem_allocate(this%dbh0, this%ndelaycells, ndelaybeds, &
1730  'DBH0', trim(this%memoryPath))
1731  call mem_allocate(this%dbgeo, this%ndelaycells, ndelaybeds, &
1732  'DBGEO', trim(this%memoryPath))
1733  call mem_allocate(this%dbes, this%ndelaycells, ndelaybeds, &
1734  'DBES', trim(this%memoryPath))
1735  call mem_allocate(this%dbes0, this%ndelaycells, ndelaybeds, &
1736  'DBES0', trim(this%memoryPath))
1737  call mem_allocate(this%dbpcs, this%ndelaycells, ndelaybeds, &
1738  'DBPCS', trim(this%memoryPath))
1739  call mem_allocate(this%dbflowtop, ndelaybeds, &
1740  'DBFLOWTOP', trim(this%memoryPath))
1741  call mem_allocate(this%dbflowbot, ndelaybeds, &
1742  'DBFLOWBOT', trim(this%memoryPath))
1743  call mem_allocate(this%dbdzini, this%ndelaycells, ndelaybeds, &
1744  'DBDZINI', trim(this%memoryPath))
1745  call mem_allocate(this%dbthetaini, this%ndelaycells, ndelaybeds, &
1746  'DBTHETAINI', trim(this%memoryPath))
1747  call mem_allocate(this%dbcomp, this%ndelaycells, ndelaybeds, &
1748  'DBCOMP', trim(this%memoryPath))
1749  call mem_allocate(this%dbtcomp, this%ndelaycells, ndelaybeds, &
1750  'DBTCOMP', trim(this%memoryPath))
1751  !
1752  ! -- allocate delay bed arrays
1753  if (this%iupdatematprop == 0) then
1754  call mem_setptr(this%dbdz, 'DBDZINI', trim(this%memoryPath))
1755  call mem_setptr(this%dbdz0, 'DBDZINI', trim(this%memoryPath))
1756  call mem_setptr(this%dbtheta, 'DBTHETAINI', trim(this%memoryPath))
1757  call mem_setptr(this%dbtheta0, 'DBTHETAINI', trim(this%memoryPath))
1758  else
1759  call mem_allocate(this%dbdz, this%ndelaycells, ndelaybeds, &
1760  'DBDZ', trim(this%memoryPath))
1761  call mem_allocate(this%dbdz0, this%ndelaycells, ndelaybeds, &
1762  'DBDZ0', trim(this%memoryPath))
1763  call mem_allocate(this%dbtheta, this%ndelaycells, ndelaybeds, &
1764  'DBTHETA', trim(this%memoryPath))
1765  call mem_allocate(this%dbtheta0, this%ndelaycells, ndelaybeds, &
1766  'DBTHETA0', trim(this%memoryPath))
1767  end if
1768  !
1769  ! -- allocate delay interbed solution arrays
1770  call mem_allocate(this%dbal, this%ndelaycells, &
1771  'DBAL', trim(this%memoryPath))
1772  call mem_allocate(this%dbad, this%ndelaycells, &
1773  'DBAD', trim(this%memoryPath))
1774  call mem_allocate(this%dbau, this%ndelaycells, &
1775  'DBAU', trim(this%memoryPath))
1776  call mem_allocate(this%dbrhs, this%ndelaycells, &
1777  'DBRHS', trim(this%memoryPath))
1778  call mem_allocate(this%dbdh, this%ndelaycells, &
1779  'DBDH', trim(this%memoryPath))
1780  call mem_allocate(this%dbaw, this%ndelaycells, &
1781  'DBAW', trim(this%memoryPath))
1782  !
1783  ! -- initialize delay bed counters
1784  do n = 1, 2
1785  this%idb_nconv_count(n) = 0
1786  end do
1787  !
1788  ! -- initialize delay bed storage
1789  do ib = 1, this%ninterbeds
1790  idelay = this%idelay(ib)
1791  if (idelay == 0) then
1792  cycle
1793  end if
1794  !
1795  ! -- initialize delay interbed variables
1796  do n = 1, this%ndelaycells
1797  rval = this%thickini(ib) / real(this%ndelaycells, dp)
1798  this%dbdzini(n, idelay) = rval
1799  this%dbh(n, idelay) = this%h0(ib)
1800  this%dbh0(n, idelay) = this%h0(ib)
1801  this%dbthetaini(n, idelay) = this%thetaini(ib)
1802  this%dbgeo(n, idelay) = dzero
1803  this%dbes(n, idelay) = dzero
1804  this%dbes0(n, idelay) = dzero
1805  this%dbpcs(n, idelay) = this%pcs(ib)
1806  this%dbcomp(n, idelay) = dzero
1807  this%dbtcomp(n, idelay) = dzero
1808  if (this%iupdatematprop /= 0) then
1809  this%dbdz(n, idelay) = this%dbdzini(n, idelay)
1810  this%dbdz0(n, idelay) = this%dbdzini(n, idelay)
1811  this%dbtheta(n, idelay) = this%theta(ib)
1812  this%dbtheta0(n, idelay) = this%theta(ib)
1813  end if
1814  end do
1815  !
1816  ! -- initialize elevation of delay bed cells
1817  call this%csub_delay_init_zcell(ib)
1818  end do
1819  !
1820  ! -- initialize delay bed solution arrays
1821  do n = 1, this%ndelaycells
1822  this%dbal(n) = dzero
1823  this%dbad(n) = dzero
1824  this%dbau(n) = dzero
1825  this%dbrhs(n) = dzero
1826  this%dbdh(n) = dzero
1827  this%dbaw(n) = dzero
1828  end do
1829  end if
1830  end if
1831  !
1832  ! -- check that ndelaycells is odd when using
1833  ! the effective stress formulation
1834  if (ndelaybeds > 0) then
1835  q = mod(real(this%ndelaycells, dp), dtwo)
1836  if (q == dzero) then
1837  write (errmsg, '(a,i0,a,1x,a)') &
1838  'NDELAYCELLS (', this%ndelaycells, ') must be an', &
1839  'odd number when using the effective stress formulation.'
1840  call store_error(errmsg)
1841  end if
1842  end if
1843  end subroutine csub_read_packagedata
1844 
1845  !> @ brief Final processing for package
1846  !!
1847  !! Final processing for the CSUB package. This method generates the final
1848  !! strain tables that are output so that the user can evaluate if calculated
1849  !! strain rates in coarse-grained sediments and interbeds exceed 1 percent.
1850  !!
1851  !<
1852  subroutine csub_fp(this)
1853  ! -- dummy variables
1854  class(gwfcsubtype) :: this
1855  ! -- local variables
1856  character(len=LINELENGTH) :: title
1857  character(len=LINELENGTH) :: tag
1858  character(len=LINELENGTH) :: msg
1859  character(len=10) :: ctype
1860  character(len=20) :: cellid
1861  character(len=10) :: cflag
1862  integer(I4B) :: i
1863  integer(I4B) :: ib
1864  integer(I4B) :: i0
1865  integer(I4B) :: i1
1866  integer(I4B) :: node
1867  integer(I4B) :: nn
1868  integer(I4B) :: idelay
1869  integer(I4B) :: iexceed
1870  integer(I4B), parameter :: ncells = 20
1871  integer(I4B) :: nlen
1872  integer(I4B) :: ntabrows
1873  integer(I4B) :: ntabcols
1874  integer(I4B) :: ipos
1875  real(DP) :: b0
1876  real(DP) :: b1
1877  real(DP) :: strain
1878  real(DP) :: pctcomp
1879  integer(I4B), dimension(:), allocatable :: imap_sel
1880  integer(I4B), dimension(:), allocatable :: locs
1881  real(DP), dimension(:), allocatable :: pctcomp_arr
1882  !
1883  ! -- initialize locs
1884  allocate (locs(this%dis%ndim))
1885  !
1886  ! -- calculate and report strain for interbeds
1887  if (this%ninterbeds > 0) then
1888  nlen = min(ncells, this%ninterbeds)
1889  allocate (imap_sel(nlen))
1890  allocate (pctcomp_arr(this%ninterbeds))
1891  iexceed = 0
1892  do ib = 1, this%ninterbeds
1893  idelay = this%idelay(ib)
1894  b0 = this%thickini(ib)
1895  strain = this%tcomp(ib) / b0
1896  pctcomp = dhundred * strain
1897  pctcomp_arr(ib) = pctcomp
1898  if (pctcomp >= done) then
1899  iexceed = iexceed + 1
1900  end if
1901  end do
1902  call selectn(imap_sel, pctcomp_arr, reverse=.true.)
1903  !
1904  ! -- summary interbed strain table
1905  i0 = max(1, this%ninterbeds - ncells + 1)
1906  i1 = this%ninterbeds
1907  msg = ''
1908  if (iexceed /= 0) then
1909  write (msg, '(1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1910  'LARGEST', (i1 - i0 + 1), 'OF', this%ninterbeds, &
1911  'INTERBED STRAIN VALUES SHOWN'
1912  call write_message(msg, this%iout, skipbefore=1)
1913  !
1914  ! -- interbed strain data
1915  ! -- set title
1916  title = trim(adjustl(this%packName))//' PACKAGE INTERBED STRAIN SUMMARY'
1917  !
1918  ! -- determine the number of columns and rows
1919  ntabrows = nlen
1920  ntabcols = 9
1921  !
1922  ! -- setup table
1923  call table_cr(this%outputtab, this%packName, title)
1924  call this%outputtab%table_df(ntabrows, ntabcols, this%iout)
1925  !
1926  ! add columns
1927  tag = 'INTERBED NUMBER'
1928  call this%outputtab%initialize_column(tag, 10, alignment=tabcenter)
1929  tag = 'INTERBED TYPE'
1930  call this%outputtab%initialize_column(tag, 10, alignment=tabcenter)
1931  tag = 'CELLID'
1932  call this%outputtab%initialize_column(tag, 20, alignment=tableft)
1933  tag = 'INITIAL THICKNESS'
1934  call this%outputtab%initialize_column(tag, 12, alignment=tabcenter)
1935  tag = 'FINAL THICKNESS'
1936  call this%outputtab%initialize_column(tag, 12, alignment=tabcenter)
1937  tag = 'TOTAL COMPACTION'
1938  call this%outputtab%initialize_column(tag, 12, alignment=tabcenter)
1939  tag = 'FINAL STRAIN'
1940  call this%outputtab%initialize_column(tag, 12, alignment=tabcenter)
1941  tag = 'PERCENT COMPACTION'
1942  call this%outputtab%initialize_column(tag, 12, alignment=tabcenter)
1943  tag = 'FLAG'
1944  call this%outputtab%initialize_column(tag, 10, alignment=tabcenter)
1945  !
1946  ! -- write data
1947  do i = 1, nlen
1948  ib = imap_sel(i)
1949  idelay = this%idelay(ib)
1950  b0 = this%thickini(ib)
1951  b1 = this%csub_calc_interbed_thickness(ib)
1952  if (idelay == 0) then
1953  ctype = 'no-delay'
1954  else
1955  ctype = 'delay'
1956  b0 = b0 * this%rnb(ib)
1957  end if
1958  strain = this%tcomp(ib) / b0
1959  pctcomp = dhundred * strain
1960  if (pctcomp >= 5.0_dp) then
1961  cflag = '**>=5%'
1962  else if (pctcomp >= done) then
1963  cflag = '*>=1%'
1964  else
1965  cflag = ''
1966  end if
1967  node = this%nodelist(ib)
1968  call this%dis%noder_to_string(node, cellid)
1969  !
1970  ! -- fill table line
1971  call this%outputtab%add_term(ib)
1972  call this%outputtab%add_term(ctype)
1973  call this%outputtab%add_term(cellid)
1974  call this%outputtab%add_term(b0)
1975  call this%outputtab%add_term(b1)
1976  call this%outputtab%add_term(this%tcomp(ib))
1977  call this%outputtab%add_term(strain)
1978  call this%outputtab%add_term(pctcomp)
1979  call this%outputtab%add_term(cflag)
1980  end do
1981  write (this%iout, '(/1X,A,1X,I0,1X,A,1X,I0,1X,A,/1X,A,/1X,A)') &
1982  'PERCENT COMPACTION IS GREATER THAN OR EQUAL TO 1 PERCENT IN', &
1983  iexceed, 'OF', this%ninterbeds, 'INTERBED(S).', &
1984  'USE THE STRAIN_CSV_INTERBED OPTION TO OUTPUT A CSV '// &
1985  'FILE WITH PERCENT COMPACTION ', 'VALUES FOR ALL INTERBEDS.'
1986  else
1987  msg = 'PERCENT COMPACTION WAS LESS THAN 1 PERCENT IN ALL INTERBEDS'
1988  write (this%iout, '(/1X,A)') trim(adjustl(msg))
1989  end if
1990  !
1991  ! -- write csv file
1992  if (this%istrainib /= 0) then
1993  !
1994  ! -- determine the number of columns and rows
1995  ntabrows = this%ninterbeds
1996  ntabcols = 7
1997  if (this%dis%ndim > 1) then
1998  ntabcols = ntabcols + 1
1999  end if
2000  ntabcols = ntabcols + this%dis%ndim
2001  !
2002  ! -- setup table
2003  call table_cr(this%outputtab, this%packName, '')
2004  call this%outputtab%table_df(ntabrows, ntabcols, this%istrainib, &
2005  lineseparator=.false., separator=',')
2006  !
2007  ! add columns
2008  tag = 'INTERBED_NUMBER'
2009  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2010  tag = 'INTERBED_TYPE'
2011  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2012  tag = 'NODE'
2013  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2014  if (this%dis%ndim == 2) then
2015  tag = 'LAYER'
2016  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2017  tag = 'ICELL2D'
2018  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2019  else
2020  tag = 'LAYER'
2021  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2022  tag = 'ROW'
2023  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2024  tag = 'COLUMN'
2025  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2026  end if
2027  tag = 'INITIAL_THICKNESS'
2028  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2029  tag = 'FINAL_THICKNESS'
2030  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2031  tag = 'TOTAL_COMPACTION'
2032  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2033  tag = 'TOTAL_STRAIN'
2034  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2035  tag = 'PERCENT_COMPACTION'
2036  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2037  !
2038  ! -- write data
2039  do ib = 1, this%ninterbeds
2040  idelay = this%idelay(ib)
2041  b0 = this%thickini(ib)
2042  b1 = this%csub_calc_interbed_thickness(ib)
2043  if (idelay == 0) then
2044  ctype = 'no-delay'
2045  else
2046  ctype = 'delay'
2047  b0 = b0 * this%rnb(ib)
2048  end if
2049  strain = this%tcomp(ib) / b0
2050  pctcomp = dhundred * strain
2051  node = this%nodelist(ib)
2052  call this%dis%noder_to_array(node, locs)
2053  !
2054  ! -- fill table line
2055  call this%outputtab%add_term(ib)
2056  call this%outputtab%add_term(ctype)
2057  if (this%dis%ndim > 1) then
2058  call this%outputtab%add_term(this%dis%get_nodeuser(node))
2059  end if
2060  do ipos = 1, this%dis%ndim
2061  call this%outputtab%add_term(locs(ipos))
2062  end do
2063  call this%outputtab%add_term(b0)
2064  call this%outputtab%add_term(b1)
2065  call this%outputtab%add_term(this%tcomp(ib))
2066  call this%outputtab%add_term(strain)
2067  call this%outputtab%add_term(pctcomp)
2068  end do
2069  end if
2070  !
2071  ! -- deallocate temporary storage
2072  deallocate (imap_sel)
2073  deallocate (pctcomp_arr)
2074  end if
2075  !
2076  ! -- calculate and report strain for coarse-grained materials
2077  nlen = min(ncells, this%dis%nodes)
2078  allocate (imap_sel(nlen))
2079  allocate (pctcomp_arr(this%dis%nodes))
2080  iexceed = 0
2081  do node = 1, this%dis%nodes
2082  strain = dzero
2083  if (this%cg_thickini(node) > dzero) then
2084  strain = this%cg_tcomp(node) / this%cg_thickini(node)
2085  end if
2086  pctcomp = dhundred * strain
2087  pctcomp_arr(node) = pctcomp
2088  if (pctcomp >= done) then
2089  iexceed = iexceed + 1
2090  end if
2091  end do
2092  call selectn(imap_sel, pctcomp_arr, reverse=.true.)
2093  !
2094  ! -- summary coarse-grained strain table
2095  i0 = max(1, this%dis%nodes - ncells + 1)
2096  i1 = this%dis%nodes
2097  msg = ''
2098  if (iexceed /= 0) then
2099  write (msg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
2100  'LARGEST ', (i1 - i0 + 1), 'OF', this%dis%nodes, &
2101  'CELL COARSE-GRAINED VALUES SHOWN'
2102  call write_message(msg, this%iout, skipbefore=1)
2103  !
2104  ! -- set title
2105  title = trim(adjustl(this%packName))// &
2106  ' PACKAGE COARSE-GRAINED STRAIN SUMMARY'
2107  !
2108  ! -- determine the number of columns and rows
2109  ntabrows = nlen
2110  ntabcols = 7
2111  !
2112  ! -- setup table
2113  call table_cr(this%outputtab, this%packName, title)
2114  call this%outputtab%table_df(ntabrows, ntabcols, this%iout)
2115  !
2116  ! add columns
2117  tag = 'CELLID'
2118  call this%outputtab%initialize_column(tag, 20, alignment=tableft)
2119  tag = 'INITIAL THICKNESS'
2120  call this%outputtab%initialize_column(tag, 12, alignment=tabcenter)
2121  tag = 'FINAL THICKNESS'
2122  call this%outputtab%initialize_column(tag, 12, alignment=tabcenter)
2123  tag = 'TOTAL COMPACTION'
2124  call this%outputtab%initialize_column(tag, 12, alignment=tabcenter)
2125  tag = 'FINAL STRAIN'
2126  call this%outputtab%initialize_column(tag, 12, alignment=tabcenter)
2127  tag = 'PERCENT COMPACTION'
2128  call this%outputtab%initialize_column(tag, 12, alignment=tabcenter)
2129  tag = 'FLAG'
2130  call this%outputtab%initialize_column(tag, 10, alignment=tabcenter)
2131  ! -- write data
2132  do nn = 1, nlen
2133  node = imap_sel(nn)
2134  if (this%cg_thickini(node) > dzero) then
2135  strain = this%cg_tcomp(node) / this%cg_thickini(node)
2136  else
2137  strain = dzero
2138  end if
2139  pctcomp = dhundred * strain
2140  if (pctcomp >= 5.0_dp) then
2141  cflag = '**>=5%'
2142  else if (pctcomp >= done) then
2143  cflag = '*>=1%'
2144  else
2145  cflag = ''
2146  end if
2147  call this%dis%noder_to_string(node, cellid)
2148  !
2149  ! -- fill table line
2150  call this%outputtab%add_term(cellid)
2151  call this%outputtab%add_term(this%cg_thickini(node))
2152  call this%outputtab%add_term(this%cg_thick(node))
2153  call this%outputtab%add_term(this%cg_tcomp(node))
2154  call this%outputtab%add_term(strain)
2155  call this%outputtab%add_term(pctcomp)
2156  call this%outputtab%add_term(cflag)
2157  end do
2158  write (this%iout, '(/1X,A,1X,I0,1X,A,1X,I0,1X,A,/1X,A,/1X,A)') &
2159  'COARSE-GRAINED STORAGE PERCENT COMPACTION IS GREATER THAN OR '// &
2160  'EQUAL TO 1 PERCENT IN', iexceed, 'OF', this%dis%nodes, 'CELL(S).', &
2161  'USE THE STRAIN_CSV_COARSE OPTION TO OUTPUT A CSV '// &
2162  'FILE WITH PERCENT COMPACTION ', 'VALUES FOR ALL CELLS.'
2163  else
2164  msg = 'COARSE-GRAINED STORAGE PERCENT COMPACTION WAS LESS THAN '// &
2165  '1 PERCENT IN ALL CELLS '
2166  write (this%iout, '(/1X,A)') trim(adjustl(msg))
2167  end if
2168  !
2169  ! -- write csv file
2170  if (this%istrainsk /= 0) then
2171  !
2172  ! -- determine the number of columns and rows
2173  ntabrows = this%dis%nodes
2174  ntabcols = 5
2175  if (this%dis%ndim > 1) then
2176  ntabcols = ntabcols + 1
2177  end if
2178  ntabcols = ntabcols + this%dis%ndim
2179  !
2180  ! -- setup table
2181  call table_cr(this%outputtab, this%packName, '')
2182  call this%outputtab%table_df(ntabrows, ntabcols, this%istrainsk, &
2183  lineseparator=.false., separator=',')
2184  !
2185  ! add columns
2186  tag = 'NODE'
2187  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2188  if (this%dis%ndim == 2) then
2189  tag = 'LAYER'
2190  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2191  tag = 'ICELL2D'
2192  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2193  else
2194  tag = 'LAYER'
2195  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2196  tag = 'ROW'
2197  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2198  tag = 'COLUMN'
2199  call this%outputtab%initialize_column(tag, 10, alignment=tabright)
2200  end if
2201  tag = 'INITIAL_THICKNESS'
2202  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2203  tag = 'FINAL_THICKNESS'
2204  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2205  tag = 'TOTAL_COMPACTION'
2206  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2207  tag = 'TOTAL_STRAIN'
2208  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2209  tag = 'PERCENT_COMPACTION'
2210  call this%outputtab%initialize_column(tag, 20, alignment=tabright)
2211  !
2212  ! -- write data
2213  do node = 1, this%dis%nodes
2214  if (this%cg_thickini(node) > dzero) then
2215  strain = this%cg_tcomp(node) / this%cg_thickini(node)
2216  else
2217  strain = dzero
2218  end if
2219  pctcomp = dhundred * strain
2220  call this%dis%noder_to_array(node, locs)
2221  !
2222  ! -- fill table line
2223  if (this%dis%ndim > 1) then
2224  call this%outputtab%add_term(this%dis%get_nodeuser(node))
2225  end if
2226  do ipos = 1, this%dis%ndim
2227  call this%outputtab%add_term(locs(ipos))
2228  end do
2229  call this%outputtab%add_term(this%cg_thickini(node))
2230  call this%outputtab%add_term(this%cg_thick(node))
2231  call this%outputtab%add_term(this%cg_tcomp(node))
2232  call this%outputtab%add_term(strain)
2233  call this%outputtab%add_term(pctcomp)
2234  end do
2235  end if
2236  !
2237  ! -- write a warning message for delay interbeds in non-convertible gwf
2238  ! cells that violate minimum head assumptions
2239  if (this%ndelaybeds > 0) then
2240  if (this%idb_nconv_count(2) > 0) then
2241  write (warnmsg, '(a,1x,a,1x,i0,1x,a,1x,a)') &
2242  'Delay interbed cell heads were less than the top of the interbed', &
2243  'cell in', this%idb_nconv_count(2), 'interbed cells in ', &
2244  'non-convertible GWF cells for at least one time step during '// &
2245  'the simulation.'
2246  call store_warning(warnmsg)
2247  end if
2248  end if
2249  !
2250  ! -- deallocate temporary storage
2251  deallocate (imap_sel)
2252  deallocate (locs)
2253  deallocate (pctcomp_arr)
2254  end subroutine csub_fp
2255 
2256  !> @ brief Deallocate package memory
2257  !!
2258  !! Deallocate CSUB package scalars and arrays.
2259  !!
2260  !<
2261  subroutine csub_da(this)
2262  ! -- modules
2264  ! -- dummy variables
2265  class(gwfcsubtype) :: this
2266  !
2267  ! -- Deallocate arrays if package is active
2268  if (this%inunit > 0) then
2269  call mem_deallocate(this%unodelist)
2270  call mem_deallocate(this%nodelist)
2271  call mem_deallocate(this%idelay)
2272  call mem_deallocate(this%ielastic)
2273  call mem_deallocate(this%iconvert)
2274  !
2275  ! -- grid-based storage data
2276  call mem_deallocate(this%buff)
2277  call mem_deallocate(this%buffusr)
2278  call mem_deallocate(this%sgm)
2279  call mem_deallocate(this%sgs)
2280  call mem_deallocate(this%cg_ske_cr)
2281  call mem_deallocate(this%cg_gs)
2282  call mem_deallocate(this%cg_es)
2283  call mem_deallocate(this%cg_es0)
2284  call mem_deallocate(this%cg_pcs)
2285  call mem_deallocate(this%cg_comp)
2286  call mem_deallocate(this%cg_tcomp)
2287  call mem_deallocate(this%cg_stor)
2288  call mem_deallocate(this%cg_ske)
2289  call mem_deallocate(this%cg_sk)
2290  if (this%iupdatematprop == 0) then
2291  nullify (this%cg_thick)
2292  nullify (this%cg_thick0)
2293  nullify (this%cg_theta)
2294  nullify (this%cg_theta0)
2295  else
2296  call mem_deallocate(this%cg_thick)
2297  call mem_deallocate(this%cg_thick0)
2298  call mem_deallocate(this%cg_theta)
2299  call mem_deallocate(this%cg_theta0)
2300  end if
2301  call mem_deallocate(this%cg_thickini)
2302  call mem_deallocate(this%cg_thetaini)
2303  !
2304  ! -- cell storage
2305  call mem_deallocate(this%cell_wcstor)
2306  call mem_deallocate(this%cell_thick)
2307  !
2308  ! -- interbed storage
2309  call mem_deallocate(this%boundname, 'BOUNDNAME', this%memoryPath)
2310  call mem_deallocate(this%auxname, 'AUXNAME', this%memoryPath)
2311  call mem_deallocate(this%auxvar)
2312  call mem_deallocate(this%ci)
2313  call mem_deallocate(this%rci)
2314  call mem_deallocate(this%pcs)
2315  call mem_deallocate(this%rnb)
2316  call mem_deallocate(this%kv)
2317  call mem_deallocate(this%h0)
2318  call mem_deallocate(this%comp)
2319  call mem_deallocate(this%tcomp)
2320  call mem_deallocate(this%tcompi)
2321  call mem_deallocate(this%tcompe)
2322  call mem_deallocate(this%storagee)
2323  call mem_deallocate(this%storagei)
2324  call mem_deallocate(this%ske)
2325  call mem_deallocate(this%sk)
2326  if (this%iupdatematprop == 0) then
2327  nullify (this%thick)
2328  nullify (this%thick0)
2329  nullify (this%theta)
2330  nullify (this%theta0)
2331  else
2332  call mem_deallocate(this%thick)
2333  call mem_deallocate(this%thick0)
2334  call mem_deallocate(this%theta)
2335  call mem_deallocate(this%theta0)
2336  end if
2337  call mem_deallocate(this%thickini)
2338  call mem_deallocate(this%thetaini)
2339  !
2340  ! -- delay bed storage
2341  if (this%ndelaybeds > 0) then
2342  if (this%iupdatematprop == 0) then
2343  nullify (this%dbdz)
2344  nullify (this%dbdz0)
2345  nullify (this%dbtheta)
2346  nullify (this%dbtheta0)
2347  else
2348  call mem_deallocate(this%dbdz)
2349  call mem_deallocate(this%dbdz0)
2350  call mem_deallocate(this%dbtheta)
2351  call mem_deallocate(this%dbtheta0)
2352  end if
2353  call mem_deallocate(this%idb_nconv_count)
2354  call mem_deallocate(this%idbconvert)
2355  call mem_deallocate(this%dbdhmax)
2356  call mem_deallocate(this%dbz)
2357  call mem_deallocate(this%dbrelz)
2358  call mem_deallocate(this%dbh)
2359  call mem_deallocate(this%dbh0)
2360  call mem_deallocate(this%dbgeo)
2361  call mem_deallocate(this%dbes)
2362  call mem_deallocate(this%dbes0)
2363  call mem_deallocate(this%dbpcs)
2364  call mem_deallocate(this%dbflowtop)
2365  call mem_deallocate(this%dbflowbot)
2366  call mem_deallocate(this%dbdzini)
2367  call mem_deallocate(this%dbthetaini)
2368  call mem_deallocate(this%dbcomp)
2369  call mem_deallocate(this%dbtcomp)
2370  !
2371  ! -- delay interbed solution arrays
2372  call mem_deallocate(this%dbal)
2373  call mem_deallocate(this%dbad)
2374  call mem_deallocate(this%dbau)
2375  call mem_deallocate(this%dbrhs)
2376  call mem_deallocate(this%dbdh)
2377  call mem_deallocate(this%dbaw)
2378  end if
2379  !
2380  ! -- period data
2381  call mem_deallocate(this%nodelistsig0)
2382  call mem_deallocate(this%sig0)
2383  !
2384  ! -- pointers to gwf variables
2385  nullify (this%gwfiss)
2386  !
2387  ! -- pointers to storage variables
2388  nullify (this%stoiconv)
2389  nullify (this%stoss)
2390  !
2391  ! -- input table
2392  if (this%iprpak > 0) then
2393  call this%inputtab%table_da()
2394  deallocate (this%inputtab)
2395  nullify (this%inputtab)
2396  end if
2397  !
2398  ! -- output table
2399  if (associated(this%outputtab)) then
2400  call this%outputtab%table_da()
2401  deallocate (this%outputtab)
2402  nullify (this%outputtab)
2403  end if
2404  end if
2405  !
2406  ! -- package csv table
2407  if (this%ipakcsv > 0) then
2408  call this%pakcsvtab%table_da()
2409  deallocate (this%pakcsvtab)
2410  nullify (this%pakcsvtab)
2411  end if
2412  !
2413  ! -- deallocate character variables
2414  call mem_deallocate(this%listlabel, 'LISTLABEL', this%memoryPath)
2415  call mem_deallocate(this%stoMemPath, 'STONAME', this%memoryPath)
2416  !
2417  ! -- deallocate scalars
2418  call mem_deallocate(this%istounit)
2419  call mem_deallocate(this%inobspkg)
2420  call mem_deallocate(this%ninterbeds)
2421  call mem_deallocate(this%maxsig0)
2422  call mem_deallocate(this%nbound)
2423  call mem_deallocate(this%iscloc)
2424  call mem_deallocate(this%iauxmultcol)
2425  call mem_deallocate(this%ndelaycells)
2426  call mem_deallocate(this%ndelaybeds)
2427  call mem_deallocate(this%initialized)
2428  call mem_deallocate(this%ieslag)
2429  call mem_deallocate(this%ipch)
2430  call mem_deallocate(this%lhead_based)
2431  call mem_deallocate(this%iupdatestress)
2432  call mem_deallocate(this%ispecified_pcs)
2433  call mem_deallocate(this%ispecified_dbh)
2434  call mem_deallocate(this%inamedbound)
2435  call mem_deallocate(this%iconvchk)
2436  call mem_deallocate(this%naux)
2437  call mem_deallocate(this%istoragec)
2438  call mem_deallocate(this%istrainib)
2439  call mem_deallocate(this%istrainsk)
2440  call mem_deallocate(this%ioutcomp)
2441  call mem_deallocate(this%ioutcompi)
2442  call mem_deallocate(this%ioutcompe)
2443  call mem_deallocate(this%ioutcompib)
2444  call mem_deallocate(this%ioutcomps)
2445  call mem_deallocate(this%ioutzdisp)
2446  call mem_deallocate(this%ipakcsv)
2447  call mem_deallocate(this%iupdatematprop)
2448  call mem_deallocate(this%epsilon)
2449  call mem_deallocate(this%cc_crit)
2450  call mem_deallocate(this%gammaw)
2451  call mem_deallocate(this%beta)
2452  call mem_deallocate(this%brg)
2453  call mem_deallocate(this%satomega)
2454  call mem_deallocate(this%icellf)
2455  call mem_deallocate(this%gwfiss0)
2456  !
2457  ! -- deallocate methods on objects
2458  if (this%inunit > 0) then
2459  call this%obs%obs_da()
2460  call this%TsManager%da()
2461  !
2462  ! -- deallocate and nullify observations
2463  deallocate (this%obs)
2464  nullify (this%obs)
2465  end if
2466  !
2467  ! -- deallocate TsManager
2468  deallocate (this%TsManager)
2469  nullify (this%TsManager)
2470 
2471  !
2472  ! -- deallocate parent
2473  call this%NumericalPackageType%da()
2474  end subroutine csub_da
2475 
2476  !> @ brief Read and prepare stress period data for package
2477  !!
2478  !! Method reads and prepares stress period data for the CSUB package.
2479  !! The overlying geostatic stress (sig0) is the only stress period data
2480  !! read by the CSUB package.
2481  !!
2482  !<
2483  subroutine csub_rp(this)
2484  ! -- modules
2485  use constantsmodule, only: linelength
2486  use tdismodule, only: kper, nper
2488  ! -- dummy variables
2489  class(gwfcsubtype), intent(inout) :: this
2490  ! -- local variables
2491  character(len=LINELENGTH) :: line
2492  character(len=LINELENGTH) :: title
2493  character(len=LINELENGTH) :: text
2494  character(len=20) :: cellid
2495  logical(LGP) :: isfound
2496  logical(LGP) :: endOfBlock
2497  integer(I4B) :: jj
2498  integer(I4B) :: ierr
2499  integer(I4B) :: node
2500  integer(I4B) :: nlist
2501  real(DP), pointer :: bndElem => null()
2502  ! -- formats
2503  character(len=*), parameter :: fmtblkerr = &
2504  &"('Looking for BEGIN PERIOD iper. Found ',a,' instead.')"
2505  character(len=*), parameter :: fmtlsp = &
2506  &"(1X,/1X,'REUSING ',a,'S FROM LAST STRESS PERIOD')"
2507  !
2508  ! -- return if data is not read from file
2509  if (this%inunit == 0) return
2510  !
2511  ! -- get stress period data
2512  if (this%ionper < kper) then
2513  !
2514  ! -- get period block
2515  call this%parser%GetBlock('PERIOD', isfound, ierr, &
2516  supportopenclose=.true., &
2517  blockrequired=.false.)
2518  if (isfound) then
2519  !
2520  ! -- read ionper and check for increasing period numbers
2521  call this%read_check_ionper()
2522  else
2523  !
2524  ! -- PERIOD block not found
2525  if (ierr < 0) then
2526  ! -- End of file found; data applies for remainder of simulation.
2527  this%ionper = nper + 1
2528  else
2529  ! -- Found invalid block
2530  call this%parser%GetCurrentLine(line)
2531  write (errmsg, fmtblkerr) adjustl(trim(line))
2532  call store_error(errmsg)
2533  end if
2534  end if
2535  end if
2536  !
2537  ! -- read data if ionper == kper
2538  if (this%ionper == kper) then
2539  !
2540  ! -- setup table for period data
2541  if (this%iprpak /= 0) then
2542  !
2543  ! -- reset the input table object
2544  title = 'CSUB'//' PACKAGE ('// &
2545  trim(adjustl(this%packName))//') DATA FOR PERIOD'
2546  write (title, '(a,1x,i6)') trim(adjustl(title)), kper
2547  call table_cr(this%inputtab, this%packName, title)
2548  call this%inputtab%table_df(1, 2, this%iout, finalize=.false.)
2549  text = 'CELLID'
2550  call this%inputtab%initialize_column(text, 20)
2551  text = 'SIG0'
2552  call this%inputtab%initialize_column(text, 15, alignment=tableft)
2553  end if
2554  !
2555  ! -- initialize nlist
2556  nlist = 0
2557  !
2558  ! -- Remove all time-series links associated with this package.
2559  call this%TsManager%Reset(this%packName)
2560  !
2561  ! -- read data
2562  readdata: do
2563  call this%parser%GetNextLine(endofblock)
2564  !
2565  ! -- test for end of block
2566  if (endofblock) then
2567  exit readdata
2568  end if
2569  !
2570  ! -- increment counter
2571  nlist = nlist + 1
2572  !
2573  ! -- check for error condition with nlist
2574  if (nlist > this%maxsig0) then
2575  write (errmsg, '(a,i0,a,i0,a)') &
2576  'The number of stress period entries (', nlist, &
2577  ') exceeds the maximum number of stress period entries (', &
2578  this%maxsig0, ').'
2579  call store_error(errmsg)
2580  exit readdata
2581  end if
2582  !
2583  ! -- get cell i
2584  call this%parser%GetCellid(this%dis%ndim, cellid)
2585  node = this%dis%noder_from_cellid(cellid, &
2586  this%parser%iuactive, this%iout)
2587  !
2588  !
2589  if (node < 1) then
2590  write (errmsg, '(a,2(1x,a))') &
2591  'CELLID', cellid, 'is not in the active model domain.'
2592  call store_error(errmsg)
2593  cycle readdata
2594  end if
2595  this%nodelistsig0(nlist) = node
2596  !
2597  ! -- get sig0
2598  call this%parser%GetString(text)
2599  jj = 1 ! For 'SIG0'
2600  bndelem => this%sig0(nlist)
2601  call read_value_or_time_series_adv(text, nlist, jj, bndelem, &
2602  this%packName, 'BND', &
2603  this%tsManager, this%iprpak, &
2604  'SIG0')
2605  !
2606  ! -- write line to table
2607  if (this%iprpak /= 0) then
2608  call this%dis%noder_to_string(node, cellid)
2609  call this%inputtab%add_term(cellid)
2610  call this%inputtab%add_term(bndelem)
2611  end if
2612  end do readdata
2613  !
2614  ! -- set nbound
2615  this%nbound = nlist
2616  !
2617  ! -- finalize the table
2618  if (this%iprpak /= 0) then
2619  call this%inputtab%finalize_table()
2620  end if
2621  !
2622  ! -- reuse data from last stress period
2623  else
2624  write (this%iout, fmtlsp) trim(this%filtyp)
2625  end if
2626  !
2627  ! -- terminate if errors encountered in reach block
2628  if (count_errors() > 0) then
2629  call this%parser%StoreErrorUnit()
2630  end if
2631  !
2632  ! -- read observations
2633  call this%csub_rp_obs()
2634  end subroutine csub_rp
2635 
2636  !> @ brief Advance the package
2637  !!
2638  !! Advance data in the CSUB package. The method sets data for the previous
2639  !! time step to the current value for the data (e.g., HOLD = HNEW). The
2640  !! method also calls the method to initialize the initial stress conditions
2641  !! if this is the first transient stress period.
2642  !!
2643  !<
2644  subroutine csub_ad(this, nodes, hnew)
2645  ! -- modules
2646  use tdismodule, only: nper, kper
2647  ! -- dummy variables
2648  class(gwfcsubtype) :: this
2649  integer(I4B), intent(in) :: nodes !< number of active model nodes
2650  real(DP), dimension(nodes), intent(in) :: hnew !< current head
2651  ! -- local variables
2652  integer(I4B) :: ib
2653  integer(I4B) :: n
2654  integer(I4B) :: idelay
2655  integer(I4B) :: node
2656  real(DP) :: h
2657  real(DP) :: es
2658  real(DP) :: pcs
2659  !
2660  ! -- evaluate if steady-state stress periods are specified for more
2661  ! than the first and last stress period if interbeds are simulated
2662  if (this%ninterbeds > 0) then
2663  if (kper > 1 .and. kper < nper) then
2664  if (this%gwfiss /= 0) then
2665  write (errmsg, '(a,i0,a,1x,a,1x,a,1x,i0,1x,a)') &
2666  'Only the first and last (', nper, ')', &
2667  'stress period can be steady if interbeds are simulated.', &
2668  'Stress period', kper, 'has been defined to be steady state.'
2669  call store_error(errmsg, terminate=.true.)
2670  end if
2671  end if
2672  end if
2673  !
2674  ! -- set initial states
2675  if (this%initialized == 0) then
2676  if (this%gwfiss == 0) then
2677  call this%csub_set_initial_state(nodes, hnew)
2678  end if
2679  end if
2680  !
2681  ! -- update state variables
2682  !
2683  ! -- coarse-grained materials
2684  do node = 1, nodes
2685  this%cg_comp(node) = dzero
2686  this%cg_es0(node) = this%cg_es(node)
2687  if (this%iupdatematprop /= 0) then
2688  this%cg_thick0(node) = this%cg_thick(node)
2689  this%cg_theta0(node) = this%cg_theta(node)
2690  end if
2691  end do
2692  !
2693  ! -- interbeds
2694  do ib = 1, this%ninterbeds
2695  idelay = this%idelay(ib)
2696  !
2697  ! -- update common terms for no-delay and delay interbeds
2698  this%comp(ib) = dzero
2699  node = this%nodelist(ib)
2700  if (this%initialized /= 0) then
2701  es = this%cg_es(node)
2702  pcs = this%pcs(ib)
2703  if (es > pcs) then
2704  this%pcs(ib) = es
2705  end if
2706  end if
2707  if (this%iupdatematprop /= 0) then
2708  this%thick0(ib) = this%thick(ib)
2709  this%theta0(ib) = this%theta(ib)
2710  end if
2711  !
2712  ! -- update delay interbed terms
2713  if (idelay /= 0) then
2714  !
2715  ! -- update state if previous period was steady state
2716  if (kper > 1) then
2717  if (this%gwfiss0 /= 0) then
2718  node = this%nodelist(ib)
2719  h = hnew(node)
2720  do n = 1, this%ndelaycells
2721  this%dbh(n, idelay) = h
2722  end do
2723  end if
2724  end if
2725  !
2726  ! -- update preconsolidation stress, stresses, head, dbdz0, and theta0
2727  do n = 1, this%ndelaycells
2728  ! update preconsolidation stress
2729  if (this%initialized /= 0) then
2730  if (this%dbes(n, idelay) > this%dbpcs(n, idelay)) then
2731  this%dbpcs(n, idelay) = this%dbes(n, idelay)
2732  end if
2733  end if
2734  this%dbh0(n, idelay) = this%dbh(n, idelay)
2735  this%dbes0(n, idelay) = this%dbes(n, idelay)
2736  if (this%iupdatematprop /= 0) then
2737  this%dbdz0(n, idelay) = this%dbdz(n, idelay)
2738  this%dbtheta0(n, idelay) = this%dbtheta(n, idelay)
2739  end if
2740  end do
2741  end if
2742  end do
2743  !
2744  ! -- set gwfiss0
2745  this%gwfiss0 = this%gwfiss
2746  !
2747  ! -- Advance the time series managers
2748  call this%TsManager%ad()
2749  !
2750  ! -- For each observation, push simulated value and corresponding
2751  ! simulation time from "current" to "preceding" and reset
2752  ! "current" value.
2753  call this%obs%obs_ad()
2754  end subroutine csub_ad
2755 
2756  !> @ brief Fill A and r for the package
2757  !!
2758  !! Fill the coefficient matrix and right-hand side with the CSUB package terms.
2759  !!
2760  !<
2761  subroutine csub_fc(this, kiter, hold, hnew, matrix_sln, idxglo, rhs)
2762  ! -- modules
2763  use tdismodule, only: delt
2764  ! -- dummy variables
2765  class(gwfcsubtype) :: this
2766  integer(I4B), intent(in) :: kiter !< outer iteration numbed
2767  real(DP), intent(in), dimension(:) :: hold !< previous heads
2768  real(DP), intent(in), dimension(:) :: hnew !< current heads
2769  class(matrixbasetype), pointer :: matrix_sln !< A matrix
2770  integer(I4B), intent(in), dimension(:) :: idxglo !< global index model to solution
2771  real(DP), intent(inout), dimension(:) :: rhs !< right-hand side
2772  ! -- local variables
2773  integer(I4B) :: ib
2774  integer(I4B) :: node
2775  integer(I4B) :: idiag
2776  integer(I4B) :: idelay
2777  real(DP) :: tled
2778  real(DP) :: area
2779  real(DP) :: hcof
2780  real(DP) :: rhsterm
2781  real(DP) :: comp
2782  !
2783  ! -- update geostatic load calculation
2784  call this%csub_cg_calc_stress(this%dis%nodes, hnew)
2785  !
2786  ! -- formulate csub terms
2787  if (this%gwfiss == 0) then
2788  !
2789  ! -- initialize tled
2790  tled = done / delt
2791  !
2792  ! -- coarse-grained storage
2793  do node = 1, this%dis%nodes
2794  idiag = this%dis%con%ia(node)
2795  area = this%dis%get_area(node)
2796  !
2797  ! -- skip inactive cells
2798  if (this%ibound(node) < 1) cycle
2799  !
2800  ! -- update coarse-grained material properties
2801  if (this%iupdatematprop /= 0) then
2802  if (this%ieslag == 0) then
2803  !
2804  ! -- calculate compaction
2805  call this%csub_cg_calc_comp(node, hnew(node), hold(node), comp)
2806  this%cg_comp(node) = comp
2807  !
2808  ! -- update coarse-grained thickness and void ratio
2809  call this%csub_cg_update(node)
2810  end if
2811  end if
2812  !
2813  ! -- calculate coarse-grained storage terms
2814  call this%csub_cg_fc(node, tled, area, hnew(node), hold(node), &
2815  hcof, rhsterm)
2816  !
2817  ! -- add coarse-grained storage terms to amat and rhs for coarse-grained storage
2818  call matrix_sln%add_value_pos(idxglo(idiag), hcof)
2819  rhs(node) = rhs(node) + rhsterm
2820  !
2821  ! -- calculate coarse-grained water compressibility
2822  ! storage terms
2823  if (this%brg /= dzero) then
2824  call this%csub_cg_wcomp_fc(node, tled, area, hnew(node), hold(node), &
2825  hcof, rhsterm)
2826  !
2827  ! -- add water compression storage terms to amat and rhs for
2828  ! coarse-grained storage
2829  call matrix_sln%add_value_pos(idxglo(idiag), hcof)
2830  rhs(node) = rhs(node) + rhsterm
2831  end if
2832  end do
2833  !
2834  ! -- interbed storage
2835  if (this%ninterbeds /= 0) then
2836  !
2837  ! -- calculate the contribution of interbeds to the
2838  ! groundwater flow equation
2839  do ib = 1, this%ninterbeds
2840  node = this%nodelist(ib)
2841  idelay = this%idelay(ib)
2842  idiag = this%dis%con%ia(node)
2843  area = this%dis%get_area(node)
2844  call this%csub_interbed_fc(ib, node, area, hnew(node), hold(node), &
2845  hcof, rhsterm)
2846  call matrix_sln%add_value_pos(idxglo(idiag), hcof)
2847  rhs(node) = rhs(node) + rhsterm
2848  !
2849  ! -- calculate interbed water compressibility terms
2850  if (.not. is_close(this%brg, dzero) .and. idelay == 0) then
2851  call this%csub_nodelay_wcomp_fc(ib, node, tled, area, &
2852  hnew(node), hold(node), &
2853  hcof, rhsterm)
2854  !
2855  ! -- add water compression storage terms to amat and rhs for interbed
2856  call matrix_sln%add_value_pos(idxglo(idiag), hcof)
2857  rhs(node) = rhs(node) + rhsterm
2858  end if
2859  end do
2860  end if
2861  end if
2862  !
2863  ! -- terminate if errors encountered when updating material properties
2864  if (count_errors() > 0) then
2865  call this%parser%StoreErrorUnit()
2866  end if
2867  end subroutine csub_fc
2868 
2869  !> @ brief Fill Newton-Raphson terms in A and r for the package
2870  !!
2871  !! Fill the coefficient matrix and right-hand side with CSUB package
2872  !! with Newton-Raphson terms.
2873  !!
2874  !! @param[in,out] amat A matrix
2875  !! @param[in,out] rhs right-hand side
2876  !!
2877  !<
2878  subroutine csub_fn(this, kiter, hold, hnew, matrix_sln, idxglo, rhs)
2879  ! -- modules
2880  use tdismodule, only: delt
2881  ! -- dummy variables
2882  class(gwfcsubtype) :: this
2883  integer(I4B), intent(in) :: kiter !< outer iteration number
2884  real(DP), intent(in), dimension(:) :: hold !< previous heads
2885  real(DP), intent(in), dimension(:) :: hnew !< current heads
2886  class(matrixbasetype), pointer :: matrix_sln !< A matrix
2887  integer(I4B), intent(in), dimension(:) :: idxglo !< global index model to solution
2888  real(DP), intent(inout), dimension(:) :: rhs !< right-hand side
2889  ! -- local variables
2890  integer(I4B) :: idelay
2891  integer(I4B) :: node
2892  integer(I4B) :: idiag
2893  integer(I4B) :: ib
2894  real(DP) :: tled
2895  real(DP) :: area
2896  real(DP) :: hcof
2897  real(DP) :: rhsterm
2898  !
2899  ! -- formulate csub terms
2900  if (this%gwfiss == 0) then
2901  tled = done / delt
2902  !
2903  ! -- coarse-grained storage
2904  do node = 1, this%dis%nodes
2905  idiag = this%dis%con%ia(node)
2906  area = this%dis%get_area(node)
2907  !
2908  ! -- skip inactive cells
2909  if (this%ibound(node) < 1) cycle
2910  !
2911  ! -- calculate coarse-grained storage newton terms
2912  call this%csub_cg_fn(node, tled, area, &
2913  hnew(node), hcof, rhsterm)
2914  !
2915  ! -- add coarse-grained storage newton terms to amat and rhs for
2916  ! coarse-grained storage
2917  call matrix_sln%add_value_pos(idxglo(idiag), hcof)
2918  rhs(node) = rhs(node) + rhsterm
2919  !
2920  ! -- calculate coarse-grained water compressibility storage
2921  ! newton terms
2922  if (this%brg /= dzero) then
2923  call this%csub_cg_wcomp_fn(node, tled, area, hnew(node), hold(node), &
2924  hcof, rhsterm)
2925  !
2926  ! -- add water compression storage newton terms to amat and rhs for
2927  ! coarse-grained storage
2928  call matrix_sln%add_value_pos(idxglo(idiag), hcof)
2929  rhs(node) = rhs(node) + rhsterm
2930  end if
2931  end do
2932  !
2933  ! -- interbed storage
2934  if (this%ninterbeds /= 0) then
2935  !
2936  ! -- calculate the interbed newton terms for the
2937  ! groundwater flow equation
2938  do ib = 1, this%ninterbeds
2939  idelay = this%idelay(ib)
2940  node = this%nodelist(ib)
2941  !
2942  ! -- skip inactive cells
2943  if (this%ibound(node) < 1) cycle
2944  !
2945  ! -- calculate interbed newton terms
2946  idiag = this%dis%con%ia(node)
2947  area = this%dis%get_area(node)
2948  call this%csub_interbed_fn(ib, node, hnew(node), hold(node), &
2949  hcof, rhsterm)
2950  !
2951  ! -- add interbed newton terms to amat and rhs
2952  call matrix_sln%add_value_pos(idxglo(idiag), hcof)
2953  rhs(node) = rhs(node) + rhsterm
2954  !
2955  ! -- calculate interbed water compressibility terms
2956  if (this%brg /= dzero .and. idelay == 0) then
2957  call this%csub_nodelay_wcomp_fn(ib, node, tled, area, &
2958  hnew(node), hold(node), &
2959  hcof, rhsterm)
2960  !
2961  ! -- add interbed water compression newton terms to amat and rhs
2962  call matrix_sln%add_value_pos(idxglo(idiag), hcof)
2963  rhs(node) = rhs(node) + rhsterm
2964  end if
2965  end do
2966  end if
2967  end if
2968  end subroutine csub_fn
2969 
2970  !> @ brief Initialize optional tables
2971  !!
2972  !! Subroutine to initialize optional tables. Tables include:
2973  !! o delay interbeds convergence tables
2974  !!
2975  !<
2976  subroutine csub_initialize_tables(this)
2977  class(gwfcsubtype) :: this
2978 
2979  character(len=LINELENGTH) :: tag
2980  integer(I4B) :: ntabrows
2981  integer(I4B) :: ntabcols
2982 
2983  if (this%ipakcsv > 0) then
2984  if (this%ndelaybeds < 1) then
2985  write (warnmsg, '(a,1x,3a)') &
2986  'Package convergence data is requested but delay interbeds', &
2987  'are not included in package (', &
2988  trim(adjustl(this%packName)), ').'
2989  call store_warning(warnmsg)
2990  end if
2991 
2992  ntabrows = 1
2993  ntabcols = 9
2994 
2995  ! setup table
2996  call table_cr(this%pakcsvtab, this%packName, '')
2997  call this%pakcsvtab%table_df(ntabrows, ntabcols, this%ipakcsv, &
2998  lineseparator=.false., separator=',', &
2999  finalize=.false.)
3000 
3001  ! add columns to package csv
3002  tag = 'total_inner_iterations'
3003  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3004  tag = 'totim'
3005  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3006  tag = 'kper'
3007  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3008  tag = 'kstp'
3009  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3010  tag = 'nouter'
3011  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3012  tag = 'dvmax'
3013  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3014  tag = 'dvmax_loc'
3015  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3016  tag = 'dstoragemax'
3017  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3018  tag = 'dstoragemax_loc'
3019  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3020  end if
3021 
3022  end subroutine csub_initialize_tables
3023 
3024  !> @ brief Final convergence check
3025  !!
3026  !! Final convergence check for the CSUB package. The final convergence
3027  !! check is only required when the simulation includes delay interbeds.
3028  !! The final convergence check compares the sum of water contributed
3029  !! by storage and water compressibility in the delay bed to the fluid
3030  !! exchange between the delay interbed and the gwf cell.
3031  !!
3032  !! @param[in,out] cpak string location of the maximum change in csub package
3033  !! @param[in,out] ipak node with the maximum change in csub package
3034  !! @param[in,out] dpak maximum change in csub package
3035  !!
3036  !<
3037  subroutine csub_cc(this, innertot, kiter, iend, icnvgmod, nodes, &
3038  hnew, hold, cpak, ipak, dpak)
3039  ! -- modules
3040  use tdismodule, only: totim, kstp, kper, delt
3041  ! -- dummy variables
3042  class(gwfcsubtype) :: this
3043  integer(I4B), intent(in) :: innertot !< total number of inner iterations
3044  integer(I4B), intent(in) :: kiter !< outer iteration number
3045  integer(I4B), intent(in) :: iend !< flag indicating if it is the last iteration
3046  integer(I4B), intent(in) :: icnvgmod !< flag indicating if the solution is considered converged
3047  integer(I4B), intent(in) :: nodes !< number of active nodes
3048  real(DP), dimension(nodes), intent(in) :: hnew !< current gwf head
3049  real(DP), dimension(nodes), intent(in) :: hold !< gwf for previous time step
3050  character(len=LENPAKLOC), intent(inout) :: cpak !< string location of the maximum change in csub package
3051  integer(I4B), intent(inout) :: ipak !< node with the maximum change in csub package
3052  real(DP), intent(inout) :: dpak !< maximum change in csub package
3053  ! local variables
3054  character(len=LENPAKLOC) :: cloc
3055  integer(I4B) :: icheck
3056  integer(I4B) :: ipakfail
3057  integer(I4B) :: ib
3058  integer(I4B) :: node
3059  integer(I4B) :: idelay
3060  integer(I4B) :: locdhmax
3061  integer(I4B) :: locrmax
3062  integer(I4B) :: ifirst
3063  real(DP) :: dhmax
3064  real(DP) :: rmax
3065  real(DP) :: dh
3066  real(DP) :: area
3067  real(DP) :: hcell
3068  real(DP) :: hcellold
3069  real(DP) :: snnew
3070  real(DP) :: snold
3071  real(DP) :: stoe
3072  real(DP) :: stoi
3073  real(DP) :: dwc
3074  real(DP) :: tled
3075  real(DP) :: hcof
3076  real(DP) :: rhs
3077  real(DP) :: v1
3078  real(DP) :: v2
3079  real(DP) :: df
3080  !
3081  ! -- initialize local variables
3082  icheck = this%iconvchk
3083  ipakfail = 0
3084  locdhmax = 0
3085  locrmax = 0
3086  ifirst = 1
3087  dhmax = dzero
3088  rmax = dzero
3089  !
3090  ! -- additional checks to see if convergence needs to be checked
3091  ! -- no convergence check for steady-state stress periods
3092  if (this%gwfiss /= 0) then
3093  icheck = 0
3094  else
3095  if (icnvgmod == 0) then
3096  icheck = 0
3097  end if
3098  end if
3099  !
3100  ! -- perform package convergence check
3101  if (icheck /= 0) then
3102  if (delt > dzero) then
3103  tled = done / delt
3104  else
3105  tled = dzero
3106  end if
3107  final_check: do ib = 1, this%ninterbeds
3108  idelay = this%idelay(ib)
3109  node = this%nodelist(ib)
3110  !
3111  ! -- skip nodelay interbeds
3112  if (idelay == 0) cycle
3113  !
3114  ! -- skip inactive cells
3115  if (this%ibound(node) < 1) cycle
3116  !
3117  ! -- evaluate the maximum head change in the interbed
3118  dh = this%dbdhmax(idelay)
3119  !
3120  ! -- evaluate difference between storage changes
3121  ! in the interbed and exchange between the interbed
3122  ! and the gwf cell
3123  area = this%dis%get_area(node)
3124  hcell = hnew(node)
3125  hcellold = hold(node)
3126  !
3127  ! -- calculate cell saturation
3128  call this%csub_calc_sat(node, hcell, hcellold, snnew, snold)
3129  !
3130  ! -- calculate the change in storage
3131  call this%csub_delay_calc_dstor(ib, hcell, stoe, stoi)
3132  v1 = (stoe + stoi) * area * this%rnb(ib) * tled
3133  !
3134  ! -- add water compressibility to storage term
3135  call this%csub_delay_calc_wcomp(ib, dwc)
3136  v1 = v1 + dwc * area * this%rnb(ib)
3137  !
3138  ! -- calculate the flow between the interbed and the cell
3139  call this%csub_delay_fc(ib, hcof, rhs)
3140  v2 = (-hcof * hcell - rhs) * area * this%rnb(ib)
3141  !
3142  ! -- calculate the difference between the interbed change in
3143  ! storage and the flow between the interbed and the cell
3144  df = v2 - v1
3145  !
3146  ! -- normalize by cell area and convert to a depth
3147  df = df * delt / area
3148  !
3149  ! -- evaluate magnitude of differences
3150  if (ifirst == 1) then
3151  ifirst = 0
3152  locdhmax = ib
3153  dhmax = dh
3154  locrmax = ib
3155  rmax = df
3156  else
3157  if (abs(dh) > abs(dhmax)) then
3158  locdhmax = ib
3159  dhmax = dh
3160  end if
3161  if (abs(df) > abs(rmax)) then
3162  locrmax = ib
3163  rmax = df
3164  end if
3165  end if
3166  end do final_check
3167  !
3168  ! -- set dpak and cpak
3169  ! -- update head error
3170  if (abs(dhmax) > abs(dpak)) then
3171  ipak = locdhmax
3172  dpak = dhmax
3173  write (cloc, "(a,'-',a)") trim(this%packName), 'head'
3174  cpak = cloc
3175  end if
3176  !
3177  ! -- update storage error
3178  if (abs(rmax) > abs(dpak)) then
3179  ipak = locrmax
3180  dpak = rmax
3181  write (cloc, "(a,'-',a)") trim(this%packName), 'storage'
3182  cpak = cloc
3183  end if
3184  !
3185  ! -- write convergence data to package csv
3186  if (this%ipakcsv /= 0) then
3187  !
3188  ! -- write the data
3189  call this%pakcsvtab%add_term(innertot)
3190  call this%pakcsvtab%add_term(totim)
3191  call this%pakcsvtab%add_term(kper)
3192  call this%pakcsvtab%add_term(kstp)
3193  call this%pakcsvtab%add_term(kiter)
3194  if (this%ndelaybeds > 0) then
3195  call this%pakcsvtab%add_term(dhmax)
3196  call this%pakcsvtab%add_term(locdhmax)
3197  call this%pakcsvtab%add_term(rmax)
3198  call this%pakcsvtab%add_term(locrmax)
3199  else
3200  call this%pakcsvtab%add_term('--')
3201  call this%pakcsvtab%add_term('--')
3202  call this%pakcsvtab%add_term('--')
3203  call this%pakcsvtab%add_term('--')
3204  end if
3205  !
3206  ! -- finalize the package csv
3207  if (iend == 1) then
3208  call this%pakcsvtab%finalize_table()
3209  end if
3210  end if
3211  end if
3212  end subroutine csub_cc
3213 
3214  !> @ brief Calculate flows for package
3215  !!
3216  !! Flow calculation for the CSUB package components. Components include
3217  !! coarse-grained storage, delay and no-delay interbeds, and water
3218  !! compressibility.
3219  !!
3220  !! @param[in,out] model_budget model budget object
3221  !!
3222  !<
3223  subroutine csub_cq(this, nodes, hnew, hold, isuppress_output, flowja)
3224  ! -- modules
3225  use tdismodule, only: delt
3226  use constantsmodule, only: lenboundname, dzero, done
3227  ! -- dummy variables
3228  class(gwfcsubtype) :: this
3229  integer(I4B), intent(in) :: nodes !< number of active model nodes
3230  real(DP), intent(in), dimension(nodes) :: hnew !< current head
3231  real(DP), intent(in), dimension(nodes) :: hold !< head for the previous time step
3232  integer(I4B), intent(in) :: isuppress_output !< flag indicating if budget output should be suppressed
3233  real(DP), dimension(:), contiguous, intent(inout) :: flowja
3234  ! -- local variables
3235  integer(I4B) :: ib
3236  integer(I4B) :: idelay
3237  integer(I4B) :: ielastic
3238  integer(I4B) :: iconvert
3239  integer(I4B) :: node
3240  integer(I4B) :: nn
3241  integer(I4B) :: n
3242  integer(I4B) :: idiag
3243  real(DP) :: es
3244  real(DP) :: pcs
3245  real(DP) :: rho1
3246  real(DP) :: rho2
3247  real(DP) :: tled
3248  real(DP) :: tledm
3249  real(DP) :: es0
3250  real(DP) :: rrate
3251  real(DP) :: ratein
3252  real(DP) :: rateout
3253  real(DP) :: comp
3254  real(DP) :: compi
3255  real(DP) :: compe
3256  real(DP) :: area
3257  real(DP) :: h
3258  real(DP) :: h0
3259  real(DP) :: snnew
3260  real(DP) :: snold
3261  real(DP) :: hcof
3262  real(DP) :: rhs
3263  real(DP) :: stoe
3264  real(DP) :: stoi
3265  real(DP) :: b
3266  real(DP) :: q
3267  real(DP) :: rratewc
3268  ! -- for observations
3269  integer(I4B) :: iprobslocal
3270  ! -- formats
3271  !
3272  ! -- Suppress saving of simulated values; they
3273  ! will be saved at end of this procedure.
3274  iprobslocal = 0
3275  ratein = dzero
3276  rateout = dzero
3277  !
3278  ! -- coarse-grained coarse-grained storage
3279  do node = 1, this%dis%nodes
3280  idiag = this%dis%con%ia(node)
3281  area = this%dis%get_area(node)
3282  comp = dzero
3283  rrate = dzero
3284  rratewc = dzero
3285  if (this%gwfiss == 0) then
3286  if (delt > dzero) then
3287  tled = done / delt
3288  else
3289  tled = dzero
3290  end if
3291  if (this%ibound(node) > 0 .and. this%cg_thickini(node) > dzero) then
3292  !
3293  ! -- calculate coarse-grained storage terms
3294  call this%csub_cg_fc(node, tled, area, hnew(node), hold(node), &
3295  hcof, rhs)
3296  rrate = hcof * hnew(node) - rhs
3297  !
3298  ! -- calculate compaction
3299  call this%csub_cg_calc_comp(node, hnew(node), hold(node), comp)
3300  !
3301  ! -- calculate coarse-grained water compressibility storage terms
3302  call this%csub_cg_wcomp_fc(node, tled, area, hnew(node), hold(node), &
3303  hcof, rhs)
3304  rratewc = hcof * hnew(node) - rhs
3305  end if
3306  end if
3307  !
3308  ! -- update coarse-grained storage and water
3309  ! compression variables
3310  this%cg_stor(node) = rrate
3311  this%cell_wcstor(node) = rratewc
3312  this%cell_thick(node) = this%cg_thick(node)
3313  !
3314  ! -- update incremental coarse-grained compaction
3315  this%cg_comp(node) = comp
3316  !
3317  !
3318  ! -- update states if required
3319  if (isuppress_output == 0) then
3320  !
3321  ! -- calculate strain and change in coarse-grained void ratio and thickness
3322  ! todo: consider moving error check in csub_cg_update to ot()
3323  if (this%iupdatematprop /= 0) then
3324  call this%csub_cg_update(node)
3325  end if
3326  !
3327  ! -- update total compaction
3328  this%cg_tcomp(node) = this%cg_tcomp(node) + comp
3329  end if
3330  !
3331  ! -- update flowja
3332  flowja(idiag) = flowja(idiag) + rrate
3333  flowja(idiag) = flowja(idiag) + rratewc
3334  end do
3335  !
3336  ! -- interbed storage
3337  !
3338  ! -- reset delay bed counters for the current time step
3339  if (this%ndelaybeds > 0) then
3340  this%idb_nconv_count(1) = 0
3341  end if
3342  !
3343  ! -- initialize tled
3344  tled = done
3345  !
3346  ! -- calculate budget terms for each interbed
3347  do ib = 1, this%ninterbeds
3348  rratewc = dzero
3349  idelay = this%idelay(ib)
3350  ielastic = this%ielastic(ib)
3351  !
3352  ! -- calculate interbed thickness
3353  ! -- no delay interbeds
3354  if (idelay == 0) then
3355  b = this%thick(ib)
3356  ! -- delay interbeds
3357  else
3358  b = this%thick(ib) * this%rnb(ib)
3359  end if
3360  !
3361  ! -- set variables required for no-delay and delay interbeds
3362  node = this%nodelist(ib)
3363  idiag = this%dis%con%ia(node)
3364  area = this%dis%get_area(node)
3365  !
3366  ! -- add interbed thickness to cell thickness
3367  this%cell_thick(node) = this%cell_thick(node) + b
3368  !
3369  ! -- update budget terms if transient stress period
3370  if (this%gwfiss == 0) then
3371  if (delt > dzero) then
3372  tledm = done / delt
3373  else
3374  tledm = dzero
3375  end if
3376  !
3377  ! -- skip inactive and constant head cells
3378  if (this%ibound(node) < 1) cycle
3379  !
3380  ! -- no delay interbeds
3381  if (idelay == 0) then
3382  iconvert = this%iconvert(ib)
3383  stoi = dzero
3384  !
3385  ! -- calculate compaction
3386  call this%csub_nodelay_calc_comp(ib, hnew(node), hold(node), comp, &
3387  rho1, rho2)
3388  !
3389  ! -- interbed stresses
3390  es = this%cg_es(node)
3391  pcs = this%pcs(ib)
3392  es0 = this%cg_es0(node)
3393  !
3394  ! -- calculate inelastic and elastic compaction
3395  if (ielastic > 0 .or. iconvert == 0) then
3396  stoe = comp
3397  else
3398  stoi = -pcs * rho2 + (rho2 * es)
3399  stoe = pcs * rho1 - (rho1 * es0)
3400  end if
3401  compe = stoe
3402  compi = stoi
3403  stoe = stoe * area
3404  stoi = stoi * area
3405  this%storagee(ib) = stoe * tledm
3406  this%storagei(ib) = stoi * tledm
3407  !
3408  ! -- update compaction
3409  this%comp(ib) = comp
3410  !
3411  ! -- update states if required
3412  if (isuppress_output == 0) then
3413  !
3414  ! -- calculate strain and change in interbed void ratio and thickness
3415  if (this%iupdatematprop /= 0) then
3416  call this%csub_nodelay_update(ib)
3417  end if
3418  !
3419  ! -- update total compaction
3420  this%tcomp(ib) = this%tcomp(ib) + comp
3421  this%tcompe(ib) = this%tcompe(ib) + compe
3422  this%tcompi(ib) = this%tcompi(ib) + compi
3423  end if
3424  !
3425  ! -- delay interbeds
3426  else
3427  h = hnew(node)
3428  h0 = hold(node)
3429  !
3430  ! -- calculate cell saturation
3431  call this%csub_calc_sat(node, h, h0, snnew, snold)
3432  !
3433  ! -- calculate inelastic and elastic storage contributions
3434  call this%csub_delay_calc_dstor(ib, h, stoe, stoi)
3435  this%storagee(ib) = stoe * area * this%rnb(ib) * tledm
3436  this%storagei(ib) = stoi * area * this%rnb(ib) * tledm
3437  !
3438  ! -- calculate flow across the top and bottom of the delay interbed
3439  q = this%csub_calc_delay_flow(ib, 1, h) * area * this%rnb(ib)
3440  this%dbflowtop(idelay) = q
3441  nn = this%ndelaycells
3442  q = this%csub_calc_delay_flow(ib, nn, h) * area * this%rnb(ib)
3443  this%dbflowbot(idelay) = q
3444  !
3445  ! -- update states if required
3446  if (isuppress_output == 0) then
3447  !
3448  ! -- calculate sum of compaction in delay interbed
3449  call this%csub_delay_calc_comp(ib, h, h0, comp, compi, compe)
3450  !
3451  ! - calculate strain and change in interbed void ratio and thickness
3452  ! todo: consider moving error check in csub_delay_update to ot()
3453  if (this%iupdatematprop /= 0) then
3454  call this%csub_delay_update(ib)
3455  end if
3456  !
3457  ! -- update total compaction for interbed
3458  this%tcomp(ib) = this%tcomp(ib) + comp
3459  this%tcompi(ib) = this%tcompi(ib) + compi
3460  this%tcompe(ib) = this%tcompe(ib) + compe
3461  !
3462  ! -- update total compaction for each delay bed cell
3463  do n = 1, this%ndelaycells
3464  this%dbtcomp(n, idelay) = this%dbtcomp(n, idelay) + &
3465  this%dbcomp(n, idelay)
3466  end do
3467  !
3468  ! -- check delay bed heads relative to the top and bottom of each
3469  ! delay bed cell for convertible and non-convertible gwf cells
3470  call this%csub_delay_head_check(ib)
3471  end if
3472  end if
3473  !
3474  ! -- interbed water compressibility
3475  !
3476  ! -- no-delay interbed
3477  if (idelay == 0) then
3478  call this%csub_nodelay_wcomp_fc(ib, node, tledm, area, &
3479  hnew(node), hold(node), hcof, rhs)
3480  rratewc = hcof * hnew(node) - rhs
3481  !
3482  ! -- delay interbed
3483  else
3484  call this%csub_delay_calc_wcomp(ib, q)
3485  rratewc = q * area * this%rnb(ib)
3486  end if
3487  this%cell_wcstor(node) = this%cell_wcstor(node) + rratewc
3488  !
3489  ! -- flowja
3490  flowja(idiag) = flowja(idiag) + rratewc
3491  else
3492  this%storagee(ib) = dzero
3493  this%storagei(ib) = dzero
3494  if (idelay /= 0) then
3495  this%dbflowtop(idelay) = dzero
3496  this%dbflowbot(idelay) = dzero
3497  end if
3498  end if
3499  !
3500  ! -- flowja
3501  flowja(idiag) = flowja(idiag) + this%storagee(ib)
3502  flowja(idiag) = flowja(idiag) + this%storagei(ib)
3503  end do
3504  !
3505  ! -- terminate if errors encountered when updating material properties
3506  if (this%iupdatematprop /= 0) then
3507  if (count_errors() > 0) then
3508  call this%parser%StoreErrorUnit()
3509  end if
3510  end if
3511  end subroutine csub_cq
3512 
3513  !> @ brief Model budget calculation for package
3514  !!
3515  !! Budget calculation for the CSUB package components. Components include
3516  !! coarse-grained storage, delay and no-delay interbeds, and water
3517  !! compressibility.
3518  !!
3519  !! @param[in,out] model_budget model budget object
3520  !!
3521  !<
3522  subroutine csub_bd(this, isuppress_output, model_budget)
3523  ! -- modules
3524  use tdismodule, only: delt
3525  use constantsmodule, only: lenboundname, dzero, done
3527  ! -- dummy variables
3528  class(gwfcsubtype) :: this
3529  integer(I4B), intent(in) :: isuppress_output
3530  type(budgettype), intent(inout) :: model_budget !< model budget object
3531  ! -- local
3532  real(DP) :: rin
3533  real(DP) :: rout
3534  !
3535  ! -- interbed elastic storage (this%cg_stor)
3536  call rate_accumulator(this%cg_stor, rin, rout)
3537  call model_budget%addentry(rin, rout, delt, budtxt(1), &
3538  isuppress_output, ' CSUB')
3539  if (this%ninterbeds > 0) then
3540  !
3541  ! -- interbed elastic storage (this%storagee)
3542  call rate_accumulator(this%storagee, rin, rout)
3543  call model_budget%addentry(rin, rout, delt, budtxt(2), &
3544  isuppress_output, ' CSUB')
3545  !
3546  ! -- interbed elastic storage (this%storagei)
3547  call rate_accumulator(this%storagei, rin, rout)
3548  call model_budget%addentry(rin, rout, delt, budtxt(3), &
3549  isuppress_output, ' CSUB')
3550  end if
3551  call rate_accumulator(this%cell_wcstor, rin, rout)
3552  call model_budget%addentry(rin, rout, delt, budtxt(4), &
3553  isuppress_output, ' CSUB')
3554  return
3555  end subroutine csub_bd
3556 
3557 !> @ brief Save model flows for package
3558 !!
3559 !! Save cell-by-cell budget terms for the CSUB package.
3560 !!
3561 !<
3562  subroutine csub_save_model_flows(this, icbcfl, icbcun)
3563  ! -- dummy variables
3564  class(gwfcsubtype) :: this
3565  integer(I4B), intent(in) :: icbcfl !< flag to output budget data
3566  integer(I4B), intent(in) :: icbcun !< unit number for cell-by-cell file
3567  ! -- local variables
3568  character(len=1) :: cdatafmp = ' '
3569  character(len=1) :: editdesc = ' '
3570  integer(I4B) :: ibinun
3571  integer(I4B) :: iprint
3572  integer(I4B) :: nvaluesp
3573  integer(I4B) :: nwidthp
3574  integer(I4B) :: ib
3575  integer(I4B) :: node
3576  integer(I4B) :: naux
3577  real(DP) :: dinact
3578  real(DP) :: Q
3579  ! -- formats
3580  !
3581  ! -- Set unit number for binary output
3582  if (this%ipakcb < 0) then
3583  ibinun = icbcun
3584  elseif (this%ipakcb == 0) then
3585  ibinun = 0
3586  else
3587  ibinun = this%ipakcb
3588  end if
3589  if (icbcfl == 0) ibinun = 0
3590  !
3591  ! -- Record the storage rates if requested
3592  if (ibinun /= 0) then
3593  iprint = 0
3594  dinact = dzero
3595  !
3596  ! -- coarse-grained storage (sske)
3597  call this%dis%record_array(this%cg_stor, this%iout, iprint, -ibinun, &
3598  budtxt(1), cdatafmp, nvaluesp, &
3599  nwidthp, editdesc, dinact)
3600  if (this%ninterbeds > 0) then
3601  naux = 0
3602  !
3603  ! -- interbed elastic storage
3604  call this%dis%record_srcdst_list_header(budtxt(2), &
3605  this%name_model, &
3606  this%name_model, &
3607  this%name_model, &
3608  this%packName, &
3609  naux, &
3610  this%auxname, &
3611  ibinun, &
3612  this%ninterbeds, &
3613  this%iout)
3614  do ib = 1, this%ninterbeds
3615  q = this%storagee(ib)
3616  node = this%nodelist(ib)
3617  call this%dis%record_mf6_list_entry(ibinun, node, node, q, naux, &
3618  this%auxvar(:, ib))
3619  end do
3620  !
3621  ! -- interbed inelastic storage
3622  call this%dis%record_srcdst_list_header(budtxt(3), &
3623  this%name_model, &
3624  this%name_model, &
3625  this%name_model, &
3626  this%packName, &
3627  naux, &
3628  this%auxname, &
3629  ibinun, &
3630  this%ninterbeds, &
3631  this%iout)
3632  do ib = 1, this%ninterbeds
3633  q = this%storagei(ib)
3634  node = this%nodelist(ib)
3635  call this%dis%record_mf6_list_entry(ibinun, node, node, q, naux, &
3636  this%auxvar(:, ib))
3637  end do
3638  end if
3639  !
3640  ! -- water compressibility
3641  call this%dis%record_array(this%cell_wcstor, this%iout, iprint, -ibinun, &
3642  budtxt(4), cdatafmp, nvaluesp, &
3643  nwidthp, editdesc, dinact)
3644  end if
3645  end subroutine csub_save_model_flows
3646 
3647 !> @ brief Save and print dependent values for package
3648 !!
3649 !! Method saves cell-by-cell compaction and z-displacement terms. The method
3650 !! also calls the method to process observation output.
3651 !!
3652 !<
3653  subroutine csub_ot_dv(this, idvfl, idvprint)
3654  ! -- dummy variables
3655  class(gwfcsubtype) :: this
3656  integer(I4B), intent(in) :: idvfl !< flag to save dependent variable data
3657  integer(I4B), intent(in) :: idvprint !< flag to print dependent variable data
3658  ! -- local variables
3659  character(len=1) :: cdatafmp = ' '
3660  character(len=1) :: editdesc = ' '
3661  integer(I4B) :: ibinun
3662  integer(I4B) :: iprint
3663  integer(I4B) :: nvaluesp
3664  integer(I4B) :: nwidthp
3665  integer(I4B) :: ib
3666  integer(I4B) :: node
3667  integer(I4B) :: nodem
3668  integer(I4B) :: nodeu
3669  integer(I4B) :: i
3670  integer(I4B) :: ii
3671  integer(I4B) :: idx_conn
3672  integer(I4B) :: k
3673  integer(I4B) :: ncpl
3674  integer(I4B) :: nlay
3675  integer(I4B) :: ihc
3676  real(DP) :: dinact
3677  real(DP) :: va_scale
3678  ! -- formats
3679  character(len=*), parameter :: fmtnconv = &
3680  "(/4x, 'DELAY INTERBED CELL HEADS IN ', i0, ' INTERBEDS IN', &
3681  &' NON-CONVERTIBLE GWF CELLS WERE LESS THAN THE TOP OF THE INTERBED CELL')"
3682  !
3683  ! -- Save compaction results
3684  !
3685  ! -- Set unit number for binary compaction and z-displacement output
3686  if (this%ioutcomp /= 0 .or. this%ioutzdisp /= 0) then
3687  ibinun = 1
3688  else
3689  ibinun = 0
3690  end if
3691  if (idvfl == 0) ibinun = 0
3692  !
3693  ! -- save compaction results
3694  if (ibinun /= 0) then
3695  iprint = 0
3696  dinact = dhnoflo
3697  !
3698  ! -- fill buff with total compaction
3699  do node = 1, this%dis%nodes
3700  this%buff(node) = this%cg_tcomp(node)
3701  end do
3702  do ib = 1, this%ninterbeds
3703  node = this%nodelist(ib)
3704  this%buff(node) = this%buff(node) + this%tcomp(ib)
3705  end do
3706  !
3707  ! -- write compaction data to binary file
3708  if (this%ioutcomp /= 0) then
3709  ibinun = this%ioutcomp
3710  call this%dis%record_array(this%buff, this%iout, iprint, ibinun, &
3711  comptxt(1), cdatafmp, nvaluesp, &
3712  nwidthp, editdesc, dinact)
3713  end if
3714  !
3715  ! -- calculate z-displacement (subsidence) and write data to binary file
3716  if (this%ioutzdisp /= 0) then
3717  ibinun = this%ioutzdisp
3718  !
3719  ! -- initialize buffusr
3720  do nodeu = 1, this%dis%nodesuser
3721  this%buffusr(nodeu) = dzero
3722  end do
3723  !
3724  ! -- fill buffusr with buff
3725  do node = 1, this%dis%nodes
3726  nodeu = this%dis%get_nodeuser(node)
3727  this%buffusr(nodeu) = this%buff(node)
3728  end do
3729  !
3730  ! -- calculate z-displacement
3731  ncpl = this%dis%get_ncpl()
3732  !
3733  ! -- disu
3734  if (this%dis%ndim == 1) then
3735  do node = this%dis%nodes, 1, -1
3736  do ii = this%dis%con%ia(node) + 1, this%dis%con%ia(node + 1) - 1
3737  !
3738  ! -- Set the m cell number
3739  nodem = this%dis%con%ja(ii)
3740  idx_conn = this%dis%con%jas(ii)
3741  !
3742  ! -- vertical connection
3743  ihc = this%dis%con%ihc(idx_conn)
3744  if (ihc == 0) then
3745  !
3746  ! -- node has an underlying cell
3747  if (node < nodem) then
3748  va_scale = this%dis%get_area_factor(node, idx_conn)
3749  this%buffusr(node) = this%buffusr(node) + &
3750  va_scale * this%buffusr(nodem)
3751  end if
3752  end if
3753  end do
3754  end do
3755  ! -- disv or dis
3756  else
3757  nlay = this%dis%nodesuser / ncpl
3758  do k = nlay - 1, 1, -1
3759  do i = 1, ncpl
3760  node = (k - 1) * ncpl + i
3761  nodem = k * ncpl + i
3762  this%buffusr(node) = this%buffusr(node) + this%buffusr(nodem)
3763  end do
3764  end do
3765  end if
3766  !
3767  ! -- fill buff with data from buffusr
3768  do nodeu = 1, this%dis%nodesuser
3769  node = this%dis%get_nodenumber_idx1(nodeu, 1)
3770  if (node > 0) then
3771  this%buff(node) = this%buffusr(nodeu)
3772  end if
3773  end do
3774  !
3775  ! -- write z-displacement
3776  call this%dis%record_array(this%buff, this%iout, iprint, ibinun, &
3777  comptxt(6), cdatafmp, nvaluesp, &
3778  nwidthp, editdesc, dinact)
3779 
3780  end if
3781  end if
3782  !
3783  ! -- Set unit number for binary inelastic interbed compaction
3784  if (this%ioutcompi /= 0) then
3785  ibinun = this%ioutcompi
3786  else
3787  ibinun = 0
3788  end if
3789  if (idvfl == 0) ibinun = 0
3790  !
3791  ! -- save inelastic interbed compaction results
3792  if (ibinun /= 0) then
3793  iprint = 0
3794  dinact = dhnoflo
3795  !
3796  ! -- fill buff with inelastic interbed compaction
3797  do node = 1, this%dis%nodes
3798  this%buff(node) = dzero
3799  end do
3800  do ib = 1, this%ninterbeds
3801  node = this%nodelist(ib)
3802  this%buff(node) = this%buff(node) + this%tcompi(ib)
3803  end do
3804  !
3805  ! -- write inelastic interbed compaction data to binary file
3806  call this%dis%record_array(this%buff, this%iout, iprint, ibinun, &
3807  comptxt(2), cdatafmp, nvaluesp, &
3808  nwidthp, editdesc, dinact)
3809  end if
3810  !
3811  ! -- Set unit number for binary elastic interbed compaction
3812  if (this%ioutcompe /= 0) then
3813  ibinun = this%ioutcompe
3814  else
3815  ibinun = 0
3816  end if
3817  if (idvfl == 0) ibinun = 0
3818  !
3819  ! -- save elastic interbed compaction results
3820  if (ibinun /= 0) then
3821  iprint = 0
3822  dinact = dhnoflo
3823  !
3824  ! -- fill buff with elastic interbed compaction
3825  do node = 1, this%dis%nodes
3826  this%buff(node) = dzero
3827  end do
3828  do ib = 1, this%ninterbeds
3829  node = this%nodelist(ib)
3830  this%buff(node) = this%buff(node) + this%tcompe(ib)
3831  end do
3832  !
3833  ! -- write elastic interbed compaction data to binary file
3834  call this%dis%record_array(this%buff, this%iout, iprint, ibinun, &
3835  comptxt(3), cdatafmp, nvaluesp, &
3836  nwidthp, editdesc, dinact)
3837  end if
3838  !
3839  ! -- Set unit number for binary interbed compaction
3840  if (this%ioutcompib /= 0) then
3841  ibinun = this%ioutcompib
3842  else
3843  ibinun = 0
3844  end if
3845  if (idvfl == 0) ibinun = 0
3846  !
3847  ! -- save interbed compaction results
3848  if (ibinun /= 0) then
3849  iprint = 0
3850  dinact = dhnoflo
3851  !
3852  ! -- fill buff with interbed compaction
3853  do node = 1, this%dis%nodes
3854  this%buff(node) = dzero
3855  end do
3856  do ib = 1, this%ninterbeds
3857  node = this%nodelist(ib)
3858  this%buff(node) = this%buff(node) + this%tcompe(ib) + this%tcompi(ib)
3859  end do
3860  !
3861  ! -- write interbed compaction data to binary file
3862  call this%dis%record_array(this%buff, this%iout, iprint, ibinun, &
3863  comptxt(4), cdatafmp, nvaluesp, &
3864  nwidthp, editdesc, dinact)
3865  end if
3866  !
3867  ! -- Set unit number for binary coarse-grained compaction
3868  if (this%ioutcomps /= 0) then
3869  ibinun = this%ioutcomps
3870  else
3871  ibinun = 0
3872  end if
3873  if (idvfl == 0) ibinun = 0
3874  !
3875  ! -- save coarse-grained compaction results
3876  if (ibinun /= 0) then
3877  iprint = 0
3878  dinact = dhnoflo
3879  !
3880  ! -- fill buff with coarse-grained compaction
3881  do node = 1, this%dis%nodes
3882  this%buff(node) = this%cg_tcomp(node)
3883  end do
3884  !
3885  ! -- write coarse-grained compaction data to binary file
3886  call this%dis%record_array(this%buff, this%iout, iprint, ibinun, &
3887  comptxt(5), cdatafmp, nvaluesp, &
3888  nwidthp, editdesc, dinact)
3889  end if
3890  !
3891  ! -- check that final effective stress values for the time step
3892  ! are greater than zero
3893  if (this%gwfiss == 0) then
3894  call this%csub_cg_chk_stress()
3895  end if
3896  !
3897  ! -- update maximum count of delay interbeds that violate
3898  ! basic head assumptions for delay beds and write a message
3899  ! for delay interbeds in non-convertible gwf cells that
3900  ! violate these head assumptions
3901  if (this%ndelaybeds > 0) then
3902  if (this%idb_nconv_count(1) > this%idb_nconv_count(2)) then
3903  this%idb_nconv_count(2) = this%idb_nconv_count(1)
3904  end if
3905  if (this%idb_nconv_count(1) > 0) then
3906  write (this%iout, fmtnconv) this%idb_nconv_count(1)
3907  end if
3908  end if
3909  end subroutine csub_ot_dv
3910 
3911  !> @ brief Calculate the stress for model cells
3912  !!
3913  !! Method calculates the geostatic stress, pressure head, and effective
3914  !! stress at the bottom of each cell. The method also applies the overlying
3915  !! geostatic stress (sig0) not represented in the model.
3916  !!
3917  !<
3918  subroutine csub_cg_calc_stress(this, nodes, hnew)
3919  ! -- dummy variables
3920  class(gwfcsubtype) :: this
3921  integer(I4B), intent(in) :: nodes !< number of active model nodes
3922  real(DP), dimension(nodes), intent(in) :: hnew !< current head
3923  ! -- local variables
3924  integer(I4B) :: node
3925  integer(I4B) :: ii
3926  integer(I4B) :: nn
3927  integer(I4B) :: m
3928  integer(I4B) :: idx_conn
3929  real(DP) :: gs
3930  real(DP) :: top
3931  real(DP) :: bot
3932  real(DP) :: thick
3933  real(DP) :: va_scale
3934  real(DP) :: hcell
3935  real(DP) :: hbar
3936  real(DP) :: gs_conn
3937  real(DP) :: es
3938  real(DP) :: phead
3939  real(DP) :: sadd
3940  !
3941  ! -- calculate geostatic stress if necessary
3942  if (this%iupdatestress /= 0) then
3943  do node = 1, this%dis%nodes
3944  !
3945  ! -- calculate geostatic stress for this node
3946  ! this represents the geostatic stress component
3947  ! for the cell
3948  top = this%dis%top(node)
3949  bot = this%dis%bot(node)
3950  thick = top - bot
3951  !
3952  ! -- calculate cell contribution to geostatic stress
3953  if (this%ibound(node) /= 0) then
3954  hcell = hnew(node)
3955  else
3956  hcell = bot
3957  end if
3958  !
3959  ! -- calculate corrected head (hbar)
3960  hbar = squadratic0sp(hcell, bot, this%satomega)
3961  !
3962  ! -- geostatic stress calculation
3963  if (hcell < top) then
3964  gs = (top - hbar) * this%sgm(node) + (hbar - bot) * this%sgs(node)
3965  else
3966  gs = thick * this%sgs(node)
3967  end if
3968  !
3969  ! -- cell contribution to geostatic stress
3970  this%cg_gs(node) = gs
3971  end do
3972  !
3973  ! -- add user specified overlying geostatic stress
3974  do nn = 1, this%nbound
3975  node = this%nodelistsig0(nn)
3976  sadd = this%sig0(nn)
3977  this%cg_gs(node) = this%cg_gs(node) + sadd
3978  end do
3979  !
3980  ! -- calculate geostatic stress above cell
3981  do node = 1, this%dis%nodes
3982  !
3983  ! -- geostatic stress of cell
3984  gs = this%cg_gs(node)
3985  !
3986  ! -- Add geostatic stress of overlying cells (ihc=0)
3987  ! m < node = m is vertically above node
3988  do ii = this%dis%con%ia(node) + 1, this%dis%con%ia(node + 1) - 1
3989  !
3990  ! -- Set the m cell number
3991  m = this%dis%con%ja(ii)
3992  idx_conn = this%dis%con%jas(ii)
3993  !
3994  ! -- vertical connection
3995  if (this%dis%con%ihc(idx_conn) == 0) then
3996  !
3997  ! -- node has an overlying cell
3998  if (m < node) then
3999  !
4000  ! -- dis and disv discretization
4001  if (this%dis%ndim /= 1) then
4002  gs = gs + this%cg_gs(m)
4003  !
4004  ! -- disu discretization
4005  else
4006  va_scale = this%dis%get_area_factor(node, idx_conn)
4007  gs_conn = this%cg_gs(m)
4008  gs = gs + (gs_conn * va_scale)
4009  end if
4010  end if
4011  end if
4012  end do
4013  !
4014  ! -- geostatic stress for cell with geostatic stress
4015  ! of overlying cells
4016  this%cg_gs(node) = gs
4017  end do
4018  end if
4019  !
4020  ! -- save effective stress from the last iteration and
4021  ! calculate the new effective stress for a cell
4022  do node = 1, this%dis%nodes
4023  top = this%dis%top(node)
4024  bot = this%dis%bot(node)
4025  if (this%ibound(node) /= 0) then
4026  hcell = hnew(node)
4027  else
4028  hcell = bot
4029  end if
4030  !
4031  ! -- calculate corrected head (hbar)
4032  hbar = squadratic0sp(hcell, bot, this%satomega)
4033  !
4034  ! -- calculate pressure head
4035  phead = hbar - bot
4036  !
4037  ! -- calculate effective stress
4038  es = this%cg_gs(node) - phead
4039  this%cg_es(node) = es
4040  end do
4041  end subroutine csub_cg_calc_stress
4042 
4043  !> @ brief Check effective stress values
4044  !!
4045  !! Method checks calculated effective stress values to ensure that
4046  !! effective stress values are positive. An error condition and message are
4047  !! issued if calculated effective stress values are less than a small positive
4048  !! value (DEM6).
4049  !!
4050  !<
4051  subroutine csub_cg_chk_stress(this)
4052  ! -- dummy variables
4053  class(gwfcsubtype) :: this
4054  ! -- local variables
4055  character(len=20) :: cellid
4056  integer(I4B) :: ierr
4057  integer(I4B) :: node
4058  real(DP) :: gs
4059  real(DP) :: bot
4060  real(DP) :: hcell
4061  real(DP) :: es
4062  real(DP) :: phead
4063  !
4064  ! -- initialize variables
4065  ierr = 0
4066  !
4067  ! -- check geostatic stress if necessary
4068  !
4069  ! -- save effective stress from the last iteration and
4070  ! calculate the new effective stress for a cell
4071  do node = 1, this%dis%nodes
4072  if (this%ibound(node) < 1) cycle
4073  bot = this%dis%bot(node)
4074  gs = this%cg_gs(node)
4075  es = this%cg_es(node)
4076  phead = dzero
4077  if (this%ibound(node) /= 0) then
4078  phead = gs - es
4079  end if
4080  hcell = phead + bot
4081  if (this%lhead_based .EQV. .false.) then
4082  if (es < dem6) then
4083  ierr = ierr + 1
4084  call this%dis%noder_to_string(node, cellid)
4085  write (errmsg, '(a,g0,a,1x,a,1x,a,4(g0,a))') &
4086  'Small to negative effective stress (', es, ') in cell', &
4087  trim(adjustl(cellid)), '. (', es, ' = ', this%cg_gs(node), &
4088  ' - (', hcell, ' - ', bot, ').'
4089  call store_error(errmsg)
4090  end if
4091  end if
4092  end do
4093  !
4094  ! -- write a summary error message
4095  if (ierr > 0) then
4096  write (errmsg, '(a,1x,i0,3(1x,a))') &
4097  'Solution: small to negative effective stress values in', ierr, &
4098  'cells can be eliminated by increasing storage values and/or ', &
4099  'adding/modifying stress boundaries to prevent water-levels from', &
4100  'exceeding the top of the model.'
4101  call store_error(errmsg)
4102  call this%parser%StoreErrorUnit()
4103  end if
4104  end subroutine csub_cg_chk_stress
4105 
4106  !> @ brief Update no-delay material properties
4107  !!
4108  !! Method updates no-delay material properties based on the current
4109  !! compaction value.
4110  !!
4111  !<
4112  subroutine csub_nodelay_update(this, i)
4113  ! -- dummy variables
4114  class(gwfcsubtype), intent(inout) :: this
4115  integer(I4B), intent(in) :: i
4116  ! -- local variables
4117  real(DP) :: comp
4118  real(DP) :: thick
4119  real(DP) :: theta
4120  !
4121  ! -- update thickness and theta
4122  comp = this%tcomp(i) + this%comp(i)
4123  if (abs(comp) > dzero) then
4124  thick = this%thickini(i)
4125  theta = this%thetaini(i)
4126  call this%csub_adj_matprop(comp, thick, theta)
4127  if (thick <= dzero) then
4128  write (errmsg, '(a,1x,i0,1x,a,g0,a)') &
4129  'Adjusted thickness for no-delay interbed', i, &
4130  'is less than or equal to 0 (', thick, ').'
4131  call store_error(errmsg)
4132  end if
4133  if (theta <= dzero) then
4134  write (errmsg, '(a,1x,i0,1x,a,g0,a)') &
4135  'Adjusted theta for no-delay interbed', i, &
4136  'is less than or equal to 0 (', theta, ').'
4137  call store_error(errmsg)
4138  end if
4139  this%thick(i) = thick
4140  this%theta(i) = theta
4141  end if
4142  end subroutine csub_nodelay_update
4143 
4144  !> @ brief Calculate no-delay interbed storage coefficients
4145  !!
4146  !! Method calculates the skeletal storage coefficients for a no-delay
4147  !! interbed. The method also calculates the contribution of the
4148  !! no-delay interbed to the right-hand side of the groundwater flow
4149  !! equation for the cell.
4150  !!
4151  !! @param[in,out] rho1 no-delay storage value using Sske
4152  !! @param[in,out] rho2 no-delay storage value using Ssk
4153  !! @param[in,out] rhs no-delay right-hand side contribution
4154  !!
4155  !<
4156  subroutine csub_nodelay_fc(this, ib, hcell, hcellold, rho1, rho2, rhs, &
4157  argtled)
4158  ! -- modules
4159  use tdismodule, only: delt
4160  ! -- dummy variables
4161  class(gwfcsubtype) :: this
4162  integer(I4B), intent(in) :: ib !< interbed number
4163  real(DP), intent(in) :: hcell !< current head in the cell
4164  real(DP), intent(in) :: hcellold !< previous head in the cell
4165  real(DP), intent(inout) :: rho1 !< current storage coefficient value using Sske
4166  real(DP), intent(inout) :: rho2 !< current storage coefficient value based on Ssk
4167  real(DP), intent(inout) :: rhs !< no-delay interbed contribution to the right-hand side
4168  real(DP), intent(in), optional :: argtled !< optional reciprocal of the time step length
4169  ! -- local variables
4170  integer(I4B) :: node
4171  real(DP) :: tled
4172  real(DP) :: top
4173  real(DP) :: bot
4174  real(DP) :: thick
4175  real(DP) :: hbar
4176  real(DP) :: znode
4177  real(DP) :: snold
4178  real(DP) :: snnew
4179  real(DP) :: sto_fac
4180  real(DP) :: sto_fac0
4181  real(DP) :: area
4182  real(DP) :: theta
4183  real(DP) :: es
4184  real(DP) :: es0
4185  real(DP) :: f
4186  real(DP) :: f0
4187  real(DP) :: rcorr
4188  !
4189  ! -- process optional variables
4190  if (present(argtled)) then
4191  tled = argtled
4192  else
4193  tled = done / delt
4194  end if
4195  node = this%nodelist(ib)
4196  area = this%dis%get_area(node)
4197  bot = this%dis%bot(node)
4198  top = this%dis%top(node)
4199  thick = this%thickini(ib)
4200  !
4201  ! -- calculate corrected head (hbar)
4202  hbar = squadratic0sp(hcell, bot, this%satomega)
4203  !
4204  ! -- set iconvert
4205  this%iconvert(ib) = 0
4206  !
4207  ! -- aquifer saturation
4208  call this%csub_calc_sat(node, hcell, hcellold, snnew, snold)
4209  if (this%lhead_based .EQV. .true.) then
4210  f = done
4211  f0 = done
4212  else
4213  znode = this%csub_calc_znode(top, bot, hbar)
4214  es = this%cg_es(node)
4215  es0 = this%cg_es0(node)
4216  theta = this%thetaini(ib)
4217  !
4218  ! -- calculate the compression index factors for the delay
4219  ! node relative to the center of the cell based on the
4220  ! current and previous head
4221  call this%csub_calc_sfacts(node, bot, znode, theta, es, es0, f)
4222  end if
4223  sto_fac = tled * snnew * thick * f
4224  sto_fac0 = tled * snold * thick * f
4225  !
4226  ! -- calculate rho1 and rho2
4227  rho1 = this%rci(ib) * sto_fac0
4228  rho2 = this%rci(ib) * sto_fac
4229  if (this%cg_es(node) > this%pcs(ib)) then
4230  this%iconvert(ib) = 1
4231  rho2 = this%ci(ib) * sto_fac
4232  end if
4233  !
4234  ! -- calculate correction term
4235  rcorr = rho2 * (hcell - hbar)
4236  !
4237  ! -- fill right-hand side
4238  if (this%ielastic(ib) /= 0) then
4239  rhs = rho1 * this%cg_es0(node) - &
4240  rho2 * (this%cg_gs(node) + bot) - &
4241  rcorr
4242  else
4243  rhs = -rho2 * (this%cg_gs(node) + bot) + &
4244  (this%pcs(ib) * (rho2 - rho1)) + &
4245  (rho1 * this%cg_es0(node)) - &
4246  rcorr
4247  end if
4248  !
4249  ! -- save ske and sk
4250  this%ske(ib) = rho1
4251  this%sk(ib) = rho2
4252  end subroutine csub_nodelay_fc
4253 
4254  !> @ brief Calculate no-delay interbed compaction
4255  !!
4256  !! Method calculates the compaction for a no-delay interbed. The method
4257  !! also calculates the storage coefficients for the no-delay interbed.
4258  !!
4259  !! @param[in,out] comp no-delay compaction
4260  !! @param[in,out] rho1 no-delay storage value using Sske
4261  !! @param[in,out] rho2 no-delay storage value using Ssk
4262  !!
4263  !<
4264  subroutine csub_nodelay_calc_comp(this, ib, hcell, hcellold, comp, rho1, rho2)
4265  ! -- dummy variables
4266  class(gwfcsubtype) :: this
4267  integer(I4B), intent(in) :: ib !< interbed number
4268  real(DP), intent(in) :: hcell !< current head for the cell
4269  real(DP), intent(in) :: hcellold !< previous head for the cell
4270  real(DP), intent(inout) :: comp !< no-delay interbed compaction
4271  real(DP), intent(inout) :: rho1 !< current storage coefficient based on Sske
4272  real(DP), intent(inout) :: rho2 !< current storage coefficient based on Ssk
4273  ! -- local variables
4274  integer(I4B) :: node
4275  real(DP) :: es
4276  real(DP) :: es0
4277  real(DP) :: pcs
4278  real(DP) :: tled
4279  real(DP) :: rhs
4280  !
4281  ! -- initialize variables
4282  node = this%nodelist(ib)
4283  tled = done
4284  es = this%cg_es(node)
4285  es0 = this%cg_es0(node)
4286  pcs = this%pcs(ib)
4287  !
4288  ! -- calculate no-delay interbed rho1 and rho2
4289  call this%csub_nodelay_fc(ib, hcell, hcellold, rho1, rho2, rhs, argtled=tled)
4290  !
4291  ! -- calculate no-delay interbed compaction
4292  if (this%ielastic(ib) /= 0) then
4293  comp = rho2 * es - rho1 * es0
4294  else
4295  comp = -pcs * (rho2 - rho1) - (rho1 * es0) + (rho2 * es)
4296  end if
4297  end subroutine csub_nodelay_calc_comp
4298 
4299  !> @ brief Set initial states for the package
4300  !!
4301  !! Method sets the initial states for coarse-grained materials and fine-
4302  !! grained sediments in the interbeds.
4303  !!
4304  !<
4305  subroutine csub_set_initial_state(this, nodes, hnew)
4306  ! -- dummy variables
4307  class(gwfcsubtype) :: this
4308  ! -- dummy variables
4309  integer(I4B), intent(in) :: nodes !< number of active model nodes
4310  real(DP), dimension(nodes), intent(in) :: hnew !< current heads
4311  ! -- local variables
4312  character(len=LINELENGTH) :: title
4313  character(len=LINELENGTH) :: tag
4314  character(len=20) :: cellid
4315  integer(I4B) :: ib
4316  integer(I4B) :: node
4317  integer(I4B) :: n
4318  integer(I4B) :: idelay
4319  integer(I4B) :: ntabrows
4320  integer(I4B) :: ntabcols
4321  real(DP) :: pcs0
4322  real(DP) :: pcs
4323  real(DP) :: fact
4324  real(DP) :: top
4325  real(DP) :: bot
4326  real(DP) :: void_ratio
4327  real(DP) :: es
4328  real(DP) :: znode
4329  real(DP) :: hcell
4330  real(DP) :: hbar
4331  real(DP) :: dzhalf
4332  real(DP) :: zbot
4333  real(DP) :: dbpcs
4334  !
4335  ! -- update geostatic load calculation
4336  call this%csub_cg_calc_stress(nodes, hnew)
4337  !
4338  ! -- initialize coarse-grained material effective stress
4339  ! for the previous time step and the previous iteration
4340  do node = 1, nodes
4341  this%cg_es0(node) = this%cg_es(node)
4342  end do
4343  !
4344  ! -- initialize interbed initial states
4345  do ib = 1, this%ninterbeds
4346  idelay = this%idelay(ib)
4347  node = this%nodelist(ib)
4348  top = this%dis%top(node)
4349  bot = this%dis%bot(node)
4350  hcell = hnew(node)
4351  pcs = this%pcs(ib)
4352  pcs0 = pcs
4353  if (this%ispecified_pcs == 0) then
4354  ! relative pcs...subtract head (u) from sigma'
4355  if (this%ipch /= 0) then
4356  pcs = this%cg_es(node) - pcs0
4357  else
4358  pcs = this%cg_es(node) + pcs0
4359  end if
4360  else
4361  ! specified pcs...subtract head (u) from sigma
4362  if (this%ipch /= 0) then
4363  pcs = this%cg_gs(node) - (pcs0 - bot)
4364  end if
4365  if (pcs < this%cg_es(node)) then
4366  pcs = this%cg_es(node)
4367  end if
4368  end if
4369  this%pcs(ib) = pcs
4370  !
4371  ! -- delay bed initial states
4372  if (idelay /= 0) then
4373  dzhalf = dhalf * this%dbdzini(1, idelay)
4374  !
4375  ! -- fill delay bed head with aquifer head or offset from aquifer head
4376  ! heads need to be filled first since used to calculate
4377  ! the effective stress for each delay bed
4378  do n = 1, this%ndelaycells
4379  if (this%ispecified_dbh == 0) then
4380  this%dbh(n, idelay) = hcell + this%dbh(n, idelay)
4381  else
4382  this%dbh(n, idelay) = hcell
4383  end if
4384  this%dbh0(n, idelay) = this%dbh(n, idelay)
4385  end do
4386  !
4387  ! -- fill delay bed effective stress
4388  call this%csub_delay_calc_stress(ib, hcell)
4389  !
4390  ! -- fill delay bed pcs
4391  pcs = this%pcs(ib)
4392  do n = 1, this%ndelaycells
4393  zbot = this%dbz(n, idelay) - dzhalf
4394  ! -- adjust pcs to bottom of each delay bed cell
4395  ! not using csub_calc_adjes() since smoothing not required
4396  dbpcs = pcs - (zbot - bot) * (this%sgs(node) - done)
4397  this%dbpcs(n, idelay) = dbpcs
4398  !
4399  ! -- initialize effective stress for previous time step
4400  this%dbes0(n, idelay) = this%dbes(n, idelay)
4401  end do
4402  end if
4403  end do
4404  !
4405  ! -- scale coarse-grained materials cr
4406  do node = 1, nodes
4407  top = this%dis%top(node)
4408  bot = this%dis%bot(node)
4409  !
4410  ! -- user-specified specific storage
4411  if (this%istoragec == 1) then
4412  !
4413  ! -- retain specific storage values since they are constant
4414  if (this%lhead_based .EQV. .true.) then
4415  fact = done
4416  !
4417  ! -- convert specific storage values since they are simulated to
4418  ! be a function of the average effective stress
4419  else
4420  void_ratio = this%csub_calc_void_ratio(this%cg_theta(node))
4421  es = this%cg_es(node)
4422  hcell = hnew(node)
4423  !
4424  ! -- calculate corrected head (hbar)
4425  hbar = squadratic0sp(hcell, bot, this%satomega)
4426  !
4427  ! -- calculate znode and factor
4428  znode = this%csub_calc_znode(top, bot, hbar)
4429  fact = this%csub_calc_adjes(node, es, bot, znode)
4430  fact = fact * (done + void_ratio)
4431  end if
4432  !
4433  ! -- user-specified compression indices - multiply by dlog10es
4434  else
4435  fact = dlog10es
4436  end if
4437  this%cg_ske_cr(node) = this%cg_ske_cr(node) * fact
4438  !
4439  ! -- write error message if negative compression indices
4440  if (fact <= dzero) then
4441  call this%dis%noder_to_string(node, cellid)
4442  write (errmsg, '(a,1x,a,a)') &
4443  'Negative recompression index calculated for cell', &
4444  trim(adjustl(cellid)), '.'
4445  call store_error(errmsg)
4446  end if
4447  end do
4448  !
4449  ! -- scale interbed cc and cr
4450  do ib = 1, this%ninterbeds
4451  idelay = this%idelay(ib)
4452  node = this%nodelist(ib)
4453  top = this%dis%top(node)
4454  bot = this%dis%bot(node)
4455  !
4456  ! -- user-specified specific storage
4457  if (this%istoragec == 1) then
4458  !
4459  ! -- retain specific storage values since they are constant
4460  if (this%lhead_based .EQV. .true.) then
4461  fact = done
4462  !
4463  ! -- convert specific storage values since they are simulated to
4464  ! be a function of the average effective stress
4465  else
4466  void_ratio = this%csub_calc_void_ratio(this%theta(ib))
4467  es = this%cg_es(node)
4468  hcell = hnew(node)
4469  !
4470  ! -- calculate corrected head (hbar)
4471  hbar = squadratic0sp(hcell, bot, this%satomega)
4472  !
4473  ! -- calculate zone and factor
4474  znode = this%csub_calc_znode(top, bot, hbar)
4475  fact = this%csub_calc_adjes(node, es, bot, znode)
4476  fact = fact * (done + void_ratio)
4477  end if
4478  !
4479  ! -- user-specified compression indices - multiply by dlog10es
4480  else
4481  fact = dlog10es
4482  end if
4483  this%ci(ib) = this%ci(ib) * fact
4484  this%rci(ib) = this%rci(ib) * fact
4485  !
4486  ! -- write error message if negative compression indices
4487  if (fact <= dzero) then
4488  call this%dis%noder_to_string(node, cellid)
4489  write (errmsg, '(a,1x,i0,2(1x,a),a)') &
4490  'Negative compression indices calculated for interbed', ib, &
4491  'in cell', trim(adjustl(cellid)), '.'
4492  call store_error(errmsg)
4493  end if
4494  end do
4495  !
4496  ! -- write current stress and initial preconsolidation stress
4497  if (this%iprpak == 1) then
4498  ! -- set title
4499  title = trim(adjustl(this%packName))// &
4500  ' PACKAGE CALCULATED INITIAL INTERBED STRESSES AT THE CELL BOTTOM'
4501  !
4502  ! -- determine the number of columns and rows
4503  ntabrows = this%ninterbeds
4504  ntabcols = 5
4505  if (this%inamedbound /= 0) then
4506  ntabcols = ntabcols + 1
4507  end if
4508  !
4509  ! -- setup table
4510  call table_cr(this%inputtab, this%packName, title)
4511  call this%inputtab%table_df(ntabrows, ntabcols, this%iout)
4512  !
4513  ! add columns
4514  tag = 'INTERBED NUMBER'
4515  call this%inputtab%initialize_column(tag, 10, alignment=tableft)
4516  tag = 'CELLID'
4517  call this%inputtab%initialize_column(tag, 20)
4518  tag = 'GEOSTATIC STRESS'
4519  call this%inputtab%initialize_column(tag, 16)
4520  tag = 'EFFECTIVE STRESS'
4521  call this%inputtab%initialize_column(tag, 16)
4522  tag = 'PRECONSOLIDATION STRESS'
4523  call this%inputtab%initialize_column(tag, 16)
4524  if (this%inamedbound /= 0) then
4525  tag = 'BOUNDNAME'
4526  call this%inputtab%initialize_column(tag, lenboundname, &
4527  alignment=tableft)
4528  end if
4529  !
4530  ! -- write the data
4531  do ib = 1, this%ninterbeds
4532  node = this%nodelist(ib)
4533  call this%dis%noder_to_string(node, cellid)
4534  !
4535  ! -- write the columns
4536  call this%inputtab%add_term(ib)
4537  call this%inputtab%add_term(cellid)
4538  call this%inputtab%add_term(this%cg_gs(node))
4539  call this%inputtab%add_term(this%cg_es(node))
4540  call this%inputtab%add_term(this%pcs(ib))
4541  if (this%inamedbound /= 0) then
4542  call this%inputtab%add_term(this%boundname(ib))
4543  end if
4544  end do
4545  !
4546  ! -- write effective stress and preconsolidation stress
4547  ! for delay beds
4548  ! -- set title
4549  title = trim(adjustl(this%packName))// &
4550  ' PACKAGE CALCULATED INITIAL DELAY INTERBED STRESSES'
4551  !
4552  ! -- determine the number of columns and rows
4553  ntabrows = 0
4554  do ib = 1, this%ninterbeds
4555  idelay = this%idelay(ib)
4556  if (idelay /= 0) then
4557  ntabrows = ntabrows + this%ndelaycells
4558  end if
4559  end do
4560  ntabcols = 6
4561  if (this%inamedbound /= 0) then
4562  ntabcols = ntabcols + 1
4563  end if
4564  !
4565  ! -- setup table
4566  call table_cr(this%inputtab, this%packName, title)
4567  call this%inputtab%table_df(ntabrows, ntabcols, this%iout)
4568  !
4569  ! add columns
4570  tag = 'INTERBED NUMBER'
4571  call this%inputtab%initialize_column(tag, 10, alignment=tableft)
4572  tag = 'CELLID'
4573  call this%inputtab%initialize_column(tag, 20)
4574  tag = 'DELAY CELL'
4575  call this%inputtab%initialize_column(tag, 10, alignment=tableft)
4576  tag = 'GEOSTATIC STRESS'
4577  call this%inputtab%initialize_column(tag, 16)
4578  tag = 'EFFECTIVE STRESS'
4579  call this%inputtab%initialize_column(tag, 16)
4580  tag = 'PRECONSOLIDATION STRESS'
4581  call this%inputtab%initialize_column(tag, 16)
4582  if (this%inamedbound /= 0) then
4583  tag = 'BOUNDNAME'
4584  call this%inputtab%initialize_column(tag, lenboundname, &
4585  alignment=tableft)
4586  end if
4587  !
4588  ! -- write the data
4589  do ib = 1, this%ninterbeds
4590  idelay = this%idelay(ib)
4591  if (idelay /= 0) then
4592  node = this%nodelist(ib)
4593  call this%dis%noder_to_string(node, cellid)
4594  !
4595  ! -- write the columns
4596  do n = 1, this%ndelaycells
4597  if (n == 1) then
4598  call this%inputtab%add_term(ib)
4599  call this%inputtab%add_term(cellid)
4600  else
4601  call this%inputtab%add_term(' ')
4602  call this%inputtab%add_term(' ')
4603  end if
4604  call this%inputtab%add_term(n)
4605  call this%inputtab%add_term(this%dbgeo(n, idelay))
4606  call this%inputtab%add_term(this%dbes(n, idelay))
4607  call this%inputtab%add_term(this%dbpcs(n, idelay))
4608  if (this%inamedbound /= 0) then
4609  if (n == 1) then
4610  call this%inputtab%add_term(this%boundname(ib))
4611  else
4612  call this%inputtab%add_term(' ')
4613  end if
4614  end if
4615  end do
4616  end if
4617  end do
4618  !
4619  ! -- write calculated compression indices
4620  if (this%istoragec == 1) then
4621  if (this%lhead_based .EQV. .false.) then
4622  ! -- set title
4623  title = trim(adjustl(this%packName))// &
4624  ' PACKAGE COMPRESSION INDICES'
4625  !
4626  ! -- determine the number of columns and rows
4627  ntabrows = this%ninterbeds
4628  ntabcols = 4
4629  if (this%inamedbound /= 0) then
4630  ntabcols = ntabcols + 1
4631  end if
4632  !
4633  ! -- setup table
4634  call table_cr(this%inputtab, this%packName, title)
4635  call this%inputtab%table_df(ntabrows, ntabcols, this%iout)
4636  !
4637  ! add columns
4638  tag = 'INTERBED NUMBER'
4639  call this%inputtab%initialize_column(tag, 10, alignment=tableft)
4640  tag = 'CELLID'
4641  call this%inputtab%initialize_column(tag, 20)
4642  tag = 'CC'
4643  call this%inputtab%initialize_column(tag, 16)
4644  tag = 'CR'
4645  call this%inputtab%initialize_column(tag, 16)
4646  if (this%inamedbound /= 0) then
4647  tag = 'BOUNDNAME'
4648  call this%inputtab%initialize_column(tag, lenboundname, &
4649  alignment=tableft)
4650  end if
4651  !
4652  ! -- write the data
4653  do ib = 1, this%ninterbeds
4654  fact = done / dlog10es
4655  node = this%nodelist(ib)
4656  call this%dis%noder_to_string(node, cellid)
4657  !
4658  ! -- write the columns
4659  call this%inputtab%add_term(ib)
4660  call this%inputtab%add_term(cellid)
4661  call this%inputtab%add_term(this%ci(ib) * fact)
4662  call this%inputtab%add_term(this%rci(ib) * fact)
4663  if (this%inamedbound /= 0) then
4664  call this%inputtab%add_term(this%boundname(ib))
4665  end if
4666  end do
4667  end if
4668  end if
4669  end if
4670  !
4671  ! -- terminate if any initialization errors have been detected
4672  if (count_errors() > 0) then
4673  call this%parser%StoreErrorUnit()
4674  end if
4675  !
4676  ! -- set initialized
4677  this%initialized = 1
4678  !
4679  ! -- set flag to retain initial stresses for entire simulation
4680  if (this%lhead_based .EQV. .true.) then
4681  this%iupdatestress = 0
4682  end if
4683  end subroutine csub_set_initial_state
4684 
4685  !> @ brief Formulate the coefficients for coarse-grained materials
4686  !!
4687  !! Method formulates the coefficient matrix and right-hand side terms
4688  !! for coarse grained materials in a cell.
4689  !!
4690  !! @param[in,out] hcof coarse-grained A matrix entry
4691  !! @param[in,out] rhs coarse-grained right-hand side entry
4692  !!
4693  !<
4694  subroutine csub_cg_fc(this, node, tled, area, hcell, hcellold, hcof, rhs)
4695  ! -- dummy variables
4696  class(gwfcsubtype) :: this
4697  integer(I4B), intent(in) :: node !< cell node number
4698  real(DP), intent(in) :: tled !< recripicol of the time step length
4699  real(DP), intent(in) :: area !< horizontal cell area
4700  real(DP), intent(in) :: hcell !< current head
4701  real(DP), intent(in) :: hcellold !< previous head
4702  real(DP), intent(inout) :: hcof !< coarse-grained A matrix entry
4703  real(DP), intent(inout) :: rhs !< coarse-grained right-hand side entry
4704  ! -- local variables
4705  real(DP) :: top
4706  real(DP) :: bot
4707  real(DP) :: tthk
4708  real(DP) :: snold
4709  real(DP) :: snnew
4710  real(DP) :: hbar
4711  real(DP) :: sske
4712  real(DP) :: rho1
4713  !
4714  ! -- initialize variables
4715  rhs = dzero
4716  hcof = dzero
4717  !
4718  ! -- aquifer elevations and thickness
4719  top = this%dis%top(node)
4720  bot = this%dis%bot(node)
4721  tthk = this%cg_thickini(node)
4722  !
4723  ! -- calculate hcof and rhs terms if coarse-grained materials present
4724  if (tthk > dzero) then
4725  !
4726  ! -- calculate aquifer saturation
4727  call this%csub_calc_sat(node, hcell, hcellold, snnew, snold)
4728  !
4729  ! -- calculate corrected head (hbar)
4730  hbar = squadratic0sp(hcell, bot, this%satomega)
4731  !
4732  ! -- storage coefficients
4733  call this%csub_cg_calc_sske(node, sske, hcell)
4734  rho1 = sske * area * tthk * tled
4735  !
4736  ! -- update sk and ske
4737  this%cg_ske(node) = sske * tthk * snold
4738  this%cg_sk(node) = sske * tthk * snnew
4739  !
4740  ! -- calculate hcof and rhs term
4741  hcof = -rho1 * snnew
4742  rhs = rho1 * snold * this%cg_es0(node) - &
4743  rho1 * snnew * (this%cg_gs(node) + bot)
4744  !
4745  ! -- calculate and apply the flow correction term
4746  rhs = rhs - rho1 * snnew * (hcell - hbar)
4747  end if
4748  end subroutine csub_cg_fc
4749 
4750  !> @ brief Formulate coarse-grained Newton-Raphson terms
4751  !!
4752  !! Method formulates the coefficient matrix and right-hand side terms
4753  !! for coarse grained materials in a cell when using the Newton-Raphson
4754  !! formulation.
4755  !!
4756  !! @param[in,out] hcof coarse-grained A matrix entry
4757  !! @param[in,out] rhs coarse-grained right-hand side entry
4758  !!
4759  !<
4760  subroutine csub_cg_fn(this, node, tled, area, hcell, hcof, rhs)
4761  ! -- dummy variables
4762  class(gwfcsubtype) :: this
4763  integer(I4B), intent(in) :: node !< node number
4764  real(DP), intent(in) :: tled !< reciprocal of the time step length
4765  real(DP), intent(in) :: area !< horizontal cell area
4766  real(DP), intent(in) :: hcell !< current head in cell
4767  real(DP), intent(inout) :: hcof !< coarse-grained A matrix entry
4768  real(DP), intent(inout) :: rhs !< coarse-grained right-hand side entry
4769  ! -- local variables
4770  real(DP) :: top
4771  real(DP) :: bot
4772  real(DP) :: tthk
4773  real(DP) :: snnew
4774  real(DP) :: snold
4775  real(DP) :: satderv
4776  real(DP) :: hbar
4777  real(DP) :: hbarderv
4778  real(DP) :: sske
4779  real(DP) :: rho1
4780  !
4781  ! -- initialize variables
4782  rhs = dzero
4783  hcof = dzero
4784  !
4785  ! -- aquifer elevations and thickness
4786  top = this%dis%top(node)
4787  bot = this%dis%bot(node)
4788  tthk = this%cg_thickini(node)
4789  !
4790  ! -- calculate newton terms if coarse-grained materials present
4791  if (tthk > dzero) then
4792  !
4793  ! -- calculate aquifer saturation - only need snnew
4794  call this%csub_calc_sat(node, hcell, top, snnew, snold)
4795  !
4796  ! -- calculate saturation derivative
4797  satderv = this%csub_calc_sat_derivative(node, hcell)
4798  !
4799  ! -- calculate corrected head (hbar)
4800  hbar = squadratic0sp(hcell, bot, this%satomega)
4801  !
4802  ! -- calculate the derivative of the hbar functions
4803  hbarderv = squadratic0spderivative(hcell, bot, this%satomega)
4804  !
4805  ! -- storage coefficients
4806  call this%csub_cg_calc_sske(node, sske, hcell)
4807  rho1 = sske * area * tthk * tled
4808  !
4809  ! -- calculate hcof term
4810  hcof = rho1 * snnew * (done - hbarderv) + &
4811  rho1 * (this%cg_gs(node) - hbar + bot) * satderv
4812  !
4813  ! -- Add additional term if using lagged effective stress
4814  if (this%ieslag /= 0) then
4815  hcof = hcof - rho1 * this%cg_es0(node) * satderv
4816  end if
4817  !
4818  ! -- calculate rhs term
4819  rhs = hcof * hcell
4820  end if
4821  end subroutine csub_cg_fn
4822 
4823  !> @ brief Formulate the coefficients for a interbed
4824  !!
4825  !! Method formulates the coefficient matrix and right-hand side terms
4826  !! for a interbed in a cell.
4827  !!
4828  !! @param[in,out] hcof interbed A matrix entry
4829  !! @param[in,out] rhs interbed right-hand side entry
4830  !!
4831  !<
4832  subroutine csub_interbed_fc(this, ib, node, area, hcell, hcellold, hcof, rhs)
4833  ! -- dummy variables
4834  class(gwfcsubtype) :: this
4835  integer(I4B), intent(in) :: ib !< interbed number
4836  integer(I4B), intent(in) :: node !< cell node number
4837  real(DP), intent(in) :: area !< horizontal cell area
4838  real(DP), intent(in) :: hcell !< current head in cell
4839  real(DP), intent(in) :: hcellold !< previous head in cell
4840  real(DP), intent(inout) :: hcof !< interbed A matrix entry
4841  real(DP), intent(inout) :: rhs !< interbed right-hand side
4842  ! -- local variables
4843  real(DP) :: snnew
4844  real(DP) :: snold
4845  real(DP) :: comp
4846  real(DP) :: compi
4847  real(DP) :: compe
4848  real(DP) :: rho1
4849  real(DP) :: rho2
4850  real(DP) :: f
4851  !
4852  ! -- initialize variables
4853  rhs = dzero
4854  hcof = dzero
4855  comp = dzero
4856  compi = dzero
4857  compe = dzero
4858  !
4859  ! -- skip inactive and constant head cells
4860  if (this%ibound(node) > 0) then
4861  if (this%idelay(ib) == 0) then
4862  !
4863  ! -- update material properties
4864  if (this%iupdatematprop /= 0) then
4865  if (this%ieslag == 0) then
4866  !
4867  ! -- calculate compaction
4868  call this%csub_nodelay_calc_comp(ib, hcell, hcellold, comp, &
4869  rho1, rho2)
4870  this%comp(ib) = comp
4871  !
4872  ! -- update thickness and void ratio
4873  call this%csub_nodelay_update(ib)
4874  end if
4875  end if
4876  !
4877  ! -- calculate no-delay interbed rho1 and rho2
4878  call this%csub_nodelay_fc(ib, hcell, hcellold, rho1, hcof, rhs)
4879  f = area
4880  else
4881  !
4882  ! -- calculate cell saturation
4883  call this%csub_calc_sat(node, hcell, hcellold, snnew, snold)
4884  !
4885  ! -- update material properties
4886  if (this%iupdatematprop /= 0) then
4887  if (this%ieslag == 0) then
4888  !
4889  ! -- calculate compaction
4890  call this%csub_delay_calc_comp(ib, hcell, hcellold, &
4891  comp, compi, compe)
4892  this%comp(ib) = comp
4893  !
4894  ! -- update thickness and void ratio
4895  call this%csub_delay_update(ib)
4896  end if
4897  end if
4898  !
4899  ! -- calculate delay interbed hcof and rhs
4900  call this%csub_delay_sln(ib, hcell)
4901  call this%csub_delay_fc(ib, hcof, rhs)
4902  f = area * this%rnb(ib)
4903  end if
4904  rhs = rhs * f
4905  hcof = -hcof * f
4906  end if
4907  end subroutine csub_interbed_fc
4908 
4909  !> @ brief Formulate the coefficients for a interbed
4910  !!
4911  !! Method formulates the Newton-Raphson formulation coefficient matrix and
4912  !! right-hand side terms for a interbed in a cell.
4913  !!
4914  !! @param[in,out] hcof interbed A matrix entry
4915  !! @param[in,out] rhs interbed right-hand side entry
4916  !!
4917  !<
4918  subroutine csub_interbed_fn(this, ib, node, hcell, hcellold, hcof, rhs)
4919  ! -- modules
4920  use tdismodule, only: delt
4921  ! -- dummy variables
4922  class(gwfcsubtype) :: this
4923  integer(I4B), intent(in) :: ib !< interbed number
4924  integer(I4B), intent(in) :: node !< cell node number
4925  real(DP), intent(in) :: hcell !< current head in a cell
4926  real(DP), intent(in) :: hcellold !< previous head in a cell
4927  real(DP), intent(inout) :: hcof !< interbed A matrix entry
4928  real(DP), intent(inout) :: rhs !< interbed right-hand side entry
4929  ! -- local variables
4930  integer(I4B) :: idelay
4931  real(DP) :: hcofn
4932  real(DP) :: rhsn
4933  real(DP) :: top
4934  real(DP) :: bot
4935  real(DP) :: tled
4936  real(DP) :: tthk
4937  real(DP) :: snnew
4938  real(DP) :: snold
4939  real(DP) :: f
4940  real(DP) :: satderv
4941  real(DP) :: hbar
4942  real(DP) :: hbarderv
4943  real(DP) :: rho1
4944  real(DP) :: rho2
4945  !
4946  ! -- initialize variables
4947  rhs = dzero
4948  hcof = dzero
4949  rhsn = dzero
4950  hcofn = dzero
4951  satderv = dzero
4952  idelay = this%idelay(ib)
4953  top = this%dis%top(node)
4954  bot = this%dis%bot(node)
4955  !
4956  ! -- skip inactive and constant head cells
4957  if (this%ibound(node) > 0) then
4958  tled = done / delt
4959  tthk = this%thickini(ib)
4960  !
4961  ! -- calculate cell saturation
4962  call this%csub_calc_sat(node, hcell, hcellold, snnew, snold)
4963  !
4964  ! -- no-delay interbeds
4965  if (idelay == 0) then
4966  !
4967  ! -- initialize factor
4968  f = done
4969  !
4970  ! -- calculate the saturation derivative
4971  satderv = this%csub_calc_sat_derivative(node, hcell)
4972  !
4973  ! -- calculate corrected head (hbar)
4974  hbar = squadratic0sp(hcell, bot, this%satomega)
4975  !
4976  ! -- calculate the derivative of the hbar functions
4977  hbarderv = squadratic0spderivative(hcell, bot, this%satomega)
4978  !
4979  ! -- calculate storage coefficient
4980  call this%csub_nodelay_fc(ib, hcell, hcellold, rho1, rho2, rhsn)
4981  !
4982  ! -- calculate hcofn term
4983  hcofn = rho2 * (done - hbarderv) * snnew + &
4984  rho2 * (this%cg_gs(node) - hbar + bot) * satderv
4985  if (this%ielastic(ib) == 0) then
4986  hcofn = hcofn - rho2 * this%pcs(ib) * satderv
4987  end if
4988  !
4989  ! -- Add additional term if using lagged effective stress
4990  if (this%ieslag /= 0) then
4991  if (this%ielastic(ib) /= 0) then
4992  hcofn = hcofn - rho1 * this%cg_es0(node) * satderv
4993  else
4994  hcofn = hcofn - rho1 * (this%pcs(ib) - this%cg_es0(node)) * satderv
4995  end if
4996  end if
4997  end if
4998  end if
4999  end subroutine csub_interbed_fn
5000 
5001  !> @ brief Calculate Sske for a cell
5002  !!
5003  !! Method calculates Sske for coarse-grained materials in a cell.
5004  !!
5005  !! @param[in,out] sske coarse-grained Sske
5006  !!
5007  !<
5008  subroutine csub_cg_calc_sske(this, n, sske, hcell)
5009  ! -- dummy variables
5010  class(gwfcsubtype), intent(inout) :: this
5011  integer(I4B), intent(in) :: n !< cell node number
5012  real(DP), intent(inout) :: sske !< coarse grained Sske
5013  real(DP), intent(in) :: hcell !< current head in cell
5014  ! -- local variables
5015  real(DP) :: top
5016  real(DP) :: bot
5017  real(DP) :: hbar
5018  real(DP) :: znode
5019  real(DP) :: es
5020  real(DP) :: es0
5021  real(DP) :: theta
5022  real(DP) :: f
5023  real(DP) :: f0
5024  !
5025  ! -- initialize variables
5026  sske = dzero
5027  !
5028  ! -- calculate factor for the head-based case
5029  if (this%lhead_based .EQV. .true.) then
5030  f = done
5031  f0 = done
5032  !
5033  ! -- calculate factor for the effective stress case
5034  else
5035  top = this%dis%top(n)
5036  bot = this%dis%bot(n)
5037  !
5038  ! -- calculate corrected head (hbar)
5039  hbar = squadratic0sp(hcell, bot, this%satomega)
5040  !
5041  ! -- calculate znode
5042  znode = this%csub_calc_znode(top, bot, hbar)
5043  !
5044  ! -- calculate effective stress and theta
5045  es = this%cg_es(n)
5046  es0 = this%cg_es0(n)
5047  theta = this%cg_thetaini(n)
5048  !
5049  ! -- calculate the compression index factors for the delay
5050  ! node relative to the center of the cell based on the
5051  ! current and previous head
5052  call this%csub_calc_sfacts(n, bot, znode, theta, es, es0, f)
5053  end if
5054  sske = f * this%cg_ske_cr(n)
5055  end subroutine csub_cg_calc_sske
5056 
5057  !> @ brief Calculate coarse-grained compaction in a cell
5058  !!
5059  !! Method calculates coarse-grained compaction in a cell.
5060  !!
5061  !! @param[in,out] comp coarse-grained compaction
5062  !!
5063  !<
5064  subroutine csub_cg_calc_comp(this, node, hcell, hcellold, comp)
5065  ! -- dummy variables
5066  class(gwfcsubtype) :: this
5067  integer(I4B), intent(in) :: node !< cell node number
5068  real(DP), intent(in) :: hcell !< current head in cell
5069  real(DP), intent(in) :: hcellold !< previous head in cell
5070  real(DP), intent(inout) :: comp !< coarse-grained compaction
5071  ! -- local variables
5072  real(DP) :: area
5073  real(DP) :: tled
5074  real(DP) :: hcof
5075  real(DP) :: rhs
5076  !
5077  ! -- initialize variables
5078  area = done
5079  tled = done
5080  !
5081  ! -- calculate terms
5082  call this%csub_cg_fc(node, tled, area, hcell, hcellold, hcof, rhs)
5083  !
5084  ! - calculate compaction
5085  comp = hcof * hcell - rhs
5086  end subroutine csub_cg_calc_comp
5087 
5088  !> @ brief Update coarse-grained material properties
5089  !!
5090  !! Method updates coarse-grained material properties in a cell.
5091  !!
5092  !<
5093  subroutine csub_cg_update(this, node)
5094  ! -- dummy variables
5095  class(gwfcsubtype), intent(inout) :: this
5096  integer(I4B), intent(in) :: node !< cell node number
5097  ! -- local variables
5098  character(len=20) :: cellid
5099  real(DP) :: comp
5100  real(DP) :: thick
5101  real(DP) :: theta
5102  !
5103  ! -- update thickness and theta
5104  comp = this%cg_tcomp(node) + this%cg_comp(node)
5105  call this%dis%noder_to_string(node, cellid)
5106  if (abs(comp) > dzero) then
5107  thick = this%cg_thickini(node)
5108  theta = this%cg_thetaini(node)
5109  call this%csub_adj_matprop(comp, thick, theta)
5110  if (thick <= dzero) then
5111  write (errmsg, '(a,1x,a,1x,a,g0,a)') &
5112  'Adjusted thickness for cell', trim(adjustl(cellid)), &
5113  'is less than or equal to 0 (', thick, ').'
5114  call store_error(errmsg)
5115  end if
5116  if (theta <= dzero) then
5117  write (errmsg, '(a,1x,a,1x,a,g0,a)') &
5118  'Adjusted theta for cell', trim(adjustl(cellid)), &
5119  'is less than or equal to 0 (', theta, ').'
5120  call store_error(errmsg)
5121  end if
5122  this%cg_thick(node) = thick
5123  this%cg_theta(node) = theta
5124  end if
5125  end subroutine csub_cg_update
5126 
5127  !> @ brief Formulate coarse-grained water compressibility coefficients
5128  !!
5129  !! Method formulates the standard formulation coefficient matrix and
5130  !! right-hand side terms for water compressibility in coarse-grained
5131  !! sediments.
5132  !!
5133  !! @param[in,out] hcof coarse-grained A matrix entry
5134  !! @param[in,out] rhs coarse-grained right-hand side entry
5135  !!
5136  !<
5137  subroutine csub_cg_wcomp_fc(this, node, tled, area, hcell, hcellold, &
5138  hcof, rhs)
5139  ! -- dummy variables
5140  class(gwfcsubtype), intent(inout) :: this
5141  integer(I4B), intent(in) :: node !< cell node number
5142  real(DP), intent(in) :: tled !< reciprocal of the time step length
5143  real(DP), intent(in) :: area !< horizontal cell area
5144  real(DP), intent(in) :: hcell !< current head in cell
5145  real(DP), intent(in) :: hcellold !< previous head in cell
5146  real(DP), intent(inout) :: hcof !< coarse-grained A matrix entry
5147  real(DP), intent(inout) :: rhs !< coarse-grained right-hand side entry
5148  ! -- local variables
5149  real(DP) :: top
5150  real(DP) :: bot
5151  real(DP) :: tthk
5152  real(DP) :: tthk0
5153  real(DP) :: snold
5154  real(DP) :: snnew
5155  real(DP) :: wc
5156  real(DP) :: wc0
5157  !
5158  ! -- initialize variables
5159  rhs = dzero
5160  hcof = dzero
5161  !
5162  ! -- aquifer elevations and thickness
5163  top = this%dis%top(node)
5164  bot = this%dis%bot(node)
5165  tthk = this%cg_thick(node)
5166  tthk0 = this%cg_thick0(node)
5167  !
5168  ! -- aquifer saturation
5169  call this%csub_calc_sat(node, hcell, hcellold, snnew, snold)
5170  !
5171  ! -- storage coefficients
5172  wc0 = this%brg * area * tthk0 * this%cg_theta0(node) * tled
5173  wc = this%brg * area * tthk * this%cg_theta(node) * tled
5174  !
5175  ! -- calculate hcof term
5176  hcof = -wc * snnew
5177  !
5178  ! -- calculate rhs term
5179  rhs = -wc0 * snold * hcellold
5180  end subroutine csub_cg_wcomp_fc
5181 
5182  !> @ brief Formulate coarse-grained water compressibility coefficients
5183  !!
5184  !! Method formulates the Newton-Raphson formulation coefficient matrix and
5185  !! right-hand side terms for water compressibility in coarse-grained
5186  !! sediments.
5187  !!
5188  !! @param[in,out] hcof coarse-grained A matrix entry
5189  !! @param[in,out] rhs coarse-grained right-hand side entry
5190  !!
5191  !<
5192  subroutine csub_cg_wcomp_fn(this, node, tled, area, hcell, hcellold, hcof, rhs)
5193  ! -- dummy variables
5194  class(gwfcsubtype), intent(inout) :: this
5195  integer(I4B), intent(in) :: node !< cell node number
5196  real(DP), intent(in) :: tled !< reciprocal of the time step length
5197  real(DP), intent(in) :: area !< horizontal cell area
5198  real(DP), intent(in) :: hcell !< current head in cell
5199  real(DP), intent(in) :: hcellold !< previous head in cell
5200  real(DP), intent(inout) :: hcof !< coarse-grained A matrix entry
5201  real(DP), intent(inout) :: rhs !< coarse-grained right-hand side entry
5202  ! -- local variables
5203  real(DP) :: top
5204  real(DP) :: bot
5205  real(DP) :: tthk
5206  real(DP) :: tthk0
5207  real(DP) :: satderv
5208  real(DP) :: f
5209  real(DP) :: wc
5210  real(DP) :: wc0
5211  !
5212  ! -- initialize variables
5213  rhs = dzero
5214  hcof = dzero
5215  !
5216  ! -- aquifer elevations and thickness
5217  top = this%dis%top(node)
5218  bot = this%dis%bot(node)
5219  tthk = this%cg_thick(node)
5220  !
5221  ! -- calculate saturation derivative
5222  satderv = this%csub_calc_sat_derivative(node, hcell)
5223  !
5224  ! -- calculate water compressibility factor
5225  f = this%brg * area * tled
5226  !
5227  ! -- water compressibility coefficient
5228  wc = f * tthk * this%cg_theta(node)
5229  !
5230  ! -- calculate hcof term
5231  hcof = -wc * hcell * satderv
5232  !
5233  ! -- Add additional term if using lagged effective stress
5234  if (this%ieslag /= 0) then
5235  tthk0 = this%cg_thick0(node)
5236  wc0 = f * tthk0 * this%cg_theta0(node)
5237  hcof = hcof + wc * hcellold * satderv
5238  end if
5239  !
5240  ! -- calculate rhs term
5241  rhs = hcof * hcell
5242  end subroutine csub_cg_wcomp_fn
5243 
5244  !> @ brief Formulate no-delay interbed water compressibility coefficients
5245  !!
5246  !! Method formulates the standard formulation coefficient matrix and
5247  !! right-hand side terms for water compressibility in no-delay
5248  !! interbeds.
5249  !!
5250  !! @param[in,out] hcof no-delay A matrix entry
5251  !! @param[in,out] rhs no-delay right-hand side entry
5252  !!
5253  !<
5254  subroutine csub_nodelay_wcomp_fc(this, ib, node, tled, area, &
5255  hcell, hcellold, hcof, rhs)
5256  ! -- dummy variables
5257  class(gwfcsubtype), intent(inout) :: this
5258  integer(I4B), intent(in) :: ib !< interbed number
5259  integer(I4B), intent(in) :: node !< cell node number
5260  real(DP), intent(in) :: tled !< reciprocal of time step length
5261  real(DP), intent(in) :: area !< horizontal cell area
5262  real(DP), intent(in) :: hcell !< current head in cell
5263  real(DP), intent(in) :: hcellold !< previous head in cell
5264  real(DP), intent(inout) :: hcof !< no-delay A matrix entry
5265  real(DP), intent(inout) :: rhs !< no-delay right-hand side entry
5266  ! -- local variables
5267  real(DP) :: top
5268  real(DP) :: bot
5269  real(DP) :: snold
5270  real(DP) :: snnew
5271  real(DP) :: f
5272  real(DP) :: wc
5273  real(DP) :: wc0
5274  !
5275  ! -- initialize variables
5276  rhs = dzero
5277  hcof = dzero
5278  !
5279  ! -- aquifer elevations and thickness
5280  top = this%dis%top(node)
5281  bot = this%dis%bot(node)
5282  !
5283  ! -- calculate cell saturation
5284  call this%csub_calc_sat(node, hcell, hcellold, snnew, snold)
5285  !
5286  !
5287  f = this%brg * area * tled
5288  wc0 = f * this%theta0(ib) * this%thick0(ib)
5289  wc = f * this%theta(ib) * this%thick(ib)
5290  hcof = -wc * snnew
5291  rhs = -wc0 * snold * hcellold
5292  end subroutine csub_nodelay_wcomp_fc
5293 
5294  !> @ brief Formulate no-delay interbed water compressibility coefficients
5295  !!
5296  !! Method formulates the Newton-Raphson formulation coefficient matrix and
5297  !! right-hand side terms for water compressibility in no-delay
5298  !! interbeds.
5299  !!
5300  !! @param[in,out] hcof no-delay A matrix entry
5301  !! @param[in,out] rhs no-delay right-hand side entry
5302  !!
5303  !<
5304  subroutine csub_nodelay_wcomp_fn(this, ib, node, tled, area, &
5305  hcell, hcellold, hcof, rhs)
5306  ! -- dummy variables
5307  class(gwfcsubtype), intent(inout) :: this
5308  integer(I4B), intent(in) :: ib !< interbed number
5309  integer(I4B), intent(in) :: node !< cell node number
5310  real(DP), intent(in) :: tled !< reciprocal of time step length
5311  real(DP), intent(in) :: area !< horizontal cell area
5312  real(DP), intent(in) :: hcell !< current head in cell
5313  real(DP), intent(in) :: hcellold !< previous head in cell
5314  real(DP), intent(inout) :: hcof !< no-delay A matrix entry
5315  real(DP), intent(inout) :: rhs !< no-delay right-hand side entry
5316  ! -- local variables
5317  real(DP) :: top
5318  real(DP) :: bot
5319  real(DP) :: f
5320  real(DP) :: wc
5321  real(DP) :: wc0
5322  real(DP) :: satderv
5323  !
5324  ! -- initialize variables
5325  rhs = dzero
5326  hcof = dzero
5327  !
5328  ! -- aquifer elevations and thickness
5329  top = this%dis%top(node)
5330  bot = this%dis%bot(node)
5331  !
5332  !
5333  f = this%brg * area * tled
5334  !
5335  ! -- calculate saturation derivative
5336  satderv = this%csub_calc_sat_derivative(node, hcell)
5337  !
5338  ! -- calculate the current water compressibility factor
5339  wc = f * this%theta(ib) * this%thick(ib)
5340  !
5341  ! -- calculate derivative term
5342  hcof = -wc * hcell * satderv
5343  !
5344  ! -- Add additional term if using lagged effective stress
5345  if (this%ieslag /= 0) then
5346  wc0 = f * this%theta0(ib) * this%thick0(ib)
5347  hcof = hcof + wc0 * hcellold * satderv
5348  end if
5349  !
5350  ! -- set rhs
5351  rhs = hcof * hcell
5352  end subroutine csub_nodelay_wcomp_fn
5353 
5354  !> @brief Calculate the void ratio
5355  !!
5356  !! Function to calculate the void ratio from the porosity.
5357  !!
5358  !! @return void void ratio
5359  !<
5360  function csub_calc_void_ratio(this, theta) result(void_ratio)
5361  ! -- dummy variables
5362  class(gwfcsubtype), intent(inout) :: this
5363  real(dp), intent(in) :: theta !< porosity
5364  ! -- local variables
5365  real(dp) :: void_ratio
5366  ! -- calculate void ratio
5367  void_ratio = theta / (done - theta)
5368  end function csub_calc_void_ratio
5369 
5370  !> @brief Calculate the porosity
5371  !!
5372  !! Function to calculate the porosity from the void ratio.
5373  !!
5374  !! @return theta porosity
5375  !<
5376  function csub_calc_theta(this, void_ratio) result(theta)
5377  ! -- dummy variables
5378  class(gwfcsubtype), intent(inout) :: this
5379  real(dp), intent(in) :: void_ratio
5380  ! -- local variables
5381  real(dp) :: theta
5382  !
5383  ! -- calculate theta
5384  theta = void_ratio / (done + void_ratio)
5385  end function csub_calc_theta
5386 
5387  !> @brief Calculate the interbed thickness
5388  !!
5389  !! Function to calculate the interbed thickness.
5390  !!
5391  !! @return thick interbed thickness
5392  !<
5393  function csub_calc_interbed_thickness(this, ib) result(thick)
5394  ! -- dummy variables
5395  class(gwfcsubtype), intent(inout) :: this
5396  integer(I4B), intent(in) :: ib !< interbed number
5397  ! -- local variables
5398  integer(I4B) :: idelay
5399  real(dp) :: thick
5400  !
5401  ! -- calculate interbed thickness
5402  idelay = this%idelay(ib)
5403  thick = this%thick(ib)
5404  if (idelay /= 0) then
5405  thick = thick * this%rnb(ib)
5406  end if
5407  end function csub_calc_interbed_thickness
5408 
5409  !> @brief Calculate the cell node
5410  !!
5411  !! Function to calculate elevation of the node between the specified corrected
5412  !! elevation zbar and the bottom elevation. If zbar is greater than the top
5413  !! elevation, the node elevation is halfway between the top and bottom
5414  !! elevations. The corrected elevation (zbar) is always greater than or
5415  !! equal to bottom.
5416  !!
5417  !! @return znode node elevation
5418  !<
5419  function csub_calc_znode(this, top, bottom, zbar) result(znode)
5420  ! -- dummy variables
5421  class(gwfcsubtype), intent(inout) :: this
5422  real(dp), intent(in) :: top !< top of cell
5423  real(dp), intent(in) :: bottom !< bottom of cell
5424  real(dp), intent(in) :: zbar !< corrected elevation
5425  ! -- local variables
5426  real(dp) :: znode
5427  real(dp) :: v
5428  !
5429  ! -- calculate the node elevation
5430  if (zbar > top) then
5431  v = top
5432  else
5433  v = zbar
5434  end if
5435  znode = dhalf * (v + bottom)
5436  end function csub_calc_znode
5437 
5438  !> @brief Calculate the effective stress at elevation z
5439  !!
5440  !! Function to calculate the effective stress at specified elevation z
5441  !! using the provided effective stress (es0) calculated at elevation
5442  !! z0 (which is <= z)
5443  !!
5444  !! @return es node elevation
5445  !<
5446  function csub_calc_adjes(this, node, es0, z0, z) result(es)
5447  ! -- dummy variables
5448  class(gwfcsubtype), intent(inout) :: this
5449  integer(I4B), intent(in) :: node !< cell node number
5450  real(dp), intent(in) :: es0 !< effective stress at elevation z0
5451  real(dp), intent(in) :: z0 !< elevation effective stress is calculate at
5452  real(dp), intent(in) :: z !< elevation to calculate effective stress at
5453  ! -- local variables
5454  real(dp) :: es
5455  !
5456  ! -- adjust effective stress to vertical node position
5457  es = es0 - (z - z0) * (this%sgs(node) - done)
5458  end function csub_calc_adjes
5459 
5460  !> @brief Check delay interbed head
5461  !!
5462  !! Method to determine if the delay interbed head in any delay cell
5463  !! in a non-convertible gwf cell is less than the top of each delay
5464  !! interbed cell.
5465  !!
5466  !<
5467  subroutine csub_delay_head_check(this, ib)
5468  ! -- dummy variables
5469  class(gwfcsubtype), intent(inout) :: this
5470  integer(I4B), intent(in) :: ib !< interbed number
5471  ! -- local variables
5472  integer(I4B) :: iviolate
5473  integer(I4B) :: idelay
5474  integer(I4B) :: node
5475  integer(I4B) :: n
5476  real(DP) :: z
5477  real(DP) :: h
5478  real(DP) :: dzhalf
5479  real(DP) :: ztop
5480  !
5481  ! -- initialize variables
5482  iviolate = 0
5483  idelay = this%idelay(ib)
5484  node = this%nodelist(ib)
5485  !
5486  ! -- evaluate every delay cell
5487  idelaycells: do n = 1, this%ndelaycells
5488  z = this%dbz(n, idelay)
5489  h = this%dbh(n, idelay)
5490  dzhalf = dhalf * this%dbdzini(1, idelay)
5491  !
5492  ! -- non-convertible cell
5493  if (this%stoiconv(node) == 0) then
5494  ztop = z + dzhalf
5495  if (h < ztop) then
5496  this%idb_nconv_count(1) = this%idb_nconv_count(1) + 1
5497  iviolate = 1
5498  end if
5499  end if
5500  !
5501  ! -- terminate the loop
5502  if (iviolate > 0) then
5503  exit idelaycells
5504  end if
5505  end do idelaycells
5506  end subroutine csub_delay_head_check
5507 
5508  !> @brief Calculate cell saturation
5509  !!
5510  !! Method to calculate the cell saturation for the current and
5511  !! previous time step.
5512  !!
5513  !! @param[in,out] snnew current saturation
5514  !! @param[in,out] snold previous saturation
5515  !!
5516  !<
5517  subroutine csub_calc_sat(this, node, hcell, hcellold, snnew, snold)
5518  ! -- dummy variables
5519  class(gwfcsubtype), intent(inout) :: this
5520  integer(I4B), intent(in) :: node !< cell node number
5521  real(DP), intent(in) :: hcell !< current head
5522  real(DP), intent(in) :: hcellold !< previous head
5523  real(DP), intent(inout) :: snnew !< current saturation
5524  real(DP), intent(inout) :: snold !< previous saturation
5525  ! -- local variables
5526  real(DP) :: top
5527  real(DP) :: bot
5528  !
5529  ! -- calculate cell saturation
5530  if (this%stoiconv(node) /= 0) then
5531  top = this%dis%top(node)
5532  bot = this%dis%bot(node)
5533  snnew = squadraticsaturation(top, bot, hcell, this%satomega)
5534  snold = squadraticsaturation(top, bot, hcellold, this%satomega)
5535  else
5536  snnew = done
5537  snold = done
5538  end if
5539  if (this%ieslag /= 0) then
5540  snold = snnew
5541  end if
5542  end subroutine csub_calc_sat
5543 
5544  !> @brief Calculate the saturation derivative
5545  !!
5546  !! Function to calculate the derivative of the saturation with
5547  !! respect to the current head.
5548  !!
5549  !! @return satderv derivative of saturation
5550  !<
5551  function csub_calc_sat_derivative(this, node, hcell) result(satderv)
5552  ! -- dummy variables
5553  class(gwfcsubtype), intent(inout) :: this
5554  integer(I4B), intent(in) :: node !< cell node number
5555  real(dp), intent(in) :: hcell !< current head
5556  ! -- local variables
5557  real(dp) :: satderv
5558  real(dp) :: top
5559  real(dp) :: bot
5560 
5561  if (this%stoiconv(node) /= 0) then
5562  top = this%dis%top(node)
5563  bot = this%dis%bot(node)
5564  satderv = squadraticsaturationderivative(top, bot, hcell, this%satomega)
5565  else
5566  satderv = dzero
5567  end if
5568  end function csub_calc_sat_derivative
5569 
5570  !> @brief Calculate specific storage coefficient factor
5571  !!
5572  !! Method to calculate the factor that is used to calculate skeletal
5573  !! specific storage coefficients. Can be used for coarse-grained
5574  !! materials and interbeds.
5575  !!
5576  !! @param[in,out] fact skeletal storage coefficient factor
5577  !!
5578  !<
5579  subroutine csub_calc_sfacts(this, node, bot, znode, theta, es, es0, fact)
5580  ! -- dummy variables
5581  class(gwfcsubtype), intent(inout) :: this
5582  integer(I4B), intent(in) :: node !< cell node number
5583  real(DP), intent(in) :: bot !
5584  real(DP), intent(in) :: znode
5585  real(DP), intent(in) :: theta !< porosity
5586  real(DP), intent(in) :: es !< current effective stress
5587  real(DP), intent(in) :: es0 !< previous effective stress
5588  real(DP), intent(inout) :: fact !< skeletal storage coefficient factor (1/((1+void_ratio)*bar(es)))
5589  ! -- local variables
5590  real(DP) :: esv
5591  real(DP) :: void_ratio
5592  real(DP) :: denom
5593  !
5594  ! -- initialize variables
5595  fact = dzero
5596  if (this%ieslag /= 0) then
5597  esv = es0
5598  else
5599  esv = es
5600  end if
5601  !
5602  ! -- calculate storage factors for the effective stress case
5603  void_ratio = this%csub_calc_void_ratio(theta)
5604  denom = this%csub_calc_adjes(node, esv, bot, znode)
5605  denom = denom * (done + void_ratio)
5606  if (denom /= dzero) then
5607  fact = done / denom
5608  end if
5609  end subroutine csub_calc_sfacts
5610 
5611  !> @brief Calculate new material properties
5612  !!
5613  !! Method to calculate the current thickness and porosity.
5614  !!
5615  !! @param[in,out] thick initial and current thickness
5616  !! @param[in,out] theta initial and current porosity
5617  !!
5618  !<
5619  subroutine csub_adj_matprop(this, comp, thick, theta)
5620  ! -- dummy variables
5621  class(gwfcsubtype), intent(inout) :: this
5622  real(DP), intent(in) :: comp !< compaction
5623  real(DP), intent(inout) :: thick !< thickness
5624  real(DP), intent(inout) :: theta !< porosity
5625  ! -- local variables
5626  real(DP) :: strain
5627  real(DP) :: void_ratio
5628  !
5629  ! -- initialize variables
5630  strain = dzero
5631  void_ratio = this%csub_calc_void_ratio(theta)
5632  !
5633  ! -- calculate strain
5634  if (thick > dzero) strain = -comp / thick
5635  !
5636  ! -- update void ratio, theta, and thickness
5637  void_ratio = void_ratio + strain * (done + void_ratio)
5638  theta = this%csub_calc_theta(void_ratio)
5639  thick = thick - comp
5640  end subroutine csub_adj_matprop
5641 
5642  !> @brief Solve delay interbed continuity equation
5643  !!
5644  !! Method to calculate solve the delay interbed continuity equation for a
5645  !! delay interbed. The method encapsulates the non-linear loop and calls the
5646  !! linear solution.
5647  !!
5648  !<
5649  subroutine csub_delay_sln(this, ib, hcell, update)
5650  ! -- dummy variables
5651  class(gwfcsubtype), intent(inout) :: this
5652  integer(I4B), intent(in) :: ib !< interbed number
5653  real(DP), intent(in) :: hcell !< current head in a cell
5654  logical(LGP), intent(in), optional :: update !< optional logical variable indicating
5655  !! if the maximum head change variable
5656  !! in a delay bed should be updated
5657  ! -- local variables
5658  logical(LGP) :: lupdate
5659  integer(I4B) :: n
5660  integer(I4B) :: icnvg
5661  integer(I4B) :: iter
5662  integer(I4B) :: idelay
5663  real(DP) :: dh
5664  real(DP) :: dhmax
5665  real(DP) :: dhmax0
5666  real(DP), parameter :: dclose = dhundred * dprec
5667  !
5668  ! -- initialize variables
5669  if (present(update)) then
5670  lupdate = update
5671  else
5672  lupdate = .true.
5673  end if
5674  !
5675  ! -- calculate geostatic and effective stress for each delay bed cell
5676  call this%csub_delay_calc_stress(ib, hcell)
5677  !
5678  ! -- terminate if the aquifer head is below the top of delay interbeds
5679  if (count_errors() > 0) then
5680  call this%parser%StoreErrorUnit()
5681  end if
5682  !
5683  ! -- solve for delay bed heads
5684  if (this%thickini(ib) > dzero) then
5685  icnvg = 0
5686  iter = 0
5687  idelay = this%idelay(ib)
5688  do
5689  iter = iter + 1
5690  !
5691  ! -- assemble coefficients
5692  call this%csub_delay_assemble(ib, hcell)
5693  !
5694  ! -- solve for head change in delay interbed cells
5695  call ims_misc_thomas(this%ndelaycells, &
5696  this%dbal, this%dbad, this%dbau, &
5697  this%dbrhs, this%dbdh, this%dbaw)
5698  !
5699  ! -- calculate maximum head change and update delay bed heads
5700  dhmax = dzero
5701  do n = 1, this%ndelaycells
5702  dh = this%dbdh(n) - this%dbh(n, idelay)
5703  if (abs(dh) > abs(dhmax)) then
5704  dhmax = dh
5705  if (lupdate) then
5706  this%dbdhmax(idelay) = dhmax
5707  end if
5708  end if
5709  ! -- update delay bed heads
5710  this%dbh(n, idelay) = this%dbdh(n)
5711  end do
5712  !
5713  ! -- update delay bed stresses
5714  call this%csub_delay_calc_stress(ib, hcell)
5715  !
5716  ! -- check delay bed convergence
5717  if (abs(dhmax) < dclose) then
5718  icnvg = 1
5719  else if (iter /= 1) then
5720  if (abs(dhmax) - abs(dhmax0) < dprec) then
5721  icnvg = 1
5722  end if
5723  end if
5724  if (icnvg == 1) then
5725  exit
5726  end if
5727  dhmax0 = dhmax
5728  end do
5729  end if
5730  end subroutine csub_delay_sln
5731 
5732  !> @brief Calculate delay interbed znode and z relative to interbed center
5733  !!
5734  !! Method to calculate the initial center of each delay interbed cell,
5735  !! assuming the delay bed head is equal to the top of the delay interbed.
5736  !! The method also calculates the distance of the center of each delay
5737  !! bed cell from the center of the delay interbed (z_offset) that is used
5738  !! to calculate average skeletal specific storage values for a delay interbed
5739  !! centered on the center of the saturated thickness for a cell.
5740  !!
5741  !<
5742  subroutine csub_delay_init_zcell(this, ib)
5743  ! -- dummy variables
5744  class(gwfcsubtype), intent(inout) :: this
5745  integer(I4B), intent(in) :: ib !< interbed number
5746  ! -- local variables
5747  integer(I4B) :: n
5748  integer(I4B) :: node
5749  integer(I4B) :: idelay
5750  real(DP) :: bot
5751  real(DP) :: top
5752  real(DP) :: hbar
5753  real(DP) :: znode
5754  real(DP) :: dzz
5755  real(DP) :: z
5756  real(DP) :: zr
5757  real(DP) :: b
5758  real(DP) :: dz
5759  !
5760  ! -- initialize variables
5761  idelay = this%idelay(ib)
5762  node = this%nodelist(ib)
5763  b = this%thickini(ib)
5764  bot = this%dis%bot(node)
5765  top = bot + b
5766  hbar = top
5767  !
5768  ! -- calculate znode based on assumption that the delay bed bottom
5769  ! is equal to the cell bottom
5770  znode = this%csub_calc_znode(top, bot, hbar)
5771  dz = dhalf * this%dbdzini(1, idelay)
5772  dzz = dhalf * b
5773  z = znode + dzz
5774  zr = dzz
5775  !
5776  ! -- calculate z and z relative to znode for each delay
5777  ! interbed node
5778  do n = 1, this%ndelaycells
5779  ! z of node relative to bottom of cell
5780  z = z - dz
5781  this%dbz(n, idelay) = z
5782  z = z - dz
5783  ! z relative to znode
5784  zr = zr - dz
5785  if (abs(zr) < dz) then
5786  zr = dzero
5787  end if
5788  this%dbrelz(n, idelay) = zr
5789  zr = zr - dz
5790  end do
5791  end subroutine csub_delay_init_zcell
5792 
5793  !> @brief Calculate delay interbed stress values
5794  !!
5795  !! Method to calculate the geostatic and effective stress in delay interbed
5796  !! cells using the passed the current head value in a cell.
5797  !!
5798  !<
5799  subroutine csub_delay_calc_stress(this, ib, hcell)
5800  ! -- dummy variables
5801  class(gwfcsubtype), intent(inout) :: this
5802  integer(I4B), intent(in) :: ib !< interbed number
5803  real(DP), intent(in) :: hcell !< current head in a cell
5804  ! -- local variables
5805  integer(I4B) :: n
5806  integer(I4B) :: idelay
5807  integer(I4B) :: node
5808  real(DP) :: sigma
5809  real(DP) :: topaq
5810  real(DP) :: botaq
5811  real(DP) :: dzhalf
5812  real(DP) :: sadd
5813  real(DP) :: sgm
5814  real(DP) :: sgs
5815  real(DP) :: h
5816  real(DP) :: hbar
5817  real(DP) :: z
5818  real(DP) :: top
5819  real(DP) :: bot
5820  real(DP) :: phead
5821  !
5822  ! -- initialize variables
5823  idelay = this%idelay(ib)
5824  node = this%nodelist(ib)
5825  sigma = this%cg_gs(node)
5826  topaq = this%dis%top(node)
5827  botaq = this%dis%bot(node)
5828  dzhalf = dhalf * this%dbdzini(1, idelay)
5829  top = this%dbz(1, idelay) + dzhalf
5830  !
5831  ! -- calculate corrected head (hbar)
5832  hbar = squadratic0sp(hcell, botaq, this%satomega)
5833  !
5834  ! -- calculate the geostatic load in the cell at the top of the interbed.
5835  sgm = this%sgm(node)
5836  sgs = this%sgs(node)
5837  if (hcell < top) then
5838  sadd = ((top - hbar) * sgm) + ((hbar - botaq) * sgs)
5839  else
5840  sadd = (top - botaq) * sgs
5841  end if
5842  sigma = sigma - sadd
5843  !
5844  ! -- calculate geostatic and effective stress for each interbed node.
5845  do n = 1, this%ndelaycells
5846  h = this%dbh(n, idelay)
5847  !
5848  ! -- geostatic calculated at the bottom of the delay cell
5849  z = this%dbz(n, idelay)
5850  top = z + dzhalf
5851  bot = z - dzhalf
5852  !
5853  ! -- calculate corrected head (hbar)
5854  hbar = squadratic0sp(h, bot, this%satomega)
5855  !
5856  ! -- geostatic stress calculation
5857  if (h < top) then
5858  sadd = ((top - hbar) * sgm) + ((hbar - bot) * sgs)
5859  else
5860  sadd = (top - bot) * sgs
5861  end if
5862  sigma = sigma + sadd
5863  phead = hbar - bot
5864  this%dbgeo(n, idelay) = sigma
5865  this%dbes(n, idelay) = sigma - phead
5866  end do
5867  end subroutine csub_delay_calc_stress
5868 
5869  !> @brief Calculate delay interbed cell storage coefficients
5870  !!
5871  !! Method to calculate the ssk and sske value for a node in a delay
5872  !! interbed cell.
5873  !!
5874  !! @param[in,out] ssk skeletal specific storage value dependent on the
5875  !! preconsolidation stress
5876  !! @param[in,out] sske elastic skeletal specific storage value
5877  !!
5878  !<
5879  subroutine csub_delay_calc_ssksske(this, ib, n, hcell, ssk, sske)
5880  ! -- dummy variables
5881  class(gwfcsubtype), intent(inout) :: this
5882  integer(I4B), intent(in) :: ib !< interbed number
5883  integer(I4B), intent(in) :: n !< delay interbed cell number
5884  real(DP), intent(in) :: hcell !< current head in a cell
5885  real(DP), intent(inout) :: ssk !< delay interbed skeletal specific storage
5886  real(DP), intent(inout) :: sske !< delay interbed elastic skeletal specific storage
5887  ! -- local variables
5888  integer(I4B) :: idelay
5889  integer(I4B) :: ielastic
5890  integer(I4B) :: node
5891  real(DP) :: topcell
5892  real(DP) :: botcell
5893  real(DP) :: hbarcell
5894  real(DP) :: zcell
5895  real(DP) :: zcenter
5896  real(DP) :: dzhalf
5897  real(DP) :: top
5898  real(DP) :: bot
5899  real(DP) :: h
5900  real(DP) :: hbar
5901  real(DP) :: znode
5902  real(DP) :: zbot
5903  real(DP) :: es
5904  real(DP) :: es0
5905  real(DP) :: theta
5906  real(DP) :: f
5907  real(DP) :: f0
5908  !
5909  ! -- initialize variables
5910  sske = dzero
5911  ssk = dzero
5912  idelay = this%idelay(ib)
5913  ielastic = this%ielastic(ib)
5914  !
5915  ! -- calculate factor for the head-based case
5916  if (this%lhead_based .EQV. .true.) then
5917  f = done
5918  f0 = f
5919  !
5920  ! -- calculate factor for the effective stress case
5921  else
5922  node = this%nodelist(ib)
5923  theta = this%dbthetaini(n, idelay)
5924  !
5925  ! -- set top and bottom of layer
5926  topcell = this%dis%top(node)
5927  botcell = this%dis%bot(node)
5928  !
5929  ! -- calculate corrected head for the cell (hbarcell)
5930  hbarcell = squadratic0sp(hcell, botcell, this%satomega)
5931  !
5932  ! -- set location of delay node relative to the center
5933  ! of the cell based on current head
5934  zcell = this%csub_calc_znode(topcell, botcell, hbarcell)
5935  !
5936  ! -- set variables for delay interbed zcell calculations
5937  zcenter = zcell + this%dbrelz(n, idelay)
5938  dzhalf = dhalf * this%dbdzini(1, idelay)
5939  top = zcenter + dzhalf
5940  bot = zcenter - dzhalf
5941  h = this%dbh(n, idelay)
5942  !
5943  ! -- calculate corrected head for the delay interbed cell (hbar)
5944  hbar = squadratic0sp(h, bot, this%satomega)
5945  !
5946  ! -- calculate the center of the saturated portion of the
5947  ! delay interbed cell
5948  znode = this%csub_calc_znode(top, bot, hbar)
5949  !
5950  ! -- set reference point for bottom of delay interbed cell that is used to
5951  ! scale the effective stress at the bottom of the delay interbed cell
5952  zbot = this%dbz(n, idelay) - dzhalf
5953  !
5954  ! -- set the effective stress
5955  es = this%dbes(n, idelay)
5956  es0 = this%dbes0(n, idelay)
5957  !
5958  ! -- calculate the compression index factors for the delay
5959  ! node relative to the center of the cell based on the
5960  ! current and previous head
5961  call this%csub_calc_sfacts(node, zbot, znode, theta, es, es0, f)
5962  end if
5963  this%idbconvert(n, idelay) = 0
5964  sske = f * this%rci(ib)
5965  ssk = f * this%rci(ib)
5966  if (ielastic == 0) then
5967  if (this%dbes(n, idelay) > this%dbpcs(n, idelay)) then
5968  this%idbconvert(n, idelay) = 1
5969  ssk = f * this%ci(ib)
5970  end if
5971  end if
5972  end subroutine csub_delay_calc_ssksske
5973 
5974  !> @brief Assemble delay interbed coefficients
5975  !!
5976  !! Method to assemble matrix and right-hand side coefficients for a delay
5977  !! interbed. The method calls the appropriate standard or Newton-Raphson
5978  !! assembly routines and fills all of the entries for a delay interbed.
5979  !!
5980  !<
5981  subroutine csub_delay_assemble(this, ib, hcell)
5982  ! -- dummy variables
5983  class(gwfcsubtype), intent(inout) :: this
5984  integer(I4B), intent(in) :: ib !< interbed number
5985  real(DP), intent(in) :: hcell !< current head in a cell
5986  ! -- local variables
5987  integer(I4B) :: n
5988  real(DP) :: aii
5989  real(DP) :: au
5990  real(DP) :: al
5991  real(DP) :: r
5992  !
5993  ! -- calculate matrix terms for each delay bed cell
5994  do n = 1, this%ndelaycells
5995  !
5996  ! -- assemble terms
5997  if (this%inewton == 0) then
5998  call this%csub_delay_assemble_fc(ib, n, hcell, aii, au, al, r)
5999  else
6000  call this%csub_delay_assemble_fn(ib, n, hcell, aii, au, al, r)
6001  end if
6002  !
6003  ! -- add terms
6004  this%dbal(n) = al
6005  this%dbau(n) = au
6006  this%dbad(n) = aii
6007  this%dbrhs(n) = r
6008  end do
6009  end subroutine csub_delay_assemble
6010 
6011  !> @brief Assemble delay interbed standard formulation coefficients
6012  !!
6013  !! Method to assemble standard formulation matrix and right-hand side
6014  !! coefficients for a delay interbed.
6015  !!
6016  !<
6017  subroutine csub_delay_assemble_fc(this, ib, n, hcell, aii, au, al, r)
6018  ! -- modules
6019  use tdismodule, only: delt
6020  ! -- dummy variables
6021  class(gwfcsubtype), intent(inout) :: this
6022  integer(I4B), intent(in) :: ib !< interbed number
6023  integer(I4B), intent(in) :: n !< delay interbed cell number
6024  real(DP), intent(in) :: hcell !< current head in a cell
6025  real(DP), intent(inout) :: aii !< diagonal in the A matrix
6026  real(DP), intent(inout) :: au !< upper term in the A matrix
6027  real(DP), intent(inout) :: al !< lower term in the A matrix
6028  real(DP), intent(inout) :: r !< right-hand side term
6029  ! -- local variables
6030  integer(I4B) :: node
6031  integer(I4B) :: idelay
6032  integer(I4B) :: ielastic
6033  real(DP) :: dzini
6034  real(DP) :: dzhalf
6035  real(DP) :: c
6036  real(DP) :: c2
6037  real(DP) :: c3
6038  real(DP) :: tled
6039  real(DP) :: wcf
6040  real(DP) :: smult
6041  real(DP) :: sske
6042  real(DP) :: ssk
6043  real(DP) :: z
6044  real(DP) :: ztop
6045  real(DP) :: zbot
6046  real(DP) :: dz
6047  real(DP) :: dz0
6048  real(DP) :: theta
6049  real(DP) :: theta0
6050  real(DP) :: dsn
6051  real(DP) :: dsn0
6052  real(DP) :: gs
6053  real(DP) :: es0
6054  real(DP) :: pcs
6055  real(DP) :: wc
6056  real(DP) :: wc0
6057  real(DP) :: h
6058  real(DP) :: h0
6059  real(DP) :: hbar
6060  !
6061  ! -- initialize accumulators
6062  aii = dzero
6063  au = dzero
6064  al = dzero
6065  r = dzero
6066  !
6067  ! -- initialize local variables
6068  idelay = this%idelay(ib)
6069  ielastic = this%ielastic(ib)
6070  node = this%nodelist(ib)
6071  dzini = this%dbdzini(1, idelay)
6072  dzhalf = dhalf * dzini
6073  tled = done / delt
6074  c = this%kv(ib) / dzini
6075  c2 = dtwo * c
6076  c3 = dthree * c
6077  !
6078  ! -- add qdb terms
6079  aii = aii - c2
6080  !
6081  ! -- top or bottom cell
6082  if (n == 1 .or. n == this%ndelaycells) then
6083  aii = aii - c
6084  r = r - c2 * hcell
6085  end if
6086  !
6087  ! -- lower qdb term
6088  if (n > 1) then
6089  al = c
6090  end if
6091  !
6092  ! -- upper qdb term
6093  if (n < this%ndelaycells) then
6094  au = c
6095  end if
6096  !
6097  ! -- current and previous delay cell states
6098  z = this%dbz(n, idelay)
6099  ztop = z + dzhalf
6100  zbot = z - dzhalf
6101  h = this%dbh(n, idelay)
6102  h0 = this%dbh0(n, idelay)
6103  dz = this%dbdz(n, idelay)
6104  dz0 = this%dbdz0(n, idelay)
6105  theta = this%dbtheta(n, idelay)
6106  theta0 = this%dbtheta0(n, idelay)
6107  !
6108  ! -- calculate corrected head (hbar)
6109  hbar = squadratic0sp(h, zbot, this%satomega)
6110  !
6111  ! -- calculate saturation
6112  call this%csub_delay_calc_sat(node, idelay, n, h, h0, dsn, dsn0)
6113  !
6114  ! -- calculate ssk and sske
6115  call this%csub_delay_calc_ssksske(ib, n, hcell, ssk, sske)
6116  !
6117  ! -- calculate and add storage terms
6118  smult = dzini * tled
6119  gs = this%dbgeo(n, idelay)
6120  es0 = this%dbes0(n, idelay)
6121  pcs = this%dbpcs(n, idelay)
6122  aii = aii - smult * dsn * ssk
6123  if (ielastic /= 0) then
6124  r = r - smult * &
6125  (dsn * ssk * (gs + zbot) - dsn0 * sske * es0)
6126  else
6127  r = r - smult * &
6128  (dsn * ssk * (gs + zbot - pcs) + dsn0 * sske * (pcs - es0))
6129  end if
6130  !
6131  ! -- add storage correction term
6132  r = r + smult * dsn * ssk * (h - hbar)
6133  !
6134  ! -- add water compressibility terms
6135  wcf = this%brg * tled
6136  wc = dz * wcf * theta
6137  wc0 = dz0 * wcf * theta0
6138  aii = aii - dsn * wc
6139  r = r - dsn0 * wc0 * h0
6140  end subroutine csub_delay_assemble_fc
6141 
6142  !> @brief Assemble delay interbed Newton-Raphson formulation coefficients
6143  !!
6144  !! Method to assemble Newton-Raphson formulation matrix and right-hand side
6145  !! coefficients for a delay interbed.
6146  !!
6147  !<
6148  subroutine csub_delay_assemble_fn(this, ib, n, hcell, aii, au, al, r)
6149  ! -- modules
6150  use tdismodule, only: delt
6151  ! -- dummy variables
6152  class(gwfcsubtype), intent(inout) :: this
6153  integer(I4B), intent(in) :: ib !< interbed number
6154  integer(I4B), intent(in) :: n !< delay interbed cell number
6155  real(DP), intent(in) :: hcell !< current head in a cell
6156  real(DP), intent(inout) :: aii !< diagonal in the A matrix
6157  real(DP), intent(inout) :: au !< upper term in the A matrix
6158  real(DP), intent(inout) :: al !< lower term in the A matrix
6159  real(DP), intent(inout) :: r !< right-hand side term
6160  ! -- local variables
6161  integer(I4B) :: node
6162  integer(I4B) :: idelay
6163  integer(I4B) :: ielastic
6164  real(DP) :: dzini
6165  real(DP) :: dzhalf
6166  real(DP) :: c
6167  real(DP) :: c2
6168  real(DP) :: c3
6169  real(DP) :: tled
6170  real(DP) :: wcf
6171  real(DP) :: smult
6172  real(DP) :: sske
6173  real(DP) :: ssk
6174  real(DP) :: z
6175  real(DP) :: ztop
6176  real(DP) :: zbot
6177  real(DP) :: dz
6178  real(DP) :: dz0
6179  real(DP) :: theta
6180  real(DP) :: theta0
6181  real(DP) :: dsn
6182  real(DP) :: dsn0
6183  real(DP) :: dsnderv
6184  real(DP) :: wc
6185  real(DP) :: wc0
6186  real(DP) :: h
6187  real(DP) :: h0
6188  real(DP) :: hbar
6189  real(DP) :: hbarderv
6190  real(DP) :: gs
6191  real(DP) :: es0
6192  real(DP) :: pcs
6193  real(DP) :: qsto
6194  real(DP) :: stoderv
6195  real(DP) :: qwc
6196  real(DP) :: wcderv
6197  !
6198  ! -- initialize accumulators
6199  aii = dzero
6200  au = dzero
6201  al = dzero
6202  r = dzero
6203  !
6204  ! -- initialize local variables
6205  idelay = this%idelay(ib)
6206  ielastic = this%ielastic(ib)
6207  node = this%nodelist(ib)
6208  dzini = this%dbdzini(1, idelay)
6209  dzhalf = dhalf * dzini
6210  tled = done / delt
6211  c = this%kv(ib) / dzini
6212  c2 = dtwo * c
6213  c3 = dthree * c
6214  !
6215  ! -- add qdb terms
6216  aii = aii - c2
6217  !
6218  ! -- top or bottom cell
6219  if (n == 1 .or. n == this%ndelaycells) then
6220  aii = aii - c
6221  r = r - c2 * hcell
6222  end if
6223  !
6224  ! -- lower qdb term
6225  if (n > 1) then
6226  al = c
6227  end if
6228  !
6229  ! -- upper qdb term
6230  if (n < this%ndelaycells) then
6231  au = c
6232  end if
6233  !
6234  ! -- current and previous delay cell states
6235  z = this%dbz(n, idelay)
6236  ztop = z + dzhalf
6237  zbot = z - dzhalf
6238  h = this%dbh(n, idelay)
6239  h0 = this%dbh0(n, idelay)
6240  dz = this%dbdz(n, idelay)
6241  dz0 = this%dbdz0(n, idelay)
6242  theta = this%dbtheta(n, idelay)
6243  theta0 = this%dbtheta0(n, idelay)
6244  !
6245  ! -- calculate corrected head (hbar)
6246  hbar = squadratic0sp(h, zbot, this%satomega)
6247  !
6248  ! -- calculate the derivative of the hbar functions
6249  hbarderv = squadratic0spderivative(h, zbot, this%satomega)
6250  !
6251  ! -- calculate saturation
6252  call this%csub_delay_calc_sat(node, idelay, n, h, h0, dsn, dsn0)
6253  !
6254  ! -- calculate the derivative of the saturation
6255  dsnderv = this%csub_delay_calc_sat_derivative(node, idelay, n, hcell)
6256  !
6257  ! -- calculate ssk and sske
6258  call this%csub_delay_calc_ssksske(ib, n, hcell, ssk, sske)
6259  !
6260  ! -- calculate storage terms
6261  smult = dzini * tled
6262  gs = this%dbgeo(n, idelay)
6263  es0 = this%dbes0(n, idelay)
6264  pcs = this%dbpcs(n, idelay)
6265  if (ielastic /= 0) then
6266  qsto = smult * (dsn * ssk * (gs - hbar + zbot) - dsn0 * sske * es0)
6267  stoderv = -smult * dsn * ssk * hbarderv + &
6268  smult * ssk * (gs - hbar + zbot) * dsnderv
6269  else
6270  qsto = smult * (dsn * ssk * (gs - hbar + zbot - pcs) + &
6271  dsn0 * sske * (pcs - es0))
6272  stoderv = -smult * dsn * ssk * hbarderv + &
6273  smult * ssk * (gs - hbar + zbot - pcs) * dsnderv
6274  end if
6275  !
6276  ! -- Add additional term if using lagged effective stress
6277  if (this%ieslag /= 0) then
6278  if (ielastic /= 0) then
6279  stoderv = stoderv - smult * sske * es0 * dsnderv
6280  else
6281  stoderv = stoderv + smult * sske * (pcs - es0) * dsnderv
6282  end if
6283  end if
6284  !
6285  ! -- add newton-raphson storage terms
6286  aii = aii + stoderv
6287  r = r - qsto + stoderv * h
6288  !
6289  ! -- add water compressibility terms
6290  wcf = this%brg * tled
6291  wc = dz * wcf * theta
6292  wc0 = dz0 * wcf * theta0
6293  qwc = dsn0 * wc0 * h0 - dsn * wc * h
6294  wcderv = -dsn * wc - wc * h * dsnderv
6295  !
6296  ! -- Add additional term if using lagged effective stress
6297  if (this%ieslag /= 0) then
6298  wcderv = wcderv + wc0 * h0 * dsnderv
6299  end if
6300  !
6301  ! -- add newton-raphson water compressibility terms
6302  aii = aii + wcderv
6303  r = r - qwc + wcderv * h
6304  end subroutine csub_delay_assemble_fn
6305 
6306  !> @brief Calculate delay interbed saturation
6307  !!
6308  !! Method to calculate the saturation in a delay interbed cell.
6309  !!
6310  !! @param[in,out] snnew current saturation in delay interbed cell n
6311  !! @param[in,out] snold previous saturation in delay interbed cell n
6312  !!
6313  !<
6314  subroutine csub_delay_calc_sat(this, node, idelay, n, hcell, hcellold, &
6315  snnew, snold)
6316  ! -- dummy variables
6317  class(gwfcsubtype), intent(inout) :: this
6318  integer(I4B), intent(in) :: node !< cell node number
6319  integer(I4B), intent(in) :: idelay !< delay interbed number
6320  integer(I4B), intent(in) :: n !< delay interbed cell number
6321  real(DP), intent(in) :: hcell !< current head in delay interbed cell n
6322  real(DP), intent(in) :: hcellold !< previous head in delay interbed cell n
6323  real(DP), intent(inout) :: snnew !< current saturation in delay interbed cell n
6324  real(DP), intent(inout) :: snold !< previous saturation in delay interbed cell n
6325  ! -- local variables
6326  real(DP) :: dzhalf
6327  real(DP) :: top
6328  real(DP) :: bot
6329  !
6330  ! -- calculate delay interbed cell saturation
6331  if (this%stoiconv(node) /= 0) then
6332  dzhalf = dhalf * this%dbdzini(n, idelay)
6333  top = this%dbz(n, idelay) + dzhalf
6334  bot = this%dbz(n, idelay) - dzhalf
6335  snnew = squadraticsaturation(top, bot, hcell, this%satomega)
6336  snold = squadraticsaturation(top, bot, hcellold, this%satomega)
6337  else
6338  snnew = done
6339  snold = done
6340  end if
6341  if (this%ieslag /= 0) then
6342  snold = snnew
6343  end if
6344  end subroutine csub_delay_calc_sat
6345 
6346  !> @brief Calculate the delay interbed cell saturation derivative
6347  !!
6348  !! Function to calculate the derivative of the saturation with
6349  !! respect to the current head in delay interbed cell n.
6350  !!
6351  !! @return satderv derivative of saturation
6352  !<
6353  function csub_delay_calc_sat_derivative(this, node, idelay, n, hcell) &
6354  result(satderv)
6355  ! -- dummy variables
6356  class(gwfcsubtype), intent(inout) :: this
6357  integer(I4B), intent(in) :: node !< cell node number
6358  integer(I4B), intent(in) :: idelay !< delay interbed number
6359  integer(I4B), intent(in) :: n !< delay interbed cell number
6360  real(dp), intent(in) :: hcell !< current head in delay interbed cell n
6361  ! -- local variables
6362  real(dp) :: satderv
6363  real(dp) :: dzhalf
6364  real(dp) :: top
6365  real(dp) :: bot
6366 
6367  if (this%stoiconv(node) /= 0) then
6368  dzhalf = dhalf * this%dbdzini(n, idelay)
6369  top = this%dbz(n, idelay) + dzhalf
6370  bot = this%dbz(n, idelay) - dzhalf
6371  satderv = squadraticsaturationderivative(top, bot, hcell, this%satomega)
6372  else
6373  satderv = dzero
6374  end if
6375  end function csub_delay_calc_sat_derivative
6376 
6377  !> @brief Calculate delay interbed storage change
6378  !!
6379  !! Method to calculate the storage change in a delay interbed.
6380  !!
6381  !! @param[in,out] stoe current elastic storage change in delay interbed
6382  !! @param[in,out] stoi current inelastic storage changes in delay interbed
6383  !!
6384  !<
6385  subroutine csub_delay_calc_dstor(this, ib, hcell, stoe, stoi)
6386  ! -- dummy variables
6387  class(gwfcsubtype), intent(inout) :: this
6388  integer(I4B), intent(in) :: ib !< interbed number
6389  real(DP), intent(in) :: hcell !< current head in cell
6390  real(DP), intent(inout) :: stoe !< elastic storage change
6391  real(DP), intent(inout) :: stoi !< inelastic storage change
6392  ! -- local variables
6393  integer(I4B) :: idelay
6394  integer(I4B) :: ielastic
6395  integer(I4B) :: node
6396  integer(I4B) :: n
6397  real(DP) :: sske
6398  real(DP) :: ssk
6399  real(DP) :: fmult
6400  real(DP) :: v1
6401  real(DP) :: v2
6402  real(DP) :: ske
6403  real(DP) :: sk
6404  real(DP) :: z
6405  real(DP) :: zbot
6406  real(DP) :: h
6407  real(DP) :: h0
6408  real(DP) :: dsn
6409  real(DP) :: dsn0
6410  real(DP) :: hbar
6411  real(DP) :: dzhalf
6412  !
6413  ! -- initialize variables
6414  idelay = this%idelay(ib)
6415  ielastic = this%ielastic(ib)
6416  node = this%nodelist(ib)
6417  stoe = dzero
6418  stoi = dzero
6419  ske = dzero
6420  sk = dzero
6421  !
6422  !
6423  if (this%thickini(ib) > dzero) then
6424  fmult = this%dbdzini(1, idelay)
6425  dzhalf = dhalf * this%dbdzini(1, idelay)
6426  do n = 1, this%ndelaycells
6427  call this%csub_delay_calc_ssksske(ib, n, hcell, ssk, sske)
6428  z = this%dbz(n, idelay)
6429  zbot = z - dzhalf
6430  h = this%dbh(n, idelay)
6431  h0 = this%dbh0(n, idelay)
6432  call this%csub_delay_calc_sat(node, idelay, n, h, h0, dsn, dsn0)
6433  hbar = squadratic0sp(h, zbot, this%satomega)
6434  if (ielastic /= 0) then
6435  v1 = dsn * ssk * (this%dbgeo(n, idelay) - hbar + zbot) - &
6436  dsn0 * sske * this%dbes0(n, idelay)
6437  v2 = dzero
6438  else
6439  v1 = dsn * ssk * (this%dbgeo(n, idelay) - hbar + zbot - &
6440  this%dbpcs(n, idelay))
6441  v2 = dsn0 * sske * (this%dbpcs(n, idelay) - this%dbes0(n, idelay))
6442  end if
6443  !
6444  ! -- calculate inelastic and elastic storage components
6445  if (this%idbconvert(n, idelay) /= 0) then
6446  stoi = stoi + v1 * fmult
6447  stoe = stoe + v2 * fmult
6448  else
6449  stoe = stoe + (v1 + v2) * fmult
6450  end if
6451  !
6452  ! calculate inelastic and elastic storativity
6453  ske = ske + sske * fmult
6454  sk = sk + ssk * fmult
6455  end do
6456  end if
6457  !
6458  ! -- save ske and sk
6459  this%ske(ib) = ske
6460  this%sk(ib) = sk
6461  end subroutine csub_delay_calc_dstor
6462 
6463  !> @brief Calculate delay interbed water compressibility
6464  !!
6465  !! Method to calculate the change in water compressibility in a delay interbed.
6466  !!
6467  !! @param[in,out] dwc current water compressibility change in delay interbed
6468  !!
6469  !<
6470  subroutine csub_delay_calc_wcomp(this, ib, dwc)
6471  ! -- modules
6472  use tdismodule, only: delt
6473  ! -- dummy variables
6474  class(gwfcsubtype), intent(inout) :: this
6475  integer(I4B), intent(in) :: ib !< interbed number
6476  real(DP), intent(inout) :: dwc !< water compressibility change
6477  ! -- local variables
6478  integer(I4B) :: idelay
6479  integer(I4B) :: node
6480  integer(I4B) :: n
6481  real(DP) :: tled
6482  real(DP) :: h
6483  real(DP) :: h0
6484  real(DP) :: dz
6485  real(DP) :: dz0
6486  real(DP) :: dsn
6487  real(DP) :: dsn0
6488  real(DP) :: wc
6489  real(DP) :: wc0
6490  real(DP) :: v
6491  !
6492  ! -- initialize variables
6493  dwc = dzero
6494  !
6495  !
6496  if (this%thickini(ib) > dzero) then
6497  idelay = this%idelay(ib)
6498  node = this%nodelist(ib)
6499  tled = done / delt
6500  do n = 1, this%ndelaycells
6501  h = this%dbh(n, idelay)
6502  h0 = this%dbh0(n, idelay)
6503  dz = this%dbdz(n, idelay)
6504  dz0 = this%dbdz0(n, idelay)
6505  call this%csub_delay_calc_sat(node, idelay, n, h, h0, dsn, dsn0)
6506  wc = dz * this%brg * this%dbtheta(n, idelay)
6507  wc0 = dz0 * this%brg * this%dbtheta0(n, idelay)
6508  v = dsn0 * wc0 * h0 - dsn * wc * h
6509  dwc = dwc + v * tled
6510  end do
6511  end if
6512  end subroutine csub_delay_calc_wcomp
6513 
6514  !> @brief Calculate delay interbed compaction
6515  !!
6516  !! Method to calculate the compaction in a delay interbed.
6517  !!
6518  !! @param[in,out] comp compaction in delay interbed
6519  !! @param[in,out] compi inelastic compaction in delay interbed
6520  !! @param[in,out] compe elastic compaction in delay interbed
6521  !!
6522  !<
6523  subroutine csub_delay_calc_comp(this, ib, hcell, hcellold, comp, compi, compe)
6524  ! -- dummy variables
6525  class(gwfcsubtype), intent(inout) :: this
6526  integer(I4B), intent(in) :: ib !< interbed number
6527  real(DP), intent(in) :: hcell !< current head in cell
6528  real(DP), intent(in) :: hcellold !< previous head in cell
6529  real(DP), intent(inout) :: comp !< compaction in delay interbed
6530  real(DP), intent(inout) :: compi !< inelastic compaction in delay interbed
6531  real(DP), intent(inout) :: compe !< elastic compaction in delay interbed
6532  ! -- local variables
6533  integer(I4B) :: idelay
6534  integer(I4B) :: ielastic
6535  integer(I4B) :: node
6536  integer(I4B) :: n
6537  real(DP) :: snnew
6538  real(DP) :: snold
6539  real(DP) :: sske
6540  real(DP) :: ssk
6541  real(DP) :: fmult
6542  real(DP) :: h
6543  real(DP) :: h0
6544  real(DP) :: dsn
6545  real(DP) :: dsn0
6546  real(DP) :: v
6547  real(DP) :: v1
6548  real(DP) :: v2
6549  !
6550  ! -- initialize variables
6551  idelay = this%idelay(ib)
6552  ielastic = this%ielastic(ib)
6553  node = this%nodelist(ib)
6554  comp = dzero
6555  compi = dzero
6556  compe = dzero
6557  !
6558  ! -- calculate cell saturation
6559  call this%csub_calc_sat(node, hcell, hcellold, snnew, snold)
6560  !
6561  ! -- calculate compaction
6562  if (this%thickini(ib) > dzero) then
6563  fmult = this%dbdzini(1, idelay)
6564  do n = 1, this%ndelaycells
6565  h = this%dbh(n, idelay)
6566  h0 = this%dbh0(n, idelay)
6567  call this%csub_delay_calc_sat(node, idelay, n, h, h0, dsn, dsn0)
6568  call this%csub_delay_calc_ssksske(ib, n, hcell, ssk, sske)
6569  if (ielastic /= 0) then
6570  v1 = dsn * ssk * this%dbes(n, idelay) - sske * this%dbes0(n, idelay)
6571  v2 = dzero
6572  else
6573  v1 = dsn * ssk * (this%dbes(n, idelay) - this%dbpcs(n, idelay))
6574  v2 = dsn0 * sske * (this%dbpcs(n, idelay) - this%dbes0(n, idelay))
6575  end if
6576  v = (v1 + v2) * fmult
6577  comp = comp + v
6578  !
6579  ! -- save compaction data
6580  this%dbcomp(n, idelay) = v * snnew
6581  !
6582  ! -- calculate inelastic and elastic storage components
6583  if (this%idbconvert(n, idelay) /= 0) then
6584  compi = compi + v1 * fmult
6585  compe = compe + v2 * fmult
6586  else
6587  compe = compe + (v1 + v2) * fmult
6588  end if
6589  end do
6590  end if
6591  !
6592  ! -- fill compaction
6593  comp = comp * this%rnb(ib)
6594  compi = compi * this%rnb(ib)
6595  compe = compe * this%rnb(ib)
6596  end subroutine csub_delay_calc_comp
6597 
6598  !> @brief Update delay interbed material properties
6599  !!
6600  !! Method to update the thickness and porosity of each delay interbed cell.
6601  !!
6602  !<
6603  subroutine csub_delay_update(this, ib)
6604  ! -- dummy variables
6605  class(gwfcsubtype), intent(inout) :: this
6606  integer(I4B), intent(in) :: ib !< interbed number
6607  ! -- local variables
6608  integer(I4B) :: idelay
6609  integer(I4B) :: n
6610  real(DP) :: comp
6611  real(DP) :: thick
6612  real(DP) :: theta
6613  real(DP) :: tthick
6614  real(DP) :: wtheta
6615  !
6616  ! -- initialize variables
6617  idelay = this%idelay(ib)
6618  comp = dzero
6619  tthick = dzero
6620  wtheta = dzero
6621  !
6622  !
6623  do n = 1, this%ndelaycells
6624  !
6625  ! -- initialize compaction for delay cell
6626  comp = this%dbtcomp(n, idelay) + this%dbcomp(n, idelay)
6627  !
6628  ! -- scale compaction by rnb to get the compaction for
6629  ! the interbed system (as opposed to the full system)
6630  comp = comp / this%rnb(ib)
6631  !
6632  ! -- update thickness and theta
6633  if (abs(comp) > dzero) then
6634  thick = this%dbdzini(n, idelay)
6635  theta = this%dbthetaini(n, idelay)
6636  call this%csub_adj_matprop(comp, thick, theta)
6637  if (thick <= dzero) then
6638  write (errmsg, '(2(a,i0),a,g0,a)') &
6639  'Adjusted thickness for delay interbed (', ib, &
6640  ') cell (', n, ') is less than or equal to 0 (', thick, ').'
6641  call store_error(errmsg)
6642  end if
6643  if (theta <= dzero) then
6644  write (errmsg, '(2(a,i0),a,g0,a)') &
6645  'Adjusted theta for delay interbed (', ib, &
6646  ') cell (', n, 'is less than or equal to 0 (', theta, ').'
6647  call store_error(errmsg)
6648  end if
6649  this%dbdz(n, idelay) = thick
6650  this%dbtheta(n, idelay) = theta
6651  tthick = tthick + thick
6652  wtheta = wtheta + thick * theta
6653  else
6654  thick = this%dbdz(n, idelay)
6655  theta = this%dbtheta(n, idelay)
6656  tthick = tthick + thick
6657  wtheta = wtheta + thick * theta
6658  end if
6659  end do
6660  !
6661  ! -- calculate thickness weighted theta and save thickness and weighted
6662  ! theta values for delay interbed
6663  if (tthick > dzero) then
6664  wtheta = wtheta / tthick
6665  else
6666  tthick = dzero
6667  wtheta = dzero
6668  end if
6669  this%thick(ib) = tthick
6670  this%theta(ib) = wtheta
6671  end subroutine csub_delay_update
6672 
6673  !> @brief Calculate delay interbed contribution to the cell
6674  !!
6675  !! Method to calculate the coefficients to calculate the delay interbed
6676  !! contribution to a cell. The product of hcof* h - rhs equals the
6677  !! delay contribution to the cell
6678  !!
6679  !! @param[in,out] hcof coefficient dependent on current head
6680  !! @param[in,out] rhs right-hand side contributions
6681  !!
6682  !<
6683  subroutine csub_delay_fc(this, ib, hcof, rhs)
6684  ! -- dummy variables
6685  class(gwfcsubtype), intent(inout) :: this
6686  integer(I4B), intent(in) :: ib !< interbed number
6687  real(DP), intent(inout) :: hcof !< head dependent coefficient
6688  real(DP), intent(inout) :: rhs !< right-hand side
6689  ! -- local variables
6690  integer(I4B) :: idelay
6691  real(DP) :: c1
6692  real(DP) :: c2
6693  !
6694  ! -- initialize variables
6695  idelay = this%idelay(ib)
6696  hcof = dzero
6697  rhs = dzero
6698  if (this%thickini(ib) > dzero) then
6699  ! -- calculate terms for gwf matrix
6700  c1 = dtwo * this%kv(ib) / this%dbdzini(1, idelay)
6701  rhs = -c1 * this%dbh(1, idelay)
6702  c2 = dtwo * &
6703  this%kv(ib) / this%dbdzini(this%ndelaycells, idelay)
6704  rhs = rhs - c2 * this%dbh(this%ndelaycells, idelay)
6705  hcof = c1 + c2
6706  end if
6707  end subroutine csub_delay_fc
6708 
6709  !> @brief Calculate the flow from delay interbed top or bottom
6710  !!
6711  !! Function to calculate the flow from across the top or bottom of
6712  !! a delay interbed.
6713  !!
6714  !! @return q flow across the top or bottom of a delay interbed
6715  !<
6716  function csub_calc_delay_flow(this, ib, n, hcell) result(q)
6717  ! -- dummy variables
6718  class(gwfcsubtype), intent(inout) :: this
6719  integer(I4B), intent(in) :: ib !< interbed number
6720  integer(I4B), intent(in) :: n !< delay interbed cell
6721  real(dp), intent(in) :: hcell !< current head in cell
6722  ! -- local variables
6723  integer(I4B) :: idelay
6724  real(dp) :: q
6725  real(dp) :: c
6726  !
6727  ! -- calculate flow between delay interbed and GWF
6728  idelay = this%idelay(ib)
6729  c = dtwo * this%kv(ib) / this%dbdzini(n, idelay)
6730  q = c * (hcell - this%dbh(n, idelay))
6731  end function csub_calc_delay_flow
6732 
6733  !
6734  ! -- Procedures related to observations (type-bound)
6735 
6736  !> @brief Determine if observations are supported.
6737  !!
6738  !! Function to determine if observations are supported by the CSUB package.
6739  !! Observations are supported by the CSUB package.
6740  !!
6741  !<
6742  logical function csub_obs_supported(this)
6743  ! -- dummy variables
6744  class(gwfcsubtype) :: this
6745  !
6746  ! -- initialize variables
6747  csub_obs_supported = .true.
6748  end function csub_obs_supported
6749 
6750  !> @brief Define the observation types available in the package
6751  !!
6752  !! Method to define the observation types available in the CSUB package.
6753  !!
6754  !<
6755  subroutine csub_df_obs(this)
6756  ! -- dummy variables
6757  class(gwfcsubtype) :: this
6758  ! -- local variables
6759  integer(I4B) :: indx
6760  !
6761  ! -- Store obs type and assign procedure pointer
6762  ! for csub observation type.
6763  call this%obs%StoreObsType('csub', .true., indx)
6764  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6765  !
6766  ! -- Store obs type and assign procedure pointer
6767  ! for inelastic-csub observation type.
6768  call this%obs%StoreObsType('inelastic-csub', .true., indx)
6769  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6770  !
6771  ! -- Store obs type and assign procedure pointer
6772  ! for elastic-csub observation type.
6773  call this%obs%StoreObsType('elastic-csub', .true., indx)
6774  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6775  !
6776  ! -- Store obs type and assign procedure pointer
6777  ! for coarse-csub observation type.
6778  call this%obs%StoreObsType('coarse-csub', .false., indx)
6779  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6780  !
6781  ! -- Store obs type and assign procedure pointer
6782  ! for csub-cell observation type.
6783  call this%obs%StoreObsType('csub-cell', .true., indx)
6784  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6785  !
6786  ! -- Store obs type and assign procedure pointer
6787  ! for watercomp-csub observation type.
6788  call this%obs%StoreObsType('wcomp-csub-cell', .false., indx)
6789  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6790  !
6791  ! -- Store obs type and assign procedure pointer
6792  ! for interbed ske observation type.
6793  call this%obs%StoreObsType('ske', .true., indx)
6794  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6795  !
6796  ! -- Store obs type and assign procedure pointer
6797  ! for interbed sk observation type.
6798  call this%obs%StoreObsType('sk', .true., indx)
6799  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6800  !
6801  ! -- Store obs type and assign procedure pointer
6802  ! for ske-cell observation type.
6803  call this%obs%StoreObsType('ske-cell', .true., indx)
6804  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6805  !
6806  ! -- Store obs type and assign procedure pointer
6807  ! for sk-cell observation type.
6808  call this%obs%StoreObsType('sk-cell', .true., indx)
6809  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6810  !
6811  ! -- Store obs type and assign procedure pointer
6812  ! for geostatic-stress-cell observation type.
6813  call this%obs%StoreObsType('gstress-cell', .false., indx)
6814  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6815  !
6816  ! -- Store obs type and assign procedure pointer
6817  ! for effective-stress-cell observation type.
6818  call this%obs%StoreObsType('estress-cell', .false., indx)
6819  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6820  !
6821  ! -- Store obs type and assign procedure pointer
6822  ! for total-compaction observation type.
6823  call this%obs%StoreObsType('interbed-compaction', .true., indx)
6824  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6825  !
6826  ! -- Store obs type and assign procedure pointer
6827  ! for inelastic-compaction observation type.
6828  call this%obs%StoreObsType('inelastic-compaction', .true., indx)
6829  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6830  !
6831  ! -- Store obs type and assign procedure pointer
6832  ! for inelastic-compaction observation type.
6833  call this%obs%StoreObsType('elastic-compaction', .true., indx)
6834  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6835  !
6836  ! -- Store obs type and assign procedure pointer
6837  ! for coarse-compaction observation type.
6838  call this%obs%StoreObsType('coarse-compaction', .false., indx)
6839  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6840  !
6841  ! -- Store obs type and assign procedure pointer
6842  ! for inelastic-compaction-cell observation type.
6843  call this%obs%StoreObsType('inelastic-compaction-cell', .true., indx)
6844  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6845  !
6846  ! -- Store obs type and assign procedure pointer
6847  ! for elastic-compaction-cell observation type.
6848  call this%obs%StoreObsType('elastic-compaction-cell', .true., indx)
6849  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6850  !
6851  ! -- Store obs type and assign procedure pointer
6852  ! for compaction-cell observation type.
6853  call this%obs%StoreObsType('compaction-cell', .true., indx)
6854  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6855  !
6856  ! -- Store obs type and assign procedure pointer
6857  ! for interbed thickness observation type.
6858  call this%obs%StoreObsType('thickness', .true., indx)
6859  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6860  !
6861  ! -- Store obs type and assign procedure pointer
6862  ! for coarse-thickness observation type.
6863  call this%obs%StoreObsType('coarse-thickness', .false., indx)
6864  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6865  !
6866  ! -- Store obs type and assign procedure pointer
6867  ! for thickness-cell observation type.
6868  call this%obs%StoreObsType('thickness-cell', .false., indx)
6869  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6870  !
6871  ! -- Store obs type and assign procedure pointer
6872  ! for interbed theta observation type.
6873  call this%obs%StoreObsType('theta', .true., indx)
6874  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6875  !
6876  ! -- Store obs type and assign procedure pointer
6877  ! for coarse-theta observation type.
6878  call this%obs%StoreObsType('coarse-theta', .false., indx)
6879  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6880  !
6881  ! -- Store obs type and assign procedure pointer
6882  ! for theta-cell observation type.
6883  call this%obs%StoreObsType('theta-cell', .true., indx)
6884  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6885  !
6886  ! -- Store obs type and assign procedure pointer
6887  ! for preconstress-cell observation type.
6888  call this%obs%StoreObsType('preconstress-cell', .false., indx)
6889  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6890  !
6891  ! -- Store obs type and assign procedure pointer
6892  ! for delay-preconstress observation type.
6893  call this%obs%StoreObsType('delay-preconstress', .false., indx)
6894  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6895  !
6896  ! -- Store obs type and assign procedure pointer
6897  ! for delay-head observation type.
6898  call this%obs%StoreObsType('delay-head', .false., indx)
6899  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6900  !
6901  ! -- Store obs type and assign procedure pointer
6902  ! for delay-gstress observation type.
6903  call this%obs%StoreObsType('delay-gstress', .false., indx)
6904  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6905  !
6906  ! -- Store obs type and assign procedure pointer
6907  ! for delay-estress observation type.
6908  call this%obs%StoreObsType('delay-estress', .false., indx)
6909  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6910  !
6911  ! -- Store obs type and assign procedure pointer
6912  ! for delay-compaction observation type.
6913  call this%obs%StoreObsType('delay-compaction', .false., indx)
6914  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6915  !
6916  ! -- Store obs type and assign procedure pointer
6917  ! for delay-thickness observation type.
6918  call this%obs%StoreObsType('delay-thickness', .false., indx)
6919  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6920  !
6921  ! -- Store obs type and assign procedure pointer
6922  ! for delay-theta observation type.
6923  call this%obs%StoreObsType('delay-theta', .false., indx)
6924  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6925  !
6926  ! -- Store obs type and assign procedure pointer
6927  ! for delay-flowtop observation type.
6928  call this%obs%StoreObsType('delay-flowtop', .true., indx)
6929  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6930  !
6931  ! -- Store obs type and assign procedure pointer
6932  ! for delay-flowbot observation type.
6933  call this%obs%StoreObsType('delay-flowbot', .true., indx)
6934  this%obs%obsData(indx)%ProcessIdPtr => csub_process_obsid
6935  end subroutine csub_df_obs
6936 
6937  !> @brief Set the observations for this time step
6938  !!
6939  !! Method to set the CSUB package observations for this time step.
6940  !!
6941  !<
6942  subroutine csub_bd_obs(this)
6943  ! -- dummy variables
6944  class(gwfcsubtype), intent(inout) :: this
6945  ! -- local variables
6946  type(observetype), pointer :: obsrv => null()
6947  integer(I4B) :: i
6948  integer(I4B) :: j
6949  integer(I4B) :: n
6950  integer(I4B) :: idelay
6951  integer(I4B) :: ncol
6952  integer(I4B) :: node
6953  real(DP) :: v
6954  real(DP) :: r
6955  real(DP) :: f
6956  !
6957  ! -- Fill simulated values for all csub observations
6958  if (this%obs%npakobs > 0) then
6959  call this%obs%obs_bd_clear()
6960  do i = 1, this%obs%npakobs
6961  obsrv => this%obs%pakobs(i)%obsrv
6962  if (obsrv%BndFound) then
6963  if (obsrv%ObsTypeId == 'SKE' .or. &
6964  obsrv%ObsTypeId == 'SK' .or. &
6965  obsrv%ObsTypeId == 'SKE-CELL' .or. &
6966  obsrv%ObsTypeId == 'SK-CELL' .or. &
6967  obsrv%ObsTypeId == 'DELAY-HEAD' .or. &
6968  obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. &
6969  obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. &
6970  obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. &
6971  obsrv%ObsTypeId == 'PRECONSTRESS-CELL') then
6972  if (this%gwfiss /= 0) then
6973  call this%obs%SaveOneSimval(obsrv, dnodata)
6974  else
6975  v = dzero
6976  do j = 1, obsrv%indxbnds_count
6977  n = obsrv%indxbnds(j)
6978  select case (obsrv%ObsTypeId)
6979  case ('SKE')
6980  v = this%ske(n)
6981  case ('SK')
6982  v = this%sk(n)
6983  case ('SKE-CELL')
6984  !
6985  ! -- add the coarse component
6986  if (j == 1) then
6987  v = this%cg_ske(n)
6988  else
6989  v = this%ske(n)
6990  end if
6991  case ('SK-CELL')
6992  !
6993  ! -- add the coarse component
6994  if (j == 1) then
6995  v = this%cg_sk(n)
6996  else
6997  v = this%sk(n)
6998  end if
6999  case ('DELAY-HEAD', 'DELAY-PRECONSTRESS', &
7000  'DELAY-GSTRESS', 'DELAY-ESTRESS')
7001  if (n > this%ndelaycells) then
7002  r = real(n - 1, dp) / real(this%ndelaycells, dp)
7003  idelay = int(floor(r)) + 1
7004  ncol = n - int(floor(r)) * this%ndelaycells
7005  else
7006  idelay = 1
7007  ncol = n
7008  end if
7009  select case (obsrv%ObsTypeId)
7010  case ('DELAY-HEAD')
7011  v = this%dbh(ncol, idelay)
7012  case ('DELAY-PRECONSTRESS')
7013  v = this%dbpcs(ncol, idelay)
7014  case ('DELAY-GSTRESS')
7015  v = this%dbgeo(ncol, idelay)
7016  case ('DELAY-ESTRESS')
7017  v = this%dbes(ncol, idelay)
7018  end select
7019  case ('PRECONSTRESS-CELL')
7020  v = this%pcs(n)
7021  case default
7022  errmsg = "Unrecognized observation type '"// &
7023  trim(obsrv%ObsTypeId)//"'."
7024  call store_error(errmsg)
7025  end select
7026  call this%obs%SaveOneSimval(obsrv, v)
7027  end do
7028  end if
7029  else
7030  v = dzero
7031  do j = 1, obsrv%indxbnds_count
7032  n = obsrv%indxbnds(j)
7033  select case (obsrv%ObsTypeId)
7034  case ('CSUB')
7035  v = this%storagee(n) + this%storagei(n)
7036  case ('INELASTIC-CSUB')
7037  v = this%storagei(n)
7038  case ('ELASTIC-CSUB')
7039  v = this%storagee(n)
7040  case ('COARSE-CSUB')
7041  v = this%cg_stor(n)
7042  case ('WCOMP-CSUB-CELL')
7043  v = this%cell_wcstor(n)
7044  case ('CSUB-CELL')
7045  !
7046  ! -- add the coarse component
7047  if (j == 1) then
7048  v = this%cg_stor(n)
7049  else
7050  v = this%storagee(n) + this%storagei(n)
7051  end if
7052  case ('THETA')
7053  v = this%theta(n)
7054  case ('COARSE-THETA')
7055  v = this%cg_theta(n)
7056  case ('THETA-CELL')
7057  !
7058  ! -- add the coarse component
7059  if (j == 1) then
7060  f = this%cg_thick(n) / this%cell_thick(n)
7061  v = f * this%cg_theta(n)
7062  else
7063  node = this%nodelist(n)
7064  f = this%csub_calc_interbed_thickness(n) / this%cell_thick(node)
7065  v = f * this%theta(n)
7066  end if
7067  case ('GSTRESS-CELL')
7068  v = this%cg_gs(n)
7069  case ('ESTRESS-CELL')
7070  v = this%cg_es(n)
7071  case ('INTERBED-COMPACTION')
7072  v = this%tcomp(n)
7073  case ('INELASTIC-COMPACTION')
7074  v = this%tcompi(n)
7075  case ('ELASTIC-COMPACTION')
7076  v = this%tcompe(n)
7077  case ('COARSE-COMPACTION')
7078  v = this%cg_tcomp(n)
7079  case ('INELASTIC-COMPACTION-CELL')
7080  !
7081  ! -- no coarse inelastic component
7082  if (j > 1) then
7083  v = this%tcompi(n)
7084  end if
7085  case ('ELASTIC-COMPACTION-CELL')
7086  !
7087  ! -- add the coarse component
7088  if (j == 1) then
7089  v = this%cg_tcomp(n)
7090  else
7091  v = this%tcompe(n)
7092  end if
7093  case ('COMPACTION-CELL')
7094  !
7095  ! -- add the coarse component
7096  if (j == 1) then
7097  v = this%cg_tcomp(n)
7098  else
7099  v = this%tcomp(n)
7100  end if
7101  case ('THICKNESS')
7102  idelay = this%idelay(n)
7103  v = this%thick(n)
7104  if (idelay /= 0) then
7105  v = v * this%rnb(n)
7106  end if
7107  case ('COARSE-THICKNESS')
7108  v = this%cg_thick(n)
7109  case ('THICKNESS-CELL')
7110  v = this%cell_thick(n)
7111  case ('DELAY-COMPACTION', 'DELAY-THICKNESS', &
7112  'DELAY-THETA')
7113  if (n > this%ndelaycells) then
7114  r = real(n, dp) / real(this%ndelaycells, dp)
7115  idelay = int(floor(r)) + 1
7116  ncol = mod(n, this%ndelaycells)
7117  else
7118  idelay = 1
7119  ncol = n
7120  end if
7121  select case (obsrv%ObsTypeId)
7122  case ('DELAY-COMPACTION')
7123  v = this%dbtcomp(ncol, idelay)
7124  case ('DELAY-THICKNESS')
7125  v = this%dbdz(ncol, idelay)
7126  case ('DELAY-THETA')
7127  v = this%dbtheta(ncol, idelay)
7128  end select
7129  case ('DELAY-FLOWTOP')
7130  idelay = this%idelay(n)
7131  v = this%dbflowtop(idelay)
7132  case ('DELAY-FLOWBOT')
7133  idelay = this%idelay(n)
7134  v = this%dbflowbot(idelay)
7135  case default
7136  errmsg = "Unrecognized observation type: '"// &
7137  trim(obsrv%ObsTypeId)//"'."
7138  call store_error(errmsg)
7139  end select
7140  call this%obs%SaveOneSimval(obsrv, v)
7141  end do
7142  end if
7143  else
7144  call this%obs%SaveOneSimval(obsrv, dnodata)
7145  end if
7146  end do
7147  !
7148  ! -- write summary of package error messages
7149  if (count_errors() > 0) then
7150  call this%parser%StoreErrorUnit()
7151  end if
7152  end if
7153  end subroutine csub_bd_obs
7154 
7155  !> @brief Read and prepare the observations
7156  !!
7157  !! Method to read and prepare the observations for the CSUB package.
7158  !!
7159  !<
7160  subroutine csub_rp_obs(this)
7161  ! -- modules
7162  use tdismodule, only: kper
7163  ! -- dummy variables
7164  class(gwfcsubtype), intent(inout) :: this
7165  ! -- local variables
7166  class(observetype), pointer :: obsrv => null()
7167  character(len=LENBOUNDNAME) :: bname
7168  integer(I4B) :: i
7169  integer(I4B) :: j
7170  integer(I4B) :: n
7171  integer(I4B) :: n2
7172  integer(I4B) :: idelay
7173  !
7174  ! -- return if observations are not supported
7175  if (.not. this%csub_obs_supported()) then
7176  return
7177  end if
7178  !
7179  ! -- process each package observation
7180  ! only done the first stress period since boundaries are fixed
7181  ! for the simulation
7182  if (kper == 1) then
7183  do i = 1, this%obs%npakobs
7184  obsrv => this%obs%pakobs(i)%obsrv
7185  !
7186  ! -- initialize BndFound to .false.
7187  obsrv%BndFound = .false.
7188  !
7189  bname = obsrv%FeatureName
7190  if (bname /= '') then
7191  !
7192  ! -- Observation location(s) is(are) based on a boundary name.
7193  ! Iterate through all boundaries to identify and store
7194  ! corresponding index(indices) in bound array.
7195  do j = 1, this%ninterbeds
7196  if (this%boundname(j) == bname) then
7197  obsrv%BndFound = .true.
7198  obsrv%CurrentTimeStepEndValue = dzero
7199  call obsrv%AddObsIndex(j)
7200  end if
7201  end do
7202  !
7203  ! -- one value per cell
7204  else if (obsrv%ObsTypeId == 'GSTRESS-CELL' .or. &
7205  obsrv%ObsTypeId == 'ESTRESS-CELL' .or. &
7206  obsrv%ObsTypeId == 'THICKNESS-CELL' .or. &
7207  obsrv%ObsTypeId == 'COARSE-CSUB' .or. &
7208  obsrv%ObsTypeId == 'WCOMP-CSUB-CELL' .or. &
7209  obsrv%ObsTypeId == 'COARSE-COMPACTION' .or. &
7210  obsrv%ObsTypeId == 'COARSE-THETA' .or. &
7211  obsrv%ObsTypeId == 'COARSE-THICKNESS') then
7212  obsrv%BndFound = .true.
7213  obsrv%CurrentTimeStepEndValue = dzero
7214  call obsrv%AddObsIndex(obsrv%NodeNumber)
7215  else if (obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. &
7216  obsrv%ObsTypeId == 'DELAY-HEAD' .or. &
7217  obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. &
7218  obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. &
7219  obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. &
7220  obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. &
7221  obsrv%ObsTypeId == 'DELAY-THETA') then
7222  if (this%ninterbeds > 0) then
7223  n = obsrv%NodeNumber
7224  idelay = this%idelay(n)
7225  if (idelay /= 0) then
7226  j = (idelay - 1) * this%ndelaycells + 1
7227  n2 = obsrv%NodeNumber2
7228  if (n2 < 1 .or. n2 > this%ndelaycells) then
7229  write (errmsg, '(a,2(1x,a),1x,i0,1x,a,i0,a)') &
7230  trim(adjustl(obsrv%ObsTypeId)), 'interbed cell must be ', &
7231  'greater than 0 and less than or equal to', this%ndelaycells, &
7232  '(specified value is ', n2, ').'
7233  call store_error(errmsg)
7234  else
7235  j = (idelay - 1) * this%ndelaycells + n2
7236  end if
7237  obsrv%BndFound = .true.
7238  call obsrv%AddObsIndex(j)
7239  end if
7240  end if
7241  !
7242  ! -- interbed value
7243  else if (obsrv%ObsTypeId == 'CSUB' .or. &
7244  obsrv%ObsTypeId == 'INELASTIC-CSUB' .or. &
7245  obsrv%ObsTypeId == 'ELASTIC-CSUB' .or. &
7246  obsrv%ObsTypeId == 'SK' .or. &
7247  obsrv%ObsTypeId == 'SKE' .or. &
7248  obsrv%ObsTypeId == 'THICKNESS' .or. &
7249  obsrv%ObsTypeId == 'THETA' .or. &
7250  obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. &
7251  obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. &
7252  obsrv%ObsTypeId == 'ELASTIC-COMPACTION') then
7253  if (this%ninterbeds > 0) then
7254  j = obsrv%NodeNumber
7255  if (j < 1 .or. j > this%ninterbeds) then
7256  write (errmsg, '(a,2(1x,a),1x,i0,1x,a,i0,a)') &
7257  trim(adjustl(obsrv%ObsTypeId)), 'interbed cell must be greater', &
7258  'than 0 and less than or equal to', this%ninterbeds, &
7259  '(specified value is ', j, ').'
7260  call store_error(errmsg)
7261  else
7262  obsrv%BndFound = .true.
7263  obsrv%CurrentTimeStepEndValue = dzero
7264  call obsrv%AddObsIndex(j)
7265  end if
7266  end if
7267  else if (obsrv%ObsTypeId == 'DELAY-FLOWTOP' .or. &
7268  obsrv%ObsTypeId == 'DELAY-FLOWBOT') then
7269  if (this%ninterbeds > 0) then
7270  j = obsrv%NodeNumber
7271  if (j < 1 .or. j > this%ninterbeds) then
7272  write (errmsg, '(a,2(1x,a),1x,i0,1x,a,i0,a)') &
7273  trim(adjustl(obsrv%ObsTypeId)), &
7274  'interbed cell must be greater ', &
7275  'than 0 and less than or equal to', this%ninterbeds, &
7276  '(specified value is ', j, ').'
7277  call store_error(errmsg)
7278  end if
7279  idelay = this%idelay(j)
7280  if (idelay /= 0) then
7281  obsrv%BndFound = .true.
7282  obsrv%CurrentTimeStepEndValue = dzero
7283  call obsrv%AddObsIndex(j)
7284  end if
7285  end if
7286  else
7287  !
7288  ! -- Accumulate values in a single cell
7289  ! -- Observation location is a single node number
7290  ! -- save node number in first position
7291  if (obsrv%ObsTypeId == 'CSUB-CELL' .or. &
7292  obsrv%ObsTypeId == 'SKE-CELL' .or. &
7293  obsrv%ObsTypeId == 'SK-CELL' .or. &
7294  obsrv%ObsTypeId == 'THETA-CELL' .or. &
7295  obsrv%ObsTypeId == 'INELASTIC-COMPACTION-CELL' .or. &
7296  obsrv%ObsTypeId == 'ELASTIC-COMPACTION-CELL' .or. &
7297  obsrv%ObsTypeId == 'COMPACTION-CELL') then
7298  if (.NOT. obsrv%BndFound) then
7299  obsrv%BndFound = .true.
7300  obsrv%CurrentTimeStepEndValue = dzero
7301  call obsrv%AddObsIndex(obsrv%NodeNumber)
7302  end if
7303  end if
7304  jloop: do j = 1, this%ninterbeds
7305  if (this%nodelist(j) == obsrv%NodeNumber) then
7306  obsrv%BndFound = .true.
7307  obsrv%CurrentTimeStepEndValue = dzero
7308  call obsrv%AddObsIndex(j)
7309  end if
7310  end do jloop
7311  end if
7312  end do
7313  !
7314  ! -- evaluate if there are any observation errors
7315  if (count_errors() > 0) then
7316  call store_error_unit(this%inunit)
7317  end if
7318  end if
7319  end subroutine csub_rp_obs
7320 
7321  !
7322  ! -- Procedures related to observations (NOT type-bound)
7323 
7324  !> @brief Process the observation IDs for the package
7325  !!
7326  !! Method to process the observation IDs for the CSUB package. This
7327  !! procedure is pointed to by ObsDataType%ProcesssIdPtr. It processes the
7328  !! ID string of an observation definition for csub-package observations.
7329  !!
7330  !<
7331  subroutine csub_process_obsid(obsrv, dis, inunitobs, iout)
7332  ! -- dummy variables
7333  type(observetype), intent(inout) :: obsrv !< observation type
7334  class(disbasetype), intent(in) :: dis !< pointer to the model discretization
7335  integer(I4B), intent(in) :: inunitobs !< unit number of the observation file
7336  integer(I4B), intent(in) :: iout !< unit number to the model listing file
7337  ! -- local variables
7338  integer(I4B) :: nn1
7339  integer(I4B) :: nn2
7340  integer(I4B) :: icol, istart, istop
7341  character(len=LINELENGTH) :: string
7342  character(len=LENBOUNDNAME) :: bndname
7343  logical(LGP) :: flag_string
7344  !
7345  ! -- initialize variables
7346  string = obsrv%IDstring
7347  flag_string = .true.
7348  !
7349  ! -- Extract reach number from string and store it.
7350  ! If 1st item is not an integer(I4B), it should be a
7351  ! boundary name--deal with it.
7352  icol = 1
7353  !
7354  ! -- get icsubno number or boundary name
7355  if (obsrv%ObsTypeId == 'CSUB' .or. &
7356  obsrv%ObsTypeId == 'INELASTIC-CSUB' .or. &
7357  obsrv%ObsTypeId == 'ELASTIC-CSUB' .or. &
7358  obsrv%ObsTypeId == 'SK' .or. &
7359  obsrv%ObsTypeId == 'SKE' .or. &
7360  obsrv%ObsTypeId == 'THETA' .or. &
7361  obsrv%ObsTypeId == 'THICKNESS' .or. &
7362  obsrv%ObsTypeId == 'INTERBED-COMPACTION' .or. &
7363  obsrv%ObsTypeId == 'INELASTIC-COMPACTION' .or. &
7364  obsrv%ObsTypeId == 'ELASTIC-COMPACTION' .or. &
7365  obsrv%ObsTypeId == 'DELAY-HEAD' .or. &
7366  obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. &
7367  obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. &
7368  obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. &
7369  obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. &
7370  obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. &
7371  obsrv%ObsTypeId == 'DELAY-THETA' .or. &
7372  obsrv%ObsTypeId == 'DELAY-FLOWTOP' .or. &
7373  obsrv%ObsTypeId == 'DELAY-FLOWBOT') then
7374  call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname)
7375  else
7376  nn1 = dis%noder_from_string(icol, istart, istop, inunitobs, &
7377  iout, string, flag_string)
7378  end if
7379  if (nn1 == namedboundflag) then
7380  obsrv%FeatureName = bndname
7381  else
7382  if (obsrv%ObsTypeId == 'DELAY-HEAD' .or. &
7383  obsrv%ObsTypeId == 'DELAY-GSTRESS' .or. &
7384  obsrv%ObsTypeId == 'DELAY-ESTRESS' .or. &
7385  obsrv%ObsTypeId == 'DELAY-PRECONSTRESS' .or. &
7386  obsrv%ObsTypeId == 'DELAY-COMPACTION' .or. &
7387  obsrv%ObsTypeId == 'DELAY-THICKNESS' .or. &
7388  obsrv%ObsTypeId == 'DELAY-THETA') then
7389  call extract_idnum_or_bndname(string, icol, istart, istop, nn2, bndname)
7390  if (nn2 == namedboundflag) then
7391  obsrv%FeatureName = bndname
7392  ! -- reset nn1
7393  nn1 = nn2
7394  else
7395  obsrv%NodeNumber2 = nn2
7396  end if
7397  end if
7398  end if
7399  !
7400  ! -- store reach number (NodeNumber)
7401  obsrv%NodeNumber = nn1
7402  end subroutine csub_process_obsid
7403 
7404  !> @ brief Define the list label for the package
7405  !!
7406  !! Method defined the list label for the CSUB package. The list label is
7407  !! the heading that is written to iout when PRINT_INPUT option is used.
7408  !!
7409  !<
7410  subroutine define_listlabel(this)
7411  ! -- dummy variables
7412  class(gwfcsubtype), intent(inout) :: this
7413  !
7414  ! -- create the header list label
7415  this%listlabel = trim(this%filtyp)//' NO.'
7416  if (this%dis%ndim == 3) then
7417  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
7418  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
7419  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
7420  elseif (this%dis%ndim == 2) then
7421  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
7422  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
7423  else
7424  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
7425  end if
7426  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'SIG0'
7427  if (this%inamedbound == 1) then
7428  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
7429  end if
7430  end subroutine define_listlabel
7431 
7432 end module gwfcsubmodule
This module contains block parser methods.
Definition: BlockParser.f90:7
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 linelength
maximum length of a standard line
Definition: Constants.f90:45
@ tabcenter
centered table column
Definition: Constants.f90:172
@ tabright
right justified table column
Definition: Constants.f90:173
@ tableft
left justified table column
Definition: Constants.f90:171
@ mnormal
normal output mode
Definition: Constants.f90:206
real(dp), parameter dem20
real constant 1e-20
Definition: Constants.f90:117
@ tabucstring
upper case string table data
Definition: Constants.f90:180
@ tabstring
string table data
Definition: Constants.f90:179
@ tabreal
real table data
Definition: Constants.f90:182
@ tabinteger
integer table data
Definition: Constants.f90:181
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:23
real(dp), parameter dp9
real constant 9/10
Definition: Constants.f90:72
real(dp), parameter dem10
real constant 1e-10
Definition: Constants.f90:113
real(dp), parameter dem7
real constant 1e-7
Definition: Constants.f90:110
real(dp), parameter dem8
real constant 1e-8
Definition: Constants.f90:111
integer(i4b), parameter namedboundflag
named bound flag
Definition: Constants.f90:49
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:95
real(dp), parameter dhnoflo
real no flow constant
Definition: Constants.f90:93
integer(i4b), parameter lenlistlabel
maximum length of a llist label
Definition: Constants.f90:46
real(dp), parameter dhundred
real constant 100
Definition: Constants.f90:86
integer(i4b), parameter lenpakloc
maximum length of a package location
Definition: Constants.f90:50
real(dp), parameter dem1
real constant 1e-1
Definition: Constants.f90:103
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 dgravity
real constant gravitational acceleration (m/(s s))
Definition: Constants.f90:132
integer(i4b), parameter lenauxname
maximum length of a aux variable
Definition: Constants.f90:35
integer(i4b), parameter lenboundname
maximum length of a bound name
Definition: Constants.f90:36
real(dp), parameter dem4
real constant 1e-4
Definition: Constants.f90:107
real(dp), parameter dem6
real constant 1e-6
Definition: Constants.f90:109
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
real(dp), parameter dten
real constant 10
Definition: Constants.f90:84
real(dp), parameter dprec
real constant machine precision
Definition: Constants.f90:120
integer(i4b), parameter maxcharlen
maximum length of char string
Definition: Constants.f90:47
real(dp), parameter dem15
real constant 1e-15
Definition: Constants.f90:116
real(dp), parameter dtwo
real constant 2
Definition: Constants.f90:79
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
Definition: Constants.f90:37
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
real(dp), parameter dthree
real constant 3
Definition: Constants.f90:80
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
integer(i4b) function, public get_node(ilay, irow, icol, nlay, nrow, ncol)
Get node number, given layer, row, and column indices for a structured grid. If any argument is inval...
Definition: GeomUtil.f90:83
This module contains the CSUB package methods.
Definition: gwf-csub.f90:9
subroutine csub_nodelay_wcomp_fn(this, ib, node, tled, area, hcell, hcellold, hcof, rhs)
@ brief Formulate no-delay interbed water compressibility coefficients
Definition: gwf-csub.f90:5306
subroutine csub_read_packagedata(this)
@ brief Read packagedata for package
Definition: gwf-csub.f90:1398
real(dp) function csub_calc_delay_flow(this, ib, n, hcell)
Calculate the flow from delay interbed top or bottom.
Definition: gwf-csub.f90:6717
subroutine csub_cg_wcomp_fc(this, node, tled, area, hcell, hcellold, hcof, rhs)
@ brief Formulate coarse-grained water compressibility coefficients
Definition: gwf-csub.f90:5139
subroutine csub_calc_sfacts(this, node, bot, znode, theta, es, es0, fact)
Calculate specific storage coefficient factor.
Definition: gwf-csub.f90:5580
subroutine csub_read_dimensions(this)
@ brief Read dimensions for package
Definition: gwf-csub.f90:1040
subroutine csub_delay_assemble_fn(this, ib, n, hcell, aii, au, al, r)
Assemble delay interbed Newton-Raphson formulation coefficients.
Definition: gwf-csub.f90:6149
subroutine csub_ar(this, dis, ibound)
@ brief Allocate and read method for package
Definition: gwf-csub.f90:361
subroutine csub_initialize_tables(this)
@ brief Initialize optional tables
Definition: gwf-csub.f90:2977
subroutine csub_nodelay_wcomp_fc(this, ib, node, tled, area, hcell, hcellold, hcof, rhs)
@ brief Formulate no-delay interbed water compressibility coefficients
Definition: gwf-csub.f90:5256
real(dp) function csub_calc_sat_derivative(this, node, hcell)
Calculate the saturation derivative.
Definition: gwf-csub.f90:5552
character(len=lenbudtxt), dimension(4) budtxt
Definition: gwf-csub.f90:55
subroutine read_options(this)
@ brief Read options for package
Definition: gwf-csub.f90:601
subroutine csub_cg_calc_comp(this, node, hcell, hcellold, comp)
@ brief Calculate coarse-grained compaction in a cell
Definition: gwf-csub.f90:5065
real(dp) function csub_calc_adjes(this, node, es0, z0, z)
Calculate the effective stress at elevation z.
Definition: gwf-csub.f90:5447
subroutine csub_cg_wcomp_fn(this, node, tled, area, hcell, hcellold, hcof, rhs)
@ brief Formulate coarse-grained water compressibility coefficients
Definition: gwf-csub.f90:5193
subroutine csub_interbed_fc(this, ib, node, area, hcell, hcellold, hcof, rhs)
@ brief Formulate the coefficients for a interbed
Definition: gwf-csub.f90:4833
subroutine csub_delay_fc(this, ib, hcof, rhs)
Calculate delay interbed contribution to the cell.
Definition: gwf-csub.f90:6684
subroutine csub_delay_update(this, ib)
Update delay interbed material properties.
Definition: gwf-csub.f90:6604
subroutine csub_delay_init_zcell(this, ib)
Calculate delay interbed znode and z relative to interbed center.
Definition: gwf-csub.f90:5743
subroutine csub_nodelay_update(this, i)
@ brief Update no-delay material properties
Definition: gwf-csub.f90:4113
subroutine csub_allocate_arrays(this)
@ brief Allocate package arrays
Definition: gwf-csub.f90:1222
subroutine csub_delay_calc_ssksske(this, ib, n, hcell, ssk, sske)
Calculate delay interbed cell storage coefficients.
Definition: gwf-csub.f90:5880
subroutine csub_adj_matprop(this, comp, thick, theta)
Calculate new material properties.
Definition: gwf-csub.f90:5620
subroutine csub_cg_calc_sske(this, n, sske, hcell)
@ brief Calculate Sske for a cell
Definition: gwf-csub.f90:5009
real(dp) function csub_calc_void_ratio(this, theta)
Calculate the void ratio.
Definition: gwf-csub.f90:5361
subroutine csub_fc(this, kiter, hold, hnew, matrix_sln, idxglo, rhs)
@ brief Fill A and r for the package
Definition: gwf-csub.f90:2762
subroutine csub_calc_sat(this, node, hcell, hcellold, snnew, snold)
Calculate cell saturation.
Definition: gwf-csub.f90:5518
real(dp) function csub_calc_theta(this, void_ratio)
Calculate the porosity.
Definition: gwf-csub.f90:5377
subroutine csub_cc(this, innertot, kiter, iend, icnvgmod, nodes, hnew, hold, cpak, ipak, dpak)
@ brief Final convergence check
Definition: gwf-csub.f90:3039
subroutine csub_delay_calc_wcomp(this, ib, dwc)
Calculate delay interbed water compressibility.
Definition: gwf-csub.f90:6471
subroutine csub_delay_calc_sat(this, node, idelay, n, hcell, hcellold, snnew, snold)
Calculate delay interbed saturation.
Definition: gwf-csub.f90:6316
real(dp) function csub_calc_znode(this, top, bottom, zbar)
Calculate the cell node.
Definition: gwf-csub.f90:5420
subroutine csub_delay_calc_comp(this, ib, hcell, hcellold, comp, compi, compe)
Calculate delay interbed compaction.
Definition: gwf-csub.f90:6524
subroutine csub_delay_calc_stress(this, ib, hcell)
Calculate delay interbed stress values.
Definition: gwf-csub.f90:5800
subroutine csub_nodelay_calc_comp(this, ib, hcell, hcellold, comp, rho1, rho2)
@ brief Calculate no-delay interbed compaction
Definition: gwf-csub.f90:4265
subroutine csub_set_initial_state(this, nodes, hnew)
@ brief Set initial states for the package
Definition: gwf-csub.f90:4306
subroutine csub_cg_calc_stress(this, nodes, hnew)
@ brief Calculate the stress for model cells
Definition: gwf-csub.f90:3919
real(dp) function csub_calc_interbed_thickness(this, ib)
Calculate the interbed thickness.
Definition: gwf-csub.f90:5394
real(dp), parameter dlog10es
derivative of the log of effective stress
Definition: gwf-csub.f90:70
subroutine csub_delay_assemble_fc(this, ib, n, hcell, aii, au, al, r)
Assemble delay interbed standard formulation coefficients.
Definition: gwf-csub.f90:6018
subroutine csub_interbed_fn(this, ib, node, hcell, hcellold, hcof, rhs)
@ brief Formulate the coefficients for a interbed
Definition: gwf-csub.f90:4919
subroutine csub_rp_obs(this)
Read and prepare the observations.
Definition: gwf-csub.f90:7161
subroutine csub_rp(this)
@ brief Read and prepare stress period data for package
Definition: gwf-csub.f90:2484
subroutine csub_nodelay_fc(this, ib, hcell, hcellold, rho1, rho2, rhs, argtled)
@ brief Calculate no-delay interbed storage coefficients
Definition: gwf-csub.f90:4158
subroutine csub_ad(this, nodes, hnew)
@ brief Advance the package
Definition: gwf-csub.f90:2645
subroutine csub_bd_obs(this)
Set the observations for this time step.
Definition: gwf-csub.f90:6943
subroutine csub_cg_update(this, node)
@ brief Update coarse-grained material properties
Definition: gwf-csub.f90:5094
subroutine csub_delay_assemble(this, ib, hcell)
Assemble delay interbed coefficients.
Definition: gwf-csub.f90:5982
subroutine csub_bd(this, isuppress_output, model_budget)
@ brief Model budget calculation for package
Definition: gwf-csub.f90:3523
subroutine define_listlabel(this)
@ brief Define the list label for the package
Definition: gwf-csub.f90:7411
subroutine, public csub_cr(csubobj, name_model, istounit, stoPckName, inunit, iout)
@ brief Create a new package object
Definition: gwf-csub.f90:325
subroutine csub_ot_dv(this, idvfl, idvprint)
@ brief Save and print dependent values for package
Definition: gwf-csub.f90:3654
real(dp) function csub_delay_calc_sat_derivative(this, node, idelay, n, hcell)
Calculate the delay interbed cell saturation derivative.
Definition: gwf-csub.f90:6355
subroutine csub_da(this)
@ brief Deallocate package memory
Definition: gwf-csub.f90:2262
subroutine csub_save_model_flows(this, icbcfl, icbcun)
@ brief Save model flows for package
Definition: gwf-csub.f90:3563
subroutine csub_cg_fn(this, node, tled, area, hcell, hcof, rhs)
@ brief Formulate coarse-grained Newton-Raphson terms
Definition: gwf-csub.f90:4761
subroutine csub_delay_head_check(this, ib)
Check delay interbed head.
Definition: gwf-csub.f90:5468
subroutine csub_delay_sln(this, ib, hcell, update)
Solve delay interbed continuity equation.
Definition: gwf-csub.f90:5650
subroutine csub_fp(this)
@ brief Final processing for package
Definition: gwf-csub.f90:1853
subroutine csub_process_obsid(obsrv, dis, inunitobs, iout)
Process the observation IDs for the package.
Definition: gwf-csub.f90:7332
subroutine csub_fn(this, kiter, hold, hnew, matrix_sln, idxglo, rhs)
@ brief Fill Newton-Raphson terms in A and r for the package
Definition: gwf-csub.f90:2879
logical function csub_obs_supported(this)
Determine if observations are supported.
Definition: gwf-csub.f90:6743
character(len=lenbudtxt), dimension(6) comptxt
Definition: gwf-csub.f90:60
subroutine csub_delay_calc_dstor(this, ib, hcell, stoe, stoi)
Calculate delay interbed storage change.
Definition: gwf-csub.f90:6386
subroutine csub_cg_chk_stress(this)
@ brief Check effective stress values
Definition: gwf-csub.f90:4052
subroutine csub_cg_fc(this, node, tled, area, hcell, hcellold, hcof, rhs)
@ brief Formulate the coefficients for coarse-grained materials
Definition: gwf-csub.f90:4695
subroutine csub_cq(this, nodes, hnew, hold, isuppress_output, flowja)
@ brief Calculate flows for package
Definition: gwf-csub.f90:3224
subroutine csub_allocate_scalars(this)
@ brief Allocate scalars
Definition: gwf-csub.f90:1109
subroutine csub_df_obs(this)
Define the observation types available in the package.
Definition: gwf-csub.f90:6756
subroutine, public ims_misc_thomas(n, tl, td, tu, b, x, w)
Tridiagonal solve using the Thomas algorithm.
subroutine, public urdaux(naux, inunit, iout, lloc, istart, istop, auxname, line, text)
Read auxiliary variables from an input line.
subroutine, public extract_idnum_or_bndname(line, icol, istart, istop, idnum, bndname)
Starting at position icol, define string as line(istart:istop).
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
This module defines variable data types.
Definition: kind.f90:8
pure logical function, public is_close(a, b, rtol, atol, symmetric)
Check if a real value is approximately equal to another.
Definition: MathUtil.f90:46
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
Store and issue logging messages to output units.
Definition: Message.f90:2
subroutine, public write_message(text, iunit, fmt, skipbefore, skipafter, advance)
Write a message to an output unit.
Definition: Message.f90:210
This module contains the base numerical package type.
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 obs_cr(obs, inobs)
@ brief Create a new ObsType object
Definition: Obs.f90:225
character(len=20) access
Definition: OpenSpec.f90:7
character(len=20) form
Definition: OpenSpec.f90:7
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_warning(msg, substring)
Store warning message.
Definition: Sim.f90:236
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_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
character(len=maxcharlen) warnmsg
warning message string
real(dp) function squadraticsaturation(top, bot, x, eps)
@ brief sQuadraticSaturation
real(dp) function squadraticsaturationderivative(top, bot, x, eps)
@ brief Derivative of the quadratic saturation function
real(dp) function squadratic0spderivative(x, xi, tomega)
@ brief sQuadratic0spDerivative
real(dp) function squadratic0sp(x, xi, tomega)
@ brief sQuadratic0sp
subroutine, public selectn(indx, v, reverse)
Definition: sort.f90:384
subroutine, public table_cr(this, name, title)
Definition: Table.f90:87
real(dp), pointer, public totim
time relative to start of simulation
Definition: tdis.f90:32
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:24
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:29
integer(i4b), pointer, public nper
number of stress period
Definition: tdis.f90:21
type(timeserieslinktype) function, pointer, public gettimeserieslinkfromlist(list, indx)
Get time series link from a list.
subroutine, public read_value_or_time_series_adv(textInput, ii, jj, bndElem, pkgName, auxOrBnd, tsManager, iprpak, varName)
Call this subroutine from advanced packages to define timeseries link for a variable (varName).
subroutine, public tsmanager_cr(this, iout, removeTsLinksOnCompletion, extendTsToEndOfSimulation)
Create the tsmanager.
Derived type for the Budget object.
Definition: Budget.f90:39
A generic heterogeneous doubly-linked list.
Definition: List.f90:14