Conversation
…t the wall The Moeng, Schumann and constant shear-stress models combine the velocity and temperature of the first cell above the wall with their plane averages. The averages entered through one MOData object at one reference height (the level-0 half cell by default) while the local values came from the first cell of whichever level owns the wall. With a refinement level that touches the wall, that cell sits lower, so the same formula returned a plane-mean stress of u*^2 (2 r - 1), r = phi_m(z_1)/phi_m(z_ref), on the refined level, about 20 % low for typical roughness, and the heat flux was short by the same factor (kynema#1752). ABLWallFunction now keeps a MOData per level on multi-level meshes. Each level carries the plane averages of the wall-adjacent cells it owns, at its own first-cell height, and in heat-flux mode a surface temperature that returns the specified flux from that mean state. The friction velocity, Obukhov length and surface heat flux are still computed once from the plane average at the reference height. The wall-model functors are built per level from these data. Single-level meshes use the existing MOData and are bit-identical. A unit test with a level-1 box over half of the wall checks that the mean wall stress and heat flux of every level equal u*^2 and the specified flux; it fails on both levels with the previous code. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This was referenced Sep 17, 2026
GCC 13 at -O3 flags a potential null dereference when pushing the box refinement onto mesh<RefineMesh>(); check the cast like the other tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nvcc rejects device lambdas in private member functions. Co-Authored-By: Claude Opus 5 <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
Fixes the level-to-level inconsistency of the ABL wall models on meshes where more than one level touches the wall-modeled boundary (#1752).
The$u_*^2 (2r - 1)$ with $r = \phi_m(z_1)/\phi_m(z_{ref})$ , i.e. about 20 % too low for the roughness and heights in #1752; the heat flux is short by the same factor. This is what produced the box-shaped imprint of the refinement region in the time-averaged fields of that issue, and it is independent of the time averaging.
Moeng,Schumannandconstantshear-stress models combine the velocity and temperature of the first cell above the wall with their plane averages. The plane averages entered through oneMODataobject at one reference height (the level-0 half cell by default), while the local values came from the first cell of whichever level owns the wall. On a refined level the first cell sits lower, where the wind is slower and the air is warmer, so the same formula returned a different mean stress and heat flux on each level. For the Moeng model the plane-mean stress on a level whose first cell is at half the reference height isChanges
ABLWallFunctionnow keeps aMODataper level (mo(lev)) on multi-level meshes. Each level carries the plane averages of the wall-adjacent cells it owns (excluding cells covered by a finer level) at its own first-cell height; in heat-flux mode the surface temperature of that level is set so that the mean heat flux equals the specified flux. The friction velocity, Obukhov length and surface heat flux are still computed once from the plane average atABL.log_law_height, as before.ABLVelWallFuncandABLTempWallFuncbuild the shear-stress / heat-flux functor per level frommo(lev). On a single-level meshmo(lev)is the existingmo(), so single-level results are unchanged (bit-identical onabl_godunov, see below).molwall model (ABL.wall_het_model = mol) already evaluated everything at the local cell height and is untouched.ABL.wall_shear_stress_typedescribing the per-level treatment.Test
unit_tests/wind_energy/test_abl_wall_refinement.cpp: an ABL mesh with a level-1 box over half of the wall, logarithmic wind and temperature profiles that are uniform in every plane, wall-model BCs for velocity and temperature with a specified heat flux. It fills the wall-model ghost cells and checks that the mean wall stress over the cells each level owns equalsmoengandschumannmodels. With the previous code the level-1 stress is about 30 % low on this mesh and the level-0 stress is off by a few percent through the interpolated plane average, so the test fails on both levels.Regression tests
Cases with a wall model and a refinement level that touches the wall change (expected):
abl_godunov_static_refinement,abl_godunov_static_refinement_rr4. There level 1 covers the whole wall, so the wall stress moves from $u_^2 (2r-1)$ to $u_^2$. Single-level ABL cases are bit-identical. Refined cases whose boxes do not reach the wall are unaffected.Not in this PR
The multi-level
FieldPlaneAveraginginterpolates coarse cells next to a non-periodic boundary toward the ghost cell, which for a wall-model BC holds a gradient rather than a value. That is a separate issue and will come as its own PR.🤖 Generated with Claude Code