Skip to content
Open
Changes from 13 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
5efa6a6
Try some sorting idea for background state
jbisits Mar 28, 2024
7113697
First attempt at bpe implementation
jbisits Apr 1, 2024
1590116
Change docstring example
jbisits Apr 2, 2024
8ace5a8
Add space
jbisits Apr 2, 2024
5d2eee1
`sort` reverse so that matches `z`
jbisits Apr 3, 2024
84265a8
`sort(rev=true)` for density only (not buoyancy)
jbisits Apr 3, 2024
44d81c5
Removed wrong thing
jbisits Apr 3, 2024
9362a27
Correction in docstring
jbisits Apr 3, 2024
fbe8c02
Cleanup function definitions
jbisits Apr 22, 2024
e59fbad
Remove bad Type design
jbisits Apr 22, 2024
1ac15f3
Using more kfo's
jbisits Apr 22, 2024
6d3d7da
Update PotentialEnergyEquationTerms.jl
jbisits Apr 22, 2024
62b0a47
Update BPE docstring
jbisits Apr 22, 2024
1c73077
Update src/PotentialEnergyEquationTerms.jl
jbisits Apr 23, 2024
2c4faad
Try `OneDReferenceField`
jbisits May 8, 2024
0a87fbb
Export the function
jbisits May 8, 2024
73479d5
Correct BPE function, still need to check sorting
jbisits May 8, 2024
dfbbcd4
Merge branch 'main' into jib-background-potential-energy
jbisits May 9, 2024
f28a26a
Suppress some docstring output
jbisits May 9, 2024
aad59a9
Docstring updates
jbisits May 10, 2024
6251dc8
Validate model grid + docstring updates
jbisits May 10, 2024
2e98f34
Update src/PotentialEnergyEquationTerms.jl
jbisits May 10, 2024
38b9a83
Update PotentialEnergyEquationTerms.jl
jbisits May 10, 2024
24b658c
Merge branch 'jib-background-potential-energy' of https://github.com/…
jbisits May 10, 2024
3107ec6
Update src/PotentialEnergyEquationTerms.jl
jbisits May 11, 2024
23d095d
Update src/PotentialEnergyEquationTerms.jl
jbisits May 11, 2024
769ecc0
Wrong function calls
jbisits May 11, 2024
44c0206
Reduce number of methods + update packages
jbisits May 14, 2024
ac0ed37
Default to `geopotential_height = 0`
jbisits May 16, 2024
8689673
Simplify testing
jbisits May 16, 2024
8219b78
Correct misaligned brackets
jbisits May 16, 2024
71b5537
Add tests for `OneDReferenceField` + bpe
jbisits May 17, 2024
82c2421
Test z*
jbisits May 17, 2024
d4d396e
Docstring updates
jbisits May 20, 2024
63a58b2
Align `z` and `z✶`
jbisits May 22, 2024
3f752bf
Missed the ✶
jbisits May 22, 2024
1fd9d64
Correct `BuoyancyTracer()` and linear eos sorting
jbisits May 22, 2024
7514adf
Update `Type` input for `OneDReferenceField`
jbisits May 23, 2024
7cbc052
Correct function call
jbisits May 23, 2024
2ec9e41
Merge branch 'main' into jib-background-potential-energy
jbisits May 23, 2024
08832ae
Merge branch 'main' into jib-background-potential-energy
tomchor Nov 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 121 additions & 1 deletion src/PotentialEnergyEquationTerms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module PotentialEnergyEquationTerms

using DocStringExtensions

export PotentialEnergy
export PotentialEnergy, BackgroundPotentialEnergy

using Oceananigans.AbstractOperations: KernelFunctionOperation
using Oceananigans.Models: seawater_density
Expand All @@ -12,6 +12,7 @@ using Oceananigans.Grids: NegativeZDirection
using Oceananigans.BuoyancyModels: Buoyancy, BuoyancyTracer, SeawaterBuoyancy, LinearEquationOfState
using Oceananigans.BuoyancyModels: buoyancy_perturbationᶜᶜᶜ, Zᶜᶜᶜ
using Oceananigans.Models: ShallowWaterModel
using Oceananigans.Fields: Field, compute!
using Oceanostics: validate_location
using SeawaterPolynomials: BoussinesqEquationOfState

Expand Down Expand Up @@ -184,4 +185,123 @@ end

@inline g′z_ccc(i, j, k, grid, ρ, p) = (p.g / p.ρ₀) * ρ[i, j, k] * Zᶜᶜᶜ(i, j, k, grid)

"""
function sort_field(f)
Reshape a `Field` `f` into an array (that is the length of the product of the grid dimensions),
`sort` this array (default behaviour of `sort` is ascending) then distribute this `sort`ed
array throughout the grid such that the _largest_ values are at the top of the grid and
the smallest values are at the _bottom_ of the grid.
"""
@inline sorted_field(f::Field) = reshape(sort(reshape(f, :)), size(f))

