!--------------------------------------------------------------------- ! Copyright (C) GFD Dennou Club, 2006. All rights reserved. !--------------------------------------------------------------------- ! != 1 次元 (z 方向) 等間隔交互格子 有限差分モデル用 基本モジュール ! !* 履歴 ! * 2007/07/15 (小高正嗣) : 3D deepconv へ移植, dc_types を Use. ! * 2006/12/26 (小高正嗣) : r_Z を復活, z_r, r_z の名前を元に戻す ! * 2006/06/17 (小高正嗣) : IntZ_*, AvrZ_* を追加 ! * 2006/06/02 (小高正嗣) : x_base_module より作成 ! module z_base_module != 1 次元 (z 方向) 等間隔交互格子 有限差分モデル用 基本モジュール ! !== 概要 ! ! z_base_module は, 1 次元 (z 方向) 等間隔交互格子を用いた有限差分 ! 法に基づく数値モデルのための基本的な Fortran90 副プログラムおよび ! 関数を提供する. このモジュールは z_module の下位モジュールである. ! !== 備考 ! ! * 例外処理がない ! * その場合のメッセージ表示がない ! * 初期化の値はマシンイプシロン値としておくべき use dc_types, only : DBKIND => DP implicit none private public :: km, zmargin, kmin, kmax, z_Z, r_Z, z_dz, r_dz public :: z_axis_init, z_avr_r, r_avr_z, IntZ_r, IntZ_z, AvrZ_r, AvrZ_z integer :: km = 10 ! 格子点数 integer :: zmargin = 2 ! 糊代格子点数 integer :: kmin ! 配列添字の下限 integer :: kmax ! 配列添字の上限 real(DBKIND),allocatable :: z_Z(:) ! 半整数格子座標 real(DBKIND),allocatable :: r_Z(:) ! 整数格子座標 real(DBKIND),allocatable :: z_dz(:) ! 半整数格子座標 real(DBKIND),allocatable :: r_dz(:) ! 整数格子座標 save km, zmargin, kmin, kmax, z_Z, r_Z, z_dz, r_dz contains !-------------------------------------------------------------------- subroutine z_axis_init(k, zmg, zmin, zmax) ! z 方向の座標値と格子点間隔を設定する integer,intent(in) :: k ! z 方向格子点数 integer,intent(in) :: zmg ! z 方向糊代格子点数 real(DBKIND),intent(in) :: zmin ! z 座標最小値 real(DBKIND),intent(in) :: zmax ! z 座標最大値 integer :: kz ! ループ添字 real(DBKIND) :: dz km = k zmargin = zmg kmin = 1 - zmargin kmax = km + zmargin allocate(z_Z(kmin:kmax)) allocate(r_Z(kmin:kmax)) allocate(z_dz(kmin:kmax)) allocate(r_dz(kmin:kmax)) dz = (zmax - zmin)/km do kz = kmin, kmax r_Z(kz) = dz * kz z_Z(kz) = dz * (kz - 0.5) r_dz(kz) = dz z_dz(kz) = dz end do end subroutine z_axis_init !-------------------------------------------------------------------- function z_avr_r(r_Var) ! 平均操作を行い整数格子点の配列値を半整数格子点上へ返す real(DBKIND),intent(in) :: r_Var(kmin:kmax) ! 入力 real(DBKIND) :: z_avr_r(kmin:kmax) ! 出力 integer :: kz ! ループ添字 ! 初期化 ! * 0 割りを防ぐためにはマシンイプシロン値を用いるべき ! z_avr_r = 0.0d0 ! 平均操作 ! * 平均がとれない kmin 格子上の値は計算しない. ! do kz = kmin+1, kmax z_avr_r(kz) = (r_Var(kz) + r_Var(kz-1))*0.5d0 end do ! kmin 格子の値 z_avr_r(kmin) = z_avr_r(kmin+1) end function z_avr_r !-------------------------------------------------------------------- function r_avr_z(z_Var) ! 平均操作を行い半整数格子点の配列値を整数格子点上へ返す real(DBKIND),intent(in) :: z_Var(kmin:kmax) ! 入力 real(DBKIND) :: r_avr_z(kmin:kmax) ! 出力 integer :: kz ! ループ添字 ! 初期化 ! * 0 割りを防ぐためにはマシンイプシロン値を用いるべき ! r_avr_z = 0.0d0 ! 平均操作 ! * 平均がとれない kmax 格子上の値は計算しない. ! * 不等間隔格子なので重みをつけて平均する. ! 点 P, Q を a:b に内分する点の X の値は, a*X(Q) + b*X(P) ! (a+b=1 を仮定) であることから, ! ! r_Var(kz) = [0.5*z_dz(kz) /r_dz(kz)]*z_Var(kz+1) + ! [0.5*z_dz(kz+1)/r_dz(kz)]*z_Var(kz) ! ! 変形すると ! ! r_Var(kz) = [z_dz(kz)*z_Var(kz+1) + z_dz(kz+1)*z_Var(kz)] ! *0.5/r_dz(kz) ! do kz = kmin, kmax-1 r_avr_z(kz) = & & (z_dz(kz)*z_Var(kz+1) + z_dz(kz+1)*z_Var(kz))*0.5d0/r_dz(kz) end do ! kmax 格子の値 r_avr_z(kmax) = r_avr_z(kmax-1) end function r_avr_z !-------------------------------------------------------------------- function IntZ_r(r_Var) ! 整数格子上の配列に対し z 方向に重み付きの積分を行う real(DBKIND), intent(in) :: r_Var(kmin:kmax) ! 入力 real(DBKIND) :: IntZ_r ! 出力 ! 初期化 IntZ_r = 0.0d0 ! 積分 IntZ_r = sum(r_Var(1:km)*r_dz(1:km)) end function IntZ_r !-------------------------------------------------------------------- function IntZ_z(z_Var) ! 半整数格子上の配列に対し z 方向に重み付きの積分を行う real(DBKIND), intent(in) :: z_Var(kmin:kmax) ! 入力 real(DBKIND) :: IntZ_z ! 出力 ! 初期化 IntZ_z = 0.0d0 ! 積分 IntZ_z = sum(z_Var(1:km)*z_dz(1:km)) end function IntZ_z !-------------------------------------------------------------------- function AvrZ_r(r_Var) ! 整数格子上の配列に対し z 方向の平均操作を行う real(DBKIND), intent(in) :: r_Var(kmin:kmax) ! 入力 real(DBKIND) :: AvrZ_r ! 出力 AvrZ_r = IntZ_r(r_Var)/sum(r_dz(1:km)) end function AvrZ_r !-------------------------------------------------------------------- function AvrZ_z(z_Var) ! 半整数格子上の配列に対し z 方向の平均操作を行う real(DBKIND), intent(in) :: z_Var(kmin:kmax) ! 入力 real(DBKIND) :: AvrZ_z ! 出力 AvrZ_z = IntZ_z(z_Var)/sum(z_dz(1:km)) end function AvrZ_z !-------------------------------------------------------------------- end module z_base_module