MODFLOW 6  version 6.6.0.dev0
USGS Modular Hydrologic Model
Observe.f90
Go to the documentation of this file.
1 !> @brief This module contains the derived types ObserveType and ObsDataType
2 !!
3 !! This module contains the derived types ObserveType and ObsDataType.
4 !!
5 !! - ObserveType -- is designed to contain all information and
6 !! functionality needed for one observation. ObserveType contains a
7 !! pointer to an ObsDataType object.
8 !!
9 !! - ObsDataType -- is for storing package ID, observation type, and a
10 !! pointer to a subroutine that will be called to process the IDstring
11 !! provided in Obs input. The ProcessIdPtr member of ObsDataType
12 !! requires a pointer to an ObserveType object.
13 !!
14 !<
16 
17  use kindmodule, only: dp, i4b
18  use basedismodule, only: disbasetype
21  use tablemodule, only: tabletype
22  use inputoutputmodule, only: urword
23  use listmodule, only: listtype
24  use simmodule, only: store_warning, store_error, &
26  use tdismodule, only: totim, totalsimtime
28 
29  implicit none
30 
31  private
34 
35  type :: observetype
36  ! -- Public members
37  !
38  ! -- For all observations
39  integer(I4B), public :: nodenumber = 0 !< observation node number
40  integer(I4B), public :: unitnumber = 0 !< observation output unit number
41  character(len=LENOBSNAME), public :: name = '' !< observation name
42  character(len=LENOBSTYPE), public :: obstypeid = '' !< observation type id
43  character(len=200), public :: idstring = '' !< observation id string
44  character(len=LENBOUNDNAME), public :: featurename = '' !< observation feature name
45  character(len=LENBOUNDNAME), public :: featurename2 = '' !< observation feature name 2
46  !
47  ! -- members specific to NPF intercell-flow observations
48  integer(I4B), public :: nodenumber2 = 0 !< observation second nod number
49  integer(I4B), public :: jaindex = -2 !< observation JA index
50  !
51  ! -- members that can be used as needed by packages or models
52  integer(I4B), public :: intpak1 = 0 !<
53  real(dp), public :: obsdepth = dzero !<
54  real(dp), public :: dblpak1 = dzero !<
55  !
56  ! -- indxbnds is intended to hold indices of position(s) in bound
57  ! array of boundaries included in the observation.
58  integer(I4B), public :: indxbnds_count = 0 !< number of observations indexes when using boundname
59  integer(I4B), allocatable, dimension(:), public :: indxbnds !< node numbers for observations when using boundname
60  !
61  ! -- Set FormattedOutput false if output unit is opened for unformatted i/o
62  logical, public :: formattedoutput = .true. !< logical indicating if observation output is formatted
63  logical, public :: bndfound = .false. !< logical indicating if a boundname was found
64  real(dp), public :: currenttimestependvalue = dzero !< observation value
65  real(dp), public :: currenttimestependtime = dzero !< observation time
66  !
67  ! -- Members specific to continuous observations
68  integer(I4B), public :: indxobsoutput = -1 !< index for observation output
69  !
70  ! -- Private members
71  type(obsdatatype), pointer, private :: obsdatum => null() !< observation Datum
72  contains
73  ! -- Public procedures
74  procedure, public :: resetcurrentvalue
75  procedure, public :: writeto
76  procedure, public :: addobsindex
77  procedure, public :: resetobsindex
78  procedure, public :: da
79  end type observetype
80 
81  type :: obsdatatype
82  ! -- Public members
83  character(len=LENOBSTYPE), public :: obstypeid = '' !< observation type id
84  logical, public :: cumulative = .false. !< logical indicating if observations should be summed
85  procedure(processidsub), nopass, pointer, public :: processidptr => null() !< process id pointer
86  end type obsdatatype
87 
88  abstract interface
89 
90  !> @ brief Process user-provided IDstring
91  !!
92  !! Subroutine that processes the user-provided IDstring, which identifies
93  !! the grid location or model feature to be observed.
94  !!
95  !<
96  subroutine processidsub(obsrv, dis, inunitobs, iout)
97  use kindmodule, only: dp, i4b
98  import :: observetype
99  import :: disbasetype
100  ! -- dummy
101  type(observetype), intent(inout) :: obsrv !< observation type
102  class(disbasetype), intent(in) :: dis !< discretization object
103  integer(I4B), intent(in) :: inunitobs !< observation input file unit
104  integer(I4B), intent(in) :: iout !< model list file unit
105  end subroutine processidsub
106  end interface
107 
108 contains
109 
110  ! Procedures bound to ObserveType
111 
112  !> @ brief Reset current observation value
113  !!
114  !! Subroutine to reset the current observation value.
115  !!
116  !<
117  subroutine resetcurrentvalue(this)
118  ! -- dummy
119  class(observetype), intent(inout) :: this
120  !
121  ! -- Reset current value to zero.
122  this%CurrentTimeStepEndValue = dzero
123  end subroutine resetcurrentvalue
124 
125  !> @ brief Write observation input data
126  !!
127  !! Subroutine to write observation input data to a table in the model
128  !! list file.
129  !!
130  !<
131  subroutine writeto(this, obstab, btagfound, fnamein)
132  ! -- dummy
133  class(observetype), intent(inout) :: this
134  type(tabletype), intent(inout) :: obstab !< observation table
135  character(len=*), intent(in) :: btagfound !< logical indicating if boundname was found
136  character(len=*), intent(in) :: fnamein !< observation input file name
137  ! -- local
138  character(len=12) :: tag
139  character(len=80) :: fnameout
140  !
141  ! -- write btagfound to tag
142  if (len_trim(btagfound) > 12) then
143  tag = btagfound(1:12)
144  else
145  write (tag, '(a12)') btagfound
146  end if
147  !
148  ! -- write fnamein to fnameout
149  if (len_trim(fnamein) > 80) then
150  fnameout = fnamein(1:80)
151  else
152  write (fnameout, '(a80)') fnamein
153  end if
154  !
155  ! -- write data to observation table
156  call obstab%add_term(this%Name)
157  call obstab%add_term(tag//trim(this%ObsTypeId))
158  call obstab%add_term('ALL TIMES')
159  call obstab%add_term('"'//trim(this%IDstring)//'"')
160  call obstab%add_term(fnameout)
161  end subroutine writeto
162 
163  !> @ brief Reset a observation index
164  !!
165  !! Subroutine to reset the observation index count and array.
166  !!
167  !<
168  subroutine resetobsindex(this)
169  ! -- dummy
170  class(observetype), intent(inout) :: this
171  !
172  ! -- Reset the index count
173  this%indxbnds_count = 0
174  !
175  ! -- Deallocate observation index array, if necessary
176  if (allocated(this%indxbnds)) then
177  deallocate (this%indxbnds)
178  end if
179  !
180  ! -- Allocate observation index array to size 0
181  allocate (this%indxbnds(0))
182  end subroutine resetobsindex
183 
184  !> @ brief Add a observation index
185  !!
186  !! Subroutine to add the observation index to the observation index
187  !! array (indxbnds). The observation index count (indxbnds_count) is
188  !! also incremented by one and the observation index array is
189  !! expanded, if necessary.
190  !!
191  !<
192  subroutine addobsindex(this, indx)
193  ! -- dummy
194  class(observetype), intent(inout) :: this
195  integer(I4B), intent(in) :: indx !< observation index
196  !
197  ! -- Increment the index count
198  this%indxbnds_count = this%indxbnds_count + 1
199  !
200  ! -- Expand the observation index array, if necessary
201  call expandarraywrapper(this%indxbnds_count, this%indxbnds, loginc=.true.)
202  !
203  ! -- add index to observation index
204  this%indxbnds(this%indxbnds_count) = indx
205  end subroutine addobsindex
206 
207  !> @ brief Deallocate a observation
208  !!
209  !! Subroutine to deallocated a observation (ObserveType).
210  !!
211  !<
212  subroutine da(this)
213  ! -- dummy
214  class(observetype), intent(inout) :: this
215  if (allocated(this%indxbnds)) then
216  deallocate (this%indxbnds)
217  end if
218  end subroutine da
219 
220  ! Non-type-bound procedures
221 
222  !> @ brief Construct a new ObserveType
223  !!
224  !! Subroutine to construct and return an ObserveType object based
225  !! on the contents of defLine.
226  !!
227  !<
228  subroutine constructobservation(newObservation, defLine, numunit, &
229  formatted, indx, obsData, inunit)
230  ! -- dummy variables
231  type(observetype), pointer :: newobservation !< new ObserveType
232  character(len=*), intent(in) :: defline !< string with observation data
233  integer(I4B), intent(in) :: numunit !< Output unit number
234  logical, intent(in) :: formatted !< logical indicating if formatted output will be written
235  integer(I4B), intent(in) :: indx !< Index in ObsOutput array
236  type(obsdatatype), dimension(:), pointer, intent(in) :: obsdata !< obsData type
237  integer(I4B), intent(in) :: inunit !< observation input file unit
238  ! -- local
239  real(dp) :: r
240  integer(I4B) :: i
241  integer(I4B) :: icol
242  integer(I4B) :: iout
243  integer(I4B) :: istart
244  integer(I4B) :: istop
245  integer(I4B) :: n
246  !
247  ! -- initialize
248  iout = 0
249  icol = 1
250  !
251  ! -- Allocate an ObserveType object.
252  allocate (newobservation)
253  allocate (newobservation%indxbnds(0))
254  !
255  ! -- Set indxbnds_count to 0
256  newobservation%indxbnds_count = 0
257  !
258  ! -- Define the contents of the ObservationSingleType object based on the
259  ! contents of defLine.
260  !
261  ! -- Get observation name and store it
262  call urword(defline, icol, istart, istop, 1, n, r, iout, inunit)
263  newobservation%Name = defline(istart:istop)
264  !
265  ! -- Get observation type, convert it to uppercase, and store it.
266  call urword(defline, icol, istart, istop, 1, n, r, iout, inunit)
267  newobservation%ObsTypeId = defline(istart:istop)
268  !
269  ! -- Look up package ID for this observation type and store it
270  do i = 1, maxobstypes
271  if (obsdata(i)%ObsTypeID == newobservation%ObsTypeId) then
272  newobservation%obsDatum => obsdata(i)
273  exit
274  elseif (obsdata(i)%ObsTypeID == '') then
275  exit
276  end if
277  end do
278  !
279  ! -- Remaining text is ID [and ID2]; store the remainder of the string
280  istart = istop + 1
281  istop = len_trim(defline)
282  if (istart > istop) then
283  istart = istop
284  end if
285  newobservation%IDstring = defline(istart:istop)
286  !
287  ! Store UnitNumber, FormattedOutput, and IndxObsOutput
288  newobservation%UnitNumber = numunit
289  newobservation%FormattedOutput = formatted
290  newobservation%IndxObsOutput = indx
291  end subroutine constructobservation
292 
293  !> @ brief Cast a object as a ObserveType
294  !!
295  !! Function to cast an object as a ObserveType object.
296  !!
297  !<
298  function castasobservetype(obj) result(res)
299  ! -- dummy
300  class(*), pointer, intent(inout) :: obj !< object
301  ! -- return
302  type(observetype), pointer :: res !< returned ObserveType object
303  !
304  res => null()
305  if (.not. associated(obj)) return
306  !
307  select type (obj)
308  type is (observetype)
309  res => obj
310  end select
311  end function castasobservetype
312 
313  !> @ brief Add a ObserveType to a list
314  !!
315  !! Subroutine to add a ObserveType to a list.
316  !!
317  !<
318  subroutine addobstolist(list, obs)
319  ! -- dummy
320  type(listtype), intent(inout) :: list !< ObserveType list
321  type(observetype), pointer, intent(inout) :: obs !< ObserveType
322  ! -- local
323  class(*), pointer :: obj
324  !
325  obj => obs
326  call list%Add(obj)
327  end subroutine addobstolist
328 
329  !> @ brief Get an ObserveType from a list
330  !!
331  !! Function to get an ObserveType from a list.
332  !!
333  !<
334  function getobsfromlist(list, idx) result(res)
335  ! -- dummy
336  type(listtype), intent(inout) :: list !< ObserveType list
337  integer(I4B), intent(in) :: idx !< ObserveType list index
338  ! -- return
339  type(observetype), pointer :: res !< returned ObserveType
340  ! -- local
341  class(*), pointer :: obj
342  !
343  obj => list%GetItem(idx)
344  res => castasobservetype(obj)
345  end function getobsfromlist
346 
347 end module observemodule
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:95
integer(i4b), parameter maxobstypes
maximum number of observation types
Definition: Constants.f90:48
integer(i4b), parameter lenboundname
maximum length of a bound name
Definition: Constants.f90:36
integer(i4b), parameter lenobsname
maximum length of a observation name
Definition: Constants.f90:40
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
integer(i4b), parameter lenobstype
maximum length of a observation type (CONTINUOUS)
Definition: Constants.f90:41
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 derived types ObserveType and ObsDataType.
Definition: Observe.f90:15
subroutine resetcurrentvalue(this)
@ brief Reset current observation value
Definition: Observe.f90:118
subroutine da(this)
@ brief Deallocate a observation
Definition: Observe.f90:213
subroutine addobsindex(this, indx)
@ brief Add a observation index
Definition: Observe.f90:193
subroutine writeto(this, obstab, btagfound, fnamein)
@ brief Write observation input data
Definition: Observe.f90:132
subroutine, public constructobservation(newObservation, defLine, numunit, formatted, indx, obsData, inunit)
@ brief Construct a new ObserveType
Definition: Observe.f90:230
subroutine resetobsindex(this)
@ brief Reset a observation index
Definition: Observe.f90:169
type(observetype) function, pointer, public getobsfromlist(list, idx)
@ brief Get an ObserveType from a list
Definition: Observe.f90:335
subroutine, public addobstolist(list, obs)
@ brief Add a ObserveType to a list
Definition: Observe.f90:319
type(observetype) function, pointer castasobservetype(obj)
@ brief Cast a object as a ObserveType
Definition: Observe.f90:299
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_warning(msg, substring)
Store warning message.
Definition: Sim.f90:236
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168
real(dp), pointer, public totim
time relative to start of simulation
Definition: tdis.f90:32
real(dp), pointer, public totalsimtime
time at end of simulation
Definition: tdis.f90:37
A generic heterogeneous doubly-linked list.
Definition: List.f90:14