-
Notifications
You must be signed in to change notification settings - Fork 238
Remove the use of indices for storage in PerturbationAdvection
#4578
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
Conversation
src/BoundaryConditions/perturbation_advection_open_boundary_matching_scheme.jl
Show resolved
Hide resolved
Regarding the initial velocity --- is the result on this PR correct vs the previous result wrong? |
The initial condition for the velocity is The reason is that at |
I guess if we want to keep the former scheme, we also need to fix this issue. The storage index should be computed in the model constructor, shouldn't it? |
For the record here, the issue with the initial condition in the original version of using Oceananigans
using Oceananigans.BoundaryConditions: PerturbationAdvectionOpenBoundaryCondition
using Oceananigans.Diagnostics: AdvectiveCFL
using Printf
Δx = Δz = 0.05
Nx = Nz = round(Int, 2 / Δx)
grid = RectilinearGrid(size = (Nx, Nz), halo = (4, 4), extent = (1, 1),
topology = (Bounded, Flat, Bounded))
U₀ = 1.0
inflow_timescale = 1e-2
outflow_timescale = Inf
u_boundary_conditions = FieldBoundaryConditions(west = PerturbationAdvectionOpenBoundaryCondition(U₀; inflow_timescale, outflow_timescale),
east = PerturbationAdvectionOpenBoundaryCondition(U₀; inflow_timescale, outflow_timescale))
boundary_conditions = (; u = u_boundary_conditions,)
model = NonhydrostaticModel(; grid, boundary_conditions,
timestepper = :RungeKutta3,)
uᵢ(x, z) = U₀ + 1e-4 * rand()
set!(model, u=uᵢ)
simulation = Simulation(model; Δt=0.1Δx/U₀, stop_time=1, verbose=false)
cfl_calculator = AdvectiveCFL(simulation.Δt)
function progress(sim)
u, v, w = model.velocities
cfl_value = cfl_calculator(model)
west_mass_flux = Field(Average(view(u, 1, :, :)))[]
east_mass_flux = Field(Average(view(u, grid.Nx+1, :, :)))[]
net_mass_flux = east_mass_flux - west_mass_flux
@info @sprintf("time: %.3f, max|u|: %.3f, CFL: %.4f, Net mass flux: %.4e",
time(sim), maximum(abs, u), cfl_value, net_mass_flux)
end
add_callback!(simulation, progress, IterationInterval(20))
run!(simulation) On [ Info: time: 0.000, max|u|: 1.000, CFL: 0.1950, Net mass flux: 1.0001e+00
[ Info: time: 0.100, max|u|: 1.000, CFL: 0.2000, Net mass flux: -1.1620e-02
[ Info: time: 0.200, max|u|: 1.000, CFL: 0.2000, Net mass flux: -1.0537e-02
[ Info: time: 0.300, max|u|: 1.000, CFL: 0.2000, Net mass flux: -9.4626e-03
[ Info: time: 0.400, max|u|: 1.000, CFL: 0.2000, Net mass flux: -8.4977e-03
[ Info: time: 0.500, max|u|: 1.000, CFL: 0.2000, Net mass flux: -7.6311e-03
[ Info: time: 0.600, max|u|: 1.000, CFL: 0.2000, Net mass flux: -6.8528e-03
[ Info: time: 0.700, max|u|: 1.000, CFL: 0.2000, Net mass flux: -6.1538e-03
[ Info: time: 0.800, max|u|: 1.000, CFL: 0.2000, Net mass flux: -5.5261e-03
[ Info: time: 0.900, max|u|: 1.000, CFL: 0.2000, Net mass flux: -4.9623e-03
[ Info: time: 1.000, max|u|: 1.000, CFL: 0.2000, Net mass flux: -4.4560e-03 Indicating some non-negligible net mass flux. On this branch, the script produces: [ Info: time: 0.000, max|u|: 1.000, CFL: 0.2000, Net mass flux: 3.4537e-06
[ Info: time: 0.100, max|u|: 1.000, CFL: 0.2000, Net mass flux: 4.6397e-05
[ Info: time: 0.200, max|u|: 1.000, CFL: 0.2000, Net mass flux: 4.1665e-05
[ Info: time: 0.300, max|u|: 1.000, CFL: 0.2000, Net mass flux: 3.7411e-05
[ Info: time: 0.400, max|u|: 1.000, CFL: 0.2000, Net mass flux: 3.3592e-05
[ Info: time: 0.500, max|u|: 1.000, CFL: 0.2000, Net mass flux: 3.0163e-05
[ Info: time: 0.600, max|u|: 1.000, CFL: 0.2000, Net mass flux: 2.7083e-05
[ Info: time: 0.700, max|u|: 1.000, CFL: 0.2000, Net mass flux: 2.4319e-05
[ Info: time: 0.800, max|u|: 1.000, CFL: 0.2000, Net mass flux: 2.1836e-05
[ Info: time: 0.900, max|u|: 1.000, CFL: 0.2000, Net mass flux: 1.9607e-05
[ Info: time: 1.000, max|u|: 1.000, CFL: 0.2000, Net mass flux: 1.7605e-05 So the two things to note here are that:
@jagoosw let me know if you have anything to add here, otherwise I'll move forward and merge this PR. |
Based on a conversation with @glwagner and @xkykai, this PR removes the use of indices for storage in
PerturbationAdvection
and makes a couple of fixes and improvements. On main, this index sets up a hidden/secret storage for left open boundary conditions ati=0
that saves the velocity of the previous timestep. This is not done for the right boundary, so this PR will make both left and rightPerturbationAdvectionOBC
s the same.@jagoosw I'm curious to hear your thoughts here. We went through the code and couldn't find the need for a storage for the velocity at a previous timestep. In fact, if I simply get rid of it (as this PR does) the results basically don't change, with the exception of the initial velocity. Here are two identical simulations, the only difference being the use of a stored velocity by one and not the other:
_cylinder_xy_PerturbationAdvection_Nx_40.jld2_old.mp4
_cylinder_xy_PerturbationAdvection_Nx_40.jld2_new.mp4