-
Notifications
You must be signed in to change notification settings - Fork 196
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Different advection schemes in different directions (#3732)
* should be done * add the dicussion * disambiguation * remove repeat code * precopmiles * keep these changes for later * correct the outside buffer * fix tests * change the show method * back to previous buffer scheme * allow for changes in the advection * switch position of functions * better comment * better info * bugfix * better info * make sure N==1 -> nothing * Update src/Advection/momentum_advection_operators.jl Co-authored-by: Gregory L. Wagner <[email protected]> * add topologies * add topology argument * better adaptation * formatting * whoops * remove topology and less metaprogramming * add advection * dont adapt nothing * retain same behavior as before * fix multi region advection * bugfix scalar diffusivities parameter types * bugfix * enzyme error * make sure constructors are type-stable... * force required_halo_size to be an integer * add better comment * add a couple of unit tests * test biharmonic diffusivity * fix enzyme tests * correct adaptbetter explanation * add a test for adapt_advection * whoops wrong test * revert changes * add couple more tests * fix tests * without the extra space * fix enzyme test * fix enzyme tests * fix nonhydrostatic tests * rmove one newline * simplify test * Update src/Models/HydrostaticFreeSurfaceModels/hydrostatic_free_surface_model.jl Co-authored-by: Gregory L. Wagner <[email protected]> * remove extra dispatches * relaunch the tests * change comment * switch to B * new syntax for KernelParameters * bugfix * another bugfix * make sure the range is correct * Update src/Advection/adapt_advection_order.jl Co-authored-by: Gregory L. Wagner <[email protected]> * Update src/Advection/adapt_advection_order.jl Co-authored-by: Gregory L. Wagner <[email protected]> * Update src/Advection/adapt_advection_order.jl Co-authored-by: Gregory L. Wagner <[email protected]> * remove comments * this should be type stable for the moment * bugfix * bugfix * better comment * fix the docs * whoops --------- Co-authored-by: Gregory L. Wagner <[email protected]>
- Loading branch information
1 parent
989108a
commit 0210e66
Showing
24 changed files
with
487 additions
and
219 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
using Oceananigans.Grids: topology | ||
|
||
""" | ||
adapt_advection_order(advection, grid::AbstractGrid) | ||
Adapts the advection operator `advection` based on the grid `grid` by adjusting the order of advection in each direction. | ||
For example, if the grid has only one point in the x-direction, the advection operator in the x-direction is set to first order | ||
upwind or 2nd order centered scheme, depending on the original user-specified advection scheme. A high order advection sheme | ||
is reduced to a lower order advection scheme if the grid has fewer points in that direction. | ||
# Arguments | ||
- `advection`: The original advection scheme. | ||
- `grid::AbstractGrid`: The grid on which the advection scheme is applied. | ||
If the order of advection is changed in at least one direction, the adapted advection scheme with adjusted advection order returned | ||
by this function is a `FluxFormAdvection`. | ||
""" | ||
function adapt_advection_order(advection, grid::AbstractGrid) | ||
advection_x = x_advection(advection) | ||
advection_y = y_advection(advection) | ||
advection_z = z_advection(advection) | ||
|
||
new_advection_x = adapt_advection_order(advection_x, size(grid, 1), grid) | ||
new_advection_y = adapt_advection_order(advection_y, size(grid, 2), grid) | ||
new_advection_z = adapt_advection_order(advection_z, size(grid, 3), grid) | ||
|
||
# Check that we indeed changed the advection operator | ||
changed_x = new_advection_x != advection_x | ||
changed_y = new_advection_y != advection_y | ||
changed_z = new_advection_z != advection_z | ||
|
||
new_advection = FluxFormAdvection(new_advection_x, new_advection_y, new_advection_z) | ||
changed_advection = any((changed_x, changed_y, changed_z)) | ||
|
||
if changed_x | ||
@info "Using the advection scheme $(summary(new_advection.x)) in the x-direction because size(grid, 1) = $(size(grid, 1))" | ||
end | ||
if changed_y | ||
@info "Using the advection scheme $(summary(new_advection.y)) in the y-direction because size(grid, 2) = $(size(grid, 2))" | ||
end | ||
if changed_z | ||
@info "Using the advection scheme $(summary(new_advection.z)) in the x-direction because size(grid, 3) = $(size(grid, 3))" | ||
end | ||
|
||
return ifelse(changed_advection, new_advection, advection) | ||
end | ||
|
||
|
||
x_advection(flux_form::FluxFormAdvection) = flux_form.x | ||
y_advection(flux_form::FluxFormAdvection) = flux_form.y | ||
z_advection(flux_form::FluxFormAdvection) = flux_form.z | ||
|
||
x_advection(advection) = advection | ||
y_advection(advection) = advection | ||
z_advection(advection) = advection | ||
|
||
# For the moment, we do not adapt the advection order for the VectorInvariant advection scheme | ||
adapt_advection_order(advection::VectorInvariant, grid::AbstractGrid) = advection | ||
adapt_advection_order(advection::Nothing, grid::AbstractGrid) = nothing | ||
adapt_advection_order(advection::Nothing, N::Int, grid::AbstractGrid) = nothing | ||
|
||
##### | ||
##### Directional adapt advection order | ||
##### | ||
|
||
function adapt_advection_order(advection::Centered{B}, N::Int, grid::AbstractGrid) where B | ||
if N >= B | ||
return advection | ||
else | ||
return Centered(; order = 2N) | ||
end | ||
end | ||
|
||
function adapt_advection_order(advection::UpwindBiased{B}, N::Int, grid::AbstractGrid) where B | ||
if N >= B | ||
return advection | ||
else | ||
return UpwindBiased(; order = 2N - 1) | ||
end | ||
end | ||
|
||
""" | ||
new_weno_scheme(grid, order, bounds, XT, YT, ZT) | ||
Constructs a new WENO scheme based on the given parameters. `XT`, `YT`, and `ZT` is the type of the precomputed weno coefficients in the | ||
x-direction, y-direction and z-direction. A _non-stretched_ WENO scheme has `T` equal to `Nothing` everywhere. In case of a non-stretched WENO scheme, | ||
we rebuild the advection without passing the grid information, otherwise we use the grid to account for stretched directions. | ||
""" | ||
new_weno_scheme(::WENO, grid, order, bounds, ::Type{Nothing}, ::Type{Nothing}, ::Type{Nothing},) = WENO(; order, bounds) | ||
new_weno_scheme(::WENO, grid, order, bounds, XT, YT, ZT) = WENO(grid; order, bounds) | ||
|
||
function adapt_advection_order(advection::WENO{B, FT, XT, YT, ZT}, N::Int, grid::AbstractGrid) where {B, FT, XT, YT, ZT} | ||
if N >= B | ||
return advection | ||
else | ||
return new_weno_scheme(advection, grid, 2N - 1, advection.bounds, XT, YT, ZT) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
using Oceananigans.Operators: Vᶜᶜᶜ | ||
using Oceananigans.Fields: ZeroField | ||
|
||
struct FluxFormAdvection{N, FT, A, B, C} <: AbstractAdvectionScheme{N, FT} | ||
x :: A | ||
y :: B | ||
z :: C | ||
|
||
FluxFormAdvection{N, FT}(x::A, y::B, z::C) where {N, FT, A, B, C} = new{N, FT, A, B, C}(x, y, z) | ||
end | ||
|
||
""" | ||
function FluxFormAdvection(x, y, z) | ||
Builds a `FluxFormAdvection` type with reconstructions schemes `x`, `y`, and `z` to be applied in | ||
the x, y, and z direction, respectively. | ||
""" | ||
function FluxFormAdvection(x_advection, y_advection, z_advection) | ||
Hx = required_halo_size_x(x_advection) | ||
Hy = required_halo_size_y(y_advection) | ||
Hz = required_halo_size_z(z_advection) | ||
|
||
FT = eltype(x_advection) | ||
H = max(Hx, Hy, Hz) | ||
|
||
return FluxFormAdvection{H, FT}(x_advection, y_advection, z_advection) | ||
end | ||
|
||
Base.show(io::IO, scheme::FluxFormAdvection) = | ||
print(io, "FluxFormAdvection with reconstructions: ", " \n", | ||
" ├── x: ", summary(scheme.x), "\n", | ||
" ├── y: ", summary(scheme.y), "\n", | ||
" └── z: ", summary(scheme.z)) | ||
|
||
@inline required_halo_size_x(scheme::FluxFormAdvection) = required_halo_size_x(scheme.x) | ||
@inline required_halo_size_y(scheme::FluxFormAdvection) = required_halo_size_y(scheme.y) | ||
@inline required_halo_size_z(scheme::FluxFormAdvection) = required_halo_size_z(scheme.z) | ||
|
||
Adapt.adapt_structure(to, scheme::FluxFormAdvection{N, FT}) where {N, FT} = | ||
FluxFormAdvection{N, FT}(Adapt.adapt(to, scheme.x), | ||
Adapt.adapt(to, scheme.y), | ||
Adapt.adapt(to, scheme.z)) | ||
|
||
@inline _advective_tracer_flux_x(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_tracer_flux_x(i, j, k, grid, advection.x, args...) | ||
@inline _advective_tracer_flux_y(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_tracer_flux_y(i, j, k, grid, advection.y, args...) | ||
@inline _advective_tracer_flux_z(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_tracer_flux_z(i, j, k, grid, advection.z, args...) | ||
|
||
@inline _advective_momentum_flux_Uu(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_momentum_flux_Uu(i, j, k, grid, advection.x, args...) | ||
@inline _advective_momentum_flux_Vu(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_momentum_flux_Vu(i, j, k, grid, advection.y, args...) | ||
@inline _advective_momentum_flux_Wu(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_momentum_flux_Wu(i, j, k, grid, advection.z, args...) | ||
|
||
@inline _advective_momentum_flux_Uv(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_momentum_flux_Uv(i, j, k, grid, advection.x, args...) | ||
@inline _advective_momentum_flux_Vv(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_momentum_flux_Vv(i, j, k, grid, advection.y, args...) | ||
@inline _advective_momentum_flux_Wv(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_momentum_flux_Wv(i, j, k, grid, advection.z, args...) | ||
|
||
@inline _advective_momentum_flux_Uw(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_momentum_flux_Uw(i, j, k, grid, advection.x, args...) | ||
@inline _advective_momentum_flux_Vw(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_momentum_flux_Vw(i, j, k, grid, advection.y, args...) | ||
@inline _advective_momentum_flux_Ww(i, j, k, grid, advection::FluxFormAdvection, args...) = _advective_momentum_flux_Ww(i, j, k, grid, advection.z, args...) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.