MODFLOW 6  version 6.6.0.dev0
USGS Modular Hydrologic Model
swf-obs.f90
Go to the documentation of this file.
2 
3  use kindmodule, only: dp, i4b
5  use basedismodule, only: disbasetype
6  use swficmodule, only: swfictype
7  use observemodule, only: observetype
8  use obsmodule, only: obstype
9  use simmodule, only: count_errors, store_error, &
11  implicit none
12 
13  private
14  public :: swfobstype, swf_obs_cr
15 
16  type, extends(obstype) :: swfobstype
17  ! -- Private members
18  type(swfictype), pointer, private :: ic => null() ! initial conditions
19  real(dp), dimension(:), pointer, contiguous, private :: x => null() ! stage
20  real(dp), dimension(:), pointer, contiguous, private :: flowja => null() ! intercell flows
21  contains
22  ! -- Public procedures
23  procedure, public :: swf_obs_ar
24  procedure, public :: obs_bd => swf_obs_bd
25  procedure, public :: obs_df => swf_obs_df
26  procedure, public :: obs_rp => swf_obs_rp
27  procedure, public :: obs_da => swf_obs_da
28  ! -- Private procedures
29  procedure, private :: set_pointers
30  end type swfobstype
31 
32 contains
33 
34  !> @brief Create a new obs object
35  !!
36  !! Create observation object, allocate pointers, initialize values
37  !<
38  subroutine swf_obs_cr(obs, inobs)
39  ! -- dummy
40  type(swfobstype), pointer, intent(out) :: obs
41  integer(I4B), pointer, intent(in) :: inobs
42  !
43  allocate (obs)
44  call obs%allocate_scalars()
45  obs%active = .false.
46  obs%inputFilename = ''
47  obs%inUnitObs => inobs
48  end subroutine swf_obs_cr
49 
50  !> @brief Allocate and read
51  !<
52  subroutine swf_obs_ar(this, ic, x, flowja)
53  ! -- dummy
54  class(swfobstype), intent(inout) :: this
55  type(swfictype), pointer, intent(in) :: ic
56  real(DP), dimension(:), pointer, contiguous, intent(in) :: x
57  real(DP), dimension(:), pointer, contiguous, intent(in) :: flowja
58  !
59  ! Call ar method of parent class
60  call this%obs_ar()
61  !
62  ! set pointers
63  call this%set_pointers(ic, x, flowja)
64  end subroutine swf_obs_ar
65 
66  !> @brief Define
67  !<
68  subroutine swf_obs_df(this, iout, pkgname, filtyp, dis)
69  ! -- dummy
70  class(swfobstype), intent(inout) :: this
71  integer(I4B), intent(in) :: iout
72  character(len=*), intent(in) :: pkgname
73  character(len=*), intent(in) :: filtyp
74  class(disbasetype), pointer :: dis
75  ! -- local
76  integer(I4B) :: indx
77  !
78  ! Call overridden method of parent class
79  call this%ObsType%obs_df(iout, pkgname, filtyp, dis)
80  !
81  ! -- StoreObsType arguments are: (ObserveType, cumulative, indx);
82  ! indx is returned.
83  !
84  ! -- Store obs type and assign procedure pointer for head observation type
85  call this%StoreObsType('stage', .false., indx)
86  this%obsData(indx)%ProcessIdPtr => swf_process_stage_obs_id
87  !
88  ! -- Store obs type and assign procedure pointer for flow-ja-face observation type
89  call this%StoreObsType('flow-ja-face', .true., indx)
90  this%obsData(indx)%ProcessIdPtr => swf_process_intercell_obs_id
91  end subroutine swf_obs_df
92 
93  !> @brief Save obs
94  !<
95  subroutine swf_obs_bd(this)
96  ! -- dummy
97  class(swfobstype), intent(inout) :: this
98  ! -- local
99  integer(I4B) :: i, jaindex, nodenumber
100  character(len=100) :: msg
101  class(observetype), pointer :: obsrv => null()
102  !
103  call this%obs_bd_clear()
104  !
105  ! -- iterate through all SWF observations
106  if (this%npakobs > 0) then
107  do i = 1, this%npakobs
108  obsrv => this%pakobs(i)%obsrv
109  nodenumber = obsrv%NodeNumber
110  jaindex = obsrv%JaIndex
111  select case (obsrv%ObsTypeId)
112  case ('STAGE')
113  call this%SaveOneSimval(obsrv, this%x(nodenumber))
114  case ('FLOW-JA-FACE')
115  call this%SaveOneSimval(obsrv, this%flowja(jaindex))
116  case default
117  msg = ' Unrecognized observation type: '//trim(obsrv%ObsTypeId)
118  call store_error(msg)
119  call store_error_unit(this%inUnitObs)
120  end select
121  end do
122  end if
123  end subroutine swf_obs_bd
124 
125  !> @brief Do observations need any checking? If so, add checks here
126  !<
127  subroutine swf_obs_rp(this)
128  class(swfobstype), intent(inout) :: this
129  !
130  ! Do SWF observations need any checking? If so, add checks here
131  return
132  end subroutine swf_obs_rp
133 
134  !> @brief Deallocate memory
135  !<
136  subroutine swf_obs_da(this)
137  class(swfobstype), intent(inout) :: this
138  !
139  nullify (this%ic)
140  nullify (this%x)
141  nullify (this%flowja)
142  call this%ObsType%obs_da()
143  end subroutine swf_obs_da
144 
145  !> @brief Set pointers
146  !<
147  subroutine set_pointers(this, ic, x, flowja)
148  ! -- dummy
149  class(swfobstype), intent(inout) :: this
150  type(swfictype), pointer, intent(in) :: ic
151  real(DP), dimension(:), pointer, contiguous, intent(in) :: x
152  real(DP), dimension(:), pointer, contiguous, intent(in) :: flowja
153  !
154  this%ic => ic
155  this%x => x
156  this%flowja => flowja
157  end subroutine set_pointers
158 
159  ! -- Procedures related to SWF observations (NOT type-bound)
160 
161  !> @brief Calculate stage observation when requested
162  !<
163  subroutine swf_process_stage_obs_id(obsrv, dis, inunitobs, iout)
164  ! -- dummy
165  type(observetype), intent(inout) :: obsrv
166  class(disbasetype), intent(in) :: dis
167  integer(I4B), intent(in) :: inunitobs
168  integer(I4B), intent(in) :: iout
169  ! -- local
170  integer(I4B) :: nn1
171  integer(I4B) :: icol, istart, istop
172  character(len=LINELENGTH) :: ermsg, string
173  !
174  ! -- Initialize variables
175  string = obsrv%IDstring
176  icol = 1
177  !
178  ! Get node number, with option for ID string to be either node
179  ! number or lay, row, column (when dis is structured).
180  nn1 = dis%noder_from_string(icol, istart, istop, inunitobs, &
181  iout, string, .false.)
182  !
183  if (nn1 > 0) then
184  obsrv%NodeNumber = nn1
185  else
186  ermsg = 'Error reading data from ID string'
187  call store_error(ermsg)
188  call store_error_unit(inunitobs)
189  end if
190  end subroutine swf_process_stage_obs_id
191 
192  !> @brief Process flow between two cells when requested
193  !<
194  subroutine swf_process_intercell_obs_id(obsrv, dis, inunitobs, iout)
195  ! -- dummy
196  type(observetype), intent(inout) :: obsrv
197  class(disbasetype), intent(in) :: dis
198  integer(I4B), intent(in) :: inunitobs
199  integer(I4B), intent(in) :: iout
200  ! -- local
201  integer(I4B) :: nn1, nn2
202  integer(I4B) :: icol, istart, istop, jaidx
203  character(len=LINELENGTH) :: ermsg, string
204  ! formats
205 70 format('Error: No connection exists between cells identified in text: ', a)
206  !
207  ! -- Initialize variables
208  string = obsrv%IDstring
209  icol = 1
210  !
211  ! Get node number, with option for ID string to be either node
212  ! number or lay, row, column (when dis is structured).
213  nn1 = dis%noder_from_string(icol, istart, istop, inunitobs, &
214  iout, string, .false.)
215  !
216  if (nn1 > 0) then
217  obsrv%NodeNumber = nn1
218  else
219  ermsg = 'Error reading data from ID string: '//string(istart:istop)
220  call store_error(ermsg)
221  end if
222  !
223  ! Get node number, with option for ID string to be either node
224  ! number or lay, row, column (when dis is structured).
225  nn2 = dis%noder_from_string(icol, istart, istop, inunitobs, &
226  iout, string, .false.)
227  if (nn2 > 0) then
228  obsrv%NodeNumber2 = nn2
229  else
230  ermsg = 'Error reading data from ID string: '//string(istart:istop)
231  call store_error(ermsg)
232  end if
233  !
234  ! -- store JA index
235  jaidx = dis%con%getjaindex(nn1, nn2)
236  if (jaidx == 0) then
237  write (ermsg, 70) trim(string)
238  call store_error(ermsg)
239  end if
240  obsrv%JaIndex = jaidx
241  !
242  if (count_errors() > 0) then
243  call store_error_unit(inunitobs)
244  end if
245  end subroutine swf_process_intercell_obs_id
246 
247 end module swfobsmodule
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
integer(i4b), parameter maxobstypes
maximum number of observation types
Definition: Constants.f90:48
This module defines variable data types.
Definition: kind.f90:8
This module contains the derived types ObserveType and ObsDataType.
Definition: Observe.f90:15
This module contains the derived type ObsType.
Definition: Obs.f90:127
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
subroutine swf_obs_bd(this)
Save obs.
Definition: swf-obs.f90:96
subroutine swf_obs_df(this, iout, pkgname, filtyp, dis)
Define.
Definition: swf-obs.f90:69
subroutine set_pointers(this, ic, x, flowja)
Set pointers.
Definition: swf-obs.f90:148
subroutine swf_obs_da(this)
Deallocate memory.
Definition: swf-obs.f90:137
subroutine swf_process_intercell_obs_id(obsrv, dis, inunitobs, iout)
Process flow between two cells when requested.
Definition: swf-obs.f90:195
subroutine swf_obs_ar(this, ic, x, flowja)
Allocate and read.
Definition: swf-obs.f90:53
subroutine, public swf_obs_cr(obs, inobs)
Create a new obs object.
Definition: swf-obs.f90:39
subroutine swf_process_stage_obs_id(obsrv, dis, inunitobs, iout)
Calculate stage observation when requested.
Definition: swf-obs.f90:164
subroutine swf_obs_rp(this)
Do observations need any checking? If so, add checks here.
Definition: swf-obs.f90:128