Skip to content

Commit b51d5bd

Browse files
committed
changes now through _rp() routine, _ad() up next
1 parent 6047c4a commit b51d5bd

File tree

4 files changed

+431
-46
lines changed

4 files changed

+431
-46
lines changed

src/Model/GroundWaterEnergy/PbstBase.f90

Lines changed: 269 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,17 @@
77
!! flux.
88
!<
99
module PbstBaseModule
10-
use ConstantsModule, only: LINELENGTH, MAXCHARLEN, DZERO, LGP
10+
use ConstantsModule, only: LINELENGTH, MAXCHARLEN, DZERO, LGP, &
11+
LENPACKAGENAME, TABLEFT, TABCENTER, &
12+
LENVARNAME
1113
use KindModule, only: I4B, DP
1214
use NumericalPackageModule, only: NumericalPackageType
1315
use SimModule, only: count_errors, store_error, ustop
1416
use SimVariablesModule, only: errmsg
1517
use TdisModule, only: kper, nper, kstp
1618
use TimeSeriesLinkModule, only: TimeSeriesLinkType
17-
use TimeSeriesManagerModule, only: TimeSeriesManagerType, tsmanager_cr, &
18-
read_value_or_time_series_adv
19+
use TimeSeriesManagerModule, only: TimeSeriesManagerType, tsmanager_cr
20+
use TableModule, only: TableType, table_cr
1921

2022
implicit none
2123

@@ -24,22 +26,35 @@ module PbstBaseModule
2426
public :: PbstBaseType
2527
public :: pbstbase_da
2628

29+
character(len=LENVARNAME) :: text = ' PBST'
30+
2731
type, abstract, extends(NumericalPackageType) :: PbstBaseType
2832

33+
character(len=8), dimension(:), pointer, contiguous :: status => null() !< active, inactive, constant
34+
character(len=LENPACKAGENAME) :: text = '' !< text string for package transport term
2935
integer(I4B), pointer :: ncv => null() !< number of control volumes
36+
integer(I4B), dimension(:), pointer, contiguous :: iboundpbst => null() !< package ibound
3037
logical, pointer, public :: active => null() !< logical indicating if a sensible heat flux object is active
3138
character(len=LINELENGTH), pointer, public :: inputFilename => null() !< a particular pbst input file name, could be for sensible heat flux or latent heat flux subpackages, for example
32-
type(TimeSeriesManagerType), pointer, private :: tsmanager => null()
33-
39+
type(TimeSeriesManagerType), pointer :: tsmanager => null()
40+
!
41+
! -- table objects
42+
type(TableType), pointer :: inputtab => null() !< input table object
43+
3444
contains
3545

3646
procedure :: init
3747
procedure :: ar
48+
procedure :: rp
3849
procedure, private :: read_options
3950
procedure :: pbst_options
51+
procedure :: pbst_set_stressperiod
52+
procedure :: subpck_set_stressperiod
4053
procedure(read_option), deferred :: read_option
4154
procedure, private :: pbstbase_allocate_scalars
55+
procedure :: pbst_allocate_arrays
4256
procedure :: da => pbstbase_da
57+
procedure :: pbst_check_valid
4358

4459
end type PbstBaseType
4560

@@ -68,19 +83,21 @@ function read_option(this, keyword) result(success)
6883
!!
6984
!! Allocate and initialize data members of the object.
7085
!<
71-
subroutine init(this, name_model, pakname, ftype, inunit, iout)
86+
subroutine init(this, name_model, pakname, ftype, inunit, iout, ncv)
7287
! -- dummy
7388
class(PbstBaseType) :: this
7489
character(len=*), intent(in) :: name_model
7590
character(len=*), intent(in) :: pakname
7691
character(len=*), intent(in) :: ftype
7792
integer(I4B), intent(in) :: inunit
7893
integer(I4B), intent(in) :: iout
94+
integer(I4B), target, intent(in) :: ncv
7995
!
8096
call this%set_names(1, name_model, pakname, ftype)
8197
call this%pbstbase_allocate_scalars()
8298
this%inunit = inunit
8399
this%iout = iout
100+
this%ncv => ncv
84101
call this%parser%Initialize(this%inunit, this%iout)
85102
end subroutine init
86103

