Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Land stochastic perturbations #65

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions atmos_model.F90
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions gfsphysics/GFS_layer/GFS_typedefs.F90
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)'
Expand Down
14 changes: 14 additions & 0 deletions gfsphysics/GFS_layer/GFS_typedefs.meta
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
115 changes: 97 additions & 18 deletions stochastic_physics/stochastic_physics_wrapper.F90
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down