From c50362cbfcffaf36096181d7a6b6da3a9d310a7c Mon Sep 17 00:00:00 2001 From: John Truesdale Date: Mon, 26 Aug 2024 07:31:12 -0600 Subject: [PATCH] update ChangeLog, pull hvcoord addition --- doc/ChangeLog | 146 +++++++++++----------- src/control/scamMod.F90 | 85 ++++++------- src/dynamics/eul/dyn_comp.F90 | 4 +- src/dynamics/eul/dyn_grid.F90 | 13 -- src/dynamics/eul/stepon.F90 | 4 +- src/dynamics/se/apply_iop_forcing.F90 | 4 +- src/dynamics/se/dyn_comp.F90 | 7 +- src/dynamics/se/dyn_grid.F90 | 15 ++- src/dynamics/se/gravity_waves_sources.F90 | 2 +- src/dynamics/se/se_single_column_mod.F90 | 4 +- src/dynamics/se/stepon.F90 | 8 +- src/utils/hybvcoord_mod.F90 | 28 ----- src/utils/hycoef.F90 | 11 -- 13 files changed, 147 insertions(+), 184 deletions(-) delete mode 100644 src/utils/hybvcoord_mod.F90 diff --git a/doc/ChangeLog b/doc/ChangeLog index 6b34982070..31167ed661 100644 --- a/doc/ChangeLog +++ b/doc/ChangeLog @@ -2,7 +2,7 @@ Tag name: cam6_4_023 Originator(s): jet -Date: Aug 23, 2024 +Date: Aug 26, 2024 One-line Summary: cam6_4_023: SCAM-SE feature addition plus bugfixes and some refactoring Github PR URL: https://github.com/ESCOMP/CAM/pull/958 @@ -26,25 +26,29 @@ The SCAM-SE vertical advection skips the horizontal step and derives the floatin based on the IOP prescribed vertical velocity. The floating levels are subsequently remapped at the end of the vertically Lagrangian dynamics step. +Closes Issue SCAM-SE - Allow use of spectral elements dycore in single column mode. #957 +Closes Issue some SCAM IOP's are broken #853 +Closes Issue Unhelpful error message when running SCAM and IOP file is too short #742 + Describe any changes made to build system: Allow SCAM to be built with spectral element dycore Describe any changes made to the namelist: N/A List any changes to the defaults for the boundary datasets:New boundary data for SE SCM -A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-09-01-00000.nc -A atm/cam/inic/se/cami_0000-01-01_ne3np4_L30_c120315.nc -A atm/cam/inic/se/cami_0000-01-01_ne3np4_L26_c120525.nc -A atm/cam/topo/se/ne3np4_gmted2010_modis_bedmachine_nc0540_Laplace1000_noleak_20230717.nc -A atm/cam/chem/trop_mam/atmsrf_ne3np4_230718.nc -A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-01-01-00000.nc -A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-02-01-00000.nc -A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-04-01-00000.nc -A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-06-01-00000.nc -A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-07-01-00000.nc -A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-08-01-00000.nc -A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-10-01-00000.nc -A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-12-01-00000.nc -A atm/cam/scam/iop/micre2017_3mo.cam.i.2017-01-01-00000.regrid.ne3np4.nc + A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-09-01-00000.nc + A atm/cam/inic/se/cami_0000-01-01_ne3np4_L30_c120315.nc + A atm/cam/inic/se/cami_0000-01-01_ne3np4_L26_c120525.nc + A atm/cam/topo/se/ne3np4_gmted2010_modis_bedmachine_nc0540_Laplace1000_noleak_20230717.nc + A atm/cam/chem/trop_mam/atmsrf_ne3np4_230718.nc + A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-01-01-00000.nc + A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-02-01-00000.nc + A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-04-01-00000.nc + A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-06-01-00000.nc + A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-07-01-00000.nc + A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-08-01-00000.nc + A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-10-01-00000.nc + A atm/cam/inic/se/CESM2.F2000climo.ne3np4.cam.i.0003-12-01-00000.nc + A atm/cam/scam/iop/micre2017_3mo.cam.i.2017-01-01-00000.regrid.ne3np4.nc Describe any substantial timing or memory changes: N/A @@ -112,97 +116,96 @@ List all files added and what they do: N/A A src/dynamics/se/apply_iop_forcing.F90 A src/dynamics/se/dycore/se_single_column_mod.F90 - A src/utils/hybvcoord_mod.F90 - enable iop forcing for SE SCM List all existing files that have been modified, and describe the changes: -M .gitmodules + M .gitmodules - update cice to fix scam failure - update cdeps to fix CDEPS regression test build failures -M bld/build-namelist + M bld/build-namelist - update namelist defaults for scm relaxation. -M bld/config_files/definition.xml + M bld/config_files/definition.xml - new configurations option for scam_iops -M bld/configure + M bld/configure - new configure options for SCAM refactor -M bld/namelist_files/namelist_defaults_cam.xml -M bld/namelist_files/namelist_definition.xml + M bld/namelist_files/namelist_defaults_cam.xml + M bld/namelist_files/namelist_definition.xml - new configurations option for scam_iops -M cime_config/buildcpp + M cime_config/buildcpp - setup new build for se SCAM test -M cime_config/config_component.xml -M cime_config/config_compsets.xml + M cime_config/config_component.xml + M cime_config/config_compsets.xml - add scam defaults to cime -M cime_config/config_pes.xml + M cime_config/config_pes.xml - add scam se pe defaults -M cime_config/SystemTests/sct.py + M cime_config/SystemTests/sct.py - setup new BFB se SCAM test -M cime_config/testdefs/testlist_cam.xml + M cime_config/testdefs/testlist_cam.xml - fix mpace test and add test_scam category -M cime_config/testdefs/testmods_dirs/cam/scmarm/shell_commands + M cime_config/testdefs/testmods_dirs/cam/scmarm/shell_commands - add new scam se regression tests -M cime_config/usermods_dirs/scam_mandatory/shell_commands + M cime_config/usermods_dirs/scam_mandatory/shell_commands - add warmstart logic -M src/control/cam_comp.F90 + M src/control/cam_comp.F90 - cleanup some of the BFB_CAM_SCAM_IOP cppdefs -M src/control/cam_history.F90 + M src/control/cam_history.F90 - set write_camiop logical if CAMIOP history type is requested by user. -M src/control/getinterpnetcdfdata.F90 -M src/control/history_scam.F90 + M src/control/getinterpnetcdfdata.F90 + M src/control/history_scam.F90 - generalize for output on single column grid -M src/control/ncdio_atm.F90 + M src/control/ncdio_atm.F90 - add physgrid_scm, scam uses the full physgrid to read data from boundary and -M src/control/scamMod.F90 + M src/control/scamMod.F90 - new control parameters for SCAM-SE -M src/dynamics/eul/diag_dynvar_ic.F90 -M src/dynamics/eul/dyn_comp.F90 -M src/dynamics/eul/dynpkg.F90 + M src/dynamics/eul/diag_dynvar_ic.F90 + M src/dynamics/eul/dyn_comp.F90 + M src/dynamics/eul/dynpkg.F90 - remove more scam CPP defines -M src/dynamics/eul/dyn_grid.F90 -M src/dynamics/eul/iop.F90 + M src/dynamics/eul/dyn_grid.F90 + M src/dynamics/eul/iop.F90 - generalize to use common routines for SE and EUL -M src/dynamics/eul/restart_dynamics.F90 + M src/dynamics/eul/restart_dynamics.F90 - remove more scam CPP defines -M src/dynamics/eul/scmforecast.F90 -M src/dynamics/eul/stepon.F90 -M src/dynamics/eul/tfilt_massfix.F90 + M src/dynamics/eul/scmforecast.F90 + M src/dynamics/eul/stepon.F90 + M src/dynamics/eul/tfilt_massfix.F90 - refactor/cleanup -M src/dynamics/se/advect_tend.F90 + M src/dynamics/se/advect_tend.F90 - capture SE advective tendencies for BFB testing -M src/dynamics/se/dp_coupling.F90 + M src/dynamics/se/dp_coupling.F90 - phys/dyn interface additions for SE-SCAM -M src/dynamics/se/dycore/prim_advance_mod.F90 -M src/dynamics/se/dycore/prim_driver_mod.F90 -M src/dynamics/se/dycore/vertremap_mod.F90 -M src/dynamics/se/dycore/viscosity_mod.F90 + M src/dynamics/se/dycore/prim_advance_mod.F90 + M src/dynamics/se/dycore/prim_driver_mod.F90 + M src/dynamics/se/dycore/vertremap_mod.F90 + M src/dynamics/se/dycore/viscosity_mod.F90 - refactor/cleanup -M src/dynamics/se/dyn_comp.F90 -M src/dynamics/se/dyn_grid.F90 + M src/dynamics/se/dyn_comp.F90 + M src/dynamics/se/dyn_grid.F90 - add SE single column mod -M src/dynamics/se/gravity_waves_sources.F90 + M src/dynamics/se/gravity_waves_sources.F90 - hvcoord -M src/dynamics/se/stepon.F90 + M src/dynamics/se/stepon.F90 - add SE SCAM iop update calls -M src/infrastructure/phys_grid.F90 + M src/infrastructure/phys_grid.F90 - update for single column phys grid -M src/physics/cam7/physpkg.F90 -M src/physics/cam/cam_diagnostics.F90 + M src/physics/cam7/physpkg.F90 + M src/physics/cam/cam_diagnostics.F90 - clean up BFB cpp defs -M src/physics/cam/check_energy.F90 + M src/physics/cam/check_energy.F90 - add heat_glob for SE iop -M src/physics/cam/chem_surfvals.F90 + M src/physics/cam/chem_surfvals.F90 - add column initialization for greenhouse gasses -M src/physics/cam/clubb_intr.F90 + M src/physics/cam/clubb_intr.F90 - use model grid box size not arbitrary SCM column size -M src/physics/cam/convect_shallow.F90 + M src/physics/cam/convect_shallow.F90 - add DQP diagnostic -M src/physics/cam/phys_grid.F90 + M src/physics/cam/phys_grid.F90 - define scm single column grid for scm history -M src/physics/cam/physpkg.F90 + M src/physics/cam/physpkg.F90 - clean up BFB cpp defs -M src/utils/cam_grid_support.F90 + M src/utils/cam_grid_support.F90 - add trim to grid name -M src/utils/hycoef.F90 + M src/utils/hycoef.F90 - add hvcoord struct @@ -220,15 +223,12 @@ derecho/intel/aux_cam: SMS_D_Ln9_P1280x1.ne0CONUSne30x8_ne0CONUSne30x8_mt12.FCHIST.derecho_intel.cam-outfrq9s (Overall: PEND) details: - pre-existing pend/failures -- need fix in CLM external - SCT_D_Ln7.ne3_ne3_mg37.QPC5.derecho_intel.cam-scm_prep (Overall: FAIL) + SCT_D_Ln7.ne3_ne3_mg37.QPC5.derecho_intel.cam-scm_prep BFAIL - New Test; Failure expected (SCAM on spectral element grid) - SMS_D_Ln9.T42_T42.FSCAMARM97.derecho_intel.cam-outfrq9s (Overall: FAIL) details: + SMS_D_Ln9.T42_T42.FSCAMARM97.derecho_intel.cam-outfrq9s BFAIL - New Test; Failure expected; FSCAM compset named changed to FSCAMARM97 - SMS_D_Ln9.T42_T42.FSCAMARM97.derecho_intel.cam-outfrq9s (Overall: FAIL) - - New Test name; Failure expected (FSCAM->FSCAMARM97) - SCT_D_Ln7.T42_T42_mg17.QPC5.derecho_intel.cam-scm_prep (Overall: DIFF) details: - Roundoff answer changes expected to existing SCAM prep cases @@ -273,8 +273,8 @@ derecho/intel/aux_cam: - Expected failures, In addition to differences these tests also failed namelist comparisons due to the updated cice derecho/nvhpc/aux_cam: - ERS_Ln9_G4-a100-openacc.ne30pg3_ne30pg3_mg17.F2000dev.derecho_nvhpc.cam-outfrq9s_mg3_default (Overall: DIFF) details: - - Roundoff answer changes expected + ERS_Ln9_G4-a100-openacc.ne30pg3_ne30pg3_mg17.F2000dev.derecho_nvhpc.cam-outfrq9s_mg3_default (Overall: NLFAIL) + - Expected failures due to the updated cice izumi/nag/aux_cam: DAE.f45_f45_mg37.FHS94.izumi_nag.cam-dae (Overall: FAIL) details: diff --git a/src/control/scamMod.F90 b/src/control/scamMod.F90 index 425c7412e9..e26a2e63b9 100644 --- a/src/control/scamMod.F90 +++ b/src/control/scamMod.F90 @@ -388,8 +388,7 @@ subroutine scam_readnl(nlfile,single_column_in,scmlat_in,scmlon_in) end if end subroutine scam_readnl - -subroutine readiopdata(hvcoord) +subroutine readiopdata(hyam, hybm, hyai, hybi, ps0) !----------------------------------------------------------------------- ! ! Open and read netCDF file containing initial IOP conditions @@ -399,7 +398,6 @@ subroutine readiopdata(hvcoord) ! Written by J. Truesdale August, 1996, revised January, 1998 ! !----------------------------------------------------------------------- - use hybvcoord_mod, only: hvcoord_t use getinterpnetcdfdata, only: getinterpncdata use string_utils, only: to_lower use wrap_nf, only: wrap_inq_dimid,wrap_get_vara_realx @@ -410,7 +408,7 @@ subroutine readiopdata(hvcoord) ! !------------------------------Input Arguments-------------------------- ! -type (hvcoord_t), intent(in) :: hvcoord + real(r8),intent(in) :: hyam(plev),hybm(plev),hyai(plevp),hybi(plevp),ps0 ! !------------------------------Locals----------------------------------- ! @@ -430,7 +428,8 @@ subroutine readiopdata(hvcoord) logical :: have_cnst(pcnst) real(r8) :: dummy real(r8) :: srf(1) ! value at surface - real(r8) :: hyam(plev),hybm(plev) + real(r8) :: hyamiop(plev) ! a hybrid coef midpoint + real(r8) :: hybmiop(plev) ! b hybrid coef midpoint real(r8) :: pmid(plev) ! pressure at model levels (time n) real(r8) :: pint(plevp) ! pressure at model interfaces (n ) real(r8) :: pdel(plev) ! pdel(k) = pint (k+1)-pint (k) @@ -550,11 +549,11 @@ subroutine readiopdata(hvcoord) status = nf90_inq_varid( ncid, 'hyam', varid ) if ( status == nf90_noerr .and. have_ps) then call get_start_count(ncid, varid, scmlat, scmlon, ioptimeidx, strt4, cnt4) - status = nf90_get_var(ncid, varid, hyam, strt4) + status = nf90_get_var(ncid, varid, hyamiop, strt4) status = nf90_inq_varid( ncid, 'hybm', varid ) - status = nf90_get_var(ncid, varid, hybm, strt4) + status = nf90_get_var(ncid, varid, hybmiop, strt4) do i = 1, nlev - dplevs( i ) = 1000.0_r8 * hyam( i ) + psobs * hybm( i ) / 100.0_r8 + dplevs( i ) = 1000.0_r8 * hyamiop( i ) + psobs * hybmiop( i ) / 100.0_r8 end do endif @@ -643,11 +642,11 @@ subroutine readiopdata(hvcoord) if ( use_camiop ) then call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx,'t', have_tsair, & tsair(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm,tobs, status ) + dplevs, nlev,psobs, hyam, hybm,tobs, status ) else call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx,'T', have_tsair, & tsair(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, tobs, status ) + dplevs, nlev,psobs, hyam, hybm, tobs, status ) endif if ( status /= nf90_noerr ) then have_t = .false. @@ -695,7 +694,7 @@ subroutine readiopdata(hvcoord) qobs(:)= 0._r8 call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'q', have_srf, & srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, qobs, status ) + dplevs, nlev,psobs, hyam, hybm, qobs, status ) if ( status /= nf90_noerr ) then have_q = .false. if (masterproc) write(iulog,*) sub//':Could not find variable q on IOP file' @@ -710,7 +709,7 @@ subroutine readiopdata(hvcoord) cldobs = 0._r8 call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'cld', .false., & - dummy, fill_ends, scm_crm_mode, dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, cldobs, status ) + dummy, fill_ends, scm_crm_mode, dplevs, nlev,psobs, hyam, hybm, cldobs, status ) if ( status /= nf90_noerr ) then have_cld = .false. else @@ -719,7 +718,7 @@ subroutine readiopdata(hvcoord) clwpobs = 0._r8 call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'clwp', .false., & - dummy, fill_ends, scm_crm_mode, dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, clwpobs, status ) + dummy, fill_ends, scm_crm_mode, dplevs, nlev,psobs, hyam, hybm, clwpobs, status ) if ( status /= nf90_noerr ) then have_clwp = .false. else @@ -742,7 +741,7 @@ subroutine readiopdata(hvcoord) call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, & 'divq', have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, divq(:,1), status ) + dplevs, nlev,psobs, hyam, hybm, divq(:,1), status ) if ( status /= nf90_noerr ) then have_divq = .false. else @@ -765,7 +764,7 @@ subroutine readiopdata(hvcoord) call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'vertdivq', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, vertdivq(:,1), status ) + dplevs, nlev,psobs, hyam, hybm, vertdivq(:,1), status ) if ( status /= nf90_noerr ) then have_vertdivq = .false. else @@ -788,7 +787,7 @@ subroutine readiopdata(hvcoord) do m = 1, pcnst call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, trim(cnst_name(m))//'_dten', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, divq3d(:,m), status ) + dplevs, nlev,psobs, hyam, hybm, divq3d(:,m), status ) write(iulog,*)'checking ',trim(cnst_name(m))//'_dten',status if ( status /= nf90_noerr ) then have_cnst(m) = .false. @@ -801,7 +800,7 @@ subroutine readiopdata(hvcoord) coldata = 0._r8 call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, trim(cnst_name(m))//'_dqfx', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, coldata, status ) + dplevs, nlev,psobs, hyam, hybm, coldata, status ) if ( STATUS /= NF90_NOERR ) then dqfxcam(1,:,m)=0._r8 else @@ -811,7 +810,7 @@ subroutine readiopdata(hvcoord) tmpdata = 0._r8 call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, trim(cnst_name(m))//'_alph', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, tmpdata, status ) + dplevs, nlev,psobs, hyam, hybm, tmpdata, status ) if ( status /= nf90_noerr ) then alphacam(m)=0._r8 else @@ -827,7 +826,7 @@ subroutine readiopdata(hvcoord) have_srf = .false. call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'NUMLIQ', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, numliqobs, status ) + dplevs, nlev,psobs, hyam, hybm, numliqobs, status ) if ( status /= nf90_noerr ) then have_numliq = .false. else @@ -844,7 +843,7 @@ subroutine readiopdata(hvcoord) if ( icldliq > 0 ) then call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'CLDLIQ', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, cldliqobs, status ) + dplevs, nlev,psobs, hyam, hybm, cldliqobs, status ) if ( status /= nf90_noerr ) then have_cldliq = .false. else @@ -859,7 +858,7 @@ subroutine readiopdata(hvcoord) if ( icldice > 0 ) then call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'CLDICE', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, cldiceobs, status ) + dplevs, nlev,psobs, hyam, hybm, cldiceobs, status ) if ( status /= nf90_noerr ) then have_cldice = .false. else @@ -875,7 +874,7 @@ subroutine readiopdata(hvcoord) have_srf = .false. call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'NUMICE', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, numiceobs, status ) + dplevs, nlev,psobs, hyam, hybm, numiceobs, status ) if ( status /= nf90_noerr ) then have_numice = .false. else @@ -900,7 +899,7 @@ subroutine readiopdata(hvcoord) divu = 0._r8 call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'divu', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, divu, status ) + dplevs, nlev,psobs, hyam, hybm, divu, status ) if ( status /= nf90_noerr ) then have_divu = .false. else @@ -921,7 +920,7 @@ subroutine readiopdata(hvcoord) divv = 0._r8 call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'divv', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, divv, status ) + dplevs, nlev,psobs, hyam, hybm, divv, status ) if ( status /= nf90_noerr ) then have_divv = .false. else @@ -942,7 +941,7 @@ subroutine readiopdata(hvcoord) divt=0._r8 call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, & 'divT', have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, divt, status ) + dplevs, nlev,psobs, hyam, hybm, divt, status ) if ( status /= nf90_noerr ) then have_divt = .false. else @@ -964,11 +963,11 @@ subroutine readiopdata(hvcoord) vertdivt=0._r8 call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'vertdivTx', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, vertdivt, status ) + dplevs, nlev,psobs, hyam, hybm, vertdivt, status ) if ( status /= nf90_noerr ) then call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'vertdivT', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, vertdivt, status ) + dplevs, nlev,psobs, hyam, hybm, vertdivt, status ) if ( status /= nf90_noerr ) then have_vertdivt = .false. else @@ -994,7 +993,7 @@ subroutine readiopdata(hvcoord) call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'divT3d', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, divt3d, status ) + dplevs, nlev,psobs, hyam, hybm, divt3d, status ) write(iulog,*)'checking divT3d:',status,nf90_noerr if ( status /= nf90_noerr ) then have_divt3d = .false. @@ -1006,7 +1005,7 @@ subroutine readiopdata(hvcoord) call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'divU3d', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, divu3d, status ) + dplevs, nlev,psobs, hyam, hybm, divu3d, status ) if ( status /= nf90_noerr ) then have_divu3d = .false. else @@ -1017,7 +1016,7 @@ subroutine readiopdata(hvcoord) call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'divV3d', & have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, divv3d, status ) + dplevs, nlev,psobs, hyam, hybm, divv3d, status ) if ( status /= nf90_noerr ) then have_divv3d = .false. else @@ -1040,7 +1039,7 @@ subroutine readiopdata(hvcoord) call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, & 'omega', .true., ptend, fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, wfld, status ) + dplevs, nlev,psobs, hyam, hybm, wfld, status ) if ( status /= nf90_noerr ) then have_omega = .false. if (masterproc) write(iulog,*) sub//':Could not find variable omega on IOP' @@ -1052,7 +1051,7 @@ subroutine readiopdata(hvcoord) else have_omega = .true. endif - call plevs0(plev ,psobs ,pint,pmid ,pdel, hvcoord) + call plevs0(plev, psobs, ps0, hyam, hybm, hyai, hybi, pint, pmid ,pdel) ! ! Build interface vector for the specified omega profile ! (weighted average in pressure of specified level values) @@ -1077,7 +1076,7 @@ subroutine readiopdata(hvcoord) call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, & 'u', have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, uobs, status ) + dplevs, nlev,psobs, hyam, hybm, uobs, status ) if ( status /= nf90_noerr ) then have_u = .false. else @@ -1097,7 +1096,7 @@ subroutine readiopdata(hvcoord) call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, & 'v', have_srf, srf(1), fill_ends, scm_crm_mode, & - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, vobs, status ) + dplevs, nlev,psobs, hyam, hybm, vobs, status ) if ( status /= nf90_noerr ) then have_v = .false. else @@ -1117,7 +1116,7 @@ subroutine readiopdata(hvcoord) call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'Q1', & .false., dummy, fill_ends, scm_crm_mode, & ! datasets don't contain Q1 at surface - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, q1obs, status ) + dplevs, nlev,psobs, hyam, hybm, q1obs, status ) if ( status /= nf90_noerr ) then have_q1 = .false. else @@ -1128,7 +1127,7 @@ subroutine readiopdata(hvcoord) call getinterpncdata( ncid, scmlat, scmlon, ioptimeidx, 'Q2', & .false., dummy, fill_ends, scm_crm_mode, & ! datasets don't contain Q2 at surface - dplevs, nlev,psobs, hvcoord%hyam, hvcoord%hybm, q1obs, status ) + dplevs, nlev,psobs, hyam, hybm, q1obs, status ) if ( status /= nf90_noerr ) then have_q2 = .false. else @@ -1306,7 +1305,7 @@ end subroutine setiopupdate !=============================================================================== -subroutine plevs0 (nver ,ps ,pint ,pmid ,pdel, hvcoord) +subroutine plevs0 (nver, ps, ps0, hyam, hybm, hyai, hybi, pint ,pmid ,pdel) !----------------------------------------------------------------------- ! @@ -1317,18 +1316,20 @@ subroutine plevs0 (nver ,ps ,pint ,pmid ,pdel, hvcoord) ! Author: B. Boville ! !----------------------------------------------------------------------- - - use hybvcoord_mod, only : hvcoord_t implicit none !----------------------------------------------------------------------- integer , intent(in) :: nver ! vertical dimension real(r8), intent(in) :: ps ! Surface pressure (pascals) + real(r8), intent(in) :: ps0 ! reference pressure (pascals) + real(r8), intent(in) :: hyam(plev) ! hybrid midpoint coef + real(r8), intent(in) :: hybm(plev) ! hybrid midpoint coef + real(r8), intent(in) :: hyai(plevp) ! hybrid interface coef + real(r8), intent(in) :: hybi(plevp) ! hybrid interface coef real(r8), intent(out) :: pint(nver+1) ! Pressure at model interfaces real(r8), intent(out) :: pmid(nver) ! Pressure at model levels real(r8), intent(out) :: pdel(nver) ! Layer thickness (pint(k+1) - pint(k)) - type (hvcoord_t), intent(in) :: hvcoord !----------------------------------------------------------------------- !---------------------------Local workspace----------------------------- @@ -1339,14 +1340,14 @@ subroutine plevs0 (nver ,ps ,pint ,pmid ,pdel, hvcoord) ! !$OMP PARALLEL DO PRIVATE (K) do k=1,nver+1 - pint(k) = hvcoord%hyai(k)*hvcoord%ps0 + hvcoord%hybi(k)*ps + pint(k) = hyai(k)*ps0 + hybi(k)*ps end do ! ! Set midpoint pressures and layer thicknesses ! !$OMP PARALLEL DO PRIVATE (K) do k=1,nver - pmid(k) = hvcoord%hyam(k)*hvcoord%ps0 + hvcoord%hybm(k)*ps + pmid(k) = hyam(k)*ps0 + hybm(k)*ps pdel(k) = pint(k+1) - pint(k) end do diff --git a/src/dynamics/eul/dyn_comp.F90 b/src/dynamics/eul/dyn_comp.F90 index f9f19f8025..bb753fdd33 100644 --- a/src/dynamics/eul/dyn_comp.F90 +++ b/src/dynamics/eul/dyn_comp.F90 @@ -361,8 +361,8 @@ subroutine read_inidat() use ncdio_atm, only: infld use scamMod, only: setiopupdate,setiopupdate_init,readiopdata - use dyn_grid, only: hvcoord use iop, only: iop_update_prognostics + use hycoef, only: hyam, hybm, hyai, hybi, ps0 ! Local variables integer i,c,m,n,lat ! indices @@ -578,7 +578,7 @@ subroutine read_inidat() loniop(1)=(mod(scmlon-2.0_r8+360.0_r8,360.0_r8))*pi/180.0_r8 loniop(2)=(mod(scmlon+2.0_r8+360.0_r8,360.0_r8))*pi/180.0_r8 call setiopupdate() - call readiopdata(hvcoord) + call readiopdata(hyam,hybm,hyai,hybi,ps0) call iop_update_prognostics(1,t3=t3,u3=u3,v3=v3,q3=q3,ps=ps) end if end if diff --git a/src/dynamics/eul/dyn_grid.F90 b/src/dynamics/eul/dyn_grid.F90 index c9036b54ee..62d3d73f0c 100644 --- a/src/dynamics/eul/dyn_grid.F90 +++ b/src/dynamics/eul/dyn_grid.F90 @@ -17,7 +17,6 @@ module dyn_grid use cam_abortutils, only: endrun use cam_logfile, only: iulog -use hybvcoord_mod, only: hvcoord_t use shr_const_mod, only: SHR_CONST_PI, SHR_CONST_REARTH #if (defined SPMD) @@ -49,7 +48,6 @@ module dyn_grid ! from a given global column index get_horiz_grid_d, &! horizontal grid coordinates get_horiz_grid_dim_d, &! horizontal dimensions of dynamics grid - hvcoord, &! vertical coordinate parameters physgrid_copy_attributes_d ! The Eulerian dynamics grids @@ -61,8 +59,6 @@ module dyn_grid integer :: ngcols_d = 0 ! number of dynamics columns -type (hvcoord_t) :: hvcoord - !======================================================================================== contains !======================================================================================== @@ -131,15 +127,6 @@ subroutine dyn_grid_init ! Initialize hybrid coordinate arrays call hycoef_init(fh_ini) - hvcoord%hyam = hyam - hvcoord%hyai = hyai - hvcoord%hybm = hybm - hvcoord%hybi = hybi - hvcoord%ps0 = ps0 - do k = 1, plev - hvcoord%hybd(k) = hvcoord%hybi(k+1) - hvcoord%hybi(k) - end do - ! Initialize reference pressures call ref_pres_init(hypi, hypm, nprlev) diff --git a/src/dynamics/eul/stepon.F90 b/src/dynamics/eul/stepon.F90 index b19caa605c..4c86f1d27e 100644 --- a/src/dynamics/eul/stepon.F90 +++ b/src/dynamics/eul/stepon.F90 @@ -22,7 +22,6 @@ module stepon use aerosol_properties_mod, only: aerosol_properties use aerosol_state_mod, only: aerosol_state use microp_aero, only: aerosol_state_object, aerosol_properties_object - use dyn_grid, only: hvcoord implicit none private @@ -293,6 +292,7 @@ subroutine stepon_run3( ztodt, cam_out, phys_state, dyn_in, dyn_out ) use eul_control_mod,only: eul_nsplit use prognostics, only: ps use iop, only: iop_update_prognostics + use hycoef, only: hyam, hybm, hyai, hybi, ps0 real(r8), intent(in) :: ztodt ! twice time step unless nstep=0 type(cam_out_t), intent(inout) :: cam_out(begchunk:endchunk) @@ -312,7 +312,7 @@ subroutine stepon_run3( ztodt, cam_out, phys_state, dyn_in, dyn_out ) ! Read IOP data and update prognostics if needed if (doiopupdate) then - call readiopdata(hvcoord) + call readiopdata(hyam, hybm, hyai, hybi, ps0) call iop_update_prognostics(n3,ps=ps) end if endif diff --git a/src/dynamics/se/apply_iop_forcing.F90 b/src/dynamics/se/apply_iop_forcing.F90 index dbb52ac1cb..06e2a48472 100644 --- a/src/dynamics/se/apply_iop_forcing.F90 +++ b/src/dynamics/se/apply_iop_forcing.F90 @@ -71,7 +71,7 @@ subroutine advance_iop_forcing(scm_dt, ps_in, & ! In character(len=*), parameter :: subname = 'advance_iop_forcing' ! Get vertical level profiles - call plevs0(plev ,ps_in ,pintm1 ,pmidm1 ,pdelm1, hvcoord) + call plevs0(plev, ps_in, hvcoord%ps0, hvcoord%hyam, hvcoord%hybm, hvcoord%hyai, hvcoord%hybi, pintm1 ,pmidm1 ,pdelm1) ! Advance T and Q due to large scale forcing if (use_3dfrc) then @@ -173,7 +173,7 @@ subroutine advance_iop_nudging(ztodt, ps_in, & ! In if ( .not. scm_relaxation) return - call plevs0(plev ,ps_in ,pintm1 ,pmidm1 ,pdelm1, hvcoord) + call plevs0(plev, ps_in, hvcoord%ps0, hvcoord%hyam, hvcoord%hybm, hvcoord%hyai, hvcoord%hybi, pintm1 ,pmidm1 ,pdelm1) relax_T(:) = 0._r8 relax_u(:) = 0._r8 diff --git a/src/dynamics/se/dyn_comp.F90 b/src/dynamics/se/dyn_comp.F90 index b4493d7f96..586ee06b1f 100644 --- a/src/dynamics/se/dyn_comp.F90 +++ b/src/dynamics/se/dyn_comp.F90 @@ -11,7 +11,7 @@ module dyn_comp use cam_control_mod, only: initial_run use cam_initfiles, only: initial_file_get_id, topo_file_get_id, pertlim use phys_control, only: use_gw_front, use_gw_front_igw -use dyn_grid, only: ini_grid_name, timelevel, edgebuf, & +use dyn_grid, only: ini_grid_name, timelevel, hvcoord, edgebuf, & ini_grid_hdim_name use cam_grid_support, only: cam_grid_id, cam_grid_get_gcid, & @@ -48,7 +48,7 @@ module dyn_comp use bndry_mod, only: bndry_exchange use se_single_column_mod, only: scm_setinitial use scamMod, only: single_column, readiopdata, use_iop, setiopupdate_init -use hycoef, only: hyai, hybi, ps0, hvcoord +use hycoef, only: hyai, hybi, ps0 implicit none private @@ -753,7 +753,7 @@ subroutine dyn_init(dyn_in, dyn_out) call read_inidat(dyn_in) if (use_iop .and. masterproc) then call setiopupdate_init() - call readiopdata( hvcoord ) + call readiopdata( hvcoord%hyam, hvcoord%hybm, hvcoord%hyai, hvcoord%hybi, hvcoord%ps0 ) call scm_setinitial(dyn_in%elem) end if call clean_iodesc_list() @@ -1195,6 +1195,7 @@ end subroutine dyn_final subroutine read_inidat(dyn_in) use air_composition, only: thermodynamic_active_species_num, dry_air_species_num use shr_sys_mod, only: shr_sys_flush + use hycoef, only: hyai, hybi, ps0 use const_init, only: cnst_init_default use element_mod, only: timelevels diff --git a/src/dynamics/se/dyn_grid.F90 b/src/dynamics/se/dyn_grid.F90 index 300564ce07..69d9bbc520 100644 --- a/src/dynamics/se/dyn_grid.F90 +++ b/src/dynamics/se/dyn_grid.F90 @@ -44,6 +44,7 @@ module dyn_grid use dimensions_mod, only: ne, np, npsq, fv_nphys, nlev, use_cslam use element_mod, only: element_t use fvm_control_volume_mod, only: fvm_struct +use hybvcoord_mod, only: hvcoord_t use prim_init, only: prim_init1 use edge_mod, only: initEdgeBuffer use edgetype_mod, only: EdgeBuffer_t @@ -67,6 +68,7 @@ module dyn_grid integer, parameter :: ptimelevels = 2 type (TimeLevel_t) :: TimeLevel ! main time level struct (used by tracers) +type (hvcoord_t) :: hvcoord type(element_t), pointer :: elem(:) => null() ! local GLL elements for this task type(fvm_struct), pointer :: fvm(:) => null() ! local FVM elements for this task @@ -75,6 +77,7 @@ module dyn_grid public :: ini_grid_hdim_name public :: ptimelevels public :: TimeLevel +public :: hvcoord public :: elem public :: fvm public :: edgebuf @@ -119,7 +122,8 @@ subroutine dyn_grid_init() ! Initialize SE grid, and decomposition. - use hycoef, only: hycoef_init, hypi, hypm, nprlev + use hycoef, only: hycoef_init, hypi, hypm, nprlev, & + hyam, hybm, hyai, hybi, ps0 use ref_pres, only: ref_pres_init use spmd_utils, only: MPI_MAX, MPI_INTEGER, mpicom use time_manager, only: get_nstep, get_step_size @@ -159,6 +163,15 @@ subroutine dyn_grid_init() ! Initialize hybrid coordinate arrays call hycoef_init(fh_ini, psdry=.true.) + hvcoord%hyam = hyam + hvcoord%hyai = hyai + hvcoord%hybm = hybm + hvcoord%hybi = hybi + hvcoord%ps0 = ps0 + do k = 1, nlev + hvcoord%hybd(k) = hvcoord%hybi(k+1) - hvcoord%hybi(k) + end do + ! Initialize reference pressures call ref_pres_init(hypi, hypm, nprlev) diff --git a/src/dynamics/se/gravity_waves_sources.F90 b/src/dynamics/se/gravity_waves_sources.F90 index 2f8ed10392..a929dfeaf1 100644 --- a/src/dynamics/se/gravity_waves_sources.F90 +++ b/src/dynamics/se/gravity_waves_sources.F90 @@ -115,7 +115,7 @@ subroutine compute_frontogenesis(frontgf,frontga,tl,tlq,elem,ederiv,hybrid,nets, use derivative_mod, only: gradient_sphere, ugradv_sphere use edge_mod, only: edgevpack, edgevunpack use bndry_mod, only: bndry_exchange - use hycoef, only: hvcoord + use dyn_grid, only: hvcoord use dimensions_mod, only: fv_nphys,ntrac use fvm_mapping, only: dyn2phys_vector,dyn2phys diff --git a/src/dynamics/se/se_single_column_mod.F90 b/src/dynamics/se/se_single_column_mod.F90 index f6b19f09b4..1653b2e43e 100644 --- a/src/dynamics/se/se_single_column_mod.F90 +++ b/src/dynamics/se/se_single_column_mod.F90 @@ -324,7 +324,7 @@ subroutine scm_dyn_grid_indicies(elem,scmlat,scmlon,ie_scm,i_scm,j_scm,indx_scm) ! based on the input scm latitude and longitude !---------------------------------------------------------- - use shr_const_mod, only: pi => SHR_CONST_PI + use shr_const_mod, only: SHR_CONST_PI use cam_abortutils, only: endrun type(element_t), intent(in) :: elem(:) @@ -334,7 +334,7 @@ subroutine scm_dyn_grid_indicies(elem,scmlat,scmlon,ie_scm,i_scm,j_scm,indx_scm) integer :: i, j, indx, ie real(r8) :: scmposlon, minpoint, testlat, testlon, testval integer :: ierr - real(r8), parameter :: rad2deg = 180.0_r8 / pi + real(r8), parameter :: rad2deg = 180.0_r8 / SHR_CONST_PI character(len=*), parameter :: sub = 'scm_dyn_grid_indicies' ie_scm=0 diff --git a/src/dynamics/se/stepon.F90 b/src/dynamics/se/stepon.F90 index 98482ff1c8..2d49a434cc 100644 --- a/src/dynamics/se/stepon.F90 +++ b/src/dynamics/se/stepon.F90 @@ -19,7 +19,7 @@ module stepon use scamMod, only: use_iop, doiopupdate, single_column, & setiopupdate, readiopdata use se_single_column_mod, only: scm_setfield, iop_broadcast -use hycoef, only: hvcoord +use dyn_grid, only: hvcoord use time_manager, only: get_step_size, is_first_restart_step use cam_history, only: outfld, write_camiop, addfld, add_default, horiz_only use cam_history, only: write_inithist, hist_fld_active, fieldname_len @@ -141,13 +141,13 @@ subroutine stepon_run1( dtime_out, phys_state, phys_tend, & ! If first restart step then ensure that IOP data is read if (is_first_restart_step()) then - if (masterproc) call readiopdata( hvcoord ) + if (masterproc) call readiopdata( hvcoord%hyam, hvcoord%hybm, hvcoord%hyai, hvcoord%hybi, hvcoord%ps0 ) call iop_broadcast() endif iop_update_phase1 = .true. if ((is_first_restart_step() .or. doiopupdate) .and. masterproc) then - call readiopdata(hvcoord) + call readiopdata( hvcoord%hyam, hvcoord%hybm, hvcoord%hyai, hvcoord%hybi, hvcoord%ps0 ) endif call iop_broadcast() @@ -256,7 +256,7 @@ subroutine stepon_run3(dtime, cam_out, phys_state, dyn_in, dyn_out) ! Update IOP properties e.g. omega, divT, divQ iop_update_phase1 = .false. if (doiopupdate) then - if (masterproc) call readiopdata(hvcoord) + if (masterproc) call readiopdata( hvcoord%hyam, hvcoord%hybm, hvcoord%hyai, hvcoord%hybi, hvcoord%ps0 ) call iop_broadcast() call scm_setfield(dyn_out%elem,iop_update_phase1) endif diff --git a/src/utils/hybvcoord_mod.F90 b/src/utils/hybvcoord_mod.F90 deleted file mode 100644 index 1dbc6a33db..0000000000 --- a/src/utils/hybvcoord_mod.F90 +++ /dev/null @@ -1,28 +0,0 @@ -module hybvcoord_mod - use shr_kind_mod, only: r8=>shr_kind_r8 - use cam_logfile, only: iulog - use pmgrid, only: plev, plevp - use physconst, only: pstd - - implicit none - private - - !----------------------------------------------------------------------- - ! hvcoord_t: Hybrid level definitions: p = a*p0 + b*ps - ! interfaces p(k) = hyai(k)*ps0 + hybi(k)*ps - ! midpoints p(k) = hyam(k)*ps0 + hybm(k)*ps - !----------------------------------------------------------------------- - type, public :: hvcoord_t - real(r8) ps0 ! base state surface-pressure for level definitions - real(r8) hyai(plevp) ! ps0 component of hybrid coordinate - interfaces - real(r8) hyam(plev) ! ps0 component of hybrid coordinate - midpoints - real(r8) hybi(plevp) ! ps component of hybrid coordinate - interfaces - real(r8) hybm(plev) ! ps component of hybrid coordinate - midpoints - real(r8) hybd(plev) ! difference in b (hybi) across layers - real(r8) prsfac ! log pressure extrapolation factor (time, space independent) - real(r8) etam(plev) ! eta-levels at midpoints - real(r8) etai(plevp) ! eta-levels at interfaces - integer nprlev ! number of pure pressure levels at top - integer pad - end type hvcoord_t -end module hybvcoord_mod diff --git a/src/utils/hycoef.F90 b/src/utils/hycoef.F90 index 455875edee..241abf5c7e 100644 --- a/src/utils/hycoef.F90 +++ b/src/utils/hycoef.F90 @@ -10,7 +10,6 @@ module hycoef pio_double, pio_def_dim, pio_def_var, & pio_put_var, pio_get_var, & pio_seterrorhandling, PIO_BCAST_ERROR, PIO_NOERR -use hybvcoord_mod, only: hvcoord_t implicit none private @@ -53,8 +52,6 @@ module hycoef public hycoef_init -type (hvcoord_t),public :: hvcoord - type(var_desc_t) :: hyam_desc, hyai_desc, hybm_desc, hybi_desc, p0_desc public init_restart_hycoef, write_restart_hycoef @@ -248,14 +245,6 @@ subroutine hycoef_init(file, psdry) formula_terms=formula_terms) end if - ! Initialize the hvcoord coordinate - hvcoord%hyam = hyam - hvcoord%hyai = hyai - hvcoord%hybm = hybm - hvcoord%hybi = hybi - hvcoord%hybd = hybd - hvcoord%ps0 = ps0 - if (masterproc) then write(iulog,'(a)')' Layer Locations (*1000) ' do k=1,plev