module phys_control 27,4
!-----------------------------------------------------------------------
! Purpose:
!
! Provides a control interface to CAM physics packages
!
! Revision history:
! 2006-05-01 D. B. Coleman, Creation of module
! 2009-02-13 Eaton Replace *_{default,set}opts methods with module namelist.
! Add vars to indicate physics version and chemistry type.
!-----------------------------------------------------------------------
use spmd_utils
, only: masterproc
use cam_logfile
, only: iulog
use abortutils
, only: endrun
use shr_kind_mod
, only: r8 => shr_kind_r8
implicit none
private
save
public :: &
phys_ctl_readnl, &! read namelist from file
phys_getopts, &! generic query method
phys_deepconv_pbl, &! return true if deep convection is allowed in the PBL
phys_do_flux_avg, &! return true to average surface fluxes
cam_physpkg_is, &! query for the name of the physics package
cam_chempkg_is ! query for the name of the chemistry package
! Private module data
character(len=16), parameter :: unset_str = 'UNSET'
integer, parameter :: unset_int = huge(1)
! Namelist variables:
character(len=16) :: cam_physpkg = unset_str ! CAM physics package [cam3 | cam4 | cam5 |
! ideal | adiabatic].
character(len=16) :: cam_chempkg = unset_str ! CAM chemistry package [waccm_mozart |
! waccm_ghg | trop_mozart | trop_ghg |
! trop_bam | trop_mam3 | trop_mam7 |
! super_fast_llnl | super_fast_llnl_mam3 | none
character(len=16) :: deep_scheme = unset_str ! deep convection package
character(len=16) :: shallow_scheme = unset_str ! shallow convection package
character(len=16) :: eddy_scheme = unset_str ! vertical diffusion package
character(len=16) :: microp_scheme = unset_str ! microphysics package
integer :: srf_flux_avg = unset_int ! 1 => smooth surface fluxes, 0 otherwise
integer :: conv_water_in_rad = unset_int ! 0==> No; 1==> Yes-Arithmetic average;
! 2==> Yes-Average in emissivity.
logical :: atm_dep_flux = .true. ! true => deposition fluxes will be provided
! to the coupler
logical :: history_aerosol = .false. ! output the MAM aerosol tendencies
logical :: history_microphysics ! output the MG microphysics variables for AMWG package
logical :: history_budget = .false. ! output tendencies and state variables for CAM4
! temperature, water vapor, cloud ice and cloud
! liquid budgets.
logical :: do_tms ! switch for turbulent mountain stress
logical :: do_iss ! switch for implicit turbulent surface stress
real(r8) :: tms_orocnst = 1._r8 ! turbulent mountain stress parameter
!=======================================================================
contains
!=======================================================================
subroutine phys_ctl_readnl(nlfile) 1,28
use namelist_utils
, only: find_group_name
use units
, only: getunit, freeunit
use mpishorthand
character(len=*), intent(in) :: nlfile ! filepath for file containing namelist input
! Local variables
integer :: unitn, ierr
character(len=*), parameter :: subname = 'phys_ctl_readnl'
namelist /phys_ctl_nl/ cam_physpkg, cam_chempkg, deep_scheme, shallow_scheme, &
eddy_scheme, microp_scheme, &
srf_flux_avg, atm_dep_flux, do_tms, do_iss, tms_orocnst, history_aerosol, &
history_microphysics, history_budget, conv_water_in_rad
!-----------------------------------------------------------------------------
if (masterproc) then
unitn = getunit
()
open( unitn, file=trim(nlfile), status='old' )
call find_group_name
(unitn, 'phys_ctl_nl', status=ierr)
if (ierr == 0) then
read(unitn, phys_ctl_nl, iostat=ierr)
if (ierr /= 0) then
call endrun
(subname // ':: ERROR reading namelist')
end if
end if
close(unitn)
call freeunit
(unitn)
end if
#ifdef SPMD
! Broadcast namelist variables
call mpibcast
(deep_scheme, len(deep_scheme) , mpichar, 0, mpicom)
call mpibcast
(cam_physpkg, len(cam_physpkg) , mpichar, 0, mpicom)
call mpibcast
(cam_chempkg, len(cam_chempkg) , mpichar, 0, mpicom)
call mpibcast
(shallow_scheme, len(shallow_scheme), mpichar, 0, mpicom)
call mpibcast
(eddy_scheme, len(eddy_scheme) , mpichar, 0, mpicom)
call mpibcast
(microp_scheme, len(microp_scheme) , mpichar, 0, mpicom)
call mpibcast
(srf_flux_avg, 1 , mpiint, 0, mpicom)
call mpibcast
(atm_dep_flux, 1 , mpilog, 0, mpicom)
call mpibcast
(history_aerosol, 1 , mpilog, 0, mpicom)
call mpibcast
(history_microphysics, 1 , mpilog, 0, mpicom)
call mpibcast
(history_budget, 1 , mpilog, 0, mpicom)
call mpibcast
(do_tms, 1 , mpilog, 0, mpicom)
call mpibcast
(do_iss, 1 , mpilog, 0, mpicom)
call mpibcast
(tms_orocnst, 1 , mpir8, 0, mpicom)
call mpibcast
(conv_water_in_rad,1, mpiint, 0, mpicom)
#endif
! Error checking:
! Defaults for PBL and microphysics are set in build-namelist. Check here that
! values have been set to guard against problems with hand edited namelists.
if (.not. (shallow_scheme .eq. 'Hack' .or. shallow_scheme .eq. 'UW' .or. shallow_scheme .eq. 'off')) then
write(iulog,*)'phys_setopts: illegal value of shallow_scheme:', shallow_scheme
call endrun
('phys_setopts: illegal value of shallow_scheme')
endif
if (.not. (eddy_scheme .eq. 'HB' .or. eddy_scheme .eq. 'HBR' .or. eddy_scheme .eq. 'diag_TKE')) then
write(iulog,*)'phys_setopts: illegal value of eddy_scheme:', eddy_scheme
call endrun
('phys_setopts: illegal value of eddy_scheme')
endif
if (.not. (microp_scheme .eq. 'MG' .or. microp_scheme .eq. 'RK')) then
write(iulog,*)'phys_setopts: illegal value of microp_scheme:', microp_scheme
call endrun
('phys_setopts: illegal value of microp_scheme')
endif
! Check compatibility of eddy & shallow schemes
if (( shallow_scheme .eq. 'UW' ) .and. ( eddy_scheme .ne. 'diag_TKE' )) then
write(iulog,*)'Do you really want to run UW shallow scheme without diagnostic TKE eddy scheme? Quiting'
call endrun
('shallow convection and eddy scheme may be incompatible')
endif
if (( shallow_scheme .eq. 'Hack' ) .and. ( ( eddy_scheme .ne. 'HB' ) .and. ( eddy_scheme .ne. 'HBR' ))) then
write(iulog,*)'Do you really want to run Hack shallow scheme with a non-standard eddy scheme? Quiting.'
call endrun
('shallow convection and eddy scheme may be incompatible')
endif
! Check compatibility of PBL and Microphysics schemes
if (( eddy_scheme .eq. 'diag_TKE' ) .and. ( microp_scheme .ne. 'MG' )) then
write(iulog,*)'UW PBL is only compatible with MG microphysics. Quiting'
call endrun
('PBL and Microphysics schemes incompatible')
endif
end subroutine phys_ctl_readnl
!===============================================================================
logical function cam_physpkg_is(name) 8
! query for the name of the physics package
character(len=*) :: name
cam_physpkg_is = (trim(name) == trim(cam_physpkg))
end function cam_physpkg_is
!===============================================================================
logical function cam_chempkg_is(name)
! query for the name of the chemics package
character(len=*) :: name
cam_chempkg_is = (trim(name) == trim(cam_chempkg))
end function cam_chempkg_is
!===============================================================================
subroutine phys_getopts(deep_scheme_out, shallow_scheme_out, eddy_scheme_out, microp_scheme_out, & 22
atm_dep_flux_out, history_aerosol_out, history_microphysics_out, &
history_budget_out, do_tms_out, do_iss_out, tms_orocnst_out, &
conv_water_in_rad_out )
!-----------------------------------------------------------------------
! Purpose: Return runtime settings
! deep_scheme_out : deep convection scheme
! shallow_scheme_out: shallow convection scheme
! eddy_scheme_out : vertical diffusion scheme
! microp_scheme_out : microphysics scheme
!-----------------------------------------------------------------------
character(len=16), intent(out), optional :: deep_scheme_out
character(len=16), intent(out), optional :: shallow_scheme_out
character(len=16), intent(out), optional :: eddy_scheme_out
character(len=16), intent(out), optional :: microp_scheme_out
logical, intent(out), optional :: atm_dep_flux_out
logical, intent(out), optional :: history_aerosol_out
logical, intent(out), optional :: history_microphysics_out
logical, intent(out), optional :: history_budget_out
logical, intent(out), optional :: do_tms_out
logical, intent(out), optional :: do_iss_out
real(r8), intent(out), optional :: tms_orocnst_out
integer, intent(out), optional :: conv_water_in_rad_out
if ( present(deep_scheme_out ) ) deep_scheme_out = deep_scheme
if ( present(shallow_scheme_out ) ) shallow_scheme_out = shallow_scheme
if ( present(eddy_scheme_out ) ) eddy_scheme_out = eddy_scheme
if ( present(microp_scheme_out ) ) microp_scheme_out = microp_scheme
if ( present(atm_dep_flux_out ) ) atm_dep_flux_out = atm_dep_flux
if ( present(history_aerosol_out ) ) history_aerosol_out = history_aerosol
if ( present(history_microphysics_out) ) history_microphysics_out = history_microphysics
if ( present(history_budget_out ) ) history_budget_out = history_budget
if ( present(do_tms_out ) ) do_tms_out = do_tms
if ( present(do_iss_out ) ) do_iss_out = do_iss
if ( present(tms_orocnst_out ) ) tms_orocnst_out = tms_orocnst
if ( present(conv_water_in_rad_out ) ) conv_water_in_rad_out = conv_water_in_rad
end subroutine phys_getopts
!===============================================================================
function phys_deepconv_pbl() 1
logical phys_deepconv_pbl
! Don't allow deep convection in PBL if running UW PBL scheme
if ( (eddy_scheme .eq. 'diag_TKE' ) .or. (shallow_scheme .eq. 'UW' ) ) then
phys_deepconv_pbl = .true.
else
phys_deepconv_pbl = .false.
endif
return
end function phys_deepconv_pbl
!===============================================================================
function phys_do_flux_avg() 2
logical :: phys_do_flux_avg
!----------------------------------------------------------------------
phys_do_flux_avg = .false.
if (srf_flux_avg == 1) phys_do_flux_avg = .true.
end function phys_do_flux_avg
!===============================================================================
end module phys_control