#define MODHS 1
subroutine tphysidl(ztodt, state, tend) 1,18
!-----------------------------------------------------------------------
!
! Purpose:
! algorithm 1: Held/Suarez IDEALIZED physics
! algorithm 2: Held/Suarez IDEALIZED physics (Williamson modified stratosphere
! algorithm 3: Held/Suarez IDEALIZED physics (Lin/Williamson modified strato/meso-sphere
! algorithm 4: Boer/Denis IDEALIZED physics
!
! Author: J. Olson
!
!-----------------------------------------------------------------------
use shr_kind_mod
, only: r8 => shr_kind_r8
use ppgrid
, only: pcols, pver
use phys_grid
, only: get_rlat_all_p
use physics_types
, only: physics_state, physics_tend, physics_ptend, &
physics_ptend_init, physics_update
use physconst
, only: gravit, cappa, rair, cpair
use abortutils
, only: endrun
use hycoef
, only: ps0, etamid
use cam_history
, only: outfld
use cam_logfile
, only: iulog
use time_manager
, only: get_nstep
use check_energy
, only: check_energy_chng
implicit none
!
! Input arguments
!
real(r8), intent(in) :: ztodt ! Two times model timestep (2 delta-t)
type(physics_state), intent(inout) :: state
!
! Output arguments
!
type(physics_tend ), intent(inout) :: tend
!
!---------------------------Local workspace-----------------------------
!
type(physics_ptend) :: ptend
integer :: lchnk ! chunk identifier
integer :: ncol ! number of atmospheric columns
integer :: nstep ! timestep number
real(r8) clat(pcols) ! latitudes(radians) for columns
real(r8) pmid(pcols,pver) ! mid-point pressure
integer i,k ! Longitude, level indices
real(r8) tmp ! temporary
real(r8) kf ! 1./efolding_time for wind dissipation
real(r8) ka ! 1./efolding_time for temperature diss.
real(r8) kaa ! 1./efolding_time for temperature diss.
real(r8) ks ! 1./efolding_time for temperature diss.
real(r8) kv ! 1./efolding_time (normalized) for wind
real(r8) kt ! 1./efolding_time for temperature diss.
real(r8) trefa ! "radiative equilibrium" T
real(r8) trefc ! used in calc of "radiative equilibrium" T
real(r8) cossq(pcols) ! coslat**2
real(r8) cossqsq(pcols) ! coslat**4
real(r8) sinsq(pcols) ! sinlat**2
real(r8) onemsig ! 1. - sigma_reference
real(r8) efoldf ! efolding time for wind dissipation
real(r8) efolda ! efolding time for T dissipation
real(r8) efoldaa ! efolding time for T dissipation
real(r8) efolds ! efolding time for T dissipation
real(r8) efold_strat ! efolding time for T dissipation in Strat
real(r8) efold_meso ! efolding time for T dissipation in Meso
real(r8) efoldv ! efolding time for wind dissipation
real(r8) p_infint ! effective top of model
real(r8) constw ! constant
real(r8) lapsew ! lapse rate
real(r8) p0strat ! threshold pressure
real(r8) phi0 ! threshold latitude
real(r8) dphi0 ! del-latitude
real(r8) a0 ! coefficient
real(r8) aeq ! 100 mb
real(r8) apole ! 2 mb
real(r8) pi ! 3.14159...
real(r8) coslat(pcols) ! cosine(latitude)
real(r8) acoslat ! abs(acos(coslat))
real(r8) constc ! constant
real(r8) lapsec ! lapse rate
real(r8) lapse ! lapse rate
real(r8) h0 ! scale height (7 km)
real(r8) sigmab ! threshold sigma level
real(r8) pressmb ! model pressure in mb
real(r8) t00 ! minimum reference temperature
integer idlflag ! Flag to choose which idealized physics
real(r8) :: zero(pcols)
!
!-----------------------------------------------------------------------
!
idlflag = 1
lchnk = state%lchnk
ncol = state%ncol
nstep = get_nstep
()
zero = 0._r8
call get_rlat_all_p
(lchnk, ncol, clat)
do i=1,ncol
coslat (i) = cos(clat(i))
sinsq (i) = sin(clat(i))*sin(clat(i))
cossq (i) = coslat(i)*coslat(i)
cossqsq(i) = cossq (i)*cossq (i)
end do
do k = 1, pver
do i = 1, ncol
pmid(i,k) = state%pmid(i,k)
end do
end do
! initialize individual parameterization tendencies
call physics_ptend_init
(ptend)
ptend%name = 'tphysidl'
ptend%ls = .true.
ptend%lu = .true.
ptend%lv = .true.
if (idlflag == 1) then
!
!-----------------------------------------------------------------------
!
! Held/Suarez IDEALIZED physics algorithm:
!
! Held, I. M., and M. J. Suarez, 1994: A proposal for the
! intercomparison of the dynamical cores of atmospheric general
! circulation models.
! Bulletin of the Amer. Meteor. Soc., vol. 75, pp. 1825-1830.
!
!-----------------------------------------------------------------------
!
! Compute idealized radiative heating rates (as dry static energy)
!
efoldf = 1._r8
efolda = 40._r8
efolds = 4._r8
sigmab = 0.7_r8
t00 = 200._r8
!
onemsig = 1._r8 - sigmab
!
ka = 1._r8/(86400._r8*efolda)
ks = 1._r8/(86400._r8*efolds)
!
do k=1,pver
if (etamid(k) > sigmab) then
do i=1,ncol
kt = ka + (ks - ka)*cossqsq(i)*(etamid(k) - sigmab)/onemsig
#ifdef MODHS
tmp = kt/(1._r8+ ztodt*kt)
#else
tmp = kt
#endif
trefc = 315._r8 - 60._r8*sinsq(i)
trefa = (trefc - 10._r8*cossq(i)*log((pmid(i,k)/ps0)))*(pmid(i,k)/ps0)**cappa
trefa = max(t00,trefa)
ptend%s(i,k) = (trefa - state%t(i,k))*tmp*cpair
end do
else
#ifdef MODHS
tmp = ka/(1._r8+ ztodt*ka)
#else
tmp = ka
#endif
do i=1,ncol
trefc = 315._r8 - 60._r8*sinsq(i)
trefa = (trefc - 10._r8*cossq(i)*log((pmid(i,k)/ps0)))*(pmid(i,k)/ps0)**cappa
trefa = max(t00,trefa)
ptend%s(i,k) = (trefa - state%t(i,k))*tmp*cpair
end do
endif
end do
!
! Add diffusion near the surface for the wind fields
!
do k=1,pver
do i=1,pcols
ptend%u(i,k) = 0._r8
ptend%v(i,k) = 0._r8
end do
end do
kf = 1._r8/(86400._r8*efoldf)
!
do k=1,pver
if (etamid(k) > sigmab) then
kv = kf*(etamid(k) - sigmab)/onemsig
#ifdef MODHS
tmp = -kv/(1._r8+ ztodt*kv)
#else
tmp = -kv
#endif
do i=1,ncol
ptend%u(i,k) = tmp*state%u(i,k)
ptend%v(i,k) = tmp*state%v(i,k)
end do
endif
end do
elseif (idlflag == 2) then
!
!-----------------------------------------------------------------------
!
! Modified Held/Suarez IDEALIZED physics algorithm
! (modified with Williamson stratosphere):
!
! Williamson, D. L., J. G. Olson and B. A. Boville, 1998: A comparison
! of semi--Lagrangian and Eulerian tropical climate simulations.
! Mon. Wea. Rev., vol 126, pp. 1001-1012.
!
!-----------------------------------------------------------------------
!
! Compute idealized radiative heating rates (as dry static energy)
!
efoldf = 1._r8
efolda = 40._r8
efoldaa = 40._r8
efolds = 4._r8
sigmab = 0.7_r8
t00 = 200._r8
!
onemsig = 1._r8 - sigmab
!
ka = 1._r8/(86400._r8*efolda)
kaa = 1._r8/(86400._r8*efoldaa)
ks = 1._r8/(86400._r8*efolds)
!
pi = 4._r8*atan(1._r8)
phi0 = 60._r8*pi/180._r8
dphi0 = 15._r8*pi/180._r8
a0 = 2.65_r8/dphi0
aeq = 10000._r8
apole = 200._r8
lapsew = -3.345e-03_r8
constw = rair*lapsew/gravit
lapsec = 2.00e-03_r8
constc = rair*lapsec/gravit
do k=1,pver
if (etamid(k) > sigmab) then
do i=1,ncol
kt = ka + (ks - ka)*cossqsq(i)*(etamid(k) - sigmab)/onemsig
acoslat = abs(acos(coslat(i)))
p0strat = aeq - (aeq - apole)*0.5_r8*(1._r8 + tanh(a0*(acoslat - phi0)))
tmp = kt/(1._r8+ ztodt*kt)
trefc = 315._r8 - 60._r8*sinsq(i)
trefa = (trefc - 10._r8*cossq(i)*log((pmid(i,k)/ps0)))*(pmid(i,k)/ps0)** &
cappa
trefa = max(t00,trefa)
if (pmid(i,k) < 10000._r8) then
trefa = t00*((pmid(i,k)/10000._r8))**constc
tmp = kaa/(1._r8+ ztodt*kaa)
endif
if (pmid(i,k) < p0strat) then
trefa = trefa + t00*( ((pmid(i,k)/p0strat))**constw - 1._r8 )
tmp = kaa/(1._r8+ ztodt*kaa)
endif
ptend%s(i,k) = (trefa - state%t(i,k))*tmp*cpair
end do
else
do i=1,ncol
acoslat = abs(acos(coslat(i)))
p0strat = aeq - (aeq - apole)*0.5_r8*(1._r8 + tanh(a0*(acoslat - phi0)))
tmp = ka/(1._r8+ ztodt*ka)
trefc = 315._r8 - 60._r8*sinsq(i)
trefa = (trefc - 10._r8*cossq(i)*log((pmid(i,k)/ps0)))*(pmid(i,k)/ps0)** &
cappa
trefa = max(t00,trefa)
if (pmid(i,k) < 10000._r8) then
trefa = t00*((pmid(i,k)/10000._r8))**constc
tmp = kaa/(1._r8+ ztodt*kaa)
endif
if (pmid(i,k) < p0strat) then
trefa = trefa + t00*( ((pmid(i,k)/p0strat))**constw - 1._r8 )
tmp = kaa/(1._r8+ ztodt*kaa)
endif
ptend%s(i,k) = (trefa - state%t(i,k))*tmp*cpair
end do
endif
end do
!
! Add diffusion near the surface for the wind fields
!
do k=1,pver
do i=1,pcols
ptend%u(i,k) = 0._r8
ptend%v(i,k) = 0._r8
end do
end do
kf = 1._r8/(86400._r8*efoldf)
!
do k=1,pver
if (etamid(k) > sigmab) then
kv = kf*(etamid(k) - sigmab)/onemsig
tmp = -kv/(1._r8+ ztodt*kv)
do i=1,ncol
ptend%u(i,k) = tmp*state%u(i,k)
ptend%v(i,k) = tmp*state%v(i,k)
end do
endif
end do
elseif (idlflag == 3) then
!
!-----------------------------------------------------------------------
!
! Held/Suarez IDEALIZED physics algorithm:
! (modified with Lin/Williamson stratosphere/mesosphere):
!
! Held, I. M., and M. J. Suarez, 1994: A proposal for the
! intercomparison of the dynamical cores of atmospheric general
! circulation models.
! Bulletin of the Amer. Meteor. Soc., vol. 75, pp. 1825-1830.
!
!-----------------------------------------------------------------------
!
! Compute idealized radiative heating rates (as dry static energy)
!
efoldf = 1._r8
efolda = 40._r8
efolds = 4._r8
efold_strat = 40._r8
efold_meso = 10._r8
efoldv = 0.5_r8
sigmab = 0.7_r8
lapse = 0.00225_r8
h0 = 7000._r8
t00 = 200._r8
p_infint = 0.01_r8
!
onemsig = 1._r8 - sigmab
!
ka = 1._r8/(86400._r8*efolda)
ks = 1._r8/(86400._r8*efolds)
!
do k=1,pver
if (etamid(k) > sigmab) then
do i=1,ncol
kt = ka + (ks - ka)*cossqsq(i)*(etamid(k) - sigmab)/onemsig
tmp = kt/(1._r8+ ztodt*kt)
trefc = 315._r8 - 60._r8*sinsq(i)
trefa = (trefc - 10._r8*cossq(i)*log((pmid(i,k)/ps0)))*(pmid(i,k)/ps0)**cappa
trefa = max(t00,trefa)
ptend%s(i,k) = (trefa - state%t(i,k))*tmp*cpair
end do
else
do i=1,ncol
tmp = ka/(1._r8+ ztodt*ka)
pressmb = pmid(i,k)*0.01_r8
trefc = 315._r8 - 60._r8*sinsq(i)
trefa = (trefc - 10._r8*cossq(i)*log((pmid(i,k)/ps0)))*(pmid(i,k)/ps0)** &
cappa
trefa = max(t00,trefa)
if (pressmb <= 100._r8 .and. pressmb > 1._r8) then
trefa = t00 + lapse*h0*coslat(i)*log(100._r8/pressmb)
tmp = (efold_strat-efold_meso)*log(pressmb)/log(100._r8)
tmp = efold_meso + tmp
tmp = 1._r8/(86400._r8*tmp)
tmp = tmp/(1._r8+ ztodt*tmp)
endif
if (pressmb <= 1._r8 .and. pressmb > 0.01_r8) then
trefa = t00 + lapse*h0*coslat(i)*log(100._r8*pressmb)
tmp = 1._r8/(86400._r8*efold_meso)
tmp = tmp/(1._r8+ ztodt*tmp)
endif
if (pressmb <= 0.01_r8) then
tmp = 1._r8/(86400._r8*efold_meso)
tmp = tmp/(1._r8+ ztodt*tmp)
endif
ptend%s(i,k) = (trefa - state%t(i,k))*tmp*cpair
end do
endif
end do
!
! Add diffusion near the surface for the wind fields
!
do k=1,pver
do i=1,pcols
ptend%u(i,k) = 0._r8
ptend%v(i,k) = 0._r8
end do
end do
kf = 1._r8/(86400._r8*efoldf)
!
do k=1,pver
if (etamid(k) > sigmab) then
kv = kf*(etamid(k) - sigmab)/onemsig
tmp = -kv/(1._r8+ ztodt*kv)
do i=1,ncol
ptend%u(i,k) = tmp*state%u(i,k)
ptend%v(i,k) = tmp*state%v(i,k)
end do
else
do i=1,ncol
pressmb = pmid(i,k)*0.01_r8
if (pressmb <= 100._r8) then
kv = 1._r8/(86400._r8*efoldv)
tmp = 1._r8 + tanh(1.5_r8*log10(p_infint/pressmb))
kv = kv*tmp
tmp = -kv/(1._r8+ ztodt*kv)
ptend%u(i,k) = tmp*state%u(i,k)
ptend%v(i,k) = tmp*state%v(i,k)
endif
end do
endif
end do
else
write(iulog,*) 'TPHYSIDL: flag for choosing desired type of idealized ', &
'physics ("idlflag") is set incorrectly.'
write(iulog,*) 'The valid options are 1, 2, or 3.'
write(iulog,*) 'idlflag is currently set to: ',idlflag
call endrun
('tphysidl: invalid option')
endif
! update the state and total physics tendency
call physics_update
(state, tend, ptend, ztodt)
! Can't turn on conservation error messages unless the appropriate heat
! surface flux is computed and supplied as an argument to
! check_energy_chng to account for how the ideal physics forcings are
! changing the total energy.
call check_energy_chng
(state, tend, "tphysidl", nstep, ztodt, zero, zero, zero, zero)
call outfld
('QRS', tend%dtdt, pcols, lchnk)
end subroutine tphysidl