Conversation
…daries The multi-level plane average interpolates a coarse cell to the center of each fine bin using its closest neighbor. Next to a non-periodic domain boundary that neighbor was the ghost cell, treated as a value located at the domain face. What the ghost holds depends on the boundary condition (a face value for ext_dir, an extrapolation to the ghost center for hoextrap/foextrap, a gradient for the wall models until the next fill) and on whether it has been filled at all: at initialization the ABL statistics read it before the first fillpatch, and it still held the initial value. Use the interior neighbor instead (one-sided linear interpolation) across a non-periodic boundary. Cells at bin centers and periodic directions are unchanged, so single-level averages are bit-identical. A unit test fills the ghost cells outside the domain with 1e10 and checks that the averages of a linear field are unaffected; it fails on the previous code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #2041. The multi-level
FieldPlaneAveraging(from #1792) interpolates a coarse cell to the center of each fine bin using its closest neighbor. Next to a non-periodic domain boundary that neighbor is the ghost cell, which the code treats as a value located at the domain face. This PR verifies what those ghost cells actually hold during an ABL run and makes the averages independent of them.What the ghost cells hold
Checked with a temporary print in
ABLStats::calc_averagesonabl_godunov_static_refinementwith the level-1 box covering half of the wall (amr.n_error_buf = 0), reading the level-0 velocity next to the wall in the coarse part of the domain:u(k=-1)u(k=0)u(k=1)post_init_actions, before the first fillpatch)fillpatch)So in the time loop the wall-model gradient written by
apply_bc_funcsdoes not reach the averages: thefillpatchat the end of the nodal projection replaces it with thehoextrapvalue of thewall_modelBC, which is an extrapolation to the ghost-cell center, not a value at the face. At initialization the ghost is still the unfilled initial value (zero here), and the first-cell bins of the fine average read it: at step 0 the fine average at half a fine cell was 5.1 against 6.1 one step later. With the defaultABL.log_law_height(level-0 half cell) the errors of the two bins cancel exactly in the interpolated mean, so the initial friction velocity is unaffected; with another log-law height orABL.stats_max_level = 1it is not. Which value the ghost holds and where it sits therefore depends on the boundary condition (ext_dir: face value;hoextrap/foextrap: ghost center; wall models: a gradient until the next fill) and on the point in the step at which the average is taken.Change
Across a non-periodic domain boundary the interpolation now uses the interior neighbor instead of the ghost cell (one-sided linear interpolation). In the periodic direction and inside the domain nothing changes. Cells whose center coincides with the bin center still get zero interpolation weight, but only to roundoff: in the first and last cells next to a non-periodic boundary, the roundoff difference between the bin center and the cell center used to multiply the ghost value and now multiplies the interior neighbor. Single-level cases can therefore change at roundoff too (see Regression tests below;
abl_godunovhappens to be bit-identical). Multi-level cases with a coarse level at a non-periodic boundary change only in the first and last bins;abl_godunov_static_refinementwith the level-1 box over half of the wall agrees withmainto roundoff after 10 steps (1e-15 relative), because with the default log-law height the two wall bins cancel in the wall function andABLForcingsamples the profile well inside the domain.Regression tests
The CPU Release jobs compare against
mainwith no tolerance, so they report these answer changes. On the macOS job the following tests differ frommain, all at roundoff:abl_godunov_mplabl_godunov_mpl_amrabl_samplingabl_subvolumebox_refinementudf_refinementThe relative differences are at most 1e-12, except for fields close to zero (e.g. the level-1 vertical velocity, 1e-9 relative). Running
abl_godunov_mpllocally with and without this change gives the same size of difference.Test
FieldPlaneAveragingFineTest.test_linear_ignores_domain_ghosts: the linear-field test of #1792 with the ghost cells outside the domain set to 1e10. It fails on the current code and passes with this change. The existing tests, which fill the ghosts with the face value, still pass because the one-sided interpolation is exact for a linear field.🤖 Generated with Claude Code