diff --git a/.gitmodules b/.gitmodules index b940db1dfe..a93aba501a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -44,7 +44,7 @@ path = src/dynamics/fv3 url = https://github.com/ESCOMP/CAM_FV3_interface.git fxrequired = AlwaysRequired - fxtag = fv3int_053124 + fxtag = fv3int_061924 fxDONOTUSEurl = https://github.com/ESCOMP/CAM_FV3_interface.git [submodule "geoschem"] diff --git a/doc/ChangeLog b/doc/ChangeLog index 320ee73134..da9cb012c1 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,146 @@ =============================================================== +Tag name: cam6_4_006 +Originator(s): pel, eaton +Date: 3 July 2024 +One-line Summary: fix clubb interface bug (dry/moist mixing ratio conversion) +Github PR URL: https://github.com/ESCOMP/CAM/pull/1054 + +Purpose of changes (include the issue number and title text for each relevant GitHub issue): + - fix issue described in https://github.com/ESCOMP/CAM/issues/1053 + . refactor set_wet_to_dry and set_dry_to_wet to require specifying which + constituent type the mixing ratio conversion is applied to + +Describe any changes made to build system: N/A + +Describe any changes made to the namelist: N/A + +List any changes to the defaults for the boundary datasets: N/A + +Describe any substantial timing or memory changes: N/A + +Code reviewed by: nusbaume + +List all files eliminated: N/A + +List all files added and what they do: N/A + +List all existing files that have been modified, and describe the changes: + +.gitmodules +- update fv3 from fv3int_053124 to fv3int_061924 + +src/physics/cam/clubb_intr.F90 +- add convert_cnst_type='wet' to arg list for set_wet_to_dry + +src/physics/cam/physics_types.F90 +- refactor set_wet_to_dry and set_dry_to_wet to require specifying which + constituent mixing ratios are being converted. + +src/dynamics/fv3/dp_coupling.F90 +src/dynamics/fv/dp_coupling.F90 +- add convert_cnst_type='dry' to arg list for set_wet_to_dry + +src/physics/cam/gw_drag.F90 +src/physics/cam/physpkg.F90 +src/physics/carma/cam/carma_intr.F90 +src/physics/simple/physpkg.F90 +- add convert_cnst_type='dry' to arg list for set_dry_to_wet + +src/physics/cam/vertical_diffusion.F90 +- add convert_cnst_type='dry' to arg list for set_dry_to_wet + and set_wet_to_dry + +src/physics/carma/models/cirrus/carma_cloudfraction.F90 +src/physics/carma/models/cirrus_dust/carma_cloudfraction.F90 +- remove unused association of set_dry_to_wet and set_wet_to_dry + +If there were any failures reported from running test_driver.sh on any test +platform, and checkin with these failures has been OK'd by the gatekeeper, +then copy the lines from the td.*.status files for the failed tests to the +appropriate machine below. All failed tests must be justified. + +derecho/intel/aux_cam: + +ERP_Ln9.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq9s (Overall: FAIL) +SMS_D_Ln9_P1280x1.ne0ARCTICne30x4_ne0ARCTICne30x4_mt12.FHIST.derecho_intel.cam-outfrq9s (Overall: PEND) +SMS_D_Ln9_P1280x1.ne0CONUSne30x8_ne0CONUSne30x8_mt12.FCHIST.derecho_intel.cam-outfrq9s (Overall: PEND) +SMS_D_Ln9.T42_T42.FSCAM.derecho_intel.cam-outfrq9s (Overall: FAIL) +- pre-existing failures + +ERC_D_Ln9.f19_f19_mg17.QPC6.derecho_intel.cam-outfrq3s_cosp (Overall: DIFF) +ERC_D_Ln9_P144x1.ne16pg3_ne16pg3_mg17.QPC6HIST.derecho_intel.cam-outfrq3s_ttrac_usecase (Overall: DIFF) +ERP_D_Ln9.f19_f19_mg17.QPC6.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERP_D_Ln9.ne30pg3_ne30pg3_mg17.FLTHIST.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERP_D_Ln9.ne30pg3_ne30pg3_mg17.FLTHIST.derecho_intel.cam-outfrq9s_rrtmgp (Overall: DIFF) +ERP_D_Ln9_P64x2.f09_f09_mg17.QSC6.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERP_Ld3.f09_f09_mg17.FWHIST.derecho_intel.cam-reduced_hist1d (Overall: DIFF) +ERP_Ln9.C96_C96_mg17.F2000climo.derecho_intel.cam-outfrq9s_mg3 (Overall: DIFF) +ERP_Ln9.f09_f09_mg17.F1850.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERP_Ln9.f09_f09_mg17.F2000climo.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERP_Ln9.f09_f09_mg17.F2010climo.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERP_Ln9.f09_f09_mg17.FHIST_BDRD.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERP_Ln9.f19_f19_mg17.FWsc1850.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERP_Ln9.ne30pg3_ne30pg3_mg17.FCnudged.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERP_Ln9.ne30pg3_ne30pg3_mg17.FW2000climo.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERP_Ln9_P24x3.f45_f45_mg37.QPWmaC6.derecho_intel.cam-outfrq9s_mee_fluxes (Overall: DIFF) +ERS_Ld3.f10_f10_mg37.F1850.derecho_intel.cam-outfrq1d_14dec_ghg_cam7 (Overall: DIFF) +ERS_Ln9.f09_f09_mg17.FX2000.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERS_Ln9.f19_f19_mg17.FXSD.derecho_intel.cam-outfrq9s (Overall: DIFF) +ERS_Ln9_P288x1.mpasa120_mpasa120.F2000climo.derecho_intel.cam-outfrq9s_mpasa120 (Overall: DIFF) +ERS_Ln9_P36x1.mpasa480_mpasa480.F2000climo.derecho_intel.cam-outfrq9s_mpasa480 (Overall: DIFF) +SMS_D_Ln9.f09_f09_mg17.FCts2nudged.derecho_intel.cam-outfrq9s_leapday (Overall: DIFF) +SMS_D_Ln9.f09_f09_mg17.FCvbsxHIST.derecho_intel.cam-outfrq9s (Overall: DIFF) +SMS_D_Ln9.f09_f09_mg17.FSD.derecho_intel.cam-outfrq9s (Overall: DIFF) +SMS_D_Ln9.f19_f19_mg17.FWma2000climo.derecho_intel.cam-outfrq9s (Overall: DIFF) +SMS_D_Ln9.f19_f19_mg17.FWma2000climo.derecho_intel.cam-outfrq9s_waccm_ma_mam4 (Overall: DIFF) +SMS_D_Ln9.f19_f19_mg17.FXHIST.derecho_intel.cam-outfrq9s_amie (Overall: DIFF) +SMS_D_Ln9.f19_f19_mg17.QPC2000climo.derecho_intel.cam-outfrq3s_usecase (Overall: DIFF) +SMS_D_Ln9.ne16pg3_ne16pg3_mg17.FX2000.derecho_intel.cam-outfrq9s (Overall: DIFF) +SMS_D_Ln9.ne30pg3_ne30pg3_mg17.FMTHIST.derecho_intel.cam-outfrq9s (Overall: DIFF) +SMS_D_Ln9_P1280x1.ne30pg3_ne30pg3_mg17.FCLTHIST.derecho_intel.cam-outfrq9s (Overall: DIFF) +SMS_Ld1.f09_f09_mg17.FCHIST_GC.derecho_intel.cam-outfrq1d (Overall: DIFF) +SMS_Ld1.f09_f09_mg17.FW2000climo.derecho_intel.cam-outfrq1d (Overall: DIFF) +SMS_Ld1.ne30pg3_ne30pg3_mg17.FC2010climo.derecho_intel.cam-outfrq1d (Overall: DIFF) +SMS_Lh12.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq3h (Overall: DIFF) +SMS_Lm13.f10_f10_mg37.F2000climo.derecho_intel.cam-outfrq1m (Overall: DIFF) +SMS_Ln9.f09_f09_mg17.F2010climo.derecho_intel.cam-nudging (Overall: DIFF) +SMS_Ln9.f09_f09_mg17.FW1850.derecho_intel.cam-reduced_hist3s (Overall: DIFF) +SMS_Ln9.f19_f19.F2000climo.derecho_intel.cam-silhs (Overall: DIFF) +SMS_Ln9.f19_f19_mg17.FHIST.derecho_intel.cam-outfrq9s_nochem (Overall: DIFF) +SMS_Ln9.ne30pg3_ne30pg3_mg17.FW2000climo.derecho_intel.cam-outfrq9s_rrtmgp (Overall: DIFF) +- expected baseline differences for cam6/cam7 physics + +izumi/nag/aux_cam: + +DAE.f45_f45_mg37.FHS94.izumi_nag.cam-dae (Overall: FAIL) +- pre-existing failure + +ERC_D_Ln9.f10_f10_mg37.QPC6.izumi_nag.cam-outfrq3s_am (Overall: DIFF) +ERC_D_Ln9.f10_f10_mg37.QPC6.izumi_nag.cam-outfrq3s_cospsathist (Overall: DIFF) +ERC_D_Ln9.f10_f10_mg37.QPC6.izumi_nag.cam-outfrq3s (Overall: DIFF) +ERC_D_Ln9.f10_f10_mg37.QPWmaC6.izumi_nag.cam-outfrq3s (Overall: DIFF) +ERI_D_Ln18.f19_f19_mg17.QPC6.izumi_nag.cam-ghgrmp_e8 (Overall: DIFF) +ERP_Ln9.ne5pg3_ne5pg3_mg37.QPC6.izumi_nag.cam-outfrq9s_clubbmf (Overall: DIFF) +SMS_D_Ln9.f10_f10_mg37.QPC6.izumi_nag.cam-outfrq3s_ba (Overall: DIFF) +SMS_P48x1_D_Ln3.f09_f09_mg17.QPC6HIST.izumi_nag.cam-outfrq3s_co2cycle_usecase (Overall: DIFF) +- expected baseline differences for cam6 physics + +izumi/gnu/aux_cam: + +ERP_D_Ln9.C48_C48_mg17.QPC6.izumi_gnu.cam-outfrq9s (Overall: DIFF) +ERP_D_Ln9.ne3pg3_ne3pg3_mg37.QPC6.izumi_gnu.cam-outfrq9s_rrtmgp (Overall: DIFF) +- expected baseline differences for cam6 physics + +CAM tag used for the baseline comparison tests if different than previous +tag: + +Summarize any changes to answers: BFB except all tests using CLUBB (i.e., + cam6 and cam7 physics) will have baseline comparison failures. + +=============================================================== +=============================================================== + Tag name: cam6_4_005 Originator(s): eaton Date: 1 July 2024 diff --git a/src/dynamics/fv/dp_coupling.F90 b/src/dynamics/fv/dp_coupling.F90 index 64b2e7b9c8..fc02821471 100644 --- a/src/dynamics/fv/dp_coupling.F90 +++ b/src/dynamics/fv/dp_coupling.F90 @@ -576,7 +576,7 @@ subroutine d_p_coupling(grid, phys_state, phys_tend, pbuf2d, dyn_out) ! (note: cam_thermo_dry_air_update assumes dry unless optional conversion factor provided) ! call set_state_pdry(phys_state(lchnk)) ! First get dry pressure to use for this timestep - call set_wet_to_dry(phys_state(lchnk)) ! Dynamics had moist, physics wants dry + call set_wet_to_dry(phys_state(lchnk), convert_cnst_type='dry') ! Dynamics had moist, physics wants dry if (dry_air_species_num>0) then !------------------------------------------------------------ ! Apply limiters to mixing ratios of major species diff --git a/src/dynamics/fv3 b/src/dynamics/fv3 index df3550b0f6..66227690a9 160000 --- a/src/dynamics/fv3 +++ b/src/dynamics/fv3 @@ -1 +1 @@ -Subproject commit df3550b0f6a835778f32ccc8c6291942e0413f62 +Subproject commit 66227690a9fb43a64492de32de14562a25ede717 diff --git a/src/physics/cam/clubb_intr.F90 b/src/physics/cam/clubb_intr.F90 index c5bdcd71ce..89bbaf4294 100644 --- a/src/physics/cam/clubb_intr.F90 +++ b/src/physics/cam/clubb_intr.F90 @@ -2549,8 +2549,9 @@ subroutine clubb_tend_cam( state, ptend_all, pbuf, hdtime, & ! Copy the state to state1 array to use in this routine call physics_state_copy(state, state1) - ! constituents are all treated as dry mmr by clubb - call set_wet_to_dry(state1) + ! Constituents are all treated as dry mmr by clubb. Convert the water species to + ! a dry basis. + call set_wet_to_dry(state1, convert_cnst_type='wet') if (clubb_do_liqsupersat) then call pbuf_get_field(pbuf, npccn_idx, npccn) diff --git a/src/physics/cam/gw_drag.F90 b/src/physics/cam/gw_drag.F90 index 0f48e661af..f8eca5dd1f 100644 --- a/src/physics/cam/gw_drag.F90 +++ b/src/physics/cam/gw_drag.F90 @@ -1396,7 +1396,7 @@ subroutine gw_tend(state, pbuf, dt, ptend, cam_in, flx_heat) call physics_state_copy(state, state1) ! constituents are all treated as wet mmr - call set_dry_to_wet(state1) + call set_dry_to_wet(state1, convert_cnst_type='dry') lchnk = state1%lchnk ncol = state1%ncol diff --git a/src/physics/cam/physics_types.F90 b/src/physics/cam/physics_types.F90 index 9b0c23d2ff..03f8022fa8 100644 --- a/src/physics/cam/physics_types.F90 +++ b/src/physics/cam/physics_types.F90 @@ -1481,40 +1481,72 @@ end subroutine set_state_pdry !=============================================================================== -subroutine set_wet_to_dry (state) +subroutine set_wet_to_dry(state, convert_cnst_type) + + ! Convert mixing ratios from a wet to dry basis for constituents of type + ! convert_cnst_type. Constituents are given a type when they are added + ! to the constituent array by a call to cnst_add during the register + ! phase of initialization. There are two constituent types: 'wet' for + ! water species and 'dry' for non-water species. use constituents, only: pcnst, cnst_type type(physics_state), intent(inout) :: state + character(len=3), intent(in) :: convert_cnst_type + ! local variables integer m, ncol + character(len=*), parameter :: sub = 'set_wet_to_dry' + !----------------------------------------------------------------------------- + + ! check input + if (.not.(convert_cnst_type == 'wet' .or. convert_cnst_type == 'dry')) then + write(iulog,*) sub//': FATAL: convert_cnst_type not recognized: '//convert_cnst_type + call endrun(sub//': FATAL: convert_cnst_type not recognized: '//convert_cnst_type) + end if ncol = state%ncol - do m = 1,pcnst - if (cnst_type(m).eq.'dry') then + do m = 1, pcnst + if (cnst_type(m) == convert_cnst_type) then state%q(:ncol,:,m) = state%q(:ncol,:,m)*state%pdel(:ncol,:)/state%pdeldry(:ncol,:) - endif + end if end do end subroutine set_wet_to_dry !=============================================================================== -subroutine set_dry_to_wet (state) +subroutine set_dry_to_wet(state, convert_cnst_type) + + ! Convert mixing ratios from a dry to wet basis for constituents of type + ! convert_cnst_type. Constituents are given a type when they are added + ! to the constituent array by a call to cnst_add during the register + ! phase of initialization. There are two constituent types: 'wet' for + ! water species and 'dry' for non-water species. use constituents, only: pcnst, cnst_type type(physics_state), intent(inout) :: state + character(len=3), intent(in) :: convert_cnst_type + ! local variables integer m, ncol + character(len=*), parameter :: sub = 'set_dry_to_wet' + !----------------------------------------------------------------------------- + + ! check input + if (.not.(convert_cnst_type == 'wet' .or. convert_cnst_type == 'dry')) then + write(iulog,*) sub//': FATAL: convert_cnst_type not recognized: '//convert_cnst_type + call endrun(sub//': FATAL: convert_cnst_type not recognized: '//convert_cnst_type) + end if ncol = state%ncol - do m = 1,pcnst - if (cnst_type(m).eq.'dry') then + do m = 1, pcnst + if (cnst_type(m) == convert_cnst_type) then state%q(:ncol,:,m) = state%q(:ncol,:,m)*state%pdeldry(:ncol,:)/state%pdel(:ncol,:) - endif + end if end do end subroutine set_dry_to_wet diff --git a/src/physics/cam/physpkg.F90 b/src/physics/cam/physpkg.F90 index cb7322254f..b2a6832eab 100644 --- a/src/physics/cam/physpkg.F90 +++ b/src/physics/cam/physpkg.F90 @@ -1948,7 +1948,7 @@ subroutine tphysac (ztodt, cam_in, & ! ! Note: this operation will NOT be reverted with set_wet_to_dry after set_dry_to_wet call ! - call set_dry_to_wet(state) + call set_dry_to_wet(state, convert_cnst_type='dry') if (trim(cam_take_snapshot_before) == "physics_dme_adjust") then call cam_snapshot_all_outfld_tphysac(cam_snapshot_after_num, state, tend, cam_in, cam_out, pbuf,& diff --git a/src/physics/cam/vertical_diffusion.F90 b/src/physics/cam/vertical_diffusion.F90 index 555c657ef3..507e99dc8d 100644 --- a/src/physics/cam/vertical_diffusion.F90 +++ b/src/physics/cam/vertical_diffusion.F90 @@ -911,7 +911,7 @@ subroutine vertical_diffusion_tend( & ! ----------------------- ! ! Assume 'wet' mixing ratios in diffusion code. - call set_dry_to_wet(state) + call set_dry_to_wet(state, convert_cnst_type='dry') rztodt = 1._r8 / ztodt lchnk = state%lchnk @@ -1384,7 +1384,7 @@ subroutine vertical_diffusion_tend( & endif end do ! convert wet mmr back to dry before conservation check - call set_wet_to_dry(state) + call set_wet_to_dry(state, convert_cnst_type='dry') if (.not. do_pbl_diags) then slten(:ncol,:) = ( sl(:ncol,:) - sl_prePBL(:ncol,:) ) * rztodt diff --git a/src/physics/cam7/physpkg.F90 b/src/physics/cam7/physpkg.F90 index aef997716f..2d652fa2d7 100644 --- a/src/physics/cam7/physpkg.F90 +++ b/src/physics/cam7/physpkg.F90 @@ -2395,7 +2395,7 @@ subroutine tphysac (ztodt, cam_in, & ! ! Note: this operation will NOT be reverted with set_wet_to_dry after set_dry_to_wet call ! - call set_dry_to_wet(state) + call set_dry_to_wet(state, convert_cnst_type='dry') if (trim(cam_take_snapshot_before) == "physics_dme_adjust") then call cam_snapshot_all_outfld_tphysac(cam_snapshot_before_num, state, tend, cam_in, cam_out, pbuf,& diff --git a/src/physics/carma/cam/carma_intr.F90 b/src/physics/carma/cam/carma_intr.F90 index ec935e29b4..03d7ca5fab 100644 --- a/src/physics/carma/cam/carma_intr.F90 +++ b/src/physics/carma/cam/carma_intr.F90 @@ -1036,7 +1036,7 @@ subroutine carma_timestep_tend(state, cam_in, cam_out, ptend, dt, pbuf, dlf, rli ! The CARMA interface assumes that mass mixing ratios are relative to a ! wet atmosphere, so convert any dry mass mixing ratios to wet. call physics_state_copy(state, state_loc) - call set_dry_to_wet(state_loc) + call set_dry_to_wet(state_loc, convert_cnst_type='dry') spdiags(:, :, :) = 0.0_r8 gpdiags(:, :, :, :) = 0.0_r8 diff --git a/src/physics/carma/models/cirrus/carma_cloudfraction.F90 b/src/physics/carma/models/cirrus/carma_cloudfraction.F90 index 88be7373bb..0ec202041f 100644 --- a/src/physics/carma/models/cirrus/carma_cloudfraction.F90 +++ b/src/physics/carma/models/cirrus/carma_cloudfraction.F90 @@ -24,8 +24,7 @@ subroutine CARMA_CloudFraction(carma, cstate, cam_in, state, icol, cldfrc, rhcri use carma_mod use shr_kind_mod, only: r8 => shr_kind_r8 - use physics_types, only: physics_state, physics_ptend, set_wet_to_dry, & - set_dry_to_wet + use physics_types, only: physics_state, physics_ptend use constituents, only: cnst_get_ind use cam_abortutils, only: endrun diff --git a/src/physics/carma/models/cirrus_dust/carma_cloudfraction.F90 b/src/physics/carma/models/cirrus_dust/carma_cloudfraction.F90 index 88be7373bb..0ec202041f 100644 --- a/src/physics/carma/models/cirrus_dust/carma_cloudfraction.F90 +++ b/src/physics/carma/models/cirrus_dust/carma_cloudfraction.F90 @@ -24,8 +24,7 @@ subroutine CARMA_CloudFraction(carma, cstate, cam_in, state, icol, cldfrc, rhcri use carma_mod use shr_kind_mod, only: r8 => shr_kind_r8 - use physics_types, only: physics_state, physics_ptend, set_wet_to_dry, & - set_dry_to_wet + use physics_types, only: physics_state, physics_ptend use constituents, only: cnst_get_ind use cam_abortutils, only: endrun diff --git a/src/physics/simple/physpkg.F90 b/src/physics/simple/physpkg.F90 index a296fd2fdb..8c9c1586ef 100644 --- a/src/physics/simple/physpkg.F90 +++ b/src/physics/simple/physpkg.F90 @@ -654,7 +654,7 @@ subroutine tphysac (ztodt, cam_in, cam_out, state, tend, pbuf) ! ! Note: this operation will NOT be reverted with set_wet_to_dry after set_dry_to_wet call ! - call set_dry_to_wet(state) + call set_dry_to_wet(state, convert_cnst_type='dry') call physics_dme_adjust(state, tend, qini, totliqini, toticeini, ztodt) call tot_energy_phys(state, 'phAM') call tot_energy_phys(state, 'dyAM', vc=vc_dycore)