Skip to content

Commit

Permalink
Merge pull request #2 from NOAA-EMC/dev/emc
Browse files Browse the repository at this point in the history
update noaa-psd fork with EMC develop branch
  • Loading branch information
pjpegion authored Mar 2, 2020
2 parents b400a5c + db3acfb commit feaf652
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 20 deletions.
64 changes: 51 additions & 13 deletions driver/fvGFS/atmosphere.F90
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ module atmosphere_mod
use fv_nggps_diags_mod, only: fv_nggps_diag_init, fv_nggps_diag, fv_nggps_tavg
use fv_restart_mod, only: fv_restart, fv_write_restart
use fv_timing_mod, only: timing_on, timing_off
use fv_mp_mod, only: switch_current_Atm
use fv_mp_mod, only: switch_current_Atm, is_master
use fv_sg_mod, only: fv_subgrid_z
use fv_update_phys_mod, only: fv_update_phys
use fv_nwp_nudge_mod, only: fv_nwp_nudge_init, fv_nwp_nudge_end, do_adiabatic_init
Expand All @@ -194,6 +194,7 @@ module atmosphere_mod
a_step, p_step, current_time_in_seconds

use mpp_domains_mod, only: mpp_get_data_domain, mpp_get_compute_domain
use fv_grid_utils_mod, only: g_sum

implicit none
private
Expand Down Expand Up @@ -712,7 +713,7 @@ end subroutine atmosphere_dynamics

!>@brief The subroutine 'atmosphere_end' is an API for the termination of the
!! FV3 dynamical core responsible for writing out a restart and final diagnostic state.
subroutine atmosphere_end (Time, Grid_box)
subroutine atmosphere_end (Time, Grid_box, restart_endfcst)
#ifdef CCPP
#ifdef STATIC
! For static builds, the ccpp_physics_{init,run,finalize} calls
Expand All @@ -727,6 +728,7 @@ subroutine atmosphere_end (Time, Grid_box)
#endif
type (time_type), intent(in) :: Time
type(grid_box_type), intent(inout) :: Grid_box
logical, intent(in) :: restart_endfcst

#ifdef CCPP
integer :: ierr
Expand Down Expand Up @@ -754,7 +756,7 @@ subroutine atmosphere_end (Time, Grid_box)
call timing_off('FV_DIAG')
endif

call fv_end(Atm, grids_on_this_pe)
call fv_end(Atm, grids_on_this_pe, restart_endfcst)
deallocate (Atm)

