Class held_suarez_1994
In: held_suarez_1994/held_suarez_1994.f90

Held and Suarez (1994) ������å¼·å�¶ã���£é��

Forcing and dissipation suggested by Held and Suarez (1994)

Note that Japanese and English are described in parallel.

Held and Suarez (1994) �§æ�æ¡�������ä¹¾ç�¥å¤§æ°� GCM ���³ã�����¼ã������ å¼·å�¶ã���£é�¸ã��è¨�ç®����¾ã��. ä¸�����å¼·å�¶ã���£é�¸ã������, æ¸�º¦�´ã��¸¯�¶å�称å�´ã�¸ã��°¡�������¥ã�¼ã���³å�·å�´ã��, å¢���層æ������è¡�憗����ä¸�層風�����¤ã���¼æ�����������¾ã��. 詳細��以ä�������¾ã��.

Forcing and dissipation for dry air GCM benchmark suggested by Held and Suarez (1994) are caluclate. We use simple Newtonian relaxation of the temperature field to a zonally symmetric state and Rayleigh damping of low-level winds to represent boundary-layer friction. Their specifications are detailed as follows.

\[

   \left( \DP{\Dvect{v}}{t} \right)_{\mathrm{HS94}} =
       - k_v (\sigma) \Dvect{v}, \] \[
   \left( \DP{T}{t} \right)_{\mathrm{HS94}} =
       - k_T (\phi, \sigma) [T - T_{eq} (\phi,p)], \] \[
   T_{eq} = \mathrm{max}
    \left\{
       200 \mathrm{K},
       \left[
         315 \mathrm{K} - (\Delta T)_y \sin^2\phi
                        - (\Delta \theta)_z
                          \log \left(\frac{p}{p_0}\right) \cos^2\phi
       \right] \left(\frac{p}{p_0}\right)^\kappa
    \right\}, \] \[
   k_T = k_a + (k_s - k_a)
         \mathrm{max}
         \left(0, \frac{\sigma - \sigma_b}{1 - \sigma_b}\right) \cos^4\phi,
    \] \[
   k_v = k_f
         \mathrm{max}
         \left(0, \frac{\sigma - \sigma_b}{1 - \sigma_b}\right),
    \] \[
   \sigma_b = 0.7, \qquad
   k_f = 1 \mathrm{day}^{-1}, \qquad
   k_a = \Dinv{40} \mathrm{day}^{-1}, \qquad
   k_s = \Dinv{4} \mathrm{day}^{-1}, \] \[
   (\Delta T)_y = 60 \mathrm{K}, \qquad
   (\Delta \theta)_z = 10 \mathrm{K}, \qquad
   p_0 = 1000 \mathrm{hPa}, \qquad
   \kappa = \frac{R}{c_p}.

\]

Forcing �§ã��, ä¸�����������åº���æ¸�º¦ ( $ t+Delta t$ ���³å�) �������»¥ä¸���������¼·�¶ã���£é�¸ã���������¾ã��.

By Forcing, forcing and dissipation are applied to given wind and temperature ($ t+Delta t$ is expected) as follows.

\[

   \hat{\Dvect{v}}^{t+\Delta t} =
     \Dvect{v}^{t+\Delta t}
     + 2 \Delta t \left( \DP{\Dvect{v}}{t} \right)_{\mathrm{HS94}} \] \[
   \hat{T}^{t+\Delta t} =
     T^{t+\Delta t}
     + 2 \Delta t \left( \DP{T}{t} \right)_{\mathrm{HS94}}

\]

Procedures List

Hs94Forcing :å¼·å�¶ã���£é�¸ã���ç®�
Hs94Finalize :çµ�äº����� (�¢ã�¸ã�¥ã�¼ã����������°ã���²ã��ä»���解é��)
———— :————
Hs94Forcing :Calculate forcing and dissipation
Hs94Finalize :Termination (deallocate variables in this module)

References

  • Held, I. M., Suarez, M. J., 1994: A proposal for the intercomparison of the dynamical cores of atmospheric general circuation models. Bull. Am. Meteor. Soc., 75, 1825--1830.

Methods

Included Modules

gridset dc_types dc_message axesset timeset gtool_historyauto constants namelist_util dc_iounit dc_string

Public Instance methods

Subroutine :

�¢ã�¸ã�¥ã�¼ã����������°ã���²ã��ä»���解é�¤ã��è¡����¾ã��.

Deallocate variables in this module.

[Source]

  subroutine HS94Finalize
    !
    ! �¢ã�¸ã�¥ã�¼ã����������°ã���²ã��ä»���解é�¤ã��è¡����¾ã��. 
    !
    ! Deallocate variables in this module. 
    !

    ! 宣�� ; Declaration statements
    !
    implicit none

    ! ���� ; Executable statement
    !

    if ( .not. held_suarez_1994_inited ) return

    ! �²ã��ä»���解é��
    ! Deallocation
    !
    if ( allocated( z_kv  ) ) deallocate( z_kv  )
    if ( allocated( yz_kt ) ) deallocate( yz_kt )

    held_suarez_1994_inited = .false.

  end subroutine HS94Finalize
Subroutine :
xyz_U(0:imax-1, 1:jmax, 1:kmax) :real(DP), intent(in)
: $ u $ . �±è¥¿é¢���. Eastward wind
xyz_V(0:imax-1, 1:jmax, 1:kmax) :real(DP), intent(in)
: $ v $ . �������. Northward wind
xyz_Temp(0:imax-1, 1:jmax, 1:kmax) :real(DP), intent(in)
: $ T $ . æ¸�º¦. Temperature
xy_Ps(0:imax-1, 1:jmax) :real(DP), intent(in)
: $ p_s $ . �°è¡¨�¢æ���. Surface pressure
xyz_DUDt(0:imax-1, 1:jmax, 1:kmax) :real(DP), intent(out)
: $ DP{u}{t} $ . �±è¥¿é¢���å¤���. Eastward wind tendency
xyz_DVDt(0:imax-1, 1:jmax, 1:kmax) :real(DP), intent(out)
: $ DP{v}{t} $ . ����������. Northward wind tendency
xyz_DTempDt(0:imax-1, 1:jmax, 1:kmax) :real(DP), intent(out)
: $ DP{T}{t} $ . æ¸�º¦å¤���. Temperature tendency

å¼��°ã����������������±è¥¿é¢��� xyz_U, ����é¢��� xyz_V, æ¸�º¦ xyz_Temp ����, æ¸�º¦�´ã��¸¯�¶å�称å�´ã�¸ã��°¡�������¥ã�¼ã���³å�·å�´ã�� å¢���層æ������è¡�憗����ä¸�層風�����¤ã���¼æ���������� é¢�����¸©åº����������æ±���, xyz_DUDt, xyz_DVDt, xyz_DTempDt ������¾ã��.

Tendencies by simple Newtonian relaxation of the temperature field to a zonally symmetric state and Rayleigh damping of low-level winds to represent boundary-layer friction are calculated from eastward wind "xyz_U", northward wind "xyz_V", temperature "xyz_Temp". And the tencencies are returned as "xyz_DUDt", "xyz_DVDt", "xyz_DTempDt".

[Source]

  subroutine HS94Forcing( xyz_U,    xyz_V,    xyz_Temp, xy_Ps, xyz_DUDt, xyz_DVDt, xyz_DTempDt )
    !
    ! å¼��°ã����������������±è¥¿é¢��� xyz_U, ����é¢��� xyz_V, 
    ! æ¸�º¦ xyz_Temp ����, 
    ! æ¸�º¦�´ã��¸¯�¶å�称å�´ã�¸ã��°¡�������¥ã�¼ã���³å�·å�´ã��
    ! å¢���層æ������è¡�憗����ä¸�層風�����¤ã���¼æ����������
    ! é¢�����¸©åº����������æ±���, 
    ! xyz_DUDt, xyz_DVDt, xyz_DTempDt ������¾ã��. 
    !
    ! Tendencies by simple Newtonian relaxation of the temperature field to a
    ! zonally symmetric state and Rayleigh damping of low-level winds to
    ! represent boundary-layer friction are calculated 
    ! from eastward wind "xyz_U", northward wind "xyz_V", 
    ! temperature "xyz_Temp".
    ! And the tencencies are returned as 
    ! "xyz_DUDt", "xyz_DVDt", "xyz_DTempDt". 
    !
    !

    ! �¢ã�¸ã�¥ã�¼ã����� ; USE statements
    !

    ! 座æ����¼ã�¿è¨­å®�
    ! Axes data settings
    !
    use axesset, only: y_Lat, z_Sigma               ! $ \sigma $ ������ (�´æ��). 
                              ! Full $ \sigma $ level

    ! ���»ç���
    ! Time control
    !
    use timeset, only: DelTime, TimeN, TimesetClockStart, TimesetClockStop

    ! ���¹ã�������¼ã�¿å�ºå��
    ! History data output
    !
    use gtool_historyauto, only: HistoryAutoPut

    ! 宣�� ; Declaration statements
    !
    implicit none

    real(DP), intent(in):: xyz_U (0:imax-1, 1:jmax, 1:kmax)
                              ! $ u $ . �±è¥¿é¢���. 
                              ! Eastward wind
    real(DP), intent(in):: xyz_V (0:imax-1, 1:jmax, 1:kmax)
                              ! $ v $ . �������. 
                              ! Northward wind
    real(DP), intent(in):: xyz_Temp (0:imax-1, 1:jmax, 1:kmax)
                              ! $ T $ . æ¸�º¦. 
                              ! Temperature
    real(DP), intent(in):: xy_Ps (0:imax-1, 1:jmax)
                              ! $ p_s $ . �°è¡¨�¢æ���. 
                              ! Surface pressure
    real(DP), intent(out):: xyz_DUDt (0:imax-1, 1:jmax, 1:kmax)
                              ! $ \DP{u}{t} $ . �±è¥¿é¢���å¤���. 
                              ! Eastward wind tendency
    real(DP), intent(out):: xyz_DVDt (0:imax-1, 1:jmax, 1:kmax)
                              ! $ \DP{v}{t} $ . ����������. 
                              ! Northward wind tendency
    real(DP), intent(out):: xyz_DTempDt (0:imax-1, 1:jmax, 1:kmax)
                              ! $ \DP{T}{t} $ . æ¸�º¦å¤���. 
                              ! Temperature tendency

    ! �業��
    ! Work variables
    !
    real(DP):: xyz_TempEQ (0:imax-1, 1:jmax, 1:kmax)
                              ! $ T_{eq} $ . 平衡æ¸�º¦. 
                              ! Equilibrium temperature
    real(DP):: xyz_Press (0:imax-1, 1:jmax, 1:kmax)
                              ! $ T $ . �§å��. 
                              ! Pressure

    integer:: j               ! ç·�º¦�¹å�������� DO ���¼ã�����業å���
                              ! Work variables for DO loop in latitude
    integer:: k               ! ���´æ�¹å�������� DO ���¼ã�����業å���
                              ! Work variables for DO loop in vertical direction

    ! ���� ; Executable statement
    !

    ! ������確è�
    ! Initialization check
    !
    if ( .not. held_suarez_1994_inited ) then
      call MessageNotify( 'E', module_name, 'This module has not been initialized.' )
    end if

    ! �����������
    ! Start measurement of computation time
    !
    call TimesetClockStart( module_name )


    ! �±è¥¿é¢��� $ u $ ������é¢��� $ v $ �¸ã���¤ã���¼æ����������
    ! Apply Rayleigh damping to eastward wind $ u $ and northward wind $ v $
    !
    do k = 1, kmax
      xyz_DUDt (:,:,k) = - z_kv (k) * xyz_U (:,:,k)
      xyz_DVDt (:,:,k) = - z_kv (k) * xyz_V (:,:,k)
    end do

    ! æ¸�º¦ $ T $ �¸ã���¥ã�¼ã���³å�·å�´ã������
    ! Apply Newtonian relaxation to temperature $ T $
    !
    do k = 1, kmax
       xyz_Press(:,:,k) = z_Sigma(k) * xy_Ps
    enddo

    do j = 1, jmax
      xyz_TempEQ(:,j,:) = max( 200.0_DP, (   315.0_DP - DelTempY * sin( y_Lat(j) ) ** 2 - DelPotTempZ * log( xyz_Press(:,j,:) / P0 ) * cos( y_Lat(j) ) ** 2 ) * ( xyz_Press(:,j,:) / P0 ) ** Kappa )
    end do

    do k = 1, kmax
      do j = 1, jmax
        xyz_DTempDt (:,j,k) = - yz_kt (j,k) * ( xyz_Temp (:,j,k) - xyz_TempEQ (:,j,k) )
      end do
    end do


    ! ���¹ã�������¼ã�¿å�ºå��
    ! History data output
    !
    call HistoryAutoPut( TimeN, 'DUDtHS94',    xyz_DUDt )
    call HistoryAutoPut( TimeN, 'DVDtHS94',    xyz_DVDt )
    call HistoryAutoPut( TimeN, 'DTempDtHS94', xyz_DTempDt )
    call HistoryAutoPut( TimeN, 'TempEQHS94',  xyz_TempEQ )


    ! ��������������
    ! Pause measurement of computation time
    !
    call TimesetClockStop( module_name )

  end subroutine HS94Forcing
Subroutine :

held_suarez_1994 �¢ã�¸ã�¥ã�¼ã������������è¡����¾ã��. NAMELIST#held_suarez_1994_nml ����¿è¾¼�¿ã��������ç¶����§è�����¾ã��.

"held_suarez_1994" module is initialized. "NAMELIST#held_suarez_1994_nml" is loaded in this procedure.

This procedure input/output NAMELIST#held_suarez_1994_nml .

[Source]

  subroutine HS94Init
    !
    ! held_suarez_1994 �¢ã�¸ã�¥ã�¼ã������������è¡����¾ã��. 
    ! NAMELIST#held_suarez_1994_nml ����¿è¾¼�¿ã��������ç¶����§è�����¾ã��. 
    !
    ! "held_suarez_1994" module is initialized. 
    ! "NAMELIST#held_suarez_1994_nml" is loaded in this procedure. 
    !

    ! �¢ã�¸ã�¥ã�¼ã����� ; USE statements
    !

    ! ����å®��°è¨­å®�
    ! Physical constants settings
    !
    use constants, only: GasRDry, CpDry
                              ! $ C_p $ [J kg-1 K-1]. 
                              ! ä¹¾ç�¥å¤§æ°�����§æ���. 
                              ! Specific heat of air at constant pressure

    ! 座æ����¼ã�¿è¨­å®�
    ! Axes data settings
    !
    use axesset, only: y_Lat, z_Sigma               ! $ \sigma $ ������ (�´æ��). 
                              ! Full $ \sigma $ level

    ! NAMELIST ���¡ã�¤ã���¥å�����¢ã�������¼ã���£ã������
    ! Utilities for NAMELIST file input
    !
    use namelist_util, only: namelist_filename, NmlutilMsg, NmlutilAryValid

    ! ���¡ã�¤ã���¥å�ºå��è£���
    ! File I/O support
    !
    use dc_iounit, only: FileOpen

    ! ç¨��¥å�������¡ã��
    ! Kind type parameter
    !
    use dc_types, only: STDOUT ! æ¨�æº��ºå�����ç½����. Unit number of standard output

    ! ��������
    ! Character handling
    !
    use dc_string, only: StoA

    ! ���¹ã�������¼ã�¿å�ºå��
    ! History data output
    !
    use gtool_historyauto, only: HistoryAutoAddVariable

    ! 宣�� ; Declaration statements
    !
    implicit none

    real(DP), parameter :: day_seconds = 86400.0_DP
                              ! 1 �¥ã�����. 
                              ! Seconds in day. 
    real(DP):: SigmaB         ! $ \sigma_b $ .
                              ! å¢���層ä�ç«����åº�
    real(DP):: kf             ! $ k_f $ .
                              ! �°è¡¨�¢ã�§ã�� Rayleigh ������·©��ä¿���
    real(DP):: ka             ! $ k_a $ .
                              ! 大æ�ä¸�層ã�������� Newton �·å�´ã��·©��ä¿���
    real(DP):: ks             ! $ k_s $ .
                              ! 赤é���°è¡¨�¢ã�������� Newton �·å�´ã��·©��ä¿���

    real(DP):: kfTimeScaleInDay
    real(DP):: kaTimeScaleInDay
    real(DP):: ksTimeScaleInDay

    integer:: j               ! ç·�º¦�¹å�������� DO ���¼ã�����業å���
                              ! Work variables for DO loop in latitude
    integer:: k               ! ���´æ�¹å�������� DO ���¼ã�����業å���
                              ! Work variables for DO loop in vertical direction

    integer:: unit_nml        ! NAMELIST ���¡ã�¤ã�����¼ã���³ç���ç½����. 
                              ! Unit number for NAMELIST file open
    integer:: iostat_nml      ! NAMELIST 読ã�¿è¾¼�¿æ���� IOSTAT. 
                              ! IOSTAT of NAMELIST read

    ! NAMELIST å¤��°ç¾¤
    ! NAMELIST group name
    !
    namelist /held_suarez_1994_nml/ SigmaB, kfTimeScaleInDay, kaTimeScaleInDay, ksTimeScaleInDay
          !
          ! �����������¤ã���¤ã��������������ç¶� "held_suarez_1994#HS94Init" 
          ! ���½ã�¼ã�¹ã�³ã�¼ã�������§ã������. 
          !
          ! Refer to source codes in the initialization procedure
          ! "held_suarez_1994#HS94Init" for the default values. 
          !

    ! ���� ; Executable statement
    !

    if ( held_suarez_1994_inited ) return


    ! �����������¤ã��¨­å®�
    ! Default values settings
    !
    SigmaB           =  0.7_DP
    kfTimeScaleInDay =  1.0_DP
    kaTimeScaleInDay = 40.0_DP
    ksTimeScaleInDay =  4.0_DP

    ! NAMELIST ����¿è¾¼��
    ! NAMELIST is input
    !
    if ( trim(namelist_filename) /= '' ) then
      call FileOpen( unit_nml, namelist_filename, mode = 'r' ) ! (in)

      rewind( unit_nml )
      read( unit_nml, nml = held_suarez_1994_nml, iostat = iostat_nml )        ! (out)
      close( unit_nml )

      call NmlutilMsg( iostat_nml, module_name ) ! (in)
!$      if ( iostat_nml == 0 ) write( STDOUT, nml = held_suarez_1994_nml )
    end if

    ! ä¿��°ã��¨­å®�
    ! Configure coefficients
    !
    Kappa = GasRDry / CpDry

    P0          = 1000.0e2_DP
    DelTempY    = 60.0_DP
    DelPotTempZ = 10.0_DP

!!$    kf     = 1.0_DP / day_seconds
!!$    ka     = 1.0_DP / ( 40.0_DP * day_seconds )
!!$    ks     = 1.0_DP / (  4.0_DP * day_seconds )
    kf     = 1.0_DP / ( kfTimeScaleInDay * day_seconds )
    ka     = 1.0_DP / ( kaTimeScaleInDay * day_seconds )
    ks     = 1.0_DP / ( ksTimeScaleInDay * day_seconds )

    allocate( z_kv (1:kmax) )
    z_kv = kf * max( 0.0_DP, ( z_Sigma - SigmaB ) / ( 1.0_DP - SigmaB ) )

    allocate( yz_kt (1:jmax, 1:kmax) )

    do k = 1, kmax
      do j = 1, jmax
        yz_kt(j,k) = ka + ( ks - ka ) * max( 0.0_DP, ( z_Sigma(k) - SigmaB ) / ( 1.0_DP - SigmaB ) ) * cos( y_Lat(j) ) ** 4
      end do
    end do


    ! ���¹ã�������¼ã�¿å�ºå�����������¸ã����°ç�»é��
    ! Register of variables for history data output
    !
    call HistoryAutoAddVariable( 'DUDtHS94', (/ 'lon ', 'lat ', 'sig ', 'time' /), 'eastward wind tendency', 'm s-2' )
    call HistoryAutoAddVariable( 'DVDtHS94', (/ 'lon ', 'lat ', 'sig ', 'time' /), 'northward wind tendency', 'm s-2' )
    call HistoryAutoAddVariable( 'DTempDtHS94', (/ 'lon ', 'lat ', 'sig ', 'time' /), 'temperature tendency', 'K s-1' )
    call HistoryAutoAddVariable( 'TempEQHS94', (/ 'lon ', 'lat ', 'sig ', 'time' /), 'equilibrium temperature', 'K' )

    ! �°å� ; Print
    !
    call MessageNotify( 'M', module_name, '----- Initialization Messages -----' )
    call MessageNotify( 'M', module_name, 'SigmaB           = %f', d = (/ SigmaB /) )
    call MessageNotify( 'M', module_name, 'kfTimeScaleInDay = %f', d = (/ kfTimeScaleInDay /) )
    call MessageNotify( 'M', module_name, 'kaTimeScaleInDay = %f', d = (/ kaTimeScaleInDay /) )
    call MessageNotify( 'M', module_name, 'ksTimeScaleInDay = %f', d = (/ ksTimeScaleInDay /) )

    call MessageNotify( 'M', module_name, '-- version = %c', c1 = trim(version) )

    held_suarez_1994_inited = .true.

  end subroutine HS94Init

Private Instance methods

DelPotTempZ
Variable :
DelPotTempZ :real(DP)
: $ (Delta theta)_z $ . 赤é�������������´æ�¹å����¸©ä½�å·�
DelTempY
Variable :
DelTempY :real(DP)
: $ (Delta T)_y $ . 極ã��µ¤����¸©åº�·®
Kappa
Variable :
Kappa :real(DP)
: $ kappa = R/C_p $ . æ°�ä½�å®��°ã����§æ��±ã�������æ¯�. Ratio of gas constant to specific heat
P0
Variable :
P0 :real(DP)
: $ p_0 $ .
held_suarez_1994_inited
Variable :
held_suarez_1994_inited = .false. :logical, save
: ����設������. Initialization flag
module_name
Constant :
module_name = ‘held_suarez_1994 :character(*), parameter
: �¢ã�¸ã�¥ã�¼ã������ç§�. Module name
version
Constant :
version = ’$Name: $’ // ’$Id: held_suarez_1994.f90,v 1.14 2012/04/27 11:24:45 noda Exp $’ :character(*), parameter
: �¢ã�¸ã�¥ã�¼ã�������¼ã�¸ã�§ã�� Module version
yz_kt
Variable :
yz_kt(:,:) :real(DP), allocatable
: $ k_T $ .
z_kv
Variable :
z_kv(:) :real(DP), allocatable
: $ k_v $ .