!> \~japanese
!! \brief 各種正二十面体を簡単に生成するための手続きを提供するモジュール.
!!
!! \par IcGrid2D_FVM_Builder モジュールについて
!!
!! \~english
!! \brief This module provides some subroutines to generate various icosahedral grids easily.
!!
!! \par About IcGrid2D_FVM_Builder module
!!
!! \~
!! <br><br>
!! \b Copyright (C) GFD Dennou Club, 2011-2012. All rights reserved. <br>
!! \b license ?? <br>
!! \author Yuta Kawai
!!
module IcGrid2D_FVM_Builder

  ! モジュール引用 ; Use statements
  !

  ! 種類型パラメタ
  ! Kind type parameter
  !
  use dc_types, only: DP           ! 倍精度実数型. Double precision

  ! 正二十面格子データの管理
  ! Manage of icosahedral grid data
  !
  use IcGrid2D_FVM_Manager, only: &
    & IcGrid2D_FVM, &
    & IcGrid2D_FVM_Init, malloc_GP_array, malloc_CV_array, &
    & GTYPE_STDGRID, GTYPE_STDGCGRID, GTYPE_SPRGCGRID

  ! STD-grid の構築
  ! STD-grid construction
  !
  use STDGrid_Builder, only: &
    & construct_STDGrid, calc_CV_vertex, calc_CV_Area

  ! STD-GC-grid の構築
  ! STD-GC-grid construction
  !
  use STDGCGrid_Builder, only: &
    & construct_STDGCGrid

  ! SPR-GC-grid の構築
  ! SPR-GC-grid construction
  !
  use SPRGCGrid_Builder, only: &
    & construct_SPRGCGrid, set_iteration_limiter

  ! 宣言文 ; Declaration statements
  !
  implicit none
  private

  ! 公開手続き
  ! Public procedures
  !
  public :: construct_icosahedral_grid
  public :: calc_CV_vertex, calc_CV_Area  ! Cascade
  public :: GTYPE_STDGRID, GTYPE_STDGCGRID, GTYPE_SPRGCGRID ! Cascade
  public :: set_iteration_limiter ! Cascade ( SPRGCGrid_Builder module)

  ! interface 文 ; interface statements
  !
  interface construct_icosahedral_grid
    module procedure construct_icosahedral_grid1
    module procedure construct_icosahedral_grid2
  end interface construct_icosahedral_grid

contains

!
!> \~japanese
!! \brief 第一引数で指定された正二十面格子の種類を表すパラメータから, それに対応する正二十面格子を構築する.
!!
!! \param[in] grid_type 正二十面格子の種類.
!! \param[in] glevel    水平分割レベル.
!! \param[in] ic_radius 正二十面体を内包する球の半径.
!! \param[out] icgrid   構築した正二十面格子の情報を保存する構造型 IcGrid2D_FVM の変数.
!!
!! \~english
!! \brief Constructs the icosahedral grid that the first argument representing the kind of the grid corresponds to.
!!
!! \param[in] grid_type The kind of icosahedral grid.
!! \param[in] glevel    Horizontal division level.
!! \param[in] ic_radius The radius of a sphere which an icosahedron is embedded into.
!! \param[out] icgrid   The variable of derived type IcGrid2D_FVM which saves the information
!! about the constructed icsahedral grid.
!!
!!
subroutine construct_icosahedral_grid1( &
  & grid_type, glevel, ic_radius, &  ! (in)
  & icgrid                        &  ! (out)
  & )

  ! 宣言文 ; Declaration statements
  !
  integer, intent(in) :: grid_type
  integer, intent(in) :: glevel
  real(DP), intent(in) :: ic_radius
  type(IcGrid2D_FVM), intent(out) :: icgrid

  ! 実行文 ; Executable statements
  !

  call IcGrid2D_FVM_Init(icgrid, glevel, ic_radius)
  call malloc_GP_array(icgrid)
  call malloc_CV_array(icgrid)

  call construct_icosahedral_grid2(grid_type, icgrid)

end subroutine construct_icosahedral_grid1

!
!> \~japanese
!! \brief 第一引数で指定された正二十面格子の種類を表すパラメータから, それに対応する正二十面格子を構築する.
!!
!! \param[in] grid_type 正二十面格子の種類.
!! \param[in,out] icgrid   構築した正二十面格子の情報を保存する構造型 IcGrid2D_FVM の変数.
!!
!! \~english
!! \brief Constructs the icosahedral grid that the first argument representing the kind of the grid corresponds to.
!!
!! \param[in] grid_type The kind of icosahedral grid.
!! \param[in,out] icgrid   The variable of derived type IcGrid2D_FVM which saves the information
!! about the constructed icsahedral grid.
!!
subroutine construct_icosahedral_grid2( &
  & grid_type, &  ! (in)
  & icgrid     &  ! (inout)
  & )

  ! 宣言文 ; Declaration statements
  !
  integer, intent(in) :: grid_type
  type(IcGrid2D_FVM), intent(inout) :: icgrid


  ! 実行文 ; Executable statements
  !

  ! 指定された正二十面格子の種類に合わせて, 格子を生成する.
  !
  select case (grid_type)
    case (GTYPE_STDGRID)
      ! STD-grid の構築
      call construct_STDGrid(icgrid)

    case (GTYPE_STDGCGRID)
      ! STD-GC-grid の構築
      call construct_STDGCGrid(icgrid)

    case (GTYPE_SPRGCGRID)
      ! SPR-GC-grid の構築
      call construct_SPRGCGrid(icgrid)

    case default

  end select

end subroutine construct_icosahedral_grid2

end module IcGrid2D_FVM_Builder
