Skip to content

Commit 4eab65b

Browse files
Address Issues with Face Selectors (#349)
Co-authored-by: James Bruten <109733895+james-bruten-mo@users.noreply.github.com>
1 parent 1565aa4 commit 4eab65b

19 files changed

Lines changed: 1796 additions & 408 deletions

components/science/source/algorithm/sci_geometric_constants_mod.x90

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,9 @@ contains
204204
!! computing the fields for
205205
subroutine compute_face_selectors(mesh)
206206

207-
use reference_element_mod, only: S, W
208-
use sci_set_any_int_dof_kernel_mod, only: set_any_int_dof_kernel_type
209-
use sci_face_selector_kernel_mod, only: face_selector_kernel_type
207+
use sci_psykal_light_mod, only: invoke_deep_int_setval_c
208+
use sci_face_selector_kernel_mod, only: face_selector_kernel_type
209+
use sci_face_selector_halo_kernel_mod, only: face_selector_halo_kernel_type
210210

211211
implicit none
212212

@@ -220,35 +220,74 @@ contains
220220
type(integer_field_type) :: face_counter
221221
type(function_space_type), pointer :: w2h_2d_fs
222222
type(function_space_type), pointer :: w3_2d_fs
223-
integer(tik) :: id
223+
integer(kind=i_def) :: depth, max_halo_depth
224+
integer(kind=tik) :: id
224225

225226
if ( LPROF ) call start_timing( id, 'runtime_constants.geometric' )
226227

227228
twod_mesh => mesh_collection%get_mesh(mesh, TWOD)
228229
local_mesh => mesh%get_local_mesh()
229230
w2h_2d_fs => function_space_collection%get_fs(twod_mesh, 0, 0, W2H)
230231
w3_2d_fs => function_space_collection%get_fs(twod_mesh, 0, 0, W3)
232+
max_halo_depth = twod_mesh%get_halo_depth()
231233

232234
! Temporary W2H field, tracking the count for each face
233-
call face_counter%initialise( w2h_2d_fs )
235+
call face_counter%initialise(w2h_2d_fs, halo_depth=max_halo_depth)
234236

235237
call face_selector_ew_inventory%add_field( &
236-
face_selector_ew, w3_2d_fs, local_mesh &
238+
face_selector_ew, w3_2d_fs, local_mesh, halo_depth=max_halo_depth &
237239
)
238240
call face_selector_ns_inventory%add_field( &
239-
face_selector_ns, w3_2d_fs, local_mesh &
241+
face_selector_ns, w3_2d_fs, local_mesh, halo_depth=max_halo_depth &
242+
)
243+
244+
! ------------------------------------------------------------------------ !
245+
! Initialise face selectors to zero
246+
! ------------------------------------------------------------------------ !
247+
248+
call invoke_deep_int_setval_c(face_selector_ew, 0, max_halo_depth)
249+
call invoke_deep_int_setval_c(face_selector_ns, 0, max_halo_depth)
250+
251+
! ------------------------------------------------------------------------ !
252+
! Setting face selectors in owned cells
253+
! ------------------------------------------------------------------------ !
254+
255+
! Set face counter to be one for halo DoFs, but zero for owned (and annexed,
256+
! if using) DoFs. The use of annexed DoFs will be picked up by using normal
257+
! int_setval_c invoke, but need to use psykal-lite implementation to ensure
258+
! halo DoFs are set to the correct value
259+
call invoke_deep_int_setval_c(face_counter, 1, max_halo_depth)
260+
call invoke( int_setval_c(face_counter, 0) )
261+
262+
! Compute face selector in owned cell region
263+
call invoke( &
264+
face_selector_kernel_type( &
265+
face_selector_ew, face_selector_ns, &
266+
face_counter &
267+
) &
240268
)
241269

242-
call invoke( int_setval_c(face_counter, 0), &
243-
! Do West and South faces for every cell
244-
int_setval_c(face_selector_ew, 1), &
245-
int_setval_c(face_selector_ns, 1), &
246-
set_any_int_dof_kernel_type(face_counter, W, 1), &
247-
set_any_int_dof_kernel_type(face_counter, S, 1), &
248-
! Determine where North and East faces are needed
249-
face_selector_kernel_type(face_selector_ew, &
250-
face_selector_ns, &
251-
face_counter ) )
270+
! ------------------------------------------------------------------------ !
271+
! Setting face selectors in halos
272+
! ------------------------------------------------------------------------ !
273+
274+
! Set face counter to be zero for halo DoFs, but one for owned (and annexed,
275+
! if using) DoFs. The use of annexed DoFs will be picked up by using normal
276+
! int_setval_c invoke, but need to use psykal-lite implementation to ensure
277+
! halo DoFs are set to the correct value
278+
call invoke_deep_int_setval_c(face_counter, 0, max_halo_depth)
279+
call invoke( int_setval_c(face_counter, 1) )
280+
281+
! Loop through different halo depths, setting the face selectors in the
282+
! halos at each depth as we go
283+
do depth = 1, max_halo_depth
284+
call invoke( &
285+
face_selector_halo_kernel_type( &
286+
face_selector_ew, face_selector_ns, &
287+
face_counter, depth &
288+
) &
289+
)
290+
end do
252291

253292
if ( LPROF ) call stop_timing( id, 'runtime_constants.geometric' )
254293

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
2+
!-----------------------------------------------------------------------------
3+
! (c) Crown copyright Met Office. All rights reserved.
4+
! The file LICENCE, distributed with this code, contains details of the terms
5+
! under which the code may be used.
6+
!-----------------------------------------------------------------------------
7+
!> @details Creates "face selector" fields to avoid calculation duplication on
8+
!! faces when iterating over columns
9+
module sci_face_selector_halo_kernel_mod
10+
11+
use argument_mod, only: arg_type, &
12+
GH_FIELD, GH_WRITE, &
13+
GH_REAL, GH_INTEGER, &
14+
HALO_CELL_COLUMN
15+
use constants_mod, only: i_def
16+
use fs_continuity_mod, only: W3, W2H
17+
use kernel_mod, only: kernel_type
18+
use sci_face_selector_support_mod, only: compute_face_selector
19+
20+
implicit none
21+
22+
private
23+
24+
!---------------------------------------------------------------------------
25+
! Public types
26+
!---------------------------------------------------------------------------
27+
!> The type declaration for the kernel. Contains the metadata needed by the
28+
!> PSy layer.
29+
!>
30+
type, public, extends(kernel_type) :: face_selector_halo_kernel_type
31+
private
32+
type(arg_type) :: meta_args(3) = (/ &
33+
arg_type(GH_FIELD, GH_INTEGER, GH_WRITE, W3), &
34+
arg_type(GH_FIELD, GH_INTEGER, GH_WRITE, W3), &
35+
arg_type(GH_FIELD, GH_INTEGER, GH_WRITE, W2H) &
36+
/)
37+
integer :: operates_on = HALO_CELL_COLUMN
38+
contains
39+
procedure, nopass :: face_selector_halo_code
40+
end type
41+
42+
!---------------------------------------------------------------------------
43+
! Contained functions/subroutines
44+
!---------------------------------------------------------------------------
45+
public :: face_selector_halo_code
46+
47+
contains
48+
49+
!> @details Creates "face selector" fields to avoid calculation duplication on
50+
!! faces when iterating over columns
51+
!> @param[in] nlayers The number of layers
52+
!> @param[in,out] face_selector_ew The East-West face selector. It is a W3
53+
!! integer field, which contains 2 when
54+
!! iterating over the East and West faces of a
55+
!! cell, or 1 when just the West face.
56+
!> @param[in,out] face_selector_ns The North-South face selector. It is a W3
57+
!! integer field, which contains 2 when
58+
!! iterating over the North and South faces of
59+
!! a cell, or 1 when just the South face.
60+
!> @param[in,out] face_counter An integer W2H field, counting the number of
61+
!! times that each face has been iterated over
62+
!> @param[in] ndf_w3 Num of DoFs for W3 per cell
63+
!> @param[in] undf_w3 Num of DoFs for this partition for W3
64+
!> @param[in] map_w3 DoF-map for W3 in base cells
65+
!> @param[in] ndf_w2h Num of DoFs for W2h per cell
66+
!> @param[in] undf_w2h Num of DoFs for this partition for W2h
67+
!> @param[in] map_w2h DoF-map for W2h in base cells
68+
subroutine face_selector_halo_code( nlayers, &
69+
face_selector_ew, &
70+
face_selector_ns, &
71+
face_counter, &
72+
ndf_w3, undf_w3, map_w3, &
73+
ndf_w2h, undf_w2h, map_w2h &
74+
)
75+
76+
implicit none
77+
78+
! Arguments
79+
integer(kind=i_def), intent(in) :: nlayers
80+
integer(kind=i_def), intent(in) :: ndf_w3, undf_w3
81+
integer(kind=i_def), intent(in) :: ndf_w2h, undf_w2h
82+
83+
integer(kind=i_def), intent(in) :: map_w3(ndf_w3)
84+
integer(kind=i_def), intent(in) :: map_w2h(ndf_w2h)
85+
86+
integer(kind=i_def), intent(inout) :: face_selector_ew(undf_w3)
87+
integer(kind=i_def), intent(inout) :: face_selector_ns(undf_w3)
88+
integer(kind=i_def), intent(inout) :: face_counter(undf_w2h)
89+
90+
call compute_face_selector( &
91+
face_selector_ew, &
92+
face_selector_ns, &
93+
face_counter, &
94+
ndf_w3, undf_w3, map_w3, &
95+
ndf_w2h, undf_w2h, map_w2h &
96+
)
97+
98+
end subroutine face_selector_halo_code
99+
100+
end module sci_face_selector_halo_kernel_mod

components/science/source/kernel/algebra/sci_face_selector_kernel_mod.F90

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@
88
!! faces when iterating over columns
99
module sci_face_selector_kernel_mod
1010

11-
use argument_mod, only: arg_type, &
12-
GH_FIELD, GH_SCALAR, &
13-
GH_REAL, GH_INTEGER, &
14-
GH_WRITE, GH_READ, &
15-
CELL_COLUMN
16-
use constants_mod, only: i_def
17-
use fs_continuity_mod, only: W3, W2H
18-
use kernel_mod, only: kernel_type
19-
use reference_element_mod, only: E, N
11+
use argument_mod, only: arg_type, &
12+
GH_FIELD, GH_WRITE, &
13+
GH_REAL, GH_INTEGER, &
14+
CELL_COLUMN
15+
use constants_mod, only: i_def
16+
use fs_continuity_mod, only: W3, W2H
17+
use kernel_mod, only: kernel_type
18+
use sci_face_selector_support_mod, only: compute_face_selector
2019

2120
implicit none
2221

@@ -30,11 +29,11 @@ module sci_face_selector_kernel_mod
3029
!>
3130
type, public, extends(kernel_type) :: face_selector_kernel_type
3231
private
33-
type(arg_type) :: meta_args(3) = (/ &
34-
arg_type(GH_FIELD, GH_INTEGER, GH_WRITE, W3), &
35-
arg_type(GH_FIELD, GH_INTEGER, GH_WRITE, W3), &
36-
arg_type(GH_FIELD, GH_INTEGER, GH_WRITE, W2H) &
37-
/)
32+
type(arg_type) :: meta_args(3) = (/ &
33+
arg_type(GH_FIELD, GH_INTEGER, GH_WRITE, W3), &
34+
arg_type(GH_FIELD, GH_INTEGER, GH_WRITE, W3), &
35+
arg_type(GH_FIELD, GH_INTEGER, GH_WRITE, W2H) &
36+
/)
3837
integer :: operates_on = CELL_COLUMN
3938
contains
4039
procedure, nopass :: face_selector_code
@@ -88,19 +87,13 @@ subroutine face_selector_code( nlayers, &
8887
integer(kind=i_def), intent(inout) :: face_selector_ns(undf_w3)
8988
integer(kind=i_def), intent(inout) :: face_counter(undf_w2h)
9089

91-
! If the East face hasn't been visited yet, this cell will compute the
92-
! calculation for that face.
93-
if (face_counter(map_w2h(E)) == 0) then
94-
face_selector_ew(map_w3(1)) = 2
95-
face_counter(map_w2h(E)) = 1
96-
end if
97-
98-
! If the North face hasn't been visited yet, this cell will compute the
99-
! calculation for that face.
100-
if (face_counter(map_w2h(N)) == 0) then
101-
face_selector_ns(map_w3(1)) = 2
102-
face_counter(map_w2h(N)) = 1
103-
end if
90+
call compute_face_selector( &
91+
face_selector_ew, &
92+
face_selector_ns, &
93+
face_counter, &
94+
ndf_w3, undf_w3, map_w3, &
95+
ndf_w2h, undf_w2h, map_w2h &
96+
)
10497

10598
end subroutine face_selector_code
10699

0 commit comments

Comments
 (0)