Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 31 additions & 0 deletions Docs/sphinx_doc/Inputs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3177,6 +3177,9 @@ List of Parameters
+---------------------------------------+----------------------------------------------------------+--------------------+------------------------------------+
| **erf.rad_do_subcol_sampling** | Enable MCICA subcolumn sampling | Boolean | true |
+---------------------------------------+----------------------------------------------------------+--------------------+------------------------------------+
| **erf.rad_use_shoc_cldfrac** | Use Native SHOC diagnosed liquid-cloud fraction in | Boolean | true |
| | RRTMGP when runtime Native SHOC is active | | |
+---------------------------------------+----------------------------------------------------------+--------------------+------------------------------------+
| **erf.rad_orbital_year** | Fixed orbital year for zenith calcs | Integer | < 0 uses timestamp year |
+---------------------------------------+----------------------------------------------------------+--------------------+------------------------------------+
| **erf.rad_orbital_eccentricity** | Override orbital eccentricity | Real | < 0 uses computed value |
Expand Down Expand Up @@ -3226,6 +3229,34 @@ List of Parameters
| **erf.four_stream_radiation** | use the four-stream radiation approximation | Boolean | false |
+---------------------------------------+----------------------------------------------------------+--------------------+------------------------------------+

Native SHOC cloud coupling
~~~~~~~~~~~~~~~~~~~~~~~~~~~

When ``erf.radiation_model = RRTMGP`` and runtime Native SHOC is selected,
``erf.rad_use_shoc_cldfrac`` defaults to true and uses the Native SHOC
``shoc_cldfrac`` diagnostic. This diagnostic is the liquid-cloud fraction from
the SHOC PDF; it excludes cloud ice. The host ``qc`` field remains the liquid
mixing-ratio input to RRTMGP, and the diagnostic is not a replacement
condensate field. Other radiation models and non-Native PBL paths retain their
existing behavior.

RRTMGP uses one shared total-cloud mask for the combined liquid and ice optics.
Both liquid and ice paths are therefore normalized with that same total
fraction: the SHOC liquid fraction is used for liquid-only layers, while any
positive ice gives the existing binary ice fraction of one. The existing
in-cloud mixing-ratio floor of ``1e-4`` and cap of ``0.005`` are unchanged, as
is the single conversion from kg/m2 to g/m2. This shared-mask approximation
cannot represent liquid occupying only part of an ice-cloud layer.

With ``erf.rad_use_shoc_cldfrac = false``, cloud fractions are binary, but
Native SHOC + RRTMGP still runs radiation after the post-SHOC state update;
this is a fraction-only comparison, not a restoration of the pre-coupling
algorithm. With ``erf.rad_do_subcol_sampling = true`` RRTMGP uses the existing
MCICA maximum-random-overlap path. Setting it to false uses a deterministic
clear/cloudy band-to-g-point mapping for binary fractions. The combination of
Native SHOC, ``rad_use_shoc_cldfrac = true``, and sampling disabled is rejected
at startup; use sampling, or disable the SHOC fraction for a binary experiment.

.. _inputs-notes:

Notes
Expand Down
4 changes: 3 additions & 1 deletion Docs/sphinx_doc/plotfiles/Plotfile3DReference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,9 @@ available.
- Native SHOC ``pblh`` is reported in metres above local ground (AGL).
* - ``shoc_cldfrac``
- 1
- Subgrid cloud fraction diagnosed by the native SHOC PDF.
- Liquid-cloud fraction diagnosed by the native SHOC PDF. It excludes
cloud ice and is the optional liquid-fraction input to Native-SHOC
RRTMGP coupling.
* - ``shoc_ql``
- kg/kg
- Cloud-liquid mixing ratio diagnosed by the native SHOC PDF.
Expand Down
29 changes: 29 additions & 0 deletions Docs/sphinx_doc/theory/PBLschemes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,35 @@ below. Native ``state_update`` currently rejects moisture layouts containing
cloud-water or cloud-ice number concentration components because a compatible
number closure has not yet been implemented.

Native SHOC and RRTMGP cloud coupling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For runtime Native SHOC with RRTMGP, ERF passes the same-step
``shoc_cldfrac`` field to radiation after the Native SHOC state update and its
required state refill. ``shoc_cldfrac`` is the SHOC PDF's liquid-cloud
fraction only; it excludes cloud ice. The host ``qc`` remains the liquid
condensate input to RRTMGP, and ``shoc_ql`` is not substituted for it.

With the default ``erf.rad_use_shoc_cldfrac = true``, liquid-only layers use
the diagnosed fraction and cloud ice retains its binary fraction. RRTMGP
combines the phases under one total-cloud mask and normalizes both phases with
that same mask. The existing ``1e-4`` fraction floor and ``0.005`` in-cloud
mixing-ratio cap remain active. This bounded shared-mask approximation does
not represent liquid occupying only part of an ice-cloud layer; any positive
ice invokes the binary-ice rule.

Setting ``erf.rad_use_shoc_cldfrac = false`` selects binary cloud fractions
for the comparison while retaining the post-SHOC radiation ordering. It is a
fraction-only comparison, not a restoration of the pre-PR algorithm. The
``erf.rad_do_subcol_sampling`` combinations are:

* ``true``: use the existing MCICA maximum-random-overlap sampling path;
* ``false`` with binary fractions: use deterministic clear/cloudy
band-to-g-point mapping;
* ``false`` with Native SHOC fractional coupling: reject the configuration at
startup with guidance to enable sampling or disable
``rad_use_shoc_cldfrac``.

Native SHOC transport modes
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
136 changes: 136 additions & 0 deletions PR3500_FIX_REPORT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# ERF PR3500 Fix Report

Date: 2026-09-09
Branch: `Use_SHOC_cldfrac_with_RRTMGP`

## Merge

`origin/development` was fetched and merged into this branch.

- Development tip merged: `489a2aa64b8b49986096a3445285d74bcea73739`
- Pre-merge branch tip: `2515e8db62903e9aa20f28bc389466e9e0883a71`
- Merge base: `0f7b33d46713f464d4eda60453bbca3b60e13d8b`
- Merge commit: `185ae6713`
- Repair commit: the branch `HEAD` containing this report.

The only textual conflict was `Docs/sphinx_doc/Inputs.rst`. The development
version of the table was retained and the PR3500 `erf.rad_use_shoc_cldfrac`
entry was restored in the merged table.

## Repair disposition

### R1: Simple-radiation interface

`RadiationSimple::Run` now accepts the same optional liquid-cloud-fraction
pointer as the common radiation interface. Simple radiation intentionally
ignores the pointer, preserving its existing physics while restoring the
interface contract.

### R2: Shared cloud-mass mask

Both liquid and ice condensate conversions in `Radiation::run_impl` now use
the shared total cloud mask. The existing liquid-only SHOC diagnostic, binary
positive-ice rule, fraction floor, in-cloud mixing-ratio cap, effective radii,
snow handling, and single kg/m2-to-g/m2 conversion are retained.

The production converter and the regression witness share
`radiation_cloud_mass`. For `q=1e-4`, `rho=1`, and `dz=100`, the witness gives:

- liquid-only fraction `0.25`: in-cloud mass `0.04`, grid-mean mass `0.01`;
- ice-only or mixed total fraction `1`: in-cloud mass `0.01`, grid-mean mass
`0.01` for each phase;
- fraction floor `1e-4` and `q=1e-8`: in-cloud mass `0.01`, grid-mean mass
`1e-6`;
- cap case `q=0.01`, total fraction `1`: in-cloud and grid-mean mass `0.5`.

The shared-mask limitation is documented: liquid occupying only part of an
ice-cloud layer cannot be represented by this contract.

### R3: Sampling flag

`rad_do_subcol_sampling` now selects the existing MCICA maximum-random-overlap
path when true and a deterministic binary clear/cloudy band-to-g-point map
when false. Both shortwave and longwave paths use the selection. Deterministic
mapping initializes all shortwave optical quantities (`tau`, `ssa`, `g`) and
longwave optical depth for clear and cloudy states.

Native SHOC plus `rad_use_shoc_cldfrac=true` plus disabled sampling is rejected
at initialization with actionable guidance. Binary cloud fractions remain
available with sampling disabled.

### R4: Native SHOC ordering and pointer contract

The merged development ordering is preserved: native SHOC advances first,
updated state and face quantities are refilled, and Native-SHOC RRTMGP receives
the same-step `shoc_cldfrac` diagnostic afterward. Existing optional-pointer
validation continues to check cell centering, component count, BoxArray, and
DistributionMapping compatibility.

### R5: Documentation

The Inputs, Plotfile3DReference, PBLschemes, and Native SHOC README documents
now describe the liquid-only diagnostic, host `qc` ownership, shared total
mask, binary ice rule, sampling behavior, and the mixed-phase limitation.

### R6: Fallback and cadence

`rad_use_shoc_cldfrac=false` remains a fraction-only binary comparison. It does
not restore pre-coupling radiation ordering. Native SHOC/RRTMGP still runs
radiation after the Native SHOC update and refill.

### R7: Numeric test portability

SHOC radiation tests no longer use `EXPECT_DOUBLE_EQ` for `amrex::Real`.
Exact comparisons cast literals to `amrex::Real`; mass-contract checks use a
precision-scaled tolerance.

### R8: Evidence and review status

This report records the implementation, build, and test evidence below. The
requested external P3 review was not available in this workspace; no external
review claim is made. Full scientific flux/heating-rate and multi-level
runtime validation remain follow-up work requiring usable RRTMGP coefficient
files and a CUDA device.

## Verification

Passed:

- `bash -n MyBuildcldfrac/cmake.sh`
- `git diff --check`
- Clean requested build using `MyBuildcldfrac/cmake.sh` with its configured
CUDA 12.9, MPI, Kokkos, HDF5/NetCDF, Noah-MP, and RRTMGP options.
- `erf_exec` and `erf_shoc_test` linked successfully.
- `ERF_ShocRadiationCouplingTests.cpp` compiled in the CUDA/unit-test
configuration, including the new shared-mask and sampling tests.
- The focused executable linked successfully using the generated CMake link
script.
- `LD_PRELOAD=/nopt/cuda/12.9/lib64/stubs/libcuda.so ./erf_shoc_unit_tests
--gtest_list_tests` exited 0 and listed the complete SHOC suite, including
`ShocRadiationCloudFraction.*`.

