-
Notifications
You must be signed in to change notification settings - Fork 195
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
Offline differential operators do not correctly apply boundary conditions #3224
Comments
Maybe there is just a missing call to |
Hmm yes, the halo regions are essentially never filled by default. During time-stepping they are filled at the conclusion of a time-step within For offline diagnostics, a better approach for the horizontal convection example is to save halo regions using We've discussed making Usability suggestions like places where we should fill halo regions by default are also welcome! We have debated adding that to |
Maybe I am misunderstanding you, but isn't that already what is done in the horizontal convection example? Oceananigans.jl/examples/horizontal_convection.jl Lines 153 to 157 in cca182a
It seems like this is indeed saving grids with halos, but erroneously filling them with zeros rather than the correct values? Is the intended behavior that output writers automatically call |
No, you are understanding me! I think you're on to something.
Ah no this is not default. However, for prognostic fields, the halos are filled within However, halos are not filled for diagnostic fields. We probably don't want to make filling halos default, since filling halo regions is expensive and useful only for a subset of experiments. However, we could add a keyword argument to I wonder if this is a bug in |
@navidcy might be interested in this bug |
As an aside, I think this issue illustrates that users are indeed interested in being able to evaluate gradients across boundaries. This is important because @simone-silvestri proposed a change that would make this impossible (eg it has been proposed we do not fill halos for |
Inspecting the file manually shows that the data is indeed correct in there, so the problem appears to be with julia> using JLD2
julia> file = jldopen(filename)
JLDFile /Users/gregorywagner/Desktop/simple_tracer_output_test.jld2 (read-only)
├─📂 grid
│ ├─🔢 Nx
│ ├─🔢 Ny
│ ├─🔢 Nz
│ ├─🔢 Hx
│ ├─🔢 Hy
│ ├─🔢 Hz
│ ├─🔢 Lx
│ └─ ⋯ (14 more entries)
└─ ⋯ (3 more entries)
julia> c_data = file["timeseries/c/0"][:]
9-element Vector{Float64}:
0.0
0.0
2.0
0.0
0.0
0.0
0.0
0.0
0.0
julia> c_data = file["timeseries/c/1"][:]
9-element Vector{Float64}:
0.0
0.0
1.82
0.18
0.0
0.0
0.0
0.0
0.0 The halo value across the bottom boundary is the third one down from the top. At iteration 0, it's value is 2 (so that interpolating between 0 and 2 returns 1). At iteration 1 it's value is 1.82, showing that it is changing correctly in time. |
Data is loaded into
which calls Oceananigans.jl/src/OutputReaders/field_time_series.jl Lines 200 to 205 in cca182a
The data seems to be loaded into the intermediate
so the problem may be
Voila... Oceananigans.jl/src/Fields/set!.jl Lines 43 to 55 in cca182a
|
Here's a more minimal reproducer of the core issue: using Oceananigans
grid = RectilinearGrid(size=1, z=(0, 1), topology=(Flat, Flat, Bounded))
a = CenterField(grid)
b = CenterField(grid)
parent(a) .= 1
set!(b, a) then julia> parent(a)[:]
7-element Vector{Float64}:
1.0
1.0
1.0
1.0
1.0
1.0
1.0
julia> parent(b)[:]
7-element Vector{Float64}:
0.0
0.0
0.0
1.0
0.0
0.0
0.0 |
#3225 seems to do the trick and the above example yields the plot which is correct: the value of |
I agree, but this patch-up will not work for immersed boundaries anyway. I still advocate for (maybe not now but later down the line) a general line of thought that ensures consistency between immersed boundaries and "regular" boundaries (a la MITgcm) treating them always the same way. As an example, this issue could have been brought up for immersed boundaries, which would have required a (definitely more lengthy) rework of boundaries in abstract operations but would have solved the issue in both boundaries and immersed boundaries. |
I am actually not even sure that it would be possible to do easily in this case |
Just to be clear, this is just for offline diagnostics, right? Online diagnostic operations on prognostic fields still correctly feel the boundary conditions? |
Yeah, that's right. I was referring to eliminating the halo filling (except for periodic) and baking in
|
Also, I am unsure what a |
Not sure what you mean. |
What do you mean? What patch-up?
I agree I think that would be nice. It means that operators need to know about boundary conditions though, which is a major refactor...
We support values and gradients on non-immersed boundaries, but we do not support evaluating them across immersed boundaries. We have to support what we claim / say that we support, that is the only issue. |
I think to support inserting Supporting correct boundary evaluation for non-immersed boundaries is straightforward via rules for filling halo regions. Thus despite the trade-offs, it makes sense to provide such a "bonus" feature: it's enabling for quite a few applications without a great cost (at least yet, because we don't have a user interface or great support for distributed computations). Support for operations across immersed boundaries is a more complex endeavor. Thus because I do not think we should regard Value / Gradient boundary conditions as a "core" feature (this package is oriented towards ocean modeling from large eddy simulation up to global scales --- direct numerical simulation is not our core application) the trade-off points towards not supporting this. Especially due to finite resources for software development, many of our decisions are compromises. We don't aim to be perfect, we aim to be good. |
Point taken, but I think there are still Oceananigans-relevant applications where Value / Gradient boundary conditions on non-immersed boundaries are useful enough to be a "core" feature (e.g. imposing observed SST patterns rather than observed air-sea heat fluxes), but there is always the workaround of strongly restoring boundary-adjacent sponge regions. I think this is what many ocean modelers do to implement such boundary conditions anyway. I can't really conceive of any reasons why one would want Value / Gradient BCs on the immersed boundary though, and agree it is not alone worth a major refactor. |
True! I'm not aware that has ever been done, but since it's not difficult to support (notwithstanding @simone-silvestri's concerns about parallel performance) it's interesting to allow it --- agree. For future readers I want to point out that SST restoring (and similar models) are typically be implemented as a |
Presently, applying differential operators to fields offline (as opposed to using diagnosing them online using using an
OutputWriter
) yields erroneous results because derivatives seem to be naively using output halo region values (which seem to be filled with zeroes by default) and not overwriting them to satisfy boundary conditions.One example impact of this is that the Nusselt number calculation in the
horizontal_convection.jl
example script is totally meaningless because it is dominated by spuriously large buoyancy gradients in the boundary-adjacent cells.@ikeshwani and I demonstrate this bug in this
horizontal_diffusion.jl
script, in which we turn off advection in thehorizontal_convection.jl
example and numerically integrate the solution to equilibrium. We compare timeseries of the volume-integrated buoyancy dissipation rates calculated online versus those calculated offline (as in thehorizontal_convection.jl
example). The results show that the online calculation correctly asymptotes to the numerical solution of the equilibrium boundary value problem while the offline calculation is erroneous and effectively yields a Nusselt number that is more than 6 times too high.The bug is also evident by comparing snapshots of the two buoyancy dissipation rate fields. The dissipation rates computed offline clearly do not satisfy the no-flux boundary conditions on the boundaries.
This bug is present in the live
main
Oceananigans.jl branch (circav0.86.0
), as is evident from the movie of the buoyancy dissipation rate field in thehorizontal_convection.jl
example documentation and verified locally.I am referring to this as a bug because it is contrary to the expected behavior of halos containing the necessary information for satisfying boundary conditions, as discussed in the horizontal convection documentation example:
Oceananigans.jl/examples/horizontal_convection.jl
Lines 143 to 147 in a226b3e
The text was updated successfully, but these errors were encountered: