!---------------------------------------------------------------------
!     Copyright (C) GFD Dennou Club, 2006. All rights reserved.
!---------------------------------------------------------------------
!
!= 3 次元 (xyz 方向) 不等間隔交互格子 境界条件モジュール
!
!* 履歴
!  * 2007/07/15 (小高正嗣) : 3D deepconv へ移植, dc_types を Use.
!  * 2006/06/07 (小高正嗣) : 新規作成

module xyz_bc_module
  != 3 次元 (xyz 方向) 不等間隔交互格子 有限差分モデル用 境界条件モジュール
  !
  !== 概要
  !
  ! xyz_bc_module は, 3 次元 (xyz 方向) 不等間隔交互格子を用いた有限差分法に
  ! 基づく数値モデルのための, 境界条件設定 Fortran 90 副プログラムを提供
  ! する.
  !
  ! このモジュールは xyz_module の下位モジュールである. 下請けモジュール
  ! として data_type, xyz_base_module, x_bc_module, y_bc_module, 
  ! z_bc_module モジュールを用いている. 
  !
  !
  !== 手続きの命名法
  !
  ! 境界条件を設定する副プログラムは
  !
  !   Boundary[境界条件を示す文字列][...]_(入力配列の次元情報)
  !
  ! のように命名されている. 境界条件を示す文字列の種類は x_bc_module,
  ! y_bc_module, z_bc_module の場合と同じである.
  ! 
  !
  use dc_types,        only : DBKIND => DP
  use x_base_module, only: imin, imax
  use y_base_module, only: jmin, jmax
  use z_base_module, only: kmin, kmax
!  use xyz_base_module, only : imin, imax, jmin, jmax, kmin, kmax
  use x_bc_module,   only : BoundarySym_x, BoundaryAsym_x, BoundaryCyc_x, &
    &                       BoundarySym_p, BoundaryAsym_p, BoundaryCyc_p
  use y_bc_module,   only : BoundarySym_y, BoundaryAsym_y, BoundaryCyc_y, &
    &                       BoundarySym_q, BoundaryAsym_q, BoundaryCyc_q
  use z_bc_module,   only : BoundarySym_z, BoundaryAsym_z, BoundaryCyc_z, &
    &                       BoundarySym_r, BoundaryAsym_r, BoundaryCyc_r

  implicit none

  private

  public :: BoundaryXSym_xyz, BoundaryXAsym_xyz, BoundaryXCyc_xyz 
  public :: BoundaryXSym_xqz, BoundaryXAsym_xqz, BoundaryXCyc_xqz 
  public :: BoundaryXSym_xyr, BoundaryXAsym_xyr, BoundaryXCyc_xyr 
  public :: BoundaryXSym_pyz, BoundaryXAsym_pyz, BoundaryXCyc_pyz 

  public :: BoundaryYSym_xyz, BoundaryYAsym_xyz, BoundaryYCyc_xyz 
  public :: BoundaryYSym_xqz, BoundaryYAsym_xqz, BoundaryYCyc_xqz 
  public :: BoundaryYSym_xyr, BoundaryYAsym_xyr, BoundaryYCyc_xyr 
  public :: BoundaryYSym_pyz, BoundaryYAsym_pyz, BoundaryYCyc_pyz 

  public :: BoundaryZSym_xyz, BoundaryZAsym_xyz, BoundaryZCyc_xyz 
  public :: BoundaryZSym_xqz, BoundaryZAsym_xqz, BoundaryZCyc_xqz 
  public :: BoundaryZSym_xyr, BoundaryZAsym_xyr, BoundaryZCyc_xyr 
  public :: BoundaryZSym_pyz, BoundaryZAsym_pyz, BoundaryZCyc_pyz 

  interface BoundaryXSym_xyz
    module procedure BoundaryXSym_xaa
  end interface

  interface BoundaryXSym_xqz
    module procedure BoundaryXSym_xaa
  end interface

  interface BoundaryXSym_xyr
    module procedure BoundaryXSym_xaa
  end interface

  interface BoundaryXAsym_xyz
    module procedure BoundaryXAsym_xaa
  end interface

  interface BoundaryXAsym_xqz
    module procedure BoundaryXAsym_xaa
  end interface

  interface BoundaryXAsym_xyr
    module procedure BoundaryXAsym_xaa
  end interface

  interface BoundaryXCyc_xyz
    module procedure BoundaryXCyc_xaa
  end interface

  interface BoundaryXCyc_xqz
    module procedure BoundaryXCyc_xaa
  end interface

  interface BoundaryXCyc_xyr
    module procedure BoundaryXCyc_xaa
  end interface

  interface BoundaryYSym_xyz
    module procedure BoundaryYSym_aya
  end interface

  interface BoundaryYSym_pyz
    module procedure BoundaryYSym_aya
  end interface

  interface BoundaryYSym_xyr
    module procedure BoundaryYSym_aya
  end interface

  interface BoundaryYAsym_xyz
    module procedure BoundaryYAsym_aya
  end interface

  interface BoundaryYAsym_pyz
    module procedure BoundaryYAsym_aya
  end interface

  interface BoundaryYAsym_xyr
    module procedure BoundaryYAsym_aya
  end interface

  interface BoundaryYCyc_xyz
    module procedure BoundaryYCyc_aya
  end interface

  interface BoundaryYCyc_pyz
    module procedure BoundaryYCyc_aya
  end interface

  interface BoundaryYCyc_xyr
    module procedure BoundaryYCyc_aya
  end interface

  interface BoundaryZSym_xyz
    module procedure BoundaryZSym_aaz
  end interface

  interface BoundaryZSym_pyz
    module procedure BoundaryZSym_aaz
  end interface

  interface BoundaryZSym_xqz
    module procedure BoundaryZSym_aaz
  end interface

  interface BoundaryZAsym_xyz
    module procedure BoundaryZAsym_aaz
  end interface

  interface BoundaryZAsym_pyz
    module procedure BoundaryZAsym_aaz
  end interface

  interface BoundaryZAsym_xqz
    module procedure BoundaryZAsym_aaz
  end interface

  interface BoundaryZCyc_xyz
    module procedure BoundaryZCyc_aaz
  end interface

  interface BoundaryZCyc_pyz
    module procedure BoundaryZCyc_aaz
  end interface

  interface BoundaryZCyc_xqz
    module procedure BoundaryZCyc_aaz
  end interface

  contains

