MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
NumericalPackage.f90
Go to the documentation of this file.
1 !> @brief This module contains the base numerical package type
2 !!
3 !! This module contains the base model package class that is extended
4 !! by all model packages.
5 !!
6 !<
8  ! -- modules
9  use kindmodule, only: dp, i4b, lgp
13  use simvariablesmodule, only: errmsg
14  use simmodule, only: store_error
16  use basedismodule, only: disbasetype
18 
19  implicit none
20  private
22 
24 
25  ! -- strings
26  character(len=LENMODELNAME) :: name_model = '' !< the name of the model that contains this package
27  character(len=LENPACKAGENAME) :: packname = '' !< name of the package
28  character(len=LENMEMPATH) :: memorypath = '' !< the location in the memory manager where the variables are stored
29  character(len=LENMEMPATH) :: memorypathmodel = '' !< the location in the memory manager where the variables
30  !! of the parent model are stored
31  character(len=LENMEMPATH) :: input_mempath = '' !< input context mempath
32  character(len=LINELENGTH), pointer :: input_fname => null() !< input file name
33  character(len=LENFTYPE) :: filtyp = '' !< file type (CHD, DRN, RIV, etc.)
34  character(len=LENFTYPE), pointer :: package_type => null() !< package type (same as filtyp) stored in memory manager
35 
36  ! -- integers
37  integer(I4B), pointer :: id => null() !< consecutive package number in model
38  integer(I4B), pointer :: inunit => null() !< unit number for input file
39  integer(I4B), pointer :: iout => null() !< unit number for writing package output
40  integer(I4B), pointer :: inewton => null() !< newton flag
41  integer(I4B), pointer :: iasym => null() !< package causes matrix asymmetry
42  integer(I4B), pointer :: iprpak => null() !< integer flag to echo input
43  integer(I4B), pointer :: iprflow => null() !< flag to print simulated flows
44  integer(I4B), pointer :: ipakcb => null() !< output flows (-1, 0, 1) - save_flows
45  integer(I4B), pointer :: ionper => null() !< stress period for next data
46  integer(I4B), pointer :: lastonper => null() !< last value of ionper (for checking)
47  !
48  ! -- derived types
49  type(blockparsertype) :: parser !< parser object for reading blocks of information
50  class(disbasetype), pointer :: dis => null() !< model discretization object
51 
52  contains
53  procedure :: set_names
54  procedure :: allocate_scalars
55  procedure :: da
56  procedure :: read_check_ionper
57  procedure :: get_block_data
58  end type numericalpackagetype
59  !
60 contains
61  !
62  !> @ brief Set package names
63  !!
64  !! Method to assign the filtyp (ftype), the model name, and package name for
65  !! a package. This method also creates the memoryPath and memoryPathModel that
66  !! is used by the memory manager when variables are allocated.
67  !!
68  !<
69  subroutine set_names(this, ibcnum, name_model, pakname, ftype, input_mempath)
70  ! -- dummy variables
71  class(numericalpackagetype), intent(inout) :: this !< NumericalPackageType object
72  integer(I4B), intent(in) :: ibcnum !< unique package number
73  character(len=*), intent(in) :: name_model !< name of the model
74  character(len=*), intent(in) :: pakname !< name of the package
75  character(len=*), intent(in) :: ftype !< package type
76  character(len=*), optional, intent(in) :: input_mempath !< input_mempath
77  !
78  ! -- set names
79  this%filtyp = ftype
80  this%name_model = name_model
81  if (present(input_mempath)) this%input_mempath = input_mempath
82  if (pakname == '') then
83  write (this%packName, '(a, i0)') trim(ftype)//'-', ibcnum
84  else
85  !
86  ! -- Ensure pakname has no spaces
87  if (index(trim(pakname), ' ') > 0) then
88  errmsg = 'Package name contains spaces: '//trim(pakname)
89  call store_error(errmsg)
90  errmsg = 'Remove spaces from name.'
91  call store_error(errmsg, terminate=.true.)
92  end if
93  !
94  this%packName = pakname
95  end if
96  this%memoryPath = create_mem_path(name_model, this%packName)
97  this%memoryPathModel = create_mem_path(name_model)
98  end subroutine set_names
99 
100  !> @ brief Allocate package scalars
101  !!
102  !! Allocate and initialize base numerical package scalars.
103  !!
104  !<
105  subroutine allocate_scalars(this)
106  ! -- modules
109  ! -- dummy variables
110  class(numericalpackagetype) :: this !< NumericalPackageType object
111  ! -- local variables
112  integer(I4B), pointer :: imodelnewton => null()
113  integer(I4B), pointer :: imodelprpak => null()
114  integer(I4B), pointer :: imodelprflow => null()
115  integer(I4B), pointer :: imodelpakcb => null()
116  logical(LGP) :: found
117  !
118  ! -- allocate scalars
119  call mem_allocate(this%input_fname, linelength, 'INPUT_FNAME', &
120  this%memoryPath)
121  call mem_allocate(this%package_type, lenftype, 'PACKAGE_TYPE', &
122  this%memoryPath)
123  call mem_allocate(this%id, 'ID', this%memoryPath)
124  call mem_allocate(this%inunit, 'INUNIT', this%memoryPath)
125  call mem_allocate(this%iout, 'IOUT', this%memoryPath)
126  call mem_allocate(this%inewton, 'INEWTON', this%memoryPath)
127  call mem_allocate(this%iasym, 'IASYM', this%memoryPath)
128  call mem_allocate(this%iprpak, 'IPRPAK', this%memoryPath)
129  call mem_allocate(this%iprflow, 'IPRFLOW', this%memoryPath)
130  call mem_allocate(this%ipakcb, 'IPAKCB', this%memoryPath)
131  !
132  call mem_allocate(this%ionper, 'IONPER', this%memoryPath)
133  call mem_allocate(this%lastonper, 'LASTONPER', this%memoryPath)
134  !
135  ! -- set pointer to model variables
136  call mem_setptr(imodelnewton, 'INEWTON', this%memoryPathModel)
137  call mem_setptr(imodelprpak, 'IPRPAK', this%memoryPathModel)
138  call mem_setptr(imodelprflow, 'IPRFLOW', this%memoryPathModel)
139  call mem_setptr(imodelpakcb, 'IPAKCB', this%memoryPathModel)
140  !
141  ! -- initialize
142  this%input_fname = ''
143  this%package_type = this%filtyp
144  this%id = 0
145  this%inunit = 0
146  this%iout = 0
147  this%inewton = imodelnewton
148  this%iasym = 0
149  this%iprpak = imodelprpak
150  this%iprflow = imodelprflow
151  this%ipakcb = imodelpakcb
152  this%ionper = 0
153  this%lastonper = 0
154  !
155  ! -- nullify unneeded pointers
156  imodelnewton => null()
157  imodelprpak => null()
158  imodelprflow => null()
159  imodelpakcb => null()
160  !
161  ! -- update input filename
162  if (this%input_mempath /= '') then
163  call mem_set_value(this%input_fname, 'INPUT_FNAME', &
164  this%input_mempath, found)
165  end if
166  end subroutine allocate_scalars
167 
168  !> @ brief Deallocate package scalars
169  !!
170  !! Deallocate and initialize base numerical package scalars.
171  !!
172  !<
173  subroutine da(this)
174  ! -- modules
176  ! -- dummy variables
177  class(numericalpackagetype) :: this !< NumericalPackageType object
178  !
179  ! -- deallocate
180  call mem_deallocate(this%input_fname, 'INPUT_FNAME', this%memoryPath)
181  call mem_deallocate(this%package_type, 'PACKAGE_TYPE', this%memoryPath)
182  call mem_deallocate(this%id)
183  call mem_deallocate(this%inunit)
184  call mem_deallocate(this%iout)
185  call mem_deallocate(this%inewton)
186  call mem_deallocate(this%iasym)
187  call mem_deallocate(this%iprpak)
188  call mem_deallocate(this%iprflow)
189  call mem_deallocate(this%ipakcb)
190  call mem_deallocate(this%ionper)
191  call mem_deallocate(this%lastonper)
192  end subroutine da
193 
194  !> @ brief Check ionper
195  !!
196  !! Generic method to read and check ionperiod, which is used to determine
197  !! if new period data should be read from the input file. The check of
198  !! ionperiod also makes sure periods are increasing in subsequent period
199  !! data blocks.
200  !!
201  !<
202  subroutine read_check_ionper(this)
203  ! -- modules
204  use tdismodule, only: kper
205  ! -- dummy variables
206  class(numericalpackagetype), intent(inout) :: this !< NumericalPackageType object
207  !
208  ! -- save last value and read period number
209  this%lastonper = this%ionper
210  this%ionper = this%parser%GetInteger()
211  !
212  ! -- make check
213  if (this%ionper <= this%lastonper) then
214  write (errmsg, '(a, i0, a, i0, a, i0, a)') &
215  'Error in stress period ', kper, &
216  '. Period numbers not increasing. Found ', this%ionper, &
217  ' but last period block was assigned ', this%lastonper, '.'
218  call store_error(errmsg)
219  call this%parser%StoreErrorUnit()
220  end if
221  end subroutine read_check_ionper
222 
223  !> @ brief Read griddata block for a package
224  !!
225  !! Generic method to read data in the GRIDDATA block for a package.
226  !!
227  !<
228  subroutine get_block_data(this, tags, lfound, varinames)
229  ! -- modules
231  ! -- dummy variables
232  class(numericalpackagetype) :: this !< NumericalPackageType object
233  character(len=24), dimension(:), intent(in) :: tags !< vector with variable tags
234  logical, dimension(:), intent(inout) :: lfound !< boolean vector indicating of a variable tag was found
235  character(len=24), dimension(:), intent(in), optional :: varinames !< optional vector of variable names
236  ! -- local variables
237  logical :: lkeyword
238  logical :: endOfBlock
239  integer(I4B) :: nsize
240  integer(I4B) :: j
241  character(len=24) :: tmpvar
242  character(len=LENVARNAME) :: varname
243  character(len=LINELENGTH) :: keyword
244  character(len=:), allocatable :: line
245  integer(I4B) :: istart, istop, lloc
246  integer(I4B), dimension(:), pointer, contiguous :: aint
247  real(DP), dimension(:), pointer, contiguous :: adbl
248  !
249  ! -- initialize nsize
250  nsize = size(tags)
251  do
252  call this%parser%GetNextLine(endofblock)
253  if (endofblock) exit
254  call this%parser%GetStringCaps(keyword)
255  call this%parser%GetRemainingLine(line)
256  lkeyword = .false.
257  lloc = 1
258  tag_iter: do j = 1, nsize
259  if (trim(adjustl(keyword)) == trim(adjustl(tags(j)))) then
260  lkeyword = .true.
261  lfound(j) = .true.
262  if (present(varinames)) then
263  tmpvar = adjustl(varinames(j))
264  else
265  tmpvar = adjustl(tags(j))
266  end if
267  varname = tmpvar(1:lenvarname)
268  if (keyword(1:1) == 'I') then
269  call mem_setptr(aint, trim(varname), trim(this%memoryPath))
270  call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
271  this%parser%iuactive, aint, tags(j))
272  else
273  call mem_setptr(adbl, trim(varname), trim(this%memoryPath))
274  call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
275  this%parser%iuactive, adbl, tags(j))
276  end if
277  exit tag_iter
278  end if
279  end do tag_iter
280  if (.not. lkeyword) then
281  write (errmsg, '(a,a)') 'Unknown GRIDDATA tag: ', &
282  trim(keyword)
283  call store_error(errmsg)
284  call this%parser%StoreErrorUnit()
285  end if
286  end do
287  end subroutine get_block_data
288 
289 end module numericalpackagemodule
290 
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
integer(i4b), parameter lenmodelname
maximum length of the model name
Definition: Constants.f90:22
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:23
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
Definition: Constants.f90:39
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
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.
subroutine get_block_data(this, tags, lfound, varinames)
@ brief Read griddata block for a package
subroutine read_check_ionper(this)
@ brief Check ionper
subroutine set_names(this, ibcnum, name_model, pakname, ftype, input_mempath)
@ brief Set package names
subroutine allocate_scalars(this)
@ brief Allocate package scalars
subroutine da(this)
@ brief Deallocate package scalars
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23