-
Notifications
You must be signed in to change notification settings - Fork 24
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
set_vars! function to easily set variables in PrognosticVariables #154
Changes from 5 commits
9486640
c6900ca
49ad052
f96ab02
a52cbc6
6660f07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,8 @@ struct BarotropicModel{NF<:AbstractFloat, D<:AbstractDevice} <: ModelSetup{D} | |
device_setup::DeviceSetup{D} | ||
end | ||
|
||
has(::Type{BarotropicModel{NF,D}}, var_name::Symbol) where {NF,D} = var_name in [:vor] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the julia> struct ABC{A,B,C}
a::Int
b::Int
end
julia> abc = ABC{Float64,Float32,Float16}(1,2)
ABC{Float64, Float32, Float16}(1, 2)
julia> t(abc::ABC{T}) where T = T(abc.a)
julia> t(abc)
1.0 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So dispatch is only performed following the first type if the others are not specified. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand why exactly, but it is required, otherwise it won't work. I did try it before. Just again: MethodError: no method matching has(::Type{SpeedyWeather.PrimitiveEquationModel{Float64, SpeedyWeather.CPUDevice}}, ::Symbol)
Closest candidates are:
has(::Type{SpeedyWeather.BarotropicModel{NF}}, ::Symbol) where NF at ~/Nextcloud/SpeedyFork/SpeedyWeather.jl/src/models.jl:23
has(::Type{SpeedyWeather.ShallowWaterModel{NF}}, ::Symbol) where NF at ~/Nextcloud/SpeedyFork/SpeedyWeather.jl/src/models.jl:46
has(::Type{SpeedyWeather.PrimitiveEquationModel{NF}}, ::Symbol) where NF at ~/Nextcloud/SpeedyFork/SpeedyWeather.jl/src/models.jl:71 |
||
|
||
""" | ||
M = ShallowWaterModel( ::Parameters, | ||
::Constants, | ||
|
@@ -41,6 +43,9 @@ struct ShallowWaterModel{NF<:AbstractFloat, D<:AbstractDevice} <: ModelSetup{D} | |
device_setup::DeviceSetup{D} | ||
end | ||
|
||
has(::Type{ShallowWaterModel{NF,D}}, var_name::Symbol) where {NF,D} = var_name in [:vor, :div, :pres] | ||
maximilian-gelbrecht marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
""" | ||
M = PrimitiveEquationModel( ::Parameters, | ||
::Constants, | ||
|
@@ -62,3 +67,13 @@ struct PrimitiveEquationModel{NF<:AbstractFloat,D<:AbstractDevice} <: ModelSetup | |
implicit::Implicit{NF} | ||
device_setup::DeviceSetup{D} | ||
end | ||
|
||
has(::Type{PrimitiveEquationModel{NF,D}}, var_name::Symbol) where {NF,D} = var_name in [:vor, :div, :temp, :humid, :pres] | ||
maximilian-gelbrecht marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
""" | ||
has(::ModelSetup, var_name::Symbol) | ||
|
||
Returns true if the model `M` has a prognostic variable `var_name`, false otherwise. The default fallback is that all variables are included. | ||
""" | ||
has(::Type{ModelSetup{D}}, var_name::Symbol) where D = var_name in [:vor, :div, :temp, :humid, :pres] | ||
maximilian-gelbrecht marked this conversation as resolved.
Show resolved
Hide resolved
|
||
has(M::ModelSetup, var_name) = has(typeof(M), var_name) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ struct SurfaceLeapfrog{NF<:AbstractFloat} | |
leapfrog::Vector{LowerTriangularMatrix{Complex{NF}}} # 2-element vector for two leapfrog time steps | ||
end | ||
|
||
struct PrognosticVariables{NF<:AbstractFloat} | ||
struct PrognosticVariables{NF<:AbstractFloat, M<:ModelSetup} | ||
# data | ||
layers::Vector{PrognosticVariablesLeapfrog{NF}} # each element = 1 vertical layer (incl leapfrog dim) | ||
pres::SurfaceLeapfrog{NF} # 2-element leapfrog vec of log of surface pressure [log(hPa)] | ||
|
@@ -44,12 +44,11 @@ end | |
# reduce size of unneeded variables if ModelSetup is provided | ||
function Base.zeros(::Type{PrognosticVariablesLayer{NF}},model::ModelSetup,lmax::Integer,mmax::Integer) where NF | ||
# use one more l for size compat with vector quantities | ||
vor = zeros(LowerTriangularMatrix{Complex{NF}},lmax+2,mmax+1) | ||
lmax,mmax = model isa BarotropicModel ? (-2,-1) : (lmax,mmax) # other variables not needed for BarotropicModel | ||
div = zeros(LowerTriangularMatrix{Complex{NF}},lmax+2,mmax+1) | ||
lmax,mmax = model isa ShallowWaterModel ? (-2,-1) : (lmax,mmax) # other variables not needed for ShallowWaterModel | ||
temp = zeros(LowerTriangularMatrix{Complex{NF}},lmax+2,mmax+1) | ||
humid = zeros(LowerTriangularMatrix{Complex{NF}},lmax+2,mmax+1) | ||
vor = has(model, :vor) ? zeros(LowerTriangularMatrix{Complex{NF}},lmax+2,mmax+1) : LowerTriangularMatrix{Complex{NF}}(undef, 0, 0) | ||
div = has(model, :div) ? zeros(LowerTriangularMatrix{Complex{NF}},lmax+2,mmax+1) : LowerTriangularMatrix{Complex{NF}}(undef, 0, 0) | ||
temp = has(model, :temp) ? zeros(LowerTriangularMatrix{Complex{NF}},lmax+2,mmax+1) : LowerTriangularMatrix{Complex{NF}}(undef, 0, 0) | ||
humid = has(model, :humid) ? zeros(LowerTriangularMatrix{Complex{NF}},lmax+2,mmax+1) : LowerTriangularMatrix{Complex{NF}}(undef, 0, 0) | ||
maximilian-gelbrecht marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return PrognosticVariablesLayer(vor,div,temp,humid) | ||
end | ||
|
||
|
@@ -81,7 +80,7 @@ function Base.zeros(::Type{PrognosticVariables{NF}}, | |
|
||
layers = [zeros(PrognosticVariablesLeapfrog{NF},lmax,mmax) for _ in 1:nlev] # k layers | ||
pres = zeros(SurfaceLeapfrog{NF},lmax,mmax) # 2 leapfrog time steps for pres | ||
return PrognosticVariables(layers,pres,lmax,mmax,N_LEAPFROG,nlev) | ||
return PrognosticVariables{NF,ModelSetup}(layers,pres,lmax,mmax,N_LEAPFROG,nlev) | ||
end | ||
|
||
# pass on model to reduce size | ||
|
@@ -92,7 +91,199 @@ function Base.zeros(::Type{PrognosticVariables{NF}}, | |
nlev::Integer) where NF | ||
|
||
layers = [zeros(PrognosticVariablesLeapfrog{NF},model,lmax,mmax) for _ in 1:nlev] # k layers | ||
_lmax,_mmax = model isa BarotropicModel ? (-2,-1) : (lmax,mmax) # pressure not needed for BarotropicModel | ||
pres = zeros(SurfaceLeapfrog{NF},_lmax,_mmax) # 2 leapfrog time steps for pres | ||
return PrognosticVariables(layers,pres,lmax,mmax,N_LEAPFROG,nlev) | ||
pres = has(model, :pres) ? zeros(SurfaceLeapfrog{NF},lmax,mmax) : zeros(SurfaceLeapfrog{NF},-2,-1) # 2 leapfrog time steps for pres | ||
return PrognosticVariables{NF,typeof(model)}(layers,pres,lmax,mmax,N_LEAPFROG,nlev) | ||
end | ||
|
||
has(progn::PrognosticVariables{NF,M}, var_name::Symbol) where {NF,M} = has(M, var_name) | ||
|
||
# SET_VAR FUNCTIONS TO ASSIGN NEW VALUES TO PrognosticVariables | ||
|
||
""" | ||
set_var!(progn::PrognosticVariables{NF}, | ||
varname::Symbol, | ||
var::Vector{<:LowerTriangularMatrix}; | ||
lf::Integer=1) where NF | ||
|
||
Sets the prognostic variable with the name `varname` in all layers at leapfrog index `lf` | ||
with values given in `var` a vector with all information for all layers in spectral space. | ||
""" | ||
function set_var!(progn::PrognosticVariables{NF}, | ||
varname::Symbol, | ||
var::Vector{<:LowerTriangularMatrix}; | ||
lf::Integer=1) where NF | ||
|
||
@assert length(var) == length(progn.layers) | ||
maximilian-gelbrecht marked this conversation as resolved.
Show resolved
Hide resolved
|
||
@assert has(progn, varname) | ||
Comment on lines
+116
to
+117
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reminder to self that we should do something about error messages in general. I like the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I didn't know that before, but |
||
|
||
for (progn_layer, var_layer) in zip(progn.layers, var) | ||
_set_var_core!(getfield(progn_layer.leapfrog[lf], varname), var_layer) | ||
end | ||
|
||
return progn | ||
end | ||
|
||
function _set_var_core!(var_old::LowerTriangularMatrix{T}, var_new::LowerTriangularMatrix{R}) where {T,R} | ||
maximilian-gelbrecht marked this conversation as resolved.
Show resolved
Hide resolved
|
||
lmax,mmax = size(var_old) .- (2,1) | ||
var_new_trunc = spectral_truncation!(var_new, lmax+1, mmax) | ||
copyto!(var_old, var_new_trunc) | ||
end | ||
|
||
""" | ||
set_var!(progn::PrognosticVariables{NF}, | ||
varname::Symbol, | ||
var::Vector{<:AbstractGrid}; | ||
lf::Integer=1) where NF | ||
|
||
Sets the prognostic variable with the name `varname` in all layers at leapfrog index `lf` | ||
with values given in `var` a vector with all information for all layers in grid space. | ||
""" | ||
function set_var!(progn::PrognosticVariables{NF}, | ||
varname::Symbol, | ||
var::Vector{<:AbstractGrid}; | ||
lf::Integer=1) where NF | ||
|
||
@assert length(var) == length(progn.layers) | ||
|
||
var_sph = [spectral(var_layer) for var_layer in var] | ||
|
||
return set_var!(progn, varname, var_sph; lf=lf) | ||
end | ||
|
||
""" | ||
set_var!(progn::PrognosticVariables{NF}, | ||
varname::Symbol, | ||
var::Vector{<:AbstractGrid}, | ||
M::ModelSetup; | ||
lf::Integer=1) where NF | ||
|
||
Sets the prognostic variable with the name `varname` in all layers at leapfrog index `lf` | ||
with values given in `var` a vector with all information for all layers in grid space. | ||
""" | ||
function set_var!(progn::PrognosticVariables{NF}, | ||
varname::Symbol, | ||
var::Vector{<:AbstractGrid}, | ||
M::ModelSetup; | ||
lf::Integer=1) where NF | ||
|
||
@assert length(var) == length(progn.layers) | ||
|
||
var_sph = [spectral(var_layer, M.spectral_transform) for var_layer in var] | ||
|
||
return set_var!(progn, varname, var_sph; lf=lf) | ||
end | ||
|
||
""" | ||
set_var!(progn::PrognosticVariables{NF}, | ||
varname::Symbol, | ||
var::Vector{<:AbstractGrid}, | ||
Grid::Type{<:AbstractGrid}=FullGaussianGrid; | ||
lf::Integer=1) where NF | ||
|
||
Sets the prognostic variable with the name `varname` in all layers at leapfrog index `lf` | ||
with values given in `var` a vector with all information for all layers in grid space. | ||
""" | ||
function set_var!(progn::PrognosticVariables{NF}, | ||
varname::Symbol, | ||
var::Vector{<:AbstractMatrix}, | ||
Grid::Type{<:AbstractGrid}=FullGaussianGrid; | ||
lf::Integer=1) where NF | ||
|
||
@assert length(var) == length(progn.layers) | ||
|
||
var_grid = [spectral(var_layer, Grid) for var_layer in var] | ||
|
||
return set_var!(progn, varname, var_grid; lf=lf) | ||
end | ||
|
||
""" | ||
set_vorticity!(progn::PrognosticVariables, varargs...; kwargs...) | ||
|
||
See [`get_var`](@ref) | ||
""" | ||
set_vorticity!(progn::PrognosticVariables, varargs...; kwargs...) = set_var!(progn, :vor, varargs...; kwargs...) | ||
|
||
""" | ||
set_divergence!(progn::PrognosticVariables, varargs...; kwargs...) | ||
|
||
See [`get_var`](@ref) | ||
""" | ||
set_divergence!(progn::PrognosticVariables, varargs...; kwargs...) = set_var!(progn, :div, varargs...; kwargs...) | ||
|
||
""" | ||
set_temperature!(progn::PrognosticVariables, varargs...; kwargs...) | ||
|
||
See [`get_var`](@ref) | ||
""" | ||
set_temperature!(progn::PrognosticVariables, varargs...; kwargs...) = set_var!(progn, :temp, varargs...; kwargs...) | ||
|
||
""" | ||
set_humidity!(progn::PrognosticVariables, varargs...; kwargs...) | ||
|
||
See [`get_var`](@ref) | ||
""" | ||
set_humidity!(progn::PrognosticVariables, varargs...; kwargs...) = set_var!(progn, :humid, varargs...; kwargs...) | ||
|
||
""" | ||
set_pressure!(progn::PrognosticVariables{NF}, | ||
pressure::LowerTriangularMatrix; | ||
lf::Integer=1) where NF | ||
|
||
Sets the prognostic variable with the surface pressure in spectral space at leapfrog index `lf`. | ||
""" | ||
function set_pressure!(progn::PrognosticVariables{NF}, | ||
pressure::LowerTriangularMatrix; | ||
lf::Integer=1) where NF | ||
|
||
_set_var_core!(progn.pres.leapfrog[lf], pressure) | ||
|
||
return progn | ||
end | ||
|
||
""" | ||
set_pressure!(progn::PrognosticVariables{NF}, | ||
pressure::AbstractGrid, | ||
M::ModelSetup; | ||
lf::Integer=1) where NF | ||
|
||
Sets the prognostic variable with the surface pressure in grid space at leapfrog index `lf`. | ||
""" | ||
set_pressure!(progn::PrognosticVariables, pressure::AbstractGrid, M::ModelSetup; lf::Integer=1) = set_pressure!(progn, spectral(pressure, M.spectral_transform); lf=lf) | ||
|
||
""" | ||
set_pressure!(progn::PrognosticVariables{NF}, | ||
pressure::AbstractGrid, | ||
lf::Integer=1) where NF | ||
|
||
Sets the prognostic variable with the surface pressure in grid space at leapfrog index `lf`. | ||
""" | ||
set_pressure!(progn::PrognosticVariables, pressure::AbstractGrid, lf::Integer=1) = set_pressure!(progn, spectral(pressure); lf=lf) | ||
|
||
""" | ||
set_pressure!(progn::PrognosticVariables{NF}, | ||
pressure::AbstractMatrix, | ||
Grid::Type{<:AbstractGrid}, | ||
lf::Integer=1) where NF | ||
|
||
Sets the prognostic variable with the surface pressure in grid space at leapfrog index `lf`. | ||
""" | ||
set_pressure!(progn::PrognosticVariables, pressure::AbstractMatrix, Grid::Type{<:AbstractGrid}, lf::Integer=1) = set_pressure!(progn, spectral(pressure, Grid); lf=lf) | ||
|
||
""" | ||
get_var(progn::PrognosticVariables, var_name::Symbol; lf::Integer=1) | ||
|
||
Returns the prognostic variable `var_name` at leapfrog index `lf` as a `Vector{LowerTriangularMatrices}`. | ||
""" | ||
function get_var(progn::PrognosticVariables, var_name::Symbol; lf::Integer=1) | ||
@assert has(progn, var_name) | ||
return [getfield(layer.leapfrog[lf], var_name) for layer in progn.layers] | ||
end | ||
|
||
get_vorticity(progn::PrognosticVariables; kwargs...) = get_var(progn, :vor; kwargs...) | ||
get_divergence(progn::PrognosticVariables; kwargs...) = get_var(progn, :div; kwargs...) | ||
get_temperature(progn::PrognosticVariables; kwargs...) = get_var(progn, :temp; kwargs...) | ||
get_humidity(progn::PrognosticVariables; kwargs...) = get_var(progn, :humid; kwargs...) | ||
get_pressure(progn::PrognosticVariables; lf::Integer=1) = progn.pres.leapfrog[lf] | ||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neat. I like it.