Skip to content

Commit 3f33b01

Browse files
committed
refactor routines, better docstrings
1 parent a133a2b commit 3f33b01

1 file changed

Lines changed: 125 additions & 113 deletions

File tree

src/Exchange/exg-prtprt.f90

Lines changed: 125 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module PrtPrtExchangeModule
55
use ConstantsModule, only: LENPACKAGENAME, LINELENGTH, LENMEMPATH, &
66
LENMODELNAME, LENBOUNDNAME, LENAUXNAME, &
77
DZERO, DONE
8+
use ErrorUtilModule, only: pstop
89
use ListsModule, only: basemodellist, baseexchangelist
910
use SimModule, only: store_error, store_error_filename, count_errors
1011
use SimVariablesModule, only: errmsg
@@ -31,7 +32,7 @@ module PrtPrtExchangeModule
3132
private
3233

3334
public :: PrtPrtExchangeType
34-
public :: prtprt_cr, try_particle_transfer
35+
public :: prtprt_cr, try_transfer_particle
3536
public :: GetPrtPrtExchangeFromList
3637

3738
!> @brief Exchange that transfers particles between two PRT models.
@@ -78,6 +79,7 @@ module PrtPrtExchangeModule
7879
procedure, private :: noder
7980
procedure, private :: get_exchange_faces
8081
procedure, private :: transform_particle
82+
procedure, private :: transfer_particle
8183
end type PrtPrtExchangeType
8284

8385
contains
@@ -162,8 +164,8 @@ subroutine exg_df(this)
162164
end if
163165
!
164166
p => this%self ! self-pointer. can't point directly to `this`
165-
call this%prtmodel1%handlers%subscribe(try_particle_transfer, p)
166-
call this%prtmodel2%handlers%subscribe(try_particle_transfer, p)
167+
call this%prtmodel1%handlers%subscribe(try_transfer_particle, p)
168+
call this%prtmodel2%handlers%subscribe(try_transfer_particle, p)
167169
end subroutine exg_df
168170

169171
!> @brief Allocate and read: load the connected-cell list from IDM.
@@ -470,7 +472,10 @@ function noder(this, model, cellid, iout)
470472
noder = model%dis%get_nodenumber(node, 0)
471473
end function noder
472474

473-
function try_particle_transfer(context, particle, event) result(transferred)
475+
!> @brief Event handler for particle transfers. Checks whether the particle
476+
!! should be transferred in either direction through any exchange connection
477+
!! and, if so, conducts the transfer and return signals that it has occurred.
478+
function try_transfer_particle(context, particle, event) result(transferred)
474479
use ModelExitEventModule, only: ModelExitEventType
475480
use PrtPrpModule, only: PrtPrpType, ExgPrtPrpType
476481
! dummy
@@ -480,10 +485,8 @@ function try_particle_transfer(context, particle, event) result(transferred)
480485
logical(LGP) :: transferred
481486
! local
482487
type(PrtPrtExchangeType), pointer :: exg
483-
class(BndType), pointer :: exgprp_obj
484-
type(ExgPrtPrpType), pointer :: exgprp
485-
integer(I4B) :: i, dest_cell
486-
logical(LGP) :: found
488+
logical(LGP) :: should
489+
integer(I4B) :: iexg
487490

488491
transferred = .false.
489492

@@ -496,110 +499,105 @@ function try_particle_transfer(context, particle, event) result(transferred)
496499

497500
select type (event)
498501
type is (ModelExitEventType)
499-
! model1 -> model2
500-
found = .false.
501-
do i = 1, exg%nexg
502+
! model1->model2
503+
should = .false.
504+
do iexg = 1, exg%nexg
502505
if ((particle%itrdomain(LEVEL_MODEL) == exg%prtmodel1%id) .and. &
503-
(particle%icu == exg%nodem1(i))) then
504-
dest_cell = exg%nodem2(i)
505-
found = .true.
506+
(particle%icu == exg%nodem1(iexg))) then
507+
should = .true.
506508
exit
507509
end if
508510
end do
509-
if (found) then
510-
exgprp_obj => GetBndFromList( &
511-
exg%prtmodel2%bndlist, &
512-
exg%prtmodel2%bndlist%Count())
513-
select type (exgprp_obj)
514-
type is (ExgPrtPrpType)
515-
exgprp => exgprp_obj
516-
call exg%transform_particle(particle, particle%icu, &
517-
nint(exg%auxvar(exg%iflowface1, i)), &
518-
from_m1=.true.)
519-
exgprp%has_pending = .true.
520-
exgprp%nparticles = exgprp%nparticles + 1
521-
call exgprp%particles%resize(exgprp%nparticles, exgprp%memoryPath)
522-
call exgprp%particles%put(particle, exgprp%nparticles)
523-
particle%itrdomain(1) = exg%prtmodel1%id
524-
particle%advancing = .false.
525-
transferred = .true.
526-
return
527-
end select
511+
if (should) then
512+
call exg%transfer_particle(particle, iexg=iexg, from_m1=.true.)
513+
return
528514
end if
529515

