module comhd 1,5
!-----------------------------------------------------------------------
!
! Purpose: horizontal diffusion module
!
! Author: CCM Core Group
!
!-----------------------------------------------------------------------
!-----------------------------------------------------------------------
!- use statements ------------------------------------------------------
!-----------------------------------------------------------------------
use shr_kind_mod
, only: r8 => shr_kind_r8
use infnan
, only: inf
use pspect
, only: pnmax
use pmgrid
, only: plev
use abortutils
, only: endrun
!-----------------------------------------------------------------------
!- module boilerplate --------------------------------------------------
!-----------------------------------------------------------------------
implicit none
private ! Make the default access private
save
!-----------------------------------------------------------------------
! Public interfaces ----------------------------------------------------
!-----------------------------------------------------------------------
public comhd_defaultopts ! get default runtime options
public comhd_setopts ! set runtime options
!-----------------------------------------------------------------------
! Public data ----------------------------------------------------------
!-----------------------------------------------------------------------
!
real(r8), public :: cnfac ! Courant num factor(multiply by max |V|)
real(r8), public :: cnlim ! Maximum allowable courant number
real(r8), public :: dif2 = inf ! Del^2 diffusion coeff. (also namelist
! variable)
real(r8), public :: dif4 = inf ! Del^4 diffusion coeff. (also namelist
! variable)
real(r8), public :: hdfsd2(pnmax) ! Del^2 mult. for each wave
! (vorticity-divergence)
real(r8), public :: hdfst2(pnmax) ! Del^2 multiplier for each wave (t-q)
real(r8), public :: hdfsd4(pnmax) ! Del^4 mult. for each wave
! (vorticity-divergence)
real(r8), public :: hdfst4(pnmax) ! Del^4 multiplier for each wave (t-q)
real(r8), public :: hdiftq(pnmax,plev) ! Temperature-tracer diffusion
! factors
real(r8), public :: hdifzd(pnmax,plev) ! Vorticity-divergence diffusion
! factors
!
integer, public :: kmnhd4 ! Top level for del^4 diffusion
integer, public :: kmxhd2 ! Bottom level for increased del^2 diffusion
! The Courant limiter is only used in eul dycore.
! Number of levels to apply Courant limiter (also in namelist)
integer, private, parameter :: def_kmxhdc = 5 ! default
integer, public :: kmxhdc = def_kmxhdc
integer, public :: nindex(plev) ! Starting index for spectral truncation
integer, public :: nmaxhd ! Maximum two dimensional wave number
!
contains
subroutine comhd_defaultopts(dif2_out, & 1,5
dif4_out, &
kmxhdc_out)
!-----------------------------------------------------------------------
! Purpose: Return default runtime options
! Author: Tom Henderson
!-----------------------------------------------------------------------
use dycore
, only: dycore_is, get_resolution
!------------------------------Arguments--------------------------------
! Del^2 diffusion coeff.
real(r8), intent(out), optional :: dif2_out
! Del^4 diffusion coeff.
real(r8), intent(out), optional :: dif4_out
! Number of levels to apply Courant limiter
integer, intent(out), optional :: kmxhdc_out
!-----------------------------------------------------------------------
!
! Horizontal diffusion is used in both eul and sld dycores, but for sld
! the parameters are zero in the production version.
! Horizontal diffusion is not used in the fv dycore.
!
! Set dif2 and dif4 values for known resolutions, otherwise require in
! namelist
!
if ( present(dif2_out) ) then
if (dycore_is
('EUL')) then
select case ( get_resolution
() )
case ( 'T5' )
dif2_out = 2.5e7_r8
case ( 'T21' )
dif2_out = 2.5e5_r8
case ( 'T31' )
dif2_out = 2.5e5_r8
case ( 'T42' )
dif2_out = 2.5e5_r8
case ( 'T85' )
dif2_out = 2.5e5_r8
case ( 'T170' )
dif2_out = 2.5e5_r8
case default
dif2_out = 2.5e5_r8
end select
else
dif2_out = 0._r8
endif
endif
if ( present(dif4_out) ) then
if (dycore_is
('EUL')) then
select case ( get_resolution
() )
case ( 'T5' )
dif4_out = 1.0e18_r8
case ( 'T21' )
dif4_out = 2.0e16_r8
case ( 'T31' )
dif4_out = 2.0e16_r8
case ( 'T42' )
dif4_out = 1.0e16_r8
case ( 'T85' )
dif4_out = 1.0e15_r8
case ( 'T170' )
dif4_out = 1.5e14_r8
case default
dif4_out = inf
end select
else
dif4_out = 0._r8
endif
endif
if ( present(kmxhdc_out) ) then
kmxhdc_out = def_kmxhdc
endif
end subroutine comhd_defaultopts
subroutine comhd_setopts(dif2_in, & 1,2
dif4_in, &
kmxhdc_in)
!-----------------------------------------------------------------------
! Purpose: Set runtime options
! Author: Tom Henderson
!-----------------------------------------------------------------------
!------------------------------Arguments--------------------------------
! Del^2 diffusion coeff.
real(r8), intent(in), optional :: dif2_in
! Del^4 diffusion coeff.
real(r8), intent(in), optional :: dif4_in
! Number of levels to apply Courant limiter
integer, intent(in), optional :: kmxhdc_in
!-----------------------------------------------------------------------
!
! Horizontal diffusion is used in both eul and sld dycores, but for sld
! the parameters are zero in the production version.
! Horizontal diffusion is not used in the fv dycore.
!
! Set dif2 and dif4 values for known resolutions, otherwise require in
! namelist
!
if ( present(dif2_in) ) then
dif2 = dif2_in
endif
if ( present(dif4_in) ) then
dif4 = dif4_in
if ( dif4 == inf ) then
call endrun
('COMHD_SETOPTS: dif4 must be set in the namelist for this resolution.')
end if
endif
if ( present(kmxhdc_in) ) then
kmxhdc = kmxhdc_in
if (kmxhdc >= plev .or. kmxhdc < 0) then
call endrun
('COMHD_SETOPTS: ERROR: KMXHDC must be between 0 and plev-1')
end if
endif
end subroutine comhd_setopts
end module comhd