-
Notifications
You must be signed in to change notification settings - Fork 190
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
Fix index calculation for Lagrangian particles in periodic directions #3416
Conversation
Here's a test script: using Oceananigans
using Oceananigans.Units
using StructArrays
using Printf
using Random
using Statistics
Random.seed!(123)
grid = RectilinearGrid(CPU(), Float64,
size = (2, 2, 2),
halo = (5, 5, 5),
x = (0, 1),
y = (0, 1),
z = (-1, 0),
topology = (Periodic, Bounded, Bounded))
#%%
struct SimpleParticle{X}
x :: X
y :: X
z :: X
end
x_particle = collect(0:0.25:1.5)
y_particle = collect(0:0.25:1.5)
z_particle = collect(fill(-0.5, length(x_particle)))
particles = StructArray{SimpleParticle}((x_particle, y_particle, z_particle))
lagrangian_particles = LagrangianParticles(particles)
#%%
model = NonhydrostaticModel(;
grid = grid,
timestepper = :RungeKutta3,
advection = WENO(order=9),
particles = lagrangian_particles
)
u, v, w = model.velocities
simulation = Simulation(model, Δt=0.1seconds, stop_iteration=2)
wall_clock = [time_ns()]
function print_progress(sim)
@printf("i: %d, t: %s, wall time: %s, max(u): (%6.3e, %6.3e, %6.3e) m/s, next Δt: %s\n",
sim.model.clock.iteration,
prettytime(sim.model.clock.time),
prettytime(1e-9 * (time_ns() - wall_clock[1])),
maximum(abs, sim.model.velocities.u),
maximum(abs, sim.model.velocities.v),
maximum(abs, sim.model.velocities.w),
prettytime(sim.Δt))
@info "x(particle): $(round.(lagrangian_particles.properties.x, digits=2)), y(particle): $(round.(lagrangian_particles.properties.y, digits=2)), z(particle): $(round.(lagrangian_particles.properties.z, digits=2))\n"
wall_clock[1] = time_ns()
return nothing
end
simulation.callbacks[:print_progress] = Callback(print_progress, IterationInterval(1))
run!(simulation) In the test script, the domain is initialized to be Here's the output of the script:
We see that the particles that are outside of the domain in |
Oh I see, that looks good. My confusion was because I guess instead of using |
I suggest defining a new function for the rightmost cell index instead of using interface_index_rightmost(::Bounded, N) = N + 1
interface_index_rightmost(::Periodic, N) = N + 1
interface_index_rightmost(::Flat, N) = N Then iᴿ = interface_index_rightmost(tx, Nx)
jᴿ = interface_index_rightmost(ty, Ny)
kᴿ = interface_index_rightmost(tz, Nz) I am not sure whether |
That is indeed different from |
This seems to be ready to merge? |
Does it resolve #3415? |
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.
Please check whether it resolves #3415 (the title of the issue just says to "see" that issue, but doesn't mention wheether the problem is solved or not)
This resolves issue #3415. See this script: using Oceananigans
using StructArrays
using Printf
grid = RectilinearGrid(CPU(), Float64,
size = (10, 10),
halo = (5, 5),
x = (0, 1),
y = (0, 1),
topology = (Bounded, Periodic, Flat))
#%%
struct SimpleParticle{X}
x :: X
y :: X
z :: X
end
x_particle = collect(0:0.25:1.5)
y_particle = collect(0:0.25:1.5)
z_particle = collect(fill(-0.5, length(x_particle)))
particles = StructArray{SimpleParticle}((x_particle, y_particle, z_particle))
lagrangian_particles = LagrangianParticles(particles)
#%%
model = NonhydrostaticModel(;
grid = grid,
timestepper = :RungeKutta3,
advection = WENO(order=9),
particles = lagrangian_particles
)
u, v, w = model.velocities
simulation = Simulation(model, Δt=0.1, stop_iteration=2)
wall_clock = [time_ns()]
function print_progress(sim)
@printf("i: %d, t: %s, wall time: %s, max(u): (%6.3e, %6.3e, %6.3e) m/s, next Δt: %s\n",
sim.model.clock.iteration,
prettytime(sim.model.clock.time),
prettytime(1e-9 * (time_ns() - wall_clock[1])),
maximum(abs, sim.model.velocities.u),
maximum(abs, sim.model.velocities.v),
maximum(abs, sim.model.velocities.w),
prettytime(sim.Δt))
@info "x(particle): $(round.(lagrangian_particles.properties.x, digits=2)), y(particle): $(round.(lagrangian_particles.properties.y, digits=2)), z(particle): $(round.(lagrangian_particles.properties.z, digits=2))\n"
wall_clock[1] = time_ns()
return nothing
end
simulation.callbacks[:print_progress] = Callback(print_progress, IterationInterval(1))
run!(simulation) which outputs [ Info: Initializing simulation...
i: 0, t: 0 seconds, wall time: 4.726 seconds, max(u): (0.000e+00, 0.000e+00, 0.000e+00) m/s, next Δt: 100 ms
[ Info: x(particle): [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5], y(particle): [0.0, 0.25, 0.5, 0.75, 1.0, 1.25, 1.5], z(particle): [-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5]
[ Info: ... simulation initialization complete (3.406 seconds)
[ Info: Executing initial time step...
[ Info: ... initial time step complete (6.270 seconds).
i: 1, t: 100 ms, wall time: 6.286 seconds, max(u): (0.000e+00, 0.000e+00, 0.000e+00) m/s, next Δt: 100 ms
[ Info: x(particle): [0.0, 0.25, 0.5, 0.75, 1.0, 0.75, 0.5], y(particle): [0.0, 0.25, 0.5, 0.75, 1.0, 0.25, 0.5], z(particle): [-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5]
[ Info: Simulation is stopping after running for 9.706 seconds.
[ Info: Model iteration 2 equals or exceeds stop iteration 2.
i: 2, t: 200 ms, wall time: 2.858 ms, max(u): (0.000e+00, 0.000e+00, 0.000e+00) m/s, next Δt: 100 ms
[ Info: x(particle): [0.0, 0.25, 0.5, 0.75, 1.0, 0.75, 0.5], y(particle): [0.0, 0.25, 0.5, 0.75, 1.0, 0.25, 0.5], z(particle): [-0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5] Particles are bounced and shifted appropriately, and it also works in |
Can you change the first post so merging this issue closes #3415 (and makes the connection clear) |
I'm merging this |
Closes #3415