Skip to content
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

Soil moisture and vegetation #403

Merged
merged 4 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file added input_data/albedo.nc
Binary file not shown.
Binary file modified input_data/sea_ice.nc
Binary file not shown.
Binary file modified input_data/snow.nc
Binary file not shown.
Binary file removed input_data/soil.nc
Binary file not shown.
Binary file added input_data/soil_moisture.nc
Binary file not shown.
Binary file removed input_data/surface.nc
Binary file not shown.
Binary file added input_data/vegetation.nc
Binary file not shown.
5 changes: 4 additions & 1 deletion src/SpeedyWeather.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import BitInformation: round, round!
import UnicodePlots
import ProgressMeter

# to avoid a `using Dates` to pass on DateTime arguments
export DateTime

# EXPORT MONOLITHIC INTERFACE TO SPEEDY
export run_speedy,
run_speedy!,
Expand Down Expand Up @@ -183,7 +186,7 @@ include("physics/pretty_printing.jl")

# OCEAN AND LAND
include("dynamics/ocean.jl")
include("dynamics/land.jl")
include("physics/land.jl")

# MODELS
include("dynamics/models.jl")
Expand Down
1 change: 0 additions & 1 deletion src/abstract_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ abstract type InitialConditions end
abstract type AbstractOrography{NF,Grid} end
abstract type AbstractLandSeaMask{NF,Grid} end
abstract type AbstractAlbedo{NF,Grid} end
abstract type AbstractVegetation{NF,Grid} end

# ATMOSPHERIC COLUMN FOR PARAMETERIZATIONS
abstract type AbstractColumnVariables{NF} end
Expand Down
1 change: 1 addition & 0 deletions src/dynamics/diagnostic_variables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ Base.@kwdef struct SurfaceVariables{NF<:AbstractFloat,Grid<:AbstractGrid{NF}}

precip_large_scale::Grid = zeros(Grid,nlat_half) # large scale precipitation (for output)
precip_convection::Grid = zeros(Grid,nlat_half) # convective precipitation (for output)
soil_moisture_availability::Grid = zeros(Grid,nlat_half)
end

# generator function based on a SpectralGrid
Expand Down
110 changes: 0 additions & 110 deletions src/dynamics/land.jl

This file was deleted.

36 changes: 23 additions & 13 deletions src/dynamics/models.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ $(TYPEDSIGNATURES)
Calls all `initialize!` functions for components of `model`,
except for `model.output` and `model.feedback` which are always called
at in `time_stepping!`."""
function initialize!(model::Barotropic)
function initialize!(model::Barotropic;time::DateTime = DEFAULT_DATE)
(;spectral_grid) = model

spectral_grid.nlev > 1 && @warn "Only nlev=1 supported for BarotropicModel, \
Expand All @@ -68,6 +68,7 @@ function initialize!(model::Barotropic)
# initial conditions
prognostic_variables = PrognosticVariables(spectral_grid,model)
initialize!(prognostic_variables,model.initial_conditions,model)
prognostic_variables.clock.time = time # set the time

diagnostic_variables = DiagnosticVariables(spectral_grid,model)
return Simulation(prognostic_variables,diagnostic_variables,model)
Expand Down Expand Up @@ -115,7 +116,7 @@ $(TYPEDSIGNATURES)
Calls all `initialize!` functions for components of `model`,
except for `model.output` and `model.feedback` which are always called
at in `time_stepping!` and `model.implicit` which is done in `first_timesteps!`."""
function initialize!(model::ShallowWater)
function initialize!(model::ShallowWater;time::DateTime = DEFAULT_DATE)
(;spectral_grid) = model

spectral_grid.nlev > 1 && @warn "Only nlev=1 supported for ShallowWaterModel, \
Expand All @@ -129,6 +130,7 @@ function initialize!(model::ShallowWater)
# initial conditions
prognostic_variables = PrognosticVariables(spectral_grid,model)
initialize!(prognostic_variables,model.initial_conditions,model)
prognostic_variables.clock.time = time # set the time

diagnostic_variables = DiagnosticVariables(spectral_grid,model)
return Simulation(prognostic_variables,diagnostic_variables,model)
Expand All @@ -153,7 +155,7 @@ Base.@kwdef struct PrimitiveDryModel{NF<:AbstractFloat, D<:AbstractDevice} <: Pr
# BOUNDARY CONDITIONS
land_sea_mask::AbstractLandSeaMask{NF} = LandSeaMask(spectral_grid)
ocean::AbstractOcean{NF} = SeasonalOceanClimatology(spectral_grid)
land::AbstractLand{NF} = SeasonalLandClimatology(spectral_grid)
land::AbstractLand{NF} = SeasonalLandTemperature(spectral_grid)

