MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
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  !
49  return
50  end subroutine swf_obs_cr
51 
52  !> @brief Allocate and read
53  !<
54  subroutine swf_obs_ar(this, ic, x, flowja)
55  ! -- dummy
56  class(swfobstype), intent(inout) :: this
57  type(swfictype), pointer, intent(in) :: ic
58  real(DP), dimension(:), pointer, contiguous, intent(in) :: x
59  real(DP), dimension(:), pointer, contiguous, intent(in) :: flowja
60  !
61  ! Call ar method of parent class
62  call this%obs_ar()
63  !
64  ! set pointers
65  call this%set_pointers(ic, x, flowja)
66  !
67  return
68  end subroutine swf_obs_ar
69 
70  !> @brief Define
71  !<
72  subroutine swf_obs_df(this, iout, pkgname, filtyp, dis)
73  ! -- dummy
74  class(swfobstype), intent(inout) :: this
75  integer(I4B), intent(in) :: iout
76  character(len=*), intent(in) :: pkgname
77  character(len=*), intent(in) :: filtyp
78  class(disbasetype), pointer :: dis
79  ! -- local
80  integer(I4B) :: indx
81  !
82  ! Call overridden method of parent class
83  call this%ObsType%obs_df(iout, pkgname, filtyp, dis)
84  !
85  ! -- StoreObsType arguments are: (ObserveType, cumulative, indx);
86  ! indx is returned.
87  !
88  ! -- Store obs type and assign procedure pointer for head observation type
89  call this%StoreObsType('stage', .false., indx)
90  this%obsData(indx)%ProcessIdPtr => swf_process_stage_obs_id
91  !
92  ! -- Store obs type and assign procedure pointer for flow-ja-face observation type
93  call this%StoreObsType('flow-ja-face', .true., indx)
94  this%obsData(indx)%ProcessIdPtr => swf_process_intercell_obs_id
95  !
96  return
97  end subroutine swf_obs_df
98 
99  !> @brief Save obs
100  !<
101  subroutine swf_obs_bd(this)
102  ! -- dummy
103  class(swfobstype), intent(inout) :: this
104  ! -- local
105  integer(I4B) :: i, jaindex, nodenumber
106  character(len=100) :: msg
107  class(observetype), pointer :: obsrv => null()
108  !
109  call this%obs_bd_clear()
110  !
111  ! -- iterate through all SWF observations
112  if (this%npakobs > 0) then
113  do i = 1, this%npakobs
114  obsrv => this%pakobs(i)%obsrv
115  nodenumber = obsrv%NodeNumber
116  jaindex = obsrv%JaIndex
117  select case (obsrv%ObsTypeId)
118  case ('STAGE')
119  call this%SaveOneSimval(obsrv, this%x(nodenumber))
120  case ('FLOW-JA-FACE')
121  call this%SaveOneSimval(obsrv, this%flowja(jaindex))
122  case default
123  msg = ' Unrecognized observation type: '//trim(obsrv%ObsTypeId)
124  call store_error(msg)
125  call store_error_unit(this%inUnitObs)
126  end select
127  end do
128  end if
129  !
130  return
131  end subroutine swf_obs_bd
132 
133  !> @brief Do observations need any checking? If so, add checks here
134  !<
135  subroutine swf_obs_rp(this)
136  class(swfobstype), intent(inout) :: this
137  !
138  ! Do SWF observations need any checking? If so, add checks here
139  return
140  end subroutine swf_obs_rp
141 
142  !> @brief Deallocate memory
143  !<
144  subroutine swf_obs_da(this)
145  class(swfobstype), intent(inout) :: this
146  !
147  nullify (this%ic)
148  nullify (this%x)
149  nullify (this%flowja)
150  call this%ObsType%obs_da()
151  !
152  return
153  end subroutine swf_obs_da
154 
155  !> @brief Set pointers
156  !<
157  subroutine set_pointers(this, ic, x, flowja)
158  ! -- dummy
159  class(swfobstype), intent(inout) :: this
160  type(swfictype), pointer, intent(in) :: ic
161  real(DP), dimension(:), pointer, contiguous, intent(in) :: x
162  real(DP), dimension(:), pointer, contiguous, intent(in) :: flowja
163  !
164  this%ic => ic
165  this%x => x
166  this%flowja => flowja
167  !
168  return
169  end subroutine set_pointers
170 
171  ! -- Procedures related to SWF observations (NOT type-bound)
172 
173  !> @brief Calculate stage observation when requested
174  !<
175  subroutine swf_process_stage_obs_id(obsrv, dis, inunitobs, iout)
176  ! -- dummy
177  type(observetype), intent(inout) :: obsrv
178  class(disbasetype), intent(in) :: dis
179  integer(I4B), intent(in) :: inunitobs
180  integer(I4B), intent(in) :: iout
181  ! -- local
182  integer(I4B) :: nn1
183  integer(I4B) :: icol, istart, istop
184  character(len=LINELENGTH) :: ermsg, string
185  !
186  ! -- Initialize variables
187  string = obsrv%IDstring
188  icol = 1
189  !
190  ! Get node number, with option for ID string to be either node
191  ! number or lay, row, column (when dis is structured).
192  nn1 = dis%noder_from_string(icol, istart, istop, inunitobs, &
193  iout, string, .false.)
194  !
195  if (nn1 > 0) then
196  obsrv%NodeNumber = nn1
197  else
198  ermsg = 'Error reading data from ID string'
199  call store_error(ermsg)
200  call store_error_unit(inunitobs)
201  end if
202  !
203  return
204  end subroutine swf_process_stage_obs_id
205 
206  !> @brief Process flow between two cells when requested
207  !<
208  subroutine swf_process_intercell_obs_id(obsrv, dis, inunitobs, iout)
209  ! -- dummy
210  type(observetype), intent(inout) :: obsrv
211  class(disbasetype), intent(in) :: dis
212  integer(I4B), intent(in) :: inunitobs
213  integer(I4B), intent(in) :: iout
214  ! -- local
215  integer(I4B) :: nn1, nn2
216  integer(I4B) :: icol, istart, istop, jaidx
217  character(len=LINELENGTH) :: ermsg, string
218  ! formats
219 70 format('Error: No connection exists between cells identified in text: ', a)
220  !
221  ! -- Initialize variables
222  string = obsrv%IDstring
223  icol = 1
224  !
225  ! Get node number, with option for ID string to be either node
226  ! number or lay, row, column (when dis is structured).
227  nn1 = dis%noder_from_string(icol, istart, istop, inunitobs, &
228  iout, string, .false.)
229  !
230  if (nn1 > 0) then
231  obsrv%NodeNumber = nn1
232  else
233  ermsg = 'Error reading data from ID string: '//string(istart:istop)
234  call store_error(ermsg)
235  end if
236  !
237  ! Get node number, with option for ID string to be either node
238  ! number or lay, row, column (when dis is structured).
239  nn2 = dis%noder_from_string(icol, istart, istop, inunitobs, &
240  iout, string, .false.)
241  if (nn2 > 0) then
242  obsrv%NodeNumber2 = nn2
243  else
244  ermsg = 'Error reading data from ID string: '//string(istart:istop)
245  call store_error(ermsg)
246  end if
247  !
248  ! -- store JA index
249  jaidx = dis%con%getjaindex(nn1, nn2)
250  if (jaidx == 0) then
251  write (ermsg, 70) trim(string)
252  call store_error(ermsg)
253  end if
254  obsrv%JaIndex = jaidx
255  !
256  if (count_errors() > 0) then
257  call store_error_unit(inunitobs)
258  end if
259  !
260  return
261  end subroutine swf_process_intercell_obs_id
262 
263 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:44
integer(i4b), parameter maxobstypes
maximum number of observation types
Definition: Constants.f90:47
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:102
subroutine swf_obs_df(this, iout, pkgname, filtyp, dis)
Define.
Definition: swf-obs.f90:73
subroutine set_pointers(this, ic, x, flowja)
Set pointers.
Definition: swf-obs.f90:158
subroutine swf_obs_da(this)
Deallocate memory.
Definition: swf-obs.f90:145
subroutine swf_process_intercell_obs_id(obsrv, dis, inunitobs, iout)
Process flow between two cells when requested.
Definition: swf-obs.f90:209
subroutine swf_obs_ar(this, ic, x, flowja)
Allocate and read.
Definition: swf-obs.f90:55
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:176
subroutine swf_obs_rp(this)
Do observations need any checking? If so, add checks here.
Definition: swf-obs.f90:136