Skip to content

merge new clubb_mf into cam6_4_180 - #1576

Open
jtruesdal wants to merge 29 commits into
ESCOMP:cam_developmentfrom
jtruesdal:clubbdev
Open

merge new clubb_mf into cam6_4_180#1576
jtruesdal wants to merge 29 commits into
ESCOMP:cam_developmentfrom
jtruesdal:clubbdev

Conversation

@jtruesdal

@jtruesdal jtruesdal commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

This PR merges updated CLUBB+MF (clubb-mf) changes into CAM, extending the CLUBB interface to support the enhanced integrate_mf call, adding new EDMF diagnostics/outputs, and introducing additional namelist controls for CLUBB+MF behavior (radiation coupling, microphysics, TKE contribution, etc.).

Changes:

  • Expanded clubb_intr.F90 CLUBB+MF interface: new pbuf fields, history coords, diagnostic outputs, and enhanced MF plumbing.
  • Added new CLUBB+MF namelist entries + defaults, and wired them into build-namelist.

The majority of the code updates reside in clubb_mf.F90. In addition to the new science, clubb_mf is now agnostic to the direction of the vertical level, adjusting the looping and indexes as needed depending on the top down or bottom up nature of the input arrays. Additionally the number of vertical levels for the new mf arrays are consistent with their associated thermodynamic or momentum grid. There are order of operation differences between this update and Adam's original cam6_4_124 version of clubb_mf which cause roundoff precision differences from the base code. On top of these roundoff differences there are bug fixes which are answer changing.

This PR closes #1370

jtruesdal and others added 2 commits June 9, 2026 09:08
…rations on several variables with latest clubb interface and externals.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR merges updated CLUBB+MF (clubb-mf) changes into CAM, extending the CLUBB interface to support the enhanced integrate_mf call, adding new EDMF diagnostics/outputs, and introducing additional namelist controls for CLUBB+MF behavior (radiation coupling, microphysics, TKE contribution, etc.).

Changes:

  • Expanded clubb_intr.F90 CLUBB+MF interface: new pbuf fields, history coords, diagnostic outputs, and enhanced MF plumbing.
  • Added new CLUBB+MF namelist entries + defaults, and wired them into build-namelist.
  • Updated COSP namelist documentation text (but introduced encoding issues that need correction).

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 18 comments.

File Description
src/physics/cam/clubb_intr.F90 Adds/updates CLUBB+MF fields, diagnostics, and MF integration interface wiring.
bld/namelist_files/namelist_definition.xml Adds new CLUBB+MF namelist definitions and edits COSP localtime documentation.
bld/namelist_files/namelist_defaults_cam.xml Adds default values for the new CLUBB+MF namelist entries.
bld/build-namelist Adds add_default(...) plumbing for (most) new CLUBB+MF namelist variables.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment thread bld/namelist_files/namelist_definition.xml Outdated
Comment thread bld/namelist_files/namelist_definition.xml Outdated
Comment thread bld/namelist_files/namelist_definition.xml
Comment thread bld/namelist_files/namelist_definition.xml
Comment thread bld/namelist_files/namelist_definition.xml
Comment thread bld/namelist_files/namelist_defaults_cam.xml Outdated
Comment thread bld/build-namelist
Comment on lines +5201 to +5219
!jt check with Adam These are not bfb with nonclubbmf run
!jt check with Adam ! Values to use above top_lev, for variables that have not already been
!jt check with Adam ! set up there. These are mostly fill values that should not actually be
!jt check with Adam ! used in the run, but may end up in diagnostic output.
!jt check with Adam !$acc parallel loop gang vector collapse(2) default(present)
!jt check with Adam do k=1, top_lev-1
!jt check with Adam do i=1, ncol
!jt check with Adam upwp_pbuf(i,k) = 0._r8
!jt check with Adam vpwp_pbuf(i,k) = 0._r8
!jt check with Adam rcm(i,k) = 0._r8
!jt check with Adam wprcp(i,k) = 0._r8
!jt check with Adam cloud_frac(i,k) = 0._r8
!jt check with Adam rcm_in_layer(i,k) = 0._r8
!jt check with Adam zt_output(i,k) = 0._r8
!jt check with Adam zi_output(i,k) = 0._r8
!jt check with Adam khzm_pbuf(i,k) = 0._r8
!jt check with Adam qclvar(i,k) = 2._r8
!jt check with Adam end do
!jt check with Adam end do

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'm still looking into this section as one of these variables is causing numberical differences.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment on lines +5782 to +5795
mf_upa_flip(i,k,:clubb_mf_nup) = mf_upa(i,k_clubb,:clubb_mf_nup)
mf_upw_flip(i,k,:clubb_mf_nup) = mf_upw(i,k_clubb,:clubb_mf_nup)
mf_upmf_flip(i,k,:clubb_mf_nup) = mf_upmf(i,k_clubb,:clubb_mf_nup)
mf_upqt_flip(i,k,:clubb_mf_nup) = mf_upqt(i,k_clubb,:clubb_mf_nup)
mf_upthl_flip(i,k,:clubb_mf_nup) = mf_upthl(i,k_clubb,:clubb_mf_nup)
mf_upthv_flip(i,k,:clubb_mf_nup) = mf_upthv(i,k_clubb,:clubb_mf_nup)
mf_upth_flip(i,k,:clubb_mf_nup) = mf_upth(i,k_clubb,:clubb_mf_nup)
mf_upqc_flip(i,k,:clubb_mf_nup) = mf_upqc(i,k_clubb,:clubb_mf_nup)
mf_upent_flip(i,k,:clubb_mf_nup) = mf_upent(i,k_clubb,:clubb_mf_nup)
mf_updet_flip(i,k,:clubb_mf_nup) = mf_updet(i,k_clubb,:clubb_mf_nup)
mf_upbuoy_flip(i,k,:clubb_mf_nup) = mf_upbuoy(i,k_clubb,:clubb_mf_nup)
mf_dnw_flip(i,k,:clubb_mf_nup) = mf_dnw(i,k_clubb,:clubb_mf_nup)
mf_dnthl_flip(i,k,:clubb_mf_nup) = mf_dnthl(i,k_clubb,:clubb_mf_nup)
mf_dnqt_flip(i,k,:clubb_mf_nup) = mf_dnqt(i,k_clubb,:clubb_mf_nup)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Testing alternate solution to flip array.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Tested and removed these.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment thread src/physics/cam/clubb_intr.F90
Comment thread src/physics/cam/clubb_intr.F90
@@ -1,684 +1,3201 @@
module clubb_mf

