Skip to content

Commit 37974bc

Browse files
committed
separate files for buffer implementations
1 parent 5ffeb01 commit 37974bc

6 files changed

Lines changed: 260 additions & 203 deletions

File tree

msvs/mf6core.vfproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,9 @@
585585
<File RelativePath="..\src\Solution\ParticleTracker\Particle\Events\ParticleEvent.f90"/>
586586
<File RelativePath="..\src\Solution\ParticleTracker\Particle\Events\ParticleEvents.f90"/>
587587
<File RelativePath="..\src\Solution\ParticleTracker\Particle\ParticleReleaseSchedule.f90"/>
588+
<File RelativePath="..\src\Solution\ParticleTracker\Particle\ParticleTrackEventBuffer.f90"/>
589+
<File RelativePath="..\src\Solution\ParticleTracker\Particle\MemoryBuffer.f90"/>
590+
<File RelativePath="..\src\Solution\ParticleTracker\Particle\ScratchFileBuffer.f90"/>
588591
<File RelativePath="..\src\Solution\ParticleTracker\Particle\ParticleTracks.f90"/>
589592
<File RelativePath="..\src\Solution\ParticleTracker\Particle\Events\ReleaseEvent.f90"/>
590593
<File RelativePath="..\src\Solution\SolutionFactory.F90">
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
!> @brief In-memory particle event buffer module.
2+
!<
3+
module MemoryBufferModule
4+
5+
use KindModule, only: I4B
6+
use ParticleTrackEventBufferModule, only: ParticleTrackEventBufferType, &
7+
TrackRecordType, &
8+
ParticleTrackFileType, &
9+
save_record
10+
11+
implicit none
12+
private
13+
public :: MemoryBufferType
14+
15+
!> @brief In-memory particle event buffer. Records are held in a
16+
!! dynamically growing array that doubles in capacity as needed.
17+
type, extends(ParticleTrackEventBufferType) :: MemoryBufferType
18+
type(TrackRecordType), allocatable :: records(:) !< buffer
19+
contains
20+
procedure :: append => memory_append
21+
procedure :: flush => memory_flush
22+
procedure :: discard => memory_discard
23+
procedure :: destroy => memory_destroy
24+
end type MemoryBufferType
25+
26+
contains
27+
28+
subroutine memory_append(this, rec)
29+
class(MemoryBufferType) :: this
30+
type(TrackRecordType), intent(in) :: rec
31+
type(TrackRecordType), allocatable :: tmp(:)
32+
33+
if (.not. allocated(this%records)) then
34+
allocate (this%records(64))
35+
else if (this%nrecords == size(this%records)) then
36+
allocate (tmp(size(this%records) * 2))
37+
tmp(1:this%nrecords) = this%records
38+
call move_alloc(tmp, this%records)
39+
end if
40+
this%nrecords = this%nrecords + 1
41+
this%records(this%nrecords) = rec
42+
end subroutine memory_append
43+
44+
subroutine memory_flush(this, files)
45+
class(MemoryBufferType) :: this
46+
type(ParticleTrackFileType), intent(in) :: files(:)
47+
integer(I4B) :: n, i
48+
type(TrackRecordType) :: rec
49+
50+
do n = 1, this%nrecords
51+
rec = this%records(n)
52+
do i = 1, size(files)
53+
if (files(i)%iun > 0 .and. &
54+
(files(i)%iprp == -1 .or. files(i)%iprp == rec%iprp)) &
55+
call save_record(files(i)%iun, rec, files(i)%csv)
56+
end do
57+
end do
58+
this%nrecords = 0
59+
end subroutine memory_flush
60+
61+
subroutine memory_discard(this)
62+
class(MemoryBufferType) :: this
63+
this%nrecords = 0
64+
end subroutine memory_discard
65+
66+
subroutine memory_destroy(this)
67+
class(MemoryBufferType) :: this
68+
if (allocated(this%records)) deallocate (this%records)
69+
end subroutine memory_destroy
70+
71+
end module MemoryBufferModule
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
!> @brief Particle track event buffer module.
2+
!!
3+
!! Defines the abstract ParticleTrackEventBufferType, the TrackRecordType
4+
!! and ParticleTrackFileType data types, and the save_record helper used
5+
!! by concrete buffer implementations.
6+
!<
7+
module ParticleTrackEventBufferModule
8+
9+
use KindModule, only: DP, I4B, LGP
10+
use ErrorUtilModule, only: pstop
11+
12+
implicit none
13+
14+
character(len=*), parameter, public :: TRACKHEADER = &
15+
'kper,kstp,imdl,iprp,irpt,ilay,icell,izone,&
16+
&istatus,ireason,trelease,t,x,y,z,name'
17+
18+
character(len=*), parameter, public :: TRACKDTYPES = &
19+
'<i4,<i4,<i4,<i4,<i4,<i4,<i4,<i4,&
20+
&<i4,<i4,<f8,<f8,<f8,<f8,<f8,|S40'
21+
22+
!> @brief Flat record of a particle track event.
23+
type :: TrackRecordType
24+
integer(I4B) :: kper, kstp, imdl, iprp, irpt, ilay, icu, izone
25+
integer(I4B) :: istatus, ireason
26+
real(DP) :: trelease, ttrack, x, y, z
27+
character(len=40) :: name
28+
end type TrackRecordType
29+
30+
!> @brief Output file containing all or some particle pathlines.
31+
!!
32+
!! Can be associated with a particle release point (PRP) package
33+
!! or with an entire model, and can be binary or text (CSV).
34+
!<
35+
type :: ParticleTrackFileType
36+
private
37+
integer(I4B), public :: iun = 0 !< file unit number
38+
logical(LGP), public :: csv = .false. !< whether the file is binary or CSV
39+
integer(I4B), public :: iprp = -1 !< -1 is model-level file, 0 is exchange PRP
40+
end type ParticleTrackFileType
41+
42+
!> @brief Event buffering strategy
43+
type, abstract :: ParticleTrackEventBufferType
44+
integer(I4B) :: nrecords = 0 !< number of records stored
45+
contains
46+
procedure :: init => buffer_init !< open/allocate resources
47+
procedure(buffer_append), deferred :: append !< buffer one record
48+
procedure(buffer_flush), deferred :: flush !< write buffered records, reset
49+
procedure(buffer_simple), deferred :: discard !< reset without writing
50+
procedure(buffer_simple), deferred :: destroy !< release resources
51+
end type ParticleTrackEventBufferType
52+
53+
abstract interface
54+
subroutine buffer_append(this, rec)
55+
import ParticleTrackEventBufferType, TrackRecordType
56+
class(ParticleTrackEventBufferType) :: this
57+
type(TrackRecordType), intent(in) :: rec
58+
end subroutine buffer_append
59+
60+
subroutine buffer_flush(this, files)
61+
import ParticleTrackEventBufferType, ParticleTrackFileType
62+
class(ParticleTrackEventBufferType) :: this
63+
type(ParticleTrackFileType), intent(in) :: files(:)
64+
end subroutine buffer_flush
65+
66+
! Shared interface for discard and destroy: both take only `this`.
67+
subroutine buffer_simple(this)
68+
import ParticleTrackEventBufferType
69+
class(ParticleTrackEventBufferType) :: this
70+
end subroutine buffer_simple
71+
end interface
72+
73+
contains
74+
75+
subroutine buffer_init(this)
76+
class(ParticleTrackEventBufferType) :: this
77+
end subroutine buffer_init
78+
79+
!> @brief Save an event record to a binary or CSV file.
80+
subroutine save_record(iun, rec, csv)
81+
integer(I4B), intent(in) :: iun
82+
type(TrackRecordType), intent(in) :: rec
83+
logical(LGP), intent(in) :: csv
84+
85+
if (csv) then
86+
write (iun, '(*(G0,:,","))') &
87+
rec%kper, rec%kstp, rec%imdl, rec%iprp, rec%irpt, &
88+
rec%ilay, rec%icu, rec%izone, rec%istatus, rec%ireason, &
89+
rec%trelease, rec%ttrack, rec%x, rec%y, rec%z, trim(rec%name)
90+
else
91+
write (iun) &
92+
rec%kper, rec%kstp, rec%imdl, rec%iprp, rec%irpt, &
93+
rec%ilay, rec%icu, rec%izone, rec%istatus, rec%ireason, &
94+
rec%trelease, rec%ttrack, rec%x, rec%y, rec%z, rec%name
95+
end if
96+
end subroutine save_record
97+
98+
end module ParticleTrackEventBufferModule

0 commit comments

Comments
 (0)