diff --git a/atmos_model.F90 b/atmos_model.F90 index 7105f6997..7e19fee3d 100644 --- a/atmos_model.F90 +++ b/atmos_model.F90 @@ -2349,6 +2349,266 @@ subroutine assign_importdata(jdat, rc) endif endif +! get surface snow area fraction: over land (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_snow_area_fraction_lnd' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%sncovr1_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get snow area fraction from land' + endif + endif + +! get latent heat flux: over land (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_laten_heat_flx_lnd' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%evap_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get latent heat flux from land' + endif + endif + +! get sensible heat flux: over land (if cpllnd=true and cpllnd2atm=true) +!-------------------------------------------------- + fldname = 'inst_sensi_heat_flx_lnd' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%hflx_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get sensible heat flux from land' + endif + endif + +! get surface upward potential latent heat flux: over land (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_potential_laten_heat_flx_lnd' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%ep_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get potential latent heat flux from land' + endif + endif + +! get 2m air temperature: over land (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_temp_height2m_lnd' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%t2mmp_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get temperature at 2m from land' + endif + endif + +! get 2m specific humidity: over land (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_spec_humid_height2m_lnd' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%q2mp_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get specific humidity at 2m from land' + endif + endif + +! get specific humidity: over land (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_spec_humid_lnd' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%qsurf_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get specific humidity from land' + endif + endif + +! get upward heat flux in soil (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_upward_heat_flux_lnd' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%gflux_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get upward heat flux from land' + endif + endif + +! get surface runoff in soil (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_runoff_rate_lnd' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%runoff_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get surface runoff from land' + endif + endif + +! get subsurface runoff in soil (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_subsurface_runoff_rate_lnd' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%drain_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get subsurface runoff from land' + endif + endif + +! get momentum exchange coefficient (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_drag_wind_speed_for_momentum' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%cmm_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get drag wind speed for momentum from land' + endif + endif + +! get thermal exchange coefficient (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_drag_mass_flux_for_heat_and_moisture' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%chh_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get thermal exchange coefficient form land' + endif + endif + +! get function of surface roughness length and green vegetation fraction (if cpllnd=true and cpllnd2atm=true) +!------------------------------------------------ + fldname = 'inst_func_of_roughness_length_and_vfrac' + if (trim(impfield_name) == trim(fldname)) then + findex = queryImportFields(fldname) + if (importFieldsValid(findex) .and. GFS_control%cpllnd .and. GFS_control%cpllnd2atm) then +!$omp parallel do default(shared) private(i,j,nb,ix) + do j=jsc,jec + do i=isc,iec + nb = Atm_block%blkno(i,j) + ix = Atm_block%ixp(i,j) + if (GFS_data(nb)%Sfcprop%landfrac(ix) > zero) then + GFS_data(nb)%Coupling%zvfun_lnd(ix) = datar8(i,j) + endif + enddo + enddo + if (mpp_pe() == mpp_root_pe() .and. debug) print *,'fv3 assign_import: get func. of roughness length and vfrac form land' + endif + endif + endif ! if (datar8(isc,jsc) > -99999.0) then !------------------------------------------------------- @@ -3072,12 +3332,6 @@ subroutine setup_exportdata(rc) ! bottom layer meridional wind (v) case('inst_merid_wind_height_lowest') call block_data_copy_or_fill(datar82d, DYCORE_data(nb)%coupling%v_bot, zeror8, Atm_block, nb, rc=localrc) - ! bottom layer zonal wind (u) from physics - case('inst_zonal_wind_height_lowest_from_phys') - call block_data_copy_or_fill(datar82d, GFS_data(nb)%Statein%ugrs, 1, zeror8, Atm_block, nb, rc=localrc) - ! bottom layer meridional wind (v) from physics - case('inst_merid_wind_height_lowest_from_phys') - call block_data_copy_or_fill(datar82d, GFS_data(nb)%Statein%vgrs, 1, zeror8, Atm_block, nb, rc=localrc) ! surface friction velocity case('surface_friction_velocity') call block_data_copy_or_fill(datar82d, GFS_data(nb)%Sfcprop%uustar, zeror8, Atm_block, nb, rc=localrc) diff --git a/ccpp/config/ccpp_prebuild_config.py b/ccpp/config/ccpp_prebuild_config.py index 1ed2c6245..b27e5a2f6 100755 --- a/ccpp/config/ccpp_prebuild_config.py +++ b/ccpp/config/ccpp_prebuild_config.py @@ -192,6 +192,7 @@ 'physics/physics/SFC_Layer/UFS/sfc_nst_post.f90', 'physics/physics/SFC_Models/Land/RUC/lsm_ruc.F90', 'physics/physics/SFC_Models/SeaIce/CICE/sfc_cice.f', + 'physics/physics/SFC_Models/Land/sfc_land.F90', 'physics/physics/SFC_Models/Land/Noah/lsm_noah.f', 'physics/physics/SFC_Models/Land/Noahmp/noahmpdrv.F90', 'physics/physics/SFC_Models/Lake/Flake/flake_driver.F90', diff --git a/ccpp/data/GFS_typedefs.F90 b/ccpp/data/GFS_typedefs.F90 index 5a8368a40..b0e816baf 100644 --- a/ccpp/data/GFS_typedefs.F90 +++ b/ccpp/data/GFS_typedefs.F90 @@ -458,15 +458,18 @@ module GFS_typedefs real (kind=kind_phys), pointer :: emanoc (:) => null() !< instantaneous anthro. oc emission !--- Smoke. These 2 arrays are input smoke emission and frp - real (kind=kind_phys), pointer :: ebb_smoke_in(:) => null() !< input smoke emission - real (kind=kind_phys), pointer :: frp_input (:) => null() !< input FRP - + real (kind=kind_phys), pointer :: ebb_smoke_in(:) => null() !< input smoke emission + real (kind=kind_phys), pointer :: frp_output (:) => null() !< output FRP !--- For fire diurnal cycle real (kind=kind_phys), pointer :: fhist (:) => null() !< instantaneous fire coef_bb real (kind=kind_phys), pointer :: coef_bb_dc (:) => null() !< instantaneous fire coef_bb + integer, pointer :: fire_type (:) => null() !< fire type + real (kind=kind_phys), pointer :: peak_hr (:) => null() !< peak hour of fire emissions + real (kind=kind_phys), pointer :: lu_nofire (:) => null() ! null() ! null() !< heat flux from wildfire - real (kind=kind_phys), pointer :: frac_grid_burned_out (:) => null() !< fraction of grid cell burning + real (kind=kind_phys), pointer :: fire_heat_flux (:) => null() !< heat flux from wildfire + real (kind=kind_phys), pointer :: frac_grid_burned (:) => null() !< fraction of grid cell burning !--- For smoke and dust auxiliary inputs real (kind=kind_phys), pointer :: fire_in (:,:) => null() !< fire auxiliary inputs @@ -536,6 +539,20 @@ module GFS_typedefs real (kind=kind_phys), pointer :: dtsfcin_med(:) => null() !< sfc latent heat flux over ocean real (kind=kind_phys), pointer :: dqsfcin_med(:) => null() !< sfc sensible heat flux over ocean real (kind=kind_phys), pointer :: ulwsfcin_med(:) => null() !< sfc upward lw flux over ocean + !--- variables needed for cpllnd = .TRUE. and cpllnd2atm=.TRUE. + real (kind=kind_phys), pointer :: sncovr1_lnd(:) => null() !< sfc snow area fraction over land + real (kind=kind_phys), pointer :: qsurf_lnd(:) => null() !< sfc specific humidity + real (kind=kind_phys), pointer :: evap_lnd(:) => null() !< sfc latent heat flux over land, converted to evaporative flux + real (kind=kind_phys), pointer :: hflx_lnd(:) => null() !< sfc sensible heat flux over land + real (kind=kind_phys), pointer :: ep_lnd(:) => null() !< sfc up pot latent heat flux over land + real (kind=kind_phys), pointer :: t2mmp_lnd(:) => null() !< 2 meter temperature over land + real (kind=kind_phys), pointer :: q2mp_lnd(:) => null() !< 2 meter spec humidity over land + real (kind=kind_phys), pointer :: gflux_lnd(:) => null() !< soil heat flux over land + real (kind=kind_phys), pointer :: runoff_lnd(:) => null() !< surface runoff over land + real (kind=kind_phys), pointer :: drain_lnd(:) => null() !< subsurface runoff over land + real (kind=kind_phys), pointer :: cmm_lnd(:) => null() !< surface drag wind speed for momentum + real (kind=kind_phys), pointer :: chh_lnd(:) => null() !< surface drag mass flux for heat and moisture + real (kind=kind_phys), pointer :: zvfun_lnd(:) => null() !< function of surface roughness length and green vegetation fraction !--- outgoing accumulated quantities real (kind=kind_phys), pointer :: rain_cpl (:) => null() !< total rain precipitation @@ -616,10 +633,6 @@ module GFS_typedefs !--- For fire diurnal cycle real (kind=kind_phys), pointer :: ebu_smoke (:,:) => null() !< 3D ebu array - !--- For smoke and dust optical extinction - real (kind=kind_phys), pointer :: smoke_ext (:,:) => null() !< 3D aod array - real (kind=kind_phys), pointer :: dust_ext (:,:) => null() !< 3D aod array - !--- For MYNN PBL transport of smoke and dust real (kind=kind_phys), pointer :: chem3d (:,:,:) => null() !< 3D aod array real (kind=kind_phys), pointer :: ddvel (:,: ) => null() !< 2D dry deposition velocity @@ -633,6 +646,8 @@ module GFS_typedefs !--- Fire plume rise diagnostics real (kind=kind_phys), pointer :: min_fplume (:) => null() !< minimum plume rise level real (kind=kind_phys), pointer :: max_fplume (:) => null() !< maximum plume rise level + real (kind=kind_phys), pointer :: uspdavg (:) => null() !< BL average wind speed + real (kind=kind_phys), pointer :: hpbl_thetav (:) => null() !< BL depth parcel method !--- hourly fire potential index real (kind=kind_phys), pointer :: rrfs_hwp (:) => null() !< hourly fire potential index real (kind=kind_phys), pointer :: rrfs_hwp_ave (:) => null() !< *Average* hourly fire potential index @@ -741,6 +756,7 @@ module GFS_typedefs logical :: cplaqm !< default no cplaqm collection logical :: cplchm !< default no cplchm collection logical :: cpllnd !< default no cpllnd collection + logical :: cpllnd2atm !< default no lnd->atm coupling logical :: rrfs_sd !< default no rrfs_sd collection logical :: use_cice_alb !< default .false. - i.e. don't use albedo imported from the ice model logical :: cpl_imp_mrg !< default no merge import with internal forcings @@ -1528,6 +1544,7 @@ module GFS_typedefs logical :: do_plumerise integer :: addsmoke_flag integer :: plumerisefire_frq + integer :: n_dbg_lines integer :: smoke_forecast logical :: aero_ind_fdb ! WFA/IFA indirect logical :: aero_dir_fdb ! smoke/dust direct @@ -2688,8 +2705,8 @@ subroutine sfcprop_create (Sfcprop, IM, Model) allocate (Sfcprop%acsnow_land (IM)) allocate (Sfcprop%acsnow_ice (IM)) allocate (Sfcprop%xlaixy (IM)) - allocate (Sfcprop%fire_heat_flux_out (IM)) - allocate (Sfcprop%frac_grid_burned_out (IM)) + allocate (Sfcprop%fire_heat_flux (IM)) + allocate (Sfcprop%frac_grid_burned(IM)) ! Sfcprop%wetness = clear_val @@ -2710,8 +2727,8 @@ subroutine sfcprop_create (Sfcprop, IM, Model) Sfcprop%acsnow_land = clear_val Sfcprop%acsnow_ice = clear_val Sfcprop%xlaixy = clear_val - Sfcprop%fire_heat_flux_out = clear_val - Sfcprop%frac_grid_burned_out = clear_val + Sfcprop%fire_heat_flux = clear_val + Sfcprop%frac_grid_burned= clear_val ! end if @@ -2805,9 +2822,13 @@ subroutine sfcprop_create (Sfcprop, IM, Model) allocate (Sfcprop%emseas (IM)) allocate (Sfcprop%emanoc (IM)) allocate (Sfcprop%ebb_smoke_in (IM)) - allocate (Sfcprop%frp_input (IM)) + allocate (Sfcprop%frp_output (IM)) allocate (Sfcprop%fhist (IM)) allocate (Sfcprop%coef_bb_dc(IM)) + allocate (Sfcprop%fire_type (IM)) + allocate (Sfcprop%peak_hr (IM)) + allocate (Sfcprop%lu_nofire (IM)) + allocate (Sfcprop%lu_qfire (IM)) allocate (Sfcprop%fire_in (IM,Model%fire_aux_data_levels)) ! IMPORTANT: This initialization must match rrfs_sd_fill_data @@ -2815,10 +2836,14 @@ subroutine sfcprop_create (Sfcprop, IM, Model) Sfcprop%emseas = clear_val Sfcprop%emanoc = clear_val Sfcprop%ebb_smoke_in = clear_val - Sfcprop%frp_input = clear_val + Sfcprop%frp_output = clear_val Sfcprop%fhist = 1. Sfcprop%coef_bb_dc = clear_val + Sfcprop%fire_type = 0 Sfcprop%fire_in = clear_val + Sfcprop%peak_hr = clear_val + Sfcprop%lu_nofire = clear_val + Sfcprop%lu_qfire = clear_val endif end subroutine sfcprop_create @@ -3041,7 +3066,38 @@ subroutine coupling_create (Coupling, IM, Model) Coupling%slmsk_cpl = clear_val !< pointer to sfcprop%slmsk endif - !-- cellular automata + ! -- Coupling options to retrive land fluxes from external land component + if (Model%cpllnd .and. Model%cpllnd2atm) then + allocate (Coupling%sncovr1_lnd (IM)) + allocate (Coupling%qsurf_lnd (IM)) + allocate (Coupling%evap_lnd (IM)) + allocate (Coupling%hflx_lnd (IM)) + allocate (Coupling%ep_lnd (IM)) + allocate (Coupling%t2mmp_lnd (IM)) + allocate (Coupling%q2mp_lnd (IM)) + allocate (Coupling%gflux_lnd (IM)) + allocate (Coupling%runoff_lnd (IM)) + allocate (Coupling%drain_lnd (IM)) + allocate (Coupling%cmm_lnd (IM)) + allocate (Coupling%chh_lnd (IM)) + allocate (Coupling%zvfun_lnd (IM)) + + Coupling%sncovr1_lnd = clear_val + Coupling%qsurf_lnd = clear_val + Coupling%evap_lnd = clear_val + Coupling%hflx_lnd = clear_val + Coupling%ep_lnd = clear_val + Coupling%t2mmp_lnd = clear_val + Coupling%q2mp_lnd = clear_val + Coupling%gflux_lnd = clear_val + Coupling%runoff_lnd = clear_val + Coupling%drain_lnd = clear_val + Coupling%cmm_lnd = clear_val + Coupling%chh_lnd = clear_val + Coupling%zvfun_lnd = clear_val + end if + + !-- cellular automata allocate (Coupling%condition(IM)) if (Model%do_ca) then allocate (Coupling%ca1 (IM)) @@ -3157,8 +3213,6 @@ subroutine coupling_create (Coupling, IM, Model) if(Model%rrfs_sd) then !--- needed for smoke aerosol option allocate (Coupling%ebu_smoke (IM,Model%levs)) - allocate (Coupling%smoke_ext (IM,Model%levs)) - allocate (Coupling%dust_ext (IM,Model%levs)) allocate (Coupling%chem3d (IM,Model%levs,Model%nchem)) allocate (Coupling%ddvel (IM,Model%ndvel)) allocate (Coupling%wetdpc_flux(IM,Model%nchem)) @@ -3166,11 +3220,11 @@ subroutine coupling_create (Coupling, IM, Model) allocate (Coupling%drydep_flux(IM,Model%ndvel)) allocate (Coupling%min_fplume(IM)) allocate (Coupling%max_fplume(IM)) + allocate (Coupling%uspdavg(IM)) + allocate (Coupling%hpbl_thetav(IM)) allocate (Coupling%rrfs_hwp (IM)) allocate (Coupling%rrfs_hwp_ave (IM)) Coupling%ebu_smoke = clear_val - Coupling%smoke_ext = clear_val - Coupling%dust_ext = clear_val Coupling%chem3d = clear_val Coupling%ddvel = clear_val Coupling%wetdpc_flux = clear_val @@ -3178,6 +3232,8 @@ subroutine coupling_create (Coupling, IM, Model) Coupling%drydep_flux = clear_val Coupling%min_fplume = clear_val Coupling%max_fplume = clear_val + Coupling%uspdavg = clear_val + Coupling%hpbl_thetav = clear_val Coupling%rrfs_hwp = clear_val Coupling%rrfs_hwp_ave = clear_val endif @@ -3281,6 +3337,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & logical :: cplaqm = .false. !< default no cplaqm collection logical :: cplchm = .false. !< default no cplchm collection logical :: cpllnd = .false. !< default no cpllnd collection + logical :: cpllnd2atm = .false. !< default no cpllnd2atm coupling logical :: rrfs_sd = .false. !< default no rrfs_sd collection logical :: use_cice_alb = .false. !< default no cice albedo logical :: cpl_imp_mrg = .false. !< default no merge import with internal forcings @@ -3865,11 +3922,11 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & real(kind=kind_phys) :: dust_moist_correction = 1.0 real(kind=kind_phys) :: dust_alpha = 0. real(kind=kind_phys) :: dust_gamma = 0. - real(kind=kind_phys) :: wetdep_ls_alpha = 0. + real(kind=kind_phys) :: wetdep_ls_alpha = 0.5 integer :: dust_moist_opt = 1 ! fecan :1 else shao integer :: ebb_dcycle = 1 ! 1:retro; 2:forecast integer :: seas_opt = 2 - integer :: dust_opt = 5 + integer :: dust_opt = 1 integer :: drydep_opt = 1 integer :: coarsepm_settling = 1 integer :: plume_wind_eff = 1 @@ -3878,6 +3935,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & logical :: do_plumerise = .false. integer :: addsmoke_flag = 1 integer :: plumerisefire_frq = 60 + integer :: n_dbg_lines = 3 integer :: smoke_forecast = 0 ! RRFS-sd read in ebb_smoke logical :: aero_ind_fdb = .false. ! RRFS-sd wfa/ifa emission logical :: aero_dir_fdb = .false. ! RRFS-sd smoke/dust radiation feedback @@ -3914,8 +3972,8 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & thermodyn_id, sfcpress_id, & !--- coupling parameters cplflx, cplice, cplocn2atm, cplwav, cplwav2atm, cplaqm, & - cplchm, cpllnd, cpl_imp_mrg, cpl_imp_dbg, rrfs_sd, & - use_cice_alb, & + cplchm, cpllnd, cpllnd2atm, cpl_imp_mrg, cpl_imp_dbg, & + rrfs_sd, use_cice_alb, & #ifdef IDEA_PHYS lsidea, weimer_model, f107_kp_size, f107_kp_interval, & f107_kp_skip_size, f107_kp_data_size, f107_kp_read_in_start, & @@ -4049,7 +4107,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & wetdep_ls_opt, smoke_forecast, aero_ind_fdb, aero_dir_fdb, & rrfs_smoke_debug, do_plumerise, plumerisefire_frq, & addsmoke_flag, enh_mix, mix_chem, smoke_dir_fdb_coef, & - do_smoke_transport,smoke_conv_wet_coef, & + do_smoke_transport,smoke_conv_wet_coef,n_dbg_lines, & !--- C3/GF closures ichoice,ichoicem,ichoice_s, & !--- (DFI) time ranges with radar-prescribed microphysics tendencies @@ -4260,6 +4318,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%cplaqm = cplaqm Model%cplchm = cplchm .or. cplaqm Model%cpllnd = cpllnd + Model%cpllnd2atm = cpllnd2atm Model%use_cice_alb = use_cice_alb Model%cpl_imp_mrg = cpl_imp_mrg Model%cpl_imp_dbg = cpl_imp_dbg @@ -4282,6 +4341,7 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & Model%extended_sd_diags = extended_sd_diags Model%wetdep_ls_opt = wetdep_ls_opt Model%do_plumerise = do_plumerise + Model%n_dbg_lines = n_dbg_lines Model%plumerisefire_frq = plumerisefire_frq Model%addsmoke_flag = addsmoke_flag Model%smoke_forecast = smoke_forecast @@ -6388,6 +6448,7 @@ subroutine control_print(Model) print *, ' cplaqm : ', Model%cplaqm print *, ' cplchm : ', Model%cplchm print *, ' cpllnd : ', Model%cpllnd + print *, ' cpllnd2atm : ', Model%cpllnd2atm print *, ' rrfs_sd : ', Model%rrfs_sd print *, ' use_cice_alb : ', Model%use_cice_alb print *, ' cpl_imp_mrg : ', Model%cpl_imp_mrg diff --git a/ccpp/data/GFS_typedefs.meta b/ccpp/data/GFS_typedefs.meta index ebaa9af7f..d408f5f42 100644 --- a/ccpp/data/GFS_typedefs.meta +++ b/ccpp/data/GFS_typedefs.meta @@ -979,7 +979,7 @@ type = real kind = kind_phys active = (control_for_land_surface_scheme == identifier_for_ruc_land_surface_scheme) -[fire_heat_flux_out] +[fire_heat_flux] standard_name = surface_fire_heat_flux long_name = heat flux of fire at the surface units = W m-2 @@ -987,7 +987,7 @@ type = real kind = kind_phys active = (control_for_land_surface_scheme == identifier_for_ruc_land_surface_scheme) -[frac_grid_burned_out] +[frac_grid_burned] standard_name = fraction_of_grid_cell_burning long_name = ration of the burnt area to the grid cell area units = frac @@ -2288,7 +2288,7 @@ type = real kind = kind_phys active = (do_smoke_coupling) -[frp_input] +[frp_output] standard_name = frp_hourly long_name = hourly fire radiative power units = MW @@ -2312,6 +2312,37 @@ type = real kind = kind_phys active = (do_smoke_coupling) +[fire_type] + standard_name = fire_type + long_name = type of fire + units = 1 + dimensions = (horizontal_loop_extent) + type = integer + active = (do_smoke_coupling) +[peak_hr] + standard_name = peak_hr_fire + long_name = time_of_peak_fire_emissions + units = s + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (do_smoke_coupling) +[lu_nofire] + standard_name = sum_of_land_use_fractions_for_no_fire_pixels + long_name = land use of no fire pixels for type + units = 1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (do_smoke_coupling) +[lu_qfire] + standard_name = sum_of_land_use_fractions_for_cropland_fire_pixels + long_name = land use of fire pixels for type + units = 1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (do_smoke_coupling) [fire_in] standard_name = smoke_fire_auxiliary_input long_name = smoke fire auxiliary input variables @@ -2822,6 +2853,110 @@ type = real kind = kind_phys active = (flag_for_surface_flux_coupling .and. do_mediator_atmosphere_ocean_fluxes) +[sncovr1_lnd] + standard_name = surface_snow_area_fraction_over_land_from_land + long_name = surface snow area fraction over land for coupling + units = frac + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[qsurf_lnd] + standard_name = surface_specific_humidity_over_land_from_land + long_name = surface air saturation specific humidity over land + units = kg kg-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[hflx_lnd] + standard_name = surface_upward_sensible_heat_flux_over_land_from_land + long_name = sfc sensible heat flux input over land for coupling + units = K m s-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[evap_lnd] + standard_name = surface_upward_latent_heat_flux_over_land_from_land + long_name = sfc latent heat flux input over land for coupling + units = kg kg-1 m s-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[ep_lnd] + standard_name = surface_upward_potential_latent_heat_flux_over_land_from_land + long_name = surface upward potential latent heat flux over land for coupling + units = W m-2 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[t2mmp_lnd] + standard_name = temperature_at_2m_over_land_from_land + long_name = 2 meter temperature over land for coupling + units = K + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[q2mp_lnd] + standard_name = specific_humidity_at_2m_over_land_from_land + long_name = 2 meter specific humidity over land for coupling + units = kg kg-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[gflux_lnd] + standard_name = upward_heat_flux_in_soil_over_land_from_land + long_name = soil heat flux over land for coupling + units = W m-2 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[runoff_lnd] + standard_name = surface_runoff_flux_from_land + long_name = surface runoff flux over land for coupling + units = kg m-2 s-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[drain_lnd] + standard_name = subsurface_runoff_flux_from_land + long_name = subsurface runoff flux over land for coupling + units = kg m-2 s-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[cmm_lnd] + standard_name = surface_drag_wind_speed_for_momentum_in_air_over_land_from_land + long_name = momentum exchange coefficient over land for coupling + units = m s-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[chh_lnd] + standard_name = surface_drag_mass_flux_for_heat_and_moisture_in_air_over_land_from_land + long_name = thermal exchange coefficient over land for coupling + units = kg m-2 s-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) +[zvfun_lnd] + standard_name = function_of_surface_roughness_length_and_green_vegetation_fraction_from_land + long_name = function of surface roughness length and green vegetation fraction + units = none + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (flag_for_land_coupling .and. flag_for_one_way_land_coupling_to_atmosphere) [hsnoin_cpl] standard_name = lwe_surface_snow_from_coupled_process long_name = sfc snow depth in meters over sea ice for coupling @@ -3052,6 +3187,22 @@ type = real kind = kind_phys active = (do_smoke_coupling) +[uspdavg] + standard_name = mean_wind_speed_in_boundary_layer + long_name = average wind speed within the boundary layer + units = m s-1 + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (do_smoke_coupling) +[hpbl_thetav] + standard_name = atmosphere_boundary_layer_thickness_from_modified_parcel + long_name = pbl height based on modified parcel method + units = m + dimensions = (horizontal_loop_extent) + type = real + kind = kind_phys + active = (do_smoke_coupling) [rrfs_hwp] standard_name = hourly_wildfire_potential long_name = rrfs hourly fire weather potential @@ -3430,6 +3581,12 @@ units = flag dimensions = () type = logical +[cpllnd2atm] + standard_name = flag_for_one_way_land_coupling_to_atmosphere + long_name = flag controlling land coupling to the atmosphere (default off) + units = flag + dimensions = () + type = logical [rrfs_sd] standard_name = do_smoke_coupling long_name = flag controlling rrfs_sd collection (default off) @@ -6678,6 +6835,13 @@ dimensions = () type = integer active = (do_smoke_coupling) +[n_dbg_lines] + standard_name = smoke_debug_lines + long_name = rrfs smoke add smoke option + units = index + dimensions = () + type = integer + active = (do_smoke_coupling) [addsmoke_flag] standard_name = control_for_smoke_biomass_burning_emissions long_name = rrfs smoke add smoke option diff --git a/ccpp/driver/GFS_diagnostics.F90 b/ccpp/driver/GFS_diagnostics.F90 index 3bbd300d5..def71566d 100644 --- a/ccpp/driver/GFS_diagnostics.F90 +++ b/ccpp/driver/GFS_diagnostics.F90 @@ -3761,6 +3761,18 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop enddo if (Model%lsm == Model%lsm_ruc) then + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'sfalb' + ExtDiag(idx)%desc = 'surface albedo over land' + ExtDiag(idx)%unit = 'fraction' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%sfalb_lnd(:) + enddo + idx = idx + 1 ExtDiag(idx)%axes = 2 ExtDiag(idx)%name = 'rhofr' @@ -4077,7 +4089,7 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop ExtDiag(idx)%name = 'nirbmdi' ExtDiag(idx)%desc = 'sfc nir beam sw downward flux' ExtDiag(idx)%unit = 'W/m**2' - ExtDiag(idx)%mod_name = 'gfs_sfc' + ExtDiag(idx)%mod_name = 'gfs_phys' allocate (ExtDiag(idx)%data(nblks)) do nb = 1,nblks ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%nirbmdi(:) @@ -4088,7 +4100,7 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop ExtDiag(idx)%name = 'nirdfdi' ExtDiag(idx)%desc = 'sfc nir diff sw downward flux' ExtDiag(idx)%unit = 'W/m**2' - ExtDiag(idx)%mod_name = 'gfs_sfc' + ExtDiag(idx)%mod_name = 'gfs_phys' allocate (ExtDiag(idx)%data(nblks)) do nb = 1,nblks ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%nirdfdi(:) @@ -4099,7 +4111,7 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop ExtDiag(idx)%name = 'visbmdi' ExtDiag(idx)%desc = 'sfc uv+vis beam sw downward flux' ExtDiag(idx)%unit = 'W/m**2' - ExtDiag(idx)%mod_name = 'gfs_sfc' + ExtDiag(idx)%mod_name = 'gfs_phys' allocate (ExtDiag(idx)%data(nblks)) do nb = 1,nblks ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%visbmdi(:) @@ -4110,7 +4122,7 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop ExtDiag(idx)%name = 'visdfdi' ExtDiag(idx)%desc = ' sfc uv+vis diff sw downward flux' ExtDiag(idx)%unit = 'W/m**2' - ExtDiag(idx)%mod_name = 'gfs_sfc' + ExtDiag(idx)%mod_name = 'gfs_phys' allocate (ExtDiag(idx)%data(nblks)) do nb = 1,nblks ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%visdfdi(:) @@ -4568,7 +4580,7 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop ExtDiag(idx)%mod_name = 'gfs_sfc' allocate (ExtDiag(idx)%data(nblks)) do nb = 1,nblks - ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%fire_heat_flux_out + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%fire_heat_flux enddo idx = idx + 1 @@ -4579,7 +4591,7 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop ExtDiag(idx)%mod_name = 'gfs_sfc' allocate (ExtDiag(idx)%data(nblks)) do nb = 1,nblks - ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%frac_grid_burned_out + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%frac_grid_burned enddo idx = idx + 1 @@ -4669,6 +4681,96 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%rrfs_hwp_ave enddo + extended_smoke_dust_diagnostics: if ( Model%extended_sd_diags ) then + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'uspdavg' + ExtDiag(idx)%desc = 'BL average wind speed' + ExtDiag(idx)%unit = '' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%uspdavg + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'hpbl_thetav' + ExtDiag(idx)%desc = 'BL depth modified parcel method' + ExtDiag(idx)%unit = '' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%hpbl_thetav + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'drydep_smoke' + ExtDiag(idx)%desc = 'dry deposition smoke' + ExtDiag(idx)%unit = ' ' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%drydep_flux(:,1) + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'drydep_dust' + ExtDiag(idx)%desc = 'dry deposition dust' + ExtDiag(idx)%unit = ' ' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%drydep_flux(:,2) + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'drydep_coarsepm' + ExtDiag(idx)%desc = 'dry deposition coarsepm' + ExtDiag(idx)%unit = ' ' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%drydep_flux(:,3) + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'wetdpr_smoke' + ExtDiag(idx)%desc = 'resolved wet deposition smoke' + ExtDiag(idx)%unit = ' ' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%wetdpr_flux(:,1) + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'wetdpr_dust' + ExtDiag(idx)%desc = 'resolved wet deposition dust' + ExtDiag(idx)%unit = ' ' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%wetdpr_flux(:,2) + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'wetdpr_coarsepm' + ExtDiag(idx)%desc = 'resolved wet deposition coarsepm' + ExtDiag(idx)%unit = ' ' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Coupling(nb)%wetdpr_flux(:,3) + enddo + idx = idx + 1 ExtDiag(idx)%axes = 2 ExtDiag(idx)%name = 'wetdpc_smoke' @@ -4704,13 +4806,46 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop idx = idx + 1 ExtDiag(idx)%axes = 2 - ExtDiag(idx)%name = 'ebb_smoke_in' - ExtDiag(idx)%desc = 'input smoke emission' - ExtDiag(idx)%unit = 'ug m-2 s-1' + ExtDiag(idx)%name = 'peak_hr' + ExtDiag(idx)%desc = 'hour of peak smoke emissions' + ExtDiag(idx)%unit = ' ' ExtDiag(idx)%mod_name = 'gfs_sfc' allocate (ExtDiag(idx)%data(nblks)) do nb = 1,nblks - ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%ebb_smoke_in + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%peak_hr + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'fire_type' + ExtDiag(idx)%desc = 'fire type' + ExtDiag(idx)%unit = '' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%int2 => Sfcprop(nb)%fire_type + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'lu_nofire' + ExtDiag(idx)%desc = 'lu nofire pixes' + ExtDiag(idx)%unit = '' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lu_nofire + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'lu_qfire' + ExtDiag(idx)%desc = 'lu qfire pixes' + ExtDiag(idx)%unit = '' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%lu_qfire enddo idx = idx + 1 @@ -4724,17 +4859,85 @@ subroutine GFS_externaldiag_populate (ExtDiag, Model, Statein, Stateout, Sfcprop ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%fhist enddo + if (Model%ebb_dcycle == 2 ) then + idx = idx + 1 ExtDiag(idx)%axes = 2 - ExtDiag(idx)%name = 'frp_input' - ExtDiag(idx)%desc = 'input frp' + ExtDiag(idx)%name = 'fire_end_hr' + ExtDiag(idx)%desc = 'Hours since fire was last detected' + ExtDiag(idx)%unit = 'hrs' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%smoke2d_RRFS(:,3) + enddo + + endif + + endif extended_smoke_dust_diagnostics + + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'ebb_smoke_in' + ExtDiag(idx)%desc = 'input smoke emission' + ExtDiag(idx)%unit = 'ug m-2 s-1' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%ebb_smoke_in + enddo + + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'frp_output' + ExtDiag(idx)%desc = 'output frp' + ExtDiag(idx)%unit = 'mw' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%frp_output + enddo + + smoke_forecast_mode: if (Model%ebb_dcycle == 2 ) then + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'ebb_rate' + ExtDiag(idx)%desc = 'Total EBB Emissions' + ExtDiag(idx)%unit = 'ug m-2 s-1' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%smoke2d_RRFS(:,1) + enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'frp_davg' + ExtDiag(idx)%desc = 'Daily mean Fire Radiative Power' ExtDiag(idx)%unit = 'mw' ExtDiag(idx)%mod_name = 'gfs_sfc' allocate (ExtDiag(idx)%data(nblks)) do nb = 1,nblks - ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%frp_input + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%smoke2d_RRFS(:,2) enddo + + idx = idx + 1 + ExtDiag(idx)%axes = 2 + ExtDiag(idx)%name = 'hwp_davg' + ExtDiag(idx)%desc = 'Daily mean Hourly Wildfire Potential' + ExtDiag(idx)%unit = ' ' + ExtDiag(idx)%mod_name = 'gfs_sfc' + allocate (ExtDiag(idx)%data(nblks)) + do nb = 1,nblks + ExtDiag(idx)%data(nb)%var2 => Sfcprop(nb)%smoke2d_RRFS(:,4) + enddo + + endif smoke_forecast_mode + idx = idx + 1 ExtDiag(idx)%axes = 3 ExtDiag(idx)%name = 'ebu_smoke' diff --git a/ccpp/driver/GFS_restart.F90 b/ccpp/driver/GFS_restart.F90 index 9abf926de..890aeb9fb 100644 --- a/ccpp/driver/GFS_restart.F90 +++ b/ccpp/driver/GFS_restart.F90 @@ -152,7 +152,7 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, & Restart%num2d = Restart%num2d + Model%num_dfi_radar endif if (Model%rrfs_sd) then - Restart%num2d = Restart%num2d + 5 + Restart%num2d = Restart%num2d + 6 endif Restart%num3d = Model%ntot3d @@ -179,7 +179,7 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, & Restart%num3d = Restart%num3d + 9 endif if (Model%rrfs_sd) then - Restart%num3d = Restart%num3d + 7 + Restart%num3d = Restart%num3d + 4 endif !Prognostic area fraction if (Model%progsigma) then @@ -515,6 +515,11 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, & do nb = 1,nblks Restart%data(nb,num)%var2p => Coupling(nb)%rrfs_hwp(:) enddo + num = num + 1 + Restart%name2d(num) = 'rrfs_hwp_ave' + do nb = 1,nblks + Restart%data(nb,num)%var2p => Coupling(nb)%rrfs_hwp_ave(:) + enddo endif !--- phy_f3d variables @@ -669,21 +674,6 @@ subroutine GFS_restart_populate (Restart, Model, Statein, Stateout, Sfcprop, & endif if(Model%rrfs_sd) then - num = num + 1 - Restart%name3d(num) = 'ebu_smoke' - do nb = 1,nblks - Restart%data(nb,num)%var3p => Coupling(nb)%ebu_smoke(:,:) - enddo - num = num + 1 - Restart%name3d(num) = 'smoke_ext' - do nb = 1,nblks - Restart%data(nb,num)%var3p => Coupling(nb)%smoke_ext(:,:) - enddo - num = num + 1 - Restart%name3d(num) = 'dust_ext' - do nb = 1,nblks - Restart%data(nb,num)%var3p => Coupling(nb)%dust_ext(:,:) - enddo num = num + 1 Restart%name3d(num) = 'chem3d_1' do nb = 1,nblks diff --git a/ccpp/physics b/ccpp/physics index a492addf8..d0c3294c7 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit a492addf860d29d797bca488f53d39b260584924 +Subproject commit d0c3294c7efa1531f489dcacff676b92acdab5a1 diff --git a/ccpp/suites/suite_FV3_GFS_v17_p8.xml b/ccpp/suites/suite_FV3_GFS_v17_p8.xml index 4fa6c222d..e90d0c42b 100644 --- a/ccpp/suites/suite_FV3_GFS_v17_p8.xml +++ b/ccpp/suites/suite_FV3_GFS_v17_p8.xml @@ -43,6 +43,7 @@ sfc_nst sfc_nst_post noahmpdrv + sfc_land sfc_sice GFS_surface_loop_control_part2 diff --git a/cpl/module_cplfields.F90 b/cpl/module_cplfields.F90 index 83d62ee30..58f31236f 100644 --- a/cpl/module_cplfields.F90 +++ b/cpl/module_cplfields.F90 @@ -26,7 +26,7 @@ module module_cplfields ! l : model levels (3D) ! s : surface (2D) ! t : tracers (4D) - integer, public, parameter :: NexportFields = 121 + integer, public, parameter :: NexportFields = 119 type(ESMF_Field), target, public :: exportFields(NexportFields) type(FieldInfo), dimension(NexportFields), public, parameter :: exportFieldsInfo = [ & @@ -118,8 +118,6 @@ module module_cplfields FieldInfo("leaf_area_index ", "s"), & FieldInfo("temperature_of_soil_layer ", "g"), & FieldInfo("height ", "s"), & - FieldInfo("inst_zonal_wind_height_lowest_from_phys ", "s"), & - FieldInfo("inst_merid_wind_height_lowest_from_phys ", "s"), & FieldInfo("inst_pres_height_lowest_from_phys ", "s"), & FieldInfo("inst_spec_humid_height_lowest_from_phys ", "s"), & FieldInfo("inst_prec_rate_conv ", "s"), & @@ -158,7 +156,7 @@ module module_cplfields FieldInfo("t2m ", "s") ] ! Import Fields ---------------------------------------- - integer, public, parameter :: NimportFields = 48 + integer, public, parameter :: NimportFields = 62 logical, public :: importFieldsValid(NimportFields) type(ESMF_Field), target, public :: importFields(NimportFields) @@ -189,6 +187,22 @@ module module_cplfields FieldInfo("sensi_heat_flx_atm_into_ocn ", "s"), & FieldInfo("lwup_flx_ocn ", "s"), & + ! For receiving fluxes from external land component + FieldInfo("land_fraction ", "s"), & + FieldInfo("inst_snow_area_fraction_lnd ", "s"), & + FieldInfo("inst_spec_humid_lnd ", "s"), & + FieldInfo("inst_laten_heat_flx_lnd ", "s"), & + FieldInfo("inst_sensi_heat_flx_lnd ", "s"), & + FieldInfo("inst_potential_laten_heat_flx_lnd ", "s"), & + FieldInfo("inst_temp_height2m_lnd ", "s"), & + FieldInfo("inst_spec_humid_height2m_lnd ", "s"), & + FieldInfo("inst_upward_heat_flux_lnd ", "s"), & + FieldInfo("inst_runoff_rate_lnd ", "s"), & + FieldInfo("inst_subsurface_runoff_rate_lnd ", "s"), & + FieldInfo("inst_drag_wind_speed_for_momentum ", "s"), & + FieldInfo("inst_drag_mass_flux_for_heat_and_moisture", "s"), & + FieldInfo("inst_func_of_roughness_length_and_vfrac ", "s"), & + ! For JEDI ! dynamics FieldInfo("u ", "l"), &