@inline function sort_field(f::Field)

compute!(f)
grid = f.grid
sf = sorted_field(f)

return KernelFunctionOperation{Center, Center, Center}(sorted_field, grid, sf)
end
"""
function sort_field_revesre(f)
Same method as [`sort_field`](@ref) but the 1D array is sorted in _descending_ order.
"""
@inline sorted_field_reverse(f::Field) = reshape(sort(reshape(f, :), rev = true), size(f))

@inline function sort_field_reverse(f::Field)

compute!(f)
grid = f.grid
sf = sorted_field_reverse(f)

return KernelFunctionOperation{Center, Center, Center}(sorted_field, grid, sf)
end

@inline sorted_field(i, j, k, grid, sf) = sf[i, j, k]

"""
$(SIGNATURES)

Return a `kernelFunctionOperation` to compute the `BackgroundPotentialEnergy` per unit
volume,
```math
E_{b} = \\frac{gρ✶z}{ρ₀}.
```
The `BackgroundPotentialEnergy` is the potential energy computed after adiabatically resorting
the buoyancy or density field into a reference state of minimal potential energy.
The reference state is computed by reshaping the gridded buoyancy or density field and
`sort`ing into a monotonically increasing `Vector`. This `sort`ed vector is then reshaped into
the `size(model.grid)`.

Examples
========

```jldoctest
julia> using Oceananigans

julia> using Oceanostics.PotentialEnergyEquationTerms: BackgroundPotentialEnergy

julia> grid = RectilinearGrid(size=100, z=(-1000, 0), topology=(Flat, Flat, Bounded))
1×1×100 RectilinearGrid{Float64, Flat, Flat, Bounded} on CPU with 0×0×3 halo
├── Flat x
├── Flat y
└── Bounded z ∈ [-1000.0, 0.0] regularly spaced with Δz=10.0

julia> model = NonhydrostaticModel(; grid, buoyancy=BuoyancyTracer(), tracers=(:b,))
NonhydrostaticModel{CPU, RectilinearGrid}(time = 0 seconds, iteration = 0)
├── grid: 1×1×100 RectilinearGrid{Float64, Flat, Flat, Bounded} on CPU with 0×0×3 halo
├── timestepper: QuasiAdamsBashforth2TimeStepper
├── tracers: b
├── closure: Nothing
├── buoyancy: BuoyancyTracer with ĝ = NegativeZDirection()
└── coriolis: Nothing

julia> bpe = BackgroundPotentialEnergy(model)
KernelFunctionOperation at (Center, Center, Center)
├── grid: 1×1×100 RectilinearGrid{Float64, Flat, Flat, Bounded} on CPU with 0×0×3 halo
├── kernel_function: bz_ccc (generic function with 2 methods)
└── arguments: ("KernelFunctionOperation at (Center, Center, Center)",)
```
"""
@inline function BackgroundPotentialEnergy(model; location = (Center, Center, Center),
geopotential_height = model_geopotential_height(model))

validate_location(location, "BackgroundPotentialEnergy")
isnothing(model.buoyancy) ? nothing : validate_gravity_unit_vector(model.buoyancy.gravity_unit_vector)

return BackgroundPotentialEnergy(model, model.buoyancy, geopotential_height)
end

@inline function BackgroundPotentialEnergy(model, buoyancy_model::BuoyancyTracerModel, geopotential_height)

grid = model.grid
b✶ = sort_field(model.tracers.b)

return KernelFunctionOperation{Center, Center, Center}(bz_ccc, grid, b✶)
end

linear_eos_buoyancy(grid, buoyancy, tracers) = KernelFunctionOperation{Center, Center, Center}(buoyancy_perturbationᶜᶜᶜ, grid, buoyancy, tracers)

@inline function BackgroundPotentialEnergy(model, buoyancy_model::BuoyancyLinearEOSModel, geopotential_height)

grid = model.grid
buoyancy = model.buoyancy.model
tracers = model.tracers
b = linear_eos_buoyancy(grid, buoyancy, tracers)
b✶ = sort_field(b)

return KernelFunctionOperation{Center, Center, Center}(bz_ccc, grid, b✶)
end

@inline function BackgroundPotentialEnergy(model, buoyancy_model::BuoyancyBoussinesqEOSModel, geopotential_height)

grid = model.grid
ρ = seawater_density(model; geopotential_height)
ρ✶ = sort_field_reverse(ρ)
parameters = (g = model.buoyancy.model.gravitational_acceleration,
ρ₀ = model.buoyancy.model.equation_of_state.reference_density)

return KernelFunctionOperation{Center, Center, Center}(g′z_ccc, grid, ρ✶, parameters)
end

end # module