MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
OutputControlData.f90
Go to the documentation of this file.
1 !> @brief Output control data module.
3 
4  use basedismodule, only: disbasetype
6  use kindmodule, only: dp, i4b, lgp
8 
9  implicit none
10  private
12 
13  !> @brief Output control data type.
14  !!
15  !! Determines whether output data should be printed to a list file or saved to disk.
16  !! This type can be assigned to different variables, such as head or concentration.
17  !! This type controls the logging and saving of output data in a consistent manner.
18  !<
20  class(disbasetype), pointer :: dis => null() !< discretization package
21  type(printsavemanagertype), pointer :: psm => null() !< print/save manager
22  character(len=16), pointer :: cname => null() !< name of variable, such as HEAD
23  character(len=60), pointer :: cdatafmp => null() !< fortran format for printing
24  character(len=1), pointer :: editdesc => null() !< fortran format type (I, G, F, S, E)
25  integer(I4B), pointer :: idataun => null() !< fortran unit number for binary output
26  integer(I4B), pointer :: nvaluesp => null() !< number of values per line for printing
27  integer(I4B), pointer :: nwidthp => null() !< width of the number for printing
28  integer(I4B), pointer :: inodata => null() !< integer no data value
29  real(dp), pointer :: dnodata => null() !< no data value
30  integer(I4B), pointer, contiguous :: intdata(:) => null() !< integer data array
31  real(dp), pointer, contiguous :: dbldata(:) => null() !< double precision data array
32  contains
33  procedure :: allocate_scalars => allocate
34  procedure :: init_int
35  procedure :: init_dbl
36  procedure :: set_option
37  procedure :: ocd_rp_check
38  procedure :: ocd_ot
39  procedure :: ocd_da
40  end type outputcontroldatatype
41 
42 contains
43 
44  !> @ brief Create a new output control data type.
45  subroutine ocd_cr(ocdobj)
46  type(outputcontroldatatype), pointer :: ocdobj !< this instance
47  allocate (ocdobj)
48  call ocdobj%allocate_scalars()
49  end subroutine ocd_cr
50 
51  !> @ brief Check the output control data type for consistency.
52  subroutine ocd_rp_check(this, inunit)
53  ! modules
54  use constantsmodule, only: linelength
56  ! dummy
57  class(outputcontroldatatype) :: this !< this instance
58  integer(I4B), intent(in) :: inunit !< output unit number
59  ! locals
60  character(len=LINELENGTH) :: errmsg
61  ! formats
62  character(len=*), parameter :: fmtocsaveerr = &
63  "(1X,'REQUESTING TO SAVE ',A,' BUT ',A,' SAVE FILE NOT SPECIFIED. ', &
64  &A,' SAVE FILE MUST BE SPECIFIED IN OUTPUT CONTROL OPTIONS.')"
65 
66  ! If saving is enabled, make sure an output file was specified
67  if (this%psm%save_steps%any()) then
68  if (this%idataun == 0) then
69  write (errmsg, fmtocsaveerr) trim(adjustl(this%cname)), &
70  trim(adjustl(this%cname)), &
71  trim(adjustl(this%cname))
72  call store_error(errmsg)
73  end if
74  end if
75 
76  if (count_errors() > 0) then
77  call store_error_unit(inunit)
78  end if
79  end subroutine ocd_rp_check
80 
81  !> @brief Write to list file and/or save to binary file, depending on settings.
82  subroutine ocd_ot(this, ipflg, kstp, endofperiod, iout, iprint_opt, isav_opt)
83  ! dummy
84  class(outputcontroldatatype) :: this !< OutputControlDataType object
85  integer(I4B), intent(inout) :: ipflg !< Flag indicating if something was printed
86  integer(I4B), intent(in) :: kstp !< Current time step
87  logical(LGP), intent(in) :: endofperiod !< End of period logical flag
88  integer(I4B), intent(in) :: iout !< Unit number for output
89  integer(I4B), optional, intent(in) :: iprint_opt !< Optional print flag override
90  integer(I4B), optional, intent(in) :: isav_opt !< Optional save flag override
91  ! local
92  integer(I4B) :: iprint
93  integer(I4B) :: idataun
94 
95  ! Initialize
96  iprint = 0
97  ipflg = 0
98  idataun = 0
99 
100  ! Determine whether or not to print the array. The present
101  ! check allows a caller to override the print/save manager
102  if (present(iprint_opt)) then
103  if (iprint_opt /= 0) then
104  iprint = 1
105  ipflg = 1
106  end if
107  else
108  if (this%psm%should_print(kstp, endofperiod)) then
109  iprint = 1
110  ipflg = 1
111  end if
112  end if
113 
114  ! Determine whether to save the array to a file
115  if (present(isav_opt)) then
116  if (isav_opt /= 0) then
117  idataun = this%idataun
118  end if
119  else
120  if (this%psm%should_save(kstp, endofperiod)) idataun = this%idataun
121  end if
122 
123  ! Record double precision array
124  if (associated(this%dbldata)) &
125  call this%dis%record_array(this%dbldata, iout, iprint, idataun, &
126  this%cname, this%cdatafmp, this%nvaluesp, &
127  this%nwidthp, this%editdesc, this%dnodata)
128 
129  ! Record integer array (not supported yet)
130  !if(associated(this%intvec)) &
131  !call this%dis%record_array(this%intvec, iout, iprint, idataun, &
132  ! this%cname, this%cdatafmp, this%nvaluesp, &
133  ! this%nwidthp, this%editdesc, this%inodata)
134  end subroutine ocd_ot
135 
136  !> @brief Deallocate the output control data type
137  subroutine ocd_da(this)
138  class(outputcontroldatatype) :: this
139 
140  deallocate (this%cname)
141  deallocate (this%cdatafmp)
142  deallocate (this%idataun)
143  deallocate (this%editdesc)
144  deallocate (this%nvaluesp)
145  deallocate (this%nwidthp)
146  deallocate (this%dnodata)
147  deallocate (this%inodata)
148  end subroutine ocd_da
149 
150  !> @brief Initialize the output control data type for double precision data.
151  subroutine init_dbl(this, cname, dblvec, dis, cdefpsm, cdeffmp, iout, &
152  dnodata)
153  class(outputcontroldatatype) :: this !< OutputControlDataType object
154  character(len=*), intent(in) :: cname !< Name of variable
155  real(DP), dimension(:), pointer, contiguous, intent(in) :: dblvec !< Data array that will be managed by this object
156  class(disbasetype), pointer, intent(in) :: dis !< Discretization package
157  character(len=*), intent(in) :: cdefpsm !< String for defining the print/save manager
158  character(len=*), intent(in) :: cdeffmp !< String for print format
159  integer(I4B), intent(in) :: iout !< Unit number for output
160  real(DP), intent(in) :: dnodata !< No data value
161 
162  this%cname = cname
163  this%dbldata => dblvec
164  this%dis => dis
165  this%dnodata = dnodata
166  if (cdefpsm /= '') call this%psm%read(cdefpsm, iout)
167  call print_format(cdeffmp, this%cdatafmp, &
168  this%editdesc, this%nvaluesp, this%nwidthp, 0)
169  end subroutine init_dbl
170 
171  !> @ brief Initialize the output control data type for integer data.
172  subroutine init_int(this, cname, intvec, dis, cdefpsm, cdeffmp, iout, &
173  inodata)
174  class(outputcontroldatatype) :: this !< OutputControlDataType object
175  character(len=*), intent(in) :: cname !< Name of variable
176  integer(I4B), dimension(:), pointer, contiguous, intent(in) :: intvec !< Data array that will be managed by this object
177  class(disbasetype), pointer, intent(in) :: dis !< Discretization package
178  character(len=*), intent(in) :: cdefpsm !< String for defining the print/save manager
179  character(len=*), intent(in) :: cdeffmp !< String for print format
180  integer(I4B), intent(in) :: iout !< Unit number for output
181  integer(I4B), intent(in) :: inodata !< No data value
182 
183  this%cname = cname
184  this%intdata => intvec
185  this%dis => dis
186  this%inodata = inodata
187  this%editdesc = 'I'
188  if (cdefpsm /= '') call this%psm%read(cdefpsm, iout)
189  call print_format(cdeffmp, this%cdatafmp, this%editdesc, this%nvaluesp, &
190  this%nwidthp, 0)
191  end subroutine init_int
192 
193  !> @ brief Allocate scalar variables
194  subroutine allocate (this)
195  ! modules
196  use constantsmodule, only: dzero
197  ! dummy
198  class(outputcontroldatatype) :: this !< OutputControlDataType object
199 
200  allocate (this%cname)
201  allocate (this%cdatafmp)
202  allocate (this%idataun)
203  allocate (this%editdesc)
204  allocate (this%nvaluesp)
205  allocate (this%nwidthp)
206  allocate (this%dnodata)
207  allocate (this%inodata)
208 
209  this%cname = ''
210  this%cdatafmp = ''
211  this%idataun = 0
212  this%editdesc = ''
213  this%nvaluesp = 0
214  this%nwidthp = 0
215  this%dnodata = dzero
216  this%inodata = 0
217  this%psm => create_psm()
218  end subroutine allocate
219 
220  !> @ brief Set FILEOUT and PRINT_FORMAT based on an input string.
221  subroutine set_option(this, linein, inunit, iout)
222  ! modules
223  use constantsmodule, only: mnormal
224  use openspecmodule, only: access, form
227  ! dummy
228  class(outputcontroldatatype) :: this !< OutputControlDataType object
229  character(len=*), intent(in) :: linein !< Character string with options
230  integer(I4B), intent(in) :: inunit !< Unit number for input
231  integer(I4B), intent(in) :: iout !< Unit number for output
232  ! local
233  character(len=len(linein)) :: line
234  integer(I4B) :: lloc, istart, istop, ival
235  real(DP) :: rval
236  ! format
237  character(len=*), parameter :: fmtocsave = &
238  "(4X,A,' INFORMATION WILL BE WRITTEN TO:', &
239  &/,6X,'UNIT NUMBER: ', I0,/,6X, 'FILE NAME: ', A)"
240 
241  line(:) = linein(:)
242  lloc = 1
243  call urword(line, lloc, istart, istop, 1, ival, rval, 0, 0)
244  select case (line(istart:istop))
245  case ('FILEOUT')
246  call urword(line, lloc, istart, istop, 0, ival, rval, 0, 0)
247  this%idataun = getunit()
248  write (iout, fmtocsave) trim(adjustl(this%cname)), this%idataun, &
249  line(istart:istop)
250  call openfile(this%idataun, iout, line(istart:istop), 'DATA(BINARY)', &
251  form, access, 'REPLACE', mnormal)
252  case ('PRINT_FORMAT')
253  call urword(line, lloc, istart, istop, 1, ival, rval, 0, 0)
254  call print_format(line(istart:), this%cdatafmp, this%editdesc, &
255  this%nvaluesp, this%nwidthp, inunit)
256  case default
257  call store_error('Looking for FILEOUT or PRINT_FORMAT. Found:')
258  call store_error(trim(adjustl(line)))
259  call store_error_unit(inunit)
260  end select
261  end subroutine set_option
262 
263 end module outputcontroldatamodule
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
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public print_format(linein, cdatafmp, editdesc, nvaluesp, nwidthp, inunit)
Define the print or save format.
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
character(len=20) access
Definition: OpenSpec.f90:7
character(len=20) form
Definition: OpenSpec.f90:7
Output control data module.
subroutine init_dbl(this, cname, dblvec, dis, cdefpsm, cdeffmp, iout, dnodata)
Initialize the output control data type for double precision data.
subroutine ocd_da(this)
Deallocate the output control data type.
subroutine ocd_rp_check(this, inunit)
@ brief Check the output control data type for consistency.
subroutine ocd_ot(this, ipflg, kstp, endofperiod, iout, iprint_opt, isav_opt)
Write to list file and/or save to binary file, depending on settings.
subroutine allocate(this)
@ brief Allocate scalar variables
subroutine set_option(this, linein, inunit, iout)
@ brief Set FILEOUT and PRINT_FORMAT based on an input string.
subroutine init_int(this, cname, intvec, dis, cdefpsm, cdeffmp, iout, inodata)
@ brief Initialize the output control data type for integer data.
subroutine, public ocd_cr(ocdobj)
@ brief Create a new output control data type.
Print/save manager module.
type(printsavemanagertype) function, pointer, public create_psm()
Initialize or clear the print/save manager.
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_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168