diff --git a/bld/build-namelist b/bld/build-namelist index 65e0b36c8f..d23e72cfc9 100755 --- a/bld/build-namelist +++ b/bld/build-namelist @@ -798,6 +798,18 @@ if ($docosp) { add_default($nl, 'docosp', 'val'=>'.true.'); } +# TEM diags +if ($phys =~ /cam7/) { + add_default($nl, 'ctem_diags_numlats'); +} +# check for conflicting TEM diagnostics settings +if ((defined $nl->get_value('ctem_diags_numlats')) and (defined $nl->get_value('phys_grid_ctem_za_nlat'))) { + my $esmf_nlats = $nl->get_value('ctem_diags_numlats'); + my $sphr_nlats = $nl->get_value('phys_grid_ctem_za_nlat'); + if ($esmf_nlats>0 and $sphr_nlats>0) { + die "Cannot set both Spherical Harmonics and ESMF regrid methods of TEM zonal mean diagnostics.\n"; + } +} # Constituents # ============ @@ -3123,7 +3135,6 @@ else { # present in the namelist. add_default($nl, 'use_hemco'); if ($nl->get_value('use_hemco') =~ m/$TRUE/io) { - add_default($nl, 'cam_physics_mesh'); add_default($nl, 'hemco_data_root'); add_default($nl, 'hemco_config_file'); add_default($nl, 'hemco_diagn_file'); @@ -3211,7 +3222,6 @@ if ($waccmx) { add_default($nl, 'fv_high_altitude', 'val'=>'.true.'); } if ($ionos ne 'none') { - add_default($nl, 'cam_physics_mesh'); add_default($nl, 'oplus_grid'); add_default($nl, 'edyn_grid'); } diff --git a/bld/namelist_files/namelist_defaults_cam.xml b/bld/namelist_files/namelist_defaults_cam.xml index 356eb4e635..e61320cfbb 100644 --- a/bld/namelist_files/namelist_defaults_cam.xml +++ b/bld/namelist_files/namelist_defaults_cam.xml @@ -959,18 +959,10 @@ 320x385 320x385 - -atm/cam/coords/fv0.47x0.63_esmf_c210305.nc -atm/cam/coords/fv0.9x1.25_esmf_c210305.nc -atm/cam/coords/fv1.9x2.5_esmf_200428.nc -atm/cam/coords/fv4x5_esmf_c210305.nc -atm/cam/coords/ne5np4_esmf_20191204.nc -atm/cam/coords/ne5np4.pg3_esmf_mesh_c210121.nc -atm/cam/coords/ne16np4_esmf_c210305.nc -share/meshes/ne16pg3_ESMFmesh_cdf5_c20211018.nc -atm/cam/coords/ne30np4_esmf_c210305.nc -atm/cam/coords/ne30pg3_esmf_20200428.nc -share/meshes/ne120pg3_ESMFmesh_cdf5_c20211018.nc + +0 +90 +180 1.00D0 diff --git a/bld/namelist_files/use_cases/1850_trop_strat_t4s_cam7.xml b/bld/namelist_files/use_cases/1850_trop_strat_t4s_cam7.xml index bf255bfb24..f5ad20c1c1 100644 --- a/bld/namelist_files/use_cases/1850_trop_strat_t4s_cam7.xml +++ b/bld/namelist_files/use_cases/1850_trop_strat_t4s_cam7.xml @@ -114,13 +114,6 @@ 'HCFC22', 'N2O', 'CFC114', 'CFC115', 'HCFC141B', 'HCFC142B', 'CH2BR2', 'CHBR3', 'H2402', 'OCS', 'SF6', 'CFC11eq' - - -share/meshes/ne16pg3_ESMFmesh_cdf5_c20211018.nc -share/meshes/ne30pg3_ESMFmesh_cdf5_c20211018.nc - 90 -180 - 0, 5, 20, 40, 12, 120, 73 diff --git a/cime_config/buildnml b/cime_config/buildnml index fefafc887c..44238cf6e5 100755 --- a/cime_config/buildnml +++ b/cime_config/buildnml @@ -49,6 +49,7 @@ def buildnml(case, caseroot, compname): COMP_INTERFACE = case.get_value("COMP_INTERFACE") CALENDAR = case.get_value("CALENDAR") COMPSET = case.get_value("COMPSET") + mesh_file = case.get_value("ATM_DOMAIN_MESH") # The Gregorian calendar currently can't be used with spinup compsets # because CAM's stream-handling code can't handle a request for data @@ -153,6 +154,9 @@ def buildnml(case, caseroot, compname): if ninst > 1: logger.info("%s is being used for cam_branch_file", cam_branch_file) + # ESMF mesh file + infile_lines.append(" cam_physics_mesh = '" + mesh_file + "'") + # In python3 integer division returns a float value. # Adjust argument of int() to get nearest integer. dtime = int( (3600*24)/int(atm_ncpl) + .5) diff --git a/cime_config/testdefs/testmods_dirs/cam/outfrq3s_physgrid_tem/user_nl_cam b/cime_config/testdefs/testmods_dirs/cam/outfrq3s_physgrid_tem/user_nl_cam index dad2b49ac7..8f26b521bb 100644 --- a/cime_config/testdefs/testmods_dirs/cam/outfrq3s_physgrid_tem/user_nl_cam +++ b/cime_config/testdefs/testmods_dirs/cam/outfrq3s_physgrid_tem/user_nl_cam @@ -6,3 +6,4 @@ phys_grid_ctem_nfreq=3 phys_grid_ctem_zm_nbas=16 phys_grid_ctem_za_nlat=15 fincl3 = 'Uzm','Vzm','Wzm','THzm', 'VTHzm','WTHzm','UVzm','UWzm' +ctem_diags_numlats=0 diff --git a/cime_config/testdefs/testmods_dirs/cam/outfrq9s_ctem/user_nl_cam b/cime_config/testdefs/testmods_dirs/cam/outfrq9s_ctem/user_nl_cam index ea040c7c83..59037182ad 100644 --- a/cime_config/testdefs/testmods_dirs/cam/outfrq9s_ctem/user_nl_cam +++ b/cime_config/testdefs/testmods_dirs/cam/outfrq9s_ctem/user_nl_cam @@ -4,7 +4,6 @@ nhtfrq=9,9,9,9,9,9,9,9,9,9 write_nstep0=.true. inithist='ENDOFRUN' -cam_physics_mesh = '$ATM_DOMAIN_MESH' ctem_diags_numlats = 90 fincl2 = 'THtem','Utem','Vtem','Wtem','VTHtem','WTHtem','UVtem', 'UWtem', 'MSKtem', 'PStem' diff --git a/cime_config/testdefs/testmods_dirs/cam/outfrq9s_physgrid_tem_1deg/user_nl_cam b/cime_config/testdefs/testmods_dirs/cam/outfrq9s_physgrid_tem_1deg/user_nl_cam index a82b687449..ce1b66d301 100644 --- a/cime_config/testdefs/testmods_dirs/cam/outfrq9s_physgrid_tem_1deg/user_nl_cam +++ b/cime_config/testdefs/testmods_dirs/cam/outfrq9s_physgrid_tem_1deg/user_nl_cam @@ -6,3 +6,4 @@ phys_grid_ctem_nfreq=-2 phys_grid_ctem_zm_nbas=120 phys_grid_ctem_za_nlat=90 fincl3 = 'Uzm','Vzm','Wzm','THzm', 'VTHzm','WTHzm','UVzm','UWzm' +ctem_diags_numlats=0 diff --git a/doc/ChangeLog b/doc/ChangeLog index c34a0decaa..7deae2e301 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -1,5 +1,199 @@ =============================================================== +Tag name: cam6_4_170 +Originator(s): fvitt +Date: 30 Apr 2026 +One-line Summary: TEM diagnostics updates +Github PR URL: https://github.com/ESCOMP/CAM/pull/1543 + +Purpose of changes (include the issue number and title text for each relevant GitHub issue): + + Issue #1542 + Implement the following updates to TEM diagnostics: + - Set up default namelist settings so that ESMF regrid method is used by default + in cam7 configurations + - ESMF bilinear interpolation for the zonal mean calculations + - Use constant scale height of 7 km + - Correct calculation of potential temperature (Exner bug fix) + - Vertically interpolate to constant pressures before TEM terms are calculated + +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: cacraigucar + +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: + +M bld/build-namelist + - set default TEM diags namelist settings + - add check for conflicting namelist settings + - remove add_default for cam_physics_mesh -- now set by buildnml for all configurations + +M bld/namelist_files/namelist_defaults_cam.xml + - remove cam_physics_mesh defaults -- now set to $ATM_DOMAIN_MESH in buildnml + - default TEM num lats for ne16 and ne30 grids + +M bld/namelist_files/use_cases/1850_trop_strat_t4s_cam7.xml + - remove TEM settings -- now set by default + +M cime_config/buildnml + - set cam_physics_mesh to $ATM_DOMAIN_MESH for all configurations + +M cime_config/testdefs/testmods_dirs/cam/outfrq3s_physgrid_tem/user_nl_cam +M cime_config/testdefs/testmods_dirs/cam/outfrq9s_physgrid_tem_1deg/user_nl_cam + - avoid conflicting TEM settings + +M cime_config/testdefs/testmods_dirs/cam/outfrq9s_ctem/user_nl_cam + - remove cam_physics_mesh settings -- now default + +M src/physics/cam/phys_grid_ctem.F90 + - use constant scale height of 7 km + - correct calculation of potential temperature (Exner bug fix) + +M src/utils/ctem_diags_mod.F90 + - use constant scale height of 7 km + - correct calculation of potential temperature (Exner bug fix) + - vertically interpolate to constant pressures before TEM terms are calculated + +M src/utils/esmf_phys2lonlat_mod.F90 + - ESMF bilinear interpolation for the zonal mean calculations + +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: + NLFAIL ERC_D_Ln9.f09_f09_mt232.FHIST_BDRD.derecho_intel.cam-outfrq9s + NLFAIL ERC_D_Ln9.f19_f19_mg17.QPMOZ.derecho_intel.cam-outfrq3s + NLFAIL ERC_D_Ln9.f19_f19_mt232.QPC6.derecho_intel.cam-outfrq3s_cosp + NLFAIL ERC_D_Ln9.mpasa120_mpasa120.F2000climo.derecho_intel.cam-outfrq9s_mpasa120 + NLFAIL ERC_D_Ln9.mpasa120_mpasa120.FHISTC_LTso.derecho_intel.cam-outfrq9s_mpasa120 + NLFAIL ERC_D_Ln9.mpasa120_mpasa120.QPC7.derecho_intel.cam-outfrq9s_mpasa120 + NLFAIL ERC_D_Ln9.ne30pg2_ne30pg2_mt232.QPC7.derecho_intel.cam-outfrq9s + NLFAIL ERC_D_Ln9.ne30pg3_ne30pg3_mt232.F1850C_LTso.derecho_intel.cam-outfrq9s + NLFAIL ERC_Ln9.C96_C96_mt232.F2000climo.derecho_intel.cam-outfrq9s + NLFAIL ERI_D_Ln18.f09_f09_mt232.FHIST.derecho_intel.cam-outfrq3s_eri + NLFAIL ERI_D_Ln18.f19_f19_mt232.FHIST_C5.derecho_intel.cam-outfrq3s_eri + NLFAIL ERI_D_Ln18.ne16pg3_ne16pg3_mt232.FHIST_C4.derecho_intel.cam-outfrq3s_eri + NLFAIL ERI_D_Ln18.ne30pg3_ne30pg3_mt232.FHISTC_LTso.derecho_intel.cam-outfrq3s_eri + NLFAIL ERP_D_Ln9.ne30pg3_ne30pg3_mt232.F1850C_MTso.derecho_intel.cam-outfrq9s + NLFAIL ERP_D_Ln9_P64x2.f09_f09_mg17.QSC6.derecho_intel.cam-outfrq9s + NLFAIL ERP_Ld3.ne16pg3_ne16pg3_mg17.FHISTC_WAt1ma.derecho_intel.cam-reduced_hist1d + NLFAIL ERP_Ld3.ne30pg3_ne30pg3_mt232.FHISTC_MTt4s.derecho_intel.cam-outfrq1d_aoa + NLFAIL ERP_Lh12.f19_f19_mg17.FW4madSD.derecho_intel.cam-outfrq3h + NLFAIL ERP_Ln9.f19_f19_mg17.FWsc1850.derecho_intel.cam-outfrq9s + NLFAIL ERP_Ln9.ne30pg3_ne30pg3_mg17.FCnudged.derecho_intel.cam-outfrq9s + NLFAIL ERP_Ln9.ne30pg3_ne30pg3_mg17.FHISTC_WAma.derecho_intel.cam-outfrq9s + NLFAIL ERR_Ln9.ne16pg3_ne16pg3_mt232.FHISTC_LTso.derecho_intel.cam-outfrq9s_bwic + NLFAIL SCT_D_Ln7.ne3_ne3_mg37.QPC5.derecho_intel.cam-scm_prep + NLFAIL SMS_C2_D_Ln9.ne16pg3_ne16pg3_mg17.FHISTC_WXma.derecho_intel.cam-outfrq9s + NLFAIL SMS_D_Ld5.f09_f09_mt232.PC6.derecho_intel.cam-cam6_port_f09 + NLFAIL SMS_D_Ld5.f19_f19_mt232.PC4.derecho_intel.cam-cam4_port5d + NLFAIL SMS_D_Ln9.f09_f09_mg17.FCts2nudged.derecho_intel.cam-outfrq9s_leapday + NLFAIL SMS_D_Ln9.f09_f09_mg17.FCvbsxHIST.derecho_intel.cam-outfrq9s + NLFAIL SMS_D_Ln9.f09_f09_mg17.FSD.derecho_intel.cam-outfrq9s + NLFAIL SMS_D_Ln9.f19_f19_mg17.FCARMA2000climo.derecho_intel.cam-outfrq9s + NLFAIL SMS_D_Ln9.f19_f19_mg17.FCHIST_SLH.derecho_intel.cam-outfrq9s + NLFAIL SMS_D_Ln9.f19_f19_mg17.FWma2000climo.derecho_intel.cam-outfrq9s + NLFAIL SMS_D_Ln9.f19_f19_mg17.FWma2000climo.derecho_intel.cam-outfrq9s_waccm_ma_mam4 + NLFAIL SMS_D_Ln9.f19_f19_mg17.QPC2000climo.derecho_intel.cam-outfrq3s_usecase + NLFAIL SMS_D_Ln9.f19_f19_mt232.FHIST_C5.derecho_intel.cam-mam7 + NLFAIL SMS_D_Ln9.ne0ARCTICne30x4_ne0ARCTICne30x4_mt12.FHIST.derecho_intel.cam-outfrq9s + NLFAIL SMS_D_Ln9.ne30pg3_ne30pg3_mt232.FHISTC_MTso.derecho_intel.cam-outfrq9s + NLFAIL SMS_D_Ln9_P1280x1.ne30pg3_ne30pg3_mt232.FHISTC_MTt1s.derecho_intel.cam-outfrq9s_Leung_dust + NLFAIL SMS_D_Ln9_P1536x1.ne0CONUSne30x8_ne0CONUSne30x8_mt12.FCHIST.derecho_intel.cam-outfrq9s + NLFAIL SMS_Ld1.f09_f09_mg17.FW2000climo.derecho_intel.cam-outfrq1d + NLFAIL SMS_Ld1.ne30pg3_ne30pg3_mg17.FC2010climo.derecho_intel.cam-outfrq1d + NLFAIL SMS_Ln9.f09_f09_mg17.F2010climo.derecho_intel.cam-nudging + NLFAIL SMS_Ln9.f09_f09_mg17.FW1850.derecho_intel.cam-reduced_hist3s + NLFAIL SMS_Ln9.f19_f19_mt232.F2000climo.derecho_intel.cam-silhs + NLFAIL SMS_Ln9.ne30pg3_ne30pg3_mg17.FW2000climo.derecho_intel.cam-outfrq9s_rrtmgp + - cam_physics_mesh setting added to atm_in, otherwise bit-for-bit + + DIFF ERP_Ln9.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq9s + DIFF ERS_Ln9.f09_f09_mg17.FX2000.derecho_intel.cam-outfrq9s + DIFF ERS_Ln9.f19_f19_mg17.FXSD.derecho_intel.cam-outfrq9s + DIFF SMS_Ld1.f09_f09_mg17.FCHIST_GC.derecho_intel.cam-outfrq1d + DIFF SMS_Lh12.f09_f09_mg17.FCSD_HCO.derecho_intel.cam-outfrq3h + DIFF SMS_D_Ln9.ne16_ne16_mg17.QPX2000.derecho_intel.cam-outfrq9s_amie + - change in default cam_physics_mesh has caused differences + + DIFF ERS_Ln9.ne30pg3_ne30pg3_mg17.FHISTC_WXma.derecho_intel.cam-outfrq9s_ctem + DIFF SMS_D_Ln9.ne30pg3_ne30pg3_mt232.1850C_CAM70%MT%CT4S2_CLM60%SP_CICE%PRES_DOCN%DOM_MOSART_SGLC_SWAV_SESP.derecho_intel.cam-outfrq9s + - TEM diags update -- corrections in scale height and Exner, otherwise bit-for-bit + +derecho/nvhpc/aux_cam: + NLFAIL ERS_Ln9.ne30pg3_ne30pg3_mt232.FHISTC_LTso.derecho_nvhpc.cam-outfrq9s_gpu_default + +izumi/nag/aux_cam: + FAIL ERC_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_nag.cam-outfrq3s_subcol COMPARE_base_rest + - pre-existing failure -- see https://github.com/ESCOMP/CAM/issues/1514 + + NLFAIL ERC_D_Ln27.ne3pg3_ne3pg3_mt232.FKESSLER.izumi_nag.cam-outfrq9s + NLFAIL ERC_D_Ln9.f10_f10_mg37.QPWmaC6.izumi_nag.cam-outfrq3s + NLFAIL ERC_D_Ln9.f10_f10_mt232.FHIST.izumi_nag.cam-outfrq3s_cospsathist + NLFAIL ERC_D_Ln9.mpasa480_mpasa480_mt232.FHS94.izumi_nag.cam-outfrq9s + NLFAIL ERC_D_Ln9.mpasa480_mpasa480_mt232.QPC7.izumi_nag.cam-outfrq9s_mpasa480 + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FHISTC_LTso.izumi_nag.cam-cosp_rad_diags + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FHISTC_LTso.izumi_nag.cam-outfrq9s_nochem + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.QPC4.izumi_nag.cam-outfrq9s + NLFAIL ERC_D_Ln9_P1x1.ne3pg3_ne3pg3_mt232.FADIAB.izumi_nag.cam-outfrq9s + NLFAIL SMS_D_Ld2.f45_f45_mg37.PC5.izumi_nag.cam-outfrq24h_port + NLFAIL SMS_D_Ln9.f10_f10_mt232.F1850.izumi_nag.cam-outfrq9s + NLFAIL SMS_D_Ln9.ne3pg3_ne3pg3_mt232.QPC7.izumi_nag.cam-carma_test_tracers + NLFAIL TMC_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_nag.cam-mc_ttrac + - cam_physics_mesh setting added to atm_in, otherwise bit-for-bit + + DIFF SMS_D_Ln3.ne5pg3_ne5pg3_mg37.QPX2000.izumi_nag.cam-outfrq3s + - change in cam_physics_mesh has caused differences in WACCM-X + -- slight differences in physics-ionosphere mapping (regridding) + + DIFF SMS_D_Ln6.ne5_ne5_mg37.QPWmaC4.izumi_nag.cam-outfrq3s_physgrid_tem + - TEM diags update -- corrections in scale height and Exner, otherwise bit-for-bit + +izumi/gnu/aux_cam: + NLFAIL ERC_D_Ln9.C48_C48_mg17.QPC6.izumi_gnu.cam-outfrq9s + NLFAIL ERC_D_Ln9.f10_f10_mg37.QPC4.izumi_gnu.cam-outfrq3s_diags + NLFAIL ERC_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_gnu.cam-rad_diag + NLFAIL ERC_D_Ln9.f19_f19_mt232.FHIST.izumi_gnu.cam-lonlat_fv_diags + NLFAIL ERC_D_Ln9.mpasa480_mpasa480_mt232.FHISTC_LTso.izumi_gnu.cam-outfrq9s_mpasa480 + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.F1850_C4.izumi_gnu.cam-co2rmp + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FGRAYRAD.izumi_gnu.cam-outfrq9s + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FHIST_C5.izumi_gnu.cam-carma_cosp_rad_diag_mam + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FHISTC_LTso.izumi_gnu.cam-sat_lcltod + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FHIST.izumi_gnu.cam-nochem_clubbmf + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.FTJ16.izumi_gnu.cam-outfrq9s + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.QPC5.izumi_gnu.cam-outfrq9s + NLFAIL ERC_D_Ln9.ne3pg3_ne3pg3_mt232.QPC7.izumi_gnu.cam-outfrq9s + NLFAIL ERC_D_Ln9.ne5_ne5_mg37.QPC4.izumi_gnu.cam-outfrq3s_nudging_ne5_L26 + NLFAIL ERS_Ln9_P24x1.mpasa480_mpasa480.F2000climo.izumi_gnu.cam-outfrq9s_mpasa480 + NLFAIL PLB_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_gnu.cam-ttrac_loadbal0 + NLFAIL PLB_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_gnu.cam-ttrac_loadbal1 + NLFAIL PLB_D_Ln9.f10_f10_mt232.FHIST_C5.izumi_gnu.cam-ttrac_loadbal3 + NLFAIL SCT_D_Ln7.ne3_ne3_mg37.QPC6.izumi_gnu.cam-scm_prep_c6 + NLFAIL SMS_D_Ln3.f10_f10_mg37.QPMOZ.izumi_gnu.cam-outfrq3s_chemproc + NLFAIL SMS_D_Ln3.ne3pg3_ne3pg3_mt232.PC7.izumi_gnu.cam-pc7_ne3pg3 + NLFAIL SMS_D_Ln9.f10_f10_mg37.FWmaHIST.izumi_gnu.cam-outfrq9s_mee_fluxes + NLFAIL SMS_D_Ln9.f10_f10_mg37.QPWmaC4.izumi_gnu.cam-outfrq9s_apmee + NLFAIL SMS_D_Ln9.f19_f19_mt232.FW4madSD.izumi_gnu.cam-outfrq9s + NLFAIL SUB_D_Ln9.ne3pg3_ne3pg3_mt232.FHIST.izumi_gnu.cam-outfrq9s + - cam_physics_mesh setting added to atm_in, otherwise bit-for-bit + +Summarize any changes to answers: bit-for-bit climate -- differences in TEM diags + +=============================================================== +=============================================================== + Tag name: cam6_4_169 Originator(s): fvitt Date: 28 Apr 2026 diff --git a/src/physics/cam/phys_grid_ctem.F90 b/src/physics/cam/phys_grid_ctem.F90 index 6863799864..4d38ed5b93 100644 --- a/src/physics/cam/phys_grid_ctem.F90 +++ b/src/physics/cam/phys_grid_ctem.F90 @@ -222,6 +222,8 @@ end subroutine phys_grid_ctem_init !----------------------------------------------------------------------------- !----------------------------------------------------------------------------- subroutine phys_grid_ctem_diags(phys_state) + use air_composition, only: cappav + use physconst, only: pref type(physics_state), intent(in) :: phys_state(begchunk:endchunk) character(len=*), parameter :: prefix = 'phys_grid_ctem_diags: ' @@ -260,7 +262,7 @@ subroutine phys_grid_ctem_diags(phys_state) real(r8) :: wza(nzalat,pver) real(r8) :: thza(nzalat,pver) - real(r8) :: sheight(pcols,pver) ! pressure scale height (m) + real(r8), parameter :: hscale = 7000._r8 ! pressure scale height (meters) if (.not.do_calc()) return @@ -268,14 +270,12 @@ subroutine phys_grid_ctem_diags(phys_state) ncol = phys_state(lchnk)%ncol - ! scale height - sheight(:ncol,:) = phys_state(lchnk)%t(:ncol,:) * rgas / ( mbarv(:ncol,:,lchnk) * grav ) ! meters - ! potential temperature - theta(:ncol,:,lchnk) = phys_state(lchnk)%t(:ncol,:) * phys_state(lchnk)%exner(:ncol,:) + theta(:ncol,:,lchnk) = phys_state(lchnk)%t(:ncol,:) * & + (pref/ phys_state(lchnk)%pmid(:ncol,:))**cappav(:ncol,:,lchnk) ! vertical velocity - w(:ncol,:,lchnk) = -sheight(:ncol,:) * phys_state(lchnk)%omega(:ncol,:) / phys_state(lchnk)%pmid(:ncol,:) + w(:ncol,:,lchnk) = -hscale * phys_state(lchnk)%omega(:ncol,:) / phys_state(lchnk)%pmid(:ncol,:) u(:ncol,:,lchnk) = phys_state(lchnk)%u(:ncol,:) v(:ncol,:,lchnk) = phys_state(lchnk)%v(:ncol,:) diff --git a/src/utils/ctem_diags_mod.F90 b/src/utils/ctem_diags_mod.F90 index 280837ba7d..bd6e67702b 100644 --- a/src/utils/ctem_diags_mod.F90 +++ b/src/utils/ctem_diags_mod.F90 @@ -228,13 +228,14 @@ end subroutine ctem_diags_init !----------------------------------------------------------------------------- !----------------------------------------------------------------------------- subroutine ctem_diags_calc(phys_state) - use air_composition, only: mbarv ! g/mole use shr_const_mod, only: rgas => shr_const_rgas ! J/K/kmole use shr_const_mod, only: grav => shr_const_g ! m/s2 use esmf_phys2lonlat_mod, only: esmf_phys2lonlat_regrid use esmf_zonal_mean_mod, only: esmf_zonal_mean_calc, esmf_zonal_mean_wsums, esmf_zonal_mean_masked use interpolate_data, only: lininterp use esmf_phys2lonlat_mod, only: fields_bundle_t, nflds + use air_composition, only: cappav + use physconst, only: pref type(physics_state), intent(in) :: phys_state(begchunk:endchunk) @@ -242,7 +243,6 @@ subroutine ctem_diags_calc(phys_state) real(r8), target :: v_phys(pver,pcols,begchunk:endchunk) real(r8), target :: w_phys(pver,pcols,begchunk:endchunk) real(r8), target :: t_phys(pver,pcols,begchunk:endchunk) - real(r8), target :: p_phys(pver,pcols,begchunk:endchunk) real(r8), target :: uv_phys(pver,pcols,begchunk:endchunk) real(r8), target :: uw_phys(pver,pcols,begchunk:endchunk) @@ -255,26 +255,14 @@ subroutine ctem_diags_calc(phys_state) real(r8), target :: v_lonlat(beglon:endlon,beglat:endlat,pver) real(r8), target :: w_lonlat(beglon:endlon,beglat:endlat,pver) real(r8), target :: t_lonlat(beglon:endlon,beglat:endlat,pver) - real(r8), target :: p_lonlat(beglon:endlon,beglat:endlat,pver) real(r8) :: ps_lonlat(beglon:endlon,beglat:endlat) real(r8) :: mskind1(beglon:endlon,beglat:endlat) ! vertical index where mountain masking begins - real(r8) :: ui_lonlat(beglon:endlon,beglat:endlat,pver) - real(r8) :: vi_lonlat(beglon:endlon,beglat:endlat,pver) - real(r8) :: wi_lonlat(beglon:endlon,beglat:endlat,pver) - real(r8) :: ti_lonlat(beglon:endlon,beglat:endlat,pver) - real(r8), target :: uv_lonlat(beglon:endlon,beglat:endlat,pver) real(r8), target :: uw_lonlat(beglon:endlon,beglat:endlat,pver) real(r8), target :: vt_lonlat(beglon:endlon,beglat:endlat,pver) real(r8), target :: wt_lonlat(beglon:endlon,beglat:endlat,pver) - real(r8) :: uvi_lonlat(beglon:endlon,beglat:endlat,pver) - real(r8) :: uwi_lonlat(beglon:endlon,beglat:endlat,pver) - real(r8) :: vti_lonlat(beglon:endlon,beglat:endlat,pver) - real(r8) :: wti_lonlat(beglon:endlon,beglat:endlat,pver) - - real(r8) :: u_zm(beglat:endlat,pver) real(r8) :: v_zm(beglat:endlat,pver) real(r8) :: w_zm(beglat:endlat,pver) @@ -299,7 +287,6 @@ subroutine ctem_diags_calc(phys_state) real(r8) :: wsums(beglat:endlat,pver) integer :: lchnk, ncol, i, j, k - real(r8) :: sheight(pver) ! pressure scale height (m) real(r8) :: outtmp(beglon:endlon,pver) integer :: outcnt @@ -309,6 +296,9 @@ subroutine ctem_diags_calc(phys_state) type(fields_bundle_t) :: physflds(nflds) type(fields_bundle_t) :: lonlatflds(nflds) + real(r8) :: theta(pver) + real(r8), parameter :: hscale = 7000._r8 ! pressure scale height (meters) + if (.not.ctem_diags_active) return call t_startf('ctem_diags_calc') @@ -318,21 +308,26 @@ subroutine ctem_diags_calc(phys_state) do lchnk = begchunk,endchunk ncol = phys_state(lchnk)%ncol do i = 1,ncol - ! wind components - u_phys(:,i,lchnk) = phys_state(lchnk)%u(i,:) - v_phys(:,i,lchnk) = phys_state(lchnk)%v(i,:) - ! scale height - sheight(:) = phys_state(lchnk)%t(i,:) * rgas / ( mbarv(i,:,lchnk) * grav ) ! meters + ! wind components -- vertically intepolate to ref press + call lininterp( phys_state(lchnk)%u(i,:), phys_state(lchnk)%pmid(i,:), pver, & + u_phys(:,i,lchnk), pref_mid(:), pver ) + + call lininterp( phys_state(lchnk)%v(i,:), phys_state(lchnk)%pmid(i,:), pver, & + v_phys(:,i,lchnk), pref_mid(:), pver ) + + call lininterp( phys_state(lchnk)%omega(i,:), phys_state(lchnk)%pmid(i,:), pver, & + w_phys(:,i,lchnk), pref_mid(:), pver ) - ! vertical velocity - w_phys(:,i,lchnk) = -sheight(:) * phys_state(lchnk)%omega(i,:) / phys_state(lchnk)%pmid(i,:) + ! omega -> vertical velocity + w_phys(:,i,lchnk) = -hscale * w_phys(:,i,lchnk)/pref_mid(:) - ! potential temperature - t_phys(:,i,lchnk) = phys_state(lchnk)%t(i,:) * phys_state(lchnk)%exner(i,:) + ! potential temperature -- vertically intepolate to ref press + theta(:) = phys_state(lchnk)%t(i,:) * & + (pref/ phys_state(lchnk)%pmid(i,:))**cappav(i,:,lchnk) - ! mid point press - p_phys(:,i,lchnk) = phys_state(lchnk)%pmid(i,:) + call lininterp( theta(:), phys_state(lchnk)%pmid(i,:), pver, & + t_phys(:,i,lchnk), pref_mid(:), pver ) ! surface pressure ps_phys(i,lchnk) = phys_state(lchnk)%ps(i) @@ -351,39 +346,37 @@ subroutine ctem_diags_calc(phys_state) ! regrid to lon/lat grid - physflds(1)%fld => u_phys + ! set feild-bundle pointers for regridding utility + physflds(1)%fld => u_phys ! regrid inputs physflds(2)%fld => v_phys physflds(3)%fld => w_phys physflds(4)%fld => t_phys - physflds(5)%fld => p_phys - physflds(6)%fld => uv_phys - physflds(7)%fld => uw_phys - physflds(8)%fld => vt_phys - physflds(9)%fld => wt_phys + physflds(5)%fld => uv_phys + physflds(6)%fld => uw_phys + physflds(7)%fld => vt_phys + physflds(8)%fld => wt_phys - lonlatflds(1)%fld => u_lonlat + lonlatflds(1)%fld => u_lonlat ! regrid outputs lonlatflds(2)%fld => v_lonlat lonlatflds(3)%fld => w_lonlat lonlatflds(4)%fld => t_lonlat - lonlatflds(5)%fld => p_lonlat - lonlatflds(6)%fld => uv_lonlat - lonlatflds(7)%fld => uw_lonlat - lonlatflds(8)%fld => vt_lonlat - lonlatflds(9)%fld => wt_lonlat + lonlatflds(5)%fld => uv_lonlat + lonlatflds(6)%fld => uw_lonlat + lonlatflds(7)%fld => vt_lonlat + lonlatflds(8)%fld => wt_lonlat + ! regrid 3-D fields call esmf_phys2lonlat_regrid(physflds, lonlatflds) + ! regrid 2-D field separately call esmf_phys2lonlat_regrid(ps_phys, ps_lonlat) call t_stopf('ctem_diags_calc-regrid') - call t_startf('ctem_diags_calc-zonal_mean-ps') - call esmf_zonal_mean_calc(ps_lonlat, ps_zm) - call t_stopf('ctem_diags_calc-zonal_mean-ps') - call t_startf('ctem_diags_calc-interp') + call t_startf('ctem_diags_calc-zonal_mean-uvwt') - ! vertically intepolate to ref press + ! Mask out the mountains do i = beglon,endlon do j = beglat,endlat @@ -397,54 +390,28 @@ subroutine ctem_diags_calc(phys_state) wght(i,j,k) = 0._r8 end if end do - - call lininterp( u_lonlat(i,j,:), p_lonlat(i,j,:), pver, & - ui_lonlat(i,j,:), pref_mid(:), pver ) - - call lininterp( v_lonlat(i,j,:), p_lonlat(i,j,:), pver, & - vi_lonlat(i,j,:), pref_mid(:), pver ) - - call lininterp( w_lonlat(i,j,:), p_lonlat(i,j,:), pver, & - wi_lonlat(i,j,:), pref_mid(:), pver ) - - call lininterp( t_lonlat(i,j,:), p_lonlat(i,j,:), pver, & - ti_lonlat(i,j,:), pref_mid(:), pver ) - - call lininterp( uv_lonlat(i,j,:), p_lonlat(i,j,:), pver, & - uvi_lonlat(i,j,:), pref_mid(:), pver ) - - call lininterp( uw_lonlat(i,j,:), p_lonlat(i,j,:), pver, & - uwi_lonlat(i,j,:), pref_mid(:), pver ) - - call lininterp( vt_lonlat(i,j,:), p_lonlat(i,j,:), pver, & - vti_lonlat(i,j,:), pref_mid(:), pver ) - - call lininterp( wt_lonlat(i,j,:), p_lonlat(i,j,:), pver, & - wti_lonlat(i,j,:), pref_mid(:), pver ) - end do end do - call t_stopf('ctem_diags_calc-interp') - - call t_startf('ctem_diags_calc-zonal_mean-uvwt') - ! calculate zonal means from interpolated fields ! mask out mountains from the zonal mean calculations wsums = esmf_zonal_mean_wsums(wght) - call esmf_zonal_mean_masked(ui_lonlat, wght, wsums, u_zm) - call esmf_zonal_mean_masked(vi_lonlat, wght, wsums, v_zm) - call esmf_zonal_mean_masked(wi_lonlat, wght, wsums, w_zm) - call esmf_zonal_mean_masked(ti_lonlat, wght, wsums, t_zm) - - call esmf_zonal_mean_masked(uvi_lonlat, wght, wsums, uv_zm) - call esmf_zonal_mean_masked(uwi_lonlat, wght, wsums, uw_zm) - call esmf_zonal_mean_masked(vti_lonlat, wght, wsums, vt_zm) - call esmf_zonal_mean_masked(wti_lonlat, wght, wsums, wt_zm) + ! compute zonal-mean fields + call esmf_zonal_mean_masked(u_lonlat, wght, wsums, u_zm) + call esmf_zonal_mean_masked(v_lonlat, wght, wsums, v_zm) + call esmf_zonal_mean_masked(w_lonlat, wght, wsums, w_zm) + call esmf_zonal_mean_masked(t_lonlat, wght, wsums, t_zm) + call esmf_zonal_mean_masked(uv_lonlat, wght, wsums, uv_zm) + call esmf_zonal_mean_masked(uw_lonlat, wght, wsums, uw_zm) + call esmf_zonal_mean_masked(vt_lonlat, wght, wsums, vt_zm) + call esmf_zonal_mean_masked(wt_lonlat, wght, wsums, wt_zm) call t_stopf('ctem_diags_calc-zonal_mean-uvwt') + ! compute zonal-mean PS + call esmf_zonal_mean_calc(ps_lonlat, ps_zm) + call t_startf('ctem_diags_calc-calc_dev_flx') ! Calculate fluxes @@ -474,6 +441,7 @@ subroutine ctem_diags_calc(phys_state) call t_startf('ctem_diags_calc-zonal_mean-p') + ! compute zonal-mean flux terms call esmf_zonal_mean_masked(vtp, wght, wsums, vtp_zm) call esmf_zonal_mean_masked(wtp, wght, wsums, wtp_zm) call esmf_zonal_mean_masked(uwp, wght, wsums, uwp_zm) @@ -485,15 +453,15 @@ subroutine ctem_diags_calc(phys_state) outcnt = endlon-beglon+1 - ! output diagnostics + ! output TEM diagnostics do j = beglat,endlat - outtmp(beglon:endlon,1:pver) = ti_lonlat(beglon:endlon,j,1:pver) + outtmp(beglon:endlon,1:pver) = t_lonlat(beglon:endlon,j,1:pver) call outfld('THtem',outtmp, outcnt, j) - outtmp(beglon:endlon,1:pver) = ui_lonlat(beglon:endlon,j,1:pver) + outtmp(beglon:endlon,1:pver) = u_lonlat(beglon:endlon,j,1:pver) call outfld('Utem',outtmp, outcnt, j) - outtmp(beglon:endlon,1:pver) = vi_lonlat(beglon:endlon,j,1:pver) + outtmp(beglon:endlon,1:pver) = v_lonlat(beglon:endlon,j,1:pver) call outfld('Vtem',outtmp, outcnt, j) - outtmp(beglon:endlon,1:pver) = wi_lonlat(beglon:endlon,j,1:pver) + outtmp(beglon:endlon,1:pver) = w_lonlat(beglon:endlon,j,1:pver) call outfld('Wtem',outtmp, outcnt, j) outtmp(beglon:endlon,1:pver) = vtp(beglon:endlon,j,1:pver) call outfld('VTHtem',outtmp, outcnt, j) diff --git a/src/utils/esmf_phys2lonlat_mod.F90 b/src/utils/esmf_phys2lonlat_mod.F90 index 46438d1a24..bfdc770b15 100644 --- a/src/utils/esmf_phys2lonlat_mod.F90 +++ b/src/utils/esmf_phys2lonlat_mod.F90 @@ -13,7 +13,7 @@ module esmf_phys2lonlat_mod use ESMF, only: ESMF_FieldCreate, ESMF_FieldRegridStore use ESMF, only: ESMF_FieldGet, ESMF_FieldRegrid use ESMF, only: ESMF_KIND_I4, ESMF_KIND_R8, ESMF_TYPEKIND_R8 - use ESMF, only: ESMF_REGRIDMETHOD_CONSERVE + use ESMF, only: ESMF_REGRIDMETHOD_BILINEAR, ESMF_POLEMETHOD_ALLAVG, ESMF_EXTRAPMETHOD_NEAREST_IDAVG use ESMF, only: ESMF_TERMORDER_SRCSEQ, ESMF_MESHLOC_ELEMENT, ESMF_STAGGERLOC_CENTER use ESMF, only: ESMF_FieldDestroy, ESMF_RouteHandleDestroy use esmf_check_error_mod, only: check_esmf_error @@ -46,7 +46,7 @@ module esmf_phys2lonlat_mod real(r8), pointer :: fld(:,:,:) => null() end type fields_bundle_t - integer, parameter :: nflds = 9 + integer, parameter :: nflds = 8 contains @@ -101,19 +101,21 @@ subroutine esmf_phys2lonlat_init() call check_esmf_error(rc, subname//'ESMF_FieldCreate 2D lonlat fld ERROR') call ESMF_FieldRegridStore(srcField=physfld_3d, dstField=lonlatfld_3d, & - regridMethod=ESMF_REGRIDMETHOD_CONSERVE, & - routeHandle=rh_phys2lonlat_3d, & - srcTermProcessing=smm_srctermproc, & - pipelineDepth=smm_pipelinedep, & - rc=rc) + regridMethod=ESMF_REGRIDMETHOD_BILINEAR, & + polemethod=ESMF_POLEMETHOD_ALLAVG, & + extrapMethod=ESMF_EXTRAPMETHOD_NEAREST_IDAVG, & + routeHandle=rh_phys2lonlat_3d, factorIndexList=factorIndexList, & + factorList=factorList, srcTermProcessing=smm_srctermproc, & + pipelineDepth=smm_pipelinedep, rc=rc) call check_esmf_error(rc, subname//'ESMF_FieldRegridStore 3D routehandle ERROR') call ESMF_FieldRegridStore(srcField=physfld_2d, dstField=lonlatfld_2d, & - regridMethod=ESMF_REGRIDMETHOD_CONSERVE, & - routeHandle=rh_phys2lonlat_2d, & - srcTermProcessing=smm_srctermproc, & - pipelineDepth=smm_pipelinedep, & - rc=rc) + regridMethod=ESMF_REGRIDMETHOD_BILINEAR, & + polemethod=ESMF_POLEMETHOD_ALLAVG, & + extrapMethod=ESMF_EXTRAPMETHOD_NEAREST_IDAVG, & + routeHandle=rh_phys2lonlat_2d, factorIndexList=factorIndexList, & + factorList=factorList, srcTermProcessing=smm_srctermproc, & + pipelineDepth=smm_pipelinedep, rc=rc) call check_esmf_error(rc, subname//'ESMF_FieldRegridStore 3D routehandle ERROR') end subroutine esmf_phys2lonlat_init