!c Description: 
!c   座標軸設定用モジュール
!c
!c Current Code Owner: 
!c   sugiyama@gfd-dennou.org
!c
!c Histry: 
!c   Version    Date          Comment
!c   -------    ----------    --------
!c   1.0        2003-11-12    作成
!c
!c Copyright (C) SUGIYAMA Ko-ichiro, 2003, All rights reserved

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

  !--- save 属性
  save

  !--- 変数定義
  real(8)               :: xmin, xmax    ! x 方向の始点・終点
  real(8)               :: zmin, zmax    ! z 方向の始点・終点
  real(8)               :: dx, dz        !格子間隔
  real(8)               :: pres_sfc      !地表面圧力 
  real(8)               :: temp_sfc      !地表面温度
  integer               :: im, km        !格子点数
  integer               :: bdc_s         !境界(スカラー量)
  integer               :: bdc_u         !境界(ベクトル u)
  integer               :: bdc_w         !境界(ベクトル w)
  integer               :: imin, imax
  integer               :: kmin, kmax
  integer               :: ime, kme
  integer, parameter    :: imb = 0
  integer, parameter    :: kmb = 0
  integer, parameter    :: bm = 2        !境界のグリッド数
  real(8), allocatable  :: x(:)
  real(8), allocatable  :: z(:)
  real(8), allocatable  :: xs(:)
  real(8), allocatable  :: zs(:)
  
contains
  subroutine gridset_init
    !--- モジュール読み込み
    use fileset, only: cfgfile

    !--- 内部変数の定義
    integer             :: i
    character(20)       :: x_boundary
    character(20)       :: z_boundary

    !--- NAMELIST の定義
    NAMELIST /gridset/ &
         & im, km, xmin, xmax, zmin, zmax, pres_sfc, temp_sfc, &
         & x_boundary, z_boundary
    
    !---変数の取り出し
    open (10, FILE=cfgfile)
    read(10, NML=gridset)
    close(10)
    
    !--- 格子点間隔計算
    dx = (xmax - xmin) / real(im, 8)
    dz = (zmax - zmin) / real(km, 8)
    
    !--- 配列の添字を用意
    ime  = imb + im - 1
    kme  = kmb + km - 1
    imin = imb - bm
    kmin = kmb - bm
    imax = ime + bm
    kmax = kme + bm
    
    !--- グリッドの設定
    allocate(x(imin:imax), z(kmin:kmax))
    do i = imin, imax
       x(i) = xmin + dx * ( real(i, 8) - imb )
    end do
    do i = kmin, kmax
       z(i) = zmin + dz * ( real(i, 8) - kmb )
    end do
    
    !--- 半格子ずれたグリッドの設定. 等間隔を前提にしている.
    allocate(xs(imin:imax), zs(kmin:kmax))
    xs(imin:imax-1) =             &
         &  (                     &
         &     x(imin+1:imax)     &
         &   + x(imin:imax-1)     &
         &  ) * 5.0d-1
    xs(imax) = xs(imax - 1) + dx
    
    zs(kmin:kmax-1) =             &
         &  (                     &
         &     z(kmin+1:kmax)     &
         &   + z(kmin:kmax-1)     &
         &  ) * 5.0d-1
    zs(kmax) = zs(kmax - 1) + dz

    !--- 境界のタイプを指定 (boundary.f90 参照)
    if (trim(x_boundary) == "cyclic" &
         & .AND. trim(z_boundary) == "rigid") then        
       bdc_s = 2
       bdc_u = 2
       bdc_w = 3
    else 
       write(*,*) "gridset.f90, unknown boundary condition" 
    end if
    
  end subroutine gridset_init
  
end module gridset
