Conversation
…IBSEB PR erf-model#3860 turned ERF::m_SurfaceLayer from a single unique_ptr into one entry per domain face, and PR erf-model#3960 added ibseb_advance, which reads the surface layer for the wall function beyond neutral. The two merged independently and git merged them cleanly, so development did not compile: ERF_IBSEB.cpp still dereferenced m_SurfaceLayer as a pointer. Index zlo. What the wall function needs is the ground beneath the buildings; a surface layer on a lateral or upper wall says nothing about the stability of the column, and this is the same face that the other zlo-only consumers select (see ERF.cpp:876). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…live table With more than one surface-layer face, ERF decides whether to keep reading the historical unqualified erf.most.* / erf.surface_layer.* keys for zlo by asking whether any such key exists. It asked ParmParse directly, which cannot answer the question: ERF_InputSoundingData.H queries most.surf_temp and most.surf_moist with queryAdd while reading the sounding, and queryAdd inserts the default it was handed whenever the key is absent. By the time InitData_post runs, both keys are in the table holding their negative sentinels whether or not the user ever typed them. Every input_sounding run with more than one surface-layer face therefore looked as though it carried legacy inputs. A deck that also wrote the face-qualified spelling -- Tests/test_files/ABL_MOST_Cloudchamber, for one -- hit the "both spellings present" abort and could not start at all; a deck without it silently took the legacy path. Snapshot the inputs table at the top of ReadParameters, which is the last point at which presence in the table still means the user wrote it, and scan the snapshot. This stays correct if another erf.most.* queryAdd is added elsewhere later, which a fix targeting the two known keys would not. ABL_MOST_Cloudchamber is the regression test: it aborts before this change and initializes cleanly after it. Also document the prefixing rule in SurfaceLayer.rst -- unqualified for a lone zlo face, face-qualified once a second face is declared, unqualified applied to zlo with a warning, both spellings an error -- along with the configurations that now abort away from zlo, which the page previously covered only as "not all existing options are supported". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 15, 2026
Closed
hgopalan
added a commit
to hgopalan/ERF
that referenced
this pull request
Sep 15, 2026
Merge upstream/development (2026-09-15: erf-model#3860 surface layers per wall, erf-model#4021 anelastic MidPoint, erf-model#4025) into ERF-Fire
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.
Two fixes on top of the #3860 merge.
1.
developmentdid not compile at HEAD#3860 changed
ERF::m_SurfaceLayerfrom a singleunique_ptr<SurfaceLayer>to oneentry per domain face. #3960 added
ibseb_advance, which reads the surface layer forthe wall function beyond neutral. The two merged independently, git merged them
cleanly, and the result does not build —
ERF_IBSEB.cpp:143-146still dereferencedm_SurfaceLayeras a pointer.Indexed to zlo: what the wall function needs is the ground beneath the buildings, and
that is the face the other zlo-only consumers already select (
ERF.cpp:876).2. Legacy surface-layer input detection was reading the wrong thing
With more than one surface-layer face,
ERF::InitData_postdecides whether to keepreading the historical unqualified
erf.most.*/erf.surface_layer.*keys for zlo byasking whether any such key is present. It asked the live ParmParse table, which cannot
answer that question:
ERF_InputSoundingData.H:150,165queriesmost.surf_tempandmost.surf_moistwithqueryAddwhile reading the sounding, andqueryAddinsertsthe default it was handed when the key is absent. By the time
InitData_postruns, bothkeys sit in the table holding their negative sentinels whether or not the user typed them.
So every
init_type = input_soundingrun with more than one surface-layer face looked asthough it carried legacy inputs:
abort and could not start — including
Tests/test_files/ABL_MOST_Cloudchamber, theregression case added by Extend SurfaceLayer for all boundary sides #3860;
The fix snapshots the inputs table at the top of
ReadParameters()— the last point atwhich presence in the table still means the user wrote it — and the detector scans the
snapshot. This is prefix-agnostic, so it stays correct if another
erf.most.*queryAddappears elsewhere later, which a fix targeting just the two known keys would not.
Verification
ABL_MOST_Cloudchamberis its own regression test. Run locally with the anelastic solveskipped (this build has no FFT support, so the unmodified deck dies at
project_initial_velocitybefore reaching the surface-layer code):erf.most.*+ a second faceerf_unit_tests: 585 passed, 3 skipped, 0 failed.Docs
Docs/sphinx_doc/SurfaceLayer.rstnow states the prefixing rule — unqualified for a lonezlo face, face-qualified once a second face is declared, unqualified applied to zlo with a
warning, both spellings an error — and lists what actually aborts away from zlo: the
bulk_coeff/custom/ricoflux types, prescribed surface heat flux, the adiabaticcase, variable sea roughness, and
most.pblh_calc/most.include_wstar. The pagepreviously covered this only as "not all existing options are supported".
Note, not fixed here
In the legacy-warning case,
erf.most.surf_temp/surf_moistare also read by theinput-sounding consistency check, which compares with exact floating-point equality — a
sounding line of
12.13g/kg will not matchmost.surf_moist = 0.01213. Pre-existing andorthogonal, but it makes the legacy path harder to exercise than it looks.
🤖 Generated with Claude Code