Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
325254b
mcycle branch update to top ccpp-physics
XuLi-NOAA Apr 13, 2025
a907150
update the order of cplflx and lakefrac_threshold in^Cubroutine GFS_…
XuLi-NOAA Apr 14, 2025
0e0fa88
code update about one logic if it is water surface or not for branch …
XuLi-NOAA Apr 15, 2025
4ea8ec6
use oceanfrac in gcycle update to ccpp-physics branch mgcycle
XuLi-NOAA Apr 22, 2025
2aa165d
the use of oceanfrac update to top ccpp-physics
XuLi-NOAA May 1, 2025
fcd32a1
Noah-MP, set zero for canopy liquid and canopy ice over glacier
wzzheng90 May 2, 2025
dc02ac0
update to ccpp-physics mgcycle branch
XuLi-NOAA May 5, 2025
72d4459
update to ccpp-physics mgcycle branch
XuLi-NOAA May 5, 2025
22edccb
Noah-MP, modifications for snow glacier
wzzheng90 May 7, 2025
5b245f5
tisfc and tsfco update to ccpp-physics branch mgcycle
XuLi-NOAA May 7, 2025
3fe1f18
Noah-MP, set all the undefined over the glacier to some values
wzzheng90 May 8, 2025
004131c
update to ccpp-physics branch mgcycle
XuLi-NOAA May 16, 2025
bc214a0
Merge branch 'ufs-community:ufs/dev' into mgcycle
XuLi-NOAA May 20, 2025
87945cb
remove lakefrac_threshold, an unused argument passed to gcycle
RuiyuSun May 22, 2025
09b2eb8
correct oceanfrac dimenion
RuiyuSun May 23, 2025
9ae08ca
Merge pull request #281 from ChristianBoyer-NOAA/lakefrac_ice_sfcr
rhaesung Jun 2, 2025
d5c5765
Merge remote-tracking branch 'upstream/ufs/dev' into canopywater_glacier
jkbk2004 Jun 3, 2025
2574825
Merge pull request #278 from wzzheng90/canopywater_glacier
grantfirl Jun 5, 2025
7d67635
Merge remote-tracking branch 'upstream/ufs/dev' into gcycleupdate
rhaesung Jun 6, 2025
15e19ee
Merge branch 'canopywater_glacier' into ufs-dev-PR278
grantfirl Jun 18, 2025
cfcaf63
Merge branch 'main' into ufs-dev-PR278
grantfirl Jun 20, 2025
db40996
Merge branch 'gcycleupdate' into ufs-dev-PR278
grantfirl Jun 20, 2025
ff1f277
Merge branch 'main' into ufs-dev-PR278
grantfirl Jun 20, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -702,14 +702,16 @@ end subroutine GFS_phys_time_vary_init
!>\section gen_GFS_phys_time_vary_timestep_init GFS_phys_time_vary_timestep_init General Algorithm
!> @{
subroutine GFS_phys_time_vary_timestep_init ( &
me, master, cnx, cny, isc, jsc, nrcm, im, levs, kdt, idate, nsswr, fhswr, lsswr, fhour, &
me, master, cnx, cny, isc, jsc, nrcm, im, levs, kdt, idate, cplflx, &
nsswr, fhswr, lsswr, fhour, &
imfdeepcnv, cal_pre, random_clds, nscyc, ntoz, h2o_phys, iaerclm, iccn, clstp, &
jindx1_o3, jindx2_o3, ddy_o3, ozpl, jindx1_h, jindx2_h, ddy_h, h2opl, iflip, &
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, in_nm, ccn_nm, fn_nml, &
imap, jmap, prsl, seed0, rann, nthrds, nx, ny, nsst, tile_num, nlunit, lsoil, lsoil_lsm,&
kice, ialb, isot, ivegsrc, input_nml_file, use_ufo, nst_anl, frac_grid, fhcyc, phour, &
lakefrac, min_seaice, min_lakeice, smc, slc, stc, smois, sh2o, tslb, tiice, tg3, tref, &
oceanfrac, lakefrac, min_seaice, min_lakeice, smc, slc, stc, smois, sh2o, tslb, tiice, &
tg3, tref, &
tsfc, tsfco, tisfc, hice, fice, facsf, facwf, alvsf, alvwf, alnsf, alnwf, zorli, zorll, &
zorlo, weasd, slope, snoalb, canopy, vfrac, vtype, stype,scolor, shdmin, shdmax, snowd, &
cv, cvb, cvt, oro, oro_uf, xlat_d, xlon_d, slmsk, landfrac, ozphys, h2ophys, &
Expand All @@ -723,7 +725,7 @@ subroutine GFS_phys_time_vary_timestep_init (
nsswr, imfdeepcnv, iccn, nscyc, ntoz, iflip
integer, intent(in) :: idate(:)
real(kind_phys), intent(in) :: fhswr, fhour
logical, intent(in) :: lsswr, cal_pre, random_clds, h2o_phys, iaerclm
logical, intent(in) :: lsswr, cal_pre, random_clds, h2o_phys, iaerclm, cplflx
real(kind_phys), intent(out) :: clstp
integer, intent(in), optional :: jindx1_o3(:), jindx2_o3(:), jindx1_h(:), jindx2_h(:)
real(kind_phys), intent(in), optional :: ddy_o3(:), ddy_h(:)
Expand Down Expand Up @@ -753,7 +755,7 @@ subroutine GFS_phys_time_vary_timestep_init (
character(len=*), intent(in) :: fn_nml
logical, intent(in) :: use_ufo, nst_anl, frac_grid
real(kind_phys), intent(in) :: fhcyc, phour, lakefrac(:), min_seaice, min_lakeice, &
xlat_d(:), xlon_d(:), landfrac(:)
xlat_d(:), xlon_d(:), landfrac(:),oceanfrac(:)
real(kind_phys), intent(inout) :: smc(:,:), slc(:,:), stc(:,:), tiice(:,:), tg3(:), &
tsfc(:), tsfco(:), tisfc(:), hice(:), fice(:), &
facsf(:), facwf(:), alvsf(:), alvwf(:), alnsf(:), alnwf(:), &
Expand Down Expand Up @@ -926,6 +928,7 @@ subroutine GFS_phys_time_vary_timestep_init (
tsfco, tisfc, hice, fice, facsf, facwf, alvsf, alvwf, alnsf, alnwf, &
zorli, zorll, zorlo, weasd, slope, snoalb, canopy, vfrac, vtype, &
stype, scolor, shdmin, shdmax, snowd, cv, cvb, cvt, oro, oro_uf, &
cplflx, oceanfrac, &
xlat_d, xlon_d, slmsk, imap, jmap, errmsg, errflg)
endif
endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1173,6 +1173,13 @@
dimensions = (4)
type = integer
intent = in
[cplflx]
standard_name = flag_for_surface_flux_coupling
long_name = flag controlling cplflx collection (default off)
units = flag
dimensions = ()
type = logical
intent = in
[nsswr]
standard_name = number_of_timesteps_between_shortwave_radiation_calls
long_name = number of timesteps between shortwave radiation calls
Expand Down Expand Up @@ -1638,6 +1645,14 @@
type = real
kind = kind_phys
intent = in
[oceanfrac]
standard_name = sea_area_fraction
long_name = fraction of horizontal grid area occupied by ocean
units = frac
dimensions = (horizontal_dimension)
type = real
kind = kind_phys
intent = in
[lakefrac]
standard_name = lake_area_fraction
long_name = fraction of horizontal grid area occupied by lake
Expand Down
74 changes: 67 additions & 7 deletions physics/Interstitials/UFS_SCM_NEPTUNE/gcycle.F90
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml,
tsfco, tisfc, hice, fice, facsf, facwf, alvsf, alvwf, alnsf, alnwf, &
zorli, zorll, zorlo, weasd, slope, snoalb, canopy, vfrac, vtype, &
stype, scolor, shdmin, shdmax, snowd, cv, cvb, cvt, oro, oro_uf, &
cplflx, oceanfrac, &
xlat_d, xlon_d, slmsk, imap, jmap, errmsg, errflg)
!
!
Expand All @@ -33,9 +34,9 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml,
integer, intent(in) :: idate(:), ialb, isot, ivegsrc
character(len = 64), intent(in) :: fn_nml
character(len=*), intent(in) :: input_nml_file(:)
logical, intent(in) :: use_ufo, nst_anl, frac_grid
logical, intent(in) :: use_ufo, nst_anl, frac_grid, cplflx
real(kind=kind_phys), intent(in) :: fhcyc, phour, landfrac(:), lakefrac(:), &
min_seaice, min_lakeice, &
min_seaice, min_lakeice,oceanfrac(:), &
xlat_d(:), xlon_d(:)
real(kind=kind_phys), intent(inout), optional :: &
smois(:,:), &
Expand Down Expand Up @@ -103,6 +104,17 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml,
STCFC1 (nx*ny*max(lsoil,lsoil_lsm)), &
SLCFC1 (nx*ny*max(lsoil,lsoil_lsm))

!
! declare the variables (arrays) for cplflx, surface type dependent gcycle changes
!
real(kind=kind_io8) :: &
hice_save (nx*ny), & ! sea or lake ice thickness
fice_save (nx*ny), & ! sea or lake ice fraction
snowd_save (nx*ny), & ! water equivalent snow depth
snoalb_save (nx*ny), & ! maximum snow albedo
tisfc_save (nx*ny), & ! surface skin temperature over (sea or lake) ice
weasd_save (nx*ny) ! water equiv of acc snow depth over land and (sea or lake) ice


real (kind=kind_io8) :: min_ice(nx*ny)
integer :: i_indx(nx*ny), j_indx(nx*ny)
Expand Down Expand Up @@ -131,11 +143,25 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml,
sig1t = 0.0_kind_phys
npts = nx*ny
!
! Some surface variables need to be updated by gcycle with coupled mode, and nsst mode dependent. A few variables are saved
! in order to be able to update them over the specific surface types only after call sfccycle
!
if ( cplflx ) then
hice_save = hice
fice_save = fice
snowd_save = snowd
snoalb_save = snoalb
tisfc_save = tisfc
weasd_save = weasd
endif

if ( nsst > 0 ) then
TSFFCS = tref
else
TSFFCS = tsfco
end if
endif


! integer to real/double precision
slpfcs = real(slope)
vegfcs = real(vtype)
Expand Down Expand Up @@ -251,11 +277,45 @@ subroutine gcycle (me, nthrds, nx, ny, isc, jsc, nsst, tile_num, nlunit, fn_nml,
close (nlunit)
#endif
!
if ( nsst > 0 ) then
tref = TSFFCS
! The gcycle resulted change is applied to some variables in the way of the coupled mode dependent, water surface type (ocean or lake)
! dependent and nsst mode dependent
!
if ( cplflx ) then
! In coupled mode, keep these variables the same as is (before sfccycle is called) over ocean
do ix=1,npts
if ( oceanfrac(ix) > 0.0_kind_phys ) then
hice(ix) = hice_save(ix)
fice(ix) = fice_save(ix)
snowd(ix) = snowd_save(ix)
snoalb(ix) = snoalb_save(ix)
tisfc(ix) = tisfc_save(ix)
weasd(ix) = weasd_save(ix)
endif
enddo
! In the coupled mode and when NSST is on, update tref over non-ocean
if ( nsst > 0 ) then
do ix=1,npts
if ( oceanfrac(ix) == 0.0_kind_phys ) then
tref(ix) = TSFFCS(ix)
endif
enddo
! In the coupled mode and when NSST is off, update tsfc and tsfco over non-ocean
else
do ix=1,npts
if ( oceanfrac(ix) == 0.0_kind_phys ) then
tsfc(ix) = TSFFCS(ix)
tsfco(ix) = TSFFCS(ix)
endif
enddo
endif
! The same as before (this modification) in uncoupled mode
else
tsfc = TSFFCS
tsfco = TSFFCS
if ( nsst > 0 ) then
tref = TSFFCS
else
tsfc = TSFFCS
tsfco = TSFFCS
endif
endif
!
! real/double precision to integer
Expand Down
59 changes: 37 additions & 22 deletions physics/SFC_Models/Land/Noahmp/module_sf_noahmp_glacier.F90
Original file line number Diff line number Diff line change
Expand Up @@ -2632,15 +2632,24 @@ subroutine snowwater_glacier (nsnow ,nsoil ,imelt ,dt ,sfctmp , & !in
snliq ,imelt ,ficeold, & !in
isnow ,dzsnso ) !inout

if(isnow < 0) & !when multi-layer
call combine_glacier (nsnow ,nsoil , & !in
isnow ,sh2o ,stc ,snice ,snliq , & !inout
dzsnso ,sice ,snowh ,sneqv , & !inout
ponding1 ,ponding2) !out

if(isnow < 0) & !when multi-layer
call divide_glacier (nsnow ,nsoil , & !in
isnow ,stc ,snice ,snliq ,dzsnso ) !inout
end if

call snowh2o_glacier (nsnow ,nsoil ,dt ,qsnfro ,qsnsub , & !in
qrain , & !in
isnow ,dzsnso ,snowh ,sneqv ,snice , & !inout
snliq ,sh2o ,sice ,stc , & !inout
ponding1 ,ponding2 ,fsh , & !inout
qsnbot ) !out

!set empty snow layers to zero

do iz = -nsnow+1, isnow
Expand All @@ -2651,16 +2660,9 @@ subroutine snowwater_glacier (nsnow ,nsoil ,imelt ,dt ,sfctmp , & !in
zsnso(iz) = 0.
enddo

call snowh2o_glacier (nsnow ,nsoil ,dt ,qsnfro ,qsnsub , & !in
qrain , & !in
isnow ,dzsnso ,snowh ,sneqv ,snice , & !inout
snliq ,sh2o ,sice ,stc , & !inout
ponding1 ,ponding2 ,fsh , & !inout
qsnbot ) !out

!to obtain equilibrium state of snow in glacier region

if(sneqv > mwd .and. isnow /= 0) then ! 100 mm -> maximum water depth
if(sneqv > mwd) then ! 100 mm -> maximum water depth
bdsnow = snice(0) / dzsnso(0)
snoflow = (sneqv - mwd)
snice(0) = snice(0) - snoflow
Expand All @@ -2670,7 +2672,7 @@ subroutine snowwater_glacier (nsnow ,nsoil ,imelt ,dt ,sfctmp , & !in

! sum up snow mass for layered snow

if(isnow /= 0) then
if(isnow < 0) then
sneqv = 0.
snowh = 0.
do iz = isnow+1,0
Expand Down Expand Up @@ -2746,7 +2748,7 @@ subroutine snowfall_glacier (nsoil ,nsnow ,dt ,qsnow ,snowhin , & !in

! creating a new layer

if(isnow == 0 .and. qsnow>0. .and. snowh >= 0.05) then
if(isnow == 0 .and. qsnow>0. .and. snowh >= 0.025) then
isnow = -1
newnode = 1
dzsnso(0)= snowh
Expand Down Expand Up @@ -2904,8 +2906,8 @@ subroutine combine_glacier (nsnow ,nsoil , & !in
real (kind=kind_phys) :: zwice !< total ice mass in snow
real (kind=kind_phys) :: zwliq !< total liquid water in snow
real (kind=kind_phys) :: dzmin(3) !< minimum of top snow layer
data dzmin /0.045, 0.05, 0.2/
! data dzmin /0.025, 0.025, 0.1/ ! mb: change limit
! data dzmin /0.045, 0.05, 0.2/
data dzmin /0.025, 0.025, 0.1/ ! mb: change limit
!-----------------------------------------------------------------------

isnow_old = isnow
Expand All @@ -2915,17 +2917,29 @@ subroutine combine_glacier (nsnow ,nsoil , & !in
if(j /= 0) then
snliq(j+1) = snliq(j+1) + snliq(j)
snice(j+1) = snice(j+1) + snice(j)
dzsnso(j+1) = dzsnso(j+1) + dzsnso(j)
else
if (isnow_old < -1) then
snliq(j-1) = snliq(j-1) + snliq(j)
snice(j-1) = snice(j-1) + snice(j)
dzsnso(j-1) = dzsnso(j-1) + dzsnso(j)
else
ponding1 = ponding1 + snliq(j) ! isnow will get set to zero below
sneqv = snice(j) ! ponding will get added to ponding from
snowh = dzsnso(j) ! phasechange which should be zero here
snliq(j) = 0.0 ! because there it was only calculated
snice(j) = 0.0 ! for thin snow
dzsnso(j) = 0.0
if(snice(j) >= 0.) then
ponding1 = snliq(j) ! isnow will get set to zero below; ponding1 will get
sneqv = snice(j) ! added to ponding from phasechange ponding should be
snowh = dzsnso(j) ! zero here because it was calculated for thin snow
else ! snice over-sublimated earlier
ponding1 = snliq(j) + snice(j)
if(ponding1 < 0.) then ! if snice and snliq sublimates remove from soil
sice(1) = max(0.0,sice(1)+ponding1/(dzsnso(1)*1000.))
ponding1 = 0.0
end if
sneqv = 0.0
snowh = 0.0
end if
snliq(j) = 0.0
snice(j) = 0.0
dzsnso(j) = 0.0
endif
! sh2o(1) = sh2o(1)+snliq(j)/(dzsnso(1)*1000.)
! sice(1) = sice(1)+snice(j)/(dzsnso(1)*1000.)
Expand Down Expand Up @@ -2968,8 +2982,8 @@ subroutine combine_glacier (nsnow ,nsoil , & !in
! check the snow depth - all snow gone
! the liquid water assumes ponding on soil surface.

! if (snowh < 0.025 .and. isnow < 0 ) then ! mb: change limit
if (snowh < 0.05 .and. isnow < 0 ) then
if (snowh < 0.025 .and. isnow < 0 ) then ! mb: change limit
! if (snowh < 0.05 .and. isnow < 0 ) then
isnow = 0
sneqv = zwice
ponding2 = ponding2 + zwliq ! limit of isnow < 0 means input ponding
Expand Down Expand Up @@ -3167,8 +3181,8 @@ subroutine divide_glacier (nsnow ,nsoil , & !in
zwliq, zwice, tsno(1))

! subdivide a new layer
! if (msno <= 2 .and. dz(2) > 0.20) then ! mb: change limit
if (msno <= 2 .and. dz(2) > 0.10) then
if (msno <= 2 .and. dz(2) > 0.20) then ! mb: change limit
! if (msno <= 2 .and. dz(2) > 0.10) then
msno = 3
dtdz = (tsno(1) - tsno(2))/((dz(1)+dz(2))/2.)
dz(2) = dz(2)/2.
Expand Down Expand Up @@ -3295,6 +3309,7 @@ subroutine snowh2o_glacier (nsnow ,nsoil ,dt ,qsnfro ,qsnsub , & !in
sneqv = sneqv - qsnsub*dt + qsnfro*dt
propor = sneqv/temp
snowh = max(0.,propor * snowh)
snowh = min(max(snowh,sneqv/500.0),sneqv/50.0) ! limit adjustment to a reasonable density
elseif(opt_gla == 2) then
fsh = fsh - (qsnfro-qsnsub)*hsub
qsnfro = 0.0
Expand Down
48 changes: 24 additions & 24 deletions physics/SFC_Models/Land/Noahmp/noahmpdrv.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1207,34 +1207,34 @@ subroutine noahmpdrv_run &
!

snow_cover_fraction = 1.0
temperature_leaf = undefined
canopy_ice = undefined
canopy_liquid = undefined
vapor_pres_canopy_air = undefined
temperature_canopy_air = undefined
canopy_wet_fraction = undefined
lake_water = undefined
depth_water_table = undefined
aquifer_water = undefined
saturated_water = undefined
leaf_carbon = undefined
root_carbon = undefined
stem_carbon = undefined
wood_carbon = undefined
soil_carbon_stable = undefined
soil_carbon_fast = undefined
leaf_area_index = undefined
stem_area_index = undefined
evaporation_canopy = undefined
transpiration = undefined
aquifer_water = undefined
precip_adv_heat_total = undefined
temperature_leaf = temperature_radiative
canopy_ice = 0.0
canopy_liquid = 0.0
vapor_pres_canopy_air = 2000.0
temperature_canopy_air = temperature_radiative
canopy_wet_fraction = 0.0
lake_water = 0.0
depth_water_table = 0.0
aquifer_water = 0.0
saturated_water = 0.0
leaf_carbon = 0.0
root_carbon = 0.0
stem_carbon = 0.0
wood_carbon = 0.0
soil_carbon_stable = 0.0
soil_carbon_fast = 0.0
leaf_area_index = 0.0
stem_area_index = 0.0
evaporation_canopy = 0.0
transpiration = 0.0
aquifer_water = 0.0
precip_adv_heat_total = 0.0
soil_moisture_wtd = 0.0
recharge = 0.0
deep_recharge = 0.0
eq_soil_water_vol = soil_moisture_vol
transpiration_heat = undefined
latent_heat_canopy = undefined
transpiration_heat = 0.0
latent_heat_canopy = 0.0
z0_total = 0.002
latent_heat_total = latent_heat_ground
t2mmp(i) = temperature_bare_2m
Expand Down