CAM
CAM copied to clipboard
Radiatively active cloud water missing from COSP
What happened?
Hi all,
I'm doing some validation for a separate radiation diagnostics tool and came across something in CAM that I think is causing erroneous output from COSP.
Effectively, it seems that COSP is not seeing the correct cloud water (liquid and ice) mixing ratios. Specifically, the way the mixing ratios are calculated seems to have been updated in the radiation code at some point but this code was not brought into the COSP interface in CAM. I've done my best to document the issue below.
I noticed this when comparing RRTMG-LW's spectral output with a comparable spectral radiation value produced by a diagnostic tool. There were cases when RRTMG-LW produced a positive LWCF value and the diagnostic had zero LWCF. I am confident that this error also affects the standard COSP output, because the CALIPSO cloud diagnostics also reported zero cloud in the cases where the diagnostic produced zero cloud radiative effect (standard CESM cloud fields were ~20% cloudy with cloud water mixing ratios of ~2.5e-4).
The issue appears to result from different cloud water mixing ratios seen in the radiation scheme vs. those seen by COSP.
Specifically, in cloud_diagnostics.F90, the cloud water/ice mixing ratios are calculated differently if convective water is radiatively active. There are other clauses to the if statement below, but this is the one being called in my simulations:
if( conv_water_in_rad /= 0 ) then
allcld_ice(:ncol,:) = 0._r8 ! Grid-avg all cloud liquid
allcld_liq(:ncol,:) = 0._r8 ! Grid-avg all cloud ice
call conv_water_4rad(state, pbuf, allcld_liq, allcld_ice)
In cospsimulator_intr.F90, there is still a simplistic calculation of the cloud water mixing ratios using the physics state DDT. This approach seems to significantly underestimate the cloud water mixing ratio in partly cloudy layers, leading to the absence of clouds in the COSP output.
mr_lsliq(i,k)=state%q(i,k,ixcldliq) ! mr_lsliq, mixing_ratio_large_scale_cloud_liquid, state only includes stratiform (kg/kg)
mr_lsice(i,k)=state%q(i,k,ixcldice) ! mr_lsice - mixing_ratio_large_scale_cloud_ice, state only includes stratiform (kg/kg)
I was able to fix the errors that I was seeing in the diagnostic by calculating the cloud water mixing ratios analogously to cloud_diagnostics.F90. But I use the cloud water values differently than the rest of the COSP simulator so I did not modify the values used elsewhere by COSP. But I expect that the code I brought in can correct these errors if applied to the other cloud water mixing ratio fields. @brianpm has also noted that calling "conv_water_4rad" additional times makes additional outfld calls and may modify the pbuf in undesired ways. In my correction, I am able to exactly reproduce the liquid water and ice mixing ratios in cospsimulator_intr.F90 by calling "conv_water_4rad" in the COSP code, though it may not be an ideal simulation. Other comments from Brian are included below.
My additional lines of code (all in cosp_simulator_intr_run):
! Use the subroutines in cloud_diagnostics.F90:
use conv_water, only: conv_water_in_rad, conv_water_4rad
! Declare new variables to hold the correct cloud water mixing ratios.
real(r8) :: allcld_ice (pcols,pver) ! cloud ice (Convective?)
real(r8) :: allcld_liq (pcols,pver) ! cloud liquid (Convective?)
! Calculate the cloud water mixing ratios analogously to cloud_diagnostics.F90 ! Calculate cloud liquid water and ice consistently with the radiation scheme.
if( conv_water_in_rad /= 0 ) then
allcld_ice(:ncol,:) = 0._r8 ! Grid-avg all cloud liquid
allcld_liq(:ncol,:) = 0._r8 ! Grid-avg all cloud ice
call conv_water_4rad(state, pbuf, allcld_liq, allcld_ice)
else
allcld_liq(:ncol,top_lev:pver) = state%q(:ncol,top_lev:pver,ixcldliq) ! Grid-ave all cloud liquid
allcld_ice(:ncol,top_lev:pver) = state%q(:ncol,top_lev:pver,ixcldice) ! " ice
end if
The affected variables in the COSP interface (mr_ccliq, mr_ccice, mr_lsliq, mr_lsice) feed into the subsampling and optics code, which I am not very familiar with. The newer cloud water mixing ratios don't distinguish between convective and large scale fields so some reconciling might be needed.
Also pinging @dustinswales who may be able to advise on how to go about fixing the "subsample_and_optics" call in cospsimulator_intr.F90.
Comments from @brianpm :
It seems like the main thing is that the radiation interface calculates that cloud optical properties using the in-cloud ice and water paths that are modified by conv_water_4rad (from cloud_diagnostics_calc). These live in pbuf fields.
The COSP interface seems pretty complicated, but I guess Dustin at least understands it! I think it could be modified to use the same pbuf fields that the radiation is using. I think that's probably preferable to calling conv_water_4rad again because that routine has a bunch of outfld calls. I didn't look carefully enough, but there's also a possibility that it is modifying pbuf fields that have already been modified (i.e., it might be doing an iteration on its own result).
Details for reproducibility: CAM version: cam6_3_144
Cloud diagnostics: https://github.com/ESCOMP/CAM/blob/cam6_3_144/src/physics/cam/cloud_diagnostics.F90
COSP simulator interface: https://github.com/ESCOMP/CAM/blob/cam6_3_144/src/physics/cam/cospsimulator_intr.F90
What are the steps to reproduce the bug?
This bug seems to occur whenever the in-cloud cloud water/ice mixing ratios are calculated using "conv_water_4rad" or effectively whenever this condition is satisfied: conv_water_in_rad /= 0. Since the COSP outputs seem to be the only values affected COSP must also be on.
I am running in SCAM in order to use the diagnostic radiation tool, but the bug seems general enough that I expect this to apply broadly in CAM.
What CAM tag were you using?
cam6_3_144
What machine were you running CAM on?
CISL machine (e.g. cheyenne)
What compiler were you using?
Intel
Path to a case directory, if applicable
/glade/u/home/jonahshaw/Cases/CESM2/cesm2_3_alpha17b_rttovhdf/20240502_142523.FHIST.f19_f19_mg17.SCAMrttov_test
Will you be addressing this bug yourself?
No
Extra info
No response
@jshaw35 Thanks for tracking this down and opening up this issue!!! Just a brief comment. There has always been a difference in how SGS variability is handled in COSP and within the radiation (RRTMG) In COSP, the subsample_and_optics routine uses SCOPS to account for SGS variability. SCOPS can distinguish between convective and stratiform clouds, if provided. RRTMG uses McICA for SGS variability, but for only one cloud type. The LS+CONV clouds are combined and provided to RRTMG as a single cloud, which is sampled internally.
The solution presented here is to use the same cloud fields in COSP as are seen by RRTMG, which I think(?) means two things:
- What Jonah proposed: To use the cloud condensate in COSP that accounts for convective condensate (add call to conv_water_4rad() or pull these fields from pbuf) AND
- do not provide convective condensate to subsample_and_optics() (Pass cca=0 into scops here). We only want COSP to see this single cloud
Hi @jshaw35, @dustinswales, @brianpm.
As Brian M. pointed out, conv_water_4rad
is not designed to be called multiple times. In order to use the totg_liq
and totg_ice
outputs from conv_water_4rad
, the best thing to do will be to put those fields in the physics buffer. Currently the conv_water
module adds the fields SH_CLDLIQ1
and SH_CLDICE1
to the pbuf. Those fields are only accessed by COSP, and would not be needed if the totg_liq
and totg_ice
fields were used in COSP. As I was tracing where the current cloud fields used in COSP are coming from I noticed a bug in the current COSP code which is that the dp_cldliq
and dp_cldice
fields that are used for the deep contributions to mr_ccliq
and mr_ccice
are both being set to zero in zm_conv_intr.F90
.
Here's what I understand to be the proposed changes in cospsimulator_intr.F90
:
. use totg_liq
and totg_ice
from conv_water_4rad
(via pbuf) to set the variables mr_lsliq
and mr_lsice
.
. set mr_ccliq
and mr_ccice
to zero
. pass a zero array to the cca
dummy array of subsample_and_optics
Comments?
I currently have a PR (#1010) under review which adds a vertical limit that restricts COSP to operate on the same domain as the cloud parameterizations. This allows us to run COSP with higher top models. That work involved a substantial cleanup in cospsimulator_intr.F90
. I plan to add the fix discussed here to a branch off of the branch for that PR. Note also that there is a bug fix in the PR for the layer interface values of height and pressure passed to COSP.
Hi @brian-eaton Yes, the three proposed changes you listed are needed. Good job tracing down the mixing-ratio discrepancy between cospsimulator_intr.F90 and zm_conv_intr.F90. Given how sprawling the coupling to COSP is, I wonder if there are other "assumptions" that need to make their way into cospsimulator_intr.F90? (These are the types of things that keep me up at night!)
As for #1010, I don't have anything.
I noticed a bug in the current COSP code which is that the dp_cldliq and dp_cldice fields that are used for the deep contributions to mr_ccliq and mr_ccice are both being set to zero in zm_conv_intr.F90.
@brian-eaton It's possible this is not a bug, but rather an assumption as these variables are not easily derived from the ZM variables. ZM interacts with radiation through the pbuf variables ICWMRDP and DP_FRAC. The former is the in-cloud "water" mixing ratio, the latter is a ZM cloud area (which is a very crude approximation). To convert these ZM variables to grid mean dp_cldliq
and dp_cldice
, we'd need to partition ICWMRDP into liquid and ice species, and then use DP_FRAC to convert to a grid mean. While DP_FRAC is seen by radiation, it may not be appropriate for converting the in-cloud mixing ratios to grid mean mixing ratios. This approach could introduce more errors than the current approach of setting those two vars used by COSP to zero.
Hi @adamrher. I think it's a bug only in the sense that COSP is using these variables assuming that they contain the deep convection cloud water when in fact they contain nothing. This is probably old code left over from early COSP implementations. I'm guessing the treatments of cloud water in the conv_water
module is the best we can do, so using those total cloud water values in COSP makes sense. Do you agree?
I'm guessing the treatments of cloud water in the conv_water module is the best we can do, so using those total cloud water values in COSP makes sense. Do you agree?
I agree.
Hi @jshaw35 and @brianpm. I have implemented the changes discussed in this issue and would like to get feedback on whether things are looking reasonable before opening a PR. Please check out the cosp-cwat
branch from my fork: https://github.com/brian-eaton/CAM
. The cosp-cwat
branch is up to date with cam6_3_160, and is off of the cosp-vlim
branch which hasn't yet been merged to cam_development
. The cosp-vlim
branch contains an additional bug
fix to COSP (see PR #1010).
Hi @brian-eaton, I don't have much familiarity with CAM outside of the COSP code so I can't comment on everything. The changes in COSP look good to me though!