Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
213 commits
Select commit Hold shift + click to select a range
ece698b
Implement Phase 1 Two-Stream Radiation Module - Core Infrastructure a…
Copilot Aug 6, 2026
dcc9173
Merge pull request #280 from hgopalan/copilot/copilotphase1-two-strea…
hgopalan Aug 7, 2026
90cf5d9
Phase 1b: Add Radiation diagnostics to build system and wiring
Copilot Aug 7, 2026
08443a7
Phase 1b: Wire Radiation Module into Build System and SolverChoice
Copilot Aug 7, 2026
7797dd8
Merge pull request #281 from hgopalan/copilot/copilotphase1b-wire-rad…
hgopalan Aug 7, 2026
73a2143
Fix Phase 1 sounding file: move case-specific soundings into their ow…
hgopalan Aug 7, 2026
e964426
Fix some files
hgopalan Aug 7, 2026
a4deff1
Equation Bug
hgopalan Aug 7, 2026
fe50d8d
Fix bug
hgopalan Aug 7, 2026
1c6cd59
Fix bug
hgopalan Aug 7, 2026
3c96abe
Fix bug
hgopalan Aug 7, 2026
32230e1
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Aug 7, 2026
68bdffe
MD files
hgopalan Aug 7, 2026
7b2aba7
MD files
hgopalan Aug 7, 2026
7a06f85
Add RAD_DEVELOPMENT.md and RAD_MPI_SKILLS.md documentation
Copilot Aug 7, 2026
4ba9bf8
Implement Phase 2: Real per-column vertical integration with GPU-safe…
Copilot Aug 7, 2026
aa90b9b
Update documentation: Mark Phase 2 complete, add Phase 2 lessons to R…
Copilot Aug 7, 2026
e52d4a4
Merge branch 'ERF-Radiation' into copilot/phase2-real-per-column-radi…
hgopalan Aug 7, 2026
3a516fc
Merge pull request #282 from hgopalan/copilot/phase2-real-per-column-…
hgopalan Aug 7, 2026
4592cc1
Phase 2b: Wire per-column kernel into diagnostics driver - Initial im…
Copilot Aug 7, 2026
db4a105
Phase 2b: Fix state access to use vars_old[lev][Vars::cons]
Copilot Aug 7, 2026
9600fd7
Fix Access Bug
hgopalan Aug 7, 2026
577343c
Merge pull request #283 from hgopalan/copilot/phase2b-wire-real-per-c…
hgopalan Aug 7, 2026
6743bee
Fix
hgopalan Aug 7, 2026
f41d400
Fix
hgopalan Aug 7, 2026
04d4a1f
Phase 2c: Implement GPU-safe ParallelFor, real LW downward sweep, and…
Copilot Aug 7, 2026
5e83943
Phase 2c: Update documentation with Phase 2b, Phase 2c sections and k…
Copilot Aug 7, 2026
dcb2691
Merge pull request #284 from hgopalan/copilot/phase2c-gpu-fix-and-lw-…
hgopalan Aug 7, 2026
f9e38d1
Fix gating
hgopalan Aug 7, 2026
ab99f75
Phase 3: Add cloud optical properties (variable tau profile + cloud f…
hgopalan Aug 7, 2026
552c1d1
Phase 3: Add SW_Cloud_Layer RegTest inputs and sounding file
hgopalan Aug 7, 2026
5d020ad
Complete Phase 3: Implement Cloud Optical Properties
hgopalan Aug 7, 2026
bcecd3c
Update RAD_MPI_SKILLS with new Phase 3 lessons
hgopalan Aug 7, 2026
8358239
Merge pull request #286 from hgopalan/copilot/phase3-cloud-optical-pr…
hgopalan Aug 7, 2026
92baf5c
Fix D.7 section split caused by misplaced D.8/D.9 insertion
hgopalan Aug 7, 2026
d9ca3d8
Phase 4: Add scattering parameters to RadChoice (single_scattering_al…
hgopalan Aug 7, 2026
a68a938
Phase 4: Add compute_sw_diffuse_flux() Meador-Weaver two-stream scatt…
hgopalan Aug 7, 2026
df30c2d
Phase 4: Wire compute_sw_diffuse_flux() into vertical_two_stream_sweep()
hgopalan Aug 7, 2026
3d99f07
Phase 4: Add SW_Scattering_Cloud RegTest
hgopalan Aug 7, 2026
4dd51ee
Merge pull request #287 from hgopalan/copilot/phase4-scattering-effec…
hgopalan Aug 7, 2026
3fcba5c
Fix stale [Phase1] hardcoded debug tag in RadiationDiagnostics::append
hgopalan Aug 7, 2026
a88b522
Revise radiation development status and documentation
hgopalan Aug 7, 2026
541e5b0
Revise RAD_MPI_SKILLS.md for clarity and updates
hgopalan Aug 7, 2026
54de2b2
Phase 5 Step 1/6: Add per-level (SW,LW) heating rate output to vertic…
hgopalan Aug 7, 2026
288566b
Modify radiation heating allocation conditions
hgopalan Aug 7, 2026
819fc3e
Wire TwoStream radiation diagnostics into time loop
hgopalan Aug 7, 2026
d8f18e0
Enable radiation source terms with TwoStream checks
hgopalan Aug 7, 2026
880bbe9
Update assertion method for lw_enabled check
hgopalan Aug 7, 2026
5ffc918
Phase 5 Step 6a: Add sounding file for RhoTheta coupling RegTest
hgopalan Aug 7, 2026
bf357dc
Merge pull request #288 from hgopalan/copilot/phase5-rhotheta-coupling
hgopalan Aug 7, 2026
eb701d2
Phase 5 Step 6a: Add RhoTheta coupling smoke-test RegTest (inputs)
hgopalan Aug 7, 2026
a8565de
Phase 5 Step 6b: Add check script for RhoTheta coupling RegTest
hgopalan Aug 7, 2026
7c02310
Update RAD_DEVELOPMENT.md
hgopalan Aug 7, 2026
385f19e
Document Phase 5 validation and RegTest results
hgopalan Aug 7, 2026
dae79e0
Document Phase 5 lesson on code correctness and wiring
hgopalan Aug 7, 2026
38ae4dc
Enhance roadmap with ease and regression test columns
hgopalan Aug 7, 2026
07e2fc0
Update RAD_DEVELOPMENT.md
hgopalan Aug 7, 2026
1b86314
Phase 6: Time-Stepping Integration - Documentation and RegTest
Copilot Aug 7, 2026
4d2279e
Merge pull request #289 from hgopalan/copilot/phase-6-radiation-integ…
hgopalan Aug 7, 2026
d341482
Fixed some minor issues
hgopalan Aug 7, 2026
5368751
Update RAD_DEVELOPMENT.md
hgopalan Aug 7, 2026
ea1d86f
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Aug 7, 2026
2eea47d
Enhance Phase 6 diagnostics handling and rules
hgopalan Aug 7, 2026
80c1701
Revise Phase 6 diagnostics identity and prevention rules
hgopalan Aug 7, 2026
f13a7cd
Phase 7: TwoStream Runtime Diagnostics Controls - Core Implementation
Copilot Aug 7, 2026
41caf39
Apply remaining changes
Copilot Aug 7, 2026
aebaab3
Delete Exec/CanonicalTests/Radiation/Phase6_TimeIntegration/__pycache…
hgopalan Aug 7, 2026
493fc8e
Merge pull request #290 from hgopalan/copilot/erf-radiation
hgopalan Aug 7, 2026
a70e7eb
Add file change
hgopalan Aug 7, 2026
ca07802
Phase 8: Complete benchmark suite implementation with metrics validation
Copilot Aug 7, 2026
bcb7caa
Phase 8: Complete benchmark suite with full testing and validation
Copilot Aug 7, 2026
07821fe
Apply remaining changes
Copilot Aug 7, 2026
036110b
Merge pull request #291 from hgopalan/copilot/erf-radiation
hgopalan Aug 7, 2026
e5f7781
Phase 9: Add diagnostics dedup hardening and nonuniform dz support
Copilot Aug 8, 2026
74264ae
Phase 9: Update documentation with Phase 9 scope and lessons learned
Copilot Aug 8, 2026
ff53c42
Merge pull request #292 from hgopalan/copilot/phase-9-twostream-integ…
hgopalan Aug 8, 2026
b19a55f
Push some
hgopalan Aug 8, 2026
c5f5709
Fix
hgopalan Aug 8, 2026
c0a981a
docs(radiation): update roadmap with Phase 9 complete and SEB phases …
hgopalan Aug 8, 2026
e69093d
Phase 10 Step 1-4: Wire per-level dz(k) into vertical_two_stream_swee…
Copilot Aug 8, 2026
df5350b
Phase 10 Step 6: Update documentation with implementation details
Copilot Aug 8, 2026
d720f42
Phase 10: Add TwoStream_NonuniformDZ test for nonuniform vertical spa…
Copilot Aug 8, 2026
d047ce4
Register TwoStream_NonuniformDZ test in CTestList
Copilot Aug 8, 2026
a4243b9
Merge pull request #293 from hgopalan/copilot/phase-10-implementation
hgopalan Aug 8, 2026
d8de167
Fix
hgopalan Aug 8, 2026
83103ef
Phase 11 Implementation: Surface Heterogeneity + Fallback for TwoStre…
Copilot Aug 8, 2026
473ca01
Phase 11 Final: Complete surface heterogeneity implementation with co…
Copilot Aug 8, 2026
89e8d3b
Phase 11 COMPLETE: All deliverables finalized
Copilot Aug 8, 2026
74cd57d
Phase 11 FINAL COMMIT: Complete implementation with full documentatio…
Copilot Aug 8, 2026
0ffe8c7
Merge pull request #294 from hgopalan/copilot/phase-11-homogeneous-su…
hgopalan Aug 8, 2026
09bf96d
Fix
hgopalan Aug 8, 2026
982fa6e
Fix
hgopalan Aug 8, 2026
c28a86f
Fix
hgopalan Aug 8, 2026
5f850e4
Fix
hgopalan Aug 8, 2026
5fc8569
Phase 12: Add dynamic tau diagnosis functions and parameters
Copilot Aug 8, 2026
caddaad
Phase 12: Complete implementation with test case and documentation
Copilot Aug 8, 2026
1cb8e98
Phase 12: Final documentation and deliverables summary
Copilot Aug 8, 2026
1017cb3
Merge pull request #295 from hgopalan/copilot/phase-12-moisture-cloud…
hgopalan Aug 8, 2026
9308740
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Aug 8, 2026
a00a9af
Fix the phase12 case
hgopalan Aug 8, 2026
4d90d25
Phase 13: Implement YSUNew radiative tendency limiter/smoothing with …
Copilot Aug 8, 2026
b5e4e20
Phase 13: Complete YSUNew radiative tendency limiter implementation w…
Copilot Aug 8, 2026
8637e54
Merge pull request #296 from hgopalan/copilot/implement-ysunew-only-c…
hgopalan Aug 8, 2026
50e9f22
Fix the python script
hgopalan Aug 8, 2026
868cc54
Phase 14: Add prognostic cloud fraction parameters and core diagnosis…
Copilot Aug 8, 2026
fd30b42
Phase 14: Add comprehensive documentation to RAD_DEVELOPMENT.md and R…
Copilot Aug 8, 2026
5520522
Phase 14: Create regression test case and checker
Copilot Aug 8, 2026
a8967e2
Phase 14: Final summary document and completion checkpoint
Copilot Aug 8, 2026
4afc7b9
Merge pull request #297 from hgopalan/copilot/implement-prognostic-cl…
hgopalan Aug 8, 2026
fa09460
Fix
hgopalan Aug 8, 2026
8c85442
Fix
hgopalan Aug 8, 2026
a5421b4
Fix
hgopalan Aug 8, 2026
499d0dc
Phase 14A: Add member variables and allocate fallback MultiFabs, wire…
Copilot Aug 8, 2026
d65de28
Phase 14A: Add comprehensive documentation to RAD_DEVELOPMENT.md
Copilot Aug 8, 2026
85fbae4
Phase 14A: Refactor LSM wiring code, remove unnecessary inline comments
Copilot Aug 8, 2026
9291120
Merge pull request #298 from hgopalan/copilot/phase-14a-wire-lsm-prop…
hgopalan Aug 8, 2026
e3b209f
Critical fix: Add .resize(nlevs_max) for TwoStream MultiFab vectors i…
Copilot Aug 8, 2026
552e1a6
Add TwoStream_ProgCloudFraction test configuration and CTestList entry
Copilot Aug 8, 2026
c9b3d96
Update RAD_DEVELOPMENT.md and RAD_MPI_SKILLS.md with Phase 14B docume…
Copilot Aug 8, 2026
60e7dcf
Merge pull request #299 from hgopalan/copilot/fix-unresized-twostream…
hgopalan Aug 8, 2026
e91c06d
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Aug 9, 2026
3fb91f6
Fix wrong file
hgopalan Aug 9, 2026
3798642
Phase 15: Implement bulk aerosol/turbidity optical depth option
Copilot Aug 9, 2026
865b3cc
Add Phase 15 headers to Make.package
Copilot Aug 9, 2026
3bb650c
Merge pull request #300 from hgopalan/copilot/phase-15-bulk-aerosol-t…
hgopalan Aug 9, 2026
9afaa68
Height
hgopalan Aug 9, 2026
ff67264
Fix Aerosol
hgopalan Aug 9, 2026
5a47555
Fix Aerosol
hgopalan Aug 9, 2026
524a330
Fix Aerosol
hgopalan Aug 9, 2026
deabd68
Phase 16: Add solar geometry module and integrate into radiation code
Copilot Aug 10, 2026
56feb39
Update roadmap: revise Phase 17-20 scope for SEB (MultiFab infra, dia…
hgopalan Aug 10, 2026
15c6c6e
Phase 16: Add documentation and test infrastructure
Copilot Aug 10, 2026
5ab564d
Phase 16: Add solar geometry header to Make.package build system
Copilot Aug 10, 2026
0de0c52
Merge branch 'ERF-Radiation' into copilot/phase16-time-varying-solar-…
hgopalan Aug 10, 2026
586deef
Merge pull request #301 from hgopalan/copilot/phase16-time-varying-so…
hgopalan Aug 10, 2026
40a326d
Fix Solar Geometry and case setup
hgopalan Aug 10, 2026
0d832c4
Phase 17: SEB MultiFab Infrastructure + Noah-MP Passthrough (Phase 16…
Copilot Aug 10, 2026
d858628
Merge pull request #302 from hgopalan/copilot/phase-16-cleanup
hgopalan Aug 10, 2026
2751a1b
Fix
hgopalan Aug 10, 2026
4b02828
Phase 18: Simplified SEB Diagnostic Mode - complete implementation
Copilot Aug 10, 2026
d4b6c8b
Merge pull request #303 from hgopalan/copilot/fix-input-sounding-bug
hgopalan Aug 10, 2026
f519bb6
Fix
hgopalan Aug 10, 2026
f246670
Fix
hgopalan Aug 10, 2026
2ea9053
Fix
hgopalan Aug 10, 2026
cb2a72a
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Aug 10, 2026
98f5aab
Phase 19a: Standardize SEB MultiFab ghost cells to 1 ghost cell in x/y
Copilot Aug 10, 2026
455083e
Merge pull request #304 from hgopalan/copilot/phase19a-standardize-se…
hgopalan Aug 10, 2026
b191ecb
Part 1: Add prognostic SEB helper functions
Copilot Aug 10, 2026
d44c083
Part 2: Add Phase 19b parameters to RadChoice
Copilot Aug 10, 2026
4c35121
Part 3: Integration of prognostic SEB update in radiation driver
Copilot Aug 10, 2026
c685e0a
Part 5: Create Phase 19b RegTest directory with inputs and validation…
Copilot Aug 10, 2026
d695912
Add Phase 19b documentation to RAD_DEVELOPMENT.md and update roadmap
Copilot Aug 10, 2026
3ba632b
Merge pull request #305 from hgopalan/copilot/phase-19b-integrate-seb…
hgopalan Aug 10, 2026
f567353
Fix
hgopalan Aug 10, 2026
498f50d
Fix
hgopalan Aug 10, 2026
369d881
Fix
hgopalan Aug 10, 2026
10ccf19
Phase 20 implementation: SEB coupling safeguards and confirmed bugfixes
Copilot Aug 11, 2026
69d6671
Merge pull request #306 from hgopalan/copilot/phase-20-seb-coupling-s…
hgopalan Aug 11, 2026
f7fc103
Fix
hgopalan Aug 11, 2026
16cae91
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Aug 11, 2026
45a63aa
Plotfile
hgopalan Aug 18, 2026
cb45999
Merge remote-tracking branch 'origin/development' into ERF-Radiation
hgopalan Aug 18, 2026
273ff85
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Aug 18, 2026
ae07497
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Aug 20, 2026
672e898
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Aug 22, 2026
164a090
Merge remote-tracking branch 'origin/development' into ERF-Radiation
hgopalan Aug 27, 2026
815655f
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Aug 28, 2026
637d7be
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Sep 1, 2026
114d3b3
Clean up Phase N references from Radiation source code comments
Copilot Sep 1, 2026
f5e284e
Merge pull request #307 from hgopalan/copilot/erf-radiation
hgopalan Sep 1, 2026
e99fa57
Add master reference inputs file for two-stream radiation ParmParse p…
hgopalan Sep 1, 2026
42d75d3
Fix ERF_TwoStreamSW.H: use gamma4 explicitly in diffuse SW source ter…
hgopalan Sep 1, 2026
dfe94a1
Fix
hgopalan Sep 1, 2026
df99d8a
Add two-stream radiation documentation to Sphinx docs
Copilot Sep 1, 2026
af17993
Merge pull request #308 from hgopalan/copilot/erf-radiation-update-docs
hgopalan Sep 1, 2026
296f8f9
Final cleaup
hgopalan Sep 1, 2026
04f9b83
Delete unrequired
hgopalan Sep 1, 2026
7440b96
Refactor radiation documentation index and references
Copilot Sep 1, 2026
96919ed
Add README files to test directories lacking documentation
Copilot Sep 1, 2026
05e6e19
Fix remaining Phase6_TimeIntegration reference in PHASE_12_MANUAL_VER…
Copilot Sep 1, 2026
aed3fd8
Merge remote-tracking branch 'origin/ERF-Radiation' into copilot/clea…
Copilot Sep 1, 2026
7db936f
Merge pull request #309 from hgopalan/copilot/clean-up-canonical-tests
hgopalan Sep 1, 2026
8ce980e
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Sep 3, 2026
24513ba
Fix two-stream radiation orientation, Exner temperature, plotfile out…
hgopalan Sep 3, 2026
e2e35f7
Merge pull request #325 from hgopalan/fix/twostream-orientation-exner
hgopalan Sep 3, 2026
694a7f8
Wire two-stream radiation into unit and regression tests; re-apply re…
hgopalan Sep 3, 2026
a2273f8
Merge pull request #327 from hgopalan/twostream-tests
hgopalan Sep 3, 2026
c8395ac
Clean up the two-stream radiation driver
hgopalan Sep 3, 2026
fe85438
Merge pull request #329 from hgopalan/twostream-cleanup
hgopalan Sep 3, 2026
71c9e0a
Two-stream SW adding method with surface albedo; honest diagnostics c…
hgopalan Sep 3, 2026
3051867
Merge pull request #332 from hgopalan/twostream-sw-adding
hgopalan Sep 3, 2026
0b548bf
Two-stream: store theta tendencies (Exner) and use a device-safe para…
hgopalan Sep 3, 2026
1bc02e6
Merge pull request #333 from hgopalan/twostream-exner-gpu
hgopalan Sep 3, 2026
05a5c49
Two-stream: mass-based gray LW, diffuse albedo, Earth-Sun distance; r…
hgopalan Sep 3, 2026
bb5f54f
Merge pull request #335 from hgopalan/twostream-lw-mass
hgopalan Sep 3, 2026
b1444b3
Two-stream: mass-based optical depth model (tau_model = mass), backwa…
hgopalan Sep 3, 2026
b24cbed
Merge pull request #336 from hgopalan/twostream-tau-mass
hgopalan Sep 3, 2026
ec86a18
Merge branch 'development' into ERF-Radiation
AMLattanzi Sep 4, 2026
3b912ea
Merge branch 'erf-model:development' into ERF-Radiation
hgopalan Sep 5, 2026
22befba
Two-stream radiation: fix portability build breaks and the column swe…
hgopalan Sep 5, 2026
43c9406
Two-stream radiation: professional comments, and reject silently-igno…
hgopalan Sep 9, 2026
45dd0e1
Two-stream radiation: keep the input validation inside the two-stream…
hgopalan Sep 9, 2026
7efd6fc
Merge branch 'development' into ERF-Radiation
hgopalan Sep 9, 2026
5185636
Two-stream radiation: report bad input instead of aborting on it
hgopalan Sep 9, 2026
3f164ec
Add a two-stream / RRTMGP cost comparison case, and profile both solvers
hgopalan Sep 9, 2026
6b6f8e0
Fix the CUDA build of the two-stream sweep, and clear the build warnings
hgopalan Sep 10, 2026
b940fb4
Run both halves of the SEB diagnostic A/B pair for the same duration
hgopalan Sep 10, 2026
2242830
Merge branch 'development' into ERF-Radiation
asalmgren Sep 11, 2026
c357c66
Merge branch 'development' into ERF-Radiation
asalmgren Sep 11, 2026
af9f0ff
Restore the HOL_abs declaration the development merge dropped from MRF
hgopalan Sep 11, 2026
0d46a03
Two-stream SEB: step by dt, sweep once per step, checkpoint the surfa…
hgopalan Sep 11, 2026
5da37e8
Two-stream radiation: close the remaining audit items
hgopalan Sep 11, 2026
a6dbe9a
Merge branch 'development' into ERF-Radiation
asalmgren Sep 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CMake/BuildERFExe.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,8 @@ function(build_erf_lib erf_lib_name)
${SRC_DIR}/PBL/ERF_ComputeDiffusivityYSU.cpp
${SRC_DIR}/PBL/ERF_ComputeDiffusivityMRF.cpp
${SRC_DIR}/PBL/ERF_ComputeDiffusivityYSUNew.cpp
${SRC_DIR}/Radiation/ERF_RadiationDiagnostics.cpp
${SRC_DIR}/Radiation/ERF_AdvanceTwoStreamRadiation.cpp
${SRC_DIR}/Refinement/ERF_Tagging.cpp
${SRC_DIR}/Refinement/ERF_RefineBox.cpp
${SRC_DIR}/Refinement/ERF_RefineHurricane.cpp
Expand Down Expand Up @@ -627,6 +629,7 @@ function(build_erf_lib erf_lib_name)
target_include_directories(${erf_lib_name} PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Source/IO>)
target_include_directories(${erf_lib_name} PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Source/LinearSolvers>)
target_include_directories(${erf_lib_name} PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Source/PBL>)
target_include_directories(${erf_lib_name} PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Source/Radiation>)
target_include_directories(${erf_lib_name} PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Source/SourceTerms>)
target_include_directories(${erf_lib_name} PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Source/TimeIntegration>)
target_include_directories(${erf_lib_name} PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/Source/Utils>)
Expand Down
272 changes: 267 additions & 5 deletions Docs/sphinx_doc/Inputs.rst

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Docs/sphinx_doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ In addition to this documentation, there is API documentation for ERF generated
theory/DNSvsLES.rst
theory/PBLschemes.rst
theory/Forcings.rst
theory/Radiation.rst
Particles.rst
SuperDroplets.rst
ProblemInputs.rst
Expand Down
403 changes: 403 additions & 0 deletions Docs/sphinx_doc/theory/Radiation.rst

Large diffs are not rendered by default.

53 changes: 53 additions & 0 deletions Exec/CanonicalTests/Radiation/LW_Isothermal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Longwave Isothermal Column Test

## Objective

Validate the gray-gas longwave solver on a physically isothermal column: an atmosphere at a
uniform absolute temperature over a black surface at the same temperature.

## Test Design

### Configuration

- **Domain**: 3000 m × 3000 m horizontal, 1024 m vertical (64 layers)
- **Time**: one slow step (0.25 s)
- **Sounding**: `theta(z) = T0 exp(g z / (c_p T0))` with `T0 = 300 K`, so `T = theta * pi = T0`
at every level (the sounding is piecewise linear between five levels, accurate to ~0.05 K)
- **Surface**: `surface_temp_k = 300`, `surface_emissivity_lw = 1`
- **Longwave optical depth per layer**: `tau_lw = 1.0` (the 64-layer column is opaque)
- **Shortwave**: disabled

### Key Physics

Every layer emits `sigma T0^4`. In an opaque isothermal column the upward flux is `sigma T0^4`
on every interface and the downward flux approaches `sigma T0^4` at the surface, so

```
LW_up_TOA = sigma T0^4 ≈ 459.3 W/m²
LW_net_surface = sigma T0^4 exp(-tau_col) ≈ 0 W/m²
```

The column still cools to space (the downward flux vanishes at the top), so the heating rate is
non-zero and strongest in the top layers. This case previously used an `isothermal_test` override
that forced `F_up = F_down` and zero heating; it now exercises the real solver.

## Files

- `inputs` — control file
- `input_sounding_lw_isothermal` — isothermal-temperature sounding
- `check_flux_accuracy.py` — validation script
- `radiation_lw_diag.dat` — reference diagnostics

## Running the Test

```bash
cd Exec/CanonicalTests/Radiation/LW_Isothermal
mpirun -np 1 erf.ex inputs
python3 check_flux_accuracy.py
```

## Validation Criteria

1. `LW_up_TOA` within 0.5% of `sigma T0^4`
2. `|LW_net_surface|` below 0.5% of `sigma T0^4`
3. `heating_rate_max` finite and non-zero
184 changes: 184 additions & 0 deletions Exec/CanonicalTests/Radiation/LW_Isothermal/check_flux_accuracy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
#!/usr/bin/env python3
"""
Two-Stream Radiation Validation Script
Longwave Isothermal Column

The sounding prescribes theta(z) = T0 exp(g z / (c_p T0)) so that the
absolute temperature is T0 = 300 K at every level, and the surface is a
black body at the same T0. With a gray optical depth of 1 per layer over
64 layers the column is opaque, so the gray-gas solution gives

LW_up_TOA = sigma T0^4 (emission of the top layers)
LW_net_surface = sigma T0^4 exp(-tau_col) ~ 0 (F_down(0) -> sigma T0^4)

and every layer cools (cooling to space, strongest at the top), so
heating_rate_max is non-zero. This replaces the former isothermal_test
override, which forced these values instead of computing them.

It reads radiation_lw_diag.dat and checks that:
1. LW_up_TOA matches sigma*T0^4 within a small tolerance (the sounding is a
piecewise-linear approximation of the exponential theta profile)
2. |LW_net_surface| is negligible compared to sigma*T0^4
3. heating_rate_max is finite and non-zero (the column radiates to space)
"""

import sys
import os
import numpy as np
import math

def read_radiation_diag(filename):
"""Read the radiation diagnostic CSV and return a dict of column lists.

The file is comma separated with a header line
(step,time,call_site,SW_surface,SW_TOA,SW_up_TOA,LW_net_surface,LW_up_TOA,heating_rate_max,...),
so columns are looked up by name rather than by position. Non-numeric
columns (call_site) are kept as strings; numeric columns are floats.
"""
import csv
try:
with open(filename, 'r') as f:
reader = csv.DictReader(f)
if reader.fieldnames is None:
print(f"ERROR: No header found in {filename}")
return None
data = {name.strip(): [] for name in reader.fieldnames}
for row in reader:
if not any((v or '').strip() for v in row.values()):
continue
for name in reader.fieldnames:
key = name.strip()
val = (row.get(name) or '').strip()
if key == 'call_site':
data[key].append(val)
elif key == 'step':
data[key].append(int(float(val)))
else:
try:
data[key].append(float(val))
except ValueError:
data[key].append(float('nan'))
except IOError:
print(f"ERROR: Could not read {filename}")
return None

if not data.get('step'):
print(f"ERROR: No data found in {filename}")
return None

return data

def compute_bb_radiation(T, sigma=5.670374419e-8):
"""
Compute blackbody radiation intensity using Stefan-Boltzmann law.

Args:
T: Temperature [K]
sigma: Stefan-Boltzmann constant [W/(m^2·K^4)]

Returns:
Radiative intensity [W/m^2]
"""
if T <= 0:
return 0.0
return sigma * T**4

def check_lw_isothermal_accuracy():
"""Check LW isothermal test accuracy."""

# Read diagnostic file
diag_file = "radiation_lw_diag.dat"
if not os.path.exists(diag_file):
print(f"ERROR: Diagnostic file {diag_file} not found")
return False

data = read_radiation_diag(diag_file)
if data is None:
return False

# Test parameters (must match inputs file and sounding)
T_iso_K = 300.0 # Isothermal temperature [K] (surface_temp_k and the sounding)
sigma = 5.670374419e-8 # Stefan-Boltzmann constant [W/(m^2·K^4)]

# Expected upwelling/downwelling flux (same in isothermal mode)
expected_flux = compute_bb_radiation(T_iso_K, sigma)

# Tolerance for numerical accuracy
# In isothermal mode with exact arithmetic:
# - Upwelling and downwelling should be identical
# - Heating rates should be exactly zero
# With finite precision, we allow ~1e-10 relative error
# The 5-point sounding approximates the exponential theta profile to
# ~0.05 K, i.e. ~0.1% in sigma T^4; allow 0.5%.
flux_tolerance = 5e-3
net_tolerance = 5e-3 # |LW_net_surface| / sigma T^4

print(f"\n{'='*70}")
print("Two-Stream Radiation: LW Isothermal Column Test")
print(f"{'='*70}")
print(f"\nTest Parameters:")
print(f" Isothermal temperature T_iso = {T_iso_K:.2f} K")
print(f" Stefan-Boltzmann constant σ = {sigma:.6e} W/(m^2·K^4)")
print(f"\nAnalytical Solution:")
print(f" Expected LW_up_TOA = σ*T^4 = {expected_flux:.4f} W/m^2")
print(f" Expected LW_net_surface ≈ 0 W/m^2 (opaque column at the surface temperature)")
print(f" Expected heating_rate_max > 0 (cooling to space from the top layers)")

# Extract last timestep data
last_idx = -1
step = data['step'][last_idx]
time = data['time'][last_idx]
LW_net_surface = data['LW_net_surface'][last_idx]
LW_up_TOA = data['LW_up_TOA'][last_idx]
heating_rate_max = data['heating_rate_max'][last_idx]

print(f"\nComputed Values (step {step}, time {time:.4f}s):")
print(f" Computed LW_up_TOA = {LW_up_TOA:.4f} W/m^2")
print(f" Computed LW_net_surface = {LW_net_surface:.4f} W/m^2")
print(f" Maximum heating rate = {heating_rate_max:.4e} K/s")

# Check results
errors = []

print(f"\nAccuracy Checks:")
# Isothermal column: the outgoing LW at the top is sigma*T^4.
if expected_flux > 0:
up_error = abs(LW_up_TOA - expected_flux) / expected_flux
print(f" LW_up_TOA relative error: {up_error:.4e}", end="")
if up_error > flux_tolerance:
print(f" [FAIL - exceeds {flux_tolerance:.4e}]")
errors.append(f"LW_up_TOA error too large: {up_error:.4e}")
else:
print(" [PASS]")

# Isothermal column: up and down fluxes are equal, so the surface net LW is zero.
net_error = abs(LW_net_surface) / expected_flux
print(f" |LW_net_surface| / sigma T^4: {net_error:.4e}", end="")
if net_error > net_tolerance:
print(f" [FAIL - exceeds {net_tolerance:.4e}]")
errors.append(f"LW_net_surface not negligible: {LW_net_surface:.4e} W/m^2")
else:
print(" [PASS]")

# The column radiates to space, so the heating (cooling) is finite and non-zero
print(f" Heating rate magnitude: {abs(heating_rate_max):.4e} K/s", end="")
if not math.isfinite(heating_rate_max) or abs(heating_rate_max) <= 0.0:
print(" [FAIL - expected a finite, non-zero cooling rate]")
errors.append(f"heating_rate_max not finite/non-zero: {heating_rate_max}")
else:
print(" [PASS]")

# Overall result
print(f"\n{'='*70}")
if errors:
print("TEST FAILED")
for err in errors:
print(f" - {err}")
return False
else:
print("TEST PASSED - isothermal column verified (LW_up_TOA = σT^4, LW_net_surface ≈ 0, cooling to space)")
return True

if __name__ == "__main__":
success = check_lw_isothermal_accuracy()
sys.exit(0 if success else 1)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
1000. 300.0 0.0
0.0 300.000 0.0 15.0 0.0
256.0 302.511 0.0 15.0 0.0
512.0 305.042 0.0 15.0 0.0
768.0 307.595 0.0 15.0 0.0
1024.0 310.169 0.0 15.0 0.0
123 changes: 123 additions & 0 deletions Exec/CanonicalTests/Radiation/LW_Isothermal/inputs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Two-Stream Radiation: Shortwave Clear-Sky Analytical Test
# Tests Beer-Lambert direct-beam solar radiation without clouds or scattering
# Verifies against analytical solution: F(z) = S0 * cos(zenith) * exp(-tau_cumulative / cos(zenith))
erf.prob_name = "ABL"

stop_time = 0.25
amrex.fpe_trap_invalid = 0

fabarray.mfiter_tile_size = 1024 1024 1024

geometry.prob_extent = 3000 3000 1024
amr.n_cell = 8 8 64
amr.max_grid_size_z = 128
geometry.is_periodic = 1 1 0


zlo.type = "surface_layer"
erf.most.z0 = 0.1 # roughness length [m]
erf.most.zref = 24.0 # reference height [m]
erf.most.surf_temp_flux = 0.0
zhi.type = "SlipWall"
zhi.theta_grad = 0.003 # adiabatic upper boundary
erf.fixed_dt = 0.5 # time step [s]

# DIAGNOSTICS & VERBOSITY
erf.sum_interval = 1 # timesteps between computing mass
erf.v = 1 # verbosity in ERF.cpp
amr.v = 1 # verbosity in Amr.cpp

# REFINEMENT / REGRIDDING
amr.max_level = 0 # maximum level number allowed

# CHECKPOINT FILES
erf.check_file = chk_neutral # root name of checkpoint file
erf.check_int = -1 # number of timesteps between checkpoints

# DATA COLLECTION
erf.data_log = neutral_hist.dat neutral_profiles.dat
erf.profile_int = 10

# PLOTFILES
erf.plot_file_1 = plt_neutral # prefix of plotfile name
erf.plot_int_1 = 1000 # number of timesteps between plotfiles
erf.plot_vars_1 = x_velocity y_velocity z_velocity theta

# SOLVER CHOICE
erf.use_gravity = true

erf.molec_diff_type = "None"
# When using a PBL model, LES closure should be disabled
erf.les_type = "None"
erf.Cs = 0.11
erf.theta_ref = 300.0

# INITIALIZATION - from sounding file
erf.init_type = "input_sounding"
erf.sounding_type = Ideal


# PBL CONFIGURATION - Baseline MRF (neutral case)
erf.pbl_type = "MRF"

# MRF PBL PARAMETERS (for MRF model)
erf.enable_mrf_cloud_adjustment = false
erf.enable_mrf_countergradient = true
erf.enable_mrf_unbounded_vpert = false
erf.mrf_moistvars = false
erf.pbl_mrf_Ribcr = 0.5
erf.pbl_mrf_const_b = 7.8
erf.pbl_mrf_coriolis_freq = 1.0e-4
erf.pbl_mrf_highres_bounds = false
erf.pbl_mrf_sf = 0.1
erf.pbl_mrf_use_zero_ri_extent = false

# ============================================================
# YSUNew PBL PARAMETERS (uncomment to use YSU model)
# For YSUNew model:
# 1. Comment out the MRF parameters above
# 2. Uncomment the following YSU parameters
# 3. Change 'erf.pbl_type = "MRF"' to 'erf.pbl_type = "YSUNew"'
# ============================================================
# erf.enable_ysu_cloud_pblh = true
# erf.enable_ysu_countergradient = true
# erf.enable_ysu_entrainment = true
# erf.enable_ysu_liquid_theta = true
# erf.enable_ysu_sat_limiter = false
# erf.enable_ysu_terrain_pblh_floor = true
# erf.enable_ysu_topdown = true
# erf.pbl_ysu_coriolis_freq = 1.0e-4
# erf.pbl_ysu_force_over_water = false
# erf.pbl_ysu_land_Ribcr = 0.25
# erf.pbl_ysu_unst_Ribcr = 0.0
# erf.pbl_ysu_use_consistent_coriolis = false
# erf.pbl_ysunew_highres_bounds = false
# erf.ysu_moistvars = false
# erf.ysu_qcloud_threshold = 1.0e-4

# Disable countergradient corrections (not relevant for neutral conditions)

# Enable moisture diffusivity for completeness (but no moisture in neutral case)

# CORIOLIS EFFECT
erf.latitude = 45.0 # mid-latitude (f = 1.0e-4 s^-1)

erf.use_coriolis = true

erf.abl_driver_type = "GeostrophicWind"

erf.abl_geo_wind = 15.0 0.0 0.0

erf.input_sounding_file = "input_sounding_lw_isothermal"

# RADIATION - Two-Stream Longwave (Isothermal mode)
erf.radiation_type = "TwoStream"
erf.radiation.sw_enabled = false
erf.radiation.lw_enabled = true
erf.radiation.tau_lw_per_layer = 1.0
# Physically isothermal column: theta(z) = 300 exp(g z / (c_p 300)) gives T = 300 K everywhere,
# and the surface is black at the same 300 K.
erf.radiation.surface_temp_k = 300.0
erf.radiation.surface_emissivity_lw = 1.0
erf.radiation.v = 1
erf.radiation.diag_file = "radiation_lw_diag.dat"
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
step,time,call_site,SW_surface,SW_TOA,SW_up_TOA,LW_net_surface,LW_up_TOA,heating_rate_max,SEB_residual_mean,SEB_residual_max,T_s_mean,T_s_max,q_s_mean,q_s_max
0,0.000000e+00,pre_dycore,0.000000e+00,0.000000e+00,0.000000e+00,-3.986685e-03,4.593046e+02,1.804952e-02,nan,nan,nan,nan,nan,nan
0,2.500000e-01,post_dycore,0.000000e+00,0.000000e+00,0.000000e+00,-3.986685e-03,4.593046e+02,1.804952e-02,nan,nan,nan,nan,nan,nan
Loading