!--------------------------------------------------------------------
    subroutine BoundaryXSym_xaa(xaa_Var)
      real(DBKIND),intent(inout) :: xaa_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: jy, kz
      
      ! x 方向に対称境界条件を適用する
      do kz = kmin, kmax
        do jy = jmin, jmax
          call BoundarySym_x(xaa_Var(:,jy,kz))
        end do
      end do

    end subroutine BoundaryXSym_xaa
!--------------------------------------------------------------------
    subroutine BoundaryXSym_pyz(pyz_Var)
      real(DBKIND),intent(inout) :: pyz_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: jy, kz
      
      ! x 方向に対称境界条件を適用する
      do kz = kmin, kmax
        do jy = jmin, jmax
          call BoundarySym_p(pyz_Var(:,jy,kz))
        end do
      end do

    end subroutine BoundaryXSym_pyz
!--------------------------------------------------------------------
    subroutine BoundaryXAsym_xaa(xaa_Var)
      real(DBKIND),intent(inout) :: xaa_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: jy, kz
      
      ! x 方向に反対称境界条件を適用する
      do kz = kmin, kmax
        do jy = jmin, jmax
          call BoundaryAsym_x(xaa_Var(:,jy,kz))
        end do
      end do

    end subroutine BoundaryXAsym_xaa
!--------------------------------------------------------------------
    subroutine BoundaryXAsym_pyz(pyz_Var)
      real(DBKIND),intent(inout) :: pyz_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: jy, kz
      
      ! x 方向に反対称境界条件を適用する
      do kz = kmin, kmax
        do jy = jmin, jmax
          call BoundaryAsym_p(pyz_Var(:,jy,kz))
        end do
      end do

    end subroutine BoundaryXAsym_pyz
!--------------------------------------------------------------------
    subroutine BoundaryXCyc_xaa(xaa_Var)
      real(DBKIND),intent(inout) :: xaa_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: jy, kz
      
      ! x 方向に周期境界条件を適用する
      do kz = kmin, kmax
        do jy = jmin, jmax
          call BoundaryCyc_x(xaa_Var(:,jy,kz))
        end do
      end do

    end subroutine BoundaryXCyc_xaa
!--------------------------------------------------------------------
    subroutine BoundaryXCyc_pyz(pyz_Var)
      real(DBKIND),intent(inout) :: pyz_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: jy, kz
      
      ! x 方向に周期境界条件を適用する
      do kz = kmin, kmax
        do jy = jmin, jmax
          call BoundaryCyc_p(pyz_Var(:,jy,kz))
        end do
      end do

    end subroutine BoundaryXCyc_pyz
!--------------------------------------------------------------------
    subroutine BoundaryYSym_aya(aya_Var)
      real(DBKIND),intent(inout) :: aya_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, kz
      
      ! y 方向に対称境界条件を適用する
      do kz = kmin, kmax
        do ix = imin, imax
          call boundarySym_y(aya_Var(ix,:,kz))
        end do
      end do

    end subroutine BoundaryYsym_aya
