Skip to content

Commit 86994e6

Browse files
committed
docs corrected
1 parent 270c41d commit 86994e6

File tree

6 files changed

+318
-0
lines changed

6 files changed

+318
-0
lines changed

docs/make.jl

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pages = [
5151
"GPU" => "gpu.md",
5252
"Examples" => [
5353
"literated/OneDShallowWaterGeostrophicAdjustment.md",
54+
"literated/XYAdvectionSetupRun.md"
5455
],
5556
"Contributor's guide" => "contributing.md",
5657
"Library" => [

docs/src/library/internals.md

+8
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,11 @@ Modules = [FourierFlows.Diffusion]
6565
Public = false
6666
Pages = ["diffusion.jl"]
6767
```
68+
69+
## XYAdvection Module
70+
71+
```@autodocs
72+
Modules = [FourierFlows.XYAdvection]
73+
Public = false
74+
Pages = ["XYAdvection.jl"]
75+
```

docs/src/library/public.md

+8
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,11 @@ Modules = [FourierFlows.Diffusion]
6767
Private = false
6868
Pages = ["diffusion.jl"]
6969
```
70+
71+
## XYAdvection Module
72+
73+
```@autodocs
74+
Modules = [FourierFlows.XYAdvection]
75+
Private = false
76+
Pages = ["XYAdvection.jl"]
77+
```

examples/XYAdvectionSetupRun.jl

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using FourierFlows, JLD2
2+
using FourierFlows:XYAdvection as xy
3+
using LinearAlgebra: mul!, ldiv!
4+
using Plots
5+
6+
dev = CPU()
7+
Nx = 80 # grid resolution
8+
Lx = 80 # box size
9+
dt = 0.02 # timestep (s)
10+
nsteps = 100 # total number of time-steps
11+
printFreq = 1 # data print frequency
12+
13+
stepper = "ForwardEuler" # timestepper_Scheme
14+
15+
16+
J = 1.0 # diffusion coefficient
17+
A = 0.0 # advection coefficient
18+
Γ = 1.0 # GL coefficient
19+
α = 1.0 # average order parameter
20+
21+
22+
grid = xy.set_2Dgrid(Nx,Lx; dev,aliased_fraction = 0)
23+
params = xy.set_Params(;J=J, A=A, Γ=Γ, α=α)
24+
vars = xy.set_Vars(grid)
25+
prob = xy.set_Problem(grid,params,vars,dt,stepper)
26+
27+
28+
px = rand(Nx,Nx)
29+
py = rand(Nx,Nx)
30+
xy.set_initialConditions!(prob,px,py)
31+
heatmap(grid.x,grid.y,atan.(py,px)',clims=(-π,π),c=:hsv,axis=true,grid=false,colorbar=true,ratio=1,size=(400,400))
32+
33+
34+
out = xy.run_and_save(prob,nsteps,printFreq)
35+
path=out.path
36+
37+
# plot order parameter time series
38+
orderP = Float64[]
39+
for titr in 0:printFreq:nsteps
40+
px,py = xy.get_data(titr,path,Nx)
41+
mag = ((sum(px)^2 + sum(py)^2)^0.5)/(Nx*Nx)
42+
push!(orderP,mag)
43+
end
44+
plot(orderP,ylims=(0,1),ylabel="m", xlabel="t", size=(400,400))
45+
46+
titr = nsteps
47+
px,py = xy.get_data(titr,path,Nx)
48+
heatmap(grid.x,grid.y,atan.(py,px)',clims=(-π,π),c=:hsv,axis=true,grid=false,colorbar=true,ratio=1,size=(400,400))

src/FourierFlows.jl

+1
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ include("timesteppers.jl")
109109

110110
# Physics
111111
include("diffusion.jl")
112+
include("XYAdvection.jl")
112113

113114

114115
function __init__()

src/XYAdvection.jl

+252
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
"""
2+
# Exports
3+
$(EXPORTS)
4+
"""
5+
module XYAdvection
6+
7+
export set_2Dgrid, set_Params, set_Vars, set_Problem, set_initialConditions!,
8+
run_and_save, get_data, updatevars!, stepforward!, saveoutput
9+
10+
using DocStringExtensions
11+
12+
using FourierFlows, JLD2
13+
using LinearAlgebra: mul!, ldiv!
14+
15+
"""
16+
struct Params{T} <: AbstractParams
17+
18+
The parameters for XYAdvection problem:
19+
$(FIELDS)
20+
"""
21+
struct Params{T} <: AbstractParams
22+
"Diffusion coefficient"
23+
J :: T
24+
"Advection coefficient"
25+
A :: T
26+
"LG coefficient"
27+
Γ :: T
28+
"Average order parameter"
29+
α :: T
30+
end
31+
32+
"""
33+
struct Vars2D{Aphys, Atrans} <: AbstractVars
34+
35+
The variables for XYAdvection problem:
36+
37+
$(FIELDS)
38+
"""
39+
struct Vars2D{Aphys, Atrans} <: AbstractVars
40+
"px and py field and its x and y derivative pxx, pxy, pyx, pyy"
41+
px :: Aphys
42+
py :: Aphys
43+
44+
pxx :: Aphys
45+
pxy :: Aphys
46+
pyx :: Aphys
47+
pyy :: Aphys
48+
49+
"px_hat, py_hat; FFT of px, py and its derivative fields"
50+
pxh :: Atrans
51+
pyh :: Atrans
52+
pxxh :: Atrans
53+
pxyh :: Atrans
54+
pyxh :: Atrans
55+
pyyh :: Atrans
56+
end
57+
58+
"""
59+
Vars2D(grid)
60+
61+
Return the variables `vars` for a XYAdvection problem on `grid`.
62+
63+
$(TYPEDFIELDS)
64+
"""
65+
function Vars2D(grid::TwoDGrid{T}) where T
66+
Dev = typeof(grid.device)
67+
68+
@devzeros Dev T (grid.nx, grid.ny) px py pxx pxy pyx pyy
69+
@devzeros Dev Complex{T} (grid.nkr, grid.nl) pxh pyh pxxh pxyh pyxh pyyh
70+
71+
return Vars2D(px, py, pxx, pxy, pyx, pyy, pxh, pyh, pxxh, pxyh, pyxh, pyyh)
72+
end
73+
74+
"""
75+
calcN!(N, sol, t, clock, vars, params, grid)
76+
77+
Calculate the nonlinear term for the XYAdvection equation.
78+
"""
79+
function calcN!(N, sol, t, clock, vars, params, grid)
80+
# multiply p__h with ik to get derivatives
81+
@. vars.pxxh = im * grid.kr .* sol[:,:,1]
82+
@. vars.pxyh = im * grid.l .* sol[:,:,1]
83+
84+
@. vars.pyxh = im * grid.kr .* sol[:,:,2]
85+
@. vars.pyyh = im * grid.l .* sol[:,:,2]
86+
87+
# get ik*p__h in physical space
88+
ldiv!(vars.pxx, grid.rfftplan, vars.pxxh) # destroys vars.pxxh when using fftw
89+
ldiv!(vars.pxy, grid.rfftplan, vars.pxyh) # destroys vars.pxyh when using fftw
90+
ldiv!(vars.pyx, grid.rfftplan, vars.pyxh) # destroys vars.pyxh when using fftw
91+
ldiv!(vars.pyy, grid.rfftplan, vars.pyyh) # destroys vars.pyyh when using fftw
92+
93+
# non-linear term
94+
@. vars.pxx = params.A * ((vars.px * vars.pxx) + (vars.py * vars.pxy)) + params.Γ * (params.α - (vars.px^2 + vars.py^2))*vars.px
95+
@. vars.pyx = params.A * ((vars.px * vars.pyx) + (vars.py * vars.pyy)) + params.Γ * (params.α - (vars.px^2 + vars.py^2))*vars.py
96+
97+
# go to fourier space and define N
98+
mul!(vars.pxxh, grid.rfftplan, vars.pxx)
99+
mul!(vars.pyxh, grid.rfftplan, vars.pyx)
100+
N[:,:, 1] = vars.pxxh
101+
N[:,:, 2] = vars.pyxh
102+
103+
dealias!(N[:,:,1], grid)
104+
dealias!(N[:,:,2], grid)
105+
return nothing
106+
end
107+
108+
"""
109+
Equation(params,grid)
110+
"""
111+
function Equation(params::Params, grid::TwoDGrid)
112+
dev = grid.device
113+
114+
# Linear operator
115+
L = zeros(dev, eltype(grid), (grid.nkr, grid.nl,2))
116+
@. L[:,:,1] = - params.J * grid.kr^2 - params.J * grid.l^2
117+
@. L[:,:,2] = - params.J * grid.kr^2 - params.J * grid.l^2
118+
119+
# full equation
120+
return FourierFlows.Equation(L, calcN!, grid)
121+
end
122+
123+
#################################### Exported Functions #################################
124+
"""
125+
To be called from main
126+
127+
set_2Dgrid(nx::Int64,Lx; dev::Device=CPU(),aliased_fraction = 0,kwargs...)
128+
129+
setup 2D grid given the parameters
130+
"""
131+
function set_2Dgrid(nx::Int64,Lx; dev::Device=CPU(),aliased_fraction = 0,kwargs...)
132+
grid = TwoDGrid(dev; nx, Lx, aliased_fraction,kwargs...)
133+
return grid
134+
end
135+
136+
"""
137+
To be called from main
138+
139+
set_Params(;J::T,A::T,Γ::T,α::T)
140+
141+
setup parameter values for the problem
142+
"""
143+
function set_Params(;J::T,A::T::T::T) where {T<:Float64}
144+
params = Params(J, A, Γ, α)
145+
return params
146+
end
147+
148+
"""
149+
To be called from main
150+
151+
set_Vars(grid::TwoDGrid)
152+
153+
setup variables for the system
154+
"""
155+
function set_Vars(grid::TwoDGrid)
156+
vars = Vars2D(grid)
157+
return vars
158+
end
159+
160+
161+
"""
162+
To be called from main
163+
164+
set_Problem(grid::TwoDGrid,params::Params,vars::Vars2D,dt::Float64=0.02,stepper = "ForwardEuler";stepperkwargs...)
165+
166+
setup the FourierFlows.Problem
167+
"""
168+
function set_Problem(grid::TwoDGrid,params::Params,vars::Vars2D,dt::Float64=0.02,stepper = "ForwardEuler";stepperkwargs...)
169+
170+
equation = Equation(params,grid)
171+
172+
prob = FourierFlows.Problem(equation, stepper, dt, grid, vars, params; stepperkwargs...)
173+
return prob
174+
end
175+
176+
"""
177+
updatevars!(prob)
178+
"""
179+
function updatevars!(prob)
180+
vars, grid, sol = prob.vars, prob.grid, prob.sol
181+
182+
@. vars.pxh = sol[:,:, 1]
183+
@. vars.pyh = sol[:,:, 2]
184+
185+
ldiv!(vars.px, grid.rfftplan, deepcopy(sol[:,:, 1])) # use deepcopy() because irfft destroys its input
186+
ldiv!(vars.py, grid.rfftplan, deepcopy(sol[:,:, 2])) # use deepcopy() because irfft destroys its input
187+
return nothing
188+
end
189+
190+
"""
191+
set_initialConditions!(prob, px, py)
192+
193+
Set the solution `sol` as the transform of `px` and `py` and update `vars`.
194+
"""
195+
function set_initialConditions!(prob, u, v)
196+
vars, grid, sol = prob.vars, prob.grid, prob.sol
197+
198+
cast_type = typeof(vars.px) # determine the type of vars.px
199+
200+
# below, e.g., A(px0) converts px0 to the same type as vars expects
201+
# (useful when px0 is a CPU array but grid.device is GPU)
202+
mul!(vars.pxh, grid.rfftplan, cast_type(u))
203+
mul!(vars.pyh, grid.rfftplan, cast_type(v))
204+
205+
@. sol[:,:,1] = vars.pxh
206+
@. sol[:,:,2] = vars.pyh
207+
208+
updatevars!(prob)
209+
210+
return nothing
211+
end
212+
213+
"""
214+
To be called from main
215+
216+
run_and_save(prob,nsteps::T=10^5,printFreq::T=10^3;filepath::T2 = ".",filename::T2 = "XYAdvection_data.jld2") where {T<:Integer,T2<:String}
217+
218+
Run the problem and save output to file.
219+
"""
220+
function run_and_save(prob,nsteps::T=10^5,printFreq::T=10^3;filepath::T2 = ".",filename::T2 = "XYAdvection_data.jld2") where {T<:Integer,T2<:String}
221+
# assert nsteps/printFreq is an integer
222+
@assert isinteger(nsteps/printFreq) "requires nsteps/printFreq == Integer"
223+
224+
fname = joinpath(filepath, filename)
225+
get_sol(prob) = prob.sol
226+
out = Output(prob, fname, (:sol, get_sol))
227+
saveproblem(out)
228+
for i in 0:Int(nsteps)
229+
if i % Int(printFreq)==0
230+
saveoutput(out)
231+
end
232+
stepforward!(prob)
233+
updatevars!(prob)
234+
end
235+
return out
236+
end
237+
238+
"""
239+
To be called from main
240+
241+
get_data(titr::Integer,filepath::String,nx::Integer)
242+
243+
Read output data from file and convert to physical space for analysis.
244+
"""
245+
function get_data(titr::Integer,filepath::String,nx::Integer)
246+
file = jldopen(filepath)
247+
px = irfft(file[string("snapshots/sol/", titr)][:,:, 1], nx)
248+
py = irfft(file[string("snapshots/sol/", titr)][:,:, 2], nx)
249+
return px,py
250+
end
251+
############################################################################################################
252+
end #end module

0 commit comments

Comments
 (0)