530-
! model2 -> model1
531-
found = .false.
532-
do i = 1, exg%nexg
516+
! model2->model1
517+
should = .false.
518+
do iexg = 1, exg%nexg
533519
if ((particle%itrdomain(LEVEL_MODEL) == exg%prtmodel2%id) .and. &
534-
(particle%icu == exg%nodem2(i))) then
535-
dest_cell = exg%nodem1(i)
536-
found = .true.
520+
(particle%icu == exg%nodem2(iexg))) then
521+
should = .true.
537522
exit
538523
end if
539524
end do
540-
if (found) then
541-
exgprp_obj => GetBndFromList( &
542-
exg%prtmodel1%bndlist, &
543-
exg%prtmodel1%bndlist%Count())
544-
select type (exgprp_obj)
545-
type is (ExgPrtPrpType)
546-
exgprp => exgprp_obj
547-
call exg%transform_particle(particle, particle%icu, &
548-
nint(exg%auxvar(exg%iflowface2, i)), &
549-
from_m1=.false.)
550-
exgprp%has_pending = .true.
551-
exgprp%nparticles = exgprp%nparticles + 1
552-
call exgprp%particles%resize(exgprp%nparticles, exgprp%memoryPath)
553-
call exgprp%particles%put(particle, exgprp%nparticles)
554-
particle%itrdomain(1) = exg%prtmodel2%id
555-
particle%advancing = .false.
556-
transferred = .true.
557-
return
558-
end select
525+
if (should) then
526+
call exg%transfer_particle(particle, iexg=iexg, from_m1=.false.)
527+
return
559528
end if
560529
end select
561-
end function try_particle_transfer
530+
end function try_transfer_particle
562531

563-
!> @brief Get PRT-PRT exchange from list
564-
function GetPrtPrtExchangeFromList(list, idx) result(res)
565-
use ListModule, only: ListType
566-
implicit none
567-
type(ListType), intent(inout) :: list
568-
integer(I4B), intent(in) :: idx
569-
class(PrtPrtExchangeType), pointer :: res
570-
class(*), pointer :: obj
571-
572-
obj => list%GetItem(idx)
573-
res => CastAsPrtPrtExchange(obj)
574-
end function GetPrtPrtExchangeFromList
575-
576-
!> @brief Cast object as PRT-PRT exchange
577-
function CastAsPrtPrtExchange(obj) result(res)
578-
implicit none
579-
class(*), pointer, intent(inout) :: obj
580-
class(PrtPrtExchangeType), pointer :: res
532+
!> @brief Transfer the particle from one model to the other through
533+
!! the given exchange connection.
534+
subroutine transfer_particle(this, particle, iexg, from_m1)
535+
use PrtPrpModule, only: PrtPrpType, ExgPrtPrpType
536+
class(PrtPrtExchangeType), intent(inout) :: this
537+
type(ParticleType), intent(inout), pointer :: particle
538+
integer(I4B), intent(in) :: iexg
539+
logical(LGP), intent(in) :: from_m1
540+
! local
541+
type(PrtModelType), pointer :: prt_dst
542+
type(ExgPrtPrpType), pointer :: exgprp
543+
class(BndType), pointer :: exgprp_obj
544+
integer(I4B) :: icu_dst
581545

582-
res => null()
583-
if (.not. associated(obj)) return
546+
if (from_m1) then
547+
prt_dst => this%prtmodel2
548+
else
549+
prt_dst => this%prtmodel1
550+
end if
584551

