!---------------------------------------------------------------------
!     Copyright (C) GFD Dennou Club, 2005. All rights reserved.
!---------------------------------------------------------------------
                                                                 !=begin
!= Module grid_3d_mod
!
!   * Developers: Morikawa Yasuhiro
!   * Version: $Id: grid_3d.f90,v 1.1.1.1 2005/11/08 14:10:23 morikawa Exp $
!   * Tag Name: $Name:  $
!   * Change History: 
!
!== Overview
!
!This module set 3 Dimensional Grid Information.
!
!3 次元の格子点情報の設定を行うためのモジュールである。
!
!== Error Handling
!
!== Known Bugs
!
!== Note
!
!== Future Plans
!
!もしかすると、「３次元」という枠組ではなく、それぞれの次元に分けた
!モジュールにすべきかも知れない。
!
                                                                 !=end

module grid_3d_mod
                                                                 !=begin
  !== Dependency
  use type_mod, only : INTKIND, STRING
                                                                 !=end
  implicit none

                                                                 !=begin
  !== Public Interface
  private
  public :: grid_3d_init, grid_3d_end ! subroutines
  public :: im, jm, km                ! variables
                                                                 !=end

  logical,          save :: grid_3d_initialized = .false.
  character(STRING),parameter:: version = &
       & '$Id: grid_3d.f90,v 1.1.1.1 2005/11/08 14:10:23 morikawa Exp $'
  character(STRING),parameter:: tagname = '$Name:  $'
                                                                 !=begin
  !== Public Data
  !
  !grid_3d_init において値が設定される。以下はデフォルト値。
  !
  integer(INTKIND), save :: im = 64 , &  ! 格子点の設定(X)
       &                    jm = 32 , &  ! 格子点の設定(Y)
       &                    km = 12      ! 格子点の設定(Y)
                                                                 !=end


contains
                                                                 !=begin
  !== Procedure Interface
  !
  !=== Initialize module and acquire NAMELIST
  !
  !NAMELIST から x 軸、 y 軸、 z 軸の格子点数を取得する。
  !取得できない場合、またはゼロ以下の値が与えられた場合、
  !上記のデフォルト値が強制的に設定される。
  !
  !NAMELIST ファイルは、メインプログラムにて ((< nmlfile_mod >)) の
  !((< nmlfile_init >)) で指定されることが想定されているが、
  !もしもこの初期化ルーチンより以前に指定されていなければ、
  !((< nmlfile_init >)) のデフォルトで指定される NAMELIST ファイルを
  !読む。
  !
  !
  subroutine grid_3d_init
  !
  !==== Dependency
  !
    use type_mod,   only: INTKIND
    use nmlfile_mod,only: nmlfile_init, nmlfile_open, nmlfile_close
    use dc_trace,   only: DbgMessage, BeginSub, EndSub
    use dc_message, only: MessageNotify
                                                                 !=end
    implicit none

    !-------------------------------------------------------------------
    !   変数定義
    !-------------------------------------------------------------------
    logical                     :: invalid_grid = .false.
    logical                     :: nmlreadable
    integer(INTKIND)            :: nmlunit, nmlstat
    character(STRING), parameter:: subname = "grid_3d_init"

                                                                 !=begin
    !==== NAMELIST
    !
    namelist /grid_3d_nml/ & 
         & im , &      ! 東西格子点数
         & jm , &      ! 南北格子点数
         & km          ! 鉛直格子点数
                                                                 !=end
  continue
    !----------------------------------------------------------------
    !   Check Initialization
    !----------------------------------------------------------------
    call BeginSub(subname)
    if (grid_3d_initialized) then
       call EndSub( subname, '%c is already called', c1=trim(subname) )
       return
    else
       grid_3d_initialized = .true.
    endif

    !----------------------------------------------------------------
    !   Version identifier
    !----------------------------------------------------------------
    call DbgMessage('%c :: %c', c1=trim(version), c2=trim(tagname))

    !----------------------------------------------------------------
    !   read grid_3d_nml
    !----------------------------------------------------------------
    call nmlfile_init
    call nmlfile_open(nmlunit, nmlreadable)
    if (nmlreadable) then
       read(nmlunit, nml=grid_3d_nml, iostat=nmlstat)
       call DbgMessage('Stat of NAMELIST grid_3d_nml Input is <%d>', &
            &           i=(/nmlstat/))
       write(0, nml=grid_3d_nml)
    else
       call DbgMessage('Not Read NAMELIST grid_3d_nml')
       call MessageNotify('W', subname, &
            & 'Can not Read NAMELIST grid_3d_nml. Force Use Default Value.')
    end if
    call nmlfile_close

    !----------------------------------------------------------------
    !   Exception handling
    !----------------------------------------------------------------
    invalid_grid = .false.
    if (im < 1) then
       im = 64 ; invalid_grid = .true.
    end if
    if (jm < 1) then
       jm = 32 ; invalid_grid = .true.
    end if
    if (km < 1) then
       km = 12 ; invalid_grid = .true.
    end if

    if (invalid_grid) then
       call MessageNotify('W', subname, &
            & 'Invalid grid number is exist. Force Set im=<%d>, jm=<%d>, km=<%d>', &
            & i=(/im, jm, km/) )
       call DbgMessage( &
            & 'Invalid grid number is exist. Force Set im=<%d>, jm=<%d>, km=<%d>', &
            & i=(/im, jm, km/) )
    endif

    call EndSub( subname, 'im=<%d>, jm=<%d>, km=<%d>', &
         &       i=(/im, jm, km/) )
  end subroutine grid_3d_init


                                                                 !=begin
  !=== Terminate module
  !
  !NAMELIST から読み込んだ値を破棄し、各定数をデフォルトの値に戻す。
  !
  subroutine grid_3d_end
  !==== Dependency
    use dc_trace,  only: DbgMessage, BeginSub, EndSub
                                                                 !=end
    implicit none

    character(STRING), parameter:: subname = "grid_3d_end"

    !----------------------------------------------------------------
    !   Check Initialization
    !----------------------------------------------------------------
    call BeginSub(subname)
    if ( .not. grid_3d_initialized) then
       call EndSub( subname, 'grid_3d_init was not called', &
            &       c1=trim(subname) )
       return
    else
       grid_3d_initialized = .false.
    endif

    !----------------------------------------------------------------
    !   Reset to default value
    !----------------------------------------------------------------
    im = 64
    jm = 32
    km = 12

    call EndSub( subname, 'im=<%d>, jm=<%d>, km=<%d>', &
         &       i=(/im, jm, km/) )
  end subroutine grid_3d_end

end module grid_3d_mod
