Subroutine : |
|
xyz_DVerdiffVelLonDt(im*jm,km) : | real(DBKIND), intent(out)
|
xyz_DVerdiffVelLatDt(im*jm,km) : | real(DBKIND), intent(out)
|
xyz_DVerdiffTempDt(im*jm,km) : | real(DBKIND), intent(out)
|
xyz_DVerdiffSurfTempDt(im*jm) : | real(DBKIND), intent(out)
|
xyz_DVerdiffQvapDt(im*jm,km) : | real(DBKIND), intent(out)
|
xyr_VelLonFlux(im*jm,km+1) : | real(DBKIND), intent(in)
|
xyr_VelLatFlux(im*jm,km+1) : | real(DBKIND), intent(in)
|
xyr_TempFlux(im*jm,km+1) : | real(DBKIND), intent(in)
|
xyr_SurfRadSFlux(im*jm) : | real(DBKIND), intent(in)
|
xyr_SurfRadLFlux(im*jm) : | real(DBKIND), intent(in)
|
xy_GroundTempFlux(im*jm) : | real(DBKIND), intent(in)
|
xyr_QvapFlux(im*jm,km+1) : | real(DBKIND), intent(in)
|
xyzo_VelMatrix(im*jm,km,-1:1) : | real(DBKIND), intent(in)
|
xyzo_TempMatrix(im*jm,0:km,-1:1) : | real(DBKIND), intent(in)
|
xyzo_QvapMatrix(im*jm,km,-1:1) : | real(DBKIND), intent(in)
|
xy_SurfVelMatrix(im*jm) : | real(DBKIND), intent(in)
|
xyoo_SurfTempMatrix(im*jm,0:1,-1:1) : | real(DBKIND), intent(in)
|
xyoo_SurfQvapMatrix(im*jm,0:1,-1:1) : | real(DBKIND), intent(in)
|
xyo_SurfRadLMatrix(im*jm,-1:1) : | real(DBKIND), intent(in)
|
DelTimePhy : | real(DBKIND), intent(in)
|
xy_SurfCondition(im*jm) : | integer(INTKIND)
|
subroutine physics_implicit_integrate( xyz_DVerdiffVelLonDt , xyz_DVerdiffVelLatDt , xyz_DVerdiffTempDt , xyz_DVerdiffSurfTempDt , xyz_DVerdiffQvapDt , xyr_VelLonFlux , xyr_VelLatFlux , xyr_TempFlux , xyr_SurfRadSFlux , xyr_SurfRadLFlux , xy_GroundTempFlux , xyr_QvapFlux , xyzo_VelMatrix , xyzo_TempMatrix , xyzo_QvapMatrix , xy_SurfVelMatrix , xyoo_SurfTempMatrix , xyoo_SurfQvapMatrix , xyo_SurfRadLMatrix , DelTimePhy , xy_SurfCondition ) ! (in) 地表状態
!==== Dependency
use type_mod, only: REKIND, DBKIND, INTKIND, TOKEN, STRING
use grid_3d_mod, only: im, jm, km
use constants_mod, only: EL, Cp
use dc_trace, only: SetDebug, BeginSub, EndSub, DbgMessage, DataDump
implicit none
!==== Output
!
real(DBKIND), intent(out) :: xyz_DVerdiffVelLonDt(im*jm,km) , xyz_DVerdiffVelLatDt(im*jm,km) , xyz_DVerdiffTempDt(im*jm,km) , xyz_DVerdiffSurfTempDt(im*jm) , xyz_DVerdiffQvapDt(im*jm,km) ! (out) 鉛直拡散加湿率
!==== Input
!
real(DBKIND), intent(in) :: xyr_VelLonFlux(im*jm,km+1) , xyr_VelLatFlux(im*jm,km+1) , xyr_TempFlux(im*jm,km+1) , xyr_SurfRadSFlux(im*jm) , xyr_SurfRadLFlux(im*jm) , xy_GroundTempFlux(im*jm) , xyr_QvapFlux(im*jm,km+1) , xyzo_VelMatrix(im*jm,km,-1:1) , xyzo_TempMatrix(im*jm,0:km,-1:1) , xyzo_QvapMatrix(im*jm,km,-1:1) , xy_SurfVelMatrix(im*jm) , xyoo_SurfTempMatrix(im*jm,0:1,-1:1) , xyoo_SurfQvapMatrix(im*jm,0:1,-1:1) , xyo_SurfRadLMatrix(im*jm,-1:1) , DelTimePhy ! (in) 2Δt
integer(INTKIND) :: xy_SurfCondition(im*jm) ! (in) 地表状態
!----- 作業用内部変数 -----
character(STRING), parameter:: subname = "physics_implicit_integrate"
! do ループ用作業変数 (東西 i*、南北 j*、鉛直 k*、波数 l*用)
integer(INTKIND) :: ij, k, l
real(DBKIND) :: xyz_DelTempQvap(im*jm,-km:km) , xyzo_TempQvapLUMatrix(im*jm,-km:km,-1:1) , xyzo_VelLUMatrix(im*jm,km,-1:1) ! LU行列
continue
!----------------------------------------------------------------
! 開始処理
!----------------------------------------------------------------
call BeginSub(subname)
!----------------------------------------------------------------
! 陰解行列計算
!----------------------------------------------------------------
! ---- 1. 速度 (Vlon, Vlat) の解 ----
xyzo_VelLUMatrix = xyzo_VelMatrix
xyzo_VelLUMatrix(:,1,0) = xyzo_VelLUMatrix(:,1,0) + xy_SurfVelMatrix(:)
call lu_decomposition_tridiagonal( xyzo_VelLUMatrix, im*jm, km )
do k = 1, km
xyz_DVerdiffVelLonDt(:,k) = xyr_VelLonFlux(:,k) - xyr_VelLonFlux(:,k+1)
xyz_DVerdiffVelLatDt(:,k) = xyr_VelLatFlux(:,k) - xyr_VelLatFlux(:,k+1)
end do
call lu_solve_tridiagonal( xyz_DVerdiffVelLonDt , xyzo_VelLUMatrix , 1, im*jm, km )
call lu_solve_tridiagonal( xyz_DVerdiffVelLatDt , xyzo_VelLUMatrix , 1, im*jm, km )
! ---- 2. 温度と比湿の解 ----
do l = -1, 1
do k = 1, km
xyzo_TempQvapLUMatrix(:,k,l) = xyzo_TempMatrix(:,k,l)
xyzo_TempQvapLUMatrix(:,-k,-l) = xyzo_QvapMatrix(:,k,l)
end do
xyzo_TempQvapLUMatrix(:,1,l) = xyzo_TempMatrix(:,1,l) + xyoo_SurfTempMatrix(:,1,l)
xyzo_TempQvapLUMatrix(:,-1,-l) = xyzo_QvapMatrix(:,1,l) + xyoo_SurfQvapMatrix(:,1,l)
end do
xyzo_TempQvapLUMatrix(:,0,0) = xyzo_TempMatrix(:,0,0) + xyoo_SurfTempMatrix(:,0,0) + xyoo_SurfQvapMatrix(:,0,0) + xyo_SurfRadLMatrix(:,0)
xyzo_TempQvapLUMatrix(:,0,1) = + xyoo_SurfTempMatrix(:,0,1) + xyo_SurfRadLMatrix(:,1)
xyzo_TempQvapLUMatrix(:,0,-1) = xyoo_SurfQvapMatrix(:,0,1)
call lu_decomposition_tridiagonal( xyzo_TempQvapLUMatrix, im*jm, 2*km+1 )
do k = 1, km
xyz_DelTempQvap(:,k) = xyr_TempFlux(:,k) - xyr_TempFlux(:,k+1)
xyz_DelTempQvap(:,-k) = xyr_QvapFlux(:,k) - xyr_QvapFlux(:,k+1)
end do
xyz_DelTempQvap(:,0) = - xyr_SurfRadSFlux - xyr_SurfRadLFlux - xyr_TempFlux(:,1) - xyr_QvapFlux(:,1) + xy_GroundTempFlux
call lu_solve_tridiagonal( xyz_DelTempQvap , xyzo_TempQvapLUMatrix , 1, im*jm, 2*km+1 )
! ---- 2. 時間変化率 ----
do k = 1, km
xyz_DVerdiffVelLonDt(:,k) = xyz_DVerdiffVelLonDt(:,k) / DeltimePhy
xyz_DVerdiffVelLatDt(:,k) = xyz_DVerdiffVelLatDt(:,k) / DeltimePhy
xyz_DVerdiffTempDt(:,k) = xyz_DelTempQvap(:,k) / DeltimePhy
xyz_DVerdiffQvapDt(:,k) = xyz_DelTempQvap(:,-k) / DeltimePhy / EL * Cp
end do
do ij = 1, im*jm
if ( xy_SurfCondition(ij) .GE. 1 ) then
xyz_DVerdiffSurfTempDt(ij) = xyz_DelTempQvap(ij,0) / DeltimePhy
else
xyz_DVerdiffSurfTempDt(ij) = 0.
end if
end do
!----------------------------------------------------------------
! 終了処理
!----------------------------------------------------------------
call EndSub(subname)
end subroutine physics_implicit_integrate