585-
select type (obj)
586-
class is (PrtPrtExchangeType)
587-
res => obj
552+
exgprp_obj => GetBndFromList( &
553+
prt_dst%bndlist, &
554+
prt_dst%bndlist%Count())
555+
556+
select type (exgprp_obj)
557+
type is (ExgPrtPrpType)
558+
call this%transform_particle(particle, particle%icu, icu_dst, &
559+
nint(this%auxvar(this%iflowface1, iexg)), &
560+
from_m1=from_m1)
561+
562+
particle%icu = icu_dst
563+
particle%advancing = .true.
564+
particle%itrdomain(LEVEL_MODEL) = prt_dst%id
565+
particle%itrdomain(LEVEL_FEATURE) = &
566+
prt_dst%dis%get_nodenumber(particle%icu, 1)
567+
568+
exgprp => exgprp_obj
569+
exgprp%has_pending = .true.
570+
exgprp%nparticles = exgprp%nparticles + 1
571+
call exgprp%particles%resize(exgprp%nparticles, exgprp%memoryPath)
572+
call exgprp%particles%put(particle, exgprp%nparticles)
588573
end select
589-
end function CastAsPrtPrtExchange
590-
591-
!> @brief Transform particle coordinates from source to destination model
592-
subroutine transform_particle(this, particle, n_src, f_src, from_m1)
574+
end subroutine transfer_particle
575+
576+
!> @brief Transform particle coordinates from source to destination cell,
577+
!! by way of intermediate transformations via cell-normalized coordinates.
578+
!!
579+
!! Transforms particle from the source model's coordinate system to coords
580+
!! local to the source cell, then to coords local to the destination cell,
581+
!! and finally to the destination model's coordinate system.
582+
!!
583+
!! If the source cell connects to multiple cells in the destination model,
584+
!! the destination cells' connecting faces are together assumed to coincide
585+
!! with the source cell's connecting face. Coordinates are then computed by
586+
!! reference to the extent of the cell in the 2 dimensions parallel to the
587+
!! connected faces, and used to determine which among potential destination
588+
!! cells the particle should enter.
589+
!<
590+
subroutine transform_particle(this, particle, n_src, n_dst, f_src, from_m1)
593591
class(PrtPrtExchangeType) :: this
594592
type(ParticleType), pointer :: particle
595593
integer(I4B), intent(in) :: n_src ! source cell
594+
integer(I4B), intent(out) :: n_dst ! destination cell
596595
integer(I4B), intent(in) :: f_src ! source face (IFLOWFACE numbering)
597596
logical(LGP), intent(in) :: from_m1 ! true = m1->m2, false = m2->m1
598-
599-
! Local variables
597+
! local
600598
integer(I4B), allocatable :: iexg_candidates(:)
601599
integer(I4B) :: n_candidates
602-
integer(I4B) :: n_dst, f_dst, iexg, i
600+
integer(I4B) :: f_dst, iexg, i
603601
integer(I4B) :: iflowface_src, iflowface_dst
604602
real(DP) :: x1min, x1max, y1min, y1max, z1min, z1max
605603
real(DP) :: x2min, x2max, y2min, y2max, z2min, z2max
@@ -609,7 +607,7 @@ subroutine transform_particle(this, particle, n_src, f_src, from_m1)
609607
logical :: found
610608
class(PrtModelType), pointer :: prt_src, prt_dst
611609

612-
! Set up source/destination based on direction
610+
! set source/destination model
613611
if (from_m1) then
614612
prt_src => this%prtmodel1
615613
prt_dst => this%prtmodel2
@@ -622,66 +620,60 @@ subroutine transform_particle(this, particle, n_src, f_src, from_m1)
622620
iflowface_dst = this%iflowface1
623621
end if
624622

625-
! 1. Find all candidate destination connections
623+
! find candidate connections
626624
call get_connections(this, n_src, f_src, iexg_candidates, &
627625
n_candidates, from_m1)
628626

629-
! 2. Get source face bounds
627+
! compute source face bounds
630628
call get_face_bounds(prt_src%dis, n_src, f_src, &
631629
x1min, x1max, y1min, y1max, z1min, z1max)
632630

633-
! 3. Get consolidated destination face bounds
631+
! compute destination face bounds
634632
call get_consolidated_bounds(this, iexg_candidates, n_candidates, &
635633
x2min, x2max, y2min, y2max, z2min, z2max, &
636634
prt_dst%dis, iflowface_dst)
637635

638-
! 4. Normalize particle position in source face [0,1]
636+
! map to cell-local coords
639637
dx1 = x1max - x1min
640638
dy1 = y1max - y1min
641639
dz1 = z1max - z1min
642-
643640
if (dx1 > DZERO) then
644641
tx = (particle%x - x1min) / dx1
645642
else
646-
tx = DZERO ! dimension constant on this face
643+
tx = DZERO ! constant dimension
647644
end if
648-
649645
if (dy1 > DZERO) then
650646
ty = (particle%y - y1min) / dy1
651647
else
652648
ty = DZERO
653649
end if
654-
655650
if (dz1 > DZERO) then
656651
tz = (particle%z - z1min) / dz1
657652
else
658653
tz = DZERO
659654
end if
660655

661-
! 5. Map to destination face space
656+
! map to destination model coords
662657
dx2 = x2max - x2min
663658
dy2 = y2max - y2min
664659
dz2 = z2max - z2min
665-
666660
if (dx2 > DZERO) then
667661
xt = x2min + tx * dx2
668662
else
669663
xt = x2min
670664
end if
671-
672665
if (dy2 > DZERO) then
673666
yt = y2min + ty * dy2
674667
else
675668
yt = y2min
676669
end if
677-
678670
if (dz2 > DZERO) then
679671
zt = z2min + tz * dz2
680672
else
681673
zt = z2min
682674
end if
683675

684-
! 6. Find which destination cell contains this position
676+
! which cell is the particle in?
685677
found = .false.
686678
do i = 1, n_candidates
687679
iexg = iexg_candidates(i)
@@ -692,28 +684,20 @@ subroutine transform_particle(this, particle, n_src, f_src, from_m1)
692684
n_dst = this%nodem1(iexg)
693685
f_dst = nint(this%auxvar(iflowface_dst, iexg))
694686
end if
695-
696687
if (point_in_face_bounds(prt_dst%dis, n_dst, f_dst, xt, yt, zt)) then
697-
! Found the destination!
698688
particle%x = xt
699689
particle%y = yt
700690
particle%z = zt
701-
particle%icu = n_dst
702-
particle%advancing = .true.
703-
particle%itrdomain(LEVEL_MODEL) = prt_dst%id
704-
particle%itrdomain(LEVEL_FEATURE) = &
705-
prt_dst%dis%get_nodenumber(particle%icu, 1)
706691
found = .true.
707692
exit
708693
end if
709694
end do
710-
711695
if (.not. found) then
712696
write (errmsg, '(a,i0,a,i0,a,3g15.6,a)') &
713697
'Particle transferring from cell ', n_src, ' face ', f_src, &
714698
' at position (', xt, yt, zt, &
715-
') not found in any destination face'
716-
call store_error(errmsg, terminate=.TRUE.)
699+
') not found in any destination cell'
700+
call pstop(1, errmsg)
717701
end if
718702

719703
deallocate (iexg_candidates)
@@ -1055,4 +1039,32 @@ function point_on_line_segment(x, y, x1, y1, x2, y2, tol) result(on_seg)
10551039
end if
10561040
end function point_on_line_segment
10571041

1042+
!> @brief Get PRT-PRT exchange from list
1043+
function GetPrtPrtExchangeFromList(list, idx) result(res)
1044+
use ListModule, only: ListType
1045+
implicit none
1046+
type(ListType), intent(inout) :: list
1047+
integer(I4B), intent(in) :: idx
1048+
class(PrtPrtExchangeType), pointer :: res
1049+
class(*), pointer :: obj
1050+
1051+
obj => list%GetItem(idx)
1052+
res => CastAsPrtPrtExchange(obj)
1053+
end function GetPrtPrtExchangeFromList
1054+
1055+
!> @brief Cast object as PRT-PRT exchange
1056+
function CastAsPrtPrtExchange(obj) result(res)
1057+
implicit none
1058+
class(*), pointer, intent(inout) :: obj
1059+
class(PrtPrtExchangeType), pointer :: res
1060+
1061+
res => null()
1062+
if (.not. associated(obj)) return
1063+
1064+
select type (obj)
1065+
class is (PrtPrtExchangeType)
1066+
res => obj
1067+
end select
1068+
end function CastAsPrtPrtExchange
1069+
10581070
end module PrtPrtExchangeModule

0 commit comments

Comments
 (0)