Skip to content

Commit

Permalink
Merge pull request #133 from milankl/wind
Browse files Browse the repository at this point in the history
time dependent wind forcing
  • Loading branch information
Milan K authored Feb 18, 2020
2 parents 8ec1c3c + 3ecc368 commit 978f0da
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 42 deletions.
17 changes: 0 additions & 17 deletions .cirrus.yml

This file was deleted.

14 changes: 10 additions & 4 deletions src/Constants.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ struct Constants{T<:AbstractFloat,Tprog<:AbstractFloat}
rSST::T # tracer restoring timescale
jSST::T # tracer consumption timescale
SSTmin::T # tracer minimum
ωyr::Float64 # frequency [1/s] of Kelvin pumping (including 2π)
ωFη::Float64 # frequency [1/s] of seasonal surface forcing incl 2π
ωFx::Float64 # frequency [1/s] of seasonal wind x incl 2π
ωFy::Float64 # frequency [1/2] of seasonal wind y incl 2π
end

"""Generator function for the mutable struct Constants."""
Expand Down Expand Up @@ -54,8 +56,12 @@ function Constants{T,Tprog}(P::Parameter,G::Grid) where {T<:AbstractFloat,Tprog<
jSST = T(G.dtadvint/(P.jSST*3600*24)) # tracer consumption [1]
SSTmin = T(P.SSTmin)

# SURFACE FORCING
ωyr = -2π*P.ωyr/24/365.25/3600
# TIME DEPENDENT FORCING
ωFη = -2π*P.ωFη/24/365.25/3600
ωFx = 2π*P.ωFx/24/365.25/3600
ωFy = 2π*P.ωFy/24/365.25/3600

return Constants{T,Tprog}(RKaΔt,RKbΔt,one_minus_α,g,cD,rD,γ,cSmag,νB,rSST,jSST,SSTmin,ωyr)
return Constants{T,Tprog}( RKaΔt,RKbΔt,one_minus_α,
g,cD,rD,γ,cSmag,νB,rSST,
jSST,SSTmin,ωFη,ωFx,ωFy)
end
6 changes: 3 additions & 3 deletions src/Continuity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ function continuity_forcing!( Diag::DiagnosticVars{T,Tprog},
@boundscheck (m,n) == size(Fη) || throw(BoundsError())

# avoid recomputation
@unpack ωyr = S.constants
Fηtt = Fηt(T,t,ωyr)
@unpack ωFη = S.constants
Fηt = Ftime(T,t,ωFη)

@inbounds for j 1:n
for i 1:m
dη[i+1,j+1] = -(Tprog(dUdx[i,j+1]) + Tprog(dVdy[i+1,j])) + Tprog(Fηtt*Fη[i,j])
dη[i+1,j+1] = -(Tprog(dUdx[i,j+1]) + Tprog(dVdy[i+1,j])) + Tprog(Fηt*Fη[i,j])
end
end
end
Expand Down
26 changes: 19 additions & 7 deletions src/DefaultParameters.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
wind_forcing_y::String="constant" # "channel", "double_gyre", "shear","constant" or "none"
Fx0::Real=0.12 # wind stress strength [Pa] in x-direction
Fy0::Real=0.0 # wind stress strength [Pa] in y-direction
seasonal_wind_x::Bool=false # Change the wind stress with a sine of frequency ωFx,ωFy
seasonal_wind_y::Bool=false # same for y-component
ωFx::Real=1.0 # frequency [1/year] for x component
ωFy::Real=1.0 # frequency [1/year] for y component

# BOTTOM TOPOGRAPHY OPTIONS
topography::String="ridge" # "ridge", "seamount", "flat", "ridges", "bathtub"
Expand All @@ -37,7 +41,7 @@

# SURFACE FORCING
surface_forcing::Bool=false # yes?
ωyr::Real=1.0 # (annual) frequency [1/year]
ωFη::Real=1.0 # frequency [1/year] for surfance forcing
A::Real=3e-5 # Amplitude [m/s]
ϕk::Real=ϕ # Central latitude of Kelvin wave pumping
wk::Real=10e3 # width [m] in y of Gaussian used for surface forcing
Expand Down Expand Up @@ -114,7 +118,6 @@
@assert topo_width > 0.0 "topo_width has to be >0, $topo_width given."
@assert t_relax > 0.0 "t_relax has to be >0, $t_relax given."
@assert η_refw > 0.0 "η_refw has to be >0, $η_refw given."
@assert ωyr > 0.0 "ωyr has to be >0, $ωyr given."
@assert RKo in [3,4] "RKo has to be 3 or 4, $RKo given."
@assert Ndays > 0.0 "Ndays has to be >0, $Ndays given."
@assert nstep_diff > 0 "nstep_diff has to be >0, $nstep_diff given."
Expand Down Expand Up @@ -144,7 +147,7 @@ Creates a Parameter struct with following options and default values
T::DataType=Float32 # number format
Tprog::DataType=T # number format for prognostic variables
Tcomm::DataType=T # number format for ghost-point copies
Tcomm::DataType=Tprog # number format for ghost-point copies
# DOMAIN RESOLUTION AND RATIO
nx::Int=100 # number of grid cells in x-direction
Expand All @@ -155,7 +158,7 @@ Creates a Parameter struct with following options and default values
g::Real=10. # gravitational acceleration [m/s]
H::Real=500. # layer thickness at rest [m]
ρ::Real=1e3 # water density [kg/m^3]
ϕ::Real=45. # central latitue of the domain (for coriolis) [°]
ϕ::Real=45. # central latitude of the domain (for coriolis) [°]
ω::Real=2π/(24*3600) # Earth's angular frequency [s^-1]
R::Real=6.371e6 # Earth's radius [m]
Expand All @@ -164,6 +167,10 @@ Creates a Parameter struct with following options and default values
wind_forcing_y::String="constant" # "channel", "double_gyre", "shear","constant" or "none"
Fx0::Real=0.12 # wind stress strength [Pa] in x-direction
Fy0::Real=0.0 # wind stress strength [Pa] in y-direction
seasonal_wind_x::Bool=false # Change the wind stress with a sine of frequency ωFx,ωFy
seasonal_wind_y::Bool=false # same for y-component
ωFx::Real=1.0 # frequency [1/year] for x component
ωFy::Real=1.0 # frequency [1/year] for y component
# BOTTOM TOPOGRAPHY OPTIONS
topography::String="ridge" # "ridge", "seamount", "flat", "ridges", "bathtub"
Expand All @@ -176,10 +183,12 @@ Creates a Parameter struct with following options and default values
η_refh::Real=5. # height difference [m] of the interface relaxation profile
η_refw::Real=50e3 # width [m] of the tangent used for the interface relaxation
# SURFACE FORCING (Currently only Kelvin wave pumping at Eq.)
# SURFACE FORCING
surface_forcing::Bool=false # yes?
ωyr::Real=1.0 # (annual) frequency [1/year]
ωFη::Real=1.0 # (annual) frequency [1/year]
A::Real=3e-5 # Amplitude [m/s]
ϕk::Real=ϕ # Central latitude of Kelvin wave pumping
wk::Real=10e3 # width [m] in y of Gaussian used for surface forcing
# TIME STEPPING OPTIONS
RKo::Int=4 # Order of the RK time stepping scheme (3 or 4)
Expand Down Expand Up @@ -230,7 +239,7 @@ Creates a Parameter struct with following options and default values
# OUTPUT OPTIONS
output::Bool=false # netcdf output?
output_vars::Array{String,1}=["u","v","η","sst","q","ζ"] # which variables to output?
output_vars::Array{String,1}=["u","v","η","sst","q","ζ"] # which variables to output? "du","dv","dη" also allowed
output_dt::Real=6 # output time step [hours]
outpath::String=pwd() # path to output folder
Expand All @@ -240,5 +249,8 @@ Creates a Parameter struct with following options and default values
init_run_id::Int=0 # run id for restart from run number
init_starti::Int=-1 # timestep to start from (-1 meaning last)
get_id_mode::String="continue" # How to determine the run id: "continue" or "fill"
run_id::Int=-1 # Output with a specific run id
init_interpolation::Bool=true # Interpolate the initial conditions in case grids don't match?
"""
Parameter
6 changes: 3 additions & 3 deletions src/Forcing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ function KelvinPump(::Type{T},P::Parameter,G::Grid) where {T<:AbstractFloat}
return T.(Fη)
end

"""Time evolution of surface forcing."""
function Fηt(::Type{T},t::Int,ωyr::AbstractFloat) where {T<:AbstractFloat}
return T(sin(ωyr*t))
"""Time evolution of forcing."""
function Ftime(::Type{T},t::Int,ω::Real) where {T<:AbstractFloat}
return T(sin(ω*t))
end
34 changes: 26 additions & 8 deletions src/rhs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ function rhs_nonlinear!(u::AbstractMatrix,
PVadvection!(Diag,S)

# adding the terms
momentum_u!(Diag,S)
momentum_v!(Diag,S)
momentum_u!(Diag,S,t)
momentum_v!(Diag,S,t)
continuity!(η,Diag,S,t)
end

Expand Down Expand Up @@ -106,8 +106,8 @@ function rhs_linear!( u::AbstractMatrix,
fu!(qhu,f_v,u_v)

# adding the terms
momentum_u!(Diag,S)
momentum_v!(Diag,S)
momentum_u!(Diag,S,t)
momentum_v!(Diag,S,t)
continuity!(η,Diag,S,t)
end

Expand Down Expand Up @@ -281,7 +281,9 @@ function fu!( qhu::AbstractMatrix,
end

"""Sum up the tendencies of the non-diffusive right-hand side for the u-component."""
function momentum_u!(Diag::DiagnosticVars{T,Tprog},S::ModelSetup) where {T,Tprog}
function momentum_u!( Diag::DiagnosticVars{T,Tprog},
S::ModelSetup,
t::Int) where {T,Tprog}

@unpack du = Diag.Tendencies
@unpack qhv = Diag.Vorticity
Expand All @@ -294,15 +296,24 @@ function momentum_u!(Diag::DiagnosticVars{T,Tprog},S::ModelSetup) where {T,Tprog
@boundscheck (m+2-ep,n+2) == size(dpdx) || throw(BoundsError())
@boundscheck (m,n) == size(Fx) || throw(BoundsError())

if S.parameters.seasonal_wind_x
@unpack ωFx = S.constants
Fxt = Ftime(T,t,ωFx)
else
Fxt = one(T)
end

@inbounds for j 1:n
for i 1:m
du[i+2,j+2] = Tprog(qhv[i,j]) - Tprog(dpdx[i+1-ep,j+1]) + Tprog(Fx[i,j])
du[i+2,j+2] = Tprog(qhv[i,j]) - Tprog(dpdx[i+1-ep,j+1]) + Tprog(Fxt*Fx[i,j])
end
end
end

"""Sum up the tendencies of the non-diffusive right-hand side for the v-component."""
function momentum_v!(Diag::DiagnosticVars{T,Tprog},S::ModelSetup) where {T,Tprog}
function momentum_v!( Diag::DiagnosticVars{T,Tprog},
S::ModelSetup,
t::Int) where {T,Tprog}

@unpack dv = Diag.Tendencies
@unpack qhu = Diag.Vorticity
Expand All @@ -314,9 +325,16 @@ function momentum_v!(Diag::DiagnosticVars{T,Tprog},S::ModelSetup) where {T,Tprog
@boundscheck (m,n) == size(qhu) || throw(BoundsError())
@boundscheck (m+2,n+2) == size(dpdy) || throw(BoundsError())

if S.parameters.seasonal_wind_y
@unpack ωFy = S.constants
Fyt = Ftime(T,t,ωFy)
else
Fyt = one(T)
end

@inbounds for j 1:n
for i 1:m
dv[i+2,j+2] = -Tprog(qhu[i,j]) - Tprog(dpdy[i+1,j+1]) + Tprog(Fy[i,j])
dv[i+2,j+2] = -Tprog(qhu[i,j]) - Tprog(dpdy[i+1,j+1]) + Tprog(Fyt*Fy[i,j])
end
end
end

0 comments on commit 978f0da

Please sign in to comment.