-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(0.94.0) Overhaul spacings functions to return KernelFunctionOperation
s
#3143
Conversation
Note: I couldn't find any tests for this, so it'd probably be a good idea to add some here before merging. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tests are a good idea!
Co-authored-by: Navid C. Constantinou <navidcy@users.noreply.github.com>
Co-authored-by: Navid C. Constantinou <navidcy@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I pushed some tests. Given that they pass then this lgtm! :)
hm... so we get this error although we added a method. Is it because we defined, e.g., Grid initialization: Error During Test at /var/lib/buildkite-agent/builds/tartarus-7/clima/oceananigans/test/test_grids.jl:203
Test threw exception
Expression: minimum_xspacing(grid) ≈ FT(π / 3)
MethodError: xspacing(::Int64, ::Int64, ::Int64, ::ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, ::Center, ::Center, ::Center) is ambiguous. Candidates:
xspacing(i, j, k, grid::ImmersedBoundaryGrid, args...) in Oceananigans.ImmersedBoundaries at /var/lib/buildkite-agent/builds/tartarus-7/clima/oceananigans/src/ImmersedBoundaries/immersed_grid_metrics.jl:40
xspacing(i, j, k, grid, ::Center, ::Center, ::Center) in Oceananigans.Operators at /var/lib/buildkite-agent/builds/tartarus-7/clima/oceananigans/src/Operators/spacings_and_areas_and_volumes.jl:264
Possible fix, define
xspacing(::Any, ::Any, ::Any, ::ImmersedBoundaryGrid, ::Center, ::Center, ::Center)
Stacktrace:
[1] getindex
@ ~/builds/tartarus-7/clima/oceananigans/src/AbstractOperations/kernel_function_operation.jl:73 [inlined]
[2] getindex
@ ~/builds/tartarus-7/clima/oceananigans/src/AbstractOperations/conditional_operations.jl:120 [inlined]
[3] getindex
@ ./subarray.jl:282 [inlined]
[4] _getindex
@ ./abstractarray.jl:1291 [inlined]
[5] getindex
@ ./abstractarray.jl:1241 [inlined]
[6] map!(f::typeof(identity), dest::SubArray{Float32, 3, Array{Float32, 3}, Tuple{UnitRange{Int64}, UnitRange{Int64}, UnitRange{Int64}}, false}, A::SubArray{Float32, 3, ConditionalOperation{Center, Center, Center, KernelFunctionOperation{Center, Center, Center, ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Float32, typeof(xspacing), Tuple{Center, Center, Center}}, typeof(identity), ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Oceananigans.ImmersedBoundaries.NotImmersed{typeof(Oceananigans.AbstractOperations.truefunc)}, Float64, Float32}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}, Base.OneTo{Int64}}, false})
@ Base ./abstractarray.jl:2926
[7] mapfirst!(f::typeof(identity), R::SubArray{Float32, 3, Array{Float32, 3}, Tuple{UnitRange{Int64}, UnitRange{Int64}, UnitRange{Int64}}, false}, A::ConditionalOperation{Center, Center, Center, KernelFunctionOperation{Center, Center, Center, ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Float32, typeof(xspacing), Tuple{Center, Center, Center}}, typeof(identity), ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Oceananigans.ImmersedBoundaries.NotImmersed{typeof(Oceananigans.AbstractOperations.truefunc)}, Float64, Float32})
@ Base ./reducedim.jl:274
[8] initialize_reduced_field!(#unused#::typeof(minimum!), f::Function, r::Field{Nothing, Nothing, Nothing, Nothing, ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArray{Float32, 3, Array{Float32, 3}}, Float32, FieldBoundaryConditions{Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, BoundaryCondition{Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, c::ConditionalOperation{Center, Center, Center, KernelFunctionOperation{Center, Center, Center, ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Float32, typeof(xspacing), Tuple{Center, Center, Center}}, typeof(identity), ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Oceananigans.ImmersedBoundaries.NotImmersed{typeof(Oceananigans.AbstractOperations.truefunc)}, Float64, Float32})
@ Oceananigans.Fields ~/builds/tartarus-7/clima/oceananigans/src/Fields/field.jl:556
[9] minimum(f::Function, c::KernelFunctionOperation{Center, Center, Center, ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Float32, typeof(xspacing), Tuple{Center, Center, Center}}; condition::Nothing, mask::Float64, dims::Function)
@ Oceananigans.Fields ~/builds/tartarus-7/clima/oceananigans/src/Fields/field.jl:647
[10] minimum
@ ~/builds/tartarus-7/clima/oceananigans/src/Fields/field.jl:637 [inlined]
[11] #minimum#45
@ ~/builds/tartarus-7/clima/oceananigans/src/Fields/field.jl:657 [inlined]
[12] minimum(c::KernelFunctionOperation{Center, Center, Center, ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Float32, typeof(xspacing), Tuple{Center, Center, Center}})
@ Oceananigans.Fields ~/builds/tartarus-7/clima/oceananigans/src/Fields/field.jl:657
[13] minimum_spacing(dir::Symbol, grid::ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, ℓx::Center, ℓy::Center, ℓz::Center)
@ Oceananigans.Grids ~/builds/tartarus-7/clima/oceananigans/src/Grids/grid_utils.jl:408
[14] minimum_xspacing(grid::ImmersedBoundaryGrid{Float32, Periodic, Periodic, Bounded, RectilinearGrid{Float32, Periodic, Periodic, Bounded, Float32, Float32, Float32, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, OffsetVector{Float32, StepRangeLen{Float32, Float64, Float64, Int64}}, CPU}, GridFittedBottom{OffsetMatrix{Float32, Matrix{Float32}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU})
@ Oceananigans.Grids ~/builds/tartarus-7/clima/oceananigans/src/Grids/grid_utils.jl:429
[15] macro expansion
@ /storage5/buildkite-agent/julia-1.8.5/share/julia/stdlib/v1.8/Test/src/Test.jl:464 [inlined]
[16] test_regular_rectilinear_xnode_ynode_znode_and_spacings(arch::CPU, FT::Type{Float32})
@ Main ~/builds/tartarus-7/clima/oceananigans/test/test_grids.jl:203
<br class="Apple-interchange-newline" style="caret-color: rgb(0, 0, 0); color: rgb(0, 0, 0); font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;"> |
OK, I think I found the culprit. |
xspacings(grid::IBG, args...; kwargs...) = xspacings(grid.underlying_grid, args...; kwargs...) | ||
yspacings(grid::IBG, args...; kwargs...) = yspacings(grid.underlying_grid, args...; kwargs...) | ||
zspacings(grid::IBG, args...; kwargs...) = zspacings(grid.underlying_grid, args...; kwargs...) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is wrong in general, are we sure we want this?
Except for the "GridFitted" immersed boundary methods, immersed boundaries in general may change the metrics of the underlying grid. I think we want this user-facing method to return the correct spacings, ie when using PartialCellBottom
, and the in-development CutCellBottom
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can proceed by dispatching this method only when valid, ie for GridFittedBoundary
and GridFittedBottom
. We'll need a different implementation for PartialCellBottom
.
I think the right approach is to use KernelFunctionOperation
for xspacing
. Then every spacings
method can simply collect the output of xspacing
. This is generically valid and would presumably reduce the amount of code we have to write by a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh good point!
so, for PartialCellBottom
only the zspacings
is not correct, right? the horizontal spacings don't change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But it's possible to write code that works for all grids by referencing the kernel functions directly (rather than trying to extract the spacings from the grid properties). That's how we get spacings inside the code, so if we use the same method in the user interface then all is good.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree that KernelFunctionOperation
s would reduce the amount of code. It would also return an AbstractOperation
instead of the current options (which are either a float or an array), which I think has extra computational costs, no? Also I think we'd lose a bit of the simplicity on the user side.
For example the following line of code (taken from this doc example would become way less readable since zspacings()
would now return an AbstractOperation
, which would need to be first converted into a 3D Field
, computed, and transformed into a 1D Array before plotting:
lines!(ax, zspacings(grid, Center()), znodes(grid, Center()))
Finally, following the same logic, would xnodes
etc. also become KernelFunctionOperation
s?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just to clarify, I'm happy to make the changes once we agree on the way forward. I just wanna make sure we're all on the same page and also get an idea of the size of the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm right I was a little confused. zspacing
is actually the kernel function itself (not an operation or array).
For zspacings
we do either have to (1) represent it with an operation or (2) compute the metrics. There's no way around this in general: with partial cells, we compute the metrics on the fly (this computation seems to have no cost on the GPU). For cut cells, computing the metrics on the fly is required in fact, because precomputing all the metrics (3D arrays) would greatly increase our memory footprint, and also probably incur a big cost since we are memory-bound.
We could implement optimized zspacings
for non-immersed grids or GridFittedBottom
. But is there a point? I don't think the costs would be noticeable compared to, for example, the computational cost of displaying a plot.
It also seems simpler to compute zspacings
from zspacing
, since more generic code might be implemented in that case. Note that for partial cells though, zspacings
has to return a 3D array. For many other grids its just a 1D array.
I think it's a good idea to think carefully about the implementation before doing anything hasty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
which would need to be first converted into a 3D Field, computed, and transformed into a 1D Array before plotting:
We have 1D fields. Also operations like "tranforming a field into an array" are not expensive. For example, we might do something like this O(100) times in a single time step.
I suggest we put performance to the side right now and think first about a clean, simple implementation. We can optimize performance later if needed; these functions neede primarily for plotting aren't performance critical anyways
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For example the following line of code (taken from this doc example would become way less readable
I'm not suggesting to change the user API. I'm suggesting to change the source code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@glwagner raised a valid point! I'm retracting my approval until we fixed this.
I'm going to try and put some some into this, but I'm a bit unsure of what to do. First, to summarize what the current state on Current behavior for
|
@inline xspacings(grid::RectilinearGrid, ℓx::Center; with_halos=false) = with_halos ? grid.Δxᶜᵃᵃ : view(grid.Δxᶜᵃᵃ, interior_indices(ℓx, topology(grid, 1)(), size(grid, 1))) | |
@inline xspacings(grid::XRegRectilinearGrid, ℓx::Center; with_halos=false) = grid.Δxᶜᵃᵃ |
which directly accesses the grid
's Δzᵃᵃᶜ
property.
The call to zspacing()
goes through some metaprogramming here but ultimately also directly accesses the grid
's Δzᵃᵃᶜ
property here:
Oceananigans.jl/src/Operators/spacings_and_areas_and_volumes.jl
Lines 104 to 112 in 56fc69b
@inline Δxᶠᵃᵃ(i, j, k, grid::RG) = @inbounds grid.Δxᶠᵃᵃ[i] | |
@inline Δxᶜᵃᵃ(i, j, k, grid::RG) = @inbounds grid.Δxᶜᵃᵃ[i] | |
@inline Δyᵃᶠᵃ(i, j, k, grid::RG) = @inbounds grid.Δyᵃᶠᵃ[j] | |
@inline Δyᵃᶜᵃ(i, j, k, grid::RG) = @inbounds grid.Δyᵃᶜᵃ[j] | |
@inline Δxᶠᵃᵃ(i, j, k, grid::RGX) = @inbounds grid.Δxᶠᵃᵃ | |
@inline Δxᶜᵃᵃ(i, j, k, grid::RGX) = @inbounds grid.Δxᶜᵃᵃ | |
@inline Δyᵃᶠᵃ(i, j, k, grid::RGY) = @inbounds grid.Δyᵃᶠᵃ | |
@inline Δyᵃᶜᵃ(i, j, k, grid::RGY) = @inbounds grid.Δyᵃᶜᵃ |
Current behavior for ImmersedBoundaryGrid
For the same grid wrapped around an ImmersedBoundaryGrid
on main
, when calling zspacings()
we get the error at the top comment (MethodError: no method matching
; which this PR aims to fix). The call to zspacing()
works the same way as with RectilinearGrid
, with the exception of an extra dispatch here.
Summary of the PR as of this post
This PR is originally trying to fix the issue with zspacings(::IBG)
simply by adding
zspacings(grid::IBG, args...; kwargs...) = zspacings(grid.underlying_grid, args...; kwargs...)
If I understand correctly, @glwagner's point is that this is wrong in cases where cells have a fraction of "wet" volume and a fraction of "immersed solid" volume. (For now the two such cases in sight are PartialCellBottom
and CutCellBottom
(for which there's open PR #3146).)
Again, if I understand correctly, the simple solution would be to redirect zspacings()
calls to
- Create a
KernelFunctionOperation
usingzspacing()
, which we know has the correct behavior for all cases - Calculate and collect the values in a Array
- Return to user
The main challenge here (imo) is that
- if we wanna keep the user-interface simple (e.g. return a float or a 1D array from calls to
zspacings(::RectilinearGrid)
instead of aField
or a 3D array), then we lose consistency (because in the general case a call tozspacings(::ImmersedBoundaryGrid)
must return a 3D array (orField
, orAbstractOp
...)). - if we wanna keep the user-interface consistent (i.e. always return the same type of object) then we lose on simplicity (e.g. a call to
zspacings(::RectilinearGrid)
would always return something 3D, even if the grid is regular).
@navidcy @glwagner is this a fair assessment of the situation? Feel free to edit the text above if not.
My take is that I don't think there's a way around the choices I just mentioned in the previous post. To make it ever harder, based on @glwagner's comment I think we also need to discuss what exactly (regardless of format)
afaik this is exactly how the code internals work. However, since
? I think this latter option is more consistent (i.e. a solid never counts as "wet space") and it makes stuff like offline integrals easier (since Oceananigans.jl/src/Grids/grid_utils.jl Lines 482 to 496 in b8b8059
(The main difference there is that the space outside the domain (i.e. halos) also doesn't count as wet volume) |
Why don't we deal with the full issue in this PR rather than merging and opening a new one. There is no rush, right? |
@tomchor FYI if you paste permalinks to code directly in the text, eg: Oceananigans.jl/src/Operators/spacings_and_areas_and_volumes.jl Lines 247 to 269 in 56fc69b
then github will generate a view into the code. This will save some time creating screenshots, etc. You have to paste the whole link for this to work, rather than appending a link onto some text (eg linking to the word "here") |
I'm hesitant because I think we create more work for ourselves when we write code that may have to be revisited in the future. Better to do it right the first time I think... |
I think the right way forward is to implement something that works for all grids. Then we can implement the grid-specific versions --- which should be viewed as conveniences or optimizations rather than necessities --- as time allows. I think this is a better and more efficient approach then implementing convenience versions first, and figuring out the general version later. You might find that the convenience versions aren't really necessary because things are convenient enough... |
My suggestion of opening a separate issue comes from the fact that I don't have much time to work on this PR (as you guys could probably see by the month-delay in answering the last comments). And in the meantime there's a bug in the code that could be fixed rn with one extra commit. But fair enough. Let's solve this here.
If I understand what you're proposing, the way forward would be to implement something that always returns the 3D field/array, since that's the only way that works for all grids no matter what. Correct? |
Thanks! I know about that feature actually. The pieces of code I pasted as hyperlink were ones I considered to be less important for the argument and didn't want it taking up space in the comment. |
@glwagner, what do you mean here by "kernel functions"? |
By "kernel function" I mean "a function meant to be used inside a kernel". In our convention these functions have the first four arguments Annoyingly they are all defined via metaprogramming, eg:
the 2D spacings though are defined
|
I fixed the tests, doctests, and plotting examples in the docs! I ended up defining the spacing functions needed and used by other modules, and it should be easy to add more in the future as needed. All pipelines should pass 🤞 And this PR should be ready for review again. |
I can't approve my own PR so I'm giving verbal approval here. Thanks for reviving this PR @ali-ramadhan! Also extra kudos for removing so many trailing white spaces :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@inline Δzᵃᵃᶠ(i, j, k, grid::OSSG) = @inbounds grid.Δzᵃᵃᶠ[k] | ||
|
||
@inline Δzᵃᵃᶜ(i, j, k, grid::OSSGZ) = grid.Δzᵃᵃᶜ | ||
@inline Δzᵃᵃᶠ(i, j, k, grid::OSSGZ) = grid.Δzᵃᵃᶠ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where did these go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @ali-ramadhan. I'm a little confused where some spacing functions went. But if tests pass I'm assuming everything is in order. It would only be nice to know so I know where to look when I need to find them.
As for white space, while perhaps it is laudable to remove them it does make reviewing the PR a lot more difficult. I suggest putting in a separate PR to remove them throughout the code base so that we don't have to remove them PR-by-PR in the future (at least, it will reduce the need for that). |
Remember to register v0.94.0 when this is merged ;) |
I found the spacings definitions! They were just moved around in the file. |
@tomchor I'll leave it to you to delete the branch if you like |
Thanks for merging! And yeah the definitions should have just moved around. |
The spacings functions aren't working for
ImmersedBoundaryGrid
s onmain
. This PR fixes that.On main:
On this branch: