Oceananigans.jl
Oceananigans.jl copied to clipboard
Add internal tide example in Docs
This is a simple example with immersed boundary.
https://github.com/CliMA/Oceananigans.jl/assets/7112768/b225a647-7f21-4dcc-8b12-1ae9d662d106
This PR requires #3094. At the moment it includes the changes there but ideally we want to conclude the discussion in #3094 and merge that one before this.
Or perhaps use the split-explicit free surface?
cc @djlikesdjs
@navidcy can you please include the link to the docs preview page so that we see how it looks before approving?
Could you build the docs locally?
Comment out all examples here https://github.com/CliMA/Oceananigans.jl/blob/72a2399394d60fa22d77dc51822d6175ffcf07e3/docs/make.jl#L30-L43 except the tide one and run:
$ rm -rf docs/build; rm -rf docs/src/generated; julia --project -e 'using Pkg; Pkg.instantiate()'; julia --project=docs/ -e 'using Pkg; Pkg.precompile()'; JULIA_DEBUG=Documenter julia --project=docs/ docs/make.jl
and then open, e.g., docs/build/generated/barotropic_tide.html.
If you even change
https://github.com/CliMA/Oceananigans.jl/blob/72a2399394d60fa22d77dc51822d6175ffcf07e3/docs/make.jl#L141-L151
to doctest = false, strict = false and checkdocs = :none, it'll speed things even more.
(It took ~8 mins on my laptop.)
Could you build the docs locally?
I know how to do it, but I didn't try. I thought the best practice was to set push_preview=true temporarily for docs changes like this one as per your first comment in https://github.com/CliMA/Oceananigans.jl/pull/2870.
But fair enough. I'll build and view them locally for review.
Could you build the docs locally?
I know how do it, but I didn't try. I thought the best practice was to set
push_preview=truetemporarily for docs changes like this one as per your first comment in #2870.But fair enough. I'll build and view them locally for review.
Thanks. It's quite cumbersome to delete the previews from the OceananigansDocumentation branch and thus I'm very reluctant doing it. Sorry :(
So I tried with SplitExplicit and 1) it's much faster but 2) I see this very fast motion in the beginning...
Compare this
https://github.com/CliMA/Oceananigans.jl/assets/7112768/b098f251-0880-4ead-8f71-a3a5282540d4
with the animation at the top of this PR.
I suppose it's the gravity waves... Are they implicitly filtered out with the implicit free surface solver at the top?
I think it would be clearer to call this "internal tide" or "barotropic tide over seamount". The point is not the barotropic tide, the point is to showcase the generation of internal waves.
Agree! "Barotropic tide over seamount" is a good title or "Internal tide generation from seamount"
So I tried with SplitExplicit and 1) it's much faster but 2) I see this very fast motion in the beginning...
Compare this
barotropic_tide_splitexplicit.mp4 with the animation at the top of this PR.
I suppose it's the gravity waves... Are they implicitly filtered out with the implicit free surface solver at the top?
Yeah, the implicit solver diffuses out all the gravity waves while the split explicit "resolves" them. You can also check out the validation case in validation/implicit_free_surface/geostrophic_adjustment_test.jl that shows quite some difference in the dynamics using the implicit solver vs split explicit solver
Just for the future I think adding an example is a big deal so I think it might be best to discuss such an addition on an issue before submitting a PR.
We can delete this validation test too after this: https://github.com/CliMA/Oceananigans.jl/blob/main/validation/immersed_boundaries/internal_tide.jl
Just for the future I think adding an example is a big deal so I think it might be best to discuss such an addition on an issue before submitting a PR.
Gotcha!
But also happy to close the PR! I had made this example for a demo and I thought it might be useful.
Just for the future I think adding an example is a big deal so I think it might be best to discuss such an addition on an issue before submitting a PR.
Gotcha!
But also happy to close the PR! I had made this example for a demo and I thought it might be useful.
I think we need more examples with immersed boundaries which was part of our motivation for doing the double gyre with bathymetry with @siddharthabishnu right? I was just also under the impression that we wanted to limit examples to keep the docs build relatively fast. (Or at least, until we had solved the problem with glacially slow docs builds, then we could afford to add more.) Maybe that has changed though, I'm not keeping track of the time it takes to build docs. It used to be 3h.
Just for the future I think adding an example is a big deal so I think it might be best to discuss such an addition on an issue before submitting a PR.
Gotcha! But also happy to close the PR! I had made this example for a demo and I thought it might be useful.
I think we need more examples with immersed boundaries which was part of our motivation for doing the double gyre with bathymetry with @siddharthabishnu right? I was just also under the impression that we wanted to limit examples to keep the docs build relatively fast. (Or at least, until we had solved the problem with glacially slow docs builds, then we could afford to add more.) Maybe that has changed though, I'm not keeping track of the time it takes to build docs. It used to be 3h.
It's still 3hrs... :(
Recently there was some suggestions in slack about parallelizing the run of the examples in the doc built but I haven't tried it yet.
Now animation looks like:
https://github.com/CliMA/Oceananigans.jl/assets/7112768/ddd57896-ae0d-45d1-a1f0-ac9b4bcb82f5
Great example @navidcy
Do we want to mask the hill in the animations? (Especially since https://github.com/CliMA/Oceananigans.jl/pull/3092 isn't merged yet.) The top plot specifically keeps changing color where the hill is supposed to be, which might throw off some readers. This could probably be done with Makie.poly.
Thanks!! I also find the rainbow mountain at top annoying. That’s what the mask_immersed! was trying to deal with.
We can delete this validation test too after this: https://github.com/CliMA/Oceananigans.jl/blob/main/validation/immersed_boundaries/internal_tide.jl
The validation script includes a multi region example. Shall I still delete it? I could also clean it up and add toml files in the validation script directory (see #3076).
We can delete this validation test too after this: https://github.com/CliMA/Oceananigans.jl/blob/main/validation/immersed_boundaries/internal_tide.jl
The validation script includes a multi region example. Shall I still delete it? I could also clean it up and add toml files in the validation script directory (see #3076).
Yeah, that's a random place for a multi region example.
@navidcy I'm trying to add a drag flux to this example like we talked about in https://github.com/CliMA/Oceananigans.jl/issues/3148 but I'm getting an error that I can't figure out. Using u as an example, I'm trying to implement the BCs as
@inline u_drag(x, y, t, u, v, w, p) = - p.cᵈ * u * √(u^2 + v^2 + w^2)
@inline u_drag(x, y, z, t, u, v, w, cᵈ) = u_drag(x, y, t, u, v, w, cᵈ)
u_drag_bc = FluxBoundaryCondition(u_drag, field_dependencies=(:u, :v, :w), parameters=(; cᵈ=1e-3))
boundary_conditions = (u = FieldBoundaryConditions(bottom=u_drag_bc),)
but when time-stepping the model I get
ERROR: LoadError: MethodError: no method matching field_arguments(::Int64, ::Int64, ::Int64, ::ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, ::NamedTuple{(:u, :v, :w, :b, :η), Tuple{Field{Face, Center, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Oceananigans.BoundaryConditions.ContinuousBoundaryFunction{Face, Center, Nothing, Oceananigans.BoundaryConditions.LeftBoundary, typeof(u_drag), NamedTuple{(:cᵈ,), Tuple{Float64}}, Tuple{Symbol, Symbol, Symbol}, Tuple{Int64, Int64, Nothing}, Tuple{typeof(Oceananigans.Operators.identity4), typeof(Oceananigans.Operators.ℑxyᶠᶜᵃ), typeof(Oceananigans.Operators.ℑxᶠᵃᵃ)}}}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Face, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Center, Face, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Center, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Center, Face, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, UnitRange{Int64}}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}}}, ::Tuple{typeof(Oceananigans.Operators.identity4), typeof(Oceananigans.Operators.ℑxyᶠᶜᵃ), typeof(Oceananigans.Operators.ℑxᶠᵃᵃ)}, ::Tuple{Int64, Int64, Nothing})
Closest candidates are:
field_arguments(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Tuple{T, T} where T)
@ Oceananigans ~/repos/Oceananigans.jl/src/Utils/user_function_arguments.jl:4
field_arguments(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Tuple{T, T, T} where T)
@ Oceananigans ~/repos/Oceananigans.jl/src/Utils/user_function_arguments.jl:8
field_arguments(::Any, ::Any, ::Any, ::Any, ::Any, ::Any, ::Tuple{Any})
@ Oceananigans ~/repos/Oceananigans.jl/src/Utils/user_function_arguments.jl:1
...
Stacktrace:
[1] user_function_arguments
@ ~/repos/Oceananigans.jl/src/Utils/user_function_arguments.jl:31 [inlined]
[2] getbc
@ ~/repos/Oceananigans.jl/src/BoundaryConditions/continuous_boundary_function.jl:129 [inlined]
[3] apply_z_bottom_bc!
@ ~/repos/Oceananigans.jl/src/BoundaryConditions/apply_flux_bcs.jl:125 [inlined]
[4] macro expansion
@ ~/repos/Oceananigans.jl/src/BoundaryConditions/apply_flux_bcs.jl:81 [inlined]
[5] cpu__apply_z_bcs!
@ ~/.julia/packages/KernelAbstractions/lhhMo/src/macros.jl:276 [inlined]
[6] cpu__apply_z_bcs!(__ctx__::KernelAbstractions.CompilerMetadata{KernelAbstractions.NDIteration.StaticSize{(250, 1)}, KernelAbstractions.NDIteration.NoDynamicCheck, CartesianIndex{2}, Nothing, KernelAbstractions.NDIteration.NDRange{2, KernelAbstractions.NDIteration.StaticSize{(1, 1)}, KernelAbstractions.NDIteration.StaticSize{(250, 1)}, Nothing, Nothing}}, Gc::Field{Face, Center, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, loc::Tuple{Face, Center, Center}, grid::ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, bottom_bc::BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Oceananigans.BoundaryConditions.ContinuousBoundaryFunction{Face, Center, Nothing, Oceananigans.BoundaryConditions.LeftBoundary, typeof(u_drag), NamedTuple{(:cᵈ,), Tuple{Float64}}, Tuple{Symbol, Symbol, Symbol}, Tuple{Int64, Int64, Nothing}, Tuple{typeof(Oceananigans.Operators.identity4), typeof(Oceananigans.Operators.ℑxyᶠᶜᵃ), typeof(Oceananigans.Operators.ℑxᶠᵃᵃ)}}}, top_bc::BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, args::Tuple{Clock{Float64}, NamedTuple{(:u, :v, :w, :b, :η), Tuple{Field{Face, Center, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Oceananigans.BoundaryConditions.ContinuousBoundaryFunction{Face, Center, Nothing, Oceananigans.BoundaryConditions.LeftBoundary, typeof(u_drag), NamedTuple{(:cᵈ,), Tuple{Float64}}, Tuple{Symbol, Symbol, Symbol}, Tuple{Int64, Int64, Nothing}, Tuple{typeof(Oceananigans.Operators.identity4), typeof(Oceananigans.Operators.ℑxyᶠᶜᵃ), typeof(Oceananigans.Operators.ℑxᶠᵃᵃ)}}}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Face, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Center, Face, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Center, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Center, Face, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, UnitRange{Int64}}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}}}, Nothing, Buoyancy{BuoyancyTracer, Oceananigans.Grids.NegativeZDirection}})
@ Oceananigans.BoundaryConditions ./none:0
[7] __thread_run(tid::Int64, len::Int64, rem::Int64, obj::KernelAbstractions.Kernel{KernelAbstractions.CPU, KernelAbstractions.NDIteration.StaticSize{(250, 1)}, KernelAbstractions.NDIteration.StaticSize{(250, 1)}, typeof(Oceananigans.BoundaryConditions.cpu__apply_z_bcs!)}, ndrange::Nothing, iterspace::KernelAbstractions.NDIteration.NDRange{2, KernelAbstractions.NDIteration.StaticSize{(1, 1)}, KernelAbstractions.NDIteration.StaticSize{(250, 1)}, Nothing, Nothing}, args::Tuple{Field{Face, Center, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Tuple{Face, Center, Center}, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Oceananigans.BoundaryConditions.ContinuousBoundaryFunction{Face, Center, Nothing, Oceananigans.BoundaryConditions.LeftBoundary, typeof(u_drag), NamedTuple{(:cᵈ,), Tuple{Float64}}, Tuple{Symbol, Symbol, Symbol}, Tuple{Int64, Int64, Nothing}, Tuple{typeof(Oceananigans.Operators.identity4), typeof(Oceananigans.Operators.ℑxyᶠᶜᵃ), typeof(Oceananigans.Operators.ℑxᶠᵃᵃ)}}}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, Tuple{Clock{Float64}, NamedTuple{(:u, :v, :w, :b, :η), Tuple{Field{Face, Center, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Oceananigans.BoundaryConditions.ContinuousBoundaryFunction{Face, Center, Nothing, Oceananigans.BoundaryConditions.LeftBoundary, typeof(u_drag), NamedTuple{(:cᵈ,), Tuple{Float64}}, Tuple{Symbol, Symbol, Symbol}, Tuple{Int64, Int64, Nothing}, Tuple{typeof(Oceananigans.Operators.identity4), typeof(Oceananigans.Operators.ℑxyᶠᶜᵃ), typeof(Oceananigans.Operators.ℑxᶠᵃᵃ)}}}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Face, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Center, Face, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Center, Center, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, Colon}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}, Field{Center, Center, Face, Nothing, ImmersedBoundaryGrid{Float64, Periodic, Flat, Bounded, RectilinearGrid{Float64, Periodic, Flat, Bounded, Float64, Float64, Float64, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}, OffsetArrays.OffsetVector{Float64, StepRangeLen{Float64, Base.TwicePrecision{Float64}, Base.TwicePrecision{Float64}, Int64}}, CPU}, GridFittedBottom{OffsetArrays.OffsetMatrix{Float64, Matrix{Float64}}, Oceananigans.ImmersedBoundaries.CenterImmersedCondition}, Nothing, CPU}, Tuple{Colon, Colon, UnitRange{Int64}}, OffsetArrays.OffsetArray{Float64, 3, Array{Float64, 3}}, Float64, FieldBoundaryConditions{BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, BoundaryCondition{Oceananigans.BoundaryConditions.Periodic, Nothing}, Nothing, Nothing, Nothing, Nothing, BoundaryCondition{Oceananigans.BoundaryConditions.Flux, Nothing}}, Nothing, Oceananigans.Fields.FieldBoundaryBuffers{Nothing, Nothing, Nothing, Nothing}}}}, Nothing, Buoyancy{BuoyancyTracer, Oceananigans.Grids.NegativeZDirection}}}, dynamic::KernelAbstractions.NDIteration.NoDynamicCheck)
However, if I use the same formulation on a NohydrostaticModel this works
julia> @inline u_drag(x, y, t, u, v, w, p) = - p.cᵈ * u * √(u^2 + v^2 + w^2)
u_drag (generic function with 2 methods)
julia> u_drag_bc = FluxBoundaryCondition(u_drag, field_dependencies=(:u, :v, :w), parameters=(; cᵈ=1e-3))
FluxBoundaryCondition: ContinuousBoundaryFunction u_drag at (Nothing, Nothing, Nothing)
julia> boundary_conditions = (u = FieldBoundaryConditions(bottom=u_drag_bc),);
julia> model = NonhydrostaticModel(; grid, boundary_conditions);
julia> time_step!(model, 1)
julia>
So whatever's happening probably has to do with the HydrostaticModel, which I'm really not familiar with unfortunately.
What do you prefer that I do?
So whatever's happening probably has to do with the HydrostaticModel, which I'm really not familiar with unfortunately.
What do you prefer that I do?
the hydrostatic model does not have w as state variable... try removing w and see if all is good.
I update the internal tide example. Let's merge this so we have an example with bathymetry in the docs?
The latest version of the movie is:
https://github.com/CliMA/Oceananigans.jl/assets/7112768/1bfdca5c-6d49-4101-9037-eadfacea6900
I'm not so sure about 979c2a7; is this a good idea?
cc @simone-silvestri, @glwagner
Without https://github.com/CliMA/Oceananigans.jl/commit/979c2a7cd10c1f2054cad996622cafd2e3fb3ffa the movie looks like
https://github.com/CliMA/Oceananigans.jl/assets/7112768/5b199c8c-0faf-4e73-97bf-b03edd40bb25
with the mountain changing colors in the first plot. A bit annoying...
with the mountain changing colors in the first plot. A bit annoying...
Can't we just plot a fixed-color shape on top on the mount on all panels? Makie.poly seems to be able to do that.
Can't we just plot a fixed-color shape on top on the mount on all panels?
Makie.polyseems to be able to do that.
We can.
We can also mask the output after we load it, e.g, via
using something like
using Oceananigans.ImmersedBoundaries: mask_immersed_field!
function mask_and_get_interior(φ_t, n; value=NaN)
mask_immersed_field!(φ_t[n], value)
return interior(φ_t[n], :, 1, :)
end
u′ₙ = @lift mask_and_get_interior(u′_t, $n)
which gives
https://github.com/CliMA/Oceananigans.jl/assets/7112768/a402bfcd-ef72-42d8-bbb9-97fb98be4fe3
But either of these solutions complicate the example a bit. Ideally, mask_immersed_field! should not be user-facing. And plotting a mountain on top of the mountain is a bit of a hack and would require a bit of explaining and justifying why we do that.
But I wouldn't mind adding the post-processing masking step with the hope we can eliminate it when masking is enabled for OutputWriters; see https://github.com/CliMA/Oceananigans.jl/pull/3092
I am in favor of not doing 979c2a7. It hardcodes a change in the source code that is only required for aesthetic reasons. I would wait for #3092 and in the meantime mask the output in the example
I am in favor of not doing 979c2a7. It hardcodes a change in the source code that is only required for aesthetic reasons. I would wait for #3092 and in the meantime mask the output in the example
Deal, done
The movie looks great and I'm happy to see this example coming to life!
One question I have is in the plot for stratification, at the very top. It looks like there is a black line and then there is a thin layer right below that. Anyone know what that is?