Skip to content

Commit 0bc5c4a

Browse files
authored
refactor(prt): introduce cell method type/module (#2203)
Introduce CellMethodType and move the check() routine there from the base MethodType. These checks occur immediately before tracking begins across a cell, so this is the proper scope — they didn't belong in the base method type.
1 parent 2d01e20 commit 0bc5c4a

9 files changed

+189
-163
lines changed

make/makefile

+1
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,7 @@ $(OBJDIR)/SfrCrossSectionUtils.o \
287287
$(OBJDIR)/TernarySolveTrack.o \
288288
$(OBJDIR)/SubcellTri.o \
289289
$(OBJDIR)/Method.o \
290+
$(OBJDIR)/MethodCell.o \
290291
$(OBJDIR)/SubcellRect.o \
291292
$(OBJDIR)/VirtualBase.o \
292293
$(OBJDIR)/STLVecInt.o \

msvs/mf6core.vfproj

+1
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@
396396
<File RelativePath="..\src\Solution\ParticleTracker\CellRectQuad.f90"/>
397397
<File RelativePath="..\src\Solution\ParticleTracker\CellUtil.f90"/>
398398
<File RelativePath="..\src\Solution\ParticleTracker\Method.f90"/>
399+
<File RelativePath="..\src\Solution\ParticleTracker\MethodCell.f90"/>
399400
<File RelativePath="..\src\Solution\ParticleTracker\MethodCellPassToBot.f90"/>
400401
<File RelativePath="..\src\Solution\ParticleTracker\MethodCellPollock.f90"/>
401402
<File RelativePath="..\src\Solution\ParticleTracker\MethodCellPollockQuad.f90"/>

src/Solution/ParticleTracker/Method.f90

-157
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ module MethodModule
5252
procedure :: save
5353
procedure :: track
5454
procedure :: try_pass
55-
procedure :: check
5655
end type MethodType
5756

5857
abstract interface
@@ -185,160 +184,4 @@ subroutine save(this, particle, reason)
185184
call this%trackctl%save(particle, kper=per, kstp=stp, reason=reason)
186185
end subroutine save
187186

188-
!> @brief Check reporting/terminating conditions before tracking.
189-
!!
190-
!! Check a number of conditions determining whether to continue
191-
!! tracking the particle or terminate it, as well as whether to
192-
!! record any output data as per selected reporting conditions.
193-
!<
194-
subroutine check(this, particle, cell_defn, tmax)
195-
! modules
196-
use TdisModule, only: endofsimulation, totimc, totim
197-
use ParticleModule, only: TERM_WEAKSINK, TERM_NO_EXITS, &
198-
TERM_STOPZONE, TERM_INACTIVE
199-
! dummy
200-
class(MethodType), intent(inout) :: this
201-
type(ParticleType), pointer, intent(inout) :: particle
202-
type(CellDefnType), pointer, intent(inout) :: cell_defn
203-
real(DP), intent(in) :: tmax
204-
! local
205-
logical(LGP) :: dry_cell, dry_particle, no_exit_face, stop_zone, weak_sink
206-
integer(I4B) :: i
207-
real(DP) :: t, ttrackmax
208-
209-
dry_cell = this%fmi%ibdgwfsat0(cell_defn%icell) == 0
210-
dry_particle = particle%z > cell_defn%top
211-
no_exit_face = cell_defn%inoexitface > 0
212-
stop_zone = cell_defn%izone > 0 .and. particle%istopzone == cell_defn%izone
213-
weak_sink = cell_defn%iweaksink > 0
214-
215-
particle%izone = cell_defn%izone
216-
if (stop_zone) then
217-
particle%advancing = .false.
218-
particle%istatus = TERM_STOPZONE
219-
call this%save(particle, reason=3)
220-
return
221-
end if
222-
223-
if (no_exit_face .and. .not. dry_cell) then
224-
particle%advancing = .false.
225-
particle%istatus = TERM_NO_EXITS
226-
call this%save(particle, reason=3)
227-
return
228-
end if
229-
230-
if (weak_sink) then
231-
if (particle%istopweaksink > 0) then
232-
particle%advancing = .false.
233-
particle%istatus = TERM_WEAKSINK
234-
call this%save(particle, reason=3)
235-
return
236-
else
237-
call this%save(particle, reason=4)
238-
end if
239-
end if
240-
241-
if (dry_cell) then
242-
if (particle%idrymeth == 0) then
243-
! drop to cell bottom. handled by pass
244-
! to bottom method, nothing to do here
245-
no_exit_face = .false.
246-
else if (particle%idrymeth == 1) then
247-
! stop
248-
particle%advancing = .false.
249-
particle%istatus = TERM_INACTIVE
250-
call this%save(particle, reason=3)
251-
return
252-
else if (particle%idrymeth == 2) then
253-
! stay
254-
particle%advancing = .false.
255-
no_exit_face = .false.
256-
257-
! we might report tracking times
258-
! out of order here, but we want
259-
! the particle termination event
260-
! (if this is the last time step)
261-
! to have the maximum tracking t,
262-
! so we need to keep tabs on it.
263-
ttrackmax = totim
264-
265-
! update tracking time to time
266-
! step end time and save record
267-
particle%ttrack = totim
268-
call this%save(particle, reason=2)
269-
270-
! record user tracking times
271-
call this%tracktimes%advance()
272-
if (this%tracktimes%any()) then
273-
do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
274-
t = this%tracktimes%times(i)
275-
if (t < totimc) cycle
276-
if (t >= tmax) exit
277-
particle%ttrack = t
278-
call this%save(particle, reason=5)
279-
if (t > ttrackmax) ttrackmax = t
280-
end do
281-
end if
282-
283-
! terminate if last period/step
284-
if (endofsimulation) then
285-
particle%istatus = TERM_NO_EXITS
286-
particle%ttrack = ttrackmax
287-
call this%save(particle, reason=3)
288-
return
289-
end if
290-
end if
291-
else if (dry_particle .and. this%name /= "passtobottom") then
292-
if (particle%idrymeth == 0) then
293-
! drop to water table
294-
particle%z = cell_defn%top
295-
call this%save(particle, reason=1)
296-
else if (particle%idrymeth == 1) then
297-
! stop
298-
particle%advancing = .false.
299-
particle%istatus = TERM_INACTIVE
300-
call this%save(particle, reason=3)
301-
return
302-
else if (particle%idrymeth == 2) then
303-
! stay
304-
particle%advancing = .false.
305-
no_exit_face = .false.
306-
307-
! we might report tracking times
308-
! out of order here, but we want
309-
! the particle termination event
310-
! (if this is the last time step)
311-
! to have the maximum tracking t,
312-
! so we need to keep tabs on it.
313-
ttrackmax = totim
314-
315-
! update tracking time to time
316-
! step end time and save record
317-
particle%ttrack = totim
318-
call this%save(particle, reason=2)
319-
320-
! record user tracking times
321-
call this%tracktimes%advance()
322-
if (this%tracktimes%any()) then
323-
do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
324-
t = this%tracktimes%times(i)
325-
if (t < totimc) cycle
326-
if (t >= tmax) exit
327-
particle%ttrack = t
328-
call this%save(particle, reason=5)
329-
if (t > ttrackmax) ttrackmax = t
330-
end do
331-
end if
332-
end if
333-
end if
334-
335-
if (no_exit_face) then
336-
particle%advancing = .false.
337-
particle%istatus = TERM_NO_EXITS
338-
call this%save(particle, reason=3)
339-
return
340-
end if
341-
342-
end subroutine check
343-
344187
end module MethodModule
+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
module MethodCellModule
2+
3+
use KindModule, only: DP, I4B, LGP
4+
use ConstantsModule, only: DONE, DZERO
5+
use MethodModule, only: MethodType
6+
use ParticleModule, only: ParticleType
7+
use CellDefnModule, only: CellDefnType
8+
implicit none
9+
10+
private
11+
public :: MethodCellType
12+
13+
type, abstract, extends(MethodType) :: MethodCellType
14+
contains
15+
procedure, public :: check
16+
end type MethodCellType
17+
18+
contains
19+
20+
!> @brief Check reporting/terminating conditions before tracking
21+
!! the particle across the cell.
22+
!!
23+
!! Check a number of conditions determining whether to continue
24+
!! tracking the particle or terminate it, as well as whether to
25+
!! record any output data as per selected reporting conditions.
26+
!<
27+
subroutine check(this, particle, cell_defn, tmax)
28+
! modules
29+
use TdisModule, only: endofsimulation, totimc, totim
30+
use ParticleModule, only: TERM_WEAKSINK, TERM_NO_EXITS, &
31+
TERM_STOPZONE, TERM_INACTIVE
32+
! dummy
33+
class(MethodCellType), intent(inout) :: this
34+
type(ParticleType), pointer, intent(inout) :: particle
35+
type(CellDefnType), pointer, intent(inout) :: cell_defn
36+
real(DP), intent(in) :: tmax
37+
! local
38+
logical(LGP) :: dry_cell, dry_particle, no_exit_face, stop_zone, weak_sink
39+
integer(I4B) :: i
40+
real(DP) :: t, ttrackmax
41+
42+
dry_cell = this%fmi%ibdgwfsat0(cell_defn%icell) == 0
43+
dry_particle = particle%z > cell_defn%top
44+
no_exit_face = cell_defn%inoexitface > 0
45+
stop_zone = cell_defn%izone > 0 .and. particle%istopzone == cell_defn%izone
46+
weak_sink = cell_defn%iweaksink > 0
47+
48+
particle%izone = cell_defn%izone
49+
if (stop_zone) then
50+
particle%advancing = .false.
51+
particle%istatus = TERM_STOPZONE
52+
call this%save(particle, reason=3)
53+
return
54+
end if
55+
56+
if (no_exit_face .and. .not. dry_cell) then
57+
particle%advancing = .false.
58+
particle%istatus = TERM_NO_EXITS
59+
call this%save(particle, reason=3)
60+
return
61+
end if
62+
63+
if (weak_sink) then
64+
if (particle%istopweaksink > 0) then
65+
particle%advancing = .false.
66+
particle%istatus = TERM_WEAKSINK
67+
call this%save(particle, reason=3)
68+
return
69+
else
70+
call this%save(particle, reason=4)
71+
end if
72+
end if
73+
74+
if (dry_cell) then
75+
if (particle%idrymeth == 0) then
76+
! drop to cell bottom. handled by pass
77+
! to bottom method, nothing to do here
78+
no_exit_face = .false.
79+
else if (particle%idrymeth == 1) then
80+
! stop
81+
particle%advancing = .false.
82+
particle%istatus = TERM_INACTIVE
83+
call this%save(particle, reason=3)
84+
return
85+
else if (particle%idrymeth == 2) then
86+
! stay
87+
particle%advancing = .false.
88+
no_exit_face = .false.
89+
90+
! we might report tracking times
91+
! out of order here, but we want
92+
! the particle termination event
93+
! (if this is the last time step)
94+
! to have the maximum tracking t,
95+
! so we need to keep tabs on it.
96+
ttrackmax = totim
97+
98+
! update tracking time to time
99+
! step end time and save record
100+
particle%ttrack = totim
101+
call this%save(particle, reason=2)
102+
103+
! record user tracking times
104+
call this%tracktimes%advance()
105+
if (this%tracktimes%any()) then
106+
do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
107+
t = this%tracktimes%times(i)
108+
if (t < totimc) cycle
109+
if (t >= tmax) exit
110+
particle%ttrack = t
111+
call this%save(particle, reason=5)
112+
if (t > ttrackmax) ttrackmax = t
113+
end do
114+
end if
115+
116+
! terminate if last period/step
117+
if (endofsimulation) then
118+
particle%istatus = TERM_NO_EXITS
119+
particle%ttrack = ttrackmax
120+
call this%save(particle, reason=3)
121+
return
122+
end if
123+
end if
124+
else if (dry_particle .and. this%name /= "passtobottom") then
125+
if (particle%idrymeth == 0) then
126+
! drop to water table
127+
particle%z = cell_defn%top
128+
call this%save(particle, reason=1)
129+
else if (particle%idrymeth == 1) then
130+
! stop
131+
particle%advancing = .false.
132+
particle%istatus = TERM_INACTIVE
133+
call this%save(particle, reason=3)
134+
return
135+
else if (particle%idrymeth == 2) then
136+
! stay
137+
particle%advancing = .false.
138+
no_exit_face = .false.
139+
140+
! we might report tracking times
141+
! out of order here, but we want
142+
! the particle termination event
143+
! (if this is the last time step)
144+
! to have the maximum tracking t,
145+
! so we need to keep tabs on it.
146+
ttrackmax = totim
147+
148+
! update tracking time to time
149+
! step end time and save record
150+
particle%ttrack = totim
151+
call this%save(particle, reason=2)
152+
153+
! record user tracking times
154+
call this%tracktimes%advance()
155+
if (this%tracktimes%any()) then
156+
do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
157+
t = this%tracktimes%times(i)
158+
if (t < totimc) cycle
159+
if (t >= tmax) exit
160+
particle%ttrack = t
161+
call this%save(particle, reason=5)
162+
if (t > ttrackmax) ttrackmax = t
163+
end do
164+
end if
165+
end if
166+
end if
167+
168+
if (no_exit_face) then
169+
particle%advancing = .false.
170+
particle%istatus = TERM_NO_EXITS
171+
call this%save(particle, reason=3)
172+
return
173+
end if
174+
175+
end subroutine check
176+
177+
end module MethodCellModule

src/Solution/ParticleTracker/MethodCellPassToBot.f90

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
module MethodCellPassToBotModule
22

33
use KindModule, only: DP, I4B
4-
use MethodModule, only: MethodType
4+
use MethodCellModule, only: MethodCellType
55
use CellDefnModule, only: CellDefnType, create_defn
66
use PrtFmiModule, only: PrtFmiType
77
use BaseDisModule, only: DisBaseType
@@ -17,7 +17,7 @@ module MethodCellPassToBotModule
1717
public :: MethodCellPassToBotType
1818
public :: create_method_cell_ptb
1919

20-
type, extends(MethodType) :: MethodCellPassToBotType
20+
type, extends(MethodCellType) :: MethodCellPassToBotType
2121
private
2222
contains
2323
procedure, public :: apply => apply_ptb

src/Solution/ParticleTracker/MethodCellPollock.f90

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module MethodCellPollockModule
33
use KindModule, only: DP, I4B
44
use ConstantsModule, only: DONE, DZERO
55
use MethodModule, only: MethodType
6+
use MethodCellModule, only: MethodCellType
67
use MethodSubcellPoolModule, only: method_subcell_plck, &
78
method_subcell_tern
89
use CellRectModule, only: CellRectType, create_cell_rect
@@ -14,7 +15,7 @@ module MethodCellPollockModule
1415
public :: MethodCellPollockType
1516
public :: create_method_cell_pollock
1617

17-
type, extends(MethodType) :: MethodCellPollockType
18+
type, extends(MethodCellType) :: MethodCellPollockType
1819
contains
1920
procedure, public :: apply => apply_mcp
2021
procedure, public :: deallocate => destroy_mcp

0 commit comments

Comments
 (0)