@@ -30,3 +30,55 @@ function fill_halo_regions!(c::AbstractArray, fieldbcs, arch, grid, args...)
30
30
fill_top_halo! (c, fieldbcs. z. top, arch, grid, args... )
31
31
return nothing
32
32
end
33
+
34
+ # ####
35
+ # #### Halo filling for flux, periodic, and no-penetration boundary conditions.
36
+ # ####
37
+
38
+ # For flux boundary conditions we fill halos as for a *no-flux* boundary condition, and add the
39
+ # flux divergence associated with the flux boundary condition in a separate step. Note that
40
+ # ranges are used to reference the data copied into halos, as this produces views of the correct
41
+ # dimension (eg size = (1, Ny, Nz) for the west halos).
42
+
43
+ _fill_west_halo! (c, :: FBC , H, N) = @views @. c. parent[1 : H, :, :] = c. parent[1 + H: 1 + H, :, :]
44
+ _fill_south_halo! (c, :: FBC , H, N) = @views @. c. parent[:, 1 : H, :] = c. parent[:, 1 + H: 1 + H, :]
45
+ _fill_bottom_halo! (c, :: FBC , H, N) = @views @. c. parent[:, :, 1 : H] = c. parent[:, :, 1 + H: 1 + H]
46
+
47
+ _fill_east_halo! (c, :: FBC , H, N) = @views @. c. parent[N+ H+ 1 : N+ 2 H, :, :] = c. parent[N+ H: N+ H, :, :]
48
+ _fill_north_halo! (c, :: FBC , H, N) = @views @. c. parent[:, N+ H+ 1 : N+ 2 H, :] = c. parent[:, N+ H: N+ H, :]
49
+ _fill_top_halo! (c, :: FBC , H, N) = @views @. c. parent[:, :, N+ H+ 1 : N+ 2 H] = c. parent[:, :, N+ H: N+ H]
50
+
51
+ # Periodic boundary conditions
52
+ _fill_west_halo! (c, :: PBC , H, N) = @views @. c. parent[1 : H, :, :] = c. parent[N+ 1 : N+ H, :, :]
53
+ _fill_south_halo! (c, :: PBC , H, N) = @views @. c. parent[:, 1 : H, :] = c. parent[:, N+ 1 : N+ H, :]
54
+ _fill_bottom_halo! (c, :: PBC , H, N) = @views @. c. parent[:, :, 1 : H] = c. parent[:, :, N+ 1 : N+ H]
55
+
56
+ _fill_east_halo! (c, :: PBC , H, N) = @views @. c. parent[N+ H+ 1 : N+ 2 H, :, :] = c. parent[1 + H: 2 H, :, :]
57
+ _fill_north_halo! (c, :: PBC , H, N) = @views @. c. parent[:, N+ H+ 1 : N+ 2 H, :] = c. parent[:, 1 + H: 2 H, :]
58
+ _fill_top_halo! (c, :: PBC , H, N) = @views @. c. parent[:, :, N+ H+ 1 : N+ 2 H] = c. parent[:, :, 1 + H: 2 H]
59
+
60
+ # Recall that, by convention, the first grid point (k=1) in an array with a no-penetration boundary
61
+ # condition lies on the boundary, where as the last grid point (k=Nz) lies in the domain.
62
+
63
+ _fill_west_halo! (c, :: NPBC , H, N) = @views @. c. parent[1 : 1 + H, :, :] = 0
64
+ _fill_south_halo! (c, :: NPBC , H, N) = @views @. c. parent[:, 1 : 1 + H, :] = 0
65
+ _fill_bottom_halo! (c, :: NPBC , H, N) = @views @. c. parent[:, :, 1 : 1 + H] = 0
66
+
67
+ _fill_east_halo! (c, :: NPBC , H, N) = @views @. c. parent[N+ H+ 1 : N+ 2 H, :, :] = 0
68
+ _fill_north_halo! (c, :: NPBC , H, N) = @views @. c. parent[:, N+ H+ 1 : N+ 2 H, :] = 0
69
+ _fill_top_halo! (c, :: NPBC , H, N) = @views @. c. parent[:, :, N+ H+ 1 : N+ 2 H] = 0
70
+
71
+ # Generate functions that implement flux, periodic, and no-penetration boundary conditions
72
+ sides = (:west , :east , :south , :north , :top , :bottom )
73
+ coords = (:x , :x , :y , :y , :z , :z )
74
+
75
+ for (x, side) in zip (coords, sides)
76
+ outername = Symbol (:fill_ , side, :_halo! )
77
+ innername = Symbol (:_fill_ , side, :_halo! )
78
+ H = Symbol (:H , x)
79
+ N = Symbol (:N , x)
80
+ @eval begin
81
+ $ outername (c, bc:: Union{FBC, PBC, NPBC} , arch, grid, args... ) =
82
+ $ innername (c, bc, grid.$ (H), grid.$ (N))
83
+ end
84
+ end
0 commit comments