!c Description: 
!c   座標軸設定用モジュール
!c
!c Current Code Owner: 
!c   sugiyama@gfd-dennou.org
!c
!c Copyright (C) SUGIYAMA Ko-ichiro, 2004, All rights reserved

module gridset
  !--- 暗黙の型宣言禁止
  implicit none

  !--- save 属性
  save

  !--- 変数定義
  real(8)               :: Xmin, Xmax    ! x 座標の始点・終点
  real(8)               :: Zmin, Zmax    ! z 座標の始点・終点
  real(8)               :: DelX, DelZ    !格子間隔
  integer               :: NX, NZ        !格子点数
  integer               :: DimXMin       ! x 方向の配列の下限
  integer               :: DimXMax       ! x 方向の配列の上限
  integer               :: DimZMin       ! z 方向の配列の下限
  integer               :: DimZMax       ! z 方向の配列の上限
  integer               :: RegXMin       ! x 方向の物理領域の下限
  integer               :: RegXMax       ! x 方向の物理領域の上限
  integer               :: RegZMin       ! z 方向の物理領域の下限
  integer               :: RegZMax       ! z 方向の物理領域の上限
  integer, parameter    :: Margin = 5    !境界のグリッド数
  integer, parameter    :: kind = 8      !精度を表す
  real(8), allocatable  :: s_X(:)
  real(8), allocatable  :: f_X(:)
  real(8), allocatable  :: s_Z(:)
  real(8), allocatable  :: f_Z(:)
  character(3)          :: ss_Bc        !境界(スカラー量)
  character(3)          :: fs_Bc        !境界(ベクトル u)
  character(3)          :: sf_Bc        !境界(ベクトル w)
  
contains
  subroutine gridset_init
    !--- モジュール読み込み
    use fileset, only: cfgfile
    
    !--- 内部変数の定義
    integer            :: i, k
    character(1)       :: BcX
    character(1)       :: BcZ
    
    !--- NAMELIST の定義
    NAMELIST /gridset/ &
         & NX, NZ, Xmin, Xmax, Zmin, Zmax, BcX, BcZ
    
    !---変数の取り出し
    open (10, FILE=cfgfile)
    read(10, NML=gridset)
    close(10)

    !--- 格子点間隔計算
    DelX = (Xmax - Xmin) / real(NX, kind)
    DelZ = (Zmax - Zmin) / real(NZ, kind)
    
    !--- 物理的に意味のある領域の上限・下限を決める
    RegXMin = 0
    RegXMax = NX
    RegZMin = 0
    RegZMax = NZ

    !--- 配列の上限・下限を決める
    DimXMin = RegXMin - Margin
    DimXMax = RegXMax + Margin
    DimZMin = RegZMin - Margin
    DimZMax = RegZMax + Margin

    !--- グリッドの設定
    allocate( f_X(DimXMin:DimXMax), f_Z(DimZMin:DimZMax) )
    do i = DimXMin, DimXMax
       f_X(i) = Xmin + DelX * ( real(i, kind) - RegXMin )
    end do
    do k = DimZMin, DimZMax
       f_Z(k) = Zmin + DelZ * ( real(k, kind) - RegZMin )
    end do
    
    !--- 半格子ずれたグリッドの設定. 等間隔を前提にしている.
    allocate( s_X(DimXMin: DimXMax), s_Z(DimZMin: DimZMax) )
    s_X(DimXMin+1:DimXMax) =            &
         &  (                     &
         &     f_X(DimXMin+1:DimXMax)     &
         &   + f_X(DimXMin:DimXMax-1)     &
         &  ) * 5.0d-1
    s_X(DimXMin) = s_X(DimXMin+1) - DelX
    
    s_Z(DimZMin+1:DimZMax) =             &
         &  (                     &
         &     f_Z(DimZMin+1:DimZMax)     &
         &   + f_Z(DimZMin:DimZMax-1)     &
         &  ) * 5.0d-1
    s_Z(DimZMin) = s_Z(DimZMin+1) - DelZ
    
    !--- 境界のタイプを指定 (boundary.f90 参照)
    if (trim(BcX) == "C" .AND. trim(BcZ) == "R") then        
       ss_Bc = "CsS"   
       fs_Bc = "CsA"
       sf_Bc = "CfA"
    else 
       write(*,*) "gridset.f90, unknown boundary condition" 
    end if
    
  end subroutine gridset_init
  
end module gridset