deallocate( u_dt, v_dt, t_dt, pref, dum1d )
Expand Down Expand Up @@ -1394,6 +1396,7 @@ subroutine atmosphere_state_update (Time, IPD_Data, IAU_Data, Atm_block, flip_vc
integer :: i, j, ix, k, k1, n, w_diff, nt_dyn, iq
integer :: nb, blen, nwat, dnats, nq_adv
real(kind=kind_phys):: rcp, q0, qwat(nq), qt, rdt
real psum, qsum, psumb, qsumb, betad
Time_prev = Time
Time_next = Time + Time_step_atmos
rdt = 1.d0 / dt_atmos
Expand All @@ -1406,6 +1409,18 @@ subroutine atmosphere_state_update (Time, IPD_Data, IAU_Data, Atm_block, flip_vc
if( nq<3 ) call mpp_error(FATAL, 'GFS phys must have 3 interactive tracers')

if (IAU_Data%in_interval) then
if (IAU_Data%drymassfixer) then
! global mean total pressure and water before IAU
psumb = g_sum(Atm(n)%domain,sum(Atm(n)%delp(isc:iec,jsc:jec,1:npz),dim=3),&
isc,iec,jsc,jec,Atm(n)%ng,Atm(n)%gridstruct%area_64,1,reproduce=.true.)
qsumb = g_sum(Atm(n)%domain,&
sum(Atm(n)%delp(isc:iec,jsc:jec,1:npz)*sum(Atm(n)%q(isc:iec,jsc:jec,1:npz,1:nwat),4),dim=3),&
isc,iec,jsc,jec,Atm(n)%ng,Atm(n)%gridstruct%area_64,1,reproduce=.true.)
if (is_master()) then
print *,'dry ps before IAU/physics',psumb+Atm(n)%ptop-qsumb
endif
endif

! IAU increments are in units of 1/sec

! add analysis increment to u,v,t tendencies
Expand Down Expand Up @@ -1468,11 +1483,11 @@ subroutine atmosphere_state_update (Time, IPD_Data, IAU_Data, Atm_block, flip_vc
call fill_gfs(blen, npz, IPD_Data(nb)%Statein%prsi, IPD_Data(nb)%Stateout%gq0, 1.e-9_kind_phys)

do k = 1, npz
if(flip_vc) then
k1 = npz+1-k !reverse the k direction
else
k1 = k
endif
if(flip_vc) then
k1 = npz+1-k !reverse the k direction
else
k1 = k
endif
do ix = 1, blen
i = Atm_block%index(nb)%ii(ix)
j = Atm_block%index(nb)%jj(ix)
Expand Down Expand Up @@ -1514,11 +1529,11 @@ subroutine atmosphere_state_update (Time, IPD_Data, IAU_Data, Atm_block, flip_vc
!--- See Note in statein...
do iq = nq+1, ncnst
do k = 1, npz
if(flip_vc) then
k1 = npz+1-k !reverse the k direction
else
k1 = k
endif
if(flip_vc) then
k1 = npz+1-k !reverse the k direction
else
k1 = k
endif
do ix = 1, blen
i = Atm_block%index(nb)%ii(ix)
j = Atm_block%index(nb)%jj(ix)
Expand All @@ -1529,6 +1544,29 @@ subroutine atmosphere_state_update (Time, IPD_Data, IAU_Data, Atm_block, flip_vc

enddo ! nb-loop

! dry mass fixer in IAU interval following
! https://onlinelibrary.wiley.com/doi/full/10.1111/j.1600-0870.2007.00299.x
if (IAU_Data%in_interval .and. IAU_data%drymassfixer) then
! global mean total pressure
psum = g_sum(Atm(n)%domain,sum(Atm(n)%delp(isc:iec,jsc:jec,1:npz),dim=3),&
isc,iec,jsc,jec,Atm(n)%ng,Atm(n)%gridstruct%area_64,1,reproduce=.true.)
! global mean total water (before adjustment)
qsum = g_sum(Atm(n)%domain,&
sum(Atm(n)%delp(isc:iec,jsc:jec,1:npz)*sum(Atm(n)%q(isc:iec,jsc:jec,1:npz,1:nwat),4),dim=3),&
isc,iec,jsc,jec,Atm(n)%ng,Atm(n)%gridstruct%area_64,1,reproduce=.true.)
betad = (psum - (psumb - qsumb))/qsum
if (is_master()) then
print *,'dry ps after IAU/physics',psum+Atm(n)%ptop-qsum
endif
Atm(n)%q(:,:,:,1:nwat) = betad*Atm(n)%q(:,:,:,1:nwat)
!qsum = g_sum(Atm(n)%domain,&
! sum(Atm(n)%delp(isc:iec,jsc:jec,1:npz)*sum(Atm(n)%q(isc:iec,jsc:jec,1:npz,1:nwat),4),dim=3),&
! isc,iec,jsc,jec,Atm(n)%ng,Atm(n)%gridstruct%area_64,1)
!if (is_master()) then
! print *,'dry ps after iau_drymassfixer',psum+Atm(n)%ptop-qsum
!endif
endif

call timing_off('GFS_TENDENCIES')

w_diff = get_tracer_index (MODEL_ATMOS, 'w_diff' )
Expand Down
5 changes: 3 additions & 2 deletions model/fv_control.F90
Original file line number Diff line number Diff line change
Expand Up @@ -592,17 +592,18 @@ end subroutine fv_init

!>@brief The subroutine 'fv_end' terminates FV3, deallocates memory,
!! saves restart files, and stops I/O.
subroutine fv_end(Atm, grids_on_this_pe)
subroutine fv_end(Atm, grids_on_this_pe, restart_endfcst)

type(fv_atmos_type), intent(inout) :: Atm(:)
logical, intent(INOUT) :: grids_on_this_pe(:)
logical, intent(in) :: restart_endfcst

integer :: n

call timing_off('TOTAL')
call timing_prt( gid )

call fv_restart_end(Atm, grids_on_this_pe)
call fv_restart_end(Atm, grids_on_this_pe, restart_endfcst)
call fv_io_exit()

! Free temporary memory from sw_core routines
Expand Down
27 changes: 27 additions & 0 deletions model/fv_mapz.F90
Original file line number Diff line number Diff line change
Expand Up @@ -3465,12 +3465,25 @@ subroutine moist_cv(is,ie, isd,ied, jsd,jed, km, j, k, nwat, sphum, liq_wat, rai
enddo
case(4) ! K_warm_rain with fake ice
do i=is,ie
#ifndef CCPP
qv(i) = q(i,j,k,sphum)
qd(i) = q(i,j,k,liq_wat) + q(i,j,k,rainwat)
#ifdef MULTI_GASES
cvm(i) = (1.-(qv(i)+qd(i)))*cv_air*vicvqd(q(i,j,k,1:num_gas)) + qv(i)*cv_vap + qd(i)*c_liq
#else
cvm(i) = (1.-(qv(i)+qd(i)))*cv_air + qv(i)*cv_vap + qd(i)*c_liq
#endif
#else
qv(i) = q(i,j,k,sphum)
ql(i) = q(i,j,k,liq_wat) + q(i,j,k,rainwat)
qs(i) = q(i,j,k,ice_wat)
qd(i) = ql(i) + qs(i)
#ifdef MULTI_GASES
cvm(i) = (1.-(qv(i)+qd(i)))*cv_air*vicvqd(q(i,j,k,1:num_gas)) + qv(i)*cv_vap + ql(i)*c_liq + qs(i)*c_ice
#else
cvm(i) = (1.-(qv(i)+qd(i)))*cv_air + qv(i)*cv_vap + ql(i)*c_liq + qs(i)*c_ice
#endif

#endif
enddo
case(5)
Expand Down Expand Up @@ -3574,12 +3587,26 @@ subroutine moist_cp(is,ie, isd,ied, jsd,jed, km, j, k, nwat, sphum, liq_wat, rai
enddo
case(4) ! K_warm_rain scheme with fake ice
do i=is,ie
#ifndef CCPP
qv(i) = q(i,j,k,sphum)
qd(i) = q(i,j,k,liq_wat) + q(i,j,k,rainwat)
#ifdef MULTI_GASES
cpm(i) = (1.-(qv(i)+qd(i)))*cp_air*vicpqd(q(i,j,k,:)) + qv(i)*cp_vapor + qd(i)*c_liq
#else
cpm(i) = (1.-(qv(i)+qd(i)))*cp_air + qv(i)*cp_vapor + qd(i)*c_liq
#endif
#else
qv(i) = q(i,j,k,sphum)
ql(i) = q(i,j,k,liq_wat) + q(i,j,k,rainwat)
qs(i) = q(i,j,k,ice_wat)
qd(i) = ql(i) + qs(i)
#ifdef MULTI_GASES
cpm(i) = (1.-(qv(i)+qd(i)))*cp_air*vicpqd(q(i,j,k,:)) + qv(i)*cp_vapor + ql(i)*c_liq + qs(i)*c_ice
#else
cpm(i) = (1.-(qv(i)+qd(i)))*cp_air + qv(i)*cp_vapor + ql(i)*c_liq + qs(i)*c_ice
#endif


#endif
enddo
case(5)
Expand Down
6 changes: 6 additions & 0 deletions model/fv_regional_bc.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,12 @@ subroutine start_regional_restart(Atm &
endif
!
!-----------------------------------------------------------------------
!*** Get the source of the input data.
!-----------------------------------------------------------------------
!
call get_data_source(data_source,Atm%flagstruct%regional)
!
!-----------------------------------------------------------------------
!*** Preliminary setup for the forecast.
!-----------------------------------------------------------------------
!
Expand Down
72 changes: 72 additions & 0 deletions model/fv_sg.F90
Original file line number Diff line number Diff line change
Expand Up @@ -299,13 +299,28 @@ subroutine fv_subgrid_z( isd, ied, jsd, jed, is, ie, js, je, km, nq, dt, &
enddo
elseif ( nwat==4 ) then
do i=is,ie
#ifndef CCPP
q_liq = q0(i,k,liq_wat) + q0(i,k,rainwat)
#ifdef MULTI_GASES
cpm(i) = (1.-(q0(i,k,sphum)+q_liq))*cp_air*vicpqd(q0(i,k,:)) + q0(i,k,sphum)*cp_vapor + q_liq*c_liq
cvm(i) = (1.-(q0(i,k,sphum)+q_liq))*cv_air*vicvqd(q0(i,k,:)) + q0(i,k,sphum)*cv_vap + q_liq*c_liq
#else
cpm(i) = (1.-(q0(i,k,sphum)+q_liq))*cp_air + q0(i,k,sphum)*cp_vapor + q_liq*c_liq
cvm(i) = (1.-(q0(i,k,sphum)+q_liq))*cv_air + q0(i,k,sphum)*cv_vap + q_liq*c_liq
#endif

#else
q_liq = q0(i,k,liq_wat) + q0(i,k,rainwat)
q_sol = q0(i,k,ice_wat)
#ifdef MULTI_GASES
cpm(i) = (1.-(q0(i,k,sphum)+q_liq+q_sol))*cp_air*vicpqd(q0(i,k,:)) + q0(i,k,sphum)*cp_vapor + q_liq*c_liq + q_sol*c_ice
cvm(i) = (1.-(q0(i,k,sphum)+q_liq+q_sol))*cv_air*vicvqd(q0(i,k,:)) + q0(i,k,sphum)*cv_vap + q_liq*c_liq + q_sol*c_ice
#else
cpm(i) = (1.-(q0(i,k,sphum)+q_liq+q_sol))*cp_air + q0(i,k,sphum)*cp_vapor + q_liq*c_liq + q_sol*c_ice
cvm(i) = (1.-(q0(i,k,sphum)+q_liq+q_sol))*cv_air + q0(i,k,sphum)*cv_vap + q_liq*c_liq + q_sol*c_ice
#endif


#endif
enddo
elseif ( nwat==5 ) then
Expand Down Expand Up @@ -382,7 +397,11 @@ subroutine fv_subgrid_z( isd, ied, jsd, jed, is, ie, js, je, km, nq, dt, &
elseif ( nwat==4 ) then
do k=1,kbot
do i=is,ie
#ifndef CCPP
qcon(i,k) = q0(i,k,liq_wat) + q0(i,k,rainwat)
#else
qcon(i,k) = q0(i,k,liq_wat) + q0(i,k,rainwat) + q0(i,k,ice_wat)
#endif
enddo
enddo
elseif ( nwat==5 ) then
Expand Down Expand Up @@ -451,7 +470,12 @@ subroutine fv_subgrid_z( isd, ied, jsd, jed, is, ie, js, je, km, nq, dt, &
elseif ( nwat==3 ) then ! AM3/AM4
qcon(i,km1) = q0(i,km1,liq_wat) + q0(i,km1,ice_wat)
elseif ( nwat==4 ) then ! K_warm_rain scheme with fake ice
#ifndef CCPP
qcon(i,km1) = q0(i,km1,liq_wat) + q0(i,km1,rainwat)
#else
qcon(i,km1) = q0(i,km1,liq_wat) + q0(i,km1,ice_wat) + &
q0(i,km1,rainwat)
#endif
elseif ( nwat==5 ) then ! K_warm_rain scheme with fake ice
qcon(i,km1) = q0(i,km1,liq_wat) + q0(i,km1,ice_wat) + &
q0(i,km1,snowwat) + q0(i,km1,rainwat)
Expand Down Expand Up @@ -572,13 +596,27 @@ subroutine fv_subgrid_z( isd, ied, jsd, jed, is, ie, js, je, km, nq, dt, &
enddo
elseif ( nwat == 4 ) then
do i=is,ie
#ifndef CCPP
q_liq = q0(i,kk,liq_wat) + q0(i,kk,rainwat)
#ifdef MULTI_GASES
cpm(i) = (1.-(q0(i,kk,sphum)+q_liq))*cp_air*vicpqd(q0(i,kk,:)) + q0(i,kk,sphum)*cp_vapor + q_liq*c_liq
cvm(i) = (1.-(q0(i,kk,sphum)+q_liq))*cv_air*vicvqd(q0(i,kk,:)) + q0(i,kk,sphum)*cv_vap + q_liq*c_liq
#else
cpm(i) = (1.-(q0(i,kk,sphum)+q_liq))*cp_air + q0(i,kk,sphum)*cp_vapor + q_liq*c_liq
cvm(i) = (1.-(q0(i,kk,sphum)+q_liq))*cv_air + q0(i,kk,sphum)*cv_vap + q_liq*c_liq
#endif
#else
q_liq = q0(i,kk,liq_wat) + q0(i,kk,rainwat)
q_sol = q0(i,kk,ice_wat)
#ifdef MULTI_GASES
cpm(i) = (1.-(q0(i,kk,sphum)+q_liq+q_sol))*cp_air*vicpqd(q0(i,kk,:)) + q0(i,kk,sphum)*cp_vapor + q_liq*c_liq + q_sol*c_ice
cvm(i) = (1.-(q0(i,kk,sphum)+q_liq+q_sol))*cv_air*vicvqd(q0(i,kk,:)) + q0(i,kk,sphum)*cv_vap + q_liq*c_liq + q_sol*c_ice
#else
cpm(i) = (1.-(q0(i,kk,sphum)+q_liq+q_sol))*cp_air + q0(i,kk,sphum)*cp_vapor + q_liq*c_liq + q_sol*c_ice
cvm(i) = (1.-(q0(i,kk,sphum)+q_liq+q_sol))*cv_air + q0(i,kk,sphum)*cv_vap + q_liq*c_liq + q_sol*c_ice
#endif


#endif
enddo
elseif ( nwat == 5 ) then
Expand Down Expand Up @@ -850,13 +888,26 @@ subroutine fv_subgrid_z( isd, ied, jsd, jed, is, ie, js, je, km, nq, dt, &
enddo
elseif ( nwat==4 ) then
do i=is,ie
#ifndef CCPP
q_liq = q0(i,k,liq_wat) + q0(i,k,rainwat)
#ifdef MULTI_GASES
cpm(i) = (1.-(q0(i,k,sphum)+q_liq))*cp_air*vicpqd(q0(i,k,:)) + q0(i,k,sphum)*cp_vapor + q_liq*c_liq
cvm(i) = (1.-(q0(i,k,sphum)+q_liq))*cv_air*vicvqd(q0(i,k,:)) + q0(i,k,sphum)*cv_vap + q_liq*c_liq
#else
cpm(i) = (1.-(q0(i,k,sphum)+q_liq))*cp_air + q0(i,k,sphum)*cp_vapor + q_liq*c_liq
cvm(i) = (1.-(q0(i,k,sphum)+q_liq))*cv_air + q0(i,k,sphum)*cv_vap + q_liq*c_liq
#endif
#else
q_liq = q0(i,k,liq_wat) + q0(i,k,rainwat)
q_sol = q0(i,k,ice_wat)
#ifdef MULTI_GASES
cpm(i) = (1.-(q0(i,k,sphum)+q_liq+q_sol))*cp_air*vicpqd(q0(i,k,:)) + q0(i,k,sphum)*cp_vapor + q_liq*c_liq + q_sol*c_ice
cvm(i) = (1.-(q0(i,k,sphum)+q_liq+q_sol))*cv_air*vicvqd(q0(i,k,:)) + q0(i,k,sphum)*cv_vap + q_liq*c_liq + q_sol*c_ice
#else
cpm(i) = (1.-(q0(i,k,sphum)+q_liq+q_sol))*cp_air + q0(i,k,sphum)*cp_vapor + q_liq*c_liq + q_sol*c_ice
cvm(i) = (1.-(q0(i,k,sphum)+q_liq+q_sol))*cv_air + q0(i,k,sphum)*cv_vap + q_liq*c_liq + q_sol*c_ice
#endif

#endif
enddo
elseif ( nwat==5 ) then
Expand Down Expand Up @@ -933,7 +984,11 @@ subroutine fv_subgrid_z( isd, ied, jsd, jed, is, ie, js, je, km, nq, dt, &
elseif ( nwat==4 ) then
do k=1,kbot
do i=is,ie
#ifndef CCPP
qcon(i,k) = q0(i,k,liq_wat) + q0(i,k,rainwat)
#else
qcon(i,k) = q0(i,k,liq_wat) + q0(i,k,rainwat) + q0(i,k,ice_wat)
#endif
enddo
enddo
elseif ( nwat==5 ) then
Expand Down Expand Up @@ -998,7 +1053,11 @@ subroutine fv_subgrid_z( isd, ied, jsd, jed, is, ie, js, je, km, nq, dt, &
elseif ( nwat==3 ) then ! AM3/AM4
qcon(i,km1) = q0(i,km1,liq_wat) + q0(i,km1,ice_wat)
elseif ( nwat==4 ) then ! K_warm_rain scheme with fake ice
#ifndef CCPP
qcon(i,km1) = q0(i,km1,liq_wat) + q0(i,km1,rainwat)
#else
qcon(i,km1) = q0(i,km1,liq_wat) + q0(i,km1,rainwat) + q0(i,km1,ice_wat)
#endif
elseif ( nwat==5 ) then
qcon(i,km1) = q0(i,km1,liq_wat) + q0(i,km1,ice_wat) + &
q0(i,km1,snowwat) + q0(i,km1,rainwat)
Expand Down Expand Up @@ -1118,13 +1177,26 @@ subroutine fv_subgrid_z( isd, ied, jsd, jed, is, ie, js, je, km, nq, dt, &
enddo
elseif ( nwat == 4 ) then
do i=is,ie
#ifndef CCPP
q_liq = q0(i,kk,liq_wat) + q0(i,kk,rainwat)
#ifdef MULTI_GASES
cpm(i) = (1.-(q0(i,kk,sphum)+q_liq))*cp_air*vicpqd(q0(i,kk,:)) + q0(i,kk,sphum)*cp_vapor + q_liq*c_liq
cvm(i) = (1.-(q0(i,kk,sphum)+q_liq))*cv_air*vicvqd(q0(i,kk,:)) + q0(i,kk,sphum)*cv_vap + q_liq*c_liq
#else
cpm(i) = (1.-(q0(i,kk,sphum)+q_liq))*cp_air + q0(i,kk,sphum)*cp_vapor + q_liq*c_liq
cvm(i) = (1.-(q0(i,kk,sphum)+q_liq))*cv_air + q0(i,kk,sphum)*cv_vap + q_liq*c_liq
#endif
#else
q_liq = q0(i,kk,liq_wat) + q0(i,kk,rainwat)
q_sol = q0(i,kk,ice_wat)
#ifdef MULTI_GASES
cpm(i) = (1.-(q0(i,kk,sphum)+q_liq+q_sol))*cp_air*vicpqd(q0(i,kk,:)) + q0(i,kk,sphum)*cp_vapor + q_liq*c_liq + q_sol*c_ice
cvm(i) = (1.-(q0(i,kk,sphum)+q_liq+q_sol))*cv_air*vicvqd(q0(i,kk,:)) + q0(i,kk,sphum)*cv_vap + q_liq*c_liq + q_sol*c_ice
#else
cpm(i) = (1.-(q0(i,kk,sphum)+q_liq+q_sol))*cp_air + q0(i,kk,sphum)*cp_vapor + q_liq*c_liq + q_sol*c_ice
cvm(i) = (1.-(q0(i,kk,sphum)+q_liq+q_sol))*cv_air + q0(i,kk,sphum)*cv_vap + q_liq*c_liq + q_sol*c_ice
#endif

#endif
enddo
elseif ( nwat == 5 ) then
Expand Down
2 changes: 2 additions & 0 deletions tools/fv_iau_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ module fv_iau_mod
real,allocatable :: delz_inc(:,:,:)
real,allocatable :: tracer_inc(:,:,:,:)
logical :: in_interval = .false.
logical :: drymassfixer = .false.
end type iau_external_data_type
type iau_state_type
type(iau_internal_data_type):: inc1
Expand Down Expand Up @@ -280,6 +281,7 @@ subroutine IAU_initialize (IPD_Control, IAU_Data,Init_parm)
call read_iau_forcing(IPD_Control,iau_state%inc2,'INPUT/'//trim(IPD_Control%iau_inc_files(2)))
endif
! print*,'in IAU init',dt,rdt
IAU_data%drymassfixer = IPD_control%iau_drymassfixer

end subroutine IAU_initialize

Expand Down
Loading

0 comments on commit feaf652

Please sign in to comment.