The focused runtime filter was attempted with:

```text
LD_PRELOAD=/nopt/cuda/12.9/lib64/stubs/libcuda.so \
./erf_shoc_unit_tests --gtest_filter=ShocRadiationCloudFraction.*
```

It returned the project skip code 77 because the node reports the CUDA stub
driver and zero devices. Assertions were therefore compiled but not executed
on this host.

The clean `cmake.sh` build log is:
`MyBuildcldfrac/cmake_build_20260909_203757.log`.

## Suggested PR text

Summary: Merge current development into the Native SHOC/RRTMGP branch and
repair PR3500 cloud-fraction coupling. Native SHOC now supplies a same-step
liquid-only PDF diagnostic to RRTMGP after state refill; liquid and ice use one
shared total optical mask; and the sampling flag has explicit MCICA and
deterministic binary behavior with an invalid-combination startup check.

Tests: clean `MyBuildcldfrac/cmake.sh` build passed; the focused SHOC test
executable compiled and linked; runtime SHOC tests were skipped on this host
because no CUDA device/driver is available.
3 changes: 2 additions & 1 deletion Source/ERF.H
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,8 @@ public:

void advance_radiation (int lev,
amrex::MultiFab& cons_in,
const double& dt_advance);
const double& dt_advance,
const amrex::MultiFab* liquid_cloud_fraction = nullptr);

#ifdef ERF_USE_EAMXX_SHOC
void compute_shoc_tendencies (int lev,
Expand Down
26 changes: 26 additions & 0 deletions Source/PBL/Shoc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,32 @@ Also run representative non-SHOC regression tests after changing shared coupling
microphysics, plotfile, or time-integration paths. Native SHOC must not alter
non-SHOC results when it is not selected at runtime.

## RRTMGP radiation coupling

When Native SHOC is coupled to RRTMGP, ERF passes SHOC's diagnosed liquid-cloud
fraction to radiation when `erf.rad_use_shoc_cldfrac = true` (the default).
Radiation is called after the current Native SHOC update so the diagnostic and
the host thermodynamic state are from the same step. The diagnostic describes
liquid-cloud macrophysics only; cloud ice retains a binary fraction. ERF's host
`qc` field remains the liquid input to RRTMGP, and `shoc_ql` is not substituted
for it by this coupling.

RRTMGP uses one shared total-cloud mask for the combined liquid and ice optics.
Both phases are normalized with that total fraction, preserving the existing
`1e-4` fraction floor, `0.005` in-cloud mixing-ratio cap, effective radii,
and maximum-random-overlap behavior. Any positive ice invokes the binary-ice
rule. This approximation cannot represent liquid occupying only part of an
ice-cloud layer.

Setting `erf.rad_use_shoc_cldfrac = false` selects binary fractions while
retaining the post-SHOC radiation ordering; it is a fraction-only comparison,
not a restoration of the pre-PR algorithm. With
`erf.rad_do_subcol_sampling = true`, radiation uses the existing MCICA path.
With sampling disabled, RRTMGP uses deterministic clear/cloudy band-to-g-point
mapping for binary fractions. Native SHOC fractional coupling with sampling
disabled is rejected at startup; enable sampling or disable the SHOC fraction
for a binary experiment.

## See also

User documentation:
Expand Down
19 changes: 18 additions & 1 deletion Source/PhysicsInterfaces/Radiation/ERF_RRTMGP_Interface.H
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,22 @@ get_subsampled_clouds (const int ncol,
real2d_k& cld,
real2d_k& p_lay);

optical_props2_t
get_deterministic_clouds (const int ncol,
const int nlay,
const int ngpt,
optical_props2_t& cloud_optics,
gas_optics_t& kdist,
const real2d_k& cld);

optical_props1_t
get_deterministic_clouds (const int ncol,
const int nlay,
const int ngpt,
optical_props1_t& cloud_optics,
gas_optics_t& kdist,
const real2d_k& cld);

void
rrtmgp_initialize (gas_concs_t& gas_concs,
const std::string& coefficients_file_sw, const std::string& coefficients_file_lw,
Expand Down Expand Up @@ -132,7 +148,8 @@ rrtmgp_main (const int ncol, const int nlay,
real3d_k& sw_bnd_flux_up , real3d_k& sw_bnd_flux_dn , real3d_k& sw_bnd_flux_dn_dir,
real3d_k& lw_bnd_flux_up , real3d_k& lw_bnd_flux_dn,
const RealT tsi_scaling,
const bool extra_clnclrsky_diag = false, const bool extra_clnsky_diag = false);
const bool extra_clnclrsky_diag = false, const bool extra_clnsky_diag = false,
const bool do_subcol_sampling = true);


void
Expand Down
Loading
Loading