27 character(len=LENFTYPE) ::
ftype =
'SPC'
28 character(len=LENPACKAGENAME) ::
text =
'STRESS PACK CONC'
40 character(len=LENMODELNAME) :: name_model =
''
41 character(len=LENPACKAGENAME) :: packname =
''
42 character(len=LENPACKAGENAME) :: packnameflow =
''
43 character(len=LENMEMPATH) :: memorypath =
''
44 integer(I4B),
pointer :: id => null()
45 integer(I4B),
pointer :: inunit => null()
46 integer(I4B),
pointer :: iout => null()
47 integer(I4B),
pointer :: maxbound => null()
48 integer(I4B),
pointer :: ionper => null()
49 integer(I4B),
pointer :: lastonper => null()
50 integer(I4B),
pointer :: iprpak => null()
51 logical(LGP),
pointer :: readasarrays => null()
52 real(dp),
dimension(:),
pointer,
contiguous :: dblvec => null()
87 subroutine initialize(this, dis, id, inunit, iout, name_model, packNameFlow)
91 integer(I4B),
intent(in) :: id
92 integer(I4B),
intent(in) :: inunit
93 integer(I4B),
intent(in) :: iout
94 character(len=*),
intent(in) :: name_model
95 character(len=*),
intent(in) :: packNameflow
99 write (this%packName,
'(a, i0)')
'SPC'//
'-', id
100 this%name_model = name_model
104 call this%allocate_scalars()
110 this%packNameFlow = packnameflow
116 call this%parser%Initialize(this%inunit, this%iout)
120 call tasmanager_cr(this%TasManager, dis, name_model, this%iout)
123 call this%read_options()
126 if (this%readasarrays)
then
127 this%maxbound = this%dis%get_ncpl()
129 call this%read_dimensions()
133 call this%allocate_arrays()
136 call this%tsmanager%tsmanager_df()
137 call this%tasmanager%tasmanager_df()
156 call mem_allocate(this%inunit,
'INUNIT', this%memoryPath)
158 call mem_allocate(this%maxbound,
'MAXBOUND', this%memoryPath)
159 call mem_allocate(this%ionper,
'IONPER', this%memoryPath)
160 call mem_allocate(this%lastonper,
'LASTONPER', this%memoryPath)
161 call mem_allocate(this%iprpak,
'IPRPAK', this%memoryPath)
162 call mem_allocate(this%readasarrays,
'READASARRAYS', this%memoryPath)
165 allocate (this%TsManager)
166 allocate (this%TasManager)
176 this%readasarrays = .false.
192 character(len=LINELENGTH) :: keyword, fname
194 logical :: isfound, endOfBlock
196 character(len=*),
parameter :: fmtiprpak = &
197 &
"(4x,'SPC INFORMATION WILL BE PRINTED TO LISTING FILE.')"
198 character(len=*),
parameter :: fmtreadasarrays = &
199 "(4x,'SPC INFORMATION WILL BE READ AS ARRAYS RATHER THAN IN LIST &
201 character(len=*),
parameter :: fmtts = &
202 &
"(4x, 'TIME-SERIES DATA WILL BE READ FROM FILE: ', a)"
203 character(len=*),
parameter :: fmttas = &
204 &
"(4x, 'TIME-ARRAY SERIES DATA WILL BE READ FROM FILE: ', a)"
207 call this%parser%GetBlock(
'OPTIONS', isfound, ierr, blockrequired=.false., &
208 supportopenclose=.true.)
212 write (this%iout,
'(1x,a)')
'PROCESSING SPC OPTIONS'
214 call this%parser%GetNextLine(endofblock)
216 call this%parser%GetStringCaps(keyword)
217 select case (keyword)
220 write (this%iout, fmtiprpak)
221 case (
'READASARRAYS')
222 this%readasarrays = .true.
223 write (this%iout, fmtreadasarrays)
225 call this%parser%GetStringCaps(keyword)
226 if (trim(adjustl(keyword)) /=
'FILEIN')
then
227 errmsg =
'TS6 keyword must be followed by "FILEIN" '// &
231 call this%parser%GetString(fname)
232 write (this%iout, fmtts) trim(fname)
233 call this%TsManager%add_tsfile(fname, this%inunit)
235 call this%parser%GetStringCaps(keyword)
236 if (trim(adjustl(keyword)) /=
'FILEIN')
then
237 errmsg =
'TAS6 keyword must be followed by "FILEIN" '// &
240 call this%parser%StoreErrorUnit()
242 call this%parser%GetString(fname)
243 write (this%iout, fmttas) trim(fname)
244 call this%TasManager%add_tasfile(fname)
246 write (
errmsg,
'(a,a)')
'Unknown SPC option: ', trim(keyword)
248 call this%parser%StoreErrorUnit()
251 write (this%iout,
'(1x,a)')
'END OF SPC OPTIONS'
267 character(len=LINELENGTH) :: keyword
268 logical(LGP) :: isfound
269 logical(LGP) :: endOfBlock
273 call this%parser%GetBlock(
'DIMENSIONS', isfound, ierr, &
274 supportopenclose=.true.)
278 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(
text))// &
281 call this%parser%GetNextLine(endofblock)
283 call this%parser%GetStringCaps(keyword)
284 select case (keyword)
286 this%maxbound = this%parser%GetInteger()
287 write (this%iout,
'(4x,a,i7)')
'MAXBOUND = ', this%maxbound
289 write (
errmsg,
'(a,3(1x,a))') &
290 'Unknown', trim(
text),
'dimension:', trim(keyword)
295 write (this%iout,
'(1x,a)')
'END OF '//trim(adjustl(
text))//
' DIMENSIONS'
297 call store_error(
'Required DIMENSIONS block not found.')
298 call this%parser%StoreErrorUnit()
302 if (this%maxbound <= 0)
then
303 write (
errmsg,
'(a)')
'MAXBOUND must be an integer greater than zero.'
309 call this%parser%StoreErrorUnit()
330 call mem_allocate(this%dblvec, this%maxbound,
'DBLVEC', this%memoryPath)
333 do i = 1, this%maxbound
334 this%dblvec(i) =
dzero
346 function get_value(this, ientry, nbound_flow)
result(value)
348 integer(I4B),
intent(in) :: ientry
349 integer(I4B),
intent(in) :: nbound_flow
352 if (this%readasarrays)
then
363 if (nbound_flow == this%maxbound)
then
366 value = this%dblvec(ientry)
376 nu = this%dis%get_nodeuser(ientry)
377 value = this%dblvec(nu)
380 value = this%dblvec(ientry)
397 character(len=LINELENGTH) :: line
401 character(len=*),
parameter :: fmtblkerr = &
402 &
"('Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
403 character(len=*),
parameter :: fmtlsp = &
404 &
"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
408 if (this%inunit == 0)
return
411 if (this%ionper <
kper)
then
414 call this%parser%GetBlock(
'PERIOD', isfound, ierr, &
415 supportopenclose=.true., &
416 blockrequired=.false.)
420 call this%read_check_ionper()
426 this%ionper =
nper + 1
429 call this%parser%GetCurrentLine(line)
430 write (
errmsg, fmtblkerr) adjustl(trim(line))
437 if (this%ionper ==
kper)
then
444 call this%TasManager%Reset(this%packName)
445 if (this%readasarrays)
then
446 call this%spc_rp_array(line)
448 call this%spc_rp_list()
453 write (this%iout, fmtlsp) trim(
ftype)
458 call this%parser%StoreErrorUnit()
476 character(len=LINELENGTH) :: line
477 character(len=LINELENGTH) :: title
478 character(len=LINELENGTH) :: tabletext
479 logical :: endOfBlock
484 if (this%iprpak /= 0)
then
487 title = trim(adjustl(
text))//
' PACKAGE ('// &
488 'SPC'//
') DATA FOR PERIOD'
489 write (title,
'(a,1x,i6)') trim(adjustl(title)),
kper
491 call this%inputtab%table_df(1, 3, this%iout, finalize=.false.)
493 call this%inputtab%initialize_column(tabletext, 10, alignment=
tabcenter)
494 tabletext =
'DATA TYPE'
495 call this%inputtab%initialize_column(tabletext, 20, alignment=
tableft)
496 write (tabletext,
'(a,1x,i6)')
'VALUE'
497 call this%inputtab%initialize_column(tabletext, 15, alignment=
tabcenter)
502 call this%parser%GetNextLine(endofblock)
505 ival = this%parser%GetInteger()
506 if (ival < 1 .or. ival > this%maxbound)
then
507 write (
errmsg,
'(2(a,1x),i0,a)') &
508 'IVAL must be greater than 0 and', &
509 'less than or equal to ', this%maxbound,
'.'
515 call this%set_value(ival)
518 if (this%iprpak /= 0)
then
519 call this%parser%GetCurrentLine(line)
520 call this%inputtab%line_to_columns(line)
525 if (this%iprpak /= 0)
then
526 call this%inputtab%finalize_table()
544 character(len=LINELENGTH),
intent(inout) :: line
547 integer(I4B) :: ncolbnd
548 integer(I4B) :: jauxcol, ivarsread
549 integer(I4B),
dimension(:),
allocatable,
target :: nodelist
550 character(len=LENTIMESERIESNAME) :: tasName
551 character(len=24),
dimension(1) :: aname
552 character(len=LINELENGTH) :: keyword
553 logical :: endOfBlock
554 logical :: convertFlux
558 real(DP),
dimension(:),
pointer :: bndArrayPtr => null()
561 data aname(1)/
' CONCENTRATION'/
569 allocate (nodelist(this%maxbound))
570 do n = 1,
size(nodelist)
576 call this%parser%GetNextLine(endofblock)
578 call this%parser%GetStringCaps(keyword)
581 select case (keyword)
582 case (
'CONCENTRATION')
586 call this%parser%GetStringCaps(keyword)
587 if (keyword ==
'TIMEARRAYSERIES')
then
589 call this%parser%GetStringCaps(tasname)
590 bndarrayptr => this%dblvec(:)
593 convertflux = .false.
594 call this%TasManager%MakeTasLink(this%packName, bndarrayptr, &
595 this%iprpak, tasname, &
597 convertflux, nodelist, &
598 this%parser%iuactive)
602 call this%dis%read_layer_array(nodelist, this%dblvec, ncolbnd, &
603 this%maxbound, 1, aname(1), &
604 this%parser%iuactive, this%iout)
608 call store_error(
'Looking for CONCENTRATION. Found: '//trim(line))
609 call this%parser%StoreErrorUnit()
623 subroutine spc_ad(this, nbound_flowpack, budtxt)
627 integer(I4B),
intent(in) :: nbound_flowpack
628 character(len=*),
intent(in) :: budtxt
632 call this%TsManager%ad()
633 call this%TasManager%ad()
636 call this%check_flow_package(nbound_flowpack, budtxt)
667 call this%TsManager%da()
668 deallocate (this%TsManager)
669 nullify (this%TsManager)
690 this%lastonper = this%ionper
691 this%ionper = this%parser%GetInteger()
694 if (this%ionper <= this%lastonper)
then
695 write (
errmsg,
'(a, i0, a, i0, a, i0, a)') &
696 'Error in stress period ',
kper, &
697 '. Period numbers not increasing. Found ', this%ionper, &
698 ' but last period block was assigned ', this%lastonper,
'.'
700 call this%parser%StoreErrorUnit()
718 integer(I4B),
intent(in) :: ival
720 character(len=LINELENGTH) :: keyword
722 real(DP),
pointer :: bndElem => null()
725 call this%parser%GetStringCaps(keyword)
726 select case (keyword)
727 case (
'CONCENTRATION')
728 call this%parser%GetString(
text)
730 bndelem => this%dblvec(ival)
732 'BND', this%tsManager, this%iprpak, &
749 integer(I4B),
intent(in) :: nbound_flowpack
750 character(len=*),
intent(in) :: budtxt
754 if (this%maxbound < nbound_flowpack)
then
755 write (
errmsg,
'(a, a, a, i0, a, i0, a)') &
756 'The SPC Package corresponding to flow package ', &
757 trim(this%packNameFlow), &
758 ' has MAXBOUND set less than the number of boundaries &
759 &active in this package. Found MAXBOUND equal ', &
761 ' and number of flow boundaries (NBOUND) equal ', &
763 '. Increase MAXBOUND in the SPC input file for this package.'
765 call this%parser%StoreErrorUnit()
770 select case (trim(adjustl(budtxt)))
772 if (.not. this%readasarrays)
then
773 write (
errmsg,
'(a, a, a)') &
774 'Array-based recharge must be used with array-based stress package &
775 &concentrations. GWF Package ', trim(this%packNameFlow),
' is being &
776 &used with list-based SPC6 input. Use array-based SPC6 input instead.'
778 call this%parser%StoreErrorUnit()
781 if (.not. this%readasarrays)
then
782 write (
errmsg,
'(a, a, a)') &
783 'Array-based evapotranspiration must be used with array-based stress &
784 &package concentrations. GWF Package ', trim(this%packNameFlow), &
785 &
' is being used with list-based SPC6 input. Use array-based SPC6 &
788 call this%parser%StoreErrorUnit()
791 if (this%readasarrays)
then
792 write (
errmsg,
'(a, a, a)') &
793 'List-based packages must be used with list-based stress &
794 &package concentrations. GWF Package ', trim(this%packNameFlow), &
795 &
' is being used with array-based SPC6 input. Use list-based SPC6 &
798 call this%parser%StoreErrorUnit()
This module contains block parser methods.
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
@ tabcenter
centered table column
@ tableft
left justified table column
integer(i4b), parameter lenmodelname
maximum length of the model name
integer(i4b), parameter lenpackagename
maximum length of the package name
integer(i4b), parameter lentimeseriesname
maximum length of a time series name
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
real(dp), parameter dzero
real constant zero
integer(i4b), parameter lenmempath
maximum length of the memory path
This module contains the GwtSpc Module.
subroutine spc_rp_list(this)
@ brief spc_rp_list
real(dp) function get_value(this, ientry, nbound_flow)
@ brief Get the data value from this package
subroutine set_value(this, ival)
@ brief Set the data value from the input file
subroutine allocate_arrays(this)
@ brief Allocate package arrays
character(len=lenftype) ftype
subroutine spc_ad(this, nbound_flowpack, budtxt)
@ brief Advance
subroutine read_dimensions(this)
@ brief Read dimensions for package
subroutine allocate_scalars(this)
@ brief Allocate package scalars
subroutine spc_rp_array(this, line)
@ brief spc_rp_array
subroutine initialize(this, dis, id, inunit, iout, name_model, packNameFlow)
@ brief Initialize the SPC type
character(len=lenpackagename) text
subroutine read_options(this)
@ brief Read options for package
subroutine check_flow_package(this, nbound_flowpack, budtxt)
@ brief check_flow_package
subroutine spc_rp(this)
@ brief Read and prepare
subroutine spc_da(this)
@ brief Deallocate variables
subroutine read_check_ionper(this)
@ brief Check ionper
This module defines variable data types.
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
This module contains simulation methods.
subroutine, public store_error(msg, terminate)
Store an error message.
integer(i4b) function, public count_errors()
Return number of errors.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
subroutine, public table_cr(this, name, title)
integer(i4b), pointer, public kper
current stress period number
integer(i4b), pointer, public nper
number of stress period
subroutine, public tasmanager_cr(this, dis, modelname, iout)
Create the time-array series manager.
subroutine, public read_value_or_time_series_adv(textInput, ii, jj, bndElem, pkgName, auxOrBnd, tsManager, iprpak, varName)
Call this subroutine from advanced packages to define timeseries link for a variable (varName).
subroutine, public tsmanager_cr(this, iout, removeTsLinksOnCompletion, extendTsToEndOfSimulation)
Create the tsmanager.
Derived type for managing SPC input.