Path: | env/basicenv.f90 |
Last Update: | Mon Nov 27 11:18:45 JST 2006 |
Authors: | SUGIYAMA Koichiro, ODAKA Masatsugu |
Version: | $Id: basicenv.f90,v 1.22 2006/11/27 02:18:45 sugiyama Exp $ |
Tag Name: | $Name: arare4-20061224 $ |
Copyright: | Copyright (C) GFD Dennou Club, 2006. All rights reserved. |
License: | See COPYRIGHT |
デフォルトの基本場を設定するための変数参照型モジュール
* BasicEnvFile_init: 基本場の値を netCDF ファイルから取得 * BasicEnvCalc_Init: 基本場の情報を Namelist から取得して値を計算
Subroutine : |
デフォルトの基本場を設定するためのサブルーチン. 基本場を計算し, BasicSet モジュールの値を初期化する.
コンパイルの順序の問題から, 基本場の値(hogeBasicZ な変数)を 計算する部分をBasicSet モジュールから切り離している. ECCM 始め, BasicSet 自体に依存するが hogeBasicZ は use しない 外部サブルーチンを利用するためである.
subroutine BasicEnv() ! !デフォルトの基本場を設定するためのサブルーチン. !基本場を計算し, BasicSet モジュールの値を初期化する. ! !コンパイルの順序の問題から, 基本場の値(hogeBasicZ な変数)を !計算する部分をBasicSet モジュールから切り離している. !ECCM 始め, BasicSet 自体に依存するが hogeBasicZ は use しない !外部サブルーチンを利用するためである. ! !モジュール読み込み use dc_message, only: MessageNotify use gridset, only: DimXMin, DimXMax, DimZMin, RegZMin, DimZMax, SpcNum, s_Z, DelZ !Z 方向の格子点間隔 use basicset, only: BasicSetArray_Init, PressBasis, GasRDry, CpDry, CvDry, MolWtDry, Grav, SpcWetMolFr, MolWtWet, EnvType, Tropopause, GasRUniv, Humidity, TempStrat, Dhight !重み関数のパラメータ [m] use Boundary, only: xz_BoundaryXCyc_xz, xz_BoundaryZSym_xz, xza_BoundaryXCyc_xza, xza_BoundaryZSym_xza ! use ECCM, only: ECCM_Dry, ECCM_MolFr !暗黙の型宣言禁止 implicit none !変数の定義 real(8) :: xz_DensBasicZ(DimXMin:DimXMax, DimZMin:DimZMax) real(8) :: xz_PressBasicZ(DimXMin:DimXMax, DimZMin:DimZMax) real(8) :: xz_ExnerBasicZ(DimXMin:DimXMax, DimZMin:DimZMax) real(8) :: xz_TempBasicZ(DimXMin:DimXMax, DimZMin:DimZMax) real(8) :: xz_PotTempBasicZ(DimXMin:DimXMax, DimZMin:DimZMax) real(8) :: xz_VelSoundBasicZ(DimXMin:DimXMax, DimZMin:DimZMax) real(8) :: xza_MixRtBasicZ(DimXMin:DimXMax, DimZMin:DimZMax, SpcNum) real(8) :: xz_EffMolWtBasicZ(DimXMin:DimXMax, DimZMin:DimZMax) real(8) :: z_TempBasicZ(DimZMin:DimZMax) real(8) :: z_PressBasicZ(DimZMin:DimZMax) real(8) :: MolFrIni(SpcNum) real(8) :: xza_MolFr(DimXMin:DimXMax, DimZMin:DimZMax, SpcNum) real(8) :: za_MolFr(DimZMin:DimZMax, SpcNum) real(8) :: xza_MixRtDivMolWt(DimXMin:DimXMax, DimZMin:DimZMax, SpcNum) real(8) :: z_DTempDZ(DimZMin:DimZMax) real(8) :: z_MolWtMean(DimZMin:DimZMax) real(8) :: DTempDZ real(8) :: Weight integer :: i, k, s real(8),allocatable :: z_TempBasicZ_Dry (:) real(8),allocatable :: z_PressBasicZ_Dry(:) real(8),allocatable :: z_TempBasicZ_Moist (:) real(8),allocatable :: z_PressBasicZ_Moist(:) !--------------------------------------------------------------- ! 配列の初期化 !--------------------------------------------------------------- allocate( z_TempBasicZ_Dry (DimZMin:DimZMax) ) allocate( z_PressBasicZ_Dry (DimZMin:DimZMax) ) allocate( z_TempBasicZ_Moist (DimZMin:DimZMax) ) allocate( z_PressBasicZ_Moist(DimZMin:DimZMax) ) xz_DensBasicZ = 0.0d0 xz_PressBasicZ = 0.0d0 xz_ExnerBasicZ = 0.0d0 xz_TempBasicZ = 0.0d0 xz_PotTempBasicZ = 0.0d0 xz_VelSoundBasicZ = 0.0d0 xza_MixRtBasicZ = 0.0d0 xz_EffMolWtBasicZ = 0.0d0 z_TempBasicZ = 0.0d0 z_PressBasicZ = 0.0d0 za_MolFr = 0.0d0 !--------------------------------------------------------------- ! EnvType を元に, 温度, 圧力, 組成を決める !--------------------------------------------------------------- ! if (trim(EnvType) == 'Dry') then ! MolFrIni = 0.0d0 ! elseif (trim(EnvType) == 'Moist') then ! MolFrIni = SpcWetMolFr(1:SpcNum) ! end if ! 対流圏界面までは熱平衡状態として与える ! call ECCM_Temp_Press( MolFrIni, z_TempBasicZ, z_PressBasicZ ) MolFrIni = SpcWetMolFr(1:SpcNum) call ECCM_Dry( MolFrIni, Humidity, z_TempBasicZ, z_PressBasicZ, z_MolWtMean, za_MolFr ) do k = RegZMin+1, DimZMax-1 z_DTempDZ(k) = (z_TempBasicZ(k) - z_TempBasicZ(k-1)) / DelZ end do ! ! 乾燥断熱 ! MolFrIni = 0.0d0 ! call ECCM_Temp_Press( MolFrIni, z_TempBasicZ_Dry, z_PressBasicZ_Dry ) ! ! 湿潤断熱 ! MolFrIni = SpcWetMolFr(1:SpcNum) ! call ECCM_Temp_Press( MolFrIni, z_TempBasicZ_Moist, z_PressBasicZ_Moist) ! ! EnvType による条件分岐 ! ! ! ! * Dry : 乾燥断熱 ! ! * Moist: 湿潤断熱 ! ! * CI : 条件付き不安定 ! ! ! if (trim(EnvType) == 'Dry') then ! z_TempBasicZ = z_TempBasicZ_Dry ! z_PressBasicZ = z_PressBasicZ_Dry ! elseif (trim(EnvType) == 'Moist') then ! z_TempBasicZ = z_TempBasicZ_Moist ! z_PressBasicZ = z_PressBasicZ_Moist ! elseif (trim(EnvType) == 'CI') then ! z_TempBasicZ = (z_TempBasicZ_Dry + z_TempBasicZ_Moist )/2.0d0 ! z_PressBasicZ = (z_PressBasicZ_Moist + z_PressBasicZ_Moist)/2.0d0 ! end if do k = RegZMin+1, DimZMax-1 z_DTempDZ(k) = (z_TempBasicZ(k) - z_TempBasicZ(k-1)) / DelZ end do ! 対流圏界面より上の扱い ! 圏界面より上は等温大気とする. 等温位大気から等温大気への遷移は ! tanh を用いてなめらかにつなぐ do k = RegZMin+1, DimZMax !重みつけの関数を用意. tanh を用いる Weight = ( tanh( (s_Z(k) - tropopause ) / Dhight ) + 1.0d0 ) * 5.0d-1 !仮値として温度を計算する. 圏界面より上では TempStrat の等温大気に近づける z_TempBasicZ(k) = z_TempBasicZ(k) * ( 1.0d0 - Weight ) + TempStrat * Weight !温度減率が断熱温度減率より小さくならないように DTempDZ = max( z_DTempDZ(k), (z_TempBasicZ(k) - z_TempBasicZ(k-1)) / DelZ ) !基本場の温度を決める z_TempBasicZ(k) = z_TempBasicZ(k-1) + DTempDZ * DelZ !圧力を静水圧平衡から計算 z_PressBasicZ(k) = z_PressBasicZ(k-1) * ( ( z_TempBasicZ(k-1) / z_TempBasicZ(k) ) ** (Grav * z_MolWtMean(k) / ( DTempDZ * GasRUniv ) ) ) end do !確認のため出力 call MessageNotify( "M", "BasicEnv", "Basic State Atmospheric Profiles." ) do k = RegZMin+1, DimZMax-1 write(*,*) "temp", k, s_Z(k), z_TempBasicZ(k), z_PressBasicZ(k) end do ! 2 次元配列に格納 do i = DimXMin, DimXMax xz_TempBasicZ(i,:) = z_TempBasicZ xz_PressBasicZ(i,:) = z_PressBasicZ end do !境界条件 xz_TempBasicZ = xz_BoundaryXCyc_xz( xz_TempBasicZ ) xz_TempBasicZ = xz_BoundaryZSym_xz( xz_TempBasicZ ) xz_PressBasicZ = xz_BoundaryXCyc_xz( xz_PressBasicZ ) xz_PressBasicZ = xz_BoundaryZSym_xz( xz_PressBasicZ ) !--------------------------------------------------------------- ! 混合比 !--------------------------------------------------------------- !鉛直方向の物質分布(モル比)を決める ! 混合比ではなくモル比を決めるのは歴史的事情. ! call ECCM_MolFr( SpcWetMolFr(1:SpcNum), Humidity, z_TempBasicZ, & ! & z_PressBasicZ, za_MolFr ) !水平方向には一様 do i = DimXMin, DimXMax xza_MolFr(i,:,:) = za_MolFr end do !気相のモル比を混合比に変換 do s = 1, SpcNum xza_MixRtBasicZ(:,:,s) = xza_MolFr(:,:,s) * MolWtWet(s) / MolWtDry end do ! !値が小さくなりすぎないように最低値を与える ! where (xza_MixRtBasicZ <= 1.0d-20 ) ! xza_MixRtBasicZ = 1.0d-20 ! end where !境界条件 xza_MixRtBasicZ = xza_BoundaryXCyc_xza( xza_MixRtBasicZ ) xza_MixRtBasicZ = xza_BoundaryZSym_xza( xza_MixRtBasicZ ) !--------------------------------------------------------------- ! 分子量の効果 !--------------------------------------------------------------- do s = 1, SpcNum xza_MixRtDivMolWt(:,:,s) = xza_MixRtBasicZ(:,:,s) / MolWtWet(s) end do xz_EffMolWtBasicZ = (1.0d0 + sum(xza_MixRtBasicZ,3) ) / ( MolWtDry * ((1.0d0 / MolWtDry) + sum(xza_MixRtDivMolWt,3)) ) ! do i = DimXMin, DimXMax ! xz_EffMolWtBasicZ(i,:) = z_MolWtMean / MolWtDry ! end do !境界条件 xz_EffMolWtBasicZ = xz_BoundaryXCyc_xz( xz_EffMolWtBasicZ ) xz_EffMolWtBasicZ = xz_BoundaryZSym_xz( xz_EffMolWtBasicZ ) !--------------------------------------------------------------- ! 温位 !--------------------------------------------------------------- xz_PotTempBasicZ = xz_TempBasicZ * (PressBasis / xz_PressBasicZ) ** (GasRDry / CpDry) !境界条件 xz_PotTempBasicZ = xz_BoundaryXCyc_xz( xz_PotTempBasicZ ) xz_PotTempBasicZ = xz_BoundaryZSym_xz( xz_PotTempBasicZ ) !--------------------------------------------------------------- ! エクスナー関数 !--------------------------------------------------------------- xz_ExnerBasicZ = xz_TempBasicZ / xz_PotTempBasicZ !境界条件 xz_ExnerBasicZ = xz_BoundaryXCyc_xz( xz_ExnerBasicZ ) xz_ExnerBasicZ = xz_BoundaryZSym_xz( xz_ExnerBasicZ ) !--------------------------------------------------------------- ! 密度 !--------------------------------------------------------------- xz_DensBasicZ = PressBasis * (xz_ExnerBasicZ ** (CvDry / GasRDry)) / (GasRDry * xz_PotTempBasicZ / xz_EffMolWtBasicZ) !境界条件 xz_DensBasicZ = xz_BoundaryXCyc_xz( xz_DensBasicZ ) xz_DensBasicZ = xz_BoundaryZSym_xz( xz_DensBasicZ ) !--------------------------------------------------------------- ! 音速 !--------------------------------------------------------------- xz_VelSoundBasicZ = sqrt ( CpDry * GasRDry * xz_ExnerBasicZ * xz_PotTempBasicZ / (CvDry * xz_EffMolWtBasicZ) ) !境界条件 xz_VelSoundBasicZ = xz_BoundaryXCyc_xz( xz_VelSoundBasicZ ) xz_VelSoundBasicZ = xz_BoundaryZSym_xz( xz_VelSoundBasicZ ) !---------------------------------------------------------- ! BasicSet モジュールに値を設定 !---------------------------------------------------------- call BasicSetArray_Init( xz_PressBasicZ, xz_ExnerBasicZ, xz_TempBasicZ, xz_PotTempBasicZ, xz_DensBasicZ, xz_VelSoundBasicZ, xza_MixRtBasicZ, xz_EffMolWtBasicZ ) end subroutine BasicEnv