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

Add calls to initialize Noah LSM lookup tables to GFS_phys_time_vary #564

Merged
merged 1 commit into from
Feb 5, 2021
Merged
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
86 changes: 53 additions & 33 deletions physics/GFS_phys_time_vary.fv3.F90
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,9 @@ module GFS_phys_time_vary

use gcycle_mod, only : gcycle

#if 0
!--- variables needed for calculating 'sncovr'
use namelist_soilveg, only: salp_data, snupx
#endif
use set_soilveg_mod, only: set_soilveg
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@climbfuji Dom, this PR moves only the initialization of Noah LSM look-up tables to GFS_phys_time_vary because the snupx(vegtyp) and salp_data are needed to initialize snow cover fraction in the cold-start runs. Do I understand this PR correctly?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the answer to my question is 'yes', then the title of this PR could be changed to "Add calls to initialize Noah LSM lookup tables used in snow cover fraction computation". The look-up tables for RUC LSM (and Noah-MP) will still happen in lsm_ruc_init. We are not going to move them, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, correct. Mike and Helin will take care of the remaining Noah MP code in fv3atm.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the answer to my question is 'yes', then the title of this PR could be changed to "Add calls to initialize Noah LSM lookup tables used in snow cover fraction computation". The look-up tables for RUC LSM (and Noah-MP) will still happen in lsm_ruc_init. We are not going to move them, right?

Correct. I'll update the name of this PR.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. Thank you!


implicit none

Expand All @@ -42,9 +41,12 @@ module GFS_phys_time_vary

logical :: is_initialized = .false.

real(kind=kind_phys), parameter :: con_hr = 3600.0_kind_phys
real(kind=kind_phys), parameter :: con_99 = 99.0_kind_phys
real(kind=kind_phys), parameter :: con_100 = 100.0_kind_phys
real(kind=kind_phys), parameter :: con_hr = 3600.0_kind_phys
real(kind=kind_phys), parameter :: con_99 = 99.0_kind_phys
real(kind=kind_phys), parameter :: con_100 = 100.0_kind_phys
real(kind=kind_phys), parameter :: drythresh = 1.e-4_kind_phys
real(kind=kind_phys), parameter :: zero = 0.0_kind_phys
real(kind=kind_phys), parameter :: one = 1.0_kind_phys

contains

Expand All @@ -58,7 +60,8 @@ subroutine GFS_phys_time_vary_init (
jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl, &
jindx1_aer, jindx2_aer, ddy_aer, iindx1_aer, iindx2_aer, ddx_aer, aer_nm, &
jindx1_ci, jindx2_ci, ddy_ci, iindx1_ci, iindx2_ci, ddx_ci, imap, jmap, &
nthrds, errmsg, errflg)
isot, ivegsrc, nlunit, sncovr, sncovr_ice, lsm, lsm_ruc, min_seaice, fice, landfrac, &
vtype, weasd, nthrds, errmsg, errflg)

implicit none

