Skip to content

cam6_4_085: Phase 1 of rk_stratiform CCPPization; CCPPize cldfrc #1271

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Apr 14, 2025

Conversation

jimmielin
Copy link
Member

@jimmielin jimmielin commented Mar 11, 2025

Purpose of changes (include the issue number and title text for each relevant GitHub issue):

Companion PR in atmospheric_physics: ESCOMP/atmospheric_physics#219

Changes are expected to be B4B for CAM regression tests
Roundoff changes to CAM4 diagnostics

Describe any changes made to build system: N/A

Describe any changes made to the namelist:

  • build-namelist updated to add rk_stratiform_tend snapshot point

List any changes to the defaults for the boundary datasets: N/A

Describe any substantial timing or memory changes: N/A

Code reviewed by: TBD

List all files eliminated:

D       src/physics/cam/cldwat.F90
D       src/physics/cam/pkg_cldoptics.F90
  - moved to atmospheric_physics: prognostic_cloud_water CCPPized scheme
  - moved to atmospheric_physics: cloud_optical_properties to-be-ccppized library; dechunkized

List all files added and what they do: N/A

List all existing files that have been modified, and describe the changes:

M       .gitmodules
M       src/atmos_phys
  - new atmos_phys external to include CCPPized schemes

M       bld/configure
  - include atmos_phys/schemes/rasch_kristjansson

M       bld/build-namelist
M       bld/namelist_files/namelist_definition.xml
M       src/physics/cam/physpkg.F90
  - add rk_stratiform_tend snapshot point

R068    src/physics/cam/rk_stratiform.F90       src/physics/cam/rk_stratiform_cam.F90
M       src/control/runtime_opts.F90
M       src/physics/cam/const_init.F90
  - rename CAM interface to rk_stratiform_cam
  - CCPPize most logic and moved into atmos_phys

M       src/physics/cam/cloud_diagnostics.F90
  - changes to support move of pkg_cldoptics to atmos_phys

M       src/physics/cam/cloud_fraction.F90
  - CCPPized cldfrc and moved to atmos_phys: compute_cloud_fraction
  - shallow and deep convective cloud cover logic separated into CCPPized scheme in atmos_phys: convective_cloud_cover

M       src/physics/cam/macrop_driver.F90
  - changes to support CCPPization of cldfrc

M       src/physics/cam/pkg_cld_sediment.F90
  - CCPPized logic and moved into atmos_phys: cloud_particle_sedimendation

M       src/physics/cam7/cam_snapshot.F90
M       src/physics/cam/cam_snapshot.F90
  - fix #1274 vertical dimension of tphysbc_cmfmc

implement cloud_optical_properties via to_be_ccppized
implement cloud_particle_sedimentation ccppization
rename to cam interface rk_stratiform_cam
move intermediate logic to rk_stratiform_* ccpp schemes
implement compute_cloud_fraction
add rk_stratiform_tend snapshot point
@jimmielin
Copy link
Member Author

jimmielin commented Mar 12, 2025

There is an answer change to some (but not all) of the QPC4 regression tests introduced by reformulating the stratiform condensate repartitioning code.

Currently:

 ! Perform repartitioning of stratiform condensate. 
 ! Corresponding heating tendency will be added later. 
  
 lq(:)        = .FALSE. 
 lq(ixcldice) = .true. 
 lq(ixcldliq) = .true. 
 call physics_ptend_init( ptend_loc, state1%psetcols, 'cldwat-repartition', lq=lq ) 
  
 totcw(:ncol,:pver)     = state1%q(:ncol,:pver,ixcldice) + state1%q(:ncol,:pver,ixcldliq) 
 repartht(:ncol,:pver)  = state1%q(:ncol,:pver,ixcldice) 
 ptend_loc%q(:ncol,:pver,ixcldice) = rdtime * ( totcw(:ncol,:pver)*fice(:ncol,:pver)          - state1%q(:ncol,:pver,ixcldice) ) 
 ptend_loc%q(:ncol,:pver,ixcldliq) = rdtime * ( totcw(:ncol,:pver)*(1.0_r8-fice(:ncol,:pver)) - state1%q(:ncol,:pver,ixcldliq) ) 
  
 call outfld( 'REPARTICE', ptend_loc%q(:,:,ixcldice), pcols, lchnk ) 
 call outfld( 'REPARTLIQ', ptend_loc%q(:,:,ixcldliq), pcols, lchnk ) 
  
 call physics_ptend_sum( ptend_loc, ptend_all, ncol ) 
 call physics_update( state1, ptend_loc, dtime ) 
  
 ! Determine repartition heating from change in cloud ice. 
  
 repartht(:ncol,:pver) = (latice/dtime) * ( state1%q(:ncol,:pver,ixcldice) - repartht(:ncol,:pver) ) 
  

