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