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