|
6 | 6 |
|
7 | 7 | Fill open boundary halo regions by filling boundary conditions on field faces with `open_fill`.
|
8 | 8 | """
|
9 |
| -function fill_open_boundary_regions!(field, boundary_conditions, indices, loc, grid, args...; kwargs...) |
| 9 | +function fill_open_boundary_regions!(field, boundary_conditions, indices, loc, grid, args...; only_local_halos = false, kwargs...) |
10 | 10 | arch = architecture(grid)
|
11 | 11 |
|
12 |
| - left_bc = left_velocity_open_boundary_condition(boundary_conditions, loc) |
13 |
| - right_bc = right_velocity_open_boundary_condition(boundary_conditions, loc) |
| 12 | + # gets `fill_halo!`, the function which fills open boundaries at `loc` |
| 13 | + # The underlying assumption is that open boundaries are uniquely defined by the location `loc`: |
| 14 | + # (Face, Center, Center) -> fill west and east |
| 15 | + # (Center, Face, Center) -> fill south and north |
| 16 | + # (Center, Center, Face) -> fill bottom and top |
| 17 | + fill_halo! = get_open_halo_filling_functions(loc) |
14 | 18 |
|
15 |
| - # gets `open_fill`, the function which fills open boundaries at `loc`, as well as `regular_fill` |
16 |
| - # which is the function which fills non-open boundaries at `loc` which informs `fill_halo_size` |
17 |
| - open_fill, regular_fill = get_open_halo_filling_functions(loc) |
18 |
| - fill_size = fill_halo_size(field, regular_fill, indices, boundary_conditions, loc, grid) |
| 19 | + left_bc = left_open_boundary_condition(boundary_conditions, loc) |
| 20 | + right_bc = right_open_boundary_condition(boundary_conditions, loc) |
19 | 21 |
|
20 |
| - launch!(arch, grid, fill_size, open_fill, field, left_bc, right_bc, loc, grid, args) |
| 22 | + bcs_tuple = (left_bc, right_bc) |
21 | 23 |
|
22 |
| - return nothing |
23 |
| -end |
24 |
| - |
25 |
| -fill_open_boundary_regions!(fields::NTuple, boundary_conditions, indices, loc, grid, args...; kwargs...) = |
26 |
| - [fill_open_boundary_regions!(field, boundary_conditions[n], indices, loc[n], grid, args...; kwargs...) for (n, field) in enumerate(fields)] |
27 |
| - |
28 |
| -# for regular halo fills |
29 |
| -@inline left_velocity_open_boundary_condition(boundary_condition, loc) = nothing |
30 |
| -@inline left_velocity_open_boundary_condition(boundary_conditions, ::Tuple{Face, Center, Center}) = boundary_conditions.west |
31 |
| -@inline left_velocity_open_boundary_condition(boundary_conditions, ::Tuple{Center, Face, Center}) = boundary_conditions.south |
32 |
| -@inline left_velocity_open_boundary_condition(boundary_conditions, ::Tuple{Center, Center, Face}) = boundary_conditions.bottom |
33 |
| - |
34 |
| -@inline right_velocity_open_boundary_condition(boundary_conditions, loc) = nothing |
35 |
| -@inline right_velocity_open_boundary_condition(boundary_conditions, ::Tuple{Face, Center, Center}) = boundary_conditions.east |
36 |
| -@inline right_velocity_open_boundary_condition(boundary_conditions, ::Tuple{Center, Face, Center}) = boundary_conditions.north |
37 |
| -@inline right_velocity_open_boundary_condition(boundary_conditions, ::Tuple{Center, Center, Face}) = boundary_conditions.top |
| 24 | + if !isnothing(fill_halo!) && any(!isnothing, bcs_tuple) |
38 | 25 |
|
39 |
| -# for multi region halo fills |
40 |
| -@inline left_velocity_open_boundary_condition(boundary_conditions::Tuple, ::Tuple{Face, Center, Center}) = @inbounds boundary_conditions[1] |
41 |
| -@inline left_velocity_open_boundary_condition(boundary_conditions::Tuple, ::Tuple{Center, Face, Center}) = @inbounds boundary_conditions[1] |
42 |
| -@inline left_velocity_open_boundary_condition(boundary_conditions::Tuple, ::Tuple{Center, Center, Face}) = @inbounds boundary_conditions[1] |
| 26 | + # Overwrite the `only_local_halos` keyword argument, because open boundaries |
| 27 | + # are always local boundaries that do not require communication |
| 28 | + only_local_halos = true |
43 | 29 |
|
44 |
| -@inline right_velocity_open_boundary_condition(boundary_conditions::Tuple, ::Tuple{Face, Center, Center}) = @inbounds boundary_conditions[2] |
45 |
| -@inline right_velocity_open_boundary_condition(boundary_conditions::Tuple, ::Tuple{Center, Face, Center}) = @inbounds boundary_conditions[2] |
46 |
| -@inline right_velocity_open_boundary_condition(boundary_conditions::Tuple, ::Tuple{Center, Center, Face}) = @inbounds boundary_conditions[2] |
| 30 | + fill_halo_event!(field, fill_halo!, bcs_tuple, indices, loc, arch, grid, args...; only_local_halos, kwargs...) |
| 31 | + end |
47 | 32 |
|
48 |
| -@inline get_open_halo_filling_functions(loc) = _no_fill!, _no_fill! |
49 |
| -@inline get_open_halo_filling_functions(::Tuple{Face, Center, Center}) = _fill_west_and_east_open_halo!, fill_west_and_east_halo! |
50 |
| -@inline get_open_halo_filling_functions(::Tuple{Center, Face, Center}) = _fill_south_and_north_open_halo!, fill_south_and_north_halo! |
51 |
| -@inline get_open_halo_filling_functions(::Tuple{Center, Center, Face}) = _fill_bottom_and_top_open_halo!, fill_bottom_and_top_halo! |
52 |
| - |
53 |
| -@kernel _no_fill!(args...) = nothing |
54 |
| - |
55 |
| -@inline fill_halo_size(field, ::typeof(_no_fill!), args...) = (0, 0) |
56 |
| - |
57 |
| -@kernel function _fill_west_and_east_open_halo!(c, west_bc, east_bc, loc, grid, args) |
58 |
| - j, k = @index(Global, NTuple) |
59 |
| - _fill_west_open_halo!(j, k, grid, c, west_bc, loc, args...) |
60 |
| - _fill_east_open_halo!(j, k, grid, c, east_bc, loc, args...) |
| 33 | + return nothing |
61 | 34 | end
|
62 | 35 |
|
63 |
| -@kernel function _fill_south_and_north_open_halo!(c, south_bc, north_bc, loc, grid, args) |
64 |
| - i, k = @index(Global, NTuple) |
65 |
| - _fill_south_open_halo!(i, k, grid, c, south_bc, loc, args...) |
66 |
| - _fill_north_open_halo!(i, k, grid, c, north_bc, loc, args...) |
67 |
| -end |
| 36 | +@inline get_open_halo_filling_functions(loc) = nothing |
| 37 | +@inline get_open_halo_filling_functions(::Tuple{Face, Center, Center}) = fill_west_and_east_halo! |
| 38 | +@inline get_open_halo_filling_functions(::Tuple{Center, Face, Center}) = fill_south_and_north_halo! |
| 39 | +@inline get_open_halo_filling_functions(::Tuple{Center, Center, Face}) = fill_bottom_and_top_halo! |
68 | 40 |
|
69 |
| -@kernel function _fill_bottom_and_top_open_halo!(c, bottom_bc, top_bc, loc, grid, args) |
70 |
| - i, j = @index(Global, NTuple) |
71 |
| - _fill_bottom_open_halo!(i, j, grid, c, bottom_bc, loc, args...) |
72 |
| - _fill_top_open_halo!(i, j, grid, c, top_bc, loc, args...) |
| 41 | +function fill_open_boundary_regions!(fields::Tuple, boundary_conditions, indices, loc, grid, args...; kwargs...) |
| 42 | + for n in eachindex(fields) |
| 43 | + fill_open_boundary_regions!(fields[n], boundary_conditions[n], indices, loc[n], grid, args...; kwargs...) |
| 44 | + end |
| 45 | + return nothing |
73 | 46 | end
|
74 | 47 |
|
75 |
| -# Generic fallback |
76 |
| - |
77 |
| -@inline _fill_west_open_halo!(j, k, grid, c, bc, loc, args...) = nothing |
78 |
| -@inline _fill_east_open_halo!(j, k, grid, c, bc, loc, args...) = nothing |
79 |
| -@inline _fill_south_open_halo!(i, k, grid, c, bc, loc, args...) = nothing |
80 |
| -@inline _fill_north_open_halo!(i, k, grid, c, bc, loc, args...) = nothing |
81 |
| -@inline _fill_bottom_open_halo!(i, j, grid, c, bc, loc, args...) = nothing |
82 |
| -@inline _fill_top_open_halo!(i, j, grid, c, bc, loc, args...) = nothing |
83 |
| - |
84 |
| -# Open boundary condition fallback |
85 |
| - |
86 |
| -@inline _fill_west_open_halo!(j, k, grid, c, bc::OBC, loc, args...) = @inbounds c[1, j, k] = getbc(bc, j, k, grid, args...) |
87 |
| -@inline _fill_east_open_halo!(j, k, grid, c, bc::OBC, loc, args...) = @inbounds c[grid.Nx + 1, j, k] = getbc(bc, j, k, grid, args...) |
88 |
| -@inline _fill_south_open_halo!(i, k, grid, c, bc::OBC, loc, args...) = @inbounds c[i, 1, k] = getbc(bc, i, k, grid, args...) |
89 |
| -@inline _fill_north_open_halo!(i, k, grid, c, bc::OBC, loc, args...) = @inbounds c[i, grid.Ny + 1, k] = getbc(bc, i, k, grid, args...) |
90 |
| -@inline _fill_bottom_open_halo!(i, j, grid, c, bc::OBC, loc, args...) = @inbounds c[i, j, 1] = getbc(bc, i, j, grid, args...) |
91 |
| -@inline _fill_top_open_halo!(i, j, grid, c, bc::OBC, loc, args...) = @inbounds c[i, j, grid.Nz + 1] = getbc(bc, i, j, grid, args...) |
92 |
| - |
93 |
| -# Regular boundary fill defaults |
94 |
| - |
95 |
| -@inline _fill_west_halo!(j, k, grid, c, bc::OBC, loc, args...) = _fill_west_open_halo!(j, k, grid, c, bc, loc, args...) |
96 |
| -@inline _fill_east_halo!(j, k, grid, c, bc::OBC, loc, args...) = _fill_east_open_halo!(j, k, grid, c, bc, loc, args...) |
97 |
| -@inline _fill_south_halo!(i, k, grid, c, bc::OBC, loc, args...) = _fill_south_open_halo!(i, k, grid, c, bc, loc, args...) |
98 |
| -@inline _fill_north_halo!(i, k, grid, c, bc::OBC, loc, args...) = _fill_north_open_halo!(i, k, grid, c, bc, loc, args...) |
99 |
| -@inline _fill_bottom_halo!(i, j, grid, c, bc::OBC, loc, args...) = _fill_bottom_open_halo!(i, j, grid, c, bc, loc, args...) |
100 |
| -@inline _fill_top_halo!(i, j, grid, c, bc::OBC, loc, args...) = _fill_top_open_halo!(i, j, grid, c, bc, loc, args...) |
101 |
| - |
102 |
| -# Regular boundary fill for wall normal velocities |
103 |
| - |
104 |
| -@inline _fill_west_halo!(j, k, grid, c, bc::OBC, ::Tuple{Face, <:Any, <:Any}, args...) = nothing |
105 |
| -@inline _fill_east_halo!(j, k, grid, c, bc::OBC, ::Tuple{Face, <:Any, <:Any}, args...) = nothing |
106 |
| -@inline _fill_south_halo!(i, k, grid, c, bc::OBC, ::Tuple{<:Any, Face, <:Any}, args...) = nothing |
107 |
| -@inline _fill_north_halo!(i, k, grid, c, bc::OBC, ::Tuple{<:Any, Face, <:Any}, args...) = nothing |
108 |
| -@inline _fill_bottom_halo!(i, j, grid, c, bc::OBC, ::Tuple{<:Any, <:Any, Face}, args...) = nothing |
109 |
| -@inline _fill_top_halo!(i, j, grid, c, bc::OBC, ::Tuple{<:Any, <:Any, Face}, args...) = nothing |
| 48 | +@inline retrieve_open_bc(bc::OBC) = bc |
| 49 | +@inline retrieve_open_bc(bc) = nothing |
| 50 | + |
| 51 | +# for regular halo fills, return nothing if the BC is not an OBC |
| 52 | +@inline left_open_boundary_condition(boundary_condition, loc) = nothing |
| 53 | +@inline left_open_boundary_condition(boundary_conditions, ::Tuple{Face, Center, Center}) = retrieve_open_bc(boundary_conditions.west) |
| 54 | +@inline left_open_boundary_condition(boundary_conditions, ::Tuple{Center, Face, Center}) = retrieve_open_bc(boundary_conditions.south) |
| 55 | +@inline left_open_boundary_condition(boundary_conditions, ::Tuple{Center, Center, Face}) = retrieve_open_bc(boundary_conditions.bottom) |
| 56 | + |
| 57 | +@inline right_open_boundary_condition(boundary_conditions, loc) = nothing |
| 58 | +@inline right_open_boundary_condition(boundary_conditions, ::Tuple{Face, Center, Center}) = retrieve_open_bc(boundary_conditions.east) |
| 59 | +@inline right_open_boundary_condition(boundary_conditions, ::Tuple{Center, Face, Center}) = retrieve_open_bc(boundary_conditions.north) |
| 60 | +@inline right_open_boundary_condition(boundary_conditions, ::Tuple{Center, Center, Face}) = retrieve_open_bc(boundary_conditions.top) |
| 61 | + |
| 62 | +# Opern boundary fill |
| 63 | +@inline _fill_west_halo!(j, k, grid, c, bc::OBC, loc, args...) = @inbounds c[1, j, k] = getbc(bc, j, k, grid, args...) |
| 64 | +@inline _fill_east_halo!(j, k, grid, c, bc::OBC, loc, args...) = @inbounds c[grid.Nx + 1, j, k] = getbc(bc, j, k, grid, args...) |
| 65 | +@inline _fill_south_halo!(i, k, grid, c, bc::OBC, loc, args...) = @inbounds c[i, 1, k] = getbc(bc, i, k, grid, args...) |
| 66 | +@inline _fill_north_halo!(i, k, grid, c, bc::OBC, loc, args...) = @inbounds c[i, grid.Ny + 1, k] = getbc(bc, i, k, grid, args...) |
| 67 | +@inline _fill_bottom_halo!(i, j, grid, c, bc::OBC, loc, args...) = @inbounds c[i, j, 1] = getbc(bc, i, j, grid, args...) |
| 68 | +@inline _fill_top_halo!(i, j, grid, c, bc::OBC, loc, args...) = @inbounds c[i, j, grid.Nz + 1] = getbc(bc, i, j, grid, args...) |
0 commit comments