MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
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  !
124  ! -- return
125  return
126  end subroutine resetcurrentvalue
127 
128  !> @ brief Write observation input data
129  !!
130  !! Subroutine to write observation input data to a table in the model
131  !! list file.
132  !!
133  !<
134  subroutine writeto(this, obstab, btagfound, fnamein)
135  ! -- dummy
136  class(observetype), intent(inout) :: this
137  type(tabletype), intent(inout) :: obstab !< observation table
138  character(len=*), intent(in) :: btagfound !< logical indicating if boundname was found
139  character(len=*), intent(in) :: fnamein !< observation input file name
140  ! -- local
141  character(len=12) :: tag
142  character(len=80) :: fnameout
143  !
144  ! -- write btagfound to tag
145  if (len_trim(btagfound) > 12) then
146  tag = btagfound(1:12)
147  else
148  write (tag, '(a12)') btagfound
149  end if
150  !
151  ! -- write fnamein to fnameout
152  if (len_trim(fnamein) > 80) then
153  fnameout = fnamein(1:80)
154  else
155  write (fnameout, '(a80)') fnamein
156  end if
157  !
158  ! -- write data to observation table
159  call obstab%add_term(this%Name)
160  call obstab%add_term(tag//trim(this%ObsTypeId))
161  call obstab%add_term('ALL TIMES')
162  call obstab%add_term('"'//trim(this%IDstring)//'"')
163  call obstab%add_term(fnameout)
164  !
165  ! -- return
166  return
167  end subroutine writeto
168 
169  !> @ brief Reset a observation index
170  !!
171  !! Subroutine to reset the observation index count and array.
172  !!
173  !<
174  subroutine resetobsindex(this)
175  ! -- dummy
176  class(observetype), intent(inout) :: this
177  !
178  ! -- Reset the index count
179  this%indxbnds_count = 0
180  !
181  ! -- Deallocate observation index array, if necessary
182  if (allocated(this%indxbnds)) then
183  deallocate (this%indxbnds)
184  end if
185  !
186  ! -- Allocate observation index array to size 0
187  allocate (this%indxbnds(0))
188  !
189  ! -- return
190  return
191  end subroutine resetobsindex
192 
193  !> @ brief Add a observation index
194  !!
195  !! Subroutine to add the observation index to the observation index
196  !! array (indxbnds). The observation index count (indxbnds_count) is
197  !! also incremented by one and the observation index array is
198  !! expanded, if necessary.
199  !!
200  !<
201  subroutine addobsindex(this, indx)
202  ! -- dummy
203  class(observetype), intent(inout) :: this
204  integer(I4B), intent(in) :: indx !< observation index
205  !
206  ! -- Increment the index count
207  this%indxbnds_count = this%indxbnds_count + 1
208  !
209  ! -- Expand the observation index array, if necessary
210  call expandarraywrapper(this%indxbnds_count, this%indxbnds, loginc=.true.)
211  !
212  ! -- add index to observation index
213  this%indxbnds(this%indxbnds_count) = indx
214  !
215  ! -- return
216  return
217  end subroutine addobsindex
218 
219  !> @ brief Deallocate a observation
220  !!
221  !! Subroutine to deallocated a observation (ObserveType).
222  !!
223  !<
224  subroutine da(this)
225  ! -- dummy
226  class(observetype), intent(inout) :: this
227  if (allocated(this%indxbnds)) then
228  deallocate (this%indxbnds)
229  end if
230  !
231  ! -- return
232  return
233  end subroutine da
234 
235  ! Non-type-bound procedures
236 
237  !> @ brief Construct a new ObserveType
238  !!
239  !! Subroutine to construct and return an ObserveType object based
240  !! on the contents of defLine.
241  !!
242  !<
243  subroutine constructobservation(newObservation, defLine, numunit, &
244  formatted, indx, obsData, inunit)
245  ! -- dummy variables
246  type(observetype), pointer :: newobservation !< new ObserveType
247  character(len=*), intent(in) :: defline !< string with observation data
248  integer(I4B), intent(in) :: numunit !< Output unit number
249  logical, intent(in) :: formatted !< logical indicating if formatted output will be written
250  integer(I4B), intent(in) :: indx !< Index in ObsOutput array
251  type(obsdatatype), dimension(:), pointer, intent(in) :: obsdata !< obsData type
252  integer(I4B), intent(in) :: inunit !< observation input file unit
253  ! -- local
254  real(dp) :: r
255  integer(I4B) :: i
256  integer(I4B) :: icol
257  integer(I4B) :: iout
258  integer(I4B) :: istart
259  integer(I4B) :: istop
260  integer(I4B) :: n
261  !
262  ! -- initialize
263  iout = 0
264  icol = 1
265  !
266  ! -- Allocate an ObserveType object.
267  allocate (newobservation)
268  allocate (newobservation%indxbnds(0))
269  !
270  ! -- Set indxbnds_count to 0
271  newobservation%indxbnds_count = 0
272  !
273  ! -- Define the contents of the ObservationSingleType object based on the
274  ! contents of defLine.
275  !
276  ! -- Get observation name and store it
277  call urword(defline, icol, istart, istop, 1, n, r, iout, inunit)
278  newobservation%Name = defline(istart:istop)
279  !
280  ! -- Get observation type, convert it to uppercase, and store it.
281  call urword(defline, icol, istart, istop, 1, n, r, iout, inunit)
282  newobservation%ObsTypeId = defline(istart:istop)
283  !
284  ! -- Look up package ID for this observation type and store it
285  do i = 1, maxobstypes
286  if (obsdata(i)%ObsTypeID == newobservation%ObsTypeId) then
287  newobservation%obsDatum => obsdata(i)
288  exit
289  elseif (obsdata(i)%ObsTypeID == '') then
290  exit
291  end if
292  end do
293  !
294  ! -- Remaining text is ID [and ID2]; store the remainder of the string
295  istart = istop + 1
296  istop = len_trim(defline)
297  if (istart > istop) then
298  istart = istop
299  end if
300  newobservation%IDstring = defline(istart:istop)
301  !
302  ! Store UnitNumber, FormattedOutput, and IndxObsOutput
303  newobservation%UnitNumber = numunit
304  newobservation%FormattedOutput = formatted
305  newobservation%IndxObsOutput = indx
306  !
307  ! -- return
308  return
309  end subroutine constructobservation
310 
311  !> @ brief Cast a object as a ObserveType
312  !!
313  !! Function to cast an object as a ObserveType object.
314  !!
315  !<
316  function castasobservetype(obj) result(res)
317  ! -- dummy
318  class(*), pointer, intent(inout) :: obj !< object
319  ! -- return
320  type(observetype), pointer :: res !< returned ObserveType object
321  !
322  res => null()
323  if (.not. associated(obj)) return
324  !
325  select type (obj)
326  type is (observetype)
327  res => obj
328  end select
329  !
330  ! -- return
331  return
332  end function castasobservetype
333 
334  !> @ brief Add a ObserveType to a list
335  !!
336  !! Subroutine to add a ObserveType to a list.
337  !!
338  !<
339  subroutine addobstolist(list, obs)
340  ! -- dummy
341  type(listtype), intent(inout) :: list !< ObserveType list
342  type(observetype), pointer, intent(inout) :: obs !< ObserveType
343  ! -- local
344  class(*), pointer :: obj
345  !
346  obj => obs
347  call list%Add(obj)
348  !
349  ! -- return
350  return
351  end subroutine addobstolist
352 
353  !> @ brief Get an ObserveType from a list
354  !!
355  !! Function to get an ObserveType from a list.
356  !!
357  !<
358  function getobsfromlist(list, idx) result(res)
359  ! -- dummy
360  type(listtype), intent(inout) :: list !< ObserveType list
361  integer(I4B), intent(in) :: idx !< ObserveType list index
362  ! -- return
363  type(observetype), pointer :: res !< returned ObserveType
364  ! -- local
365  class(*), pointer :: obj
366  !
367  obj => list%GetItem(idx)
368  res => castasobservetype(obj)
369  !
370  ! -- return
371  return
372  end function getobsfromlist
373 
374 end module observemodule
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:94
integer(i4b), parameter maxobstypes
maximum number of observation types
Definition: Constants.f90:47
integer(i4b), parameter lenboundname
maximum length of a bound name
Definition: Constants.f90:35
integer(i4b), parameter lenobsname
maximum length of a observation name
Definition: Constants.f90:39
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:64
integer(i4b), parameter lenobstype
maximum length of a observation type (CONTINUOUS)
Definition: Constants.f90:40
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:225
subroutine addobsindex(this, indx)
@ brief Add a observation index
Definition: Observe.f90:202
subroutine writeto(this, obstab, btagfound, fnamein)
@ brief Write observation input data
Definition: Observe.f90:135
subroutine, public constructobservation(newObservation, defLine, numunit, formatted, indx, obsData, inunit)
@ brief Construct a new ObserveType
Definition: Observe.f90:245
subroutine resetobsindex(this)
@ brief Reset a observation index
Definition: Observe.f90:175
type(observetype) function, pointer, public getobsfromlist(list, idx)
@ brief Get an ObserveType from a list
Definition: Observe.f90:359
subroutine, public addobstolist(list, obs)
@ brief Add a ObserveType to a list
Definition: Observe.f90:340
type(observetype) function, pointer castasobservetype(obj)
@ brief Cast a object as a ObserveType
Definition: Observe.f90:317
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:10