MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
prt-oc.f90
Go to the documentation of this file.
1 module prtocmodule
2 
3  use basedismodule, only: disbasetype
4  use kindmodule, only: dp, i4b, lgp
15 
16  implicit none
17  private
18  public prtoctype, oc_cr
19 
20  !> @ brief Output control for particle tracking models
21  type, extends(outputcontroltype) :: prtoctype
22  integer(I4B), pointer :: itrkout => null() !< binary output file
23  integer(I4B), pointer :: itrkhdr => null() !< output header file
24  integer(I4B), pointer :: itrkcsv => null() !< CSV output file
25  integer(I4B), pointer :: itrktls => null() !< track time list input file
26  logical(LGP), pointer :: trackrelease => null() !< whether to track release events
27  logical(LGP), pointer :: trackfeatexit => null() !< whether to track grid-scale feature exit events
28  logical(LGP), pointer :: tracktimestep => null() !< whether to track timestep events
29  logical(LGP), pointer :: trackterminate => null() !< whether to track termination events
30  logical(LGP), pointer :: trackweaksink => null() !< whether to track weak sink exit events
31  logical(LGP), pointer :: trackusertime => null() !< whether to track user-specified times
32  logical(LGP), pointer :: tracksubfexit => null() !< whether to track sub-grid-scale feature exit events
33  logical(LGP), pointer :: trackdropped => null() !< whether to track drops to water table
34  integer(I4B), pointer :: ntracktimes => null() !< number of user-specified tracking times
35  logical(LGP), pointer :: dump_event_trace => null() !< whether to dump event trace for debugging
36  logical(LGP), pointer :: scratch_buffer => null() !< whether to use scratch file instead of memory for event buffering
37  type(timeselecttype), pointer :: tracktimes !< user-specified tracking times
38 
39  contains
40  procedure :: oc_ar
41  procedure :: oc_da => prt_oc_da
42  procedure :: allocate_scalars => prt_oc_allocate_scalars
43  procedure :: source_options => prt_oc_source_options
44  procedure, private :: prt_oc_source_dimensions
45  procedure, private :: prt_oc_source_tracktimes
46 
47  end type prtoctype
48 
49 contains
50 
51  !> @ brief Create an output control object
52  subroutine oc_cr(ocobj, name_model, input_mempath, inunit, iout)
53  type(prtoctype), pointer :: ocobj !< PrtOcType object
54  character(len=*), intent(in) :: name_model !< name of the model
55  character(len=*), intent(in) :: input_mempath !< input mempath of the package
56  integer(I4B), intent(in) :: inunit !< unit number for input
57  integer(I4B), intent(in) :: iout !< unit number for output
58 
59  ! Create the object
60  allocate (ocobj)
61 
62  ! Allocate scalars
63  call ocobj%allocate_scalars(name_model, input_mempath)
64 
65  ! Save unit numbers
66  ocobj%inunit = inunit
67  ocobj%iout = iout
68  end subroutine oc_cr
69 
70  subroutine prt_oc_allocate_scalars(this, name_model, input_mempath)
72  class(prtoctype) :: this
73  character(len=*), intent(in) :: name_model !< name of model
74  character(len=*), intent(in) :: input_mempath !< input mempath of the package
75  logical(LGP) :: found
76 
77  this%memoryPath = create_mem_path(name_model, 'OC')
78 
79  allocate (this%name_model)
80  allocate (this%input_fname)
81  call mem_allocate(this%dump_event_trace, 'DUMP_EVENT_TRACE', this%memoryPath)
82  call mem_allocate(this%scratch_buffer, 'SCRATCH_BUFFER', this%memoryPath)
83  call mem_allocate(this%inunit, 'INUNIT', this%memoryPath)
84  call mem_allocate(this%iout, 'IOUT', this%memoryPath)
85  call mem_allocate(this%ibudcsv, 'IBUDCSV', this%memoryPath)
86  call mem_allocate(this%iperoc, 'IPEROC', this%memoryPath)
87  call mem_allocate(this%iocrep, 'IOCREP', this%memoryPath)
88  call mem_allocate(this%itrkout, 'ITRKOUT', this%memoryPath)
89  call mem_allocate(this%itrkhdr, 'ITRKHDR', this%memoryPath)
90  call mem_allocate(this%itrkcsv, 'ITRKCSV', this%memoryPath)
91  call mem_allocate(this%itrktls, 'ITRKTLS', this%memoryPath)
92  call mem_allocate(this%trackrelease, 'ITRACKRELEASE', this%memoryPath)
93  call mem_allocate(this%trackfeatexit, 'ITRACKFEATEXIT', this%memoryPath)
94  call mem_allocate(this%tracktimestep, 'ITRACKTIMESTEP', this%memoryPath)
95  call mem_allocate(this%trackterminate, 'ITRACKTERMINATE', this%memoryPath)
96  call mem_allocate(this%trackweaksink, 'ITRACKWEAKSINK', this%memoryPath)
97  call mem_allocate(this%trackusertime, 'ITRACKUSERTIME', this%memoryPath)
98  call mem_allocate(this%tracksubfexit, 'ITRACKSUBFEXIT', this%memoryPath)
99  call mem_allocate(this%trackdropped, 'ITRACKDROPPED', this%memoryPath)
100  call mem_allocate(this%ntracktimes, 'NTRACKTIMES', this%memoryPath)
101 
102  this%name_model = name_model
103  this%input_mempath = input_mempath
104  this%input_fname = ''
105  this%dump_event_trace = .false.
106  this%scratch_buffer = .false.
107  this%inunit = 0
108  this%iout = 0
109  this%ibudcsv = 0
110  this%iperoc = 0
111  this%iocrep = 0
112  this%itrkout = 0
113  this%itrkhdr = 0
114  this%itrkcsv = 0
115  this%itrktls = 0
116  this%trackrelease = .false.
117  this%trackfeatexit = .false.
118  this%tracktimestep = .false.
119  this%trackterminate = .false.
120  this%trackweaksink = .false.
121  this%trackusertime = .false.
122  this%tracksubfexit = .false.
123  this%trackdropped = .false.
124  this%ntracktimes = 0
125 
126  if (this%input_mempath /= '') then
127  call mem_set_value(this%input_fname, 'INPUT_FNAME', &
128  this%input_mempath, found)
129  end if
130  end subroutine prt_oc_allocate_scalars
131 
132  !> @ brief Setup output control variables.
133  subroutine oc_ar(this, dis, dnodata)
134  ! dummy
135  class(prtoctype) :: this !< PrtOcType object
136  class(disbasetype), pointer, intent(in) :: dis !< model discretization package
137  real(DP), intent(in) :: dnodata !< no data value
138  ! local
139  integer(I4B) :: i, nocdobj, inodata
140  type(outputcontroldatatype), pointer :: ocdobjptr
141  real(DP), dimension(:), pointer, contiguous :: nullvec => null()
142 
143  ! Allocate and initialize variables
144  allocate (this%tracktimes)
145  call this%tracktimes%init()
146  inodata = 0
147  nocdobj = 1
148  allocate (this%ocds(nocdobj))
149  do i = 1, nocdobj
150  call ocd_cr(ocdobjptr)
151  select case (i)
152  case (1)
153  call ocdobjptr%init_dbl('BUDGET', nullvec, dis, 'PRINT LAST ', &
154  'COLUMNS 10 WIDTH 11 DIGITS 4 GENERAL ', &
155  this%iout, dnodata)
156  end select
157  this%ocds(i) = ocdobjptr
158  deallocate (ocdobjptr)
159  end do
160 
161  ! Read options, dimensions, and tracktimes
162  ! blocks if this package is enabled
163  if (this%input_mempath == '') return
164  call this%source_options()
165  call this%prt_oc_source_dimensions()
166  call this%prt_oc_source_tracktimes()
167  end subroutine oc_ar
168 
169  subroutine prt_oc_da(this)
170  ! dummy
171  class(prtoctype) :: this
172  ! local
173  integer(I4B) :: i
174 
175  call this%tracktimes%deallocate()
176 
177  do i = 1, size(this%ocds)
178  call this%ocds(i)%ocd_da()
179  end do
180  deallocate (this%ocds)
181 
182  deallocate (this%name_model)
183  call mem_deallocate(this%dump_event_trace)
184  call mem_deallocate(this%scratch_buffer)
185  call mem_deallocate(this%inunit)
186  call mem_deallocate(this%iout)
187  call mem_deallocate(this%ibudcsv)
188  call mem_deallocate(this%iperoc)
189  call mem_deallocate(this%iocrep)
190  call mem_deallocate(this%itrkout)
191  call mem_deallocate(this%itrkhdr)
192  call mem_deallocate(this%itrkcsv)
193  call mem_deallocate(this%itrktls)
194  call mem_deallocate(this%trackrelease)
195  call mem_deallocate(this%trackfeatexit)
196  call mem_deallocate(this%tracktimestep)
197  call mem_deallocate(this%trackterminate)
198  call mem_deallocate(this%trackweaksink)
199  call mem_deallocate(this%trackusertime)
200  call mem_deallocate(this%tracksubfexit)
201  call mem_deallocate(this%trackdropped)
202  call mem_deallocate(this%ntracktimes)
203 
204  end subroutine prt_oc_da
205 
206  subroutine prt_oc_source_options(this)
207  ! -- modules
208  use openspecmodule, only: access, form
210  use constantsmodule, only: linelength
214  ! -- dummy
215  class(prtoctype) :: this
216  ! -- local
217  character(len=LINELENGTH) :: trackfile, trackcsv
218  type(prtocparamfoundtype) :: found
219  integer(I4B), pointer :: evinput
220  ! formats
221  character(len=*), parameter :: fmttrkbin = &
222  "(4x, 'PARTICLE TRACKS WILL BE SAVED TO BINARY FILE: ', a, /4x, &
223  &'OPENED ON UNIT: ', I0)"
224  character(len=*), parameter :: fmttrkcsv = &
225  "(4x, 'PARTICLE TRACKS WILL BE SAVED TO CSV FILE: ', a, /4x, &
226  &'OPENED ON UNIT: ', I0)"
227 
228  allocate (evinput)
229 
230  write (this%iout, '(/,1x,a,/)') 'PROCESSING OC OPTIONS'
231  !
232  ! -- source base class options
233  call this%OutPutControlType%source_options()
234  !
235  ! -- source options
236  call mem_set_value(trackfile, 'TRACKFILE', this%input_mempath, &
237  found%trackfile)
238  call mem_set_value(trackcsv, 'TRACKCSVFILE', this%input_mempath, &
239  found%trackcsvfile)
240  call mem_set_value(evinput, 'TRACK_RELEASE', this%input_mempath, &
241  found%track_release)
242  call mem_set_value(evinput, 'TRACK_EXIT', this%input_mempath, &
243  found%track_exit)
244  call mem_set_value(evinput, 'TRACK_SUBF_EXIT', this%input_mempath, &
245  found%track_subf_exit)
246  call mem_set_value(evinput, 'TRACK_DROPPED', this%input_mempath, &
247  found%track_dropped)
248  call mem_set_value(evinput, 'TRACK_TIMESTEP', this%input_mempath, &
249  found%track_timestep)
250  call mem_set_value(evinput, 'TRACK_TERMINATE', this%input_mempath, &
251  found%track_terminate)
252  call mem_set_value(evinput, 'TRACK_WEAKSINK', this%input_mempath, &
253  found%track_weaksink)
254  call mem_set_value(evinput, 'TRACK_USERTIME', this%input_mempath, &
255  found%track_usertime)
256  call mem_set_value(evinput, 'DEV_DUMP_EVTRACE', this%input_mempath, &
257  found%dev_dump_evtrace)
258  call mem_set_value(evinput, 'SCRATCH_BUFFER', this%input_mempath, &
259  found%scratch_buffer)
260 
261  if (found%track_release) this%trackrelease = .true.
262  if (found%track_exit) this%trackfeatexit = .true.
263  if (found%track_subf_exit) this%tracksubfexit = .true.
264  if (found%track_dropped) this%trackdropped = .true.
265  if (found%track_timestep) this%tracktimestep = .true.
266  if (found%track_terminate) this%trackterminate = .true.
267  if (found%track_weaksink) this%trackweaksink = .true.
268  if (found%track_usertime) this%trackusertime = .true.
269  if (found%dev_dump_evtrace) this%dump_event_trace = .true.
270  if (found%scratch_buffer) this%scratch_buffer = .true.
271 
272  if (this%scratch_buffer) then
273  write (this%iout, '(4x,a)') 'TRACK EVENT BUFFER: SCRATCH FILE'
274  else
275  write (this%iout, '(4x,a)') 'TRACK EVENT BUFFER: MEMORY'
276  end if
277 
278  ! default to all events
279  if (.not. (found%track_release .or. &
280  found%track_exit .or. &
281  found%track_timestep .or. &
282  found%track_terminate .or. &
283  found%track_weaksink .or. &
284  found%track_usertime .or. &
285  found%track_dropped)) then
286  this%trackrelease = .true.
287  this%trackfeatexit = .true.
288  this%tracktimestep = .true.
289  this%trackterminate = .true.
290  this%trackweaksink = .true.
291  this%trackusertime = .true.
292  this%trackdropped = .true.
293  end if
294 
295  if (found%trackfile) then
296  ! open binary track output file
297  this%itrkout = getunit()
298  call openfile(this%itrkout, this%iout, trackfile, 'DATA(BINARY)', &
299  form, access, filstat_opt='REPLACE', &
300  mode_opt=mnormal)
301  write (this%iout, fmttrkbin) trim(adjustl(trackfile)), this%itrkout
302  ! open and write ascii track header file
303  this%itrkhdr = getunit()
304  trackfile = trim(trackfile)//'.hdr'
305  call openfile(this%itrkhdr, this%iout, trackfile, 'CSV', &
306  filstat_opt='REPLACE', mode_opt=mnormal)
307  write (this%itrkhdr, '(a,/,a)') trackheader, trackdtypes
308  end if
309 
310  if (found%trackcsvfile) then
311  this%itrkcsv = getunit()
312  call openfile(this%itrkcsv, this%iout, trackcsv, 'CSV', &
313  filstat_opt='REPLACE')
314  write (this%iout, fmttrkcsv) trim(adjustl(trackcsv)), this%itrkcsv
315  write (this%itrkcsv, '(a)') trackheader
316  end if
317 
318  write (this%iout, '(1x,a)') 'END OF OC OPTIONS'
319  deallocate (evinput)
320  end subroutine prt_oc_source_options
321 
322  !> @brief source the dimensions block.
323  subroutine prt_oc_source_dimensions(this)
324  use constantsmodule, only: linelength
328  ! dummy
329  class(prtoctype), intent(inout) :: this
330  ! local
331  type(prtocparamfoundtype) :: found
332  write (this%iout, '(/1x,a)') &
333  'PROCESSING OUTPUT CONTROL DIMENSIONS'
334  call mem_set_value(this%ntracktimes, 'NTRACKTIMES', this%input_mempath, &
335  found%ntracktimes)
336  if (found%ntracktimes) then
337  write (this%iout, '(4x,a,i7)') 'NTRACKTIMES = ', this%ntracktimes
338  end if
339  write (this%iout, '(1x,a)') &
340  'END OF OUTPUT CONTROL DIMENSIONS'
341 
342  if (this%ntracktimes < 0) then
343  write (errmsg, '(a)') &
344  'NTRACKTIMES WAS NOT SPECIFIED OR WAS SPECIFIED INCORRECTLY.'
345  call store_error(errmsg)
346  end if
347  end subroutine prt_oc_source_dimensions
348 
349  !> @brief source the tracking times block.
350  subroutine prt_oc_source_tracktimes(this)
354  ! dummy
355  class(prtoctype), intent(inout) :: this
356  ! local
357  real(DP), dimension(:), pointer, contiguous :: tracktimes
358  integer(I4B) :: n, asize
359 
360  if (this%ntracktimes <= 0) return
361 
362  call get_isize('TIME', this%input_mempath, asize)
363 
364  if (asize /= this%ntracktimes) then
365  write (errmsg, '(a, i0)') &
366  "Expected TRACKTIMES with length ", this%ntracktimes
367  call store_error(errmsg)
368  call store_error_filename(this%input_fname)
369  else
370  call mem_setptr(tracktimes, 'TIME', this%input_mempath)
371 
372  ! allocate time selection
373  call this%tracktimes%expand(this%ntracktimes)
374 
375  do n = 1, this%ntracktimes
376  this%tracktimes%times(n) = tracktimes(n)
377  end do
378  end if
379 
380  ! make sure times strictly increase
381  if (.not. this%tracktimes%increasing()) then
382  errmsg = "TRACKTIMES must strictly increase"
383  call store_error(errmsg)
384  call store_error_filename(this%input_fname)
385  end if
386 
387  call memorystore_release('TIME', this%input_mempath)
388  end subroutine prt_oc_source_tracktimes
389 
390 end module prtocmodule
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
@ mnormal
normal output mode
Definition: Constants.f90:206
integer(i4b), parameter lenmodelname
maximum length of the model name
Definition: Constants.f90:22
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
subroutine, public urword(line, icol, istart, istop, ncode, n, r, iout, in)
Extract a word from a string.
This module defines variable data types.
Definition: kind.f90:8
This module contains the LongLineReaderType.
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
subroutine, public memorystore_release(varname, memory_path)
Release a single variable from the memory store.
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
character(len=20) access
Definition: OpenSpec.f90:7
character(len=20) form
Definition: OpenSpec.f90:7
Output control data module.
subroutine, public ocd_cr(ocdobj)
@ brief Create a new output control data type.
Model output control.
Particle track output module.
character(len= *), parameter, public trackheader
character(len= *), parameter, public trackdtypes
subroutine oc_ar(this, dis, dnodata)
@ brief Setup output control variables.
Definition: prt-oc.f90:134
subroutine prt_oc_source_dimensions(this)
source the dimensions block.
Definition: prt-oc.f90:324
subroutine prt_oc_da(this)
Definition: prt-oc.f90:170
subroutine prt_oc_source_tracktimes(this)
source the tracking times block.
Definition: prt-oc.f90:351
subroutine prt_oc_source_options(this)
Definition: prt-oc.f90:207
subroutine, public oc_cr(ocobj, name_model, input_mempath, inunit, iout)
@ brief Create an output control object
Definition: prt-oc.f90:53
subroutine prt_oc_allocate_scalars(this, name_model, input_mempath)
Definition: prt-oc.f90:71
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_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
character(len=maxcharlen) warnmsg
warning message string
Specify times for some event to occur.
Definition: TimeSelect.f90:2
@ brief Controls model output. Overridden for each model type.
@ brief Output control for particle tracking models
Definition: prt-oc.f90:21
Represents a series of instants at which some event should occur.
Definition: TimeSelect.f90:34