19 character(len=LENPACKAGENAME) ::
text =
' PRTFMI'
29 integer(I4B),
pointer,
public :: max_faces => null()
30 real(dp),
dimension(:),
pointer,
contiguous,
public :: &
32 real(dp),
dimension(:),
pointer,
contiguous,
public :: &
34 real(dp),
dimension(:),
pointer,
contiguous,
public :: &
35 storageflows => null()
36 real(dp),
dimension(:, :),
pointer,
contiguous,
public :: &
37 boundaryflows => null()
38 integer(I4B),
dimension(:),
pointer,
contiguous,
public :: &
39 boundaryfaces => null()
59 subroutine fmi_cr(fmiobj, name_model, input_mempath, inunit, iout)
62 character(len=*),
intent(in) :: name_model
63 character(len=*),
intent(in) :: input_mempath
64 integer(I4B),
intent(inout) :: inunit
65 integer(I4B),
intent(in) :: iout
71 call fmiobj%set_names(1, name_model,
'FMI',
'FMI', input_mempath)
75 call fmiobj%allocate_scalars()
78 fmiobj%inunit = inunit
82 fmiobj%depvartype =
'TRACKS '
94 character(len=15) :: nodestr
95 character(len=*),
parameter :: fmtdry = &
96 &
"(/1X,'WARNING: DRY CELL ENCOUNTERED AT ',a,'; RESET AS INACTIVE')"
97 character(len=*),
parameter :: fmtrewet = &
98 &
"(/1X,'DRY CELL REACTIVATED AT ', a)"
103 this%iflowsupdated = 1
106 if (this%iubud /= 0)
call this%advance_bfr()
109 if (this%iuhds /= 0)
call this%advance_hfr()
112 if (this%iumvr /= 0) &
113 call this%mvrbudobj%bfr_advance(this%dis, this%iout)
116 call this%accumulate_flows()
119 do n = 1, this%dis%nodes
122 if (this%gwfsat(n) > dzero)
then
123 this%ibdgwfsat0(n) = 1
125 this%ibdgwfsat0(n) = 0
129 if (this%ibound(n) > 0)
then
130 if (this%gwfhead(n) ==
dhdry)
then
133 call this%dis%noder_to_string(n, nodestr)
134 write (this%iout, fmtdry) trim(nodestr)
139 if (this%ibound(n) == 0)
then
140 if (this%gwfhead(n) /=
dhdry)
then
143 call this%dis%noder_to_string(n, nodestr)
144 write (this%iout, fmtrewet) trim(nodestr)
155 integer(I4B),
intent(in) :: idryinactive
157 call this%FlowModelInterfaceType%fmi_df(dis, idryinactive)
159 this%max_faces = this%dis%get_max_npolyverts() + 2
160 if (this%max_faces > 32)
then
161 write (
errmsg,
'(a,i0,a,i0,a)') &
162 'DISV grid contains a cell with ', this%max_faces - 2, &
163 ' lateral faces. Cells may have at most 30 lateral faces.'
165 call this%parser%StoreErrorUnit()
175 call this%FlowModelInterfaceType%allocate_scalars()
177 call mem_allocate(this%max_faces,
'MAX_FACES', this%memoryPath)
185 integer(I4B),
intent(in) :: nodes
188 call this%FlowModelInterfaceType%allocate_arrays(nodes)
191 'STORAGEFLOWS', this%memoryPath)
193 'SOURCEFLOWS', this%memoryPath)
195 'SINKFLOWS', this%memoryPath)
196 call mem_allocate(this%BoundaryFlows, nodes, this%max_faces, &
197 'BOUNDARYFLOWS', this%memoryPath)
199 'BOUNDARYFACES', this%memoryPath)
214 call this%FlowModelInterfaceType%fmi_da()
223 integer(I4B) :: j, i, ip, ib
224 integer(I4B) :: iflowface, iauxiflowface, icellface
226 character(len=LENAUXNAME) :: auxname
229 this%StorageFlows =
dzero
230 if (this%igwfstrgss /= 0) &
231 this%StorageFlows = this%StorageFlows + this%gwfstrgss
232 if (this%igwfstrgsy /= 0) &
233 this%StorageFlows = this%StorageFlows + this%gwfstrgsy
235 this%SourceFlows =
dzero
236 this%SinkFlows =
dzero
237 this%BoundaryFlows =
dzero
238 this%BoundaryFaces = 0
239 do ip = 1, this%nflowpack
241 naux = this%gwfpackages(ip)%naux
244 auxname = this%gwfpackages(ip)%auxname(j)
245 if (trim(adjustl(auxname)) ==
"IFLOWFACE")
then
251 do ib = 1, this%gwfpackages(ip)%nbound
252 i = this%gwfpackages(ip)%nodelist(ib)
254 if (this%ibound(i) <= 0) cycle
255 qbnd = this%gwfpackages(ip)%get_flow(ib)
259 if (iauxiflowface > 0)
then
260 iflowface = nint(this%gwfpackages(ip)%auxvar(iauxiflowface, ib))
261 icellface = this%iflowface_to_icellface(iflowface)
263 if (icellface > 0)
then
264 call this%mark_boundary_face(i, icellface)
265 this%BoundaryFlows(i, icellface) = &
266 this%BoundaryFlows(i, icellface) + qbnd
267 else if (qbnd .gt.
dzero)
then
268 this%SourceFlows(i) = this%SourceFlows(i) + qbnd
269 else if (qbnd .lt.
dzero)
then
270 this%SinkFlows(i) = this%SinkFlows(i) + qbnd
280 integer(I4B),
intent(in) :: ic
281 integer(I4B),
intent(in) :: icellface
283 integer(I4B) :: bit_pos
285 if (ic <= 0 .or. ic > this%dis%nodes)
then
286 print *,
'Invalid cell number: ', ic
287 print *,
'Expected a value in range [1, ', this%dis%nodes,
']'
290 if (icellface <= 0)
then
291 print *,
'Invalid face number: ', icellface
292 print *,
'Expected a value in range [1, ', this%max_faces,
']'
295 bit_pos = icellface - 1
296 if (bit_pos < 0 .or. bit_pos > 31)
then
297 print *,
'Invalid bitmask position: ', bit_pos
298 print *,
'Expected a value in range [0, 31]'
301 this%BoundaryFaces(ic) = ibset(this%BoundaryFaces(ic), bit_pos)
307 integer(I4B),
intent(in) :: ic
308 integer(I4B),
intent(in) :: icellface
309 logical(LGP) :: is_boundary
311 integer(I4B) :: bit_pos
313 is_boundary = .false.
314 if (ic <= 0 .or. ic > this%dis%nodes)
then
315 print *,
'Invalid cell number: ', ic
316 print *,
'Expected a value in range [1, ', this%dis%nodes,
']'
319 if (icellface <= 0)
then
320 print *,
'Invalid face number: ', icellface
321 print *,
'Expected a value in range [1, ', this%max_faces,
']'
324 bit_pos = icellface - 1
325 if (bit_pos < 0 .or. bit_pos > 31)
then
326 print *,
'Invalid bitmask position: ', bit_pos
327 print *,
'Expected a value in range [0, 31]'
330 is_boundary = btest(this%BoundaryFaces(ic), bit_pos)
335 result(is_net_out_boundary)
337 integer(I4B),
intent(in) :: ic
338 integer(I4B),
intent(in) :: icellface
339 logical(LGP) :: is_net_out_boundary
341 is_net_out_boundary = .false.
342 if (.not. this%is_boundary_face(ic, icellface))
return
343 if (this%BoundaryFlows(ic, icellface) <
dzero) &
344 is_net_out_boundary = .true.
351 integer(I4B),
intent(in) :: iflowface
352 integer(I4B) :: icellface
354 icellface = iflowface
355 if (icellface < 0) icellface = icellface + this%max_faces -
iflowface_top
This module contains simulation constants.
real(dp), parameter dhdry
real dry cell constant
integer(i4b), parameter lenpackagename
maximum length of the package name
integer(i4b), parameter lenvarname
maximum length of a variable name
integer(i4b), parameter lenauxname
maximum length of a aux variable
real(dp), parameter dzero
real constant zero
subroutine pstop(status, message)
Stop the program, optionally specifying an error status code.
This module defines variable data types.
subroutine accumulate_flows(this)
Accumulate flows.
subroutine mark_boundary_face(this, ic, icellface)
Mark a face as a boundary face.
integer(i4b) function iflowface_to_icellface(this, iflowface)
Convert an iflowface number to a cell face number. Maps bottom (-2) -> max_faces - 1,...
subroutine fmi_ad(this)
Time step advance.
subroutine prtfmi_allocate_arrays(this, nodes)
Allocate arrays.
subroutine prtfmi_df(this, dis, idryinactive)
Define the flow model interface.
subroutine prtfmi_da(this)
Deallocate memory.
logical(lgp) function is_boundary_face(this, ic, icellface)
Check if a face is assigned to a boundary package.
@, public iflowface_bottom
subroutine prtfmi_allocate_scalars(this)
Allocate scalars.
character(len=lenpackagename) text
subroutine, public fmi_cr(fmiobj, name_model, input_mempath, inunit, iout)
Create a new PrtFmi object.
logical(lgp) function is_net_out_boundary_face(this, ic, icellface)
Check if a face is an assigned boundary with net outflow.
This module contains simulation methods.
subroutine, public store_error(msg, terminate)
Store an error message.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string