MODFLOW 6 version 6.9.0.dev0
USGS Modular Hydrologic Model
Loading...
Searching...
No Matches
Mover.f90
Go to the documentation of this file.
1!> @brief This module contains the MvrModule Module
2!!
3!! This module contains the code for the low-level MvrType
4!! object.
5!!
6!<
8
9 use kindmodule, only: dp, i4b, lgp
13 use simvariablesmodule, only: errmsg
15
16 implicit none
17 private
18 public :: mvrtype
19
20 character(len=12), dimension(4) :: mvrtypes = &
21 &[character(len=12) :: 'FACTOR', 'EXCESS', 'THRESHOLD', 'UPTO']
22
23 !> @brief Derived type for MvrType
24 !!
25 !! This derived type contains information and methods for
26 !! moving water between packages.
27 !!
28 !<
30 character(len=LENMEMPATH) :: mem_path_src = '' !< provider package name
31 character(len=LENMEMPATH) :: mem_path_tgt = '' !< receiver package name
32 integer(I4B), pointer :: irchnrsrc => null() !< provider reach number
33 integer(I4B) :: irchnrsrcmapped !< mapped provider reach number (currently for lake outlet)
34 integer(I4B), pointer :: irchnrtgt => null() !< receiver reach number
35 integer(I4B), pointer :: imvrtype => null() !< mover type (1, 2, 3, 4) corresponds to mvrtypes
36 real(dp), pointer :: value => null() !< factor or rate depending on mvrtype
37 logical(LGP) :: is_provider_active = .true.
38 logical(LGP) :: is_receiver_active = .true.
39 real(dp) :: qpactual = dzero !< rate provided to the receiver
40 real(dp) :: qavailable = dzero !< rate available at time of providing
41 real(dp), pointer :: qtformvr_ptr => null() !< pointer to total available flow (qtformvr)
42 real(dp), pointer :: qformvr_ptr => null() !< pointer to available flow after consumed (qformvr)
43 real(dp), pointer :: qtomvr_ptr => null() !< pointer to provider flow rate (qtomvr)
44 real(dp), pointer :: qfrommvr_ptr => null() !< pointer to receiver flow rate (qfrommvr)
45 contains
46 procedure :: set_values
47 procedure :: prepare
48 procedure :: echo
49 procedure :: advance
50 procedure :: update_provider
51 procedure :: update_receiver
52 procedure :: qrcalc
53 procedure :: writeflow
54 end type mvrtype
55
56contains
57
58 !> @ brief Set values from input data
59 !!
60 !! Set values and pointers for mover object.
61 !!
62 !<
63 subroutine set_values(this, mname1, pname1, id1, mname2, pname2, &
64 id2, imvrtype, value)
66 class(mvrtype) :: this
67 character(len=*), intent(in) :: mname1
68 character(len=*), intent(in) :: pname1
69 integer(I4B), intent(in), target :: id1
70 character(len=*), intent(in) :: mname2
71 character(len=*), intent(in) :: pname2
72 integer(I4B), intent(in), target :: id2
73 integer(I4B), intent(in), target :: imvrtype
74 real(DP), intent(in), target :: value
75
76 this%mem_path_src = create_mem_path(mname1, pname1)
77 this%iRchNrSrc => id1
78 this%mem_path_tgt = create_mem_path(mname2, pname2)
79 this%iRchNrTgt => id2
80 this%imvrtype => imvrtype
81 this%value => value
82
83 ! to be set later
84 this%iRchNrSrcMapped = -1
85 end subroutine set_values
86
87 !> @ brief Prepare object
88 !!
89 !! Set values and pointers for mover object.
90 !! pckMemPaths is an array of strings which are the memory paths for those
91 !! packages. They are composed of model names and package names. The mover
92 !! entries must be in pckMemPaths, or this routine will terminate with an error.
93 !<
94 subroutine prepare(this, inunit, pckMemPaths, pakmovers)
95 ! -- modules
97 ! -- dummy
98 class(mvrtype) :: this !< MvrType object
99 integer(I4B), intent(in) :: inunit !< input file unit number
100 character(len=LENMEMPATH), &
101 dimension(:), pointer, contiguous :: pckMemPaths !< array of strings
102 type(packagemovertype), dimension(:), pointer, contiguous :: pakmovers !< Array of package mover objects
103 ! -- local
104 real(DP), dimension(:), pointer, contiguous :: temp_ptr => null()
105 logical :: found
106 integer(I4B) :: i
107 integer(I4B) :: ipakloc1, ipakloc2
108 !
109 ! -- Check to make sure provider and receiver are not the same
110 if (this%mem_path_src == this%mem_path_tgt .and. &
111 this%iRchNrSrc == this%iRchNrTgt) then
112 call store_error('Provider and receiver are the same: '// &
113 trim(this%mem_path_src)//' : '//trim(this%mem_path_tgt))
114 call store_error_unit(inunit)
115 end if
116 !
117 ! -- Check to make sure pname1 and pname2 are both listed in pckMemPaths
118 ! pname1 is the provider package; pname2 is the receiver package
119 found = .false.
120 ipakloc1 = 0
121 do i = 1, size(pckmempaths)
122 if (this%mem_path_src == pckmempaths(i)) then
123 found = .true.
124 ipakloc1 = i
125 exit
126 end if
127 end do
128 if (.not. found) then
129 call store_error('Mover capability not activated in '//this%mem_path_src)
130 call store_error('Add "MOVER" keyword to package options block.')
131 end if
132 found = .false.
133 ipakloc2 = 0
134 do i = 1, size(pckmempaths)
135 if (this%mem_path_tgt == pckmempaths(i)) then
136 found = .true.
137 ipakloc2 = i
138 exit
139 end if
140 end do
141 if (.not. found) then
142 call store_error('Mover capability not activated in '//this%mem_path_tgt)
143 call store_error('Add "MOVER" keyword to package options block.')
144 end if
145 if (count_errors() > 0) then
146 call store_error_unit(inunit)
147 end if
148
149 if (this%is_provider_active) then
150 !
151 ! -- Set pointer to QTOMVR array in the provider boundary package
152 temp_ptr => pakmovers(ipakloc1)%qtomvr
153 if (this%iRchNrSrc < 1 .or. this%iRchNrSrc > size(temp_ptr)) then
154 call store_error('Provider ID < 1 or greater than package size ')
155 write (errmsg, '(a,i0,a,i0)') 'Provider ID = ', this%iRchNrSrc, &
156 '; Package size = ', size(temp_ptr)
157 call store_error(trim(errmsg))
158 call store_error_unit(inunit)
159 end if
160 this%qtomvr_ptr => temp_ptr(this%iRchNrSrc)
161 !
162 ! -- Set pointer to QFORMVR array in the provider boundary package
163 temp_ptr => pakmovers(ipakloc1)%qformvr
164 this%qformvr_ptr => temp_ptr(this%iRchNrSrc)
165 !
166 ! -- Set pointer to QTFORMVR array in the provider boundary package
167 temp_ptr => pakmovers(ipakloc1)%qtformvr
168 this%qtformvr_ptr => temp_ptr(this%iRchNrSrc)
169 end if
170
171 if (this%is_receiver_active) then
172 !
173 ! -- Set pointer to QFROMMVR array in the receiver boundary package
174 temp_ptr => pakmovers(ipakloc2)%qfrommvr
175 if (this%iRchNrTgt < 1 .or. this%iRchNrTgt > size(temp_ptr)) then
176 call store_error('Receiver ID < 1 or greater than package size ')
177 write (errmsg, '(a,i0,a,i0)') 'Receiver ID = ', this%iRchNrTgt, &
178 '; package size = ', size(temp_ptr)
179 call store_error(trim(errmsg))
180 call store_error_unit(inunit)
181 end if
182 this%qfrommvr_ptr => temp_ptr(this%iRchNrTgt)
183 end if
184 end subroutine prepare
185
186 !> @ brief Echo data to list file
187 !!
188 !! Write mover values to output file.
189 !!
190 !<
191 subroutine echo(this, iout)
192 ! -- modules
193 ! -- dummy
194 class(mvrtype) :: this !< MvrType
195 integer(I4B), intent(in) :: iout !< unit number for output file
196 ! -- local
197 !
198 write (iout, '(4x, a, a, a, i0)') 'FROM PACKAGE: ', trim(this%mem_path_src), &
199 ' FROM ID: ', this%iRchNrSrc
200 write (iout, '(4x, a, a, a, i0)') 'TO PACKAGE: ', trim(this%mem_path_tgt), &
201 ' TO ID: ', this%iRchNrTgt
202 write (iout, '(4x, a, a, a, 1pg15.6,/)') 'MOVER TYPE: ', &
203 trim(mvrtypes(this%imvrtype)), ' ', this%value
204 end subroutine echo
205
206 !> @ brief Advance
207 !!
208 !! Advance mover object. Does nothing now.
209 !!
210 !<
211 subroutine advance(this)
212 ! -- modules
213 ! -- dummy
214 class(mvrtype) :: this
215 ! -- local
216 end subroutine advance
217
218 !> @ brief Formulate coefficients
219 !!
220 !! Make mover calculations for provider.
221 !!
222 !<
223 subroutine update_provider(this)
224 ! -- modules
225 ! -- dummy
226 class(mvrtype) :: this !< MvrType
227 ! -- local
228 real(DP) :: qavailable, qtanew, qpactual
229 !
230 ! -- Set qa and this%qavailable equal to available water in package (qtomvr)
231 qavailable = this%qformvr_ptr
232 qtanew = this%qtformvr_ptr
233 this%qavailable = qavailable
234 !
235 ! -- Using the mover rules, calculate how much of the available water will
236 ! be provided from the mover to the receiver.
237 qpactual = this%qrcalc(qavailable, qtanew)
238 !
239 ! -- Store qpactual
240 this%qpactual = qpactual
241 !
242 ! -- Add the calculated qpactual term directly into the provider package
243 ! qtomvr array.
244 this%qtomvr_ptr = this%qtomvr_ptr + qpactual
245 !
246 ! -- Reduce the amount of water that is available in the provider package
247 ! qformvr array.
248 this%qformvr_ptr = this%qformvr_ptr - qpactual
249 end subroutine update_provider
250
251 !> @ brief Formulate coefficients
252 !!
253 !! Make mover calculations for receiver.
254 !!
255 !<
256 subroutine update_receiver(this)
257 class(mvrtype) :: this !< MvrType
258 ! -- Add the calculated qpactual term directly into the receiver package
259 ! qfrommvr array.
260 this%qfrommvr_ptr = this%qfrommvr_ptr + this%qpactual
261 end subroutine update_receiver
262
263 !> @ brief Flow to receiver
264 !!
265 !! Calculate the rate of water provided to receiver.
266 !!
267 !<
268 function qrcalc(this, qa, qta) result(qr)
269 ! -- modules
270 ! -- return
271 real(dp) :: qr
272 ! -- dummy
273 class(mvrtype) :: this !< MvrType
274 real(dp), intent(in) :: qa !< actual flow
275 real(dp), intent(in) :: qta !< total available flow
276 ! -- local
277 ! -- Using the mover rules, calculate how much of the available water will
278 ! go to the receiver.
279 qr = dzero
280 ! -- Calculate qr
281 select case (this%imvrtype)
282 case (1)
283 ! -- FACTOR uses total available to make calculation, and then
284 ! limits qr by consumed available
285 if (qta > dzero) qr = qta * this%value
286 qr = min(qr, qa)
287 case (2)
288 ! -- EXCESS
289 if (qa > this%value) then
290 qr = qa - this%value
291 else
292 qr = dzero
293 end if
294 case (3)
295 ! -- THRESHOLD
296 if (this%value > qa) then
297 qr = dzero
298 else
299 qr = this%value
300 end if
301 case (4)
302 ! -- UPTO
303 if (qa > this%value) then
304 qr = this%value
305 else
306 qr = qa
307 end if
308 end select
309 end function qrcalc
310
311 !> @ brief Write flow
312 !!
313 !! Write a line of output for this mover object.
314 !!
315 !<
316 subroutine writeflow(this, iout)
317 ! -- modules
318 ! -- dummy
319 class(mvrtype) :: this !< MvrType
320 integer(I4B), intent(in) :: iout !< output file unit number
321 ! -- local
322 character(len=*), parameter :: fmt = &
323 "(1x, a, ' ID ', i0, ' AVAILABLE ', 1(1pg15.6), &
324 &' PROVIDED ', 1(1pg15.6), ' TO ', a, ' ID ', i0)"
325 !
326 write (iout, fmt) trim(this%mem_path_src), this%iRchNrSrc, this%qavailable, &
327 this%qpactual, trim(this%mem_path_tgt), this%iRchNrTgt
328 end subroutine writeflow
329
330end module mvrmodule
331
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 lenmodelname
maximum length of the model name
Definition Constants.f90:22
integer(i4b), parameter lenauxname
maximum length of a aux variable
Definition Constants.f90:35
integer(i4b), parameter lenboundname
maximum length of a bound name
Definition Constants.f90:36
real(dp), parameter dzero
real constant zero
Definition Constants.f90:65
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
Definition Constants.f90:37
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition Constants.f90:27
real(dp), parameter done
real constant 1
Definition Constants.f90:76
This module defines variable data types.
Definition kind.f90:8
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
This module contains the MvrModule Module.
Definition Mover.f90:7
subroutine echo(this, iout)
@ brief Echo data to list file
Definition Mover.f90:192
character(len=12), dimension(4) mvrtypes
Definition Mover.f90:20
subroutine update_receiver(this)
@ brief Formulate coefficients
Definition Mover.f90:257
real(dp) function qrcalc(this, qa, qta)
@ brief Flow to receiver
Definition Mover.f90:269
subroutine set_values(this, mname1, pname1, id1, mname2, pname2, id2, imvrtype, value)
@ brief Set values from input data
Definition Mover.f90:65
subroutine writeflow(this, iout)
@ brief Write flow
Definition Mover.f90:317
subroutine update_provider(this)
@ brief Formulate coefficients
Definition Mover.f90:224
subroutine prepare(this, inunit, pckmempaths, pakmovers)
@ brief Prepare object
Definition Mover.f90:95
subroutine advance(this)
@ brief Advance
Definition Mover.f90:212
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:169
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
Derived type for MvrType.
Definition Mover.f90:29