`no method matching fill_halo_kernel!` error when building `Fields` with explicit boundary conditions
The following fails on main, possibly due to the recently refactor:
julia> using Oceananigans
julia> grid = RectilinearGrid(topology=(Bounded, Bounded, Bounded), size=(4, 4, 4), extent=(1, 1, 1));
julia> boundary_conditions = FieldBoundaryConditions(top = GradientBoundaryCondition(1));
julia> b = CenterField(grid; boundary_conditions)
ERROR: MethodError: no method matching fill_halo_kernel!(::Oceananigans.BoundaryConditions.BottomAndTop, ::Oceananigans.BoundaryConditions.DefaultBoundaryCondition{…}, ::RectilinearGrid{…}, ::Symbol, ::Tuple{…}, ::OffsetArrays.OffsetArray{…}, ::Tuple{})
Closest candidates are:
fill_halo_kernel!(::Oceananigans.BoundaryConditions.BottomAndTop, ::BoundaryCondition{<:Oceananigans.BoundaryConditions.MultiRegionCommunication}, ::Any, ::Any, ::Any, ::Any, ::Any)
@ Oceananigans ~/repos/Oceananigans.jl/src/BoundaryConditions/fill_halo_kernels.jl:162
fill_halo_kernel!(::Oceananigans.BoundaryConditions.BottomAndTop, ::Oceananigans.BoundaryConditions.DistributedCommunicationBoundaryCondition, ::Any, ::Any, ::Any, ::Any, ::Any)
@ Oceananigans ~/repos/Oceananigans.jl/src/BoundaryConditions/fill_halo_kernels.jl:148
fill_halo_kernel!(::Oceananigans.BoundaryConditions.BottomAndTop, ::BoundaryCondition{<:Oceananigans.BoundaryConditions.Periodic}, ::Any, ::Any, ::Any, ::Any, ::Any)
@ Oceananigans ~/repos/Oceananigans.jl/src/BoundaryConditions/fill_halo_kernels.jl:132
...
Stacktrace:
[1] fill_halo_kernels
@ ~/repos/Oceananigans.jl/src/BoundaryConditions/fill_halo_kernels.jl:54 [inlined]
[2] construct_boundary_conditions_kernels(bcs::FieldBoundaryConditions{…}, data::OffsetArrays.OffsetArray{…}, grid::RectilinearGrid{…}, loc::Tuple{…}, indices::Tuple{…})
@ Oceananigans.BoundaryConditions ~/repos/Oceananigans.jl/src/BoundaryConditions/fill_halo_kernels.jl:19
[3] #construct_regionally#82
@ ~/repos/Oceananigans.jl/src/Utils/multi_region_transformation.jl:159 [inlined]
[4] construct_regionally
@ ~/repos/Oceananigans.jl/src/Utils/multi_region_transformation.jl:154 [inlined]
[5] macro expansion
@ ~/repos/Oceananigans.jl/src/Utils/multi_region_transformation.jl:244 [inlined]
[6] (Field{…})(grid::RectilinearGrid{…}, data::OffsetArrays.OffsetArray{…}, bcs::FieldBoundaryConditions{…}, indices::Tuple{…}, op::Nothing, status::Nothing, buffers::Nothing)
@ Oceananigans.Fields ~/repos/Oceananigans.jl/src/Fields/field.jl:35
[7] Field
@ ~/repos/Oceananigans.jl/src/Fields/field.jl:106 [inlined]
[8] Field(loc::Tuple{…}, grid::RectilinearGrid{…}, T::DataType; indices::Tuple{…}, data::OffsetArrays.OffsetArray{…}, boundary_conditions::FieldBoundaryConditions{…}, operand::Nothing, status::Nothing)
@ Oceananigans.Fields ~/repos/Oceananigans.jl/src/Fields/field.jl:196
[9] CenterField
@ ~/repos/Oceananigans.jl/src/Fields/field.jl:208 [inlined]
I think you are not meant to use the FieldBoundaryConditions like that, but specifying a grid and a location always.
Also on version 0.97.8
julia> grid = RectilinearGrid(topology=(Bounded, Bounded, Bounded), size=(4, 4, 4), extent=(1, 1, 1));
julia> bcs = boundary_conditions = FieldBoundaryConditions(top = GradientBoundaryCondition(1));
julia> b = CenterField(grid; boundary_conditions)
4×4×4 Field{Center, Center, Center} on RectilinearGrid on CPU
├── grid: 4×4×4 RectilinearGrid{Float64, Bounded, Bounded, Bounded} on CPU with 3×3×3 halo
├── boundary conditions: FieldBoundaryConditions
│ └── west: Default, east: Default, south: Default, north: Default, bottom: Default, top: Gradient, immersed: Default
└── data: 10×10×10 OffsetArray(::Array{Float64, 3}, -2:7, -2:7, -2:7) with eltype Float64 with indices -2:7×-2:7×-2:7
└── max=0.0, min=0.0, mean=0.0
julia> b.boundary_conditions
Oceananigans.FieldBoundaryConditions, with boundary conditions
├── west: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── east: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── south: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── north: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── bottom: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
├── top: GradientBoundaryCondition: 1
└── immersed: DefaultBoundaryCondition (FluxBoundaryCondition: Nothing)
julia> Oceananigans.BoundaryConditions.fill_halo_regions!(b)
ERROR: MethodError: no method matching _fill_bottom_halo!(::Int64, ::Int64, ::RectilinearGrid{…}, ::OffsetArrays.OffsetArray{…}, ::Oceananigans.BoundaryConditions.DefaultBoundaryCondition{…}, ::Tuple{…})
Closest candidates are:
_fill_bottom_halo!(::Any, ::Any, ::Any, ::Nothing, ::Any...)
@ Oceananigans ~/development/Oceananigans.jl/src/BoundaryConditions/fill_halo_regions_nothing.jl:16
_fill_bottom_halo!(::Any, ::Any, ::Any, ::Any, ::Nothing, ::Any...)
@ Oceananigans ~/development/Oceananigans.jl/src/BoundaryConditions/fill_halo_regions_nothing.jl:14
_fill_bottom_halo!(::Any, ::Any, ::Any, ::Any, ::BoundaryCondition{<:Oceananigans.BoundaryConditions.Open{<:Oceananigans.BoundaryConditions.FlatExtrapolation}}, ::Any, ::Any, ::Any)
@ Oceananigans ~/development/Oceananigans.jl/src/BoundaryConditions/flat_extrapolation_open_boundary_matching_scheme.jl:122
...
Stacktrace:
[1] macro expansion
@ ~/development/Oceananigans.jl/src/BoundaryConditions/fill_halo_regions.jl:216 [inlined]
[2] cpu__fill_bottom_and_top_halo!
@ ~/.julia/packages/KernelAbstractions/lGrz7/src/macros.jl:306 [inlined]
[3] __thread_run(tid::Int64, len::Int64, rem::Int64, obj::KernelAbstractions.Kernel{…}, ndrange::Nothing, iterspace::KernelAbstractions.NDIteration.NDRange{…}, args::Tuple{…}, dynamic::KernelAbstractions.NDIteration.DynamicCheck)
@ KernelAbstractions ~/.julia/packages/KernelAbstractions/lGrz7/src/cpu.jl:145
[4] __run(obj::KernelAbstractions.Kernel{…}, ndrange::Nothing, iterspace::KernelAbstractions.NDIteration.NDRange{…}, args::Tuple{…}, dynamic::KernelAbstractions.NDIteration.DynamicCheck, static_threads::Bool)
@ KernelAbstractions ~/.julia/packages/KernelAbstractions/lGrz7/src/cpu.jl:112
[5] (::KernelAbstractions.Kernel{…})(::OffsetArrays.OffsetArray{…}, ::Vararg{…}; ndrange::Nothing, workgroupsize::Nothing)
@ KernelAbstractions ~/.julia/packages/KernelAbstractions/lGrz7/src/cpu.jl:46
[6] (::KernelAbstractions.Kernel{…})(::OffsetArrays.OffsetArray{…}, ::Vararg{…})
@ KernelAbstractions ~/.julia/packages/KernelAbstractions/lGrz7/src/cpu.jl:39
[7] _launch!(::CPU, ::RectilinearGrid{…}, ::Oceananigans.Utils.KernelParameters{…}, ::Function, ::OffsetArrays.OffsetArray{…}, ::Oceananigans.BoundaryConditions.DefaultBoundaryCondition{…}, ::Vararg{…}; exclude_periphery::Bool, reduced_dimensions::Tuple{}, active_cells_map::Nothing)
@ Oceananigans.Utils ~/development/Oceananigans.jl/src/Utils/kernel_launching.jl:376
[8] _launch!
@ ~/development/Oceananigans.jl/src/Utils/kernel_launching.jl:363 [inlined]
[9] launch!
@ ~/development/Oceananigans.jl/src/Utils/kernel_launching.jl:340 [inlined]
[10] fill_bottom_and_top_halo!(::OffsetArrays.OffsetArray{…}, ::Oceananigans.BoundaryConditions.DefaultBoundaryCondition{…}, ::BoundaryCondition{…}, ::Symbol, ::Tuple{…}, ::Tuple{…}, ::CPU, ::RectilinearGrid{…}; only_local_halos::Bool, kwargs::@Kwargs{…})
@ Oceananigans.BoundaryConditions ~/development/Oceananigans.jl/src/BoundaryConditions/fill_halo_regions.jl:341
[11] fill_halo_event!(::OffsetArrays.OffsetArray{…}, ::Function, ::Tuple{…}, ::Tuple{…}, ::Tuple{…}, ::CPU, ::RectilinearGrid{…}; async::Bool, kwargs::@Kwargs{…})
@ Oceananigans.BoundaryConditions ~/development/Oceananigans.jl/src/BoundaryConditions/fill_halo_regions.jl:79
[12] fill_halo_regions!(::OffsetArrays.OffsetArray{…}, ::FieldBoundaryConditions{…}, ::Tuple{…}, ::Tuple{…}, ::RectilinearGrid{…}; fill_boundary_normal_velocities::Bool, kwargs::@Kwargs{…})
@ Oceananigans.BoundaryConditions ~/development/Oceananigans.jl/src/BoundaryConditions/fill_halo_regions.jl:63
[13] fill_halo_regions!
@ ~/development/Oceananigans.jl/src/BoundaryConditions/fill_halo_regions.jl:50 [inlined]
[14] #fill_halo_regions!#65
@ ~/development/Oceananigans.jl/src/Fields/field.jl:810 [inlined]
[15] fill_halo_regions!(::Field{…})
@ Oceananigans.Fields ~/development/Oceananigans.jl/src/Fields/field.jl:807
[16] top-level scope
@ REPL[6]:1
Some type information was truncated. Use `show(err)` to see complete types.
This is because bcs are not regularized. However, we could support the pattern that you are suggesting by discarding the DefaultBoundaryCondition in favor of the actual boundary conditions when passing them into a field.
There are two different ways to solve it:
- make
validate_boundary_conditionsmaterialize the default bc into the actual bc - make
construct_boundary_conditions_kernelsmaterialize the default bc into the actual bc
because both the functions have info about the grid and location. I probably prefer the first one. Tomorrow I will open a PR to fix this.
Ah, I wasn't aware this wasn't the proper usage. It seemed like it should work so I ended up posting it here. I'm okay with whatever solution you think is best. Thanks!
Hmm, it is interesting, because we do have both the grid and location inside the Field constructor. We could possibly fix this by calling regularize_field_boundary_conditions inside the Field constructor?