This uses repartht (repartitioning heat [J kg-1 s-1]) as a temporary variable to store the pre-repartitioning q(cldice) (which is in [kg kg-1]), then after physics_update, repartht is computed to its final form.

As this is problematic to implement in a CCPPized scheme, the formulation is updated to the following in rk_stratiform_condensate_repartitioning_run:

    totcw(:ncol,:) = cldice(:ncol,:) + cldliq(:ncol,:)
    tend_cldice(:ncol,:) = 1.0_kind_phys / dtime * ( totcw(:ncol,:)*fice(:ncol,:)                 - cldice(:ncol,:) )
    tend_cldliq(:ncol,:) = 1.0_kind_phys / dtime * ( totcw(:ncol,:)*(1.0_kind_phys-fice(:ncol,:)) - cldliq(:ncol,:) )

    repartht(:ncol,:pver) = latice * tend_cldice(:ncol,:pver)

This leads to ~1e-17 differences in the final heating rate (ptend%s) in every time step. After about ~10 timesteps due to chaos other quantities will start to diverge due to the noise introduced in the heating rate over timesteps. Some, but not all of the QPC4 tests will capture this change and thus answer changes are introduced.

It can be verified that this is responsible for all the answer changes by reintroducing the original formulation of repartht after call rk_stratiform_condensate_repartitioning_run in rk_stratiform_cam.F90:

