MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
gwf-hfb.f90
Go to the documentation of this file.
1 
3 
4  use kindmodule, only: dp, i4b
5  use xt3dmodule, only: xt3dtype
6  use gwfvscmodule, only: gwfvsctype
9  use basedismodule, only: disbasetype
11 
12  implicit none
13 
14  private
15  public :: gwfhfbtype
16  public :: hfb_cr
17 
18  type, extends(numericalpackagetype) :: gwfhfbtype
19 
20  type(gwfvsctype), pointer :: vsc => null() !< viscosity object
21  integer(I4B), pointer :: maxhfb => null() !< max number of hfb's
22  integer(I4B), pointer :: nhfb => null() !< number of hfb's
23  integer(I4B), dimension(:), pointer, contiguous :: noden => null() !< first cell
24  integer(I4B), dimension(:), pointer, contiguous :: nodem => null() !< second cell
25  integer(I4B), dimension(:), pointer, contiguous :: idxloc => null() !< position in model ja
26  real(dp), dimension(:), pointer, contiguous :: hydchr => null() !< hydraulic characteristic of the barrier
27  real(dp), dimension(:), pointer, contiguous :: csatsav => null() !< value of condsat prior to hfb modification
28  real(dp), dimension(:), pointer, contiguous :: condsav => null() !< saved conductance of combined npf and hfb
29  type(xt3dtype), pointer :: xt3d => null() !< pointer to xt3d object
30  !
31  integer(I4B), dimension(:), pointer, contiguous :: ibound => null() !< pointer to model ibound
32  integer(I4B), dimension(:), pointer, contiguous :: icelltype => null() !< pointer to model icelltype
33  integer(I4B), dimension(:), pointer, contiguous :: ihc => null() !< pointer to model ihc
34  integer(I4B), dimension(:), pointer, contiguous :: ia => null() !< pointer to model ia
35  integer(I4B), dimension(:), pointer, contiguous :: ja => null() !< pointer to model ja
36  integer(I4B), dimension(:), pointer, contiguous :: jas => null() !< pointer to model jas
37  integer(I4B), dimension(:), pointer, contiguous :: isym => null() !< pointer to model isym
38  real(dp), dimension(:), pointer, contiguous :: condsat => null() !< pointer to model condsat
39  real(dp), dimension(:), pointer, contiguous :: top => null() !< pointer to model top
40  real(dp), dimension(:), pointer, contiguous :: bot => null() !< pointer to model bot
41  real(dp), dimension(:), pointer, contiguous :: hwva => null() !< pointer to model hwva
42  real(dp), dimension(:), pointer, contiguous :: hnew => null() !< pointer to model xnew
43  !
44  ! -- viscosity flag
45  integer(I4B), pointer :: ivsc => null() !< flag indicating if viscosity is active in the model
46 
47  contains
48 
49  procedure :: hfb_ar
50  procedure :: hfb_rp
51  procedure :: hfb_fc
52  procedure :: hfb_cq
53  procedure :: hfb_da
54  procedure :: allocate_scalars
55  procedure, private :: allocate_arrays
56  procedure, private :: read_options
57  procedure, private :: read_dimensions
58  procedure, private :: read_data
59  procedure, private :: check_data
60  procedure, private :: condsat_reset
61  procedure, private :: condsat_modify
62 
63  end type gwfhfbtype
64 
65 contains
66 
67  !> @brief Create a new hfb object
68  !<
69  subroutine hfb_cr(hfbobj, name_model, inunit, iout)
70  ! -- dummy
71  type(gwfhfbtype), pointer :: hfbobj
72  character(len=*), intent(in) :: name_model
73  integer(I4B), intent(in) :: inunit
74  integer(I4B), intent(in) :: iout
75  !
76  ! -- Create the object
77  allocate (hfbobj)
78  !
79  ! -- create name and memory path
80  call hfbobj%set_names(1, name_model, 'HFB', 'HFB')
81  !
82  ! -- Allocate scalars
83  call hfbobj%allocate_scalars()
84  !
85  ! -- Save unit numbers
86  hfbobj%inunit = inunit
87  hfbobj%iout = iout
88  !
89  ! -- Initialize block parser
90  call hfbobj%parser%Initialize(hfbobj%inunit, hfbobj%iout)
91  end subroutine hfb_cr
92 
93  !> @brief Allocate and read
94  !<
95  subroutine hfb_ar(this, ibound, xt3d, dis, invsc, vsc)
96  ! -- modules
99  ! -- dummy
100  class(gwfhfbtype) :: this
101  integer(I4B), dimension(:), pointer, contiguous :: ibound
102  type(xt3dtype), pointer :: xt3d
103  class(disbasetype), pointer, intent(inout) :: dis !< discretization package
104  integer(I4B), pointer :: invsc !< indicates if viscosity package is active
105  type(gwfvsctype), pointer, intent(in) :: vsc !< viscosity package
106  ! -- formats
107  character(len=*), parameter :: fmtheader = &
108  "(1x, /1x, 'HFB -- HORIZONTAL FLOW BARRIER PACKAGE, VERSION 8, ', &
109  &'4/24/2015 INPUT READ FROM UNIT ', i4, //)"
110  !
111  ! -- Print a message identifying the node property flow package.
112  write (this%iout, fmtheader) this%inunit
113  !
114  ! -- Set pointers
115  this%dis => dis
116  this%ibound => ibound
117  this%xt3d => xt3d
118  !
119  call mem_setptr(this%icelltype, 'ICELLTYPE', &
120  create_mem_path(this%name_model, 'NPF'))
121  call mem_setptr(this%ihc, 'IHC', create_mem_path(this%name_model, 'CON'))
122  call mem_setptr(this%ia, 'IA', create_mem_path(this%name_model, 'CON'))
123  call mem_setptr(this%ja, 'JA', create_mem_path(this%name_model, 'CON'))
124  call mem_setptr(this%jas, 'JAS', create_mem_path(this%name_model, 'CON'))
125  call mem_setptr(this%isym, 'ISYM', create_mem_path(this%name_model, 'CON'))
126  call mem_setptr(this%condsat, 'CONDSAT', create_mem_path(this%name_model, &
127  'NPF'))
128  call mem_setptr(this%top, 'TOP', create_mem_path(this%name_model, 'DIS'))
129  call mem_setptr(this%bot, 'BOT', create_mem_path(this%name_model, 'DIS'))
130  call mem_setptr(this%hwva, 'HWVA', create_mem_path(this%name_model, 'CON'))
131  !
132  call this%read_options()
133  call this%read_dimensions()
134  call this%allocate_arrays()
135  !
136  ! -- If vsc package active, set ivsc
137  if (invsc /= 0) then
138  this%ivsc = 1
139  this%vsc => vsc
140  !
141  ! -- Notify user via listing file viscosity accounted for by HFB package
142  write (this%iout, '(/1x,a,a)') 'Viscosity active in ', &
143  trim(this%filtyp)//' Package calculations: '//trim(adjustl(this%packName))
144  end if
145  end subroutine hfb_ar
146 
147  !> @brief Check for new HFB stress period data
148  !<
149  subroutine hfb_rp(this)
150  ! -- modules
151  use constantsmodule, only: linelength
153  use tdismodule, only: kper, nper
154  ! -- dummy
155  class(gwfhfbtype) :: this
156  ! -- local
157  character(len=LINELENGTH) :: line, errmsg
158  integer(I4B) :: ierr
159  logical :: isfound
160  ! -- formats
161  character(len=*), parameter :: fmtblkerr = &
162  &"('Error. Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
163  character(len=*), parameter :: fmtlsp = &
164  &"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
165  !
166  ! -- Set ionper to the stress period number for which a new block of data
167  ! will be read.
168  if (this%ionper < kper) then
169  !
170  ! -- get period block
171  call this%parser%GetBlock('PERIOD', isfound, ierr, &
172  supportopenclose=.true., &
173  blockrequired=.false.)
174  if (isfound) then
175  !
176  ! -- read ionper and check for increasing period numbers
177  call this%read_check_ionper()
178  else
179  !
180  ! -- PERIOD block not found
181  if (ierr < 0) then
182  ! -- End of file found; data applies for remainder of simulation.
183  this%ionper = nper + 1
184  else
185  ! -- Found invalid block
186  call this%parser%GetCurrentLine(line)
187  write (errmsg, fmtblkerr) adjustl(trim(line))
188  call store_error(errmsg)
189  call this%parser%StoreErrorUnit()
190  end if
191  end if
192  end if
193  !
194  if (this%ionper == kper) then
195  call this%condsat_reset()
196  call this%read_data()
197  call this%condsat_modify()
198  else
199  write (this%iout, fmtlsp) 'HFB'
200  end if
201  end subroutine hfb_rp
202 
203  !> @brief Fill matrix terms
204  !!
205  !! Fill amatsln for the following conditions:
206  !! 1. XT3D
207  !! OR
208  !! 2. Not Newton, and
209  !! 3. Cell type n is convertible or cell type m is convertible
210  !<
211  subroutine hfb_fc(this, kiter, matrix_sln, idxglo, rhs, hnew)
212  ! -- modules
213  use constantsmodule, only: dhalf, dzero, done
214  ! -- dummy
215  class(gwfhfbtype) :: this
216  integer(I4B) :: kiter
217  class(matrixbasetype), pointer :: matrix_sln
218  integer(I4B), intent(in), dimension(:) :: idxglo
219  real(DP), intent(inout), dimension(:) :: rhs
220  real(DP), intent(inout), dimension(:) :: hnew
221  ! -- local
222  integer(I4B) :: nodes, nja
223  integer(I4B) :: ihfb, n, m
224  integer(I4B) :: ipos
225  integer(I4B) :: idiag, isymcon
226  integer(I4B) :: ixt3d
227  real(DP) :: cond, condhfb, aterm
228  real(DP) :: fawidth, faheight
229  real(DP) :: topn, topm, botn, botm
230  real(DP) :: viscratio
231  !
232  ! -- initialize variables
233  viscratio = done
234  nodes = this%dis%nodes
235  nja = this%dis%con%nja
236  if (associated(this%xt3d%ixt3d)) then
237  ixt3d = this%xt3d%ixt3d
238  else
239  ixt3d = 0
240  end if
241  !
242  if (ixt3d > 0) then
243  !
244  do ihfb = 1, this%nhfb
245  n = min(this%noden(ihfb), this%nodem(ihfb))
246  m = max(this%noden(ihfb), this%nodem(ihfb))
247  ! -- Skip if either cell is inactive.
248  if (this%ibound(n) == 0 .or. this%ibound(m) == 0) cycle
249  !!! if(this%icelltype(n) == 1 .or. this%icelltype(m) == 1) then
250  if (this%ivsc /= 0) then
251  call this%vsc%get_visc_ratio(n, m, hnew(n), hnew(m), viscratio)
252  end if
253  ! -- Compute scale factor for hfb correction
254  if (this%hydchr(ihfb) > dzero) then
255  if (this%inewton == 0) then
256  ipos = this%idxloc(ihfb)
257  topn = this%top(n)
258  topm = this%top(m)
259  botn = this%bot(n)
260  botm = this%bot(m)
261  if (this%icelltype(n) == 1) then
262  if (hnew(n) < topn) topn = hnew(n)
263  end if
264  if (this%icelltype(m) == 1) then
265  if (hnew(m) < topm) topm = hnew(m)
266  end if
267  if (this%ihc(this%jas(ipos)) == 2) then
268  faheight = min(topn, topm) - max(botn, botm)
269  else
270  faheight = dhalf * ((topn - botn) + (topm - botm))
271  end if
272  fawidth = this%hwva(this%jas(ipos))
273  condhfb = this%hydchr(ihfb) * viscratio * &
274  fawidth * faheight
275  else
276  condhfb = this%hydchr(ihfb) * viscratio
277  end if
278  else
279  condhfb = this%hydchr(ihfb)
280  end if
281  ! -- Make hfb corrections for xt3d
282  call this%xt3d%xt3d_fhfb(kiter, nodes, nja, matrix_sln, idxglo, &
283  rhs, hnew, n, m, condhfb)
284  end do
285  !
286  else
287  !
288  ! -- For Newton, the effect of the barrier is included in condsat.
289  if (this%inewton == 0) then
290  do ihfb = 1, this%nhfb
291  ipos = this%idxloc(ihfb)
292  aterm = matrix_sln%get_value_pos(idxglo(ipos))
293  n = this%noden(ihfb)
294  m = this%nodem(ihfb)
295  if (this%ibound(n) == 0 .or. this%ibound(m) == 0) cycle
296  !
297  if (this%ivsc /= 0) then
298  call this%vsc%get_visc_ratio(n, m, hnew(n), hnew(m), viscratio)
299  end if
300  !
301  if (this%icelltype(n) == 1 .or. this%icelltype(m) == 1 .or. &
302  this%ivsc /= 0) then
303  !
304  ! -- Calculate hfb conductance
305  topn = this%top(n)
306  topm = this%top(m)
307  botn = this%bot(n)
308  botm = this%bot(m)
309  if (this%icelltype(n) == 1) then
310  if (hnew(n) < topn) topn = hnew(n)
311  end if
312  if (this%icelltype(m) == 1) then
313  if (hnew(m) < topm) topm = hnew(m)
314  end if
315  if (this%ihc(this%jas(ipos)) == 2) then
316  faheight = min(topn, topm) - max(botn, botm)
317  else
318  faheight = dhalf * ((topn - botn) + (topm - botm))
319  end if
320  if (this%hydchr(ihfb) > dzero) then
321  fawidth = this%hwva(this%jas(ipos))
322  condhfb = this%hydchr(ihfb) * viscratio * &
323  fawidth * faheight
324  cond = aterm * condhfb / (aterm + condhfb)
325  else
326  cond = -aterm * this%hydchr(ihfb)
327  end if
328  !
329  ! -- Save cond for budget calculation
330  this%condsav(ihfb) = cond
331  !
332  ! -- Fill row n diag and off diag
333  idiag = this%ia(n)
334  call matrix_sln%add_value_pos(idxglo(idiag), aterm - cond)
335  call matrix_sln%set_value_pos(idxglo(ipos), cond)
336  !
337  ! -- Fill row m diag and off diag
338  isymcon = this%isym(ipos)
339  idiag = this%ia(m)
340  call matrix_sln%add_value_pos(idxglo(idiag), aterm - cond)
341  call matrix_sln%set_value_pos(idxglo(isymcon), cond)
342  !
343  end if
344  end do
345  end if
346  !
347  end if
348  end subroutine hfb_fc
349 
350  !> @brief flowja will automatically include the effects of the hfb for
351  !! confined and newton cases when xt3d is not used.
352  !!
353  !! This method recalculates flowja for the other cases.
354  !<
355  subroutine hfb_cq(this, hnew, flowja)
356  ! -- modules
357  use constantsmodule, only: dhalf, dzero, done
358  ! -- dummy
359  class(gwfhfbtype) :: this
360  real(DP), intent(inout), dimension(:) :: hnew
361  real(DP), intent(inout), dimension(:) :: flowja
362  ! -- local
363  integer(I4B) :: ihfb, n, m
364  integer(I4B) :: ipos
365  real(DP) :: qnm
366  real(DP) :: cond
367  integer(I4B) :: ixt3d
368  real(DP) :: condhfb
369  real(DP) :: fawidth, faheight
370  real(DP) :: topn, topm, botn, botm
371  real(DP) :: viscratio
372  !
373  ! -- initialize viscratio
374  viscratio = done
375  !
376  if (associated(this%xt3d%ixt3d)) then
377  ixt3d = this%xt3d%ixt3d
378  else
379  ixt3d = 0
380  end if
381  !
382  if (ixt3d > 0) then
383  !
384  do ihfb = 1, this%nhfb
385  n = min(this%noden(ihfb), this%nodem(ihfb))
386  m = max(this%noden(ihfb), this%nodem(ihfb))
387  ! -- Skip if either cell is inactive.
388  if (this%ibound(n) == 0 .or. this%ibound(m) == 0) cycle
389  !!! if(this%icelltype(n) == 1 .or. this%icelltype(m) == 1) then
390  if (this%ivsc /= 0) then
391  call this%vsc%get_visc_ratio(n, m, hnew(n), hnew(m), viscratio)
392  end if
393  !
394  ! -- Compute scale factor for hfb correction
395  if (this%hydchr(ihfb) > dzero) then
396  if (this%inewton == 0) then
397  ipos = this%idxloc(ihfb)
398  topn = this%top(n)
399  topm = this%top(m)
400  botn = this%bot(n)
401  botm = this%bot(m)
402  if (this%icelltype(n) == 1) then
403  if (hnew(n) < topn) topn = hnew(n)
404  end if
405  if (this%icelltype(m) == 1) then
406  if (hnew(m) < topm) topm = hnew(m)
407  end if
408  if (this%ihc(this%jas(ipos)) == 2) then
409  faheight = min(topn, topm) - max(botn, botm)
410  else
411  faheight = dhalf * ((topn - botn) + (topm - botm))
412  end if
413  fawidth = this%hwva(this%jas(ipos))
414  condhfb = this%hydchr(ihfb) * viscratio * &
415  fawidth * faheight
416  else
417  condhfb = this%hydchr(ihfb)
418  end if
419  else
420  condhfb = this%hydchr(ihfb)
421  end if
422  ! -- Make hfb corrections for xt3d
423  call this%xt3d%xt3d_flowjahfb(n, m, hnew, flowja, condhfb)
424  end do
425  !
426  else
427  !
428  ! -- Recalculate flowja for non-newton unconfined.
429  if (this%inewton == 0) then
430  do ihfb = 1, this%nhfb
431  n = this%noden(ihfb)
432  m = this%nodem(ihfb)
433  if (this%ibound(n) == 0 .or. this%ibound(m) == 0) cycle
434  if (this%icelltype(n) == 1 .or. this%icelltype(m) == 1 .or. &
435  this%ivsc /= 0) then
436  ipos = this%dis%con%getjaindex(n, m)
437  !
438  ! -- condsav already accnts for visc adjustment
439  cond = this%condsav(ihfb)
440  qnm = cond * (hnew(m) - hnew(n))
441  flowja(ipos) = qnm
442  ipos = this%dis%con%getjaindex(m, n)
443  flowja(ipos) = -qnm
444  !
445  end if
446  end do
447  end if
448  !
449  end if
450  end subroutine hfb_cq
451 
452  !> @brief Deallocate memory
453  !<
454  subroutine hfb_da(this)
455  ! -- modules
457  ! -- dummy
458  class(gwfhfbtype) :: this
459  !
460  ! -- Scalars
461  call mem_deallocate(this%maxhfb)
462  call mem_deallocate(this%nhfb)
463  call mem_deallocate(this%ivsc)
464  !
465  ! -- Arrays
466  if (this%inunit > 0) then
467  call mem_deallocate(this%noden)
468  call mem_deallocate(this%nodem)
469  call mem_deallocate(this%hydchr)
470  call mem_deallocate(this%idxloc)
471  call mem_deallocate(this%csatsav)
472  call mem_deallocate(this%condsav)
473  end if
474  !
475  ! -- deallocate parent
476  call this%NumericalPackageType%da()
477  !
478  ! -- nullify pointers
479  this%xt3d => null()
480  this%inewton => null()
481  this%ibound => null()
482  this%icelltype => null()
483  this%ihc => null()
484  this%ia => null()
485  this%ja => null()
486  this%jas => null()
487  this%isym => null()
488  this%condsat => null()
489  this%top => null()
490  this%bot => null()
491  this%hwva => null()
492  this%vsc => null()
493  end subroutine hfb_da
494 
495  !> @brief Allocate package scalars
496  !<
497  subroutine allocate_scalars(this)
498  ! -- modules
500  ! -- dummy
501  class(gwfhfbtype) :: this
502  !
503  ! -- allocate scalars in NumericalPackageType
504  call this%NumericalPackageType%allocate_scalars()
505  !
506  ! -- allocate scalars
507  call mem_allocate(this%maxhfb, 'MAXHFB', this%memoryPath)
508  call mem_allocate(this%nhfb, 'NHFB', this%memoryPath)
509  !
510  ! -- allocate flag for determining if vsc active
511  call mem_allocate(this%ivsc, 'IVSC', this%memoryPath)
512  !
513  ! -- initialize
514  this%maxhfb = 0
515  this%nhfb = 0
516  this%ivsc = 0
517  end subroutine allocate_scalars
518 
519  !> @brief Allocate package arrays
520  !<
521  subroutine allocate_arrays(this)
522  ! -- modules
524  ! -- dummy
525  class(gwfhfbtype) :: this
526  ! -- local
527  integer(I4B) :: ihfb
528  !
529  call mem_allocate(this%noden, this%maxhfb, 'NODEN', this%memoryPath)
530  call mem_allocate(this%nodem, this%maxhfb, 'NODEM', this%memoryPath)
531  call mem_allocate(this%hydchr, this%maxhfb, 'HYDCHR', this%memoryPath)
532  call mem_allocate(this%idxloc, this%maxhfb, 'IDXLOC', this%memoryPath)
533  call mem_allocate(this%csatsav, this%maxhfb, 'CSATSAV', this%memoryPath)
534  call mem_allocate(this%condsav, this%maxhfb, 'CONDSAV', this%memoryPath)
535  !
536  ! -- initialize idxloc to 0
537  do ihfb = 1, this%maxhfb
538  this%idxloc(ihfb) = 0
539  end do
540  end subroutine allocate_arrays
541 
542  !> @brief Read a hfb options block
543  !<
544  subroutine read_options(this)
545  ! -- modules
546  use constantsmodule, only: linelength
548  ! -- dummy
549  class(gwfhfbtype) :: this
550  ! -- local
551  character(len=LINELENGTH) :: errmsg, keyword
552  integer(I4B) :: ierr
553  logical :: isfound, endOfBlock
554  !
555  ! -- get options block
556  call this%parser%GetBlock('OPTIONS', isfound, ierr, &
557  supportopenclose=.true., blockrequired=.false.)
558  !
559  ! -- parse options block if detected
560  if (isfound) then
561  write (this%iout, '(1x,a)') 'PROCESSING HFB OPTIONS'
562  do
563  call this%parser%GetNextLine(endofblock)
564  if (endofblock) exit
565  call this%parser%GetStringCaps(keyword)
566  select case (keyword)
567  case ('PRINT_INPUT')
568  this%iprpak = 1
569  write (this%iout, '(4x,a)') &
570  'THE LIST OF HFBS WILL BE PRINTED.'
571  case default
572  write (errmsg, '(a,a)') 'Unknown HFB option: ', &
573  trim(keyword)
574  call store_error(errmsg)
575  call this%parser%StoreErrorUnit()
576  end select
577  end do
578  write (this%iout, '(1x,a)') 'END OF HFB OPTIONS'
579  end if
580  end subroutine read_options
581 
582  !> @brief Read the dimensions for this package
583  !<
584  subroutine read_dimensions(this)
585  use constantsmodule, only: linelength
587  ! -- dummy
588  class(gwfhfbtype), intent(inout) :: this
589  ! -- local
590  character(len=LINELENGTH) :: errmsg, keyword
591  integer(I4B) :: ierr
592  logical :: isfound, endOfBlock
593  !
594  ! -- get dimensions block
595  call this%parser%GetBlock('DIMENSIONS', isfound, ierr, &
596  supportopenclose=.true.)
597  !
598  ! -- parse dimensions block if detected
599  if (isfound) then
600  write (this%iout, '(/1x,a)') 'PROCESSING HFB DIMENSIONS'
601  do
602  call this%parser%GetNextLine(endofblock)
603  if (endofblock) exit
604  call this%parser%GetStringCaps(keyword)
605  select case (keyword)
606  case ('MAXHFB')
607  this%maxhfb = this%parser%GetInteger()
608  write (this%iout, '(4x,a,i7)') 'MAXHFB = ', this%maxhfb
609  case default
610  write (errmsg, '(a,a)') &
611  'Unknown HFB dimension: ', trim(keyword)
612  call store_error(errmsg)
613  call this%parser%StoreErrorUnit()
614  end select
615  end do
616  !
617  write (this%iout, '(1x,a)') 'END OF HFB DIMENSIONS'
618  else
619  call store_error('Required DIMENSIONS block not found.')
620  call this%parser%StoreErrorUnit()
621  end if
622  !
623  ! -- verify dimensions were set
624  if (this%maxhfb <= 0) then
625  write (errmsg, '(a)') &
626  'MAXHFB must be specified with value greater than zero.'
627  call store_error(errmsg)
628  call this%parser%StoreErrorUnit()
629  end if
630  end subroutine read_dimensions
631 
632  !> @brief Read HFB period block
633  !!
634  !! Data are in form of:
635  !! L, IROW1, ICOL1, IROW2, ICOL2, HYDCHR
636  !! or for unstructured:
637  !! N1, N2, HYDCHR
638  !<
639  subroutine read_data(this)
640  ! -- modules
641  use constantsmodule, only: linelength
643  use tdismodule, only: kper
644  ! -- dummy
645  class(gwfhfbtype) :: this
646  ! -- local
647  character(len=LINELENGTH) :: nodenstr, nodemstr, cellidm, cellidn
648  integer(I4B) :: ihfb, nerr
649  logical :: endOfBlock
650  ! -- formats
651  character(len=*), parameter :: fmthfb = "(i10, 2a10, 1(1pg15.6))"
652  !
653  write (this%iout, '(//,1x,a)') 'READING HFB DATA'
654  if (this%iprpak > 0) then
655  write (this%iout, '(3a10, 1a15)') 'HFB NUM', 'CELL1', 'CELL2', &
656  'HYDCHR'
657  end if
658  !
659  ihfb = 0
660  this%nhfb = 0
661  readloop: do
662  !
663  ! -- Check for END of block
664  call this%parser%GetNextLine(endofblock)
665  if (endofblock) exit
666  !
667  ! -- Reset lloc and read noden, nodem, and hydchr
668  ihfb = ihfb + 1
669  if (ihfb > this%maxhfb) then
670  call store_error('MAXHFB not large enough.')
671  call this%parser%StoreErrorUnit()
672  end if
673  call this%parser%GetCellid(this%dis%ndim, cellidn)
674  this%noden(ihfb) = this%dis%noder_from_cellid(cellidn, &
675  this%parser%iuactive, &
676  this%iout)
677  call this%parser%GetCellid(this%dis%ndim, cellidm)
678  this%nodem(ihfb) = this%dis%noder_from_cellid(cellidm, &
679  this%parser%iuactive, &
680  this%iout)
681  this%hydchr(ihfb) = this%parser%GetDouble()
682  !
683  ! -- Print input if requested
684  if (this%iprpak /= 0) then
685  call this%dis%noder_to_string(this%noden(ihfb), nodenstr)
686  call this%dis%noder_to_string(this%nodem(ihfb), nodemstr)
687  write (this%iout, fmthfb) ihfb, trim(adjustl(nodenstr)), &
688  trim(adjustl(nodemstr)), this%hydchr(ihfb)
689  end if
690  !
691  this%nhfb = ihfb
692  end do readloop
693  !
694  ! -- Stop if errors
695  nerr = count_errors()
696  if (nerr > 0) then
697  call store_error('Errors encountered in HFB input file.')
698  call this%parser%StoreErrorUnit()
699  end if
700  !
701  write (this%iout, '(3x,i0,a,i0)') this%nhfb, &
702  ' HFBs READ FOR STRESS PERIOD ', kper
703  call this%check_data()
704  write (this%iout, '(1x,a)') 'END READING HFB DATA'
705  end subroutine read_data
706 
707  !> @brief Check for hfb's between two unconnected cells and write a warning
708  !!
709  !! Store ipos in idxloc
710  !<
711  subroutine check_data(this)
712  ! -- modules
713  use constantsmodule, only: linelength
715  ! -- dummy
716  class(gwfhfbtype) :: this
717  ! -- local
718  integer(I4B) :: ihfb, n, m
719  integer(I4B) :: ipos
720  character(len=LINELENGTH) :: nodenstr, nodemstr
721  character(len=LINELENGTH) :: errmsg
722  logical :: found
723  ! -- formats
724  character(len=*), parameter :: fmterr = "(1x, 'HFB no. ',i0, &
725  &' is between two unconnected cells: ', a, ' and ', a)"
726  character(len=*), parameter :: fmtverr = "(1x, 'HFB no. ',i0, &
727  &' is between two cells not horizontally connected: ', a, ' and ', a)"
728  !
729  do ihfb = 1, this%nhfb
730  n = this%noden(ihfb)
731  m = this%nodem(ihfb)
732  found = .false.
733  do ipos = this%ia(n) + 1, this%ia(n + 1) - 1
734  if (m == this%ja(ipos)) then
735  found = .true.
736  this%idxloc(ihfb) = ipos
737  exit
738  end if
739  end do
740  !
741  ! -- check to make sure cells are connected
742  if (.not. found) then
743  call this%dis%noder_to_string(n, nodenstr)
744  call this%dis%noder_to_string(m, nodemstr)
745  write (errmsg, fmterr) ihfb, trim(adjustl(nodenstr)), &
746  trim(adjustl(nodemstr))
747  call store_error(errmsg)
748  else
749  !
750  ! -- check to make sure cells are not vertically connected
751  ipos = this%idxloc(ihfb)
752  if (this%ihc(this%jas(ipos)) == 0) then
753  call this%dis%noder_to_string(n, nodenstr)
754  call this%dis%noder_to_string(m, nodemstr)
755  write (errmsg, fmtverr) ihfb, trim(adjustl(nodenstr)), &
756  trim(adjustl(nodemstr))
757  call store_error(errmsg)
758  end if
759  end if
760  end do
761  !
762  ! -- Stop if errors detected
763  if (count_errors() > 0) then
764  call store_error_unit(this%inunit)
765  end if
766  end subroutine check_data
767 
768  !> @brief Reset condsat to its value prior to being modified by hfb's
769  !<
770  subroutine condsat_reset(this)
771  ! -- dummy
772  class(gwfhfbtype) :: this
773  ! -- local
774  integer(I4B) :: ihfb
775  integer(I4B) :: ipos
776  !
777  do ihfb = 1, this%nhfb
778  ipos = this%idxloc(ihfb)
779  this%condsat(this%jas(ipos)) = this%csatsav(ihfb)
780  end do
781  end subroutine condsat_reset
782 
783  !> @brief Modify condsat
784  !!
785  !! Modify condsat for the following conditions:
786  !! 1. If Newton is active
787  !! 2. If icelltype for n and icelltype for m is 0
788  !<
789  subroutine condsat_modify(this)
790  ! -- modules
791  use constantsmodule, only: dhalf, dzero
792  ! -- dummy
793  class(gwfhfbtype) :: this
794  ! -- local
795  integer(I4B) :: ihfb, n, m
796  integer(I4B) :: ipos
797  real(DP) :: cond, condhfb
798  real(DP) :: fawidth, faheight
799  real(DP) :: topn, topm, botn, botm
800  !
801  do ihfb = 1, this%nhfb
802  ipos = this%idxloc(ihfb)
803  cond = this%condsat(this%jas(ipos))
804  this%csatsav(ihfb) = cond
805  n = this%noden(ihfb)
806  m = this%nodem(ihfb)
807  !
808  if (this%inewton == 1 .or. &
809  (this%icelltype(n) == 0 .and. this%icelltype(m) == 0)) then
810  !
811  ! -- Calculate hfb conductance
812  topn = this%top(n)
813  topm = this%top(m)
814  botn = this%bot(n)
815  botm = this%bot(m)
816  if (this%ihc(this%jas(ipos)) == 2) then
817  faheight = min(topn, topm) - max(botn, botm)
818  else
819  faheight = dhalf * ((topn - botn) + (topm - botm))
820  end if
821  if (this%hydchr(ihfb) > dzero) then
822  fawidth = this%hwva(this%jas(ipos))
823  condhfb = this%hydchr(ihfb) * &
824  fawidth * faheight
825  cond = cond * condhfb / (cond + condhfb)
826  else
827  cond = -cond * this%hydchr(ihfb)
828  end if
829  this%condsat(this%jas(ipos)) = cond
830  end if
831  end do
832  end subroutine condsat_modify
833 
834 end module gwfhfbmodule
This module contains block parser methods.
Definition: BlockParser.f90:7
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
real(dp), parameter dhalf
real constant 1/2
Definition: Constants.f90:68
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
subroutine hfb_fc(this, kiter, matrix_sln, idxglo, rhs, hnew)
Fill matrix terms.
Definition: gwf-hfb.f90:212
subroutine check_data(this)
Check for hfb's between two unconnected cells and write a warning.
Definition: gwf-hfb.f90:712
subroutine hfb_da(this)
Deallocate memory.
Definition: gwf-hfb.f90:455
subroutine hfb_cq(this, hnew, flowja)
flowja will automatically include the effects of the hfb for confined and newton cases when xt3d is n...
Definition: gwf-hfb.f90:356
subroutine read_dimensions(this)
Read the dimensions for this package.
Definition: gwf-hfb.f90:585
subroutine read_options(this)
Read a hfb options block.
Definition: gwf-hfb.f90:545
subroutine allocate_scalars(this)
Allocate package scalars.
Definition: gwf-hfb.f90:498
subroutine condsat_modify(this)
Modify condsat.
Definition: gwf-hfb.f90:790
subroutine condsat_reset(this)
Reset condsat to its value prior to being modified by hfb's.
Definition: gwf-hfb.f90:771
subroutine, public hfb_cr(hfbobj, name_model, inunit, iout)
Create a new hfb object.
Definition: gwf-hfb.f90:70
subroutine hfb_rp(this)
Check for new HFB stress period data.
Definition: gwf-hfb.f90:150
subroutine allocate_arrays(this)
Allocate package arrays.
Definition: gwf-hfb.f90:522
subroutine read_data(this)
Read HFB period block.
Definition: gwf-hfb.f90:640
subroutine hfb_ar(this, ibound, xt3d, dis, invsc, vsc)
Allocate and read.
Definition: gwf-hfb.f90:96
This module defines variable data types.
Definition: kind.f90:8
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
This module contains the base numerical package type.
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23
integer(i4b), pointer, public nper
number of stress period
Definition: tdis.f90:21