diff --git a/atmos_model.F90 b/atmos_model.F90 index 051f5918d..c010789cd 100644 --- a/atmos_model.F90 +++ b/atmos_model.F90 @@ -627,9 +627,9 @@ subroutine atmos_model_init (Atmos, Time_init, Time, Time_step) IPD_Interstitial, commglobal, mpp_npes(), Init_parm) !--- Initialize stochastic physics pattern generation / cellular automata for first time step - call stochastic_physics_wrapper(IPD_Control, IPD_Data, Atm_block, ierr) - if (ierr/=0) call mpp_error(FATAL, 'Call to stochastic_physics_wrapper failed') - +! call stochastic_physics_wrapper(IPD_Control, IPD_Data, Atm_block, ierr) +! if (ierr/=0) call mpp_error(FATAL, 'Call to stochastic_physics_wrapper failed') +! #else call IPD_initialize (IPD_Control, IPD_Data, IPD_Diag, IPD_Restart, Init_parm) #endif @@ -684,6 +684,9 @@ subroutine atmos_model_init (Atmos, Time_init, Time, Time_step) ! Initialize the CCPP physics call CCPP_step (step="physics_init", nblks=Atm_block%nblks, ierr=ierr) if (ierr/=0) call mpp_error(FATAL, 'Call to CCPP physics_init step failed') +!--- Initialize stochastic physics pattern generation / cellular automata for first time step + call stochastic_physics_wrapper(IPD_Control, IPD_Data, Atm_block, ierr) + if (ierr/=0) call mpp_error(FATAL, 'Call to stochastic_physics_wrapper failed') #endif !--- set the initial diagnostic timestamp diff --git a/ccpp/physics b/ccpp/physics index 0ac8068d5..96cce1f88 160000 --- a/ccpp/physics +++ b/ccpp/physics @@ -1 +1 @@ -Subproject commit 0ac8068d53a19d342fc176dd62d4267f1b43008e +Subproject commit 96cce1f883c986139502d9bef861e29d9aec06ce diff --git a/gfsphysics/GFS_layer/GFS_typedefs.F90 b/gfsphysics/GFS_layer/GFS_typedefs.F90 index 2fef16ee4..57ec7da90 100644 --- a/gfsphysics/GFS_layer/GFS_typedefs.F90 +++ b/gfsphysics/GFS_layer/GFS_typedefs.F90 @@ -812,6 +812,8 @@ module GFS_typedefs integer :: lsnow_lsm !< maximum number of snow layers internal to land surface model integer :: lsnow_lsm_lbound!< lower bound for snow arrays, depending on lsnow_lsm real(kind=kind_phys), pointer :: zs(:) => null() !< depth of soil levels for land surface model + real(kind=kind_phys), pointer :: pores(:) => null() !< max soil moisture for a given soil type for land surface model + real(kind=kind_phys), pointer :: resid(:) => null() !< min soil moisture for a given soil type for land surface model logical :: rdlai !< read LAI from input file (for RUC LSM or NOAH LSM WRFv4) logical :: ua_phys !< flag for using University of Arizona? extension to NOAH LSM WRFv4 logical :: usemonalb !< flag to read surface diffused shortwave albedo from input file for NOAH LSM WRFv4 @@ -3981,6 +3983,12 @@ subroutine control_initialize (Model, nlunit, fn_nml, me, master, & end if ! Set number of ice model layers Model%kice = kice + + ! Allocate variable for min/max soil moisture for a given soil type + allocate (Model%pores(30)) + allocate (Model%resid(30)) + Model%pores = clear_val + Model%resid = clear_val ! if (lsnow_lsm /= 3) then write(0,*) 'Logic error: NoahMP expects the maximum number of snow layers to be exactly 3 (see sfc_noahmp_drv.f)' diff --git a/gfsphysics/GFS_layer/GFS_typedefs.meta b/gfsphysics/GFS_layer/GFS_typedefs.meta index 4dfb5046e..dcacc8644 100644 --- a/gfsphysics/GFS_layer/GFS_typedefs.meta +++ b/gfsphysics/GFS_layer/GFS_typedefs.meta @@ -3285,6 +3285,20 @@ type = real kind = kind_phys active = (flag_for_land_surface_scheme == flag_for_ruc_land_surface_scheme) +[pores] + standard_name = maximum_soil_moisture_content_for_land_surface_model + long_name = maximum soil moisture for a given soil type for land surface model + units = m + dimensions = (30) + type = real + kind = kind_phys +[resid] + standard_name = minimum_soil_moisture_content_for_land_surface_model + long_name = minimum soil moisture for a given soil type for land surface model + units = m + dimensions = (30) + type = real + kind = kind_phys [rdlai] standard_name = flag_for_reading_leaf_area_index_from_input long_name = flag for reading leaf area index from initial conditions diff --git a/stochastic_physics/stochastic_physics_wrapper.F90 b/stochastic_physics/stochastic_physics_wrapper.F90 index 5a3701aa8..44c82ecbd 100644 --- a/stochastic_physics/stochastic_physics_wrapper.F90 +++ b/stochastic_physics/stochastic_physics_wrapper.F90 @@ -13,10 +13,23 @@ module stochastic_physics_wrapper_mod real(kind=kind_phys), dimension(:,:,:), allocatable, save :: skebv_wts real(kind=kind_phys), dimension(:,:,:), allocatable, save :: sfc_wts + integer, save :: lsoil = -999 real(kind=kind_phys), dimension(:,:,:), allocatable, save :: smc real(kind=kind_phys), dimension(:,:,:), allocatable, save :: stc real(kind=kind_phys), dimension(:,:,:), allocatable, save :: slc + ! real(kind=kind_phys), dimension(:,:), allocatable, save :: vfrac + !albedo + real(kind=kind_phys), dimension(:,:), allocatable, save :: snoalb + real(kind=kind_phys), dimension(:,:), allocatable, save :: alvsf + real(kind=kind_phys), dimension(:,:), allocatable, save :: alnsf + real(kind=kind_phys), dimension(:,:), allocatable, save :: alvwf + real(kind=kind_phys), dimension(:,:), allocatable, save :: alnwf + real(kind=kind_phys), dimension(:,:), allocatable, save :: facsf + real(kind=kind_phys), dimension(:,:), allocatable, save :: facwf + !emissivity + real(kind=kind_phys), dimension(:,:), allocatable, save :: semis + real(kind=kind_phys), dimension(:,:), allocatable, save :: stype ! For cellular automata @@ -58,7 +71,6 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) use cellular_automata_global_mod, only: cellular_automata_global use cellular_automata_sgs_mod, only: cellular_automata_sgs use lndp_apply_perts_mod, only: lndp_apply_perts - use namelist_soilveg, only: maxsmc implicit none @@ -108,11 +120,24 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) allocate(sfc_wts(1:Atm_block%nblks,maxval(GFS_Control%blksz),1:GFS_Control%n_var_lndp)) end if if (GFS_Control%lndp_type .EQ. 2) then ! save wts, and apply lndp scheme - allocate(smc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) - allocate(slc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) - allocate(stc(1:Atm_block%nblks,maxval(GFS_Control%blksz),GFS_Control%lsoil)) + if (GFS_Control%lsm == GFS_Control%lsm_noah) then + lsoil = GFS_Control%lsoil + elseif (GFS_Control%lsm == GFS_Control%lsm_ruc) then + lsoil = GFS_Control%lsoil_lsm + endif + allocate(smc(1:Atm_block%nblks,maxval(GFS_Control%blksz),lsoil)) + allocate(slc(1:Atm_block%nblks,maxval(GFS_Control%blksz),lsoil)) + allocate(stc(1:Atm_block%nblks,maxval(GFS_Control%blksz),lsoil)) allocate(stype(1:Atm_block%nblks,maxval(GFS_Control%blksz))) allocate(vfrac(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(snoalb(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(alvsf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(alnsf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(alvwf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(alnwf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(facsf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(facwf(1:Atm_block%nblks,maxval(GFS_Control%blksz))) + allocate(semis(1:Atm_block%nblks,maxval(GFS_Control%blksz))) endif do nb=1,Atm_block%nblks @@ -171,31 +196,76 @@ subroutine stochastic_physics_wrapper (GFS_Control, GFS_Data, Atm_block, ierr) do nb=1,Atm_block%nblks stype(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%stype(:) - smc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%smc(:,:) - slc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%slc(:,:) - stc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%stc(:,:) vfrac(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%vfrac(:) + snoalb(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%snoalb(:) + alvsf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%alvsf(:) + alnsf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%alnsf(:) + alvwf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%alvwf(:) + alnwf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%alnwf(:) + facsf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%facsf(:) + facwf(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Sfcprop%facwf(:) + semis(nb,1:GFS_Control%blksz(nb)) = GFS_Data(nb)%Radtend%semis(:) end do - ! determine whether land paramaters have been over-written - if (mod(GFS_Control%kdt,GFS_Control%nscyc) == 1) then ! logic copied from GFS_driver - param_update_flag = .true. + if (GFS_Control%lsm == GFS_Control%lsm_noah) then + do nb=1,Atm_block%nblks + smc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%smc(:,:) + slc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%slc(:,:) + stc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%stc(:,:) + end do + elseif (GFS_Control%lsm == GFS_Control%lsm_ruc) then + do nb=1,Atm_block%nblks + smc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%smois(:,:) + slc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%sh2o(:,:) + stc(nb,1:GFS_Control%blksz(nb),:) = GFS_Data(nb)%Sfcprop%tslb(:,:) + end do + endif + + ! determine whether land paramaters have been over-written to + ! trigger applying perturbations (logic copied from GFS_driver), + ! or if perturbations should be applied at every time step + if (mod(GFS_Control%kdt,GFS_Control%nscyc) == 1 ) then + param_update_flag = .true. else - param_update_flag = .false. + param_update_flag = .false. endif - call lndp_apply_perts( GFS_Control%blksz, GFS_Control%lsm, GFS_Control%lsoil, GFS_Control%dtf, & - GFS_Control%n_var_lndp, GFS_Control%lndp_var_list, GFS_Control%lndp_prt_list, & - sfc_wts, xlon, xlat, stype, maxsmc,param_update_flag, smc, slc,stc, vfrac, ierr) + + call lndp_apply_perts(GFS_Control%blksz, GFS_Control%lsm, GFS_Control%lsm_noah, GFS_Control%lsm_ruc, lsoil, & + GFS_Control%dtf, GFS_Control%kdt, GFS_Control%lndp_each_step, & + GFS_Control%n_var_lndp, GFS_Control%lndp_var_list, GFS_Control%lndp_prt_list, & + sfc_wts, xlon, xlat, stype, GFS_Control%pores, GFS_Control%resid,param_update_flag, & + smc, slc, stc, vfrac, alvsf, alnsf, alvwf, alnwf, facsf, facwf, snoalb, semis, ierr) if (ierr/=0) then write(6,*) 'call to GFS_apply_lndp failed' return endif + do nb=1,Atm_block%nblks - GFS_Data(nb)%Sfcprop%smc(:,:) = smc(nb,1:GFS_Control%blksz(nb),:) - GFS_Data(nb)%Sfcprop%slc(:,:) = slc(nb,1:GFS_Control%blksz(nb),:) - GFS_Data(nb)%Sfcprop%stc(:,:) = stc(nb,1:GFS_Control%blksz(nb),:) - GFS_Data(nb)%Sfcprop%vfrac(:) = vfrac(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%vfrac(:) = vfrac(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%snoalb(:) = snoalb(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%alvsf(:) = alvsf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%alnsf(:) = alnsf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%alvwf(:) = alvwf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%alnwf(:) = alnwf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%facsf(:) = facsf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Sfcprop%facwf(:) = facwf(nb,1:GFS_Control%blksz(nb)) + GFS_Data(nb)%Radtend%semis(:) = semis(nb,1:GFS_Control%blksz(nb)) enddo + + if (GFS_Control%lsm == GFS_Control%lsm_noah) then + do nb=1,Atm_block%nblks + GFS_Data(nb)%Sfcprop%smc(:,:) = smc(nb,1:GFS_Control%blksz(nb),:) + GFS_Data(nb)%Sfcprop%slc(:,:) = slc(nb,1:GFS_Control%blksz(nb),:) + GFS_Data(nb)%Sfcprop%stc(:,:) = stc(nb,1:GFS_Control%blksz(nb),:) + enddo + elseif (GFS_Control%lsm == GFS_Control%lsm_ruc) then + do nb=1,Atm_block%nblks + GFS_Data(nb)%Sfcprop%smois(:,:) = smc(nb,1:GFS_Control%blksz(nb),:) + GFS_Data(nb)%Sfcprop%sh2o(:,:) = slc(nb,1:GFS_Control%blksz(nb),:) + GFS_Data(nb)%Sfcprop%tslb(:,:) = stc(nb,1:GFS_Control%blksz(nb),:) + enddo + endif + endif ! lndp block end if @@ -313,6 +383,7 @@ subroutine stochastic_physics_wrapper_end (GFS_Control) if (allocated(skebv_wts)) deallocate(skebv_wts) end if if ( GFS_Control%lndp_type .EQ. 2 ) then ! this scheme updates through forecast + lsoil = -999 if (allocated(sfc_wts)) deallocate(sfc_wts) end if if (GFS_Control%lndp_type .EQ. 2) then ! save wts, and apply lndp scheme @@ -321,6 +392,14 @@ subroutine stochastic_physics_wrapper_end (GFS_Control) if (allocated(stc)) deallocate(stc) if (allocated(stype)) deallocate(stype) if (allocated(vfrac)) deallocate(vfrac) + if (allocated(snoalb)) deallocate(snoalb) + if (allocated(alvsf)) deallocate(alvsf) + if (allocated(alnsf)) deallocate(alnsf) + if (allocated(alvwf)) deallocate(alvwf) + if (allocated(alnwf)) deallocate(alnwf) + if (allocated(facsf)) deallocate(facsf) + if (allocated(facwf)) deallocate(facwf) + if (allocated(semis)) deallocate(semis) endif call finalize_stochastic_physics() endif