Skip to content
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9d733ff
Add tidal potential to PrescribedAtmosphere
glwagner Mar 7, 2025
9183b20
Merge remote-tracking branch 'origin/main' into glw-ss/tidal-potential
simone-silvestri Mar 8, 2025
787b4b3
try it out
simone-silvestri Mar 8, 2025
c359118
try it out here for now
simone-silvestri Mar 8, 2025
928eea8
add it to JRA55
simone-silvestri Mar 8, 2025
7ec088c
surface layer height
simone-silvestri Mar 8, 2025
b0845a6
index
simone-silvestri Mar 8, 2025
25ec84e
finding the forcing
simone-silvestri Mar 8, 2025
141cec9
forcing
simone-silvestri Mar 8, 2025
577258a
in the potential
simone-silvestri Mar 8, 2025
9a570d6
barotropic tide
simone-silvestri Mar 8, 2025
2fffee4
keep this for the moment
simone-silvestri Mar 8, 2025
ea208b1
add a function for this
simone-silvestri Mar 9, 2025
7974435
Merge remote-tracking branch 'origin/main' into glw-ss/tidal-potential
simone-silvestri Mar 9, 2025
1c69aa9
get barotropic potential
simone-silvestri Mar 9, 2025
27524bc
small change
simone-silvestri Mar 9, 2025
baf42d6
put it up
simone-silvestri Mar 9, 2025
d8bc7ac
add boundary conditions
simone-silvestri Mar 9, 2025
22f070a
fix
simone-silvestri Mar 9, 2025
2dfcaac
small example
simone-silvestri Mar 10, 2025
4ae2e11
Merge branch 'main' into glw-ss/tidal-potential
simone-silvestri Mar 10, 2025
9590694
remove barotropic example
simone-silvestri Mar 10, 2025
8d086c5
Merge branch 'glw-ss/tidal-potential' of github.com:CliMA/ClimaOcean.…
simone-silvestri Mar 10, 2025
d4c4469
disable GPU examples
simone-silvestri Mar 10, 2025
0f47761
reenable examples
simone-silvestri Mar 10, 2025
5f459e7
interpolate tidal potential
simone-silvestri Mar 10, 2025
48a2774
bugfix
simone-silvestri Mar 10, 2025
2e76fe8
add a grid
simone-silvestri Mar 10, 2025
7b7dadf
do not compute if not there
simone-silvestri Mar 10, 2025
52af83e
updates
simone-silvestri Mar 10, 2025
0b2c78b
Merge branch 'glw-ss/tidal-potential' of github.com:CliMA/ClimaOcean.…
simone-silvestri Mar 10, 2025
51e3891
Merge remote-tracking branch 'origin/main' into glw-ss/tidal-potential
glwagner Mar 13, 2025
a564382
Updates for tidal
glwagner Mar 13, 2025
5fa08f5
Temp fix for bathy bug
glwagner Mar 13, 2025
255d80f
Merge remote-tracking branch 'origin/main' into glw-ss/tidal-potential
glwagner Mar 13, 2025
774ccf9
Merge remote-tracking branch 'origin/main' into glw-ss/tidal-potential
glwagner Mar 14, 2025
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
9 changes: 6 additions & 3 deletions examples/near_global_ocean_simulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ radiation = Radiation(arch)
# The number of snapshots that are loaded into memory is determined by
# the `backend`. Here, we load 41 snapshots at a time into memory.

atmosphere = JRA55PrescribedAtmosphere(arch; backend=JRA55NetCDFBackend(41))
tidal_potential = FieldTimeSeries("tidal_potential.jld2", "Φ"; architecture=GPU(), backend=InMemory(41))
tidal_potential = FieldTimeSeries("tidal_potential.jld2", "Φ"; architecture=GPU(), backend=InMemory(41), boundary_conditions=FieldBoundaryConditions(tidal_potential.grid, (Center, Center, Nothing)))
Oceananigans.BoundaryConditions.fill_halo_regions!(tidal_potential)
atmosphere = JRA55PrescribedAtmosphere(arch; tidal_potential, backend=JRA55NetCDFBackend(41))

# ## The coupled simulation

Expand All @@ -116,7 +119,7 @@ coupled_model = OceanSeaIceModel(ocean; atmosphere, radiation)
# We then create a coupled simulation. We start with a small-ish time step of 90 seconds.
# We run the simulation for 10 days with this small-ish time step.

simulation = Simulation(coupled_model; Δt=90, stop_time=10days)
simulation = Simulation(coupled_model; Δt=60, stop_time=30days)

# We define a callback function to monitor the simulation's progress,

Expand Down Expand Up @@ -175,7 +178,7 @@ run!(simulation)

# After the initial spin up of 10 days, we can increase the time-step and run for longer.

simulation.stop_time = 60days
simulation.stop_time = 120days
simulation.Δt = 10minutes
run!(simulation)

Expand Down
2 changes: 1 addition & 1 deletion examples/one_degree_simulation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ tracer_advection = Centered()
ocean = ocean_simulation(grid;
momentum_advection,
tracer_advection,
closure,
# closure,
forcing,
free_surface)

Expand Down
8 changes: 5 additions & 3 deletions src/DataWrangling/JRA55.jl
Original file line number Diff line number Diff line change
Expand Up @@ -652,7 +652,8 @@ Return a `PrescribedAtmosphere` representing JRA55 reanalysis data.
function JRA55PrescribedAtmosphere(architecture::AA, time_indices=Colon();
backend = nothing,
time_indexing = Cyclical(),
reference_height = 10, # meters
surface_layer_height = 10, # meters
tidal_potential = nothing,
include_rivers_and_icebergs = false,
other_kw...)

