Skip to content

Commit 033239f

Browse files
Single structure (#175)
* Update .gitignore * Adding new runid Changed the id and path of the output to match the way SpeedyWeather does it Matching the upstream repo * add Manifest.toml to .gitignore * Fixing the output function on main Just correcting the error with path versus outpath, restoring the name initpath in Parameters, all else the same * adding what's needed to move everything to a single structure Modified everything so that only a single structure is needed * removing redundant functions * removing /my_scripts from gitignore * removing the checkpointed time integration for now * re-added a function definition * Update ghost_points.jl * removing manifest file * minor changes based on comments * Found one place where I used `T` and should have used `Tprog` * Reverting the changes to default parameters, leaving the addition of some adjoint/checkpointing stuff. I can maybe delete this later if needed --------- Co-authored-by: Milan Klöwer <[email protected]>
1 parent cd0cb6a commit 033239f

10 files changed

+214
-89
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ parameter.txt
99
# It records a fixed state of all packages used by the project. As such, it should not be
1010
# committed for packages, but should be committed for applications that require a static
1111
# environment.
12-
Manifest.toml
12+
Manifest.toml
13+

src/ShallowWaters.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ module ShallowWaters
88
include("grid.jl")
99
include("constants.jl")
1010
include("forcing.jl")
11+
include("preallocate.jl")
1112
include("model_setup.jl")
1213
include("initial_conditions.jl")
13-
include("preallocate.jl")
1414

1515
include("time_integration.jl")
1616
include("ghost_points.jl")

src/default_parameters.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,15 @@
7070
α::Real=2. # lateral boundary condition parameter
7171
# 0 free-slip, 0<α<2 partial-slip, 2 no-slip
7272

73+
# PARAMETERS FOR ADJOINT METHOD
74+
data_steps::StepRange{Int,Int} = 0:1:0 # Timesteps where data exists
75+
data::Array{Float32, 1} = [0.] # model data
76+
J::Float64 = 0. # Placeholder for cost function evaluation
77+
j::Int = 1 # For keeping track of the entry in data
78+
79+
# CHECKPOINTING VARIABLES
80+
i::Int = 0 # Placeholder for current timestep, needed for Checkpointing.jl
81+
7382
# MOMENTUM ADVECTION OPTIONS
7483
adv_scheme::String="ArakawaHsu" # "Sadourny" or "ArakawaHsu"
7584
dynamics::String="nonlinear" # "linear" or "nonlinear"
@@ -273,4 +282,4 @@ Creates a Parameter struct with following options and default values
273282
run_id::Int=-1 # Output with a specific run id
274283
init_interpolation::Bool=true # Interpolate the initial conditions in case grids don't match?
275284
"""
276-
Parameter
285+
Parameter

src/ghost_points.jl

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,42 @@ function add_halo( u::Array{T,2},
3232
return u,v,η,sst
3333
end
3434

35+
""" Extends the matrices u,v,η,sst with a halo of ghost points for boundary conditions."""
36+
function add_halo( u::Array{T,2},
37+
v::Array{T,2},
38+
η::Array{T,2},
39+
sst::Array{T,2},
40+
G::Grid,
41+
P::Parameter,
42+
C::Constants) where {T<:AbstractFloat}
43+
44+
@unpack nx,ny,nux,nuy,nvx,nvy = G
45+
@unpack halo,haloη,halosstx,halossty = G
46+
47+
# Add zeros to satisfy kinematic boundary conditions
48+
u = cat(zeros(T,halo,nuy),u,zeros(T,halo,nuy),dims=1)
49+
u = cat(zeros(T,nux+2*halo,halo),u,zeros(T,nux+2*halo,halo),dims=2)
50+
51+
v = cat(zeros(T,halo,nvy),v,zeros(T,halo,nvy),dims=1)
52+
v = cat(zeros(T,nvx+2*halo,halo),v,zeros(T,nvx+2*halo,halo),dims=2)
53+
54+
η = cat(zeros(T,haloη,ny),η,zeros(T,haloη,ny),dims=1)
55+
η = cat(zeros(T,nx+2*haloη,haloη),η,zeros(T,nx+2*haloη,haloη),dims=2)
56+
57+
sst = cat(zeros(T,halosstx,ny),sst,zeros(T,halosstx,ny),dims=1)
58+
sst = cat(zeros(T,nx+2*halosstx,halossty),sst,zeros(T,nx+2*halosstx,halossty),dims=2)
59+
60+
# SCALING
61+
@unpack scale,scale_sst = C
62+
u *= scale
63+
v *= scale
64+
sst *= scale_sst
65+
66+
ghost_points!(u,v,η,P,C)
67+
ghost_points_sst!(sst,P,G)
68+
return u,v,η,sst
69+
end
70+
3571
"""Cut off the halo from the prognostic variables."""
3672
function remove_halo( u::Array{T,2},
3773
v::Array{T,2},
@@ -51,6 +87,94 @@ function remove_halo( u::Array{T,2},
5187
return ucut,vcut,ηcut,sstcut
5288
end
5389

90+
"""Cut off the halo from the prognostic variables."""
91+
function remove_halo( u::Array{T,2},
92+
v::Array{T,2},
93+
η::Array{T,2},
94+
sst::Array{T,2},
95+
G::Grid,
96+
C::Constants
97+
) where {T<:AbstractFloat}
98+
99+
@unpack halo,haloη,halosstx,halossty = G
100+
@unpack scale_inv,scale_sst = C
101+
102+
# undo scaling as well
103+
@views ucut = scale_inv*u[halo+1:end-halo,halo+1:end-halo]
104+
@views vcut = scale_inv*v[halo+1:end-halo,halo+1:end-halo]
105+
@views ηcut = η[haloη+1:end-haloη,haloη+1:end-haloη]
106+
@views sstcut = sst[halosstx+1:end-halosstx,halossty+1:end-halossty]/scale_sst
107+
108+
return ucut,vcut,ηcut,sstcut
109+
end
110+
111+
"""Decide on boundary condition P.bc which ghost point function to execute."""
112+
function ghost_points!( u::AbstractMatrix,
113+
v::AbstractMatrix,
114+
η::AbstractMatrix,
115+
P::Parameter,
116+
C::Constants)
117+
118+
@unpack bc,Tcomm = P
119+
@unpack one_minus_α = C
120+
121+
if bc == "periodic"
122+
ghost_points_u_periodic!(Tcomm,u,one_minus_α)
123+
ghost_points_v_periodic!(Tcomm,v)
124+
ghost_points_η_periodic!(Tcomm,η)
125+
else
126+
ghost_points_u_nonperiodic!(u,one_minus_α)
127+
ghost_points_v_nonperiodic!(v,one_minus_α)
128+
ghost_points_η_nonperiodic!(η)
129+
end
130+
end
131+
132+
"""Decide on boundary condition P.bc which ghost point function to execute."""
133+
function ghost_points_uv!( u::AbstractMatrix,
134+
v::AbstractMatrix,
135+
P::Parameter,
136+
C::Constants)
137+
138+
@unpack bc,Tcomm = P
139+
@unpack one_minus_α = C
140+
141+
if bc == "periodic"
142+
ghost_points_u_periodic!(Tcomm,u,one_minus_α)
143+
ghost_points_v_periodic!(Tcomm,v)
144+
else
145+
ghost_points_u_nonperiodic!(u,one_minus_α)
146+
ghost_points_v_nonperiodic!(v,one_minus_α)
147+
end
148+
end
149+
150+
"""Decide on boundary condition P.bc which ghost point function to execute."""
151+
function ghost_points_η!( η::AbstractMatrix,
152+
P::Parameter)
153+
154+
@unpack bc, Tcomm = P
155+
156+
if bc == "periodic"
157+
ghost_points_η_periodic!(Tcomm,η)
158+
else
159+
ghost_points_η_nonperiodic!(η)
160+
end
161+
end
162+
163+
"""Decide on boundary condition P.bc which ghost point function to execute."""
164+
function ghost_points_sst!( sst::AbstractMatrix,
165+
P::Parameter,
166+
G::Grid)
167+
168+
@unpack bc,Tcomm = P
169+
@unpack halosstx,halossty = G
170+
171+
if bc == "periodic"
172+
ghost_points_sst_periodic!(Tcomm,sst,halosstx,halossty)
173+
else
174+
ghost_points_sst_nonperiodic!(sst,halosstx,halossty)
175+
end
176+
end
177+
54178
""" Copy ghost points for u from inside to the halo in the nonperiodic case. """
55179
function ghost_points_u_nonperiodic!(u::AbstractMatrix{T},one_minus_α::T) where T
56180
n,m = size(u)

src/initial_conditions.jl

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
"""
2-
P = ProgVars{T}(u,v,η,sst)
3-
4-
Struct containing the prognostic variables u,v,η and sst.
5-
"""
6-
struct PrognosticVars{T<:AbstractFloat}
7-
u::Array{T,2} # u-velocity
8-
v::Array{T,2} # v-velocity
9-
η::Array{T,2} # sea surface height / interface displacement
10-
sst::Array{T,2} # tracer / sea surface temperature
11-
end
12-
131
"""Zero generator function for Grid G as argument."""
142
function PrognosticVars{T}(G::Grid) where {T<:AbstractFloat}
153
@unpack nux,nuy,nvx,nvy,nx,ny = G
@@ -23,12 +11,12 @@ function PrognosticVars{T}(G::Grid) where {T<:AbstractFloat}
2311
return PrognosticVars{T}(u,v,η,sst)
2412
end
2513

26-
function initial_conditions(::Type{T},S::ModelSetup) where {T<:AbstractFloat}
14+
function initial_conditions(::Type{T},G::Grid,P::Parameter,C::Constants) where {T<:AbstractFloat}
2715

2816
## PROGNOSTIC VARIABLES U,V,η
29-
@unpack nux,nuy,nvx,nvy,nx,ny = S.grid
30-
@unpack initial_cond = S.parameters
31-
@unpack Tini = S.parameters
17+
@unpack nux,nuy,nvx,nvy,nx,ny = G
18+
@unpack initial_cond = P
19+
@unpack Tini = P
3220

3321
if initial_cond == "rest"
3422

@@ -38,14 +26,14 @@ function initial_conditions(::Type{T},S::ModelSetup) where {T<:AbstractFloat}
3826

3927
elseif initial_cond == "ncfile"
4028

41-
@unpack initpath,init_run_id,init_starti = S.parameters
42-
@unpack init_interpolation = S.parameters
43-
@unpack nx,ny = S.grid
29+
@unpack initpath,init_run_id,init_starti = P
30+
@unpack init_interpolation = P
31+
@unpack nx,ny = G
4432

45-
inirunpath = joinpath(initpath,"run"*@sprintf("%04d",init_run_id))
33+
# inirunpath = joinpath(initpath,"run"*@sprintf("%04d",init_run_id))
4634

4735
# take starti time step from existing netcdf files
48-
ncstring = joinpath(inirunpath,"u.nc")
36+
ncstring = joinpath(initpath,"u.nc")
4937
ncu = NetCDF.open(ncstring)
5038

5139
if init_starti == -1 # replace -1 with length of time dimension
@@ -54,10 +42,10 @@ function initial_conditions(::Type{T},S::ModelSetup) where {T<:AbstractFloat}
5442

5543
u = ncu.vars["u"][:,:,init_starti]
5644

57-
ncv = NetCDF.open(joinpath(inirunpath,"v.nc"))
45+
ncv = NetCDF.open(joinpath(initpath,"v.nc"))
5846
v = ncv.vars["v"][:,:,init_starti]
5947

60-
ncη = NetCDF.open(joinpath(inirunpath,"eta.nc"))
48+
ncη = NetCDF.open(joinpath(initpath,"eta.nc"))
6149
η = ncη.vars["eta"][:,:,init_starti]
6250

6351
# remove singleton time dimension
@@ -118,10 +106,10 @@ function initial_conditions(::Type{T},S::ModelSetup) where {T<:AbstractFloat}
118106

119107
## SST
120108

121-
@unpack SSTmin, SSTmax, SSTw, SSTϕ = S.parameters
122-
@unpack SSTwaves_nx,SSTwaves_ny,SSTwaves_p = S.parameters
123-
@unpack sst_initial,scale = S.parameters
124-
@unpack x_T,y_T,Lx,Ly = S.grid
109+
@unpack SSTmin, SSTmax, SSTw, SSTϕ = P
110+
@unpack SSTwaves_nx,SSTwaves_ny,SSTwaves_p = P
111+
@unpack sst_initial,scale = P
112+
@unpack x_T,y_T,Lx,Ly = G
125113

126114
xx_T,yy_T = meshgrid(x_T,y_T)
127115

@@ -136,7 +124,7 @@ function initial_conditions(::Type{T},S::ModelSetup) where {T<:AbstractFloat}
136124
elseif sst_initial == "flat"
137125
sst = fill(SSTmin,size(xx_T))
138126
elseif sst_initial == "rect"
139-
@unpack sst_rect_coords = S.parameters
127+
@unpack sst_rect_coords = P
140128
x0,x1,y0,y1 = sst_rect_coords
141129

142130
sst = fill(SSTmin,size(xx_T))
@@ -159,7 +147,7 @@ function initial_conditions(::Type{T},S::ModelSetup) where {T<:AbstractFloat}
159147
η = T.(Tini.(η))
160148

161149
#TODO SST INTERPOLATION
162-
u,v,η,sst = add_halo(u,v,η,sst,S)
150+
u,v,η,sst = add_halo(u,v,η,sst,G,P,C)
163151

164152
return PrognosticVars{T}(u,v,η,sst)
165153
end

src/model_setup.jl

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,30 @@
1-
struct ModelSetup{T<:AbstractFloat,Tprog<:AbstractFloat}
1+
mutable struct PrognosticVars{T<:AbstractFloat}
2+
u::Array{T,2} # u-velocity
3+
v::Array{T,2} # v-velocity
4+
η::Array{T,2} # sea surface height / interface displacement
5+
sst::Array{T,2} # tracer / sea surface temperature
6+
end
7+
8+
struct DiagnosticVars{T,Tprog}
9+
RungeKutta::RungeKuttaVars{Tprog}
10+
Tendencies::TendencyVars{Tprog}
11+
VolumeFluxes::VolumeFluxVars{T}
12+
Vorticity::VorticityVars{T}
13+
Bernoulli::BernoulliVars{T}
14+
Bottomdrag::BottomdragVars{T}
15+
ArakawaHsu::ArakawaHsuVars{T}
16+
Laplace::LaplaceVars{T}
17+
Smagorinsky::SmagorinskyVars{T}
18+
SemiLagrange::SemiLagrangeVars{T}
19+
PrognosticVarsRHS::PrognosticVars{T} # low precision version
20+
end
21+
22+
mutable struct ModelSetup{T<:AbstractFloat,Tprog<:AbstractFloat}
223
parameters::Parameter
324
grid::Grid{T,Tprog}
425
constants::Constants{T,Tprog}
526
forcing::Forcing{T}
6-
end
27+
Prog::PrognosticVars{Tprog}
28+
Diag::DiagnosticVars{T, Tprog}
29+
t::Int # SW: I believe this has something to do with Checkpointing, need to verify
30+
end

src/output.jl

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -192,38 +192,29 @@ function get_run_id_path(S::ModelSetup)
192192
@unpack output,outpath,get_id_mode = S.parameters
193193

194194
if output
195-
runlist = filter(x->startswith(x,"run"),readdir(outpath))
196-
existing_runs = [parse(Int,id[4:end]) for id in runlist]
195+
196+
pattern = r"run_\d\d\d\d" # run_???? in regex
197+
runlist = filter(x->startswith(x,pattern),readdir(outpath))
198+
runlist = filter(x->endswith( x,pattern),runlist)
199+
existing_runs = [parse(Int,id[5:end]) for id in runlist]
200+
201+
# get the run id from existing folders
197202
if length(existing_runs) == 0 # if no runfolder exists yet
198-
runpath = joinpath(outpath,"run0000")
199-
mkdir(runpath)
200-
return 0,runpath
201-
else # create next folder
202-
if get_id_mode == "fill" # find the smallest gap in runfolders
203-
run_id = gap(existing_runs)
204-
runpath = joinpath(outpath,"run"*@sprintf("%04d",run_id))
205-
mkdir(runpath)
206-
207-
elseif get_id_mode == "specific" # specify the run_id as input argument
208-
@unpack run_id = S.parameters
209-
runpath = joinpath(outpath,"run"*@sprintf("%04d",run_id))
210-
try # create folder if not existent
211-
mkdir(runpath)
212-
catch # else rm folder and create new one
213-
rm(runpath,recursive=true)
214-
mkdir(runpath)
215-
end
216-
217-
elseif get_id_mode == "continue" # find largest folder and count one up
218-
run_id = maximum(existing_runs)+1
219-
runpath = joinpath(outpath,"run"*@sprintf("%04d",run_id))
220-
mkdir(runpath)
221-
else
222-
throw(error("Order '$get_id_mode' is not valid for get_run_id_path(), choose continue or fill."))
223-
end
224-
return run_id,runpath
203+
run_id = 1 # start with run_0001
204+
else
205+
run_id = maximum(existing_runs)+1 # next run gets id +1
225206
end
207+
208+
id = @sprintf("%04d",run_id)
209+
210+
run_id2 = string("run_",id)
211+
run_path = joinpath(outpath,run_id2)
212+
@assert !(run_id2 in readdir(outpath)) "Run folder $run_path already exists."
213+
mkdir(run_path) # actually create the folder
214+
215+
return run_id, run_path
216+
226217
else
227218
return 0,"no runpath"
228219
end
229-
end
220+
end

src/preallocate.jl

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -448,22 +448,6 @@ function SemiLagrangeVars{T}(G::Grid) where {T<:AbstractFloat}
448448
halosstx=halosstx,halossty=halossty)
449449
end
450450

451-
###################################################################
452-
453-
struct DiagnosticVars{T,Tprog}
454-
RungeKutta::RungeKuttaVars{Tprog}
455-
Tendencies::TendencyVars{Tprog}
456-
VolumeFluxes::VolumeFluxVars{T}
457-
Vorticity::VorticityVars{T}
458-
Bernoulli::BernoulliVars{T}
459-
Bottomdrag::BottomdragVars{T}
460-
ArakawaHsu::ArakawaHsuVars{T}
461-
Laplace::LaplaceVars{T}
462-
Smagorinsky::SmagorinskyVars{T}
463-
SemiLagrange::SemiLagrangeVars{T}
464-
PrognosticVarsRHS::PrognosticVars{T} # low precision version
465-
end
466-
467451
"""Preallocate the diagnostic variables and return them as matrices in structs."""
468452
function preallocate( ::Type{T},
469453
::Type{Tprog},

0 commit comments

Comments
 (0)