@@ -91,6 +108,16 @@ end subroutine init
91108
subroutine ar(this)
92109
! -- dummy
93110
class(PbstBaseType) :: this !< ShfType object
111+
! -- formats
112+
character(len=*), parameter :: fmtapt = &
113+
"(1x,/1x,'SHF -- SENSIBLE HEAT FLUX TRANSPORT PACKAGE, VERSION 1, 3/12/2025', &
114+
&' INPUT READ FROM UNIT ', i0, //)"
115+
!
116+
! -- print a message identifying the apt package.
117+
write (this%iout, fmtapt) this%inunit
118+
!
119+
! -- Allocate arrays
120+
!call this%pbst_allocate_arrays()
94121
!
95122
! -- Create time series manager
96123
call tsmanager_cr(this%tsmanager, this%iout, &
@@ -100,8 +127,183 @@ subroutine ar(this)
100127
! -- Read options
101128
call this%read_options()
102129
end subroutine ar
130+
131+
!> @brief PaBST read and prepare for setting stress period information
132+
!<
133+
subroutine rp(this)
134+
! -- module
135+
use TimeSeriesManagerModule, only: read_value_or_time_series_adv
136+
use TdisModule, only: kper, nper
137+
! -- dummy
138+
class(PbstBaseType) :: this !< ShfType object
139+
! -- local
140+
integer(I4B) :: ierr
141+
integer(I4B) :: n
142+
logical :: isfound, endOfBlock
143+
character(len=LINELENGTH) :: title
144+
character(len=LINELENGTH) :: line
145+
integer(I4B) :: itemno
146+
! -- formats
147+
character(len=*), parameter :: fmtblkerr = &
148+
&"('Error. Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
149+
character(len=*), parameter :: fmtlsp = &
150+
&"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
151+
!
152+
! -- Set ionper to the stress period number for which a new block of data
153+
! will be read.
154+
if (this%inunit == 0) return
155+
!
156+
! -- get stress period data
157+
if (this%ionper < kper) then
158+
!
159+
! -- get period block
160+
call this%parser%GetBlock('PERIOD', isfound, ierr, &
161+
supportOpenClose=.true., &
162+
blockRequired=.false.)
163+
if (isfound) then
164+
!
165+
! -- read ionper and check for increasing period numbers
166+
call this%read_check_ionper()
167+
else
168+
!
169+
! -- PERIOD block not found
170+
if (ierr < 0) then
171+
! -- End of file found; data applies for remainder of simulation.
172+
this%ionper = nper + 1
173+
else
174+
! -- Found invalid block
175+
call this%parser%GetCurrentLine(line)
176+
write (errmsg, fmtblkerr) adjustl(trim(line))
177+
call store_error(errmsg)
178+
call this%parser%StoreErrorUnit()
179+
end if
180+
end if
181+
end if
182+
!
183+
! -- Read data if ionper == kper
184+
if (this%ionper == kper) then
185+
!
186+
! -- setup table for period data
187+
if (this%iprpak /= 0) then
188+
!
189+
! -- reset the input table object
190+
title = trim(adjustl(this%text))//' PACKAGE ('// &
191+
trim(adjustl(this%packName))//') DATA FOR PERIOD'
192+
write (title, '(a,1x,i6)') trim(adjustl(title)), kper
193+
call table_cr(this%inputtab, this%packName, title)
194+
call this%inputtab%table_df(1, 4, this%iout, finalize=.FALSE.)
195+
text = 'NUMBER'
196+
call this%inputtab%initialize_column(text, 10, alignment=TABCENTER)
197+
text = 'KEYWORD'
198+
call this%inputtab%initialize_column(text, 20, alignment=TABLEFT)
199+
do n = 1, 2
200+
write (text, '(a,1x,i6)') 'VALUE', n
201+
call this%inputtab%initialize_column(text, 15, alignment=TABCENTER)
202+
end do
203+
end if
204+
!
205+
! -- read data
206+
stressperiod: do
207+
call this%parser%GetNextLine(endOfBlock)
208+
if (endOfBlock) exit
209+
!
210+
! -- get feature number
211+
itemno = this%parser%GetInteger()
212+
!
213+
! -- read data from the rest of the line
214+
call this%pbst_set_stressperiod(itemno)
215+
!
216+
! -- write line to table
217+
if (this%iprpak /= 0) then
218+
call this%parser%GetCurrentLine(line)
219+
call this%inputtab%line_to_columns(line)
220+
end if
221+
end do stressperiod
222+
!
223+
if (this%iprpak /= 0) then
224+
call this%inputtab%finalize_table()
225+
end if
226+
!
227+
! -- using stress period data from the previous stress period
228+
else
229+
write (this%iout, fmtlsp) trim(this%filtyp)
230+
end if
231+
!
232+
! -- write summary of stress period error messages
233+
ierr = count_errors()
234+
if (ierr > 0) then
235+
call this%parser%StoreErrorUnit()
236+
end if
237+
end subroutine rp
103238

239+
!> @brief pbst_set_stressperiod()
240+
!!
241+
!! To be overridden by Pbst sub-packages
242+
!<
243+
subroutine pbst_set_stressperiod(this, itemno)
244+
! -- dummy
245+
class(PbstBaseType), intent(inout) :: this
246+
integer(I4B), intent(in) :: itemno
247+
! -- local
248+
integer(I4B) :: ierr
249+
character(len=LINELENGTH) :: text
250+
character(len=LINELENGTH) :: keyword
251+
logical(LGP) :: found
252+
!
253+
! -- read line
254+
call this%parser%GetStringCaps(keyword)
255+
select case (keyword)
256+
case ('STATUS')
257+
ierr = this%pbst_check_valid(itemno)
258+
if (ierr /= 0) then
259+
goto 999
260+
end if
261+
call this%parser%GetStringCaps(text)
262+
this%status(itemno) = text(1:8)
263+
if (text == 'CONSTANT') then
264+
this%iboundpbst(itemno) = -1
265+
else if (text == 'INACTIVE') then
266+
this%iboundpbst(itemno) = 0
267+
else if (text == 'ACTIVE') then
268+
this%iboundpbst(itemno) = 1
269+
else
270+
write (errmsg, '(a,a)') &
271+
'Unknown '//trim(this%text)//' status keyword: ', text//'.'
272+
call store_error(errmsg)
273+
end if
274+
case default
275+
!
276+
! -- call the specific package to deal with parameters specific to the
277+
! process
278+
call this%subpck_set_stressperiod(itemno, keyword, found)
279+
! -- terminate with error if data not valid
280+
if (.not. found) then
281+
write (errmsg, '(2a)') &
282+
'Unknown '//trim(adjustl(this%text))//' data keyword: ', &
283+
trim(keyword)//'.'
284+
call store_error(errmsg)
285+
end if
286+
end select
287+
!
288+
! -- terminate if any errors were detected
289+
999 if (count_errors() > 0) then
290+
call this%parser%StoreErrorUnit()
291+
end if
292+
end subroutine pbst_set_stressperiod
104293

294+
!> @brief pbst_set_stressperiod()
295+
!!
296+
!! To be overridden by Pbst sub-packages
297+
!<
298+
subroutine subpck_set_stressperiod(this, itemno, keyword, found)
299+
! -- dummy
300+
class(PbstBaseType), intent(inout) :: this
301+
integer(I4B), intent(in) :: itemno
302+
character(len=*), intent(in) :: keyword
303+
logical, intent(inout) :: found
304+
! -- to be overwritten by pbst subpackages (or "utilities")
305+
end subroutine subpck_set_stressperiod
306+
105307
!> @brief Read the SHF-specific options from the OPTIONS block
106308
!<
107309
subroutine read_options(this)
@@ -110,7 +312,6 @@ subroutine read_options(this)
110312
! -- local
111313
character(len=LINELENGTH) :: keyword
112314
character(len=MAXCHARLEN) :: fname
113-
logical :: isfound
114315
logical :: endOfBlock
115316
logical(LGP) :: found
116317
integer(I4B) :: ierr
@@ -119,11 +320,11 @@ subroutine read_options(this)
119320
&"(4x, 'TIME-SERIES DATA WILL BE READ FROM FILE: ', a)"
120321
!
121322
! -- Get options block
122-
call this%parser%GetBlock('OPTIONS', isfound, ierr, &
323+
call this%parser%GetBlock('OPTIONS', found, ierr, &
123324
blockRequired=.false., supportOpenClose=.true.)
124325
!
125326
! -- Parse options block if detected
126-
if (isfound) then
327+
if (found) then
127328
write (this%iout, '(1x,a)') &
128329
'PROCESSING '//trim(adjustl(this%packName))//' OPTIONS'
129330
do
@@ -215,6 +416,34 @@ subroutine pbstbase_allocate_scalars(this)
215416
! -- allocate time series manager
216417
allocate (this%tsmanager)
217418
end subroutine pbstbase_allocate_scalars
419+
420+
!> @ brief Allocate arrays
421+
!!
422+
!! Allocate base process-based stream temperature package transport arrays
423+
!<
424+
subroutine pbst_allocate_arrays(this)
425+
! -- modules
426+
use MemoryManagerModule, only: mem_allocate
427+
! -- dummy
428+
class(PbstBaseType), intent(inout) :: this
429+
! -- local
430+
integer(I4B) :: n
431+
!
432+
! -- Note: For the time-being, no call to parent class allocation of arrays
433+
! as is done in tsp-apt.f90, for example. Remember that this class
434+
! extends NumericalPackage.f90 which doesn't have a standard set of
435+
! arrays to be allocated, only scalars.
436+
!call this%BndType%allocate_arrays()
437+
!
438+
! -- allocate character array for status
439+
allocate (this%status(this%ncv))
440+
!
441+
! -- initialize arrays
442+
do n = 1, this%ncv
443+
this%status(n) = 'ACTIVE'
444+
end do
445+
end subroutine pbst_allocate_arrays
446+
218447

219448
!> @brief Deallocate package memory
220449
!!
@@ -235,8 +464,39 @@ subroutine pbstbase_da(this)
235464
! -- deallocate scalars
236465
call mem_deallocate(this%ncv)
237466
!
467+
! -- deallocate arrays
468+
call mem_deallocate(this%iboundpbst)
469+
!
238470
! -- Deallocate parent
239471
call this%NumericalPackageType%da()
472+
!
473+
! -- input table object
474+
if (associated(this%inputtab)) then
475+
call this%inputtab%table_da()
476+
deallocate (this%inputtab)
477+
nullify (this%inputtab)
478+
end if
479+
240480
end subroutine pbstbase_da
481+
482+
!> @brief Process-based stream temperature transport (or utility) routine
483+
!!
484+
!! Determine if a valid feature number has been specified.
485+
!<
486+
function pbst_check_valid(this, itemno) result(ierr)
487+
! -- return
488+
integer(I4B) :: ierr
489+
! -- dummy
490+
class(PbstBaseType), intent(inout) :: this
491+
integer(I4B), intent(in) :: itemno
492+
! -- formats
493+
ierr = 0
494+
if (itemno < 1 .or. itemno > this%ncv) then
495+
write (errmsg, '(a,1x,i6,1x,a,1x,i6)') &
496+
'Featureno ', itemno, 'must be > 0 and <= ', this%ncv
497+
call store_error(errmsg)
498+
ierr = 1
499+
end if
500+
end function pbst_check_valid
241501

242502
end module PbstBaseModule

0 commit comments

Comments
 (0)