!= 物質移流過程 (セミラグランジュ法)
!
!= Semi-Lagrangian Tracer Transport scheme
!
! Authors:: Hiroki KASHIMURA, Yoshiyuki O. TAKAHASHI
! Version::
! Tag Name:: $Name: $
! Copyright:: Copyright (C) GFD Dennou Club, 2013. All rights reserved.
! License:: See COPYRIGHT[link:../../../COPYRIGHT]
!
module sltt
!
!= 物質移流 (セミラグランジュ法, Enomoto (2008) modified)
!
!= Tracer Transport (Semi-Lagrangian method, Enomoto (2008) modified)
!
! Note that Japanese and English are described in parallel.
!
! 物質移流を非保存型のセミラグランジュ法で演算するモジュールです.
! 上流点探索には Williamson and Rasch (1989, MWR) を
! 補間には Enomoto (2008) を応用した方法を用いています。
! すなわちスペクトルから求めた1階微分の値を利用した5次精度の変則エルミート補間です。
! 非負を保証するために arcsine 変換フィルタを用いています。
! スペクトル変換・高精度補間に由来する人工的な短波を除去するために Sun et al. (1996) の
! 単調フィルタを応用したものを部分的に用いている。
!
! This is a tracer transport module. Semi-Lagrangian method (Enomoto 2008 modified)
! Arcsine transformation filter is used to avoid negative values.
! Monotonicity filter (Sun et al 1996) is partly used.
!
!== Procedures List
!
! SLTTMain :: 移流計算
! SLTTInit :: 初期化
! SLTTTest :: 移流テスト用
! --------------------- :: ------------
! SLTTMain :: Main subroutine for SLTT
! SLTTInit :: Initialization for SLTT
! SLTTTest :: Generate velocity for SLTT Test
!
!== NAMELIST
!
! NAMELIST#
!
!== References
!
! * Kashimura, H., T. Enomoto, Y. O. Takahashi, 2013:
! Non-negative filter using arcsine transformation for tracer advection with semi-Lagrangian scheme.
! NCTAM, 62.
!
! * Enomoto, T., 2008:
! Bicubic Interpolation with Spectral Derivatives.
! SOLA, 4, 5-8. doi:10.2151/sola.2008-002
!
! * Williamson, D. L., and Rasch, P. J., 1989:
! Two-dimensional semi-Lagrangian transport with shape-preserving interpolation.
! Mon. Wea. Rev., 117, 102-129.
!
! * Sun, W.-Y., Yeh, K.-S., and Sun, R.-Y., 1996:
! A simple semi-Lagrangian scheme for advection equations.
! Quarterly Journal of the Royal Meteorological Society,
! 122(533), 1211-1226. doi:10.1002/qj.49712253310
! モジュール引用 ; USE statements
!
! 種別型パラメタ
! Kind type parameter
!
use dc_types, only: DP, & ! 倍精度実数型. Double precision.
& TOKEN ! キーワード. Keywords.
! メッセージ出力
! Message output
!
use dc_message, only: MessageNotify
!
! MPI
!
use mpi_wrapper, only : MPIWrapperFindMaxVal
! 時刻管理
! Time control
!
use timeset, only: &
& DelTime
! 格子点設定
! Grid points settings
!
use gridset, only: &
& imax, & ! 経度格子点数.
! Number of grid points in longitude
& jmax, & ! 緯度格子点数.
! Number of grid points in latitude
& kmax, & ! 鉛直層数.
! Number of vertical level
& lmax ! スペクトルデータの配列サイズ
! Size of array for spectral data
! 組成に関わる配列の設定
! Settings of array for atmospheric composition
!
use composition, only: &
& ncmax, &
! 成分の数
! Number of composition
& CompositionInqFlagAdv
! 質量の補正
! Mass fixer
!
use mass_fixer, only: &
& MassFixerBC02, MassFixerBC02Layer, MassFixerBC02Column, &
& MassFixer, MassFixerR95, MassFixerWO94, MassFixerColumn!, MassFixerLayer
! 宣言文 ; Declaration statements
!
implicit none
private
! 公開手続き
! Public procedure
!
public :: SLTTInit
public :: SLTTMain
! 公開変数
! Public variables
!
! 非公開変数
! Private variables
!
logical, save :: sltt_inited = .false.
! 初期設定フラグ.
! Initialization flag
real(DP) , save, allocatable :: x_LonS (:)
! $\lambda_S$ 南半球の経度。
! longitude in SH.
real(DP) , save, allocatable :: x_SinLonS(:)
! $\sin\lambda_S$
real(DP) , save, allocatable :: x_CosLonS(:)
! $\cos\lambda_S$
real(DP) , save, allocatable :: y_LatS (:)
! $\varphi_S$ 南半球の緯度。
! latitude in SH.
real(DP) , save, allocatable :: y_SinLatS(:)
! $\sin\varphai_S$
real(DP) , save, allocatable :: y_CosLatS(:)
! $\cos\varphai_S$
real(DP) , save, allocatable :: x_ExtLonS(:)
! $ x_LonSの拡張配列。
!Extended array of x_LonS.
real(DP) , save, allocatable :: y_ExtLatS(:)
! $ x_LatSの拡張配列。
!Extended array of x_LatS.
real(DP) , save, allocatable :: x_LonN (:)
! $\lambda_N$ 北半球の経度。
! longitude in NH.
real(DP) , save, allocatable :: x_SinLonN(:)
! $\sin\lambda_N$
real(DP) , save, allocatable :: x_CosLonN(:)
! $\cos\lambda_N$
real(DP) , save, allocatable :: y_LatN (:)
! $\varphi_N$ 北半球の緯度。
! latitude in NH.
real(DP) , save, allocatable :: y_SinLatN(:)
! $\sin\varphai_N$
real(DP) , save, allocatable :: y_CosLatN(:)
! $\cos\varphai_N$
real(DP) , save, allocatable :: x_ExtLonN(:)
! $ x_LonNの拡張配列。
!Extended array of x_LonN.
real(DP) , save, allocatable :: y_ExtLatN(:)
! $ x_LatNの拡張配列。
!Extended array of x_LatN.
logical, save :: FlagSLTTArcsineHor
logical, save :: FlagSLTTArcsineVer
! Arcsine変換の非負フィルタフラグ
! Flag for non-negative filter using arcsine trasformation
real(DP), save :: SLTTArcSineFactor
character(TOKEN), save :: SLTTIntHor
! 水平方向の補間方法を指定するキーワード
! Keyword for Interpolation Method for Horizontal direction
character(TOKEN), save :: SLTTIntVer
! 鉛直方向の補間方法を指定するキーワード
! Keyword for Interpolation Method for Vertical direction
character(*), parameter:: module_name = 'sltt'
! モジュールの名称.
! Module name
character(*), parameter:: version = &
& '$Name: $' // &
& '$Id: sltt.F90,v 1.8 2014/06/29 07:21:28 yot Exp $'
! モジュールのバージョン
! Module version
!--------------------------------------------------------------------------------------
contains
!--------------------------------------------------------------------------------------
subroutine SLTTMain( &
& xyr_PressB, xyr_PressA, & !(in )
& xyz_UN, xyz_VN, xyr_SigDotN, & !(in )
& xyzf_DQMixDtPhy, & !(in )
& xyzf_QMixB, & !(in )
& xyzf_QMixA & !(out)
& )
! セミラグランジュ法による物質移流計算を行う。
! Calculates tracer transports by Semi-Lagrangian method
! ヒストリデータ出力
! History data output
!
use gtool_historyauto, only: HistoryAutoPut
use timeset , only : &
& TimeN, &
& DelTime
! $\Delta t$
! 組成に関わる配列の設定
! Settings of array for atmospheric composition
!
use composition, only: &
& ncmax, &
! 成分の数
! Number of composition
& a_QMixName, &
! 成分の変数名
! Name of variables for composition
& CompositionInqFlagAdv
!!$ ! 座標データ設定
!!$ ! Axes data settings
!!$ !
!!$ use axesset, only: &
!!$ & z_DelSigma ! $ \Delta \sigma $ (整数).
!!$ ! $ \Delta \sigma $ (Full)
real(DP), intent(in ) :: xyr_PressB(0:imax-1, 1:jmax, 0:kmax)
!
! Pressure at current time step
real(DP), intent(in ) :: xyr_PressA(0:imax-1, 1:jmax, 0:kmax)
!
! Pressure at next time step
real(DP), intent(in ) :: xyz_UN (0:imax-1, 1:jmax, 1:kmax)
! 東西風速
! Zonal Wind
real(DP), intent(in ) :: xyz_VN (0:imax-1, 1:jmax, 1:kmax)
! 南北風速
! Meridional Wind
real(DP), intent(in ) :: xyr_SigDotN(0:imax-1, 1:jmax, 0:kmax)
! 鉛直流速(SigmaDot)
real(DP), intent(in ):: xyzf_DQMixDtPhy(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! $ \left(\DP{q}{t}\right)^{phy} $ .
! 外力項 (物理過程) による比湿変化.
! Temperature tendency by external force terms (physical processes)
real(DP), intent(in ) :: xyzf_QMixB(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 物質混合比
! Mix ratio of the tracers
real(DP), intent(out) :: xyzf_QMixA(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 物質混合比
! Mix ratio of the tracers
! 作業変数
! Work variables
!
real(DP) :: f_QMixMax(1:ncmax)
! 各物質混合比の最大値
! Maximum of each mix ratio of the tracers
real(DP) :: f_QMixProcMax(1:ncmax)
! 各物質混合比のプロセス内最大値
! Maximum of each mix ratio of the tracers in each process
real(DP) :: f_QMixLinMax(1:ncmax)
real(DP) :: f_QMixLinProcMax(1:ncmax)
integer:: n ! 組成方向に回る DO ループ用作業変数
! Work variables for DO loop in dimension of constituents
real(DP) :: xyz_UTest (0:imax-1, 1:jmax, 1:kmax)
! 東西風速(テスト用)
! Zonal Wind (for test)
real(DP) :: xyz_VTest (0:imax-1, 1:jmax, 1:kmax)
! 南北風速(テスト用)
! Meridional Wind (for test)
real(DP) :: xyr_SigDotTest(0:imax-1, 1:jmax, 0:kmax)
! 鉛直流速(テスト用);SigmaDot (for test)
real(DP) :: xyzf_QMixSave(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP) :: xyzf_QMixLinATentative(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP) :: xyzf_QMixLinA (0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! Variables for monotone limiter
real(DP) :: xyzf_QMixMinA (0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP) :: xyzf_QMixMaxA (0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP) :: xyzf_QMixSaveMassFix (0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP) :: xyzf_DQMixDtHorMassFix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP) :: xyzf_DQMixDtVerMassFix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP) :: xyzf_DQMixDtTotMassFix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
!!$ real(DP) :: xyrf_QMixA(0:imax-1, 1:jmax, 0:kmax, 1:ncmax)
!!$
!!$ integer :: k
! セミラグランジュ法による物質移流計算
! Semi-Lagrangian method for tracer transport
!!$! xyzf_QMixA = xyzf_QMixB !テスト用
!!$ xyzf_QMixA = xyzf_QMixB + xyzf_DQMixDtPhy * DelTime
xyzf_QMixA = xyzf_QMixB + xyzf_DQMixDtPhy * 2.0_DP * DelTime
! Save a variable for mass fixer
xyzf_QMixSave = xyzf_QMixA
! Mass fixer
! Constituents
!
!!$! call MassFixer( &
!!$ call MassFixerColumn( &
!!$! & xyr_PressA, & ! (in)
!!$ & xyr_PressB, & ! (in)
!!$ & xyzf_QMixA, & ! (inout)
!!$ & xyr_PressRef = xyr_PressB, & ! (in) optional
!!$! & xyzf_QMixRef = ( xyzf_QMixB+xyzf_DQMixDtPhy*DelTime ) & ! (in) optional
!!$! & xyzf_QMixRef = ( xyzf_QMixB+xyzf_DQMixDtPhy*2.0_DP*DelTime ) & ! (in) optional
!!$ & xyzf_QMixRef = xyzf_QMixSave & ! (in) optional
!!$ & )
!
!!$ call MassFixer( &
call MassFixerColumn( &
& xyr_PressB, & ! (in)
& xyzf_QMixA, & ! (inout)
& xyr_PressRef = xyr_PressB, & ! (in) optional
& xyzf_QMixRef = xyzf_QMixSave & ! (in) optional
& )
! Save a variable for mass fixer
xyzf_QMixSave = xyzf_QMixA
! Variable for linear interpolation
xyzf_QMixLinA = xyzf_QMixA
if ( FlagSLTTArcsineHor ) then
! 非負を保証するための arcsine変換フィルタ
! Arcsine transformation for non-negative filter
do n = 1, ncmax
f_QMixProcMax(n) = maxval( xyzf_QMixA(:,:,:,n) )
end do
call MPIWrapperFindMaxVal( &
& ncmax, f_QMixProcMax, & ! (in)
& f_QMixMax & ! (out)
& )
f_QMixMax = f_QMixMax * SLTTArcSineFactor + 1.0e-14_DP
do n = 1, ncmax
xyzf_QMixA(:,:,:,n) = &
& 0.5_DP*(asin(2.0_DP*xyzf_QMixA(:,:,:,n)/f_QMixMax(n) - 1.0_DP))
end do
! arcsine transformed variable is used for linear interpolation too
xyzf_QMixLinA = xyzf_QMixA
f_QMixLinProcMax = f_QMixProcMax
f_QMixLinMax = f_QMixMax
end if
! 水平セミラグ
! Horizontal
!!$ xyzf_QMixA = SLTTHorAdv( xyzf_QMixA, xyz_UN, xyz_VN )
xyzf_QMixA = SLTTHorAdv( xyzf_QMixA, xyz_UN, xyz_VN, & ! (in)
& xyzf_QMixLinA = xyzf_QMixLinA, & ! (inout) optional
& xyzf_QMixMinA = xyzf_QMixMinA, & ! (out) optional
& xyzf_QMixMaxA = xyzf_QMixMaxA ) ! (out) optional
! Monotonic filter
! see Diamantakis and Flemming (2014) for BS limiter
! but limiter is applied separately in horizontal and vertical directions
#ifdef SLTT2D1DMONOTONIC
xyzf_QMixA = max( min( xyzf_QMixA, xyzf_QMixMaxA ), xyzf_QMixMinA )
#endif
!==================================================
! Calculation in a case in which mass fixer applied in horizontal and
! vertical directions separately
!
!!$ if (FlagSLTTArcsine) then
!!$ ! 非負を保証するための arcsine変換フィルタ(逆変換)
!!$ ! Arcsine transformation for non-negative filter
!!$ do n = 1, ncmax
!!$ xyzf_QMixA(:,:,:,n) = &
!!$ & f_QMixMax(n)*(0.5_DP)*(sin(2.0_DP*xyzf_QMixA(:,:,:,n))+1.0_DP)
!!$! xyzf_QMixLinA(:,:,:,n) = &
!!$! & f_QMixMax(n)*(0.5_DP)*(sin(2.0_DP*xyzf_QMixLinA(:,:,:,n))+1.0_DP)
!!$ enddo
!!$ endif
!!$ !
!!$ xyzf_QMixSaveMassFix = xyzf_QMixA
!!$ !
!!$ call MassFixerBC02Layer( &
!!$ & xyr_PressA, & ! (in)
!!$ & xyzf_QMixA, & ! (inout)
!!$ & xyzf_QMixLinA, & ! (in)
!!$ & xyr_PressB, & ! (in)
!!$ & xyzf_QMixSave & ! (in)
!!$ & )
!!$ !
!!$ xyzf_DQMixDtHorMassFix = &
!!$ & ( xyzf_QMixA - xyzf_QMixSaveMassFix ) / ( 2.0_DP * DelTime )
!!$ !
!!$ ! Save a variable for mass fixer
!!$ xyzf_QMixSave = xyzf_QMixA
!!$ !
!!$ ! Variable for linear interpolation
!!$ xyzf_QMixLinATentative = xyzf_QMixA
!!$ !
!!$ if (FlagSLTTArcsine) then
!!$ ! 非負を保証するための arcsine変換フィルタ
!!$ ! Arcsine transformation for non-negative filter
!!$ !
!!$ do n = 1, ncmax
!!$ f_QMixProcMax(n) = maxval( xyzf_QMixA(:,:,:,n) )
!!$ end do
!!$ call MPIWrapperFindMaxVal( &
!!$ & ncmax, f_QMixProcMax, & ! (in)
!!$ & f_QMixMax & ! (out)
!!$ & )
!!$ f_QMixMax = f_QMixMax * SLTTArcSineFactor + 1.0e-14_DP
!!$ do n = 1, ncmax
!!$ xyzf_QMixA(:,:,:,n) = &
!!$ & 0.5_DP*(asin(2.0_DP*xyzf_QMixA(:,:,:,n)/f_QMixMax(n) - 1.0_DP))
!!$ end do
!!$ end if
!==================================================
! Calculation in a case in which mass fixer applied in horizontal and
! vertical directions in a same time
!
if ( ( .not. FlagSLTTArcsineHor ) .and. ( FlagSLTTArcsineVer ) ) then
! 非負を保証するための arcsine変換フィルタ
! Arcsine transformation for non-negative filter
do n = 1, ncmax
f_QMixProcMax(n) = maxval( xyzf_QMixA(:,:,:,n) )
end do
call MPIWrapperFindMaxVal( &
& ncmax, f_QMixProcMax, & ! (in)
& f_QMixMax & ! (out)
& )
f_QMixMax = f_QMixMax * SLTTArcSineFactor + 1.0e-14_DP
do n = 1, ncmax
xyzf_QMixA(:,:,:,n) = &
& 0.5_DP*(asin(2.0_DP*xyzf_QMixA(:,:,:,n)/f_QMixMax(n) - 1.0_DP))
end do
do n = 1, ncmax
f_QMixLinProcMax(n) = maxval( xyzf_QMixLinA(:,:,:,n) )
end do
call MPIWrapperFindMaxVal( &
& ncmax, f_QMixLinProcMax, & ! (in)
& f_QMixLinMax & ! (out)
& )
f_QMixLinMax = f_QMixLinMax * SLTTArcSineFactor + 1.0e-14_DP
do n = 1, ncmax
xyzf_QMixLinA(:,:,:,n) = &
& 0.5_DP*(asin(2.0_DP*xyzf_QMixLinA(:,:,:,n)/f_QMixLinMax(n) - 1.0_DP))
end do
else if ( ( FlagSLTTArcsineHor ) .and. ( .not. FlagSLTTArcsineVer ) ) then
! 非負を保証するための arcsine変換フィルタ(逆変換)
! Arcsine transformation for non-negative filter
do n = 1, ncmax
xyzf_QMixA(:,:,:,n) = &
& f_QMixMax(n)*(0.5_DP)*(sin(2.0_DP*xyzf_QMixA(:,:,:,n))+1.0_DP)
end do
do n = 1, ncmax
xyzf_QMixLinA(:,:,:,n) = &
& f_QMixLinMax(n)*(0.5_DP)*(sin(2.0_DP*xyzf_QMixLinA(:,:,:,n))+1.0_DP)
end do
end if
xyzf_DQMixDtHorMassFix = 0.0_DP
xyzf_QMixLinATentative = xyzf_QMixLinA
!==================================================
! 鉛直セミラグ
! Vertical
!!$ xyzf_QMixA = SLTTVerAdv( xyr_SigDotN, xyzf_QMixA )
xyzf_QMixA = SLTTVerAdv( xyr_SigDotN, xyzf_QMixA, &
& xyzf_QMixLin = xyzf_QMixLinATentative, & ! (in ) optional
& xyzf_QMixLinA = xyzf_QMixLinA, & ! (out ) optional
& xyzf_QMixMinA = xyzf_QMixMinA, & ! (inout) optional
& xyzf_QMixMaxA = xyzf_QMixMaxA ) ! (inout) optional
! Monotonic filter
! see Diamantakis and Flemming (2014) for BS limiter
! but limiter is applied separately in horizontal and vertical directions
#ifdef SLTT2D1DMONOTONIC
xyzf_QMixA = max( min( xyzf_QMixA, xyzf_QMixMaxA ), xyzf_QMixMinA )
#endif
! Vertical advection by finite difference method
!
!!$ do n = 1, ncmax
!!$ k = 1
!!$ xyrf_QMixA(:,:,k,n) = 1.0e100_DP
!!$ do k = 1, kmax-1
!!$ xyrf_QMixA(:,:,k,n) = &
!!$ & ( xyzf_QMixA(:,:,k,n) + xyzf_QMixA(:,:,k+1,n) ) / 2.0_DP
!!$ end do
!!$ k = kmax
!!$ xyrf_QMixA(:,:,k,n) = 1.0e100_DP
!!$ end do
!!$ do n = 1, ncmax
!!$ do k = 1, kmax
!!$ xyzf_QMixA(:,:,k,n) = xyzf_QMixA(:,:,k,n) &
!!$ & + ( &
!!$ & - ( xyr_SigDotN(:,:,k-1) * xyrf_QMixA(:,:,k-1,n) &
!!$ & - xyr_SigDotN(:,:,k ) * xyrf_QMixA(:,:,k ,n) ) &
!!$ & / z_DelSigma(k) &
!!$ & + xyzf_QMixA(:,:,k,n) &
!!$ & * ( xyr_SigDotN(:,:,k-1) - xyr_SigDotN(:,:,k ) ) &
!!$ & / z_DelSigma(k) &
!!$ & ) * 2.0_DP * DelTime
!!$ end do
!!$ end do
! 移流テスト
! call SLTTTest(xyz_UTest, xyz_VTest, xyr_SigDotTest)
! xyzf_QMixA = SLTTHorAdv( xyzf_QMixA, xyz_UTest, xyz_VTest ) ! 水平セミラグ
! xyzf_QMixA = SLTTVerAdv( xyr_SigDotTest, xyzf_QMixA ) ! 鉛直セミラグ
if ( FlagSLTTArcsineVer ) then
! 非負を保証するための arcsine変換フィルタ(逆変換)
! Arcsine transformation for non-negative filter
do n = 1, ncmax
xyzf_QMixA(:,:,:,n) = &
& f_QMixMax(n)*(0.5_DP)*(sin(2.0_DP*xyzf_QMixA(:,:,:,n))+1.0_DP)
end do
do n = 1, ncmax
xyzf_QMixLinA(:,:,:,n) = &
& f_QMixLinMax(n)*(0.5_DP)*(sin(2.0_DP*xyzf_QMixLinA(:,:,:,n))+1.0_DP)
end do
end if
!!$! xyzf_QMixA = xyzf_QMixB !テスト用
!!$ xyzf_QMixA = xyzf_QMixA + xyzf_DQMixDtPhy * DelTime
! Mass fixer
!!$ call MassFixerColumn( &
!!$ & xyr_PressA, & ! (in)
!!$ & xyzf_QMixA, & ! (inout)
!!$! & xyr_PressRef = xyr_PressB, & ! (in) optional
!!$ & xyr_PressRef = xyr_PressA, & ! (in) optional
!!$ & xyzf_QMixRef = xyzf_QMixSave & ! (in) optional
!!$ & )
!==================================================
! Calculation in a case in which other type of mass fixer is applied
!
!!$ xyzf_QMixSaveMassFix = xyzf_QMixA
!!$ !
!!$! call MassFixer( &
!!$! call MassFixerWO94( &
!!$ call MassFixerR95( &
!!$ & xyr_PressA, & ! (in)
!!$ & xyzf_QMixA, & ! (inout)
!!$ & xyr_PressRef = xyr_PressB, & ! (in) optional
!!$ & xyzf_QMixRef = xyzf_QMixSave & ! (in) optional
!!$ & )
!!$ !
!!$ xyzf_DQMixDtVerMassFix = 0.0_DP
!==================================================
! Calculation in a case in which mass fixer applied in horizontal and
! vertical directions separately
!
!!$ xyzf_QMixSaveMassFix = xyzf_QMixA
!!$ !
!!$ call MassFixerBC02Column( &
!!$ & xyr_PressA, & ! (in)
!!$ & xyzf_QMixA, & ! (inout)
!!$ & xyzf_QMixLinA, & ! (in)
!!$ & xyr_PressA, & ! (in)
!!$ & xyzf_QMixSave & ! (in)
!!$ & )
!!$ !
!!$ xyzf_DQMixDtVerMassFix = &
!!$ & ( xyzf_QMixA - xyzf_QMixSaveMassFix ) / ( 2.0_DP * DelTime )
!!$ !
!!$ xyzf_DQMixDtTotMassFix = &
!!$ & xyzf_DQMixDtHorMassFix + xyzf_DQMixDtVerMassFix
!==================================================
! Calculation in a case in which mass fixer applied in horizontal and
! vertical directions in a same time
!
xyzf_QMixSaveMassFix = xyzf_QMixA
!
call MassFixerBC02( &
& xyr_PressA, & ! (in)
& xyzf_QMixA, & ! (inout)
& xyzf_QMixLinA, & ! (in)
& xyr_PressB, & ! (in)
& xyzf_QMixSave & ! (in)
& )
!
xyzf_DQMixDtVerMassFix = 0.0_DP
!==================================================
xyzf_DQMixDtTotMassFix = &
& + ( xyzf_QMixA - xyzf_QMixSaveMassFix ) / ( 2.0_DP * DelTime )
do n = 1, ncmax
call HistoryAutoPut( TimeN, 'SLD'//trim(a_QMixName(n))//'DtHorMassFix', &
& xyzf_DQMixDtHorMassFix(:,:,:,n) )
call HistoryAutoPut( TimeN, 'SLD'//trim(a_QMixName(n))//'DtVerMassFix', &
& xyzf_DQMixDtVerMassFix(:,:,:,n) )
call HistoryAutoPut( TimeN, 'SLD'//trim(a_QMixName(n))//'DtTotMassFix', &
& xyzf_DQMixDtTotMassFix(:,:,:,n) )
end do
end subroutine SLTTMain
!----------------------------------------------------------------------------
function SLTTHorAdv( xyzf_QMix, xyz_U, xyz_V, & ! (in)
& xyzf_QMixLinA, & ! (inout) optional
& xyzf_QMixMinA, xyzf_QMixMaxA & ! (out) optional
& ) result( xyzf_QMixA )
! セミラグランジュ法による水平移流の計算
! Calculates tracer transports by Semi-Lagrangian method for horizontal direction
use timeset , only : DelTime
! $\Delta t$
use axesset , only : x_Lon, y_Lat
! $\lambda, \varphai$ lon and lat
use sltt_const , only : dtjw, iexmin, iexmax, jexmin, jexmax
use sltt_extarr, only : SLTTExtArrExt, SLTTExtArrExt2
! 配列拡張ルーチン
! Expansion of arrays
use sltt_dp , only : SLTTDPHor
! 水平上流点探索
! Finding departure point in horizontal
use sltt_lagint, only : SLTTIrrHerIntK13, SLTTIrrLinInt, SLTTLagIntHorMaxMin
! 水平2次元の補間
! 2D Interpolation in horizontal
! SPMODEL ライブラリ, 球面上の問題を球面調和函数変換により解く(多層対応)
! SPMODEL library, problems on sphere are solved with spherical harmonics (multi layer is supported)
!
#ifdef LIB_MPI
#ifdef SJPACK
use wa_mpi_module_sjpack, only: &
& wa_xya => wa_xva, &
& xya_wa => xva_wa, &
& wa_DLon_wa, &
& xya_GradLat_wa => xva_GradLat_wa
#else
use wa_mpi_module, only: &
& wa_xya => wa_xva, &
& xya_wa => xva_wa, &
& wa_DLon_wa, &
& xya_GradLat_wa => xva_GradLat_wa
#endif
#elif AXISYMMETRY
use wa_zonal_module, only: &
& wa_xya, xya_wa, &
& wa_DLon_wa, xya_GradLat_wa
#elif SJPACK
use wa_module_sjpack, only: &
& wa_xya, xya_wa, &
& wa_DLon_wa, xya_GradLat_wa
#elif AXISYMMETRY_SJPACK
use wa_zonal_module_sjpack, only: &
& wa_xya, xya_wa, &
& wa_DLon_wa, xya_GradLat_wa
#else
use wa_module, only: &
& wa_xya, xya_wa , &
& wa_DLon_wa, xya_GradLat_wa
#endif
real(DP), intent(in ) :: xyzf_QMix(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 現在時刻の物質混合比
! Present mix ratio of the tracers
real(DP), intent(in ) :: xyz_U (0:imax-1, 1:jmax, 1:kmax)
! 東西風速
! Zonal Wind
real(DP), intent(in ) :: xyz_V (0:imax-1, 1:jmax, 1:kmax)
! 南北風速
! Meridional Wind
real(DP), intent(inout), optional :: xyzf_QMixLinA(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 次ステップの物質混合比
! Next mix ratio of the tracers estimated by linear interpolation
real(DP), intent(out), optional :: xyzf_QMixMinA(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP), intent(out), optional :: xyzf_QMixMaxA(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP) :: xyzf_QMixA(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 次ステップの物質混合比
! Next mix ratio of the tracers
!
! local variables
!
real(DP) :: xyzf_ExtQMixS(iexmin:iexmax, jexmin:jexmax, 1:kmax, 1:ncmax)
! 現在時刻の物質混合比の拡張配列(南半球)
! Extended array (SH) of present mix ratio of the tracers.
real(DP) :: xyzf_ExtQMixN(iexmin:iexmax, jexmin:jexmax, 1:kmax, 1:ncmax)
! 現在時刻の物質混合比の拡張配列(北半球)
! Extended array (NH) of present mix ratio of the tracers.
real(DP) :: xyzf_ExtQMixLinAS(iexmin:iexmax, jexmin:jexmax, 1:kmax, 1:ncmax)
! 現在時刻の物質混合比の拡張配列(南半球)
! Extended array (SH) of present mix ratio of the tracers.
real(DP) :: xyzf_ExtQMixLinAN(iexmin:iexmax, jexmin:jexmax, 1:kmax, 1:ncmax)
! 現在時刻の物質混合比の拡張配列(北半球)
! Extended array (NH) of present mix ratio of the tracers.
real(DP) :: xyz_ExtUS (iexmin:iexmax, jexmin:jexmax, 1:kmax)
! 東西風速の拡張配列(南半球)
! Extended array (SH) of Zonal Wind
real(DP) :: xyz_ExtUN (iexmin:iexmax, jexmin:jexmax, 1:kmax)
! 東西風速の拡張配列(北半球)
! Extended array (NH) of Zonal Wind
real(DP) :: xyz_ExtVS (iexmin:iexmax, jexmin:jexmax, 1:kmax)
! 南北風速の拡張配列(南半球)
! Extended array (SH) of Meridional Wind
real(DP) :: xyz_ExtVN (iexmin:iexmax, jexmin:jexmax, 1:kmax)
! 南北風速の拡張配列(北半球)
! Extended array (NH) of Meridional Wind
integer:: i, ii ! 東西方向に回る DO ループ用作業変数
! Work variables for DO loop in zonal direction
integer:: j ! 南北方向に回る DO ループ用作業変数
! Work variables for DO loop in meridional direction
integer:: k ! 鉛直方向に回る DO ループ用作業変数
! Work variables for DO loop in vertical direction
integer:: n ! 組成方向に回る DO ループ用作業変数
! Work variables for DO loop in dimension of constituents
real(DP) :: xyz_DPLonS(0:imax-1, 1:jmax/2, 1:kmax)
! 上流点経度(南半球)
! Lon of the departure point (SH)
real(DP) :: xyz_DPLonN(0:imax-1, 1:jmax/2, 1:kmax)
! 上流点経度(北半球)
! Lon of the departure point (NH)
real(DP) :: xyz_DPLatS(0:imax-1, 1:jmax/2, 1:kmax)
! 上流点緯度(南半球)
! Lat of the departure point (SH)
real(DP) :: xyz_DPLatN(0:imax-1, 1:jmax/2, 1:kmax)
! 上流点緯度(北半球)
! Lat of the departure point (NH)
real(DP) :: xyzf_QMixAS(0:imax-1, 1:jmax/2, 1:kmax, 1:ncmax)
! 次ステップの物質混合比(南半球)
! Next mix ratio of the tracers (SH)
real(DP) :: xyzf_QMixAN(0:imax-1, 1:jmax/2, 1:kmax, 1:ncmax)
! 次ステップの物質混合比(北半球)
! Next mix ratio of the tracers (NH)
real(DP) :: xyzf_QMixMinAS(0:imax-1, 1:jmax/2, 1:kmax, 1:ncmax)
real(DP) :: xyzf_QMixMaxAS(0:imax-1, 1:jmax/2, 1:kmax, 1:ncmax)
real(DP) :: xyzf_QMixMinAN(0:imax-1, 1:jmax/2, 1:kmax, 1:ncmax)
real(DP) :: xyzf_QMixMaxAN(0:imax-1, 1:jmax/2, 1:kmax, 1:ncmax)
!---fx, fy, fxy
real(DP) :: xyzf_QMix_dlon(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 物質混合比の経度微分(グリッド)
! Zonal derivative of the mix ratio (on grid)
real(DP) :: xyzf_QMix_dlat(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 物質混合比の緯度微分(グリッド)
! Meridional derivative of the mix ratio (on grid)
real(DP) :: xyzf_QMix_dlonlat(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 物質混合比の緯度経度微分(グリッド)
! Zonal and meridional derivative of the mix ratio (on grid)
real(DP) :: xyzf_ExtQMixS_dlon(iexmin:iexmax, jexmin:jexmax, 1:kmax, 1:ncmax)
! 物質混合比の経度微分の拡張配列(南半球)
! Extended array (SH) of zonal derivative of the mix ratio
real(DP) :: xyzf_ExtQMixN_dlon(iexmin:iexmax, jexmin:jexmax, 1:kmax, 1:ncmax)
! 物質混合比の経度微分の拡張配列(北半球)
! Extended array (NH) of zonal derivative of the mix ratio
real(DP) :: xyzf_ExtQMixS_dlat(iexmin:iexmax, jexmin:jexmax, 1:kmax, 1:ncmax)
! 物質混合比の緯度微分の拡張配列(南半球)
! Extended array (SH) of meridional derivative of the mix ratio
real(DP) :: xyzf_ExtQMixN_dlat(iexmin:iexmax, jexmin:jexmax, 1:kmax, 1:ncmax)
! 物質混合比の緯度微分の拡張配列(北半球)
! Extended array (NH) of meridional derivative of the mix ratio
real(DP) :: xyzf_ExtQMixS_dlonlat(iexmin:iexmax, jexmin:jexmax, 1:kmax, 1:ncmax)
! 物質混合比の緯度経度微分の拡張配列(南半球)
! Extended array (SH) of zonal and meridional derivative of the mix ratio
real(DP) :: xyzf_ExtQMixN_dlonlat(iexmin:iexmax, jexmin:jexmax, 1:kmax, 1:ncmax)
! 物質混合比の緯度経度微分の拡張配列(北半球)
! Extended array (NH) of zonal and meridional derivative of the mix ratio
real(DP) :: wzf_QMix(1:lmax, 1:kmax, 1:ncmax)
! 物質混合比の経度微分(スペクトル)
! Zonal derivative of the mix ratio (on grid)
real(DP) :: wzf_QMix_dlon(1:lmax, 1:kmax, 1:ncmax)
! 物質混合比の経度微分(スペクトル)
! Zonal derivative of the mix ratio (on grid)
real(DP) :: PM ! 配列拡張する際、極ごえ後に符号が変わる場合は -1.0を与える。そうでない場合は1.0を与える。
! Sign change flag for array extension; -1.0 for sign change over the pole, 1.0 for no sign change
!---fxx, fyy, fxxyy
! real(DP) :: xyzf_QMix_dlon2(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_QMix_dlat2(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_QMix_dlon2lat2(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_ExtQMixS_dlon2(-2+0:imax-1+3, -jew+1:jmax/2+jew, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_ExtQMixN_dlon2(-2+0:imax-1+3, -jew+1:jmax/2+jew, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_ExtQMixS_dlat2(-2+0:imax-1+3, -jew+1:jmax/2+jew, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_ExtQMixN_dlat2(-2+0:imax-1+3, -jew+1:jmax/2+jew, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_ExtQMixS_dlon2lat2(-2+0:imax-1+3, -jew+1:jmax/2+jew, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_ExtQMixN_dlon2lat2(-2+0:imax-1+3, -jew+1:jmax/2+jew, 1:kmax, 1:ncmax)
!----fxxy
! real(DP) :: xyzf_QMix_dlon2lat(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_ExtQMixS_dlon2lat(-2+0:imax-1+3, -jew+1:jmax/2+jew, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_ExtQMixN_dlon2lat(-2+0:imax-1+3, -jew+1:jmax/2+jew, 1:kmax, 1:ncmax)
!----fxyy
! real(DP) :: xyzf_QMix_dlonlat2(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_ExtQMixS_dlonlat2(-2+0:imax-1+3, -jew+1:jmax/2+jew, 1:kmax, 1:ncmax)
! real(DP) :: xyzf_ExtQMixN_dlonlat2(-2+0:imax-1+3, -jew+1:jmax/2+jew, 1:kmax, 1:ncmax)
!----
! real(DP) :: wzf_QMix_dlon2(1:lmax, 1:kmax, 1:ncmax)
! 実行文 ; Executable statement
!
! 初期化確認
! Initialization check
!
if ( .not. sltt_inited ) then
call MessageNotify( 'E', module_name, 'This module has not been initialized.' )
end if
! QMixの微分計算(スペクトル変換利用)
! Derivatives of QMix
do n = 1, ncmax
wzf_QMix(:,:,n) = wa_xya(xyzf_QMix(:,:,:,n)) ! グリッド→スペクトル
! grid -> spectrum
xyzf_QMix_dlat(:,:,:,n) = xya_GradLat_wa(wzf_QMix(:,:,n)) ! スペクトル→グリッド緯度微分
! spectrum -> grid (dQ/dlat)
wzf_QMix_dlon(:,:,n) = wa_Dlon_wa(wzf_QMix(:,:,n)) ! スペクトル→スペクトル経度微分
! spectrum -> spectrum (dQ/dlon)
xyzf_QMix_dlon(:,:,:,n) = xya_wa(wzf_QMix_dlon(:,:,n)) ! スペクトル経度微分→グリッド経度微分
! spectrum (dQ/dlon) -> grid (dQ/dlon)
xyzf_QMix_dlonlat(:,:,:,n) = xya_GradLat_wa(wzf_QMix_dlon(:,:,n))! スペクトル経度微分→グリッド緯度経度微分
! spectrum (dQ/dlon) -> grid (d^2Q/dlon dlat)
!---fxx, fyy, fxxy, fxyy, fxxyy を計算
!xyzf_QMix_dlon2(:,:,:,n) = xya_wa(wa_Dlon_wa(wzf_QMix_dlon(:,:,n)))
!xyzf_QMix_dlat2(:,:,:,n) = xya_GradLat_wa(wa_xya(xyzf_QMix_dlat(:,:,:,n)))
!xyzf_QMix_dlon2lat(:,:,:,n) = xya_GradLat_wa(wa_xya(xyzf_QMix_dlon2(:,:,:,n)))
!xyzf_QMix_dlonlat2(:,:,:,n) = xya_GradLat_wa(wa_xya(xyzf_QMix_dlonlat(:,:,:,n)))
!xyzf_QMix_dlon2lat2(:,:,:,n) = xya_GradLat_wa(wa_xya(xyzf_QMix_dlon2lat(:,:,:,n)))
enddo
! 配列の分割と拡張
! Division and extension of arrays
!
! 配列の分割と拡張
! Division and extension of arrays
pm = -1.0_DP ! 配列拡張する際、極ごえ後に符号が変わる場合は -1.0を与える。そうでない場合は1.0を与える。
! -1.0 if the sign of value changes over the poles; if not 1.0.
!!$ call SLTTExtArrExt2( &
!!$ & xyzf_QMix_dlon, pm, & ! (in)
!!$ & xyzf_ExtQMixS_dlon, xyzf_ExtQMixN_dlon & ! (out)
!!$ & )
!!$ call SLTTExtArrExt2( &
!!$ & x_SinLonS, x_CosLonS, x_SinLonN, x_CosLonN, & ! (in)
!!$ & xyzf_QMix_dlon, pm, & ! (in)
!!$ & xyzf_ExtQMixS_dlon, xyzf_ExtQMixN_dlon, & ! (out)
!!$ & "Wave1" & ! (in)
!!$ & )
call SLTTExtArrExt2( &
& x_SinLonS, x_CosLonS, x_SinLonN, x_CosLonN, & ! (in)
& xyzf_QMix_dlon, pm, & ! (in)
& xyzf_ExtQMixS_dlon, xyzf_ExtQMixN_dlon & ! (out)
& )
pm = -1.0_DP ! 配列拡張する際、極ごえ後に符号が変わる場合は -1.0を与える。そうでない場合は1.0を与える。
! -1.0 if the sign of value changes over the poles; if not 1.0.
!!$ call SLTTExtArrExt2( &
!!$ & xyzf_QMix_dlat, pm, & ! (in)
!!$ & xyzf_ExtQMixS_dlat, xyzf_ExtQMixN_dlat & ! (out)
!!$ & )
!!$ call SLTTExtArrExt2( &
!!$ & x_SinLonS, x_CosLonS, x_SinLonN, x_CosLonN, & ! (in)
!!$ & xyzf_QMix_dlat, pm, & ! (in)
!!$ & xyzf_ExtQMixS_dlat, xyzf_ExtQMixN_dlat, & ! (out)
!!$ & "Wave1" & ! (in)
!!$ & )
call SLTTExtArrExt2( &
& x_SinLonS, x_CosLonS, x_SinLonN, x_CosLonN, & ! (in)
& xyzf_QMix_dlat, pm, & ! (in)
& xyzf_ExtQMixS_dlat, xyzf_ExtQMixN_dlat & ! (out)
& )
pm = +1.0_DP ! 配列拡張する際、極ごえ後に符号が変わる場合は -1.0を与える。そうでない場合は1.0を与える。
! -1.0 if the sign of value changes over the poles; if not 1.0.
!!$ call SLTTExtArrExt2( &
!!$ & xyzf_QMix_dlonlat, pm, & ! (in)
!!$ & xyzf_ExtQMixS_dlonlat, xyzf_ExtQMixN_dlonlat & ! (out)
!!$ & )
!!$ call SLTTExtArrExt2( &
!!$ & x_SinLonS, x_CosLonS, x_SinLonN, x_CosLonN, & ! (in)
!!$ & xyzf_QMix_dlonlat, pm, & ! (in)
!!$ & xyzf_ExtQMixS_dlonlat, xyzf_ExtQMixN_dlonlat, & ! (out)
!!$ & "Wave1" & ! (in)
!!$ & )
call SLTTExtArrExt2( &
& x_SinLonS, x_CosLonS, x_SinLonN, x_CosLonN, & ! (in)
& xyzf_QMix_dlonlat, pm, & ! (in)
& xyzf_ExtQMixS_dlonlat, xyzf_ExtQMixN_dlonlat & ! (out)
& )
!-----fxx, fyy, fxxy, fxyy, fxxyy の配列拡張
! pm = +1.0_DP ! 配列拡張する際、極ごえ後に符号が変わる場合は -1.0を与える。そうでない場合は1.0を与える。
! -1.0 if the sign of value changes over the poles; if not 1.0.
! call SLTTExtArrExt2( &
! & xyzf_QMix_dlon2, pm, & ! (in)
! & xyzf_ExtQMixS_dlon2, xyzf_ExtQMixN_dlon2 & ! (out)
! & )
! pm = +1.0_DP ! 配列拡張する際、極ごえ後に符号が変わる場合は -1.0を与える。そうでない場合は1.0を与える。
! -1.0 if the sign of value changes over the poles; if not 1.0.
! call SLTTExtArrExt2( &
! & xyzf_QMix_dlat2, pm, & ! (in)
! & xyzf_ExtQMixS_dlat2, xyzf_ExtQMixN_dlat2 & ! (out)
! & )
! pm = -1.0_DP ! 配列拡張する際、極ごえ後に符号が変わる場合は -1.0を与える。そうでない場合は1.0を与える。
! -1.0 if the sign of value changes over the poles; if not 1.0.
! call SLTTExtArrExt2( &
! & xyzf_QMix_dlon2lat, pm, & ! (in)
! & xyzf_ExtQMixS_dlon2lat, xyzf_ExtQMixN_dlon2lat & ! (out)
! & )
! pm = -1.0_DP ! 配列拡張する際、極ごえ後に符号が変わる場合は -1.0を与える。そうでない場合は1.0を与える。
! -1.0 if the sign of value changes over the poles; if not 1.0.
! call SLTTExtArrExt2( &
! & xyzf_QMix_dlonlat2, pm, & ! (in)
! & xyzf_ExtQMixS_dlonlat2, xyzf_ExtQMixN_dlonlat2 & ! (out)
! & )
! pm = +1.0_DP ! 配列拡張する際、極ごえ後に符号が変わる場合は -1.0を与える。そうでない場合は1.0を与える。
! -1.0 if the sign of value changes over the poles; if not 1.0.
! call SLTTExtArrExt2( &
! & xyzf_QMix_dlon2lat2, pm, & ! (in)
! & xyzf_ExtQMixS_dlon2lat2, xyzf_ExtQMixN_dlon2lat2 & ! (out)
! & )
!!$ call SLTTExtArrExt( &
!!$ & x_SinLonS, x_CosLonS, x_SinLonN, x_CosLonN, & ! (in)
!!$ & xyzf_QMix, xyz_U, xyz_V, & ! (in)
!!$ & xyzf_ExtQMixS, xyzf_ExtQMixN, & ! (out)
!!$ & xyz_ExtUS, xyz_ExtUN, & ! (out)
!!$ & xyz_ExtVS, xyz_ExtVN & ! (out)
!!$ & )
call SLTTExtArrExt( &
& y_ExtLatS, y_ExtLatN, & ! (in)
& x_SinLonS, x_CosLonS, x_SinLonN, x_CosLonN, & ! (in)
& xyzf_QMix, xyz_U, xyz_V, & ! (in)
! & xyzf_ExtDQMixDLatS, xyzf_ExtDQMixDLatN, & ! (in)
& xyzf_ExtQMixS_dlat, xyzf_ExtQMixN_dlat, & ! (in)
& xyzf_ExtQMixS, xyzf_ExtQMixN, & ! (out)
& xyz_ExtUS, xyz_ExtUN, & ! (out)
& xyz_ExtVS, xyz_ExtVN & ! (out)
& )
if ( present( xyzf_QMixLinA ) ) then
! Extention of array for linear interpolation
PM = 1.0_DP
call SLTTExtArrExt2( &
& x_SinLonS, x_CosLonS, x_SinLonN, x_CosLonN, & ! (in)
& xyzf_QMixLinA, PM, & ! (in)
& xyzf_ExtQMixLinAS, xyzf_ExtQMixLinAN & ! (out)
& )
end if
! 上流点の計算
! estimation of departure point
! 南半球
! south array
call SLTTDPHor( &
& DelTime, x_LonS, y_LatS, y_SinLatS, y_CosLatS, & ! (in)
& iexmin, iexmax, jexmin, jexmax, & ! (in)
& x_ExtLonS, y_ExtLatS, xyz_ExtUS, xyz_ExtVS, & ! (in)
& xyz_DPLonS, xyz_DPLatS & ! (out)
& )
! 北半球
! north array
call SLTTDPHor( &
& DelTime, x_LonN, y_LatN, y_SinLatN, y_CosLatN, & ! (in)
& iexmin, iexmax, jexmin, jexmax, & ! (in)
& x_ExtLonN, y_ExtLatN, xyz_ExtUN, xyz_ExtVN, & ! (in)
& xyz_DPLonN, xyz_DPLatN & ! (out)
& )
! 補間
! Interpolation
! do n = 1, ncmax
call SLTTIrrHerIntK13( &
& iexmin, iexmax, jexmin, jexmax, & ! (in)
& x_ExtLonS, y_ExtLatS, xyz_DPLonS, xyz_DPLatS, & ! (in)
& xyzf_ExtQMixS(:,:,:,:), xyzf_ExtQMixS_dlon(:,:,:,:), & ! (in)
& xyzf_ExtQMixS_dlat(:,:,:,:), xyzf_ExtQMixS_dlonlat(:,:,:,:), & ! (in)
! & xyzf_ExtQMixS_dlon2(:,:,:,n), xyzf_ExtQMixS_dlat2(:,:,:,n), & ! (in) fxx, fyy
! & xyzf_ExtQMixS_dlon2lat(:,:,:,n), xyzf_ExtQMixS_dlonlat2(:,:,:,n), & ! (in) fxxy, fxyy
! & xyzf_ExtQMixS_dlon2lat2(:,:,:,n), & ! (in) fxxyy
& SLTTIntHor, & ! (in)
& xyzf_QMixAS(:,:,:,:) & ! (out)
& )
call SLTTIrrHerIntK13( &
& iexmin, iexmax, jexmin, jexmax, & ! (in)
& x_ExtLonN, y_ExtLatN, xyz_DPLonN, xyz_DPLatN, & ! (in)
& xyzf_ExtQMixN(:,:,:,:), xyzf_ExtQMixN_dlon(:,:,:,:), & ! (in)
& xyzf_ExtQMixN_dlat(:,:,:,:), xyzf_ExtQMixN_dlonlat(:,:,:,:), & ! (in)
! & xyzf_ExtQMixN_dlon2(:,:,:,n), xyzf_ExtQMixN_dlat2(:,:,:,n), & ! (in) fxx, fyy
! & xyzf_ExtQMixN_dlon2lat(:,:,:,n), xyzf_ExtQMixN_dlonlat2(:,:,:,n), & ! (in) fxxy, fxyy
! & xyzf_ExtQMixN_dlon2lat2(:,:,:,n), & ! (in) fxxyy
& SLTTIntHor, & ! (in)
& xyzf_QMixAN(:,:,:,:) & ! (out)
& )
! enddo
! 南北半球の配列の結合
! joint of each array
xyzf_QMixA(:,1:jmax/2,:,:) = xyzf_QMixAS(:,1:jmax/2,:,:)
xyzf_QMixA(:,jmax/2+1:jmax,:,:) = xyzf_QMixAN(:,1:jmax/2,:,:)
if ( present( xyzf_QMixLinA ) ) then
call SLTTIrrLinInt( &
& iexmin, iexmax, jexmin, jexmax, & ! (in)
& x_ExtLonS, y_ExtLatS, xyz_DPLonS, xyz_DPLatS, xyzf_ExtQMixLinAS, & ! (in)
& xyzf_QMixAS & ! (out)
& )
call SLTTIrrLinInt( &
& iexmin, iexmax, jexmin, jexmax, & ! (in)
& x_ExtLonN, y_ExtLatN, xyz_DPLonN, xyz_DPLatN, xyzf_ExtQMixLinAN, & ! (in)
& xyzf_QMixAN & ! (out)
& )
xyzf_QMixLinA(:,1:jmax/2,:,:) = xyzf_QMixAS(:,1:jmax/2,:,:)
xyzf_QMixLinA(:,jmax/2+1:jmax,:,:) = xyzf_QMixAN(:,1:jmax/2,:,:)
end if
if ( ( ( present( xyzf_QMixMinA ) ) .and. &
& ( .not. present( xyzf_QMixMaxA ) ) ) .or. &
& ( ( .not. present( xyzf_QMixMinA ) ) .and. &
& ( present( xyzf_QMixMaxA ) ) ) ) then
call MessageNotify( 'E', module_name, &
& 'QMixMinA has to be present when QMixMaxA is present, and vice versa.' )
end if
if ( present( xyzf_QMixMinA ) ) then
call SLTTLagIntHorMaxMin( &
& iexmin, iexmax, jexmin, jexmax, & ! (in)
& x_ExtLonS, y_ExtLatS, xyz_DPLonS, xyz_DPLatS, xyzf_ExtQMixS, & ! (in)
& xyzf_QMixMinAS, xyzf_QMixMaxAS & ! (out)
& )
call SLTTLagIntHorMaxMin( &
& iexmin, iexmax, jexmin, jexmax, & ! (in)
& x_ExtLonN, y_ExtLatN, xyz_DPLonN, xyz_DPLatN, xyzf_ExtQMixN, & ! (in)
& xyzf_QMixMinAN, xyzf_QMixMaxAN & ! (out)
& )
xyzf_QMixMinA(:,1:jmax/2,:,:) = xyzf_QMixMinAS(:,1:jmax/2,:,:)
xyzf_QMixMinA(:,jmax/2+1:jmax,:,:) = xyzf_QMixMinAN(:,1:jmax/2,:,:)
xyzf_QMixMaxA(:,1:jmax/2,:,:) = xyzf_QMixMaxAS(:,1:jmax/2,:,:)
xyzf_QMixMaxA(:,jmax/2+1:jmax,:,:) = xyzf_QMixMaxAN(:,1:jmax/2,:,:)
end if
end function SLTTHorAdv
!--------------------------------------------------------------------------------------
function SLTTVerAdv( xyr_SigmaDot, xyzf_QMix, &
& xyzf_QMixLin, & ! (in ) optional
& xyzf_QMixLinA, & ! (out) optional
& xyzf_QMixMinA, xyzf_QMixMaxA & ! (out) optional
& ) result( xyzf_QMixA )
! セミラグランジュ法による鉛直移流の計算
! Calculates tracer transports by Semi-Lagrangian method for vertical direction
use axesset, only : z_Sigma ! 鉛直座標; Sigma coordinate
use timeset, only : DelTime ! $\Delta t$
use sltt_dp, only : SLTTDPVer ! 鉛直上流点探索; Finding departure point in vertical
use sltt_lagint, only : &
& SLTTIrrHerIntQui1DNonUni, & ! 不当間隔格子の五次補間; Quintic Interpolation for non-uniform grids
& SLTTHerIntCub1D
real(DP), intent(in ) :: xyr_SigmaDot(0:imax-1, 1:jmax, 0:kmax)
! 鉛直流速(SigmaDot)
real(DP), intent(in ) :: xyzf_QMix (0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 現在時刻の物質混合比
! Present mix ratio of the tracers
real(DP), intent(in ), optional :: xyzf_QMixLin (0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP), intent(out), optional :: xyzf_QMixLinA(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP), intent(out), optional :: xyzf_QMixMinA(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP), intent(out), optional :: xyzf_QMixMaxA(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP) :: xyzf_QMixA (0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 次ステップの物質混合比
! Next mix ratio of the tracers
!
! local variables
!
real(DP) :: xyz_DPSigma(0:imax-1, 1:jmax, 1:kmax)
! 上流点高度
! Sigma of the departure point
integer:: i ! 東西方向に回る DO ループ用作業変数
! Work variables for DO loop in zonal direction
integer:: j ! 南北方向に回る DO ループ用作業変数
! Work variables for DO loop in meridional direction
integer:: k, kk ! 鉛直方向に回る DO ループ用作業変数
! Work variables for DO loop in vertical direction
integer:: n ! 組成方向に回る DO ループ用作業変数
! Work variables for DO loop in dimension of constituents
integer:: xy_kk(0:imax-1, 1:jmax)
! 上流点の上下のグリッドを探索するための作業変数
! Work variable for finding the grid just above the departure point
real(DP) :: xyzf_QMix_dz(0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
! 物質混合比の鉛直微分
! Vertical derivative of the mix ratio
real(DP) :: xyzf_ExtQMix(0:imax-1, 1:jmax, 1-2:kmax+2, 1:ncmax)
! 物質混合比の拡張配列
! Extended array of the mix ratio
real(DP) :: z_ExtSigma(1-2:kmax+2)
! σ座標の拡張配列
! Extended array of the sigma coordinate
real(DP) :: xyf_F11(0:imax-1, 1:jmax, 1:ncmax)
! 微分計算時に用いる作業変数
! work variable for the derivative calculation
real(DP) :: xyf_F22(0:imax-1, 1:jmax, 1:ncmax)
! 微分計算時に用いる作業変数
! work variable for the derivative calculation
real(DP) :: xyf_F12(0:imax-1, 1:jmax, 1:ncmax)
! 微分計算時に用いる作業変数
! work variable for the derivative calculation
real(DP) :: xyf_F21(0:imax-1, 1:jmax, 1:ncmax)
! 微分計算時に用いる作業変数
! work variable for the derivative calculation
real(DP) :: s1, t1, s2, t2, r1, r2
! 微分計算時に用いる作業変数
! work variable for the derivative calculation
real(DP) :: xyzf_QMixLinLV (0:imax-1, 1:jmax, 1:kmax, 1:ncmax)
real(DP) :: xyzf_ExtQMixLinLV(0:imax-1, 1:jmax, 1-2:kmax+2, 1:ncmax)
! 実行文 ; Executable statement
!
! 初期化確認
! Initialization check
!
if ( .not. sltt_inited ) then
call MessageNotify( 'E', module_name, 'This module has not been initialized.' )
end if
if ( ( present( xyzf_QMixLin ) ) .and. ( .not. present( xyzf_QMixLinA ) ) ) then
call MessageNotify( 'E', module_name, &
& 'If xyzf_QMixLinA has to be present when xyzf_QMixLin ise present.' )
end if
if ( ( ( present( xyzf_QMixMinA ) ) .and. &
& ( .not. present( xyzf_QMixMaxA ) ) ) .or. &
& ( ( .not. present( xyzf_QMixMinA ) ) .and. &
& ( present( xyzf_QMixMaxA ) ) ) ) then
call MessageNotify( 'E', module_name, &
& 'QMixMinA has to be present when QMixMaxA is present, and vice versa.' )
end if
if ( present( xyzf_QMixLin ) ) then
xyzf_QMixLinLV = xyzf_QMixLin
else
xyzf_QMixLinLV = xyzf_QMix
end if
! 上流点探索
! estimation of departure point
!
call SLTTDPVer( &
& DelTime, xyr_SigmaDot, & ! (in )
& xyz_DPSigma & ! (out)
& )
! 配列拡張(z_Sigma)
! Array extension for z_Sigma
z_ExtSigma(-1) = 2.0_DP - z_Sigma(2)
z_ExtSigma(0) = 2.0_DP - z_Sigma(1)
z_ExtSigma(1:kmax) = z_Sigma(1:kmax)
z_ExtSigma(kmax+1) = -z_Sigma(kmax)
z_ExtSigma(kmax+2) = -z_Sigma(kmax-1)
! 配列拡張(xyzf_QMix)
! Array extension for Q_Mix
xyzf_ExtQMix(:,:,-1,:) = xyzf_QMix(:,:,2,:)
xyzf_ExtQMix(:,:,0,:) = xyzf_QMix(:,:,1,:)
xyzf_ExtQMix(:,:,1:kmax,:) = xyzf_QMix(:,:,1:kmax,:)
xyzf_ExtQMix(:,:,kmax+1,:) = xyzf_QMix(:,:,kmax,:)
xyzf_ExtQMix(:,:,kmax+2,:) = xyzf_QMix(:,:,kmax-1,:)
xyzf_ExtQMixLinLV(:,:,-1,:) = xyzf_QMixLinLV(:,:,2,:)
xyzf_ExtQMixLinLV(:,:,0,:) = xyzf_QMixLinLV(:,:,1,:)
xyzf_ExtQMixLinLV(:,:,1:kmax,:) = xyzf_QMixLinLV(:,:,1:kmax,:)
xyzf_ExtQMixLinLV(:,:,kmax+1,:) = xyzf_QMixLinLV(:,:,kmax,:)
xyzf_ExtQMixLinLV(:,:,kmax+2,:) = xyzf_QMixLinLV(:,:,kmax-1,:)
! xyzf_QMix_dz(微分)を求める
! calculate xyzf_QMix_dz
do k = 1 , kmax
s1 = z_ExtSigma(k) - z_ExtSigma(k-1)
t1 = z_ExtSigma(k+1) - z_ExtSigma(k)
s2 = z_ExtSigma(k) - z_ExtSigma(k-2)
t2 = z_ExtSigma(k+2) - z_ExtSigma(k)
if (s1 == t1 .and. s2 == t2 .and. s1 + s1 == s2) then
! 格子が等間隔の場合
! Uniform depth
! 4次精度
! 4th order
xyzf_QMix_dz(:,:,k,:) = ( 8.0_DP*( xyzf_ExtQMix(:,:,k+1,:) - xyzf_ExtQMix(:,:,k-1,:)) &
& - ( xyzf_ExtQMix(:,:,k+2,:) - xyzf_ExtQMix(:,:,k-2,:) ) )/12.0_DP
else
! 格子が不当間隔の場合
! Non-uniform depth
xyf_F11 = (s1*s1*xyzf_ExtQMix(:,:,k+1,:) +(t1*t1 - s1*s1)*xyzf_ExtQMix(:,:,k,:) - t1*t1*xyzf_ExtQMix(:,:,k-1,:))&
& /(s1*t1*(s1+t1))
xyf_F22 = (s2*s2*xyzf_ExtQMix(:,:,k+2,:) +(t2*t2 - s2*s2)*xyzf_ExtQMix(:,:,k,:) - t2*t2*xyzf_ExtQMix(:,:,k-2,:))&
& /(s2*t2*(s2+t2))
xyf_F21 = (s2*s2*xyzf_ExtQMix(:,:,k+1,:) +(t1*t1 - s2*s2)*xyzf_ExtQMix(:,:,k,:) - t1*t1*xyzf_ExtQMix(:,:,k-2,:))&
& /(s2*t1*(s2+t1))
xyf_F12 = (s1*s1*xyzf_ExtQMix(:,:,k+2,:) +(t2*t2 - s1*s1)*xyzf_ExtQMix(:,:,k,:) - t2*t2*xyzf_ExtQMix(:,:,k-1,:))&
& /(s1*t2*(s1+t2))
r1 = t1 - s1 - t2 + s2
r2 = t1 - s2 - t2 + s1
!4次精度
! 4th order
xyzf_QMix_dz(:,:,k,:) = ( (xyf_F11*s2*t2 - xyf_F22*s1*t1)*r2 - (xyf_F21*s1*t2 - xyf_F12*s2*t1)*r1 ) &
& / ( (s2*t2-s1*t1)*r2 - (s1*t2-s2*t1)*r1 )
!3次精度
! 3rd order
! xyzf_QMix_dz(:,:,k,:) = (xyf_F11*s2*t2 - xyf_F22(:,:,:)*s1*t1)/(s2*t2 - s1*t1)
!2次精度
! 2nd order
! xyzf_QMix_dz(:,:,k,:) = xyf_F11
end if
end do
xy_kk = 2
do k = 1, kmax
do j = 1, jmax
do i = 0, imax-1
if ( xyz_DPSigma(i,j,k) >= z_Sigma(1) ) then ! DPが z_Sigma(1) と 地表面(sigma = 1.0)の間の場合
! if DP is between z_Sigma(1) and the ground (sigma = 1.0)
xyzf_QMixA(i,j,k,:) = xyzf_QMix(i,j,1,:) ! Q_1で一定とする。
! use Q_1 for interpolated value
if ( present( xyzf_QMixLinA ) ) then
xyzf_QMixLinA(i,j,k,:) = xyzf_QMixLinLV(i,j,1,:)
end if
if ( present( xyzf_QMixMinA ) ) then
xyzf_QMixMinA(i,j,k,:) = xyzf_QMix(i,j,1,:)
xyzf_QMixMaxA(i,j,k,:) = xyzf_QMix(i,j,1,:)
end if
elseif (xyz_DPSigma(i,j,k) <= z_Sigma(kmax)) then! DPが z_Sigma(kmax) と 大気上端(sigma = 0.0)の間
! if DP is between z_Sigma(kmax) and the upper boundary (sigma = 0.0)
xyzf_QMixA(i,j,k,:) = xyzf_QMix(i,j,kmax,:) ! Q_kmaxで一定とする。
! use Q_kmax for interpolated value
if ( present( xyzf_QMixLinA ) ) then
xyzf_QMixLinA(i,j,k,:) = xyzf_QMixLinLV(i,j,kmax,:)
end if
if ( present( xyzf_QMixMinA ) ) then
xyzf_QMixMinA(i,j,k,:) = xyzf_QMix(i,j,kmax,:)
xyzf_QMixMaxA(i,j,k,:) = xyzf_QMix(i,j,kmax,:)
end if
else
do kk = xy_kk(i,j), kmax
if ( xyz_DPSigma(i,j,k) > z_Sigma(kk) ) then
select case (SLTTIntVer)
case("HQ") ! 変則エルミート5次補間; Irregular Hermite Quintic interpolation
do n = 1, ncmax
xyzf_QMixA(i,j,k,n) = SLTTIrrHerIntQui1DNonUni(xyzf_ExtQMix(i,j,kk-2,n), xyzf_ExtQMix(i,j,kk-1,n), &
& xyzf_ExtQMix(i,j,kk,n), xyzf_ExtQMix(i,j,kk+1,n), &
& xyzf_QMix_dz(i,j,kk-1,n), xyzf_QMix_dz(i,j,kk,n), &
& z_ExtSigma(kk-2)-z_ExtSigma(kk-1), z_ExtSigma(kk)-z_ExtSigma(kk-1), &
& z_ExtSigma(kk+1)-z_ExtSigma(kk-1), xyz_DPSigma(i,j,k)-z_ExtSigma(kk-1))
end do
case("HC") ! エルミート3次補間; Hermitian Cubic interpolation
do n = 1, ncmax
xyzf_QMixA(i,j,k,n) = SLTTHerIntCub1D( xyzf_ExtQMix(i,j,kk-1,n), xyzf_ExtQMix(i,j,kk,n),&
& xyzf_QMix_dz(i,j,kk-1,n), xyzf_QMix_dz(i,j,kk,n),&
& z_ExtSigma(kk)-z_ExtSigma(kk-1), &
& xyz_DPSigma(i,j,k)-z_ExtSigma(kk-1))
end do
case default
call MessageNotify( 'E', module_name, 'GIVE CORRECT KEYWORD FOR IN NAMELIST.' )
end select
if ( present( xyzf_QMixLinA ) ) then
! Linear interporation
do n = 1, ncmax
xyzf_QMixLinA(i,j,k,n) = &
& ( xyzf_ExtQMixLinLV(i,j,kk,n) - xyzf_ExtQMixLinLV(i,j,kk-1,n) ) &
& / ( z_ExtSigma(kk) - z_ExtSigma(kk-1) ) &
& * ( xyz_DPSigma(i,j,k) - z_ExtSigma(kk-1) ) &
& + xyzf_ExtQMixLinLV(i,j,kk-1,n)
end do
end if
if ( present( xyzf_QMixMinA ) ) then
do n = 1, ncmax
xyzf_QMixMinA(i,j,k,n) = &
& min( xyzf_QMix(i,j,kk-1,n), &
& xyzf_QMix(i,j,kk,n) )
xyzf_QMixMaxA(i,j,k,n) = &
& max( xyzf_QMix(i,j,kk-1,n), &
& xyzf_QMix(i,j,kk,n) )
end do
end if
xy_kk(i,j) = kk
exit
end if
end do
end if
end do
end do
end do
end function SLTTVerAdv
!-------------------------------------------------
subroutine SLTTInit
! セミラグランジュ法の初期化処理
! Initialization for Semi-Lagrangian method
! ヒストリデータ出力
! History data output
!
use gtool_historyauto, only: HistoryAutoAddVariable
! 組成に関わる配列の設定
! Settings of array for atmospheric composition
!
use composition, only: &
& ncmax, &
! 成分の数
! Number of composition
& a_QMixName
! 成分の変数名
! Name of variables for composition
! 座標データ設定
! Axes data settings
!
use axesset, only: &
& r_Sigma, &
! $ \sigma $ レベル (半整数).
! Half $ \sigma $ level
& z_Sigma, & ! $ \sigma $ レベル (整数).
! Full $ \sigma $ level
& x_Lon, y_Lat, &
& AxNameX, AxNameY, AxNameZ, AxNameT
use sltt_const , only : SLTTConstInit
use sltt_extarr, only : SLTTExtArrInit
! NAMELIST ファイル入力に関するユーティリティ
! Utilities for NAMELIST file input
!
use namelist_util, only: namelist_filename, NmlutilMsg
! 種別型パラメタ
! Kind type parameter
!
use dc_types, only: &
& STDOUT, & ! 標準出力の装置番号. Unit number of standard output
& STRING ! 文字列. Strings.
! ファイル入出力補助
! File I/O support
!
use dc_iounit, only: FileOpen
use sltt_const , only : iexmin, iexmax, jexmin, jexmax
!
! local variables
!
integer:: i ! 東西方向に回る DO ループ用作業変数
! Work variables for DO loop in zonal direction
integer:: j ! 南北方向に回る DO ループ用作業変数
! Work variables for DO loop in meridional direction
integer:: k ! 鉛直方向に回る DO ループ用作業変数
! Work variables for DO loop in vertical direction
integer:: n
integer:: unit_nml ! NAMELIST ファイルオープン用装置番号.
! Unit number for NAMELIST file open
integer:: iostat_nml ! NAMELIST 読み込み時の IOSTAT.
! IOSTAT of NAMELIST read
! NAMELIST 変数群
! NAMELIST group name
!
namelist /sltt_nml/ &
& FlagSLTTArcsineHor, FlagSLTTArcsineVer, SLTTIntHor, SLTTIntVer, SLTTArcSineFactor
! 実行文 ; Executable statement
!
if ( sltt_inited ) return
if ( mod( jmax, 2 ) /= 0 ) then
stop 'jmax cannot be divided by 2.'
end if
call SLTTConstInit
! デフォルト値の設定
! Default values settings
!
FlagSLTTArcsineHor = .true.
FlagSLTTArcsineVer = .true.
SLTTArcSineFactor = 1.05_DP
SLTTIntHor = "HQ"
SLTTIntVer = "HQ"
! NAMELIST の読み込み
! NAMELIST is input
!
if ( trim(namelist_filename) /= '' ) then
call FileOpen( unit_nml, & ! (out)
& namelist_filename, mode = 'r' ) ! (in)
rewind( unit_nml )
read( unit_nml, & ! (in)
& nml = sltt_nml, & ! (out)
& iostat = iostat_nml ) ! (out)
close( unit_nml )
call NmlutilMsg( iostat_nml, module_name ) ! (in)
if ( iostat_nml == 0 ) write( STDOUT, nml = sltt_nml )
end if
allocate( x_LonS (0:imax-1) )
allocate( x_SinLonS(0:imax-1) )
allocate( x_CosLonS(0:imax-1) )
allocate( y_latS (1:jmax/2) )
allocate( y_SinLatS(1:jmax/2) )
allocate( y_CosLatS(1:jmax/2) )
do i = 0, imax-1
x_LonS (i) = x_Lon(i)
x_SinLonS(i) = sin( x_LonS(i) )
x_CosLonS(i) = cos( x_LonS(i) )
end do
do j = 1, jmax/2
y_LatS (j) = y_Lat(j)
y_SinLatS(j) = sin( y_LatS(j) )
y_CosLatS(j) = cos( y_LatS(j) )
end do
allocate( x_LonN (0:imax-1) )
allocate( x_SinLonN(0:imax-1) )
allocate( x_CosLonN(0:imax-1) )
allocate( y_latN (1:jmax/2) )
allocate( y_SinLatN(1:jmax/2) )
allocate( y_CosLatN(1:jmax/2) )
do i = 0, imax-1
x_LonN (i) = x_Lon(i)
x_SinLonN(i) = sin( x_LonN(i) )
x_CosLonN(i) = cos( x_LonN(i) )
end do
do j = 1, jmax/2
y_LatN (j) = y_Lat(j+jmax/2)
y_SinLatN(j) = sin( y_LatN(j) )
y_CosLatN(j) = cos( y_LatN(j) )
end do
allocate( x_ExtLonS( iexmin:iexmax ) )
allocate( x_ExtLonN( iexmin:iexmax ) )
allocate( y_ExtLatS( jexmin:jexmax ) )
allocate( y_ExtLatN( jexmin:jexmax ) )
call SLTTExtArrInit( &
& x_LonS, y_LatS, x_LonN, y_LatN, & ! (in )
& x_ExtLonS, y_ExtLatS, x_ExtLonN, y_ExtLatN & ! (out)
& )
! ヒストリデータ出力のためのへの変数登録
! Register of variables for history data output
!
do n = 1, ncmax
call HistoryAutoAddVariable( 'SLD'//trim(a_QMixName(n))//'DtHorMassFix', &
& (/ AxNameX, AxNameY, AxNameZ, AxNameT /), &
& 'tendency of horizontal mass fix of '//trim(a_QMixName(n)), 's-1' )
call HistoryAutoAddVariable( 'SLD'//trim(a_QMixName(n))//'DtVerMassFix', &
& (/ AxNameX, AxNameY, AxNameZ, AxNameT /), &
& 'tendency of vertical mass fix of '//trim(a_QMixName(n)), 's-1' )
call HistoryAutoAddVariable( 'SLD'//trim(a_QMixName(n))//'DtTotMassFix', &
& (/ AxNameX, AxNameY, AxNameZ, AxNameT /), &
& 'tendency of mass fix of '//trim(a_QMixName(n)), 's-1' )
end do
! 印字 ; Print
!
call MessageNotify( 'M', module_name, '----- Initialization Messages -----' )
call MessageNotify( 'M', module_name, ' FlagSLTTArcsineHor = %b', l = (/ FlagSLTTArcsineHor /) )
call MessageNotify( 'M', module_name, ' FlagSLTTArcsineVer = %b', l = (/ FlagSLTTArcsineVer /) )
call MessageNotify( 'M', module_name, ' SLTTArcsineFactor = %f', d = (/ SLTTArcsineFactor /) )
call MessageNotify( 'M', module_name, ' SLTTIntHor = %c', c1 = trim( SLTTIntHor ) )
call MessageNotify( 'M', module_name, ' SLTTIntVer = %c', c1 = trim( SLTTIntVer ) )
call MessageNotify( 'M', module_name, '-- version = %c', c1 = trim(version) )
sltt_inited = .true.
end subroutine SLTTInit
!--------------------------------------------------------------------------------------
end module sltt