!= Module GridSet
!
! Authors::   SUGIYAMA Ko-ichiro
! Version::   $Id: gridset.f90,v 1.5 2007-06-09 13:12:30 sugiyama Exp $ 
! Tag Name::  $Name: arare4-20080627 $
! Copyright:: Copyright (C) GFD Dennou Club, 2006. All rights reserved.
! License::   See COPYRIGHT[link:../../COPYRIGHT]
!
!== Overview 
!
!引数に与えられた NAMELIST ファイルから, 格子点情報を取得し, 
!保管するための変数型モジュール
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!== Future Plans
!

module gridset
  !
  !引数に与えられた NAMELIST ファイルから, 格子点情報を取得し, 
  !保管するための変数型モジュール
  !

  !モジュール読み込み
  use dc_message, only: MessageNotify

  !暗黙の型宣言禁止
  implicit none

  !save 属性
  save

  !公開変数
  real(8)               :: Xmin, Xmax    ! x 座標の始点・終点
  real(8)               :: Zmin, Zmax    ! z 座標の始点・終点
  real(8)               :: DelX, DelZ    !格子間隔
  integer               :: NX, NZ        !格子点数
  integer, parameter    :: MarginX = 5   !境界のグリッド数
  integer, parameter    :: MarginZ = 5   !境界のグリッド数
  integer               :: SpcNum        !化学種の数
  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               :: FileNX        !ファイル出力用
  integer               :: FileNZ        !ファイル出力用
  integer               :: FileXMin      !ファイル出力用
  integer               :: FileXMax      !ファイル出力用
  integer               :: FileZMin      !ファイル出力用
  integer               :: FileZMax      !ファイル出力用
  real(8), allocatable  :: s_X(:)        !X 座標軸(スカラー格子点)
  real(8), allocatable  :: f_X(:)        !X 座標軸(ベクトル格子点)
  real(8), allocatable  :: s_Z(:)        !Z 座標軸(スカラー格子点)
  real(8), allocatable  :: f_Z(:)        !Z 座標軸(ベクトル格子点)

contains

  subroutine gridset_init(cfgfile)
    !
    !NAMELIST から情報を得て, 格子点を計算する
    !

    !モジュール読み込み
    use DebugSet, only: DebugOn
    
    !暗黙の型宣言禁止
    implicit none

    !入力変数
    character(*), intent(in) :: cfgfile

    !内部変数
    integer            :: i, k
    integer, parameter :: kind = 8      !精度を表す

    !-----------------------------------------------------------------
    ! NAMELIST から情報を取得
    !-----------------------------------------------------------------
    NAMELIST /gridset/ NX, NZ, Xmin, Xmax, Zmin, Zmax, SpcNum

    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

!    !-----------------------------------------------------------------
!    ! 物理的に意味のある領域の上限・下限を決める
!    !-----------------------------------------------------------------;
!    RegXMin = 1
!    RegXMax = NX
!    RegZMin = 1
!    RegZMax = NZ
!
!    !-----------------------------------------------------------------
!    ! 壁に対応する領域の配列添え字を保管
!    !-----------------------------------------------------------------;
!    WallXMin = 0
!    WallXMax = NX
!    WallZMin = 0
!    WallZMax = NZ

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

    !-----------------------------------------------------------------
    ! グリッドの設定
    !-----------------------------------------------------------------
    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

    !-----------------------------------------------------------------
    ! デバッグモードか否かで, ファイル出力に用いる変数の大きさを変える
    !-----------------------------------------------------------------
    if (DebugOn) then
      FileNX   = size(f_X, 1)
      FileNZ   = size(f_Z, 1)
      FileXMin = DimXMin
      FileXMax = DimXMax
      FileZMin = DimZMin
      FileZMax = DimZMax
    else
      FileNX   = NX
      FileNZ   = NZ
      FileXMin = RegXMin + 1
      FileXMax = RegXMax
      FileZMin = RegZMin + 1
      FileZMax = RegZMax
    end if

    !-----------------------------------------------------------------    
    ! 確認
    !-----------------------------------------------------------------
    call MessageNotify( "M", "gridset_init", "XMin = %f", d=(/XMin/)    )
    call MessageNotify( "M", "gridset_init", "XMax = %f", d=(/XMax/)    )
    call MessageNotify( "M", "gridset_init", "ZMin = %f", d=(/ZMin/)    )
    call MessageNotify( "M", "gridset_init", "ZMax = %f", d=(/ZMax/)    )
    call MessageNotify( "M", "gridset_init", "DelX = %f", d=(/DelX/)    )
    call MessageNotify( "M", "gridset_init", "DelZ = %f", d=(/DelZ/)    )
    call MessageNotify( "M", "gridset_init", "NX = %d",   i=(/NX/)      )
    call MessageNotify( "M", "gridset_init", "NZ = %d",   i=(/NZ/)      )
    call MessageNotify( "M", "gridset_init", "SpcNum = %d", i=(/SpcNum/) )
    call MessageNotify( "M", "gridset_init", "MarginX = %d", i=(/MarginX/) )
    call MessageNotify( "M", "gridset_init", "MarginZ = %d", i=(/MarginZ/) )
    call MessageNotify( "M", "gridset_init", "DimXMin = %d", i=(/DimXMin/) )
    call MessageNotify( "M", "gridset_init", "DimXMax = %d", i=(/DimXMax/) )
    call MessageNotify( "M", "gridset_init", "DimZMin = %d", i=(/DimZMin/) )
    call MessageNotify( "M", "gridset_init", "DimZMax = %d", i=(/DimZMax/) )
    call MessageNotify( "M", "gridset_init", "RegXMin = %d", i=(/RegXMin/) )
    call MessageNotify( "M", "gridset_init", "RegXMax = %d", i=(/RegXMax/) )
    call MessageNotify( "M", "gridset_init", "RegZMin = %d", i=(/RegZMin/) )
    call MessageNotify( "M", "gridset_init", "RegZMax = %d", i=(/RegZMax/) )
    call MessageNotify( "M", "gridset_init", "FileNX = %d",  i=(/FileNX/))
    call MessageNotify( "M", "gridset_init", "FileNZ = %d",  i=(/FileNZ/))
    call MessageNotify( "M", "gridset_init", "FileXMin = %d", i=(/FileXMin/))
    call MessageNotify( "M", "gridset_init", "FileXMax = %d", i=(/FileXMax/))
    call MessageNotify( "M", "gridset_init", "FileZMin = %d", i=(/FileZMin/))
    call MessageNotify( "M", "gridset_init", "FileZMax = %d", i=(/FileZMax/))

  end subroutine gridset_init
  
end module gridset
