Skip to content

Conversation

@Qingfu-Liu
Copy link
Collaborator

@Qingfu-Liu Qingfu-Liu commented Jan 5, 2026

Description of Changes:

  1. Remove Zhao-Carr cloud schemes which are no longer used in the CCPP physics suites. The new code changes remove cloud calculation for "progcld_zhao_carr" and "progcld_zhao_carr_pdf".
  2. Create a new function cld_frac_XuRandall in the module_radiation_clouds, and replaced the subroutines "cloud_fraction_mass_flx_2", "cloud_fraction_mass_flx_1", and "cloud_fraction_XuRandall" with the new function.
  3. remove the function cld_frac_XuRandall from program GFS_rrtmgp_cloud_mp.F90, and replaced the function with the new functionly created function cld_frac_XuRandall in the module_radiation_clouds.

Tests Conducted:

Regression tests are conducted on Ursa, and the results are binary identical

Dependencies:

No dependence

Documentation:

No new document (not needed)

Issue (optional):

No issues. The changes remove Zhao-Carr cloud schemes which are no longer used, and combine some similar subroutines

@dustinswales
Copy link
Collaborator

@Qingfu-Liu Thanks for making these changes.

  1. I love to see radiation_clouds.f getting some long overdue housekeeping. Good work!
  2. It's great that the RRTMG-CLDMP coupling now has only one (configurable) flavor of Xu-Randall, but it appears that we now have two identical Xu-Randall cloud fraction routines; The one being introduced here in radiation_clouds.f for the RRTMG cloud coupling, and one used for the RRTGMP cloud coupling, GFS_rrtmgp_cloud_mp.F90.

Could we create a new module, say physics/Radiation/radiation_cloud_fraction.F90, which contains a single Xu-Randall cloud fraction routine that both RRTMG (physics/Radiation/radiation_clouds.f) and RRTMGP (physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.F90) uses?

@Qingfu-Liu
Copy link
Collaborator Author

@dustinswales OK. I will make the changes. Thanks.

@Qingfu-Liu
Copy link
Collaborator Author

@dustinswales I cross-checked the code between cld_frac_XuRandall (RRTMGP) and cloud_fraction_XuRandall (RRTMG), there is small differences between the two:
Line 806 (/scratch3/NCEPDEV/global/Qingfu.Liu/git/ufs-weather-model_20251229/UFSATM/ccpp/physics/physics/Interstitials/UFS_SCM_NEPTUNE/GFS_rrtmgp_cloud_mp.F90)
tem2 = max(min(tem1*(cld_mr - clwt), 50.0 ), 0.0 ) (where clwt = 1.0e-6 * (plyr(i,k)0.001))
Line 3160 (/scratch3/NCEPDEV/global/Qingfu.Liu/git/ufs-weather-model_20260105/UFSATM/ccpp/physics/physics/Radiation/radiation_clouds.f_save)
value = max( min( tem1
(clwf(i,k)-clwm), 50.0 ), 0.0 ) (where clwm=0. here)
Do you have any comments/suggestions (I prefer to use the RRTMG version here since no impact on the GFSv17 regression tests)

cldtot(i,k) = 1.
else
onemrh= max( 1.e-10, 1.0-rhly(i,k) )
clwm = clwmin / max( 0.01, plyr(i,k)*0.001 )
Copy link
Collaborator

@dustinswales dustinswales Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Qingfu-Liu I don't understand the need for this line? (clwmin =0 above)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. we can remove this line here. Should we change the line 806 in GFS_rrtmgp_cloud_mp.F90 as:
tem2 = max(min(tem1*(cld_mr-clwm), 50.0 ), 0.0 ), where clwm=0. in RRTMG
My guess is that clwm=clwt when you change the code for RRTMGP

endif
tem1 = xrc3 / tem1

value = max( min( tem1*(clwf(i,k)-clwm), 50.0 ), 0.0 )
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Qingfu-Liu If clwm = 0, then why subtract it from here.

@dustinswales
Copy link
Collaborator

@Qingfu-Liu I don't want to make the call here, but I "think" the GP formulation is correct, and the G formulation is not. At least when looking back at https://journals.ametsoc.org/view/journals/atsc/53/21/1520-0469_1996_053_3084_ascpfu_2_0_co_2.xml?tab_body=pdf.
We should select one, and whichever way we choose, it will impact the other radiation scheme. Thoughts?

@Qingfu-Liu
Copy link
Collaborator Author

@dustinswales I will do some more research. From the code, the two cloud fraction calculations for RRTMG and RRTMGP are different.

@dustinswales
Copy link
Collaborator

dustinswales commented Jan 5, 2026

@Qingfu-Liu As you pointed out, the algorithms are nearly the same, with small differences in the exponent.
For RRTMG, exponent = cloud mixing ratio - clwm (set = 0)
For RRTMGP, exponent = cloud mixing ratio - minimum allowable condensate (~1e-8)

So whatever way is "correct", it will impact the other and cause answer changes. But they should be the same.

@Qingfu-Liu
Copy link
Collaborator Author

@dustinswales I have modified the RRTMG code to make the Xu-Randall subroutine elemental and can be used for RRTMGP ( slightly modify the input variables). I will upload the code after the regression tests

@Qingfu-Liu
Copy link
Collaborator Author

@dustinswales I uploaded the new code and change the RRTMG Xu-Randall subroutine to be a function and elemental, and can be called in the RRTMGP scheme with extra input control variable "factor".

@dustinswales
Copy link
Collaborator

@Qingfu-Liu Thanks for doing this.
For GP (GFS_rrtmgp_cloud_mp.F90) we will need to:

  • Import cld_frac_XuRandall from module_radiation_clouds here
  • Remove the cld_frac_XuRandall subroutine from here
  • Modify calls to cld_frac_XuRandall in GFS_rrtmgp_cloud_mp to provide "factor=1".

Ultimately, I think FactorG=FactorGP, but this will not give us B4B reproducibility for the RRTMGP test if we adopt this here.
Even though the change is probably insignificant, I'm reluctant to support this w/o some testing in a GP enabled application.

@Qingfu-Liu
Copy link
Collaborator Author

@dustinswales I have removed the cld_frac_XuRandall function from RRTMGP scheme, and replaced the function from module_radiation_clouds. The regression tests from RRTMGP (two suites in the default rt.conf) produce binary identical results.
I am going to run the regression test for all the suites in the default rt.conf.

! Xu-Randall (1996) cloud-fraction.
cld_cnv_frac(iCol,iLay) = cld_frac_XuRandall(p_lay(iCol,iLay), &
qs_lay(iCol,iLay), relhum(iCol,iLay), qc+qi, alpha0)
play_pa = p_lay(iCol,iLay) *0.01
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to declare this local pressure var?
Can't you just pass p_lay(iCol,iLay) *0.01 into cld_frac_XuRandall?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can change this

integer :: iCol, iLay
real(kind_phys) :: tem1, deltaP, clwc, qc, qi
real(kind_phys) :: tem1, deltaP, clwc, qc, qi, play_pa
real(kind_phys) :: lambda = 0.50
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't lambda a constant for the cld_frac_XuRandall()?
Can we move is back in there?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lambda =0.25, 0.49 and 0.50 see file: ccpp/data/GFS_typedefs.F90 variable name xr_exp

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, @dustinswales, this is new. There was a PR that tuned this for UFS, but NRL wanted the tuning to be optional, so it became a host-controlled variable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants