MODFLOW 6  version 6.7.0.dev2
USGS Modular Hydrologic Model
DefinitionSelect.f90
Go to the documentation of this file.
1 !> @brief This module contains the DefinitionSelectModule
2 !!
3 !! This module contains the routines for getting parameter
4 !! definitions, aggregate definitions, and block definitions
5 !! for the different package types.
6 !!
7 !<
9 
10  use kindmodule, only: i4b
11  use simvariablesmodule, only: errmsg
15 
16  implicit none
17  private
21  public :: idt_parse_rectype
22  public :: idt_datatype
23  public :: idt_default
24 
25 contains
26 
27  !> @brief allocate and set RECARRAY, KEYSTRING or RECORD param list
28  !<
29  subroutine idt_parse_rectype(idt, cols, ncol)
30  use constantsmodule, only: linelength
31  use inputoutputmodule, only: parseline
32  type(inputparamdefinitiontype), pointer, intent(in) :: idt
33  character(len=LINELENGTH), dimension(:), allocatable, &
34  intent(inout) :: cols
35  integer(I4B), intent(inout) :: ncol
36  character(len=:), allocatable :: parse_str
37  character(len=LINELENGTH), dimension(:), allocatable :: param_cols
38  integer(I4B) :: param_ncol, n
39 
40  ! initialize
41  if (allocated(cols)) deallocate (cols)
42  ncol = 0
43 
44  ! split definition
45  parse_str = trim(idt%datatype)//' '
46  call parseline(parse_str, param_ncol, param_cols)
47 
48  if (param_ncol > 1) then
49  if (param_cols(1) == 'RECARRAY' .or. &
50  param_cols(1) == 'KEYSTRING' .or. &
51  param_cols(1) == 'RECORD') then
52  ! exclude 1st column
53  allocate (cols(param_ncol - 1))
54  do n = 2, param_ncol
55  cols(n - 1) = param_cols(n)
56  end do
57  ! set ncol
58  ncol = param_ncol - 1
59  end if
60  end if
61 
62  ! cleanup
63  if (allocated(param_cols)) deallocate (param_cols)
64  if (allocated(parse_str)) deallocate (parse_str)
65  end subroutine idt_parse_rectype
66 
67  !> @brief return input definition type datatype
68  !<
69  function idt_datatype(idt) result(datatype)
70  use constantsmodule, only: linelength
71  type(inputparamdefinitiontype), pointer, intent(in) :: idt
72  character(len=LINELENGTH) :: datatype
73  if (idt%datatype(1:9) == 'KEYSTRING') then
74  datatype = 'KEYSTRING'
75  else if (idt%datatype(1:8) == 'RECARRAY') then
76  datatype = 'RECARRAY'
77  else if (idt%datatype(1:6) == 'RECORD') then
78  datatype = 'RECORD'
79  else
80  datatype = idt%datatype
81  end if
82  end function idt_datatype
83 
84  !> @brief Return parameter definition
85  !<
86  function get_param_definition_type(input_definition_types, &
87  component_type, subcomponent_type, &
88  blockname, tagname, filename) &
89  result(idt)
90  type(inputparamdefinitiontype), dimension(:), intent(in), target :: &
91  input_definition_types
92  character(len=*), intent(in) :: component_type !< component type, such as GWF or GWT
93  character(len=*), intent(in) :: subcomponent_type !< subcomponent type, such as DIS or NPF
94  character(len=*), intent(in) :: blockname !< name of the block
95  character(len=*), intent(in) :: tagname !< name of the input tag
96  character(len=*), intent(in) :: filename !< input filename
97  type(inputparamdefinitiontype), pointer :: idt !< corresponding InputParameterDefinitionType for this tag
98  type(inputparamdefinitiontype), pointer :: tmp_ptr
99  integer(I4B) :: i
100 
101  nullify (idt)
102  do i = 1, size(input_definition_types)
103  tmp_ptr => input_definition_types(i)
104  if (tmp_ptr%component_type == component_type .and. &
105  tmp_ptr%subcomponent_type == subcomponent_type .and. &
106  tmp_ptr%blockname == blockname .and. &
107  tmp_ptr%tagname == tagname) then
108  idt => input_definition_types(i)
109  exit
110  end if
111  end do
112 
113  if (.not. associated(idt)) then
114  write (errmsg, '(a,a,a,a,a)') &
115  'Input file tag not found: "', trim(tagname), &
116  '" in block "', trim(blockname), &
117  '".'
118  call store_error(errmsg)
119  call store_error_filename(filename)
120  end if
121  end function get_param_definition_type
122 
123  !> @brief Return aggregate definition
124  !<
125  function get_aggregate_definition_type(input_definition_types, component_type, &
126  subcomponent_type, blockname) result(idt)
127  type(inputparamdefinitiontype), dimension(:), intent(in), target :: &
128  input_definition_types
129  character(len=*), intent(in) :: component_type !< component type, such as GWF or GWT
130  character(len=*), intent(in) :: subcomponent_type !< subcomponent type, such as DIS or NPF
131  character(len=*), intent(in) :: blockname !< name of the block
132  type(inputparamdefinitiontype), pointer :: idt !< corresponding InputParameterDefinitionType for this block
133  type(inputparamdefinitiontype), pointer :: tmp_ptr
134  integer(I4B) :: i
135 
136  nullify (idt)
137  do i = 1, size(input_definition_types)
138  tmp_ptr => input_definition_types(i)
139  if (tmp_ptr%component_type == component_type .and. &
140  tmp_ptr%subcomponent_type == subcomponent_type .and. &
141  tmp_ptr%blockname == blockname) then
142  idt => input_definition_types(i)
143  exit
144  end if
145  end do
146 
147  if (.not. associated(idt)) then
148  write (errmsg, '(a,a,a,a,a,a,a)') &
149  'Idm aggregate definition not found: ', trim(blockname), &
150  '. Component="', trim(component_type), &
151  '", subcomponent="', trim(subcomponent_type), '".'
152  call store_error(errmsg, .true.)
153  end if
154  end function get_aggregate_definition_type
155 
156  !> @brief Return aggregate definition
157  !!
158  !! Split a component RECORD datatype definition whose second element matches
159  !! tagname into an array of character tokens
160  !<
161  subroutine split_record_dfn_tag1(input_definition_types, component_type, &
162  subcomponent_type, tagname, nwords, words)
163  use inputoutputmodule, only: parseline
164  type(inputparamdefinitiontype), dimension(:), intent(in), target :: &
165  input_definition_types
166  character(len=*), intent(in) :: component_type !< component type, such as GWF or GWT
167  character(len=*), intent(in) :: subcomponent_type !< subcomponent type, such as DIS or NPF
168  character(len=*), intent(in) :: tagname !< name of the input tag
169  integer(I4B), intent(inout) :: nwords
170  character(len=40), dimension(:), allocatable, intent(inout) :: words
171  type(inputparamdefinitiontype), pointer :: tmp_ptr
172  integer(I4B) :: i
173  character(len=:), allocatable :: parse_str
174 
175  ! initialize to deallocated
176  if (allocated(words)) deallocate (words)
177 
178  ! return all tokens of multi-record type that matches the first
179  ! tag following the expected first token "RECORD"
180  do i = 1, size(input_definition_types)
181 
182  ! initialize
183  nwords = 0
184 
185  ! set ptr to current definition
186  tmp_ptr => input_definition_types(i)
187 
188  ! match for definition to split
189  if (tmp_ptr%component_type == component_type .and. &
190  tmp_ptr%subcomponent_type == subcomponent_type .and. &
191  idt_datatype(tmp_ptr) == 'RECORD') then
192 
193  ! set split string
194  parse_str = trim(input_definition_types(i)%datatype)//' '
195 
196  ! split
197  call parseline(parse_str, nwords, words)
198 
199  ! check for match and manage memory
200  if (nwords >= 2) then
201  if (words(1) == 'RECORD' .and. words(2) == tagname) then
202  exit
203  end if
204  end if
205 
206  ! deallocate
207  if (allocated(parse_str)) deallocate (parse_str)
208  if (allocated(words)) deallocate (words)
209  end if
210  end do
211  end subroutine split_record_dfn_tag1
212 
213  !> @brief Return aggregate definition
214  !!
215  !! Split a component RECORD datatype definition whose second and third
216  !! elements match tagnames into an array of character tokens
217  !<
218  subroutine split_record_dfn_tag2(input_definition_types, component_type, &
219  subcomponent_type, tagname, tag2, nwords, &
220  words)
221  use inputoutputmodule, only: parseline
222  type(inputparamdefinitiontype), dimension(:), intent(in), target :: &
223  input_definition_types
224  character(len=*), intent(in) :: component_type !< component type, such as GWF or GWT
225  character(len=*), intent(in) :: subcomponent_type !< subcomponent type, such as DIS or NPF
226  character(len=*), intent(in) :: tagname !< name of the input tag
227  character(len=*), intent(in) :: tag2
228  integer(I4B), intent(inout) :: nwords
229  character(len=40), dimension(:), allocatable, intent(inout) :: words
230  type(inputparamdefinitiontype), pointer :: tmp_ptr
231  integer(I4B) :: i
232  character(len=:), allocatable :: parse_str
233 
234  ! initialize to deallocated
235  if (allocated(words)) deallocate (words)
236 
237  ! return all tokens of multi-record type that matches the first
238  ! tag following the expected first token "RECORD"
239  do i = 1, size(input_definition_types)
240 
241  ! initialize
242  nwords = 0
243 
244  ! set ptr to current definition
245  tmp_ptr => input_definition_types(i)
246 
247  ! match for definition to split
248  if (tmp_ptr%component_type == component_type .and. &
249  tmp_ptr%subcomponent_type == subcomponent_type .and. &
250  idt_datatype(tmp_ptr) == 'RECORD') then
251 
252  ! set split string
253  parse_str = trim(input_definition_types(i)%datatype)//' '
254 
255  ! split
256  call parseline(parse_str, nwords, words)
257 
258  ! check for match and manage memory
259  if (nwords >= 2) then
260  if (words(1) == 'RECORD' .and. &
261  words(2) == tagname .and. &
262  words(3) == tag2) then
263  exit
264  end if
265  end if
266 
267  ! deallocate
268  if (allocated(parse_str)) deallocate (parse_str)
269  if (allocated(words)) deallocate (words)
270  end if
271  end do
272  end subroutine split_record_dfn_tag2
273 
274  !> @brief return allocated input definition type
275  !<
276  function idt_default(component_type, subcomponent_type, blockname, tagname, &
277  mf6varname, datatype) result(idt)
278  ! -- modules
279  ! -- dummy
280  character(len=*), intent(in) :: component_type
281  character(len=*), intent(in) :: subcomponent_type
282  character(len=*), intent(in) :: blockname
283  character(len=*), intent(in) :: tagname
284  character(len=*), intent(in) :: mf6varname
285  character(len=*), intent(in) :: datatype
286  ! -- result
287  type(inputparamdefinitiontype), pointer :: idt
288 
289  allocate (idt)
290 
291  idt%component_type = trim(component_type)
292  idt%subcomponent_type = trim(subcomponent_type)
293  idt%blockname = trim(blockname)
294  idt%tagname = trim(tagname)
295  idt%mf6varname = trim(mf6varname)
296  idt%datatype = trim(datatype)
297  idt%shape = ''
298  idt%required = .true.
299  idt%in_record = .false.
300  idt%preserve_case = .false.
301  idt%layered = .false.
302  idt%timeseries = .false.
303  end function idt_default
304 
305 end module definitionselectmodule
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
This module contains the DefinitionSelectModule.
type(inputparamdefinitiontype) function, pointer, public get_param_definition_type(input_definition_types, component_type, subcomponent_type, blockname, tagname, filename)
Return parameter definition.
type(inputparamdefinitiontype) function, pointer, public idt_default(component_type, subcomponent_type, blockname, tagname, mf6varname, datatype)
return allocated input definition type
subroutine, public split_record_dfn_tag1(input_definition_types, component_type, subcomponent_type, tagname, nwords, words)
Return aggregate definition.
type(inputparamdefinitiontype) function, pointer, public get_aggregate_definition_type(input_definition_types, component_type, subcomponent_type, blockname)
Return aggregate definition.
subroutine, public split_record_dfn_tag2(input_definition_types, component_type, subcomponent_type, tagname, tag2, nwords, words)
Return aggregate definition.
subroutine, public idt_parse_rectype(idt, cols, ncol)
allocate and set RECARRAY, KEYSTRING or RECORD param list
character(len=linelength) function, public idt_datatype(idt)
return input definition type datatype
This module contains the InputDefinitionModule.
subroutine, public parseline(line, nwords, words, inunit, filename)
Parse a line into words.
This module defines variable data types.
Definition: kind.f90:8
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
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