! =============================================================================== !

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@adamrher You'll probably want to difference this code against your cam6_4_124 clubbmf merge to see my changes. The code is now top-down, bottom-up agnostic so the indexing and loops have all changed. I tried to put some commenting in about the generalization of the vertical coordinates but like the original its still pretty dense. Additionally the vertical dimensions for momentum and thermodynamic arrays are consistent with those grids. It would help if you could make sure the different arrays are dimensioned for the correct grid as well as checking some of the special if logic loops that are not executed by default to make sure the vertical indexing is OK. I've checked all loops that are executed by default and they are roundoff consistent (12-14 digits) consistent with the order of operation differences between this code and your cam6_4_124 clubbmf merge.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 14 comments.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment thread src/physics/cam/clubb_intr.F90 Outdated
@@ -4773,6 +5598,17 @@ subroutine clubb_tend_cam( state, ptend_all, pbuf, hdtime, &
end do
end do

rcm_macmic(:ncol,nzt_clubb*(macmic_it-1)+1:nzt_clubb*macmic_it) = rcm(:ncol,:nzt_clubb)
Comment thread src/physics/cam/clubb_intr.F90 Outdated
cldfrac_macmic(:ncol,pver*(macmic_it-1)+1:pver*macmic_it) = cld_pbuf(:ncol,:pver)
wpthlp_macmic(:ncol,pverp*(macmic_it-1)+1:pverp*macmic_it) = wpthlp_output(:ncol,:pverp)
wprtp_macmic(:ncol,pverp*(macmic_it-1)+1:pverp*macmic_it) = wprtp_output(:ncol,:pverp)
wpthvp_macmic(:ncol,nzm_clubb*(macmic_it-1)+1:nzm_clubb*macmic_it) = wpthvp_pbuf(:ncol,:nzm_clubb)
Comment thread bld/namelist_files/namelist_definition.xml
Comment thread bld/namelist_files/namelist_definition.xml
Comment thread bld/namelist_files/namelist_definition.xml
Comment thread bld/namelist_files/namelist_definition.xml
Comment thread src/physics/cam/clubb_intr.F90 Outdated
@cacraigucar
cacraigucar marked this pull request as ready for review June 23, 2026 16:47

@adamrher adamrher left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hi John. I've completed my first round of the code review, getting about about half-way through clubb_intr. The code merge removed a lot of stuff that Gunther cleaned up in cam6_4_144, and I tried to catch all those instances. I also found about 8 or so *_macmic variables that I'd like to remove from the pbuf.

Comment thread bld/namelist_files/namelist_defaults_cam.xml Outdated
Comment thread bld/namelist_files/namelist_defaults_cam.xml Outdated
Comment thread bld/namelist_files/namelist_definition.xml Outdated
Comment thread bld/namelist_files/namelist_defaults_cam.xml Outdated
Comment thread bld/namelist_files/namelist_definition.xml Outdated
Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment thread src/physics/cam/clubb_intr.F90
Comment thread src/physics/cam/clubb_intr.F90 Outdated
thlm_zm(:,:) = 0._r8
th_zm(:,:) = 0._r8
qv_zm(:,:) = 0._r8
qc_zm(:,:) = 0._r8

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

are these zero array initializations unnecessary?

Comment thread src/physics/cam/clubb_intr.F90 Outdated
Comment thread src/physics/cam/clubb_intr.F90 Outdated

@adamrher adamrher left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Hi John. This my part 2 review. It finishes the clubb_intr.F90 module. There will be a part 3 for clubb_mf.F90, but most of the heavy lifting is contained in a PR I've issued to your branch today.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
do i = 1, ncol
! Precip accumulates downward across the interfaces
mf_precc(i,k+1) = mf_precc(i,k) - rho_zt(i,k)*dz_g(i,k)*mf_sqt(i,k)
end do
end do

!--------------------------------------- END integrate_mf call ---------------------------------------

@adamrher adamrher Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This 'END integrate_mf call' comment should be moved up to the end do immediately after the integrate_mf call.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

@@ -3565,6 +4112,7 @@ subroutine clubb_tend_cam( state, ptend_all, pbuf, hdtime, &
rho_ds_zt = rho_ds_zt(:,nzt_clubb:1:-1)
invrs_rho_ds_zt = invrs_rho_ds_zt(:,nzt_clubb:1:-1)
thv_ds_zt = thv_ds_zt(:,nzt_clubb:1:-1)
khzt = khzt(:,nzt_clubb:1:-1)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I guess this is technically a bug fix, but note this variable is not used anywhere in the model.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I fixed it just for consistency sake. As it is an output parameter is will be on the correct levels if we decide to use it later.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I'll leave it in case khzt is used in the future, it will be on the correct levels.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
clubb_params(i,ic_K) * Lscale(i,k) * sqrt(0.5_r8 * s_aww(i,k))
end do
end do
else
!$acc parallel loop gang vector collapse(2) default(present)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

indent do loop

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done. Indented to 2 spaces like rest of routine.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
mf_qc(:ncol,:nzm_clubb) = mf_qc_nadv(:ncol,:nzm_clubb)/REAL(nadv)
mf_rcm(:ncol,:nzm_clubb) = mf_rcm_nadv(:ncol,:nzm_clubb)/REAL(nadv)
mf_cloudfrac(:ncol,:nzm_clubb) = mf_cloudfrac_nadv(:ncol,:nzm_clubb)/REAL(nadv)
prec_sh(:ncol) = mf_precc_nadv(:ncol)/REAL(nadv)

@adamrher adamrher Jul 30, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is a merge bug. This prec_sh pbuf variable needs to be defined before the energy fixer (line ~4696). This entire code block could probably be brought up to just before the energy fixer starts (line ~4649) with an appropriate comment ("process accumulated clubb-mf arrays"). The energy fixer needs prec_sh.

also, to conform with the cam6_4_166 clubb PR, can we append the prec_sh and snow_sh variables with "_pbuf"?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
mf_cloudfrac_zt = zm2zt_api( nzm_clubb, nzt_clubb, ncol, gr, mf_cloudfrac)
!mf_qc_zt(1:ncol,:) = zm2zt_api( pverp+1-top_lev, ncol, gr, mf_qc(1:ncol,:))
!mf_cloudfrac_zt(1:ncol,:) = zm2zt_api( pverp+1-top_lev, ncol, gr, mf_cloudfrac(1:ncol,:))

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

A few issues with these two variables (1) bring the initializations into the do_clubb_mf block (2) delete the commented out code, (3) these variables are supposed to set mf_qc_output & mf_cloudfrac_output, but those output arrays are not being set to anything. We need to set those output arrays since they are used to set cloud radiative pbuf vars down below (line ~5300).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It turns out none of the output variables declared in this block (line ~2414) are being set to anything:

    real(r8), dimension(pcols,pver)      :: mf_thlforcup_output, mf_qtforcup_output,  & ! thermodynamic grid
                                            mf_thlforcdn_output, mf_qtforcdn_output,  & ! thermodynamic grid
                                            mf_thlforc_output,   mf_qtforc_output,    & ! thermodynamic grid
                                            mf_ent_output,                            & ! thermodynamic grid
                                            mf_sqtup_output,     mf_sqtdn_output,     & ! thermodynamic grid
                                            mf_qc_output,        mf_cloudfrac_output    ! thermodynamic grid

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I've set all of these missing outputs, used array syntax instead of the do loops and got rid of the flip variables.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
!$acc parallel loop gang vector default(present)
do i=1, pcols
zi_output(i,1) = 0._r8
end do

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I don't know what this code block is, and it's possible I added it, but it should be deleted.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Removed.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
end do

end if
end do

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think this was pulled out in the cam6_4_166 PR. the edsclr array is size nzt_clubb, and so no 1:top_lev exists. edsclr is not even used after this block.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I removed this.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Removed this block.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
! "cloud_frac") and CLUBB+MF cloud fraction ("shalcu") compute the convective cloud
! fraction. This follows the formulation found in macrophysics code. Assumes that convective
! cloud is all nonstratiform cloud from CLUBB or CLUBB+MF plus the deep convective cloud fraction
concld_pbuf(i,k) = min(cloud_frac(i,k)-alst_pbuf(i,k)+deepcu_pbuf(i,k)+shalcu_pbuf(i,k),0.80_r8)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

can you adapt this to follow how this is done in the deepcu block above? Specifically, comment out the current concld_pbuf line and add a new line concld_pbuf(i,k) = min(deepcu_pbuf(i,k)+shalcu_pbuf(i,k),0.80_r8), with a NOTE explaining what we're doing.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Done.

Comment thread src/physics/cam/clubb_intr.F90 Outdated
mf_thlforc_output, mf_qtforc_output, & ! thermodynamic grid
mf_ent_output, & ! thermodynamic grid
mf_sqtup_output, mf_sqtdn_output, & ! thermodynamic grid
mf_qc_output, mf_cloudfrac_output ! thermodynamic grid

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

It looks like these are still in the same place?

adamrher and others added 5 commits July 30, 2026 18:45
clean up function arguments in integrate_mf + bug fixes.  John will improve the initialization for mcape/mf_cape and correct spelling errors identified by copilot.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants