Class physics_radiation_main_mod
In: physics/physics_radiation_main.f90

Methods

Included Modules

type_mod grid_3d_mod constants_mod physics_radiation_long_mod physics_radiation_short_mod physics_radiation_incoming_mod dc_trace dycore_time_mod

Public Instance methods

Subroutine :
xyz_DRadLTempDt(im,jm,km) :real(DBKIND), intent(out)
: 長波加熱率
xyz_DRadSTempDt(im,jm,km) :real(DBKIND), intent(out)
: 短波加熱率
xyr_RadLFlux(im,jm,km+1) :real(DBKIND), intent(in)
: 長波フラックス
xyr_RadSFlux(im,jm,km+1) :real(DBKIND), intent(in)
: 短波フラックス
xyr_Press(im,jm,km+1) :real(DBKIND), intent(in)
: 圧力 (半整数)

放射加熱率の計算

短波放射, 長波放射それぞれの加熱率を計算する.

[Source]

  subroutine physics_radiation_deltemp( xyz_DRadLTempDt, xyz_DRadSTempDt, xyr_RadLFlux, xyr_RadSFlux, xyr_Press )
    !
    !== 放射加熱率の計算
    !
    ! 短波放射, 長波放射それぞれの加熱率を計算する.
    !
    use type_mod,    only: REKIND, DBKIND, INTKIND, TOKEN, STRING
    use grid_3d_mod, only: im, jm, km
    use constants_mod, only: Cp    , Grav     ! 重力加速度
    use dc_trace,    only: SetDebug, BeginSub, EndSub, DbgMessage, DataDump
    implicit none
    real(DBKIND), intent(out) :: xyz_DRadLTempDt(im,jm,km) ! 長波加熱率
    real(DBKIND), intent(out) :: xyz_DRadSTempDt(im,jm,km) ! 短波加熱率
    real(DBKIND), intent(in) :: xyr_RadLFlux(im,jm,km+1) ! 長波フラックス
    real(DBKIND), intent(in) :: xyr_RadSFlux(im,jm,km+1) ! 短波フラックス
    real(DBKIND), intent(in) :: xyr_Press(im,jm,km+1) ! 圧力 (半整数)
    character(STRING), parameter:: subname = "physics_radiation_deltemp"
      ! 作業用内部変数
    integer(INTKIND) :: k
      ! do ループ用作業変数 (東西 i*、南北 j*、鉛直 k*、波数 l*用)
    continue

    !----------------------------------------------------------------
    !   開始処理
    !----------------------------------------------------------------
    call BeginSub(subname)

    !----------------------------------------------------------------
    !   放射冷却率の演算 (加熱率では?)
    !----------------------------------------------------------------

    do k = 1, km
       xyz_DRadLTempDt(:,:,k) =( xyr_RadLFlux(:,:,k) - xyr_RadLFlux(:,:,k+1) ) / (xyr_Press(:,:,k) - xyr_Press(:,:,k+1) ) / Cp * Grav
       xyz_DRadSTempDt(:,:,k) =( xyr_RadSFlux(:,:,k) - xyr_RadSFlux(:,:,k+1) ) / (xyr_Press(:,:,k) - xyr_Press(:,:,k+1) ) / Cp * Grav
    end do

    !----------------------------------------------------------------
    !   終了処理
    !----------------------------------------------------------------
    call EndSub(subname)

  end subroutine physics_radiation_deltemp
Subroutine :
xyr_RadLFlux(im,jm,km+1) :real(DBKIND), intent(out)
: (out) 日射フラックス
xyo_SurfRadLMatrix(im,jm,-1:1) :real(DBKIND), intent(out)
: (out) 日射フラックス
xyro_DelRadLFlux(im,jm,km+1,0:1) :real(DBKIND), intent(out)
: (out) 日射フラックス
xyr_RadSFlux(im,jm,km+1) :real(DBKIND), intent(out)
: (out) 日射フラックス
xyz_Temp(im,jm,km) :real(DBKIND), intent(in)
xy_SurfTemp(im,jm) :real(DBKIND), intent(in)
xyz_Qvap(im,jm,km) :real(DBKIND), intent(in)
xyr_Press(im,jm,km+1) :real(DBKIND), intent(in)
x_Lon(im) :real(DBKIND), intent(in)
y_Lat(jm) :real(DBKIND), intent(in)
xy_SurfAlbedo(im,jm) :real(DBKIND), intent(in)

(in) 地表アルベド

[Source]

  subroutine physics_radiation_main( xyr_RadLFlux              , xyo_SurfRadLMatrix        , xyro_DelRadLFlux          , xyr_RadSFlux              , xyz_Temp                  , xy_SurfTemp               , xyz_Qvap                  , xyr_Press                 , x_Lon                     , y_Lat                     , xy_SurfAlbedo )               ! (in) 地表アルベド


    !==== Dependency
    use type_mod,    only: REKIND, DBKIND, INTKIND, TOKEN, STRING
    use grid_3d_mod, only: im, jm, km
    use constants_mod, only: Grav
    use physics_radiation_long_mod,  only: physics_radiation_long
    use physics_radiation_short_mod,  only: physics_radiation_short
    use physics_radiation_incoming_mod, only: physics_radiation_incoming
    use dc_trace,    only: SetDebug, BeginSub, EndSub, DbgMessage, DataDump
    use dycore_time_mod, only: CurrentTime, CurrentLoop

    implicit none

    !==== Output
    !
    real(DBKIND), intent(out) :: xyr_RadLFlux(im,jm,km+1)          , xyo_SurfRadLMatrix(im,jm,-1:1)    , xyro_DelRadLFlux(im,jm,km+1,0:1)  , xyr_RadSFlux(im,jm,km+1)              ! (out) 日射フラックス

    !==== Input
    !
    real(DBKIND), intent(in) :: xyz_Temp(im,jm,km)     , xy_SurfTemp(im,jm)     , xyz_Qvap(im,jm,km)     , xyr_Press(im,jm,km+1)  , xy_SurfAlbedo(im,jm)   , x_Lon(im) , y_Lat(jm)


    !----- 作業用内部変数 -----
    character(STRING),  parameter:: subname = "physics_radiation_main"

    ! do ループ用作業変数 (東西 i*、南北 j*、鉛直 k*、波数 l*用)
    integer(INTKIND)    :: i,j, k

    real(DBKIND) :: xyr_TauQvap(im,jm,km+1)   , xyr_TauDryAir(im,jm,km+1) , xy_InAngle(im,jm)              !" sec(入射角)

    real(DBKIND), parameter :: RadLDelTime = 3.0
    real(DBKIND), parameter :: RadSDelTime = 1.0
    
    real(DBKIND),allocatable,save :: xy_TempOld(:,:)
    real(DBKIND),allocatable,save :: xyr_RadLFluxOld(:,:,:)
    real(DBKIND),allocatable,save :: xyr_RadSFluxOld(:,:,:)
    real(DBKIND),allocatable,save :: xyro_DelRadLFluxOld(:,:,:,:)
    real(DBKIND),save :: RadLTime, RadSTime
    
    continue

    !----------------------------------------------------------------
    !   開始処理
    !----------------------------------------------------------------
    call BeginSub(subname)

    !----------------------------------------------------------------
    !   放射計算
    !----------------------------------------------------------------

    ! 本当は, 放射計算の間隔を決めないといけない. 
    ! 現在は毎ステップ計算してしまう. 
    ! AGCM5 では, 短波は 1 時間, 長波は 3 時間間隔. 

    if ( CurrentLoop .EQ. 1 ) then
       RadLTime = -999.0d0 * 60*60
       RadSTime = -999.0d0 * 60*60
       
       allocate( xy_TempOld(im,jm), xyr_RadLFluxOld(im,jm,km+1), xyr_RadSFluxOld(im,jm,km+1), xyro_DelRadLFluxOld(im,jm,km+1,0:1) )
    end if
    
    ! ---- 1. τ の計算 ----
    xyr_TauQvap   = 0.0d0
    xyr_TauDryAir = 0.0d0

    do k = km , 1, -1
       xyr_TauQvap(:,:,k) = xyr_TauQvap(:,:,k+1) + xyz_Qvap(:,:,k) * ( xyr_Press(:,:,k) - xyr_Press(:,:,k+1) ) / Grav 
       
       xyr_TauDryAir(:,:,k) = xyr_TauDryAir(:,:,k+1) + ( xyr_Press(:,:,k) - xyr_Press(:,:,k+1) ) / Grav 
    end do


    ! ---- 2. 長波フラックスの算出 ----
    if ( (CurrentTime - RadLTime) .GE. (RadLDelTime*60*60) ) then
       
       RadLTime = CurrentTime
       
       
       call physics_radiation_long( xyr_RadLFlux          , xyro_DelRadLFlux      , xyz_Temp              , xy_SurfTemp           , xyr_TauQvap           , xyr_TauDryAir           ) ! (in) 光学的厚さ:空気
       
    ! ---- 2*. 長波フラックスを計算しない場合 ----
    else
       
       xyr_RadLFlux = xyr_RadLFluxOld
       xyro_DelRadLFlux = xyro_DelRadLFluxOld
       
       do k = 1, km+1
          xyr_RadLFlux(:,:,k) = xyr_RadLFlux(:,:,k) +  xyro_DelRadLFlux(:,:,k,1) * (xyz_Temp(:,:,1) - xy_TempOld(:,:) )
          xyro_DelRadLFlux(:,:,k,1) = xyro_DelRadLFlux(:,:,k,1) / (xy_TempOld(:,:)**3) * (xyz_Temp(:,:,1)**3)
       end do
    end if


    ! ---- 3. 長波陰解用行列 ----    
    xyo_SurfRadLMatrix(:,:,0)  = xyro_DelRadLFlux(:,:,1,0)
    xyo_SurfRadLMatrix(:,:,1)  = xyro_DelRadLFlux(:,:,1,1)
    xyo_SurfRadLMatrix(:,:,-1) = 0.0d0


    if ( (CurrentTime - RadSTime) .GE. (RadSDelTime*60*60) ) then

       ! ----  4. 短波入射 ----
       call physics_radiation_incoming( xyr_RadSFlux(:,:,km+1)   , xy_InAngle              , y_Lat                    )
       
       ! ----  5. 短波フラックス ----
       call physics_radiation_short( xyr_RadSFlux         , xyr_TauQvap          , xyr_TauDryAir        , xy_InAngle           , xy_SurfAlbedo          ) ! (in) 地表アルベド

    else
       xyr_RadSFlux = xyr_RadSFluxOld
    end if


    ! ---- 古い値の保存 ----
    xy_TempOld = xyz_Temp(:,:,1)
    xyr_RadLFluxOld = xyr_RadLFlux
    xyr_RadSFluxOld = xyr_RadSFlux
    xyro_DelRadLFluxOld = xyro_DelRadLFlux


    !----------------------------------------------------------------
    !   終了処理
    !----------------------------------------------------------------
    call EndSub(subname)

  end subroutine physics_radiation_main

[Validate]