!--------------------------------------------------------------------
    subroutine BoundaryYSym_xqz(xqz_Var)
      real(DBKIND),intent(inout) :: xqz_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, kz
      
      ! y 方向に対称境界条件を適用する
      do kz = kmin, kmax
        do ix = imin, imax
          call boundarySym_q(xqz_Var(ix,:,kz))
        end do
      end do

    end subroutine BoundaryYsym_xqz
!--------------------------------------------------------------------
    subroutine BoundaryYASym_aya(aya_Var)
      real(DBKIND),intent(inout) :: aya_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, kz
      
      ! y 方向に反対称境界条件を適用する
      do kz = kmin, kmax
        do ix = imin, imax
          call boundaryASym_y(aya_Var(ix,:,kz))
        end do
      end do

    end subroutine BoundaryYAsym_aya
!--------------------------------------------------------------------
    subroutine BoundaryYASym_xqz(xqz_Var)
      real(DBKIND),intent(inout) :: xqz_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, kz
      
      ! y 方向に反対称境界条件を適用する
      do kz = kmin, kmax
        do ix = imin, imax
          call boundaryASym_q(xqz_Var(ix,:,kz))
        end do
      end do

    end subroutine BoundaryYAsym_xqz
!--------------------------------------------------------------------
    subroutine BoundaryYCyc_aya(aya_Var)
      real(DBKIND),intent(inout) :: aya_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, kz
      
      ! y 方向に周期境界条件を適用する
      do kz = kmin, kmax
        do ix = imin, imax
          call BoundaryCyc_y(aya_Var(ix,:,kz))
        end do
      end do

    end subroutine BoundaryYCyc_aya
!--------------------------------------------------------------------
    subroutine BoundaryYCyc_xqz(xqz_Var)
      real(DBKIND),intent(inout) :: xqz_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, kz
      
      ! y 方向に周期境界条件を適用する
      do kz = kmin, kmax
        do ix = imin, imax
          call BoundaryCyc_q(xqz_Var(ix,:,kz))
        end do
      end do

    end subroutine BoundaryYCyc_xqz
!--------------------------------------------------------------------
    subroutine BoundaryZSym_aaz(aaz_Var)
      real(DBKIND),intent(inout) :: aaz_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, jy
      
      ! z 方向に対称境界条件を適用する
      do jy = jmin, jmax
        do ix = imin, imax
          call boundarySym_z(aaz_Var(ix,jy,:))
        end do
      end do

    end subroutine BoundaryZSym_aaz
!--------------------------------------------------------------------
    subroutine BoundaryZSym_xyr(xyr_Var)
      real(DBKIND),intent(inout) :: xyr_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, jy
      
      ! z 方向に対称境界条件を適用する
      do jy = jmin, jmax
        do ix = imin, imax
          call boundarySym_r(xyr_Var(ix,jy,:))
        end do
      end do

    end subroutine BoundaryZSym_xyr
!--------------------------------------------------------------------
    subroutine BoundaryZAsym_aaz(aaz_Var)
      real(DBKIND),intent(inout) :: aaz_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, jy
      
      ! z 方向に反対称境界条件を適用する
      do jy = jmin, jmax
        do ix = imin, imax
          call boundaryAsym_z(aaz_Var(ix,jy,:))
        end do
      end do

    end subroutine BoundaryZAsym_aaz
!--------------------------------------------------------------------
    subroutine BoundaryZAsym_xyr(xyr_Var)
      real(DBKIND),intent(inout) :: xyr_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, jy
      
      ! z 方向に反対称境界条件を適用する
      do jy = jmin, jmax
        do ix = imin, imax
          call boundaryAsym_r(xyr_Var(ix,jy,:))
        end do
      end do

    end subroutine BoundaryZAsym_xyr
!--------------------------------------------------------------------
    subroutine BoundaryZCyc_aaz(aaz_Var)
      real(DBKIND),intent(inout) :: aaz_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, jy
      
      ! z 方向に周期境界条件を適用する
      do jy = jmin, jmax
        do ix = imin, imax
          call boundaryCyc_z(aaz_Var(ix,jy,:))
        end do
      end do

    end subroutine BoundaryZCyc_aaz
!--------------------------------------------------------------------
    subroutine BoundaryZCyc_xyr(xyr_Var)
      real(DBKIND),intent(inout) :: xyr_Var(imin:imax,jmin:jmax,kmin:kmax) 
      integer           :: ix, jy
      
      ! z 方向に周期境界条件を適用する
      do jy = jmin, jmax
        do ix = imin, imax
          call boundaryCyc_z(xyr_Var(ix,jy,:))
        end do
      end do

    end subroutine BoundaryZCyc_xyr
!--------------------------------------------------------------------
end module xyz_bc_module