!    call rk_stratiform_condensate_repartioning_run( & ...

   call outfld( 'REPARTICE', ptend_loc%q(:,:,ixcldice), pcols, lchnk )
   call outfld( 'REPARTLIQ', ptend_loc%q(:,:,ixcldliq), pcols, lchnk )

   ! add change to restore original formulation:
   repartht(:ncol,:pver)  = state1%q(:ncol,:pver,ixcldice)
   ! / change

   call physics_ptend_sum( ptend_loc, ptend_all, ncol )
   call physics_update( state1, ptend_loc, dtime )

   ! add change to restore original formulation:
   repartht(:ncol,:pver) = (latice/dtime) * ( state1%q(:ncol,:pver,ixcldice) - repartht(:ncol,:pver) )
   ! / change

This will result in bit-for-bit in all history files and diagnostics and passing all regression tests, showing that it was the only cause of the answer changes.

Note: even if repartht temporary is changed to (latice/dtime) * state1%q(:ncol,:pver,ixcldice) to "keep the right units", then changing the post-repartitioning calculation to repartht(:ncol,:pver) = (latice/dtime) * state1%q(:ncol,:pver,ixcldice) - repartht(:ncol,:pver) will introduce answer changes.

Thus if there is no way around this I would just recommend changing it for a cleaner code.

@jimmielin jimmielin requested a review from nusbaume March 26, 2025 17:54
Copy link
Collaborator

@nusbaume nusbaume left a comment

Choose a reason for hiding this comment

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

Looks good! Just had some (hopefully) minor change requests.


! Convert rain and snow fluxes at the surface from [kg/m2/s] to [m/s]
! Compute total precipitation flux at the surface in [m/s]
wsedl(:ncol,:pver) = pvliq(:ncol,:pver)/gravit/(state1%pmid(:ncol,:pver)/(287.15_r8*state1%t(:ncol,:pver)))
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am like 95% sure that this 287 number is the gas constant for dry air. I might vote to either just use the actual physical constant, or if that changes answers too much to just create a new parameter here labeling it as the gas constant but keeping the actual value the same.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks! I think you're right that this should be rair but I think the numbers in shr_const_rdair work out to something closer to ~287.04. In the interest of keeping bit-for-bit for this pbuf field I will just make it a parameter with name rdair.

The same 287.15 number is used in a couple other places in the CAM code, as well as RK to calculate the ice/liquid water content

 1316:          iwc(i,k)   = state1%q(i,k,ixcldice)*state1%pmid(i,k)/(287.15_r8*state1%t(i,k))
 1317:          lwc(i,k)   = state1%q(i,k,ixcldliq)*state1%pmid(i,k)/(287.15_r8*state1%t(i,k))
src/physics/cam/cloud_diagnostics.F90:
  405               icimr(i,k)     = min( allcld_ice(i,k) / max(0.0001_r8,cld(i,k)),0.005_r8 )
  406               icwmr(i,k)     = min( allcld_liq(i,k) / max(0.0001_r8,cld(i,k)),0.005_r8 )
  407:              iwc(i,k)       = allcld_ice(i,k) * state%pmid(i,k) / (287.15_r8*state%t(i,k))
  408:              lwc(i,k)       = allcld_liq(i,k) * state%pmid(i,k) / (287.15_r8*state%t(i,k))
  409               ! Calculate total cloud water paths in each layer
  410               iciwp(i,k)     = icimr(i,k) * state%pdel(i,k) / gravit

src/physics/cam/micro_pumas_cam.F90:
 2642           icwmrst(i,k)   = min( state_loc%q(i,k,ixcldliq) / max(mincld,liqcldf(i,k)),0.005_r8 )
 2643           icinc(i,k)     = state_loc%q(i,k,ixnumice) / max(mincld,icecldf(i,k)) * &
 2644:               state_loc%pmid(i,k) / (287.15_r8*state_loc%t(i,k))
 2645           icwnc(i,k)     = state_loc%q(i,k,ixnumliq) / max(mincld,liqcldf(i,k)) * &
 2646:               state_loc%pmid(i,k) / (287.15_r8*state_loc%t(i,k))
 2647           ! Calculate micro_pumas_cam cloud water paths in each layer
 2648           ! Note: uses stratiform cloud fraction!

So maybe they should all be updated in one go. I'm happy to make an issue for this if we'd like to update this down the line? Thanks!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Making an issue to tackle these magic numbers later seems sensible to me. Thanks @jimmielin!

Copy link
Collaborator

Choose a reason for hiding this comment

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

@jimmielin - Have you opened an issue on this. If so, could you please post the link here?

Copy link
Member Author

Choose a reason for hiding this comment

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

Sorry forgot, here it is: #1292 Thanks!

@jimmielin jimmielin requested a review from nusbaume March 31, 2025 19:23
Copy link
Collaborator

@nusbaume nusbaume left a comment

Choose a reason for hiding this comment

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

Everything looks great to me now. Thanks @jimmielin!

Copy link
Collaborator

@cacraigucar cacraigucar left a comment

Choose a reason for hiding this comment

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

Accidentally sent my single request outside the review

@jimmielin jimmielin requested a review from cacraigucar April 10, 2025 23:09
@cacraigucar cacraigucar changed the title Phase 1 of rk_stratiform CCPPization; CCPPize cldfrc cam6_4_085: Phase 1 of rk_stratiform CCPPization; CCPPize cldfrc Apr 11, 2025
jimmielin added a commit to ESCOMP/atmospheric_physics that referenced this pull request Apr 11, 2025
#219)

Originator(s): @jimmielin

Description (include issue title and the keyword ['closes', 'fixes',
'resolves'] and issue number):
- Partial CCPPization work of rk_stratiform (CAM4 microphysics and
macrophysics) - #190, including:
- Cloud sedimentation `cloud_particle_sedimentation` (from
`src/physics/cam/pkg_cld_sediment.F90`)
- Prognostic cloud water `prognostic_cloud_water` (`pcond` from
`src/physics/cam/cldwat.F90`)
- Most interstitial code in `rk_stratiform_tend` moved to
`rk_stratiform_*` interstitial schemes
- CCPPization of `compute_cloud_fraction` (`cldfrc` in
`src/physics/cam/cloud_fraction.F90`); separating out `shallowcu` and
`deepcu` and `concld` computation to `convective_cloud_cover` CCPPized
scheme. This is used in CAM4 and CAM5
- Dechunkize and move to `to_be_ccppized/cloud_optical_properties.F90`
several cloud optical property functions to
`src/physics/cam/pkg_cldoptics.F90`: this is used in several cloud
diagnostics in CAM.
- Fixes #225 

This code is not fully ready for use in SIMA in the current state. This
is a first stage cleanup to move as much of rk_stratiform_tend code to
atmospheric_physics as possible, before completing CCPPization. Thus the
following changes are not in the scope of this PR (although reasonable
effort has been made to complete these as much as possible):
* Completing metadata for use in CAM-SIMA
* Finalize standard names
* Create diagnostic schemes that correspond to existing diagnostics
provided in CAM4
* Create test cases for FPHYStest with rasch_kristjansson SDF

Companion PR in ESCOMP/CAM: ESCOMP/CAM#1271

List all namelist files that were added or changed:
```
A       schemes/cloud_fraction/compute_cloud_fraction_namelist.xml
A       schemes/cloud_fraction/convective_cloud_cover_namelist.xml
A       schemes/rasch_kristjansson/cloud_particle_sedimentation_namelist.xml
A       schemes/rasch_kristjansson/prognostic_cloud_water_namelist.xml
  - CCPPize cldfrc; cldwat; rk_stratiform_tend;

M       schemes/zhang_mcfarlane/zm_conv_options_namelist.xml
  - Remove cam6 phys_suite namelist defaults from SIMA

```

List all files eliminated and why: N/A

List all files added and what they do:
```
A       schemes/cloud_fraction/compute_cloud_fraction.F90
A       schemes/cloud_fraction/compute_cloud_fraction.meta
A       schemes/cloud_fraction/convective_cloud_cover.F90
A       schemes/cloud_fraction/convective_cloud_cover.meta
 - CCPPize cldfrc

A       schemes/rasch_kristjansson/cloud_particle_sedimentation.F90
A       schemes/rasch_kristjansson/cloud_particle_sedimentation.meta
 - CCPPize former `pkg_cld_sediment`

A       schemes/rasch_kristjansson/prognostic_cloud_water.F90
A       schemes/rasch_kristjansson/prognostic_cloud_water.meta
 - CCPPize former `cldwat`

A       schemes/rasch_kristjansson/rk_stratiform.F90
A       schemes/rasch_kristjansson/rk_stratiform.meta
 - Move most interstitial code in rk_stratiform_tend to individual CCPPized schemes

A       test/test_suites/suite_rasch_kristjansson.xml
 - Draft rk_stratiform_tend SDF

A       to_be_ccppized/cloud_optical_properties.F90
 - Dechunkized and moved from `pkg_cldoptics.F90`
```

List all existing files that have been modified, and describe the
changes:
(Helpful git command: `git diff --name-status
development...<your_branch_name>`)
```
M       schemes/zhang_mcfarlane/zm_conv_options_namelist.xml
  - Remove cam6 phys_suite namelist defaults from SIMA

M       schemes/cloud_fraction/set_cloud_fraction_top.F90
M       schemes/dry_adiabatic_adjust/dadadj_namelist.xml
M       schemes/hack_shallow/convect_shallow_sum_to_deep.F90
M       schemes/hack_shallow/hack_convect_shallow.F90
M       schemes/hack_shallow/set_general_conv_fluxes_to_shallow.F90
M       schemes/hack_shallow/set_shallow_conv_fluxes_to_general.F90
  - Remove license headers in favor of LICENSE file in repo
```

List all automated tests that failed, as well as an explanation for why
they weren't fixed: N/A

Is this an answer-changing PR? If so, is it a new physics package,
algorithm change, tuning change, etc?

B4B for non-CAM4 regression tests and most CAM4 tests.

If all CAM4 diagnostics are enabled, there are two history fields
(`HPROGCLD` and `HREPART`) that have roundoff level differences in the
order of 1e-17 ~ 1e-16 due to rearranging of terms to compute
diagnostics.

The change in heat flux computation and the subsequent roundoff
difference will lead to some CAM4 tests to fail due to chaos. See
detailed analysis in
ESCOMP/CAM#1271 (comment)

Not fully complete for use in SIMA in current state

If yes to the above question, describe how this code was validated with
the new/modified features:

Validation is made as part of ESCOMP/CAM PR -
ESCOMP/CAM#1271

---------

Co-authored-by: Jesse Nusbaumer <nusbaume@ucar.edu>
@jimmielin jimmielin merged commit ab9c0e6 into ESCOMP:cam_development Apr 14, 2025
2 checks passed
gold2718 pushed a commit to gold2718/CAM that referenced this pull request Apr 14, 2025
Merge pull request ESCOMP#1271 from jimmielin/hplin/rk_stratiform

cam6_4_085: Phase 1 of rk_stratiform CCPPization; CCPPize cldfrc

ESCOMP commit: ab9c0e6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Tag
Development

Successfully merging this pull request may close these issues.

3 participants