# PHYSICS/PARAMETERIZATIONS
physics::Bool = true
Expand Down Expand Up @@ -189,7 +191,7 @@ $(TYPEDSIGNATURES)
Calls all `initialize!` functions for components of `model`,
except for `model.output` and `model.feedback` which are always called
at in `time_stepping!` and `model.implicit` which is done in `first_timesteps!`."""
function initialize!(model::PrimitiveDry)
function initialize!(model::PrimitiveDry;time::DateTime = DEFAULT_DATE)
(;spectral_grid) = model

# numerics (implicit is initialized later)
Expand All @@ -209,10 +211,12 @@ function initialize!(model::PrimitiveDry)
# initial conditions
prognostic_variables = PrognosticVariables(spectral_grid,model)
initialize!(prognostic_variables,model.initial_conditions,model)

(;time) = prognostic_variables.clock
initialize!(prognostic_variables.ocean,time,model)
initialize!(prognostic_variables.land,time,model)
(;clock) = prognostic_variables
clock.time = time # set the time

# initialize ocean and land and synchronize clocks
initialize!(prognostic_variables.ocean,clock.time,model)
initialize!(prognostic_variables.land,clock.time,model)

diagnostic_variables = DiagnosticVariables(spectral_grid,model)
return Simulation(prognostic_variables,diagnostic_variables,model)
Expand All @@ -237,7 +241,9 @@ Base.@kwdef struct PrimitiveWetModel{NF<:AbstractFloat, D<:AbstractDevice} <: Pr
# BOUNDARY CONDITIONS
land_sea_mask::AbstractLandSeaMask{NF} = LandSeaMask(spectral_grid)
ocean::AbstractOcean{NF} = SeasonalOceanClimatology(spectral_grid)
land::AbstractLand{NF} = SeasonalLandClimatology(spectral_grid)
land::AbstractLand{NF} = SeasonalLandTemperature(spectral_grid)
soil::AbstractSoil{NF} = SeasonalSoilMoisture(spectral_grid)
vegetation::AbstractVegetation{NF} = VegetationClimatology(spectral_grid)

# PHYSICS/PARAMETERIZATIONS
physics::Bool = true
Expand Down Expand Up @@ -276,7 +282,7 @@ $(TYPEDSIGNATURES)
Calls all `initialize!` functions for components of `model`,
except for `model.output` and `model.feedback` which are always called
at in `time_stepping!` and `model.implicit` which is done in `first_timesteps!`."""
function initialize!(model::PrimitiveWet)
function initialize!(model::PrimitiveWet;time::DateTime = DEFAULT_DATE)
(;spectral_grid) = model

# numerics (implicit is initialized later)
Expand All @@ -287,6 +293,8 @@ function initialize!(model::PrimitiveWet)
initialize!(model.land_sea_mask)
initialize!(model.ocean)
initialize!(model.land)
initialize!(model.soil)
initialize!(model.vegetation)

# parameterizations
initialize!(model.boundary_layer_drag,model)
Expand All @@ -297,10 +305,12 @@ function initialize!(model::PrimitiveWet)
# initial conditions
prognostic_variables = PrognosticVariables(spectral_grid,model)
initialize!(prognostic_variables,model.initial_conditions,model)
(;clock) = prognostic_variables
clock.time = time # set the time

(;time) = prognostic_variables.clock
initialize!(prognostic_variables.ocean,time,model)
initialize!(prognostic_variables.land,time,model)
# initialize ocean and land and synchronize clocks
initialize!(prognostic_variables.ocean,clock.time,model)
initialize!(prognostic_variables.land,clock.time,model)

diagnostic_variables = DiagnosticVariables(spectral_grid,model)
return Simulation(prognostic_variables,diagnostic_variables,model)
Expand Down
34 changes: 23 additions & 11 deletions src/dynamics/ocean.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ Base.@kwdef struct SeasonalOceanClimatology{NF,Grid<:AbstractGrid{NF}} <: Abstra
"filename of sea surface temperatures"
file::String = "sea_surface_temperature.nc"

"Variable name in netcdf file"
varname::String = "sst"

"Grid the sea surface temperature file comes on"
file_Grid::Type{<:AbstractGrid} = FullGaussianGrid

Expand All @@ -39,33 +42,42 @@ function SeasonalOceanClimatology(SG::SpectralGrid;kwargs...)
end

function initialize!(ocean::SeasonalOceanClimatology{NF,Grid}) where {NF,Grid}
load_monthly_climatology!(ocean.monthly_temperature,ocean)
end

function load_monthly_climatology!(
monthly::Vector{Grid},
scheme;
varname::String = scheme.varname
) where {Grid<:AbstractGrid}

# LOAD NETCDF FILE
if ocean.path == "SpeedyWeather.jl/input_data"
path = joinpath(@__DIR__,"../../input_data",ocean.file)
if scheme.path == "SpeedyWeather.jl/input_data"
path = joinpath(@__DIR__,"../../input_data",scheme.file)
else
path = joinpath(ocean.path,ocean.file)
path = joinpath(scheme.path,scheme.file)
end
ncfile = NCDataset(path)