Expand All @@ -78,12 +81,19 @@ subroutine GFS_phys_time_vary_init (
real(kind_phys), intent(inout) :: ddy_ci(:), ddx_ci(:)
integer, intent(inout) :: imap(:), jmap(:)

integer, intent(in) :: isot, ivegsrc, nlunit
real(kind_phys), intent(inout) :: sncovr(:), sncovr_ice(:)
integer, intent(in) :: lsm, lsm_ruc
real(kind_phys), intent(in) :: min_seaice, fice(:)
real(kind_phys), intent(in) :: landfrac(:), vtype(:), weasd(:)

integer, intent(in) :: nthrds
character(len=*), intent(out) :: errmsg
integer, intent(out) :: errflg

! Local variables
integer :: i, j, ix
integer :: i, j, ix, vegtyp
real(kind_phys) :: rsnow

! Initialize CCPP error handling variables
errmsg = ''
Expand All @@ -100,7 +110,9 @@ subroutine GFS_phys_time_vary_init (
!$OMP shared (jindx1_o3,jindx2_o3,ddy_o3,jindx1_h,jindx2_h,ddy_h) &
!$OMP shared (jindx1_aer,jindx2_aer,ddy_aer,iindx1_aer,iindx2_aer,ddx_aer) &
!$OMP shared (jindx1_ci,jindx2_ci,ddy_ci,iindx1_ci,iindx2_ci,ddx_ci) &
!$OMP private (ix,i,j)
!$OMP shared (isot,ivegsrc,nlunit,sncovr,sncovr_ice,lsm,lsm_ruc) &
!$OMP shared (min_seaice,fice,landfrac,vtype,weasd,snupx,salp_data) &
!$OMP private (ix,i,j,rsnow,vegtyp)

!$OMP sections

Expand Down Expand Up @@ -177,6 +189,10 @@ subroutine GFS_phys_time_vary_init (
! hardcoded in module iccn_def.F and GFS_typedefs.F90
endif

!$OMP section
!> - Initialize soil vegetation (needed for sncovr calculation further down)
call set_soilveg(me, isot, ivegsrc, nlunit)

!$OMP end sections

! Need an OpenMP barrier here (implicit in "end sections")
Expand Down Expand Up @@ -223,35 +239,39 @@ subroutine GFS_phys_time_vary_init (
enddo
enddo

!$OMP section
!--- if sncovr does not exist in the restart, need to create it
if (all(sncovr < zero)) then
if (me == master ) write(0,'(a)') 'GFS_phys_time_vary_init: compute sncovr from weasd and soil vegetation parameters'
!--- compute sncovr from existing variables
!--- code taken directly from read_fix.f
sncovr(:) = zero
do ix=1,im
if (landfrac(ix) >= drythresh .or. fice(ix) >= min_seaice) then
vegtyp = vtype(ix)
if (vegtyp == 0) vegtyp = 7
rsnow = 0.001_kind_phys*weasd(ix)/snupx(vegtyp)
if (0.001_kind_phys*weasd(ix) < snupx(vegtyp)) then
sncovr(ix) = one - (exp(-salp_data*rsnow) - rsnow*exp(-salp_data))
else
sncovr(ix) = one
endif
endif
enddo
endif

!--- For RUC LSM: create sncovr_ice from sncovr
if (lsm == lsm_ruc) then
if (all(sncovr_ice < zero)) then
if (me == master ) write(0,'(a)') 'GFS_phys_time_vary_init: fill sncovr_ice with sncovr for RUC LSM'
sncovr_ice(:) = sncovr(:)
endif
endif

!$OMP end sections

!$OMP end parallel

#if 0
!Calculate sncovr if it was read in but empty (from FV3/io/FV3GFS_io.F90/sfc_prop_restart_read)
if (first_time_step) then
if (nint(Data(1)%Sfcprop%sncovr(1)) == -9999) then
!--- compute sncovr from existing variables
!--- code taken directly from read_fix.f
do nb = 1, nblks
do ix = 1, Model%blksz(nb)
Data(nb)%Sfcprop%sncovr(ix) = 0.0
if (Data(nb)%Sfcprop%slmsk(ix) > 0.001) then
vegtyp = Data(nb)%Sfcprop%vtype(ix)
if (vegtyp == 0) vegtyp = 7
rsnow = 0.001*Data(nb)%Sfcprop%weasd(ix)/snupx(vegtyp)
if (0.001*Data(nb)%Sfcprop%weasd(ix) < snupx(vegtyp)) then
Data(nb)%Sfcprop%sncovr(ix) = 1.0 - (exp(-salp_data*rsnow) - rsnow*exp(-salp_data))
else
Data(nb)%Sfcprop%sncovr(ix) = 1.0
endif
endif
enddo
enddo
endif
endif
#endif

is_initialized = .true.

end subroutine GFS_phys_time_vary_init
Expand Down
105 changes: 104 additions & 1 deletion physics/GFS_phys_time_vary.fv3.meta
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[ccpp-table-properties]
name = GFS_phys_time_vary
type = scheme
dependencies = aerclm_def.F,aerinterp.F90,gcycle.F90,h2o_def.f,h2ointerp.f90,iccn_def.F,iccninterp.F90,machine.F,mersenne_twister.f,namelist_soilveg.f,ozinterp.f90,ozne_def.f,sfcsub.F
dependencies = aerclm_def.F,aerinterp.F90,gcycle.F90,h2o_def.f,h2ointerp.f90,iccn_def.F,iccninterp.F90,machine.F,mersenne_twister.f,namelist_soilveg.f,set_soilveg.f,ozinterp.f90,ozne_def.f,sfcsub.F

########################################################################
[ccpp-arg-table]
Expand Down Expand Up @@ -307,6 +307,64 @@
type = integer
intent = inout
optional = F
[isot]
standard_name = soil_type_dataset_choice
long_name = soil type dataset choice
units = index
dimensions = ()
type = integer
intent = in
optional = F
[ivegsrc]
standard_name = vegetation_type_dataset_choice
long_name = land use dataset choice
units = index
dimensions = ()
type = integer
intent = in
optional = F
[nlunit]
standard_name = iounit_namelist
long_name = fortran unit number for file opens
units = none
dimensions = ()
type = integer
intent = in
optional = F
[sncovr]
standard_name = surface_snow_area_fraction_over_land
long_name = surface snow area fraction
units = frac
dimensions = (horizontal_dimension)
type = real
kind = kind_phys
intent = inout
optional = F
[sncovr_ice]
standard_name = surface_snow_area_fraction_over_ice
long_name = surface snow area fraction over ice
units = frac
dimensions = (horizontal_dimension)
type = real
kind = kind_phys
intent = inout
optional = F
[lsm]
standard_name = flag_for_land_surface_scheme
long_name = flag for land surface model
units = flag
dimensions = ()
type = integer
intent = in
optional = F
[lsm_ruc]
standard_name = flag_for_ruc_land_surface_scheme
long_name = flag for RUC land surface model
units = flag
dimensions = ()
type = integer
intent = in
optional = F
[nthrds]
standard_name = omp_threads
long_name = number of OpenMP threads available for physics schemes
Expand All @@ -315,6 +373,51 @@
type = integer
intent = in
optional = F
[min_seaice]
standard_name = sea_ice_minimum
long_name = minimum sea ice value
units = frac
dimensions = ()
type = real
kind = kind_phys
intent = in
optional = F
[fice]
standard_name = sea_ice_concentration
long_name = ice fraction over open water
units = frac
dimensions = (horizontal_dimension)
type = real
kind = kind_phys
intent = in
optional = F
[landfrac]
standard_name = land_area_fraction
long_name = fraction of horizontal grid area occupied by land
units = frac
dimensions = (horizontal_dimension)
type = real
kind = kind_phys
intent = in
optional = F
[vtype]
standard_name = vegetation_type_classification_real
long_name = vegetation type for lsm
units = index
dimensions = (horizontal_dimension)
type = real
kind = kind_phys
intent = in
optional = F
[weasd]
standard_name = water_equivalent_accumulated_snow_depth
long_name = water equiv of acc snow depth over land and sea ice
units = mm
dimensions = (horizontal_dimension)
type = real
kind = kind_phys
intent = in
optional = F
[errmsg]
standard_name = ccpp_error_message
long_name = error message for error handling in CCPP
Expand Down