Expand Down Expand Up @@ -701,7 +702,7 @@ function JRA55PrescribedAtmosphere(architecture::AA, time_indices=Colon();

FT = eltype(ua)
boundary_layer_height = convert(FT, 600)
reference_height = convert(FT, reference_height)
surface_layer_height = convert(FT, surface_layer_height)
thermodynamics_parameters = PrescribedAtmosphereThermodynamicsParameters(FT)
grid = ua.grid
metadata = JRA55Data()
Expand All @@ -714,10 +715,11 @@ function JRA55PrescribedAtmosphere(architecture::AA, time_indices=Colon();
tracers,
freshwater_flux,
auxiliary_freshwater_flux,
tidal_potential,
downwelling_radiation,
thermodynamics_parameters,
times,
reference_height,
surface_layer_height,
boundary_layer_height)
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
using Oceananigans.Operators: intrinsic_vector
using Oceananigans.Grids: _node
using Oceananigans.Grids: _node, AbstractGrid
using Oceananigans.Fields: FractionalIndices
using Oceananigans.OutputReaders: TimeInterpolator

using ...OceanSimulations: forcing_barotropic_potential

using ClimaOcean.OceanSimulations: BarotropicPotentialForcing, forcing_barotropic_potential
using ClimaOcean.OceanSeaIceModels.PrescribedAtmospheres: PrescribedAtmosphere
import ClimaOcean.OceanSeaIceModels: interpolate_atmosphere_state!

# TODO: move to PrescribedAtmospheres
"""Interpolate the atmospheric state onto the ocean / sea-ice grid."""
function interpolate_atmosphere_state!(interfaces, atmosphere::PrescribedAtmosphere, coupled_model)
ocean = coupled_model.ocean
atmosphere_grid = atmosphere.grid

# Basic model properties
grid = ocean.model.grid
Expand Down Expand Up @@ -40,13 +40,12 @@ function interpolate_atmosphere_state!(interfaces, atmosphere::PrescribedAtmosph

# Extract info for time-interpolation
u = atmosphere.velocities.u # for example
atmosphere_times = u.times
atmosphere_backend = u.backend
atmosphere_time_indexing = u.time_indexing

atmosphere_fields = coupled_model.interfaces.exchanger.exchange_atmosphere_state
space_fractional_indices = coupled_model.interfaces.exchanger.atmosphere_exchanger
exchange_grid = coupled_model.interfaces.exchanger.exchange_grid
atmosphere_fields = interfaces.exchanger.exchange_atmosphere_state
space_fractional_indices = interfaces.exchanger.atmosphere_exchanger
exchange_grid = interfaces.exchanger.exchange_grid

# Simplify NamedTuple to reduce parameter space consumption.
# See https://github.com/CliMA/ClimaOcean.jl/issues/116.
Expand Down Expand Up @@ -106,12 +105,32 @@ function interpolate_atmosphere_state!(interfaces, atmosphere::PrescribedAtmosph
auxiliary_time_indexing)
end

# Set ocean barotropic pressure forcing
barotropic_potential = forcing_barotropic_potential(ocean)
ρₒ = coupled_model.interfaces.ocean_properties.reference_density
if !isnothing(barotropic_potential)
parent(barotropic_potential) .= parent(atmosphere_data.p) ./ ρₒ
# barotropic potential in PrescribedAtmosphere?
atmosphere_pressure = atmosphere.pressure.data
tidal_potential = atmosphere.tidal_potential

if !isnothing(tidal_potential)
tidal_potential_data = tidal_potential.data
else
tidal_potential_data = nothing
end

# Which forcing is this going to be?
barotropic_potential = forcing_barotropic_potential(ocean)

launch!(arch, grid, kernel_parameters,
_compute_barotropic_potential!,
barotropic_potential,
grid,
space_fractional_indices,
time_interpolator,
atmosphere_pressure,
tidal_potential_data,
interfaces.ocean_properties.reference_density,
atmosphere_backend,
atmosphere_time_indexing)

return nothing
end

@inline get_fractional_index(i, j, ::Nothing) = nothing
Expand Down Expand Up @@ -169,6 +188,41 @@ end
end
end

@inline interpolate_tidal_potential(::Nothing, grid, args) = zero(grid)
@inline interpolate_tidal_potential(tidal_potential, grid, args) = interp_atmos_time_series(tidal_potential, args...)

# Fallback
@kernel _compute_barotropic_potential!(::Nothing, args...) = nothing

@kernel function _compute_barotropic_potential!(barotropic_potential,
grid,
space_fractional_indices,
time_interpolator,
atmos_pressure,
tidal_potential,
ocean_reference_density,
atmos_backend,
atmos_time_indexing)

i, j = @index(Global, NTuple)

ρₒ = ocean_reference_density

ii = space_fractional_indices.i
jj = space_fractional_indices.j
fi = get_fractional_index(i, j, ii)
fj = get_fractional_index(i, j, jj)

x_itp = FractionalIndices(fi, fj, nothing)
t_itp = time_interpolator
atmos_args = (x_itp, t_itp, atmos_backend, atmos_time_indexing)

pa = interp_atmos_time_series(atmos_pressure, atmos_args...) # yes this is a re-interpolation
Φt = interpolate_tidal_potential(tidal_potential, grid, atmos_args)

@inbounds barotropic_potential[i, j, 1] = pa / ρₒ + Φt / ρₒ
end

@kernel function _interpolate_auxiliary_freshwater_flux!(freshwater_flux,
interface_grid,
clock,
Expand Down Expand Up @@ -198,6 +252,9 @@ end
##### Utility for interpolating tuples of fields
#####

# Assumption: a Nothing object interpolates to zero!!
@inline interp_atmos_time_series(::Nothing, X, time, grid::AbstractGrid, args...) = zero(grid)

# Note: assumes loc = (c, c, nothing) (and the third location should not matter.)
@inline interp_atmos_time_series(J::AbstractArray, x_itp::FractionalIndices, t_itp, args...) =
interpolate(x_itp, t_itp, J, args...)
Expand Down
30 changes: 20 additions & 10 deletions src/OceanSeaIceModels/PrescribedAtmospheres.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module PrescribedAtmospheres
using Oceananigans.Grids: grid_name
using Oceananigans.Utils: prettysummary, Time
using Oceananigans.Fields: Center
using Oceananigans.BoundaryConditions: FieldBoundaryConditions
using Oceananigans.OutputReaders: FieldTimeSeries, update_field_time_series!, extract_field_time_series
using Oceananigans.TimeSteppers: Clock, tick!

Expand Down Expand Up @@ -289,7 +290,7 @@ const PATP = PrescribedAtmosphereThermodynamicsParameters
##### Prescribed atmosphere (as opposed to dynamically evolving / prognostic)
#####

mutable struct PrescribedAtmosphere{FT, M, G, T, U, P, C, F, I, R, TP, TI}
mutable struct PrescribedAtmosphere{FT, M, G, T, U, P, C, F, I, ΦT, R, TP, TI}
grid :: G
clock :: Clock{T}
metadata :: M
Expand All @@ -298,6 +299,7 @@ mutable struct PrescribedAtmosphere{FT, M, G, T, U, P, C, F, I, R, TP, TI}
tracers :: C
freshwater_flux :: F
auxiliary_freshwater_flux :: I
tidal_potential :: ΦT # this really belongs elsewhere, but we put it here for now
downwelling_radiation :: R
thermodynamics_parameters :: TP
times :: TI
Expand All @@ -320,32 +322,37 @@ function Base.show(io::IO, pa::PrescribedAtmosphere)
end

function default_atmosphere_velocities(grid, times)
ua = FieldTimeSeries{Center, Center, Nothing}(grid, times)
va = FieldTimeSeries{Center, Center, Nothing}(grid, times)
bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing))
ua = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=bcs)
va = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=bcs)
return (u=ua, v=va)
end

function default_atmosphere_tracers(grid, times)
Ta = FieldTimeSeries{Center, Center, Nothing}(grid, times)
qa = FieldTimeSeries{Center, Center, Nothing}(grid, times)
bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing))
Ta = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=bcs)
qa = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=bcs)
parent(Ta) .= 273.15 + 20
return (T=Ta, q=qa)
end

function default_downwelling_radiation(grid, times)
Qℓ = FieldTimeSeries{Center, Center, Nothing}(grid, times)
Qs = FieldTimeSeries{Center, Center, Nothing}(grid, times)
bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing))
Qℓ = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=bcs)
Qs = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=bcs)
return TwoBandDownwellingRadiation(shortwave=Qs, longwave=Qℓ)
end

function default_freshwater_flux(grid, times)
rain = FieldTimeSeries{Center, Center, Nothing}(grid, times)
snow = FieldTimeSeries{Center, Center, Nothing}(grid, times)
bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing))
rain = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=bcs)
snow = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=bcs)
return (; rain, snow)
end

function default_atmosphere_pressure(grid, times)
pa = FieldTimeSeries{Center, Center, Nothing}(grid, times)
bcs = FieldBoundaryConditions(grid, (Center, Center, Nothing))
pa = FieldTimeSeries{Center, Center, Nothing}(grid, times; boundary_conditions=bcs)
parent(pa) .= 101325
return pa
end
Expand Down Expand Up @@ -375,6 +382,7 @@ end
boundary_layer_height = 600 # meters,
thermodynamics_parameters = PrescribedAtmosphereThermodynamicsParameters(FT),
auxiliary_freshwater_flux = nothing,
tidal_potential = nothing,
velocities = default_atmosphere_velocities(grid, times),
tracers = default_atmosphere_tracers(grid, times),
pressure = default_atmosphere_pressure(grid, times),
Expand All @@ -391,6 +399,7 @@ function PrescribedAtmosphere(grid, times;
boundary_layer_height = convert(eltype(grid), 600),
thermodynamics_parameters = nothing,
auxiliary_freshwater_flux = nothing,
tidal_potential = nothing,
velocities = default_atmosphere_velocities(grid, times),
tracers = default_atmosphere_tracers(grid, times),
pressure = default_atmosphere_pressure(grid, times),
Expand All @@ -410,6 +419,7 @@ function PrescribedAtmosphere(grid, times;
tracers,
freshwater_flux,
auxiliary_freshwater_flux,
tidal_potential,
downwelling_radiation,
thermodynamics_parameters,
times,
Expand Down
9 changes: 9 additions & 0 deletions src/OceanSimulations/barotropic_potential_forcing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ const YDirectionBPF = BarotropicPotentialForcing{<:YDirection}
forcing_barotropic_potential(something) = nothing
forcing_barotropic_potential(f::BarotropicPotentialForcing) = f.potential.data

function forcing_barotropic_potential(tf::Tuple)
n = findfirst(f -> f isa BarotropicPotentialForcing, tf)
if isnothing(n)
return nothing
else
return forcing_barotropic_potential(tf[n])
end
end

function forcing_barotropic_potential(mf::MultipleForcings)
n = findfirst(f -> f isa BarotropicPotentialForcing, mf.forcing)
if isnothing(n)
Expand Down
20 changes: 20 additions & 0 deletions wget-log
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mistake probably

Large diffs are not rendered by default.