# create interpolator from grid in file to grid used in model
nx, ny = ncfile.dim["lon"], ncfile.dim["lat"]
npoints = nx*ny
NF_file = typeof(ncfile["sst"].attrib["_FillValue"])
sst = ocean.file_Grid(zeros(NF_file,npoints))
interp = RingGrids.interpolator(NF,ocean.monthly_temperature[1],sst)
NF_file = typeof(ncfile[varname].attrib["_FillValue"])
grid = scheme.file_Grid(zeros(NF_file,npoints))
interp = RingGrids.interpolator(Float32,monthly[1],grid)

# interpolate and store in ocean
# interpolate and store in monthly
for month in 1:12
sst_this_month = ncfile["sst"][:,:,month]
this_month = ncfile[varname][:,:,month]
ij = 0
for j in 1:ny
for i in 1:nx
ij += 1
x = sst_this_month[i,j]
sst[ij] = ismissing(x) ? ocean.missing_value : x
x = this_month[i,j]
grid[ij] = ismissing(x) ? scheme.missing_value : x
end
end
interpolate!(ocean.monthly_temperature[month],sst,interp)
interpolate!(monthly[month],grid,interp)
end
return nothing
end
Expand Down
8 changes: 4 additions & 4 deletions src/dynamics/prognostic_variables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ Base.@kwdef mutable struct PrognosticVariablesLand{NF<:AbstractFloat,Grid<:Abstr
"Snow depth [m]"
const snow_depth::Grid = zeros(Grid,nlat_half)

"Soil wetness layer 1, volume fraction [1]"
const soil_wetness_layer1::Grid = zeros(Grid,nlat_half)
"Soil moisture layer 1, volume fraction [1]"
const soil_moisture_layer1::Grid = zeros(Grid,nlat_half)

"Soil wetness layer 2, volume fraction [1]"
const soil_wetness_layer2::Grid = zeros(Grid,nlat_half)
"Soil moisture layer 2, volume fraction [1]"
const soil_moisture_layer2::Grid = zeros(Grid,nlat_half)
end

# generator function based on a SpectralGrid
Expand Down
17 changes: 11 additions & 6 deletions src/dynamics/time_integration.jl
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,17 @@ function timestep!( progn::PrognosticVariables{NF}, # all prognostic variables
model.feedback.nars_detected && return nothing # exit immediately if NaRs already present
(;time) = progn.clock # current time

ocean_timestep!(progn.ocean,time,model)
land_timestep!(progn.land,time,model)

# switch on/off all physics
model.physics && parameterization_tendencies!(diagn,progn,time,model)
model.physics || zero_tendencies!(diagn) # set tendencies to zero otherwise
if model.physics # switch on/off all physics parameterizations
# time step ocean (temperature and TODO sea ice) and land (temperature and soil moisture)
ocean_timestep!(progn.ocean,time,model)
land_timestep!(progn.land,time,model)
soil_moisture_availability!(diagn.surface,progn.land,model)

# calculate all parameterizations
parameterization_tendencies!(diagn,progn,time,model)
else # set tendencies to zero otherwise for accumulators
zero_tendencies!(diagn)
end

dynamics_tendencies!(diagn,progn,model,lf2) # dynamical core
implicit_correction!(diagn,model.implicit,progn) # semi-implicit time stepping corrections
Expand Down
5 changes: 3 additions & 2 deletions src/physics/boundary_layer.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Concrete type that disables the boundary layer drag scheme."""
struct NoBoundaryLayerDrag{NF} <: BoundaryLayerDrag{NF} end

NoBoundaryLayerDrag(SG::SpectralGrid) = NoBoundaryLayerDrag{SG.NF}()

"""NoBoundaryLayer scheme does not need any initialisation."""
function initialize!( scheme::NoBoundaryLayerDrag,
model::PrimitiveEquation)
Expand All @@ -9,8 +11,7 @@ end

"""NoBoundaryLayer scheme just passes."""
function boundary_layer_drag!( column::ColumnVariables,
scheme::NoBoundaryLayerDrag,
model::PrimitiveEquation)
scheme::NoBoundaryLayerDrag)
return nothing
end

Expand Down
1 change: 1 addition & 0 deletions src/physics/column_variables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function get_column!( C::ColumnVariables,
# TODO skin = surface approximation for now
C.skin_temperature_sea = P.ocean.sea_surface_temperature[ij]
C.skin_temperature_land = P.land.land_surface_temperature[ij]
C.soil_moisture_availability = D.surface.soil_moisture_availability[ij]
end

"""Recalculate ring index if not provided."""
Expand Down
1 change: 1 addition & 0 deletions src/physics/define_column.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Base.@kwdef mutable struct ColumnVariables{NF<:AbstractFloat} <: AbstractColumnV
surface_wind_speed::NF = 0
skin_temperature_sea::NF = 0
skin_temperature_land::NF = 0
soil_moisture_availability::NF = 0

# THERMODYNAMICS
surface_air_density::NF = 0
Expand Down
Loading
Loading