Class et_module
In: libsrc/et_module/et_module.f90

et_module

Authors:Shin-ichi Takehiro, Youhei SASAKI
Version:$Id: et_module.f90 598 2013-08-20 03:23:44Z takepiro $
Copyright&License:See COPYRIGHT

概要

2 次元水路領域問題, Fourier 展開 + Chebyshev 展開法

spml/et_module モジュールは 2 次元水路領域での流体運動を スペクトル法により数値計算を実行するための Fortran90 関数を提供する. 周期的な境界条件を扱うための X 方向へのフーリエ変換と境界壁を扱うための Y 方向のチェビシェフ変換を用いる場合のスペクトル計算のためのさまざまな 関数を提供する.

内部で ae_module, at_module を用いている. 最下部ではフーリエ変換およびチェビシェフ変換のエンジンとして ISPACK/FTPACK の Fortran77 サブルーチンを用いている.

関数・変数の名前と型について

命名法

  • 関数名の先頭 (et_, yx_, x_, y_) は, 返す値の形を示している.
    et_ :2次元スペクトルデータ
    yx_ :2 次元格子点データ
    x_ :X 方向 1 次元格子点データ
    y_ :Y 方向 1 次元格子点データ
  • 関数名の間の文字列(Dx, Dy, Lapla, LaplaInv, Jacobian)は, その関数の作用を表している.
  • 関数名の最後 (_et_et, _et, _yx, _x, _y) は, 入力変数のスペクトルデータ および格子点データであることを示している.
    _et :2次元スペクトルデータ
    _et_et :2 つの2次元スペクトルデータ
    _yx :2 次元格子点データ
    _x :X 方向 1 次元格子点データ
    _y :Y 方向 1 次元格子点データ

各データの種類の説明

  • yx : 2 次元格子点データ.
    • 変数の種類と次元は real(8), dimension(0:jm,0:im-1).
    • im, jm はそれぞれ X, Y 座標の格子点数であり, サブルーチン et_initial にてあらかじめ設定しておく.
    • 第 1 次元が Y 座標の格子点位置番号, 第 2 次元が X 座標の 格子点位置番号である (X, Y の順ではない)ことに注意.
  • et : 2 次元スペクトルデータ.
    • 変数の種類と次元は real(8), dimension(-km:km,0:lm).
    • km, lm はそれぞれ X, Y 方向の最大波数であり, サブルーチン et_initial にてあらかじめ設定しておく.
    • スペクトルデータの格納のされ方については…
  • x, y : X, Y 方向 1 次元格子点データ.
    • 変数の種類と次元はそれぞれ real(8), dimension(0:im-1) および real(8), dimension(0:jm).
  • e, t : 1 次元スペクトルデータ.
    • 変数の種類と次元は real(8), dimension(-km:km) および real(8), dimension(-lm:lm).
  • ax, ay : 1 次元格子点データの並んだ 2 次元配列.
    • 変数の種類と次元は real(8), dimension(:,0:im-1) および real(8), dimension(:,0:jm).
  • ae, at : 1 次元スペクトルデータの並んだ 2 次元配列.
    • 変数の種類と次元は real(8), dimension(:,-km:km) および real(8), dimension(:,0:lm).
  • et_ で始まる関数が返す値はスペクトルデータに同じ.
  • yx_ で始まる関数が返す値は 2 次元格子点データに同じ.
  • x_, y_ で始まる関数が返す値は 1 次元格子点データに同じ.
  • スペクトルデータに対する微分等の作用とは, 対応する格子点データに 微分などを作用させたデータをスペクトル変換したものことである.

変数・手続き群の要約

初期化

et_Initial :スペクトル変換の格子点数, 波数, 領域の大きさの設定

座標変数

x_X, y_Y :格子点座標(X,Y座標)を格納した 1 次元配列
x_X_Weight, y_Y_Weight :重み座標を格納した 1 次元配列
yx_X, yx_Y :格子点データの XY 座標(X,Y)(格子点データ型 2 次元配列)

基本変換

yx_et :スペクトルデータから格子データへの変換
et_yx :格子データからスペクトルデータへの変換
ax_ae, x_e :X 方向のスペクトルデータから格子データへの変換
ay_at, y_t :Y 方向のスペクトルデータから格子データへの変換
ae_ax, e_x :X 方向の格子点データからスペクトルデータへの変換
at_ay, t_y :Y 方向の格子点データからスペクトルデータへの変換

微分

et_Lapla_et :スペクトルデータにラプラシアンを作用させる
et_Dx_et, ae_Dx_ae, e_Dx_e :スペクトルデータに X 微分を作用させる
et_Dy_et, at_Dy_at, t_Dy_t :スペクトルデータに Y 微分を作用させる
et_Jacobian_et_et :2 つのスペクトルデータからヤコビアンを計算する

境界値問題

et_Boundaries :ディリクレ, ノイマン境界条件の適用
et_LaplaInv_et :スペクトルデータにラプラシアンの逆変換を作用させる
et_Vor2Strm_et :渦度から流線を計算する
ey_Vor2Strm_ey :渦度から流線を計算する

積分・平均

IntYX_yx, AvrYX_yx :2 次元格子点データの全領域積分および平均
y_IntX_yx, y_AvrX_yx :2 次元格子点データの X 方向積分および平均
IntX_x, AvrX_x :1 次元(X)格子点データの X 方向積分および平均
x_IntY_yx, x_AvrY_yx :2 次元格子点データの Y 方向積分および平均
IntY_y, AvrY_y :1 次元(Y)格子点データの Y 方向積分および平均

補間

Interpolate_et :スペクトルデータからの特定の座標の値の補間

Methods

Included Modules

dc_message lumatrix ae_module at_module

Public Instance methods

Function :
AvrX_x :real(8)
: (out) 平均値
x :real(8), dimension(0:im-1)
: (in) 1 次元格子点データ

1 次元(X)格子点データの X 方向平均

実際には格子点データ各点毎に x_X_Weight をかけた総和を計算し, x_X_Weight の総和で割ることで平均している.

[Source]

    function AvrX_x(x)
      !
      ! 1 次元(X)格子点データの X 方向平均
      !
      ! 実際には格子点データ各点毎に x_X_Weight をかけた総和を計算し,
      ! x_X_Weight の総和で割ることで平均している.
      !
      real(8), dimension(0:im-1)   :: x          !(in)  1 次元格子点データ
      real(8)                      :: AvrX_x     !(out) 平均値

      AvrX_x = IntX_x(x)/sum(x_X_weight)
    end function AvrX_x
Function :
AvrYX_yx :real(8)
: (out) 平均値
yx :real(8), dimension(0:jm,0:im-1)
: (in) 2 次元格子点データ

2 次元格子点データの全領域平均

実際には格子点データ各点毎に x_X_Weight, y_Y_Weight をかけた 総和を計算し, x_X_Weight*y_Y_Weight の総和で割ることで平均している.

[Source]

    function AvrYX_yx(yx)
      !
      ! 2 次元格子点データの全領域平均
      !
      ! 実際には格子点データ各点毎に x_X_Weight, y_Y_Weight をかけた
      ! 総和を計算し, x_X_Weight*y_Y_Weight の総和で割ることで平均している.
      !
      real(8), dimension(0:jm,0:im-1)   :: yx
      !(in)  2 次元格子点データ

      real(8)                           :: AvrYX_yx
      !(out) 平均値

      AvrYX_yx = IntYX_yx(yx)/(sum(x_X_weight)*sum(y_Y_weight))
    end function AvrYX_yx
Function :
AvrY_y :real(8)
: (out) 平均値
y :real(8), dimension(0:jm)
: (in) 1 次元格子点データ

1 次元(Y)格子点データの Y 方向平均

実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算し, y_Y_Weight の総和で割ることで平均している.

[Source]

    function AvrY_y(y)
      !
      ! 1 次元(Y)格子点データの Y 方向平均
      !
      ! 実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算し,
      ! y_Y_Weight の総和で割ることで平均している.
      !
      real(8), dimension(0:jm)   :: y          !(in)  1 次元格子点データ
      real(8)                    :: AvrY_y     !(out) 平均値

      AvrY_y = IntY_y(y)/sum(y_Y_weight)
    end function AvrY_y
Function :
IntX_x :real(8)
: (out) 積分値
x :real(8), dimension(0:im-1)
: (in) 1 次元格子点データ

X 方向積分

1 次元(X)格子点データの X 方向積分

実際には格子点データ各点毎に x_X_Weight をかけた総和を計算している.

[Source]

    function IntX_x(x)      ! X 方向積分
      !
      ! 1 次元(X)格子点データの X 方向積分
      !
      ! 実際には格子点データ各点毎に x_X_Weight をかけた総和を計算している.
      !
      real(8), dimension(0:im-1)   :: x         !(in)  1 次元格子点データ
      real(8)                      :: IntX_x    !(out) 積分値

      IntX_x = sum(x*x_X_Weight)
    end function IntX_x
Function :
IntYX_yx :real(8)
: (out) 積分値
yx :real(8), dimension(0:jm,0:im-1)
: (in) 2 次元格子点データ

全領域積分

2 次元格子点データの全領域積分および平均.

実際には格子点データ各点毎に x_X_Weight, y_Y_Weight をかけた 総和を計算している.

[Source]

    function IntYX_yx(yx)   ! 全領域積分
      !
      ! 2 次元格子点データの全領域積分および平均.
      !
      ! 実際には格子点データ各点毎に x_X_Weight, y_Y_Weight をかけた
      ! 総和を計算している.
      !
      real(8), dimension(0:jm,0:im-1)   :: yx
      !(in)  2 次元格子点データ

      real(8)                           :: IntYX_yx
      !(out) 積分値

      integer :: i, j

      IntYX_yx = 0.0d0
      do i=0,im-1
         do j=0,jm
            IntYX_yx = IntYX_yx + yx(j,i) * y_Y_Weight(j) * x_X_Weight(i)
         enddo
      enddo
    end function IntYX_yx
Function :
IntY_y :real(8)
: (out) 積分値
y :real(8), dimension(0:jm)
: (in) 1 次元格子点データ

Y 方向積分

1 次元(Y)格子点データの Y 方向積分

実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算している.

[Source]

    function IntY_y(y)      ! Y 方向積分
      !
      ! 1 次元(Y)格子点データの Y 方向積分
      !
      ! 実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算している.
      !
      real(8), dimension(0:jm)   :: y          !(in)  1 次元格子点データ
      real(8)                    :: IntY_y     !(out) 積分値

      IntY_y = sum(y*y_Y_Weight)
    end function IntY_y
Function :
Interpolate_et :real(8)
: 補間した結果の値
et_data :real(8), dimension(-km:km,0:lm), intent(IN)
: (in) 入力フーリエデータ
xval :real(8), intent(in)
: 補間する点の X, Y 座標
yval :real(8), intent(in)
: 補間する点の X, Y 座標

[Source]

    function Interpolate_et(et_data,xval,yval)

      real(8), dimension(-km:km,0:lm), intent(IN) :: et_data
      !(in) 入力フーリエデータ

      real(8), intent(in)                         :: xval, yval
      ! 補間する点の X, Y 座標

      real(8)                                     :: Interpolate_et
      ! 補間した結果の値

      Interpolate_et = Interpolate_e(a_Interpolate_at(et_data,yval),xval)

    end function Interpolate_et
ae_Dx_ae( ae ) result(ae_Dx_ae)
Function :
ae :real(DP), dimension(:,-km:), intent(in)
: (in) 入力スペクトルデータ

入力スペクトルデータに X 微分を作用する(2 次元データ).

スペクトルデータの X 微分とは, 対応する格子点データに X 微分を 作用させたデータのスペクトル変換のことである.

Original external subprogram is ae_module#ae_Dx_ae

ae_ax( ag ) result(ae_ag)
Function :
ae_ag :real(DP), dimension(size(ag,1),-km:km)
: (out) スペクトルデータ
ag :real(DP), dimension(:,:), intent(in)
: (in) 格子点データ

格子点データからスペクトルデータへ正変換する(2 次元データ用)

スペクトル正変換の定義は以下のとおり.

  格子点データ     g_j (j=-0,...,im-1)
  スペクトルデータ e_k (k=-km,...,km)

  e_0 = (1/im)\sum_{j=0}^{im-1} g_j
  e_k = (1/im)\sum_{j=0}^{im-1} g_j \cos(2\pi jk/im)       (k=1,2,...,km)
  e_{-k} = - (1/im)\sum_{j=0}^{im-1} g_j \sin(2\pi jk/im)  (k=1,2,...,km)

Original external subprogram is ae_module#ae_ag

at_Boundaries_DD( at_data, [values] )
Subroutine :
at_data :real(8), dimension(:,0:),intent(inout)
: データ(m,0:km) (inout) 境界条件を適用するチェビシェフデータ(m,0:km)
values :real(8), dimension(:,:), intent(in), optional
: (in) 境界値(m,2)

Dirichlet 型境界条件の適用(タウ法, 2 次元配列用) 両境界での値を与える.

Original external subprogram is at_module#at_Boundaries_DD

at_Boundaries_DD( t_data, [values] )
Subroutine :
t_data :real(8), dimension(0:km),intent(inout)
: (inout) 境界条件を適用するチェビシェフデータ(0:km)
values :real(8), dimension(2), intent(in), optional
: (in) 境界値

Dirichlet 型境界条件の適用(タウ法, 1 次元配列用) 両境界での値を与える.

Original external subprogram is at_module#at_Boundaries_DD

at_Boundaries_DN( at_data, [values] )
Subroutine :
at_data :real(8), dimension(:,0:),intent(inout)
: (inout) 境界条件を適用するチェビシェフデータ(m,0:km)
values :real(8), dimension(:,:), intent(in), optional
: (in) 境界値(m,2)

Dirichlet/Neumann 型境界条件の適用(タウ法, 2 次元配列用) i=0 で値, i=im で勾配の値を与える.

Original external subprogram is at_module#at_Boundaries_DN

at_Boundaries_DN( t_data, [values] )
Subroutine :
t_data :real(8), dimension(0:km),intent(inout)
: (inout) 境界条件を適用するチェビシェフデータ(0:km)
values :real(8), dimension(2), intent(in), optional
: (in) 境界値

Dirichlet/Neumann 型境界条件の適用(タウ法, 1 次元配列用) i=0 で値, i=im で勾配の値を与える.

Original external subprogram is at_module#at_Boundaries_DN

at_Boundaries_ND( at_data, [values] )
Subroutine :
at_data :real(8), dimension(:,0:),intent(inout)
: (inout) 境界条件を適用するチェビシェフデータ(m,0:km)
values :real(8), dimension(:,:), intent(in), optional
: (in) 境界値(m,2)

Neumann/Dirichlet 型境界条件の適用(タウ法, 2 次元配列用) i=0 で勾配の値, i=im で値を与える.

Original external subprogram is at_module#at_Boundaries_ND

at_Boundaries_ND( t_data, [values] )
Subroutine :
t_data :real(8), dimension(0:km),intent(inout)
: (inout) 境界条件を適用するチェビシェフデータ(0:km)
values :real(8), dimension(2), intent(in), optional
: (in) 境界値

Neumann/Dirichlet 型境界条件の適用(タウ法, 1 次元配列用) i=0 で勾配の値, i=im で値を与える.

Original external subprogram is at_module#at_Boundaries_ND

at_Boundaries_NN( at_data, [values] )
Subroutine :
at_data :real(8), dimension(:,0:),intent(inout)
: (inout) 境界条件を適用するチェビシェフデータ(m,0:km)
values :real(8), dimension(:,:), intent(in), optional
: (in) 境界値(m,2)

Neumann/Dirichlet 型境界条件の適用(タウ法, 2 次元配列用) 両境界で勾配の値を与える.

Original external subprogram is at_module#at_Boundaries_NN

at_Boundaries_NN( t_data, [values] )
Subroutine :
t_data :real(8), dimension(0:km),intent(inout)
: (inout) 境界条件を適用するチェビシェフデータ(0:km)
values :real(8), dimension(2), intent(in), optional
: (in) 境界値

Neumann/Dirichlet 型境界条件の適用(タウ法, 1 次元配列用) 両境界で勾配の値を与える.

このサブルーチンを直接使うことを勧めない. 共通インターフェース at_Boundaries_NN を用いること.

Original external subprogram is at_module#at_Boundaries_NN

at_Dy_at( at_data ) result(at_Dx_at)
Function :
at_Dx_at :real(8), dimension(size(at_data,1),0:size(at_data,2)-1)
: (out) チェビシェフデータの X 微分
at_data :real(8), dimension(:,0:), intent(in)
: (in) 入力チェビシェフデータ

入力チェビシェフデータに X 微分を作用する(2 次元配列用).

チェビシェフデータの X 微分とは, 対応する格子点データに X 微分を 作用させたデータのチェビシェフ変換のことである.

Original external subprogram is at_module#at_Dx_at

at_ay( ag_data ) result(at_ag)
Function :
at_ag :real(8), dimension(size(ag_data,1),0:km)
: (out) チェビシェフデータ
ag_data :real(8), dimension(:,:), intent(in)
: (in) 格子点データ

格子データからチェビシェフデータへ変換する(2 次元配列用).

Original external subprogram is at_module#at_ag

ax_ae( ae ) result(ag_ae)
Function :
ag_ae :real(DP), dimension(size(ae,1),0:im-1)
: (out) 格子点データ
ae :real(DP), dimension(:,-km:), intent(in)
: (in) スペクトルデータ

スペクトルデータから格子点データへ逆変換する(2 次元データ用)

スペクトル逆変換の定義は以下のとおり.

  スペクトルデータ e_k (k=-km,...,km)
  格子点データ     g_j (j=-0,...,im-1)

 g_j = e_0
     + 2\sum_{k=1}^{km}(e_k\cos(2\pi jk/im) - e_{-k}\sin(2\pi jk/im))
                                                   (j=0,1,...,im-1).

Original external subprogram is ae_module#ag_ae

ay_at( at_data ) result(ag_at)
Function :
ag_at :real(8), dimension(size(at_data,1),0:im)
: (out) 格子点データ
at_data :real(8), dimension(:,:), intent(in)
: (in) チェビシェフデータ

チェビシェフデータから格子データへ変換する(2 次元配列用).

Original external subprogram is at_module#ag_at

e_Dx_e( e ) result(e_Dx_e)
Function :
e_Dx_e :real(DP), dimension(-km:km)
: (out) 入力スペクトルデータの X 微分
e :real(DP), dimension(-km:km), intent(in)
: (in) 入力スペクトルデータ

入力スペクトルデータに X 微分を作用する(1 次元データ).

スペクトルデータの X 微分とは, 対応する格子点データに X 微分を 作用させたデータのスペクトル変換のことである.

Original external subprogram is ae_module#e_Dx_e

e_x( g ) result(e_g)
Function :
e_g :real(DP), dimension(-km:km)
: (out) スペクトルデータ
g :real(DP), dimension(0:im-1), intent(in)
: (in) 格子点データ

格子点データからスペクトルデータへ正変換する(1 次元データ用)

スペクトル正変換の定義は以下のとおり.

  格子点データ     g_j (j=-0,...,im-1)
  スペクトルデータ e_k (k=-km,...,km)

  e_0 = (1/im)\sum_{j=0}^{im-1} g_j
  e_k = (1/im)\sum_{j=0}^{im-1} g_j \cos(2\pi jk/im)       (k=1,2,...,km)
  e_{-k} = - (1/im)\sum_{j=0}^{im-1} g_j \sin(2\pi jk/im)  (k=1,2,...,km)

Original external subprogram is ae_module#e_g

Subroutine :
et :real(8), dimension(-km:km,0:lm),intent(inout)
: 境界条件を適用するデータ. 修正された値を返す.
values :real(8), dimension(-km:km,2), intent(in), optional
: 境界での 値/勾配 分布を水平スペクトル変換したものを与える. 省略時は値/勾配 0 となる.
cond :character(len=2), intent(in), optional
: 境界条件. 省略時は ‘RR‘
  DD : 両端ディリクレ
  DN,ND : ディリクレ/ノイマン条件
  NN : 両端ノイマン

ディリクレ, ノイマン条件の適用. チェビシェフ空間での計算

実際には中で呼ばれている at_module のサブルーチン at_Boundaries_DD, at_Boundaries_DN, at_Boundaries_ND, at_Boundaries_NN を用いている. これらを直接呼ぶことも出来る.

[Source]

    subroutine et_Boundaries(et,values,cond)
      !
      ! ディリクレ, ノイマン条件の適用. チェビシェフ空間での計算
      !
      ! 実際には中で呼ばれている at_module のサブルーチン at_Boundaries_DD,
      ! at_Boundaries_DN, at_Boundaries_ND, at_Boundaries_NN を用いている.
      ! これらを直接呼ぶことも出来る.
      !
      real(8), dimension(-km:km,0:lm),intent(inout)      :: et
              ! 境界条件を適用するデータ. 修正された値を返す.

      real(8), dimension(-km:km,2), intent(in), optional :: values
              ! 境界での 値/勾配 分布を水平スペクトル変換したものを与える.
              ! 省略時は値/勾配 0 となる.

      character(len=2), intent(in), optional             :: cond
              ! 境界条件. 省略時は 'RR'
              !   DD : 両端ディリクレ
              !   DN,ND : ディリクレ/ノイマン条件
              !   NN : 両端ノイマン

      if (.not. present(cond)) then
         if (present(values)) then
            call at_Boundaries_DD(et,values)
         else
            call at_Boundaries_DD(et)
         endif
         return
      endif

      select case(cond)
      case ('NN')
         if (present(values)) then
            call at_Boundaries_NN(et,values)
         else
            call at_Boundaries_NN(et)
         endif
      case ('DN')
         if (present(values)) then
            call at_Boundaries_DN(et,values)
         else
            call at_Boundaries_DN(et)
         endif
      case ('ND')
         if (present(values)) then
            call at_Boundaries_ND(et,values)
         else
            call at_Boundaries_ND(et)
         endif
      case ('DD')
         if (present(values)) then
            call at_Boundaries_DD(et,values)
         else
            call at_Boundaries_DD(et)
         endif
      case default
         call MessageNotify('E','et_Boundaries','B.C. not supported')
      end select

    end subroutine et_Boundaries
Function :
et_Dx_et :real(8), dimension(-km:km,0:lm)
et :real(8), dimension(-km:km,0:lm), intent(in)

入力スペクトルデータに X 微分(∂x)を作用する.

スペクトルデータの X 微分とは, 対応する格子点データに X 微分を 作用させたデータのスペクトル変換のことである.

実際にはスペクトルデータに X 方向波数 k をかけて sin(kx) <-> cos(kx) 成分に入れ換える計算を行っている.

[Source]

    function et_Dx_et(et)
      !
      ! 入力スペクトルデータに X 微分(∂x)を作用する.
      !
      ! スペクトルデータの X 微分とは, 対応する格子点データに X 微分を
      ! 作用させたデータのスペクトル変換のことである.
      !
      ! 実際にはスペクトルデータに X 方向波数 k をかけて
      ! sin(kx) <-> cos(kx) 成分に入れ換える計算を行っている.
      !
      real(8), dimension(-km:km,0:lm)                :: et_Dx_et
      real(8), dimension(-km:km,0:lm), intent(in)    :: et
      integer k

      do k=-km,km
         et_Dx_et(k,:)  =  (-2*pi*k/xl)*et(-k,:)
      enddo
    end function et_Dx_et
Function :
et_Dy_et :real(8), dimension(-km:km,0:lm)
: (out) スペクトルデータの Y 微分
et :real(8), dimension(-km:km,0:lm), intent(in)
: (in) 入力スペクトルデータ

入力スペクトルデータに Y 微分(∂y)を作用する.

スペクトルデータの X 微分とは, 対応する格子点データに Y 微分を 作用させたデータのスペクトル変換のことである.

[Source]

    function et_Dy_et(et)
      !
      ! 入力スペクトルデータに Y 微分(∂y)を作用する.
      !
      ! スペクトルデータの X 微分とは, 対応する格子点データに Y 微分を
      ! 作用させたデータのスペクトル変換のことである.
      !
      real(8), dimension(-km:km,0:lm)               :: et_Dy_et
      !(out) スペクトルデータの Y 微分

      real(8), dimension(-km:km,0:lm), intent(in)   :: et
      !(in) 入力スペクトルデータ

      et_Dy_et = at_Dy_at(et)

    end function et_Dy_et
Subroutine :
i :integer,intent(in)
: 格子点数(X)
j :integer,intent(in)
: 格子点数(Y)
k :integer,intent(in)
: 切断波数(X)
l :integer,intent(in)
: 切断波数(Y)
xmin :real(8),intent(in)
: X 座標範囲
xmax :real(8),intent(in)
: X 座標範囲
ymin :real(8),intent(in)
: Y 座標範囲
ymax :real(8),intent(in)
: Y 座標範囲

スペクトル変換の格子点数, 波数, 領域の大きさを設定する.

他の関数や変数を呼ぶ前に, 最初にこのサブルーチンを呼んで 初期設定をしなければならない.

[Source]

    subroutine et_Initial(i,j,k,l,xmin,xmax,ymin,ymax)
      !
      ! スペクトル変換の格子点数, 波数, 領域の大きさを設定する.
      !
      ! 他の関数や変数を呼ぶ前に, 最初にこのサブルーチンを呼んで
      ! 初期設定をしなければならない.
      !
      integer,intent(in) :: i           ! 格子点数(X)
      integer,intent(in) :: j           ! 格子点数(Y)
      integer,intent(in) :: k           ! 切断波数(X)
      integer,intent(in) :: l           ! 切断波数(Y)

      real(8),intent(in) :: xmin, xmax     ! X 座標範囲
      real(8),intent(in) :: ymin, ymax     ! Y 座標範囲

      im = i       
       jm = j
      km = k       
       lm = l
      xl = xmax-xmin 
       yl = ymax-ymin

      call ae_initial(im,km,xmin,xmax)
      call at_initial(jm,lm,ymin,ymax)

      allocate(yx_X(0:jm,0:im-1),yx_Y(0:jm,0:im-1))
      yx_X = spread(x_X,1,jm+1)
      yx_Y = spread(y_Y,2,im)

      call MessageNotify('M','et_initial','et_module (2013/08/20) is initialized')
    end subroutine et_initial
Function :
et_Jacobian_et_et :real(8), dimension(-km:km,0:lm)
: (out) 2 つのスペクトルデータのヤコビアン
et_a :real(8), dimension(-km:km,0:lm), intent(in)
: (in) 1つ目の入力スペクトルデータ
et_b :real(8), dimension(-km:km,0:lm), intent(in)
: (in) 2つ目の入力スペクトルデータ
 2 つのスペクトルデータからヤコビアン

    J(A,B)=(∂xA)(∂yB)-(∂yA)(∂xB)

 を計算する.

 2 つのスペクトルデータのヤコビアンとは, 対応する 2 つの
 格子点データのヤコビアンのスペクトル変換のことである.

[Source]

    function et_Jacobian_et_et(et_a,et_b)
      !
      !  2 つのスペクトルデータからヤコビアン
      !
      !     J(A,B)=(∂xA)(∂yB)-(∂yA)(∂xB)
      !
      !  を計算する.
      !
      !  2 つのスペクトルデータのヤコビアンとは, 対応する 2 つの
      !  格子点データのヤコビアンのスペクトル変換のことである.
      !
      real(8), dimension(-km:km,0:lm)                :: et_Jacobian_et_et
      !(out) 2 つのスペクトルデータのヤコビアン

      real(8), dimension(-km:km,0:lm), intent(in)    :: et_a
      !(in) 1つ目の入力スペクトルデータ

      real(8), dimension(-km:km,0:lm), intent(in)    :: et_b
      !(in) 2つ目の入力スペクトルデータ

      et_Jacobian_et_et = et_yx( yx_et(et_Dx_et(et_a)) * yx_et(et_Dy_et(et_b)) -yx_et(et_Dy_et(et_a)) * yx_et(et_Dx_et(et_b)) )

    end function et_Jacobian_et_et
Function :
et_LaplaInv_et :real(8), dimension(-km:km,0:lm)
: (out) スペクトルデータの逆ラプラシアン
et :real(8), dimension(-km:km,0:lm),intent(in)
: (in) スペクトルデータ
values :real(8), dimension(-km:km,2), intent(in), optional
: (in) 境界値. 省略時は 0 が設定される.

境界で一様な値を与える条件(ディリクレ条件)下で, 入力スペクトルデータに逆ラプラシアン(∂xx+∂yy)**(-1)を作用する.

Chebyshev-tau 法による計算

スペクトルデータの逆ラプラシアンとは, 対応する格子点データに 逆ラプラシアンを作用させたデータのスペクトル変換のことである.

[Source]

    function et_LaplaInv_et(et,values)
      !
      ! 境界で一様な値を与える条件(ディリクレ条件)下で,
      ! 入力スペクトルデータに逆ラプラシアン(∂xx+∂yy)**(-1)を作用する.
      !
      ! Chebyshev-tau 法による計算
      !
      ! スペクトルデータの逆ラプラシアンとは, 対応する格子点データに
      ! 逆ラプラシアンを作用させたデータのスペクトル変換のことである.
      !
      real(8), dimension(-km:km,0:lm),intent(in)  :: et
      !(in) スペクトルデータ

      real(8), dimension(-km:km,0:lm)             :: et_LaplaInv_et
      !(out) スペクトルデータの逆ラプラシアン

      real(8), dimension(-km:km,2), intent(in), optional :: values
      !(in) 境界値. 省略時は 0 が設定される.

      real(8), dimension(:,:,:), allocatable  :: alu
      integer, dimension(:,:), allocatable    :: kp

      real(8), dimension(-km:km,0:lm)         :: et_work
      real(8), dimension(-km:km,0:jm)         :: ey_work
      real(8), dimension(-km:km)              :: value1, value2   ! 境界値

      logical :: first = .true.
      integer :: l
      save    :: alu, kp, first

      if (.not. present(values)) then
         value1=0.0D0 
          value2=0.0D0
      else
         value1 = values(:,1) 
          value2 = values(:,2)
      endif

      if ( first ) then
         first = .false.

         allocate(alu(-km:km,0:lm,0:lm),kp(-km:km,0:lm))

         do l=0,lm
            et_work=0.0D0 
             et_work(:,l) = 1.0D0
            alu(:,:,l) = et_Lapla_et(et_work)

            ey_work = ay_at(et_work)
            alu(:,lm-1,l) = ey_work(:,0)
            alu(:,lm,l)   = ey_work(:,jm)
         enddo

         call ludecomp(alu,kp)
      endif

      et_work = et
      et_work(:,lm-1) = value1
      et_work(:,lm)   = value2
      et_LaplaInv_et = lusolve(alu,kp,et_work)

    end function et_LaplaInv_et
Function :
et_Lapla_et :real(8), dimension(-km:km,0:lm)
: (out) スペクトルデータのラプラシアン
et :real(8), dimension(-km:km,0:lm), intent(in)
: (in) 入力スペクトルデータ

入力スペクトルデータにラプラシアン(∂xx+∂yy)を作用する.

スペクトルデータのラプラシアンとは, 対応する格子点データに ラプラシアンを作用させたデータのスペクトル変換のことである.

[Source]

    function et_Lapla_et(et)
      !
      ! 入力スペクトルデータにラプラシアン(∂xx+∂yy)を作用する.
      !
      ! スペクトルデータのラプラシアンとは, 対応する格子点データに
      ! ラプラシアンを作用させたデータのスペクトル変換のことである.
      !
      real(8), dimension(-km:km,0:lm)                :: et_Lapla_et
      !(out) スペクトルデータのラプラシアン

      real(8), dimension(-km:km,0:lm), intent(in)    :: et
      !(in) 入力スペクトルデータ

      integer k

      do k=-km,km
         et_Lapla_et(k,:) = -(2*pi*k/xl)**2*et(k,:)
      enddo

      et_Lapla_et = et_Lapla_et + et_Dy_et(et_Dy_et(et))

    end function et_Lapla_et
Function :
et_Vor2Strm_et :real(8), dimension(-km:km,0:lm)
: (out) 出力流線分布
et :real(8), dimension(-km:km,0:lm),intent(in)
: (in) 入力渦度分布
values :real(8), dimension(2), intent(in), optional
: (in) 流線境界値. 境界で一定なので波数 0 成分のみ
    省略時は 0.
cond :character(len=2), intent(in), optional
: (in) 境界条件スイッチ. 省略時は ‘RR‘
     RR : 両端粘着条件
     RF : 上端粘着下端応力なし条件
     FR : 上端応力なし下端粘着条件
     FF : 両端応力なし条件
new :logical, intent(IN), optional
: (in) true だと境界条件計算用行列を強制的に新たに作る.
    default は false.

渦度から流線を求める.

渦度から流線を求める.

Chebyshev-tau 法 + Crank Nicolson 法による計算 渦度 zeta を与えて流線 psi を求める.

   \nabla^2\psi = \zeta,
   \psi = const. at boundaries.

粘着条件

   \DP{\psi}{y} = 0 at boundaries

応力なし条件

   \DP[2]{\psi}{y} = 0 at boundaries

[Source]

    function et_Vor2Strm_et(et,values,cond,new)    ! 渦度から流線を求める.
      !
      ! 渦度から流線を求める.
      !
      ! Chebyshev-tau 法 + Crank Nicolson 法による計算
      ! 渦度 \zeta を与えて流線 \psi を求める.
      !    \nabla^2\psi = \zeta, 
      !    \psi = const. at boundaries.
      ! 粘着条件
      !    \DP{\psi}{y} = 0 at boundaries
      ! 応力なし条件
      !    \DP[2]{\psi}{y} = 0 at boundaries
      !
      real(8), dimension(-km:km,0:lm),intent(in)  :: et
              !(in) 入力渦度分布

      real(8), dimension(-km:km,0:lm)             :: et_Vor2Strm_et
              !(out) 出力流線分布

      real(8), dimension(2), intent(in), optional :: values
              !(in) 流線境界値. 境界で一定なので波数 0 成分のみ
              !     省略時は 0.

      character(len=2), intent(in), optional  :: cond
              ! (in) 境界条件スイッチ. 省略時は 'RR'
              !      RR : 両端粘着条件
              !      RF : 上端粘着下端応力なし条件
              !      FR : 上端応力なし下端粘着条件
              !      FF : 両端応力なし条件

      logical, intent(IN), optional :: new
              !(in) true だと境界条件計算用行列を強制的に新たに作る.
              !     default は false.

      real(8), dimension(:,:,:), allocatable  :: alu
      integer, dimension(:,:), allocatable    :: kp

      real(8), dimension(-km:km,0:lm)         :: et_work
      real(8), dimension(-km:km,0:jm)         :: ey_work
      real(8)                                 :: value1, value2   ! 境界値
      logical                                 :: rigid1, rigid2   ! 境界条件

      logical :: first = .true.
      logical :: new_matrix = .false.
      integer :: l
      save    :: alu, kp, first

      if (.not. present(values)) then
         value1=0.0D0 
          value2=0.0D0
      else
         value1 = values(1) 
          value2 = values(2)
      endif

      if ( present(cond) ) then
         select case (cond)
         case ('RR')
           rigid1 = .TRUE.  
            rigid2 = .TRUE.
         case ('RF')
           rigid1 = .TRUE.  
            rigid2 = .FALSE.
         case ('FR')
           rigid1 = .FALSE. 
            rigid2 = .TRUE.
         case ('FF')
           rigid1 = .FALSE. 
            rigid2 = .FALSE.
         case default
           call MessageNotify('E','et_Vor2Strm_et','B.C. not supported')
         end select
      else
         rigid1 = .TRUE.  
          rigid2 = .TRUE.
      endif

      if (.not. present(new)) then
         new_matrix=.false.
      else
         new_matrix=new
      endif

      if ( first .OR. new_matrix ) then
         first = .false.

         if ( allocated(alu) ) deallocate(alu)
         if ( allocated(kp) ) deallocate(kp)
         allocate(alu(-km:km,0:lm,0:lm),kp(-km:km,0:lm))

         alu = 0.0D0
         do l=0,lm-2
            et_work(:,:)= 0.0D0
            et_work(:,l)= 1.0D0

            alu(:,:,l) = et_Lapla_et(et_work)
         enddo

         do l=0,lm
            et_work(:,:)= 0.0D0
            et_work(:,l)= 1.0D0

            ! 運動学的条件. 流線は境界で一定
            ey_work = ay_at(et_work)
            alu(:,lm,l) = ey_work(:,0)
            alu(:,lm-1,l) = ey_work(:,jm)

            if ( rigid1 ) then                   ! 力学的条件粘着条件(Top)
               ey_work=ay_at(et_Dy_et(et_work))
               alu(:,lm-2,l) = ey_work(:,0)
            else                                 ! 力学的条件すべり条件(Top)
               ey_work=ay_at(et_Dy_et(et_Dy_et(et_work)))
               alu(:,lm-2,l) = ey_work(:,0)
            endif
            if ( rigid2 ) then                   ! 力学的条件粘着条件(bottom)
               ey_work=ay_at(et_Dy_et(et_work))
               alu(:,lm-3,l) = ey_work(:,jm)
            else                                 ! 力学的条件すべり条件(bottom)
               ey_work=ay_at(et_Dy_et(et_Dy_et(et_work)))
               alu(:,lm-3,l) = ey_work(:,jm)
            endif
         enddo

         call ludecomp(alu,kp)

         call MessageNotify('M','et_Vor2Strm_et', 'Matrix for stream func. calc. produced')
      endif

      ! 内部領域計算
      et_work = et

      et_work(:,lm-2) = 0.0D0           ! 力学的条件
      et_work(:,lm-3) = 0.0D0           ! 力学的条件

      et_work(:,lm-1) = 0.0D0        ! 運動学的条件. 波数 0 以外は 0
      et_work(0,lm-1) = value1*2     ! 運動学的条件. 波数 0 は重み 1/2

      et_work(:,lm)   = 0.0D0        ! 運動学的条件. 波数 0 以外は 0
      et_work(0,lm)   = value2*2     ! 運動学的条件. 波数 0 は重み 1/2

      et_Vor2Strm_et = lusolve(alu,kp,et_work)

    end function et_Vor2Strm_et
Function :
et_ey :real(8), dimension(-km:km,0:lm)
: (out) スペクトルデータ
ey :real(8), dimension(-km:km,0:jm), intent(in)
: (in) 格子点データ

Y 座標の格子データからスペクトルデータへ変換する.

[Source]

    function et_ey(ey)
      !
      ! Y 座標の格子データからスペクトルデータへ変換する.
      !
      real(8), dimension(-km:km,0:lm)              :: et_ey
      !(out) スペクトルデータ

      real(8), dimension(-km:km,0:jm), intent(in)  :: ey
      !(in) 格子点データ

      et_ey = at_ay(ey)

    end function et_ey
Function :
et_yx :real(8), dimension(-km:km,0:lm)
: (out) スペクトルデータ
yx :real(8), dimension(0:jm,0:im-1), intent(in)
: (in) 格子点データ

格子データからスペクトルデータへ変換する.

[Source]

    function et_yx(yx)
      !
      ! 格子データからスペクトルデータへ変換する.
      !
      real(8), dimension(-km:km,0:lm)              :: et_yx
      !(out) スペクトルデータ

      real(8), dimension(0:jm,0:im-1), intent(in)  :: yx
      !(in) 格子点データ

      real(8), dimension(-km:km,0:jm)              :: ey
      real(8), dimension(0:jm,-km:km)              :: ye

      integer :: j, k

      !et_yx = at_ay(transpose(ae_ax(yx)))
      !
      ! 本来上の書き方でいいはずだが, gfortran で通らないので下のように書き直す
      !
      ye = ae_ax(yx)
      do j=0,jm
         do k=-km,km
            ey(k,j) = ye(j,k) 
         enddo
      enddo
      et_yx = at_ay(ey)

    end function et_yx
Function :
ey_Vor2Strm_ey :real(8), dimension(-km:km,0:jm)
: (out) 出力流線分布
ey :real(8), dimension(-km:km,0:jm),intent(in)
: (in) 入力渦度分布
values :real(8), dimension(2), intent(in), optional
: (in) 流線境界値. 境界で一定なので波数 0 成分のみ
    省略時は 0.
cond :character(len=2), intent(in), optional
: (in) 境界条件スイッチ. 省略時は ‘RR‘
     RR : 両端粘着条件
     RF : 上端粘着下端応力なし条件
     FR : 上端応力なし下端粘着条件
     FF : 両端応力なし条件
new :logical, intent(IN), optional
: (in) true だと境界条件計算用行列を強制的に新たに作る.
    default は false.

渦度から流線を求める.

渦度から流線を求める. Y 方向格子点空間での Chebyshev-Collocation 法による計算

渦度 zeta を与えて流線 psi を求める.

   \nabla^2 \psi = \zeta,
   \psi = const. at boundaries.

粘着条件

   \DP{\psi}{y} = 0 at boundaries

応力なし条件

   \DP[2]{\psi}{y} = 0 at boundaries

[Source]

    function ey_Vor2Strm_ey(ey,values,cond,new)    ! 渦度から流線を求める.
      !
      ! 渦度から流線を求める.
      ! Y 方向格子点空間での Chebyshev-Collocation 法による計算
      !
      ! 渦度 \zeta を与えて流線 \psi を求める.
      !    \nabla^2 \psi = \zeta,
      !    \psi = const. at boundaries.
      ! 粘着条件
      !    \DP{\psi}{y} = 0 at boundaries
      ! 応力なし条件
      !    \DP[2]{\psi}{y} = 0 at boundaries
      !

      real(8), dimension(-km:km,0:jm),intent(in)  :: ey
              !(in) 入力渦度分布

      real(8), dimension(-km:km,0:jm)             :: ey_Vor2Strm_ey
              !(out) 出力流線分布

      real(8), dimension(2), intent(in), optional :: values
              !(in) 流線境界値. 境界で一定なので波数 0 成分のみ
              !     省略時は 0.

      character(len=2), intent(in), optional  :: cond
              ! (in) 境界条件スイッチ. 省略時は 'RR'
              !      RR : 両端粘着条件
              !      RF : 上端粘着下端応力なし条件
              !      FR : 上端応力なし下端粘着条件
              !      FF : 両端応力なし条件

      logical, intent(IN), optional :: new
              !(in) true だと境界条件計算用行列を強制的に新たに作る.
              !     default は false.

      real(8), dimension(:,:,:), allocatable  :: alu
      integer, dimension(:,:), allocatable    :: kp

      real(8), dimension(-km:km,0:jm)         :: ey_work
      real(8), dimension(-km:km,0:jm)         :: ey_I
      real(8)                                 :: value1, value2   ! 境界値
      logical                                 :: rigid1 = .true.
      logical                                 :: rigid2 = .true.

      logical :: first = .true.
      logical :: new_matrix = .false.
      integer :: j
      save    :: alu, kp, first

      if (.not. present(values)) then
        value1=0.0D0 
         value2=0.0D0
      else
        value1 = values(1) 
         value2 = values(2)
      endif

      if ( present(cond) ) then
         select case (cond)
         case ('RR')
            rigid1 = .TRUE.  
             rigid2 = .TRUE.
         case ('RF')
            rigid1 = .TRUE.  
             rigid2 = .FALSE.
         case ('FR')
            rigid1 = .FALSE. 
             rigid2 = .TRUE.
         case ('FF')
            rigid1 = .FALSE. 
             rigid2 = .FALSE.
         case default
            call MessageNotify('E','ey_Vor2Strm_ey','B.C. not supported')
         end select
      else
         rigid1 = .TRUE.  
          rigid2 = .TRUE.
      endif

      if (.not. present(new)) then
         new_matrix=.false.
      else
         new_matrix=new
      endif

      if ( first .OR. new_matrix ) then
         first = .false.

         if ( allocated(alu) ) deallocate(alu)
         if ( allocated(kp) ) deallocate(kp)
         allocate(alu(-km:km,0:jm,0:jm),kp(-km:km,0:jm))

         do j=0,jm
            ey_I = 0 
             ey_I(:,j) = 1.0D0
            alu(:,:,j) = ey_et(et_Lapla_et(et_ey(ey_I)))
         enddo

         do j=0,jm
            ey_I = 0
            ey_I(:,j) = 1.0D0

            ! 運動学的条件. 流線は境界で一定
            alu(:,0,j)   = ey_I(:,0)
            alu(:,jm,j)  = ey_I(:,jm)

            if ( rigid1 ) then                               ! 粘着条件(top)
               ey_work=ey_et(et_Dy_et(et_ey(ey_I)))
            else
               ey_work=ey_et(et_Dy_et(et_Dy_et(et_ey(ey_I))))  ! すべり条件(top)
            endif

            alu(:,1,j) = ey_work(:,0)

            if ( rigid2 ) then                               ! 粘着条件(bottom)
               ey_work=ey_et(et_Dy_et(et_ey(ey_I)))
            else
               ey_work=ey_et(et_Dy_et(et_Dy_et(et_ey(ey_I))))  ! すべり条件(bottom)
            endif
            alu(:,jm-1,j) = ey_work(:,jm)
         enddo

         call ludecomp(alu,kp)

         call MessageNotify('M','ey_Vor2Strm_ey', 'Matrix for stream func. calc. produced')
      endif

      ey_work = ey
      ey_work(:,1)    = 0.0D0               ! 力学的条件
      ey_work(:,jm-1) = 0.0D0               ! 力学的条件

      ey_work(:,0) = 0.0D0                  ! 運動学的条件. 波数 0 以外は 0
      ey_work(0,0) = value1*2.0D0           ! 運動学的条件. 波数 0 は重み 1/2

      ey_work(:,jm)   = 0.0D0               ! 運動学的条件. 波数 0 以外は 0
      ey_work(0,jm)   = value2*2.0D0        ! 運動学的条件. 波数 0 は重み 1/2

      ey_Vor2Strm_ey = lusolve(alu,kp,ey_work)

    end function ey_Vor2Strm_ey
Function :
ey_et :real(8), dimension(-km:km,0:jm)
: (out) 格子点データ
et :real(8), dimension(-km:km,0:lm), intent(in)
: (in) スペクトルデータ

Y 座標スペクトルデータから格子データへ変換する.

[Source]

    function ey_et(et)
      !
      ! Y 座標スペクトルデータから格子データへ変換する.
      !
      real(8), dimension(-km:km,0:jm)              :: ey_et
      !(out) 格子点データ

      real(8), dimension(-km:km,0:lm), intent(in)  :: et
      !(in) スペクトルデータ

      ey_et = ay_at(et)

    end function ey_et
Function :
ey_yx :real(8), dimension(-km:km,0:jm)
: (out) スペクトルデータ
yx :real(8), dimension(0:jm,0:im-1), intent(in)
: (in) 格子点データ

X 座標格子データからスペクトルデータへ変換する.

[Source]

    function ey_yx(yx)
      !
      ! X 座標格子データからスペクトルデータへ変換する.
      !
      real(8), dimension(-km:km,0:jm)              :: ey_yx
      !(out) スペクトルデータ

      real(8), dimension(0:jm,0:im-1), intent(in)  :: yx
      !(in) 格子点データ

      real(8), dimension(0:jm,-km:km)              :: ye

      integer :: j, k

      !ey_yx = transpose(ae_ax(yx))
      !
      ! 本来上の書き方でいいはずだが, gfortran で通らないので下のように書き直す
      !
      ye = ae_ax(yx)
      do j=0,jm
         do k=-km,km
            ey_yx(k,j) = ye(j,k) 
         enddo
      enddo

    end function ey_yx
t_Dy_t( t_data ) result(t_Dx_t)
Function :
t_Dx_t :real(8), dimension(size(t_data))
: (out) チェビシェフデータの X 微分
t_data :real(8), dimension(:), intent(in)
: (in) 入力チェビシェフデータ

入力チェビシェフデータに X 微分を作用する(1 次元配列用).

チェビシェフデータの X 微分とは, 対応する格子点データに X 微分を 作用させたデータのチェビシェフ変換のことである.

Original external subprogram is at_module#t_Dx_t

t_y( g_data ) result(t_g)
Function :
t_g :real(8), dimension(0:km)
: (out) チェビシェフデータ
g_data :real(8), dimension(:), intent(in)
: (in) 格子点データ

台形格子 -> スペクトル

格子データからチェビシェフデータへ変換する(1 次元配列用).

Original external subprogram is at_module#t_g

Function :
x_AvrY_yx :real(8), dimension(0:im-1)
: (out) 平均された 1 次元(X)格子点
yx :real(8), dimension(0:jm,0:im-1)
: (in) 2 次元格子点データ

2 次元格子点データの Y 方向平均

実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算し, y_Y_Weight の総和で割ることで平均している.

[Source]

    function x_AvrY_yx(yx)
      !
      ! 2 次元格子点データの Y 方向平均
      !
      ! 実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算し,
      ! y_Y_Weight の総和で割ることで平均している.
      !
      real(8), dimension(0:jm,0:im-1)   :: yx
      !(in) 2 次元格子点データ

      real(8), dimension(0:im-1)        :: x_AvrY_yx
      !(out) 平均された 1 次元(X)格子点

      x_AvrY_yx = x_IntY_yx(yx)/sum(y_Y_weight)
    end function x_AvrY_yx
Function :
x_IntY_yx :real(8), dimension(0:im-1)
: (out) 積分された 1 次元(X)格子点データ
yx :real(8), dimension(0:jm,0:im-1)
: (in) 2 次元格子点データ

Y 方向積分

2 次元格子点データの Y 方向積分

実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算している.

[Source]

    function x_IntY_yx(yx)  ! Y 方向積分
      !
      ! 2 次元格子点データの Y 方向積分
      !
      ! 実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算している.
      !
      real(8), dimension(0:jm,0:im-1)   :: yx
      !(in)  2 次元格子点データ

      real(8), dimension(0:im-1)        :: x_IntY_yx
      !(out) 積分された 1 次元(X)格子点データ

      integer :: j
      ! 作業変数

      x_IntY_yx = 0.0d0
      do j=0,jm
         x_IntY_yx(:) = x_IntY_yx(:) + yx(j,:) * y_Y_Weight(j)
      enddo
    end function x_IntY_yx
x_X
Variable :
g_X(:) :real(8), allocatable
: 格子点座標 km 次のチェビシェフ多項式の零点から定まる格子点

Original external subprogram is at_module#g_X

x_X
Variable :
g_x(:) :real(DP), allocatable
: 格子点座標(X)を格納した 1 次元配列.

Original external subprogram is ae_module#g_x

x_X_weight
Variable :
g_X_Weight(:) :real(8), allocatable
: 格子点重み座標 各格子点における積分のための重みが格納してある

Original external subprogram is at_module#g_X_Weight

x_X_weight
Variable :
g_x_weight(:) :real(DP), allocatable
: 重み座標を格納した 1 次元配列. X 方向の格子点の間隔が格納してある.

Original external subprogram is ae_module#g_x_weight

x_e( e ) result(g_e)
Function :
g_e :real(DP), dimension(0:im-1)
: (out) 格子点データ
e :real(DP), dimension(-km:km), intent(in)
: (in) スペクトルデータ

スペクトルデータから格子点データへ逆変換する(1 次元データ用)

スペクトル逆変換の定義は以下のとおり.

  スペクトルデータ e_k (k=-km,...,km)
  格子点データ     g_j (j=-0,...,im-1)

 g_j = e_0
     + 2\sum_{k=1}^{km}(e_k\cos(2\pi jk/im) - e_{-k}\sin(2\pi jk/im))
                                                   (j=0,1,...,im-1).

Original external subprogram is ae_module#g_e

Function :
y_AvrX_yx :real(8), dimension(0:jm)
: (out) 平均された 1 次元(Y)格子点
yx :real(8), dimension(0:jm,0:im-1)
: (in) 2 次元格子点データ

2 次元格子点データの X 方向平均

実際には格子点データ各点毎に x_X_Weight をかけた総和を計算し, x_X_Weight の総和で割ることで平均している.

[Source]

    function y_AvrX_yx(yx)
      !
      ! 2 次元格子点データの X 方向平均
      !
      ! 実際には格子点データ各点毎に x_X_Weight をかけた総和を計算し,
      ! x_X_Weight の総和で割ることで平均している.
      !
      real(8), dimension(0:jm,0:im-1)   :: yx
      !(in) 2 次元格子点データ

      real(8), dimension(0:jm)          :: y_AvrX_yx
      !(out) 平均された 1 次元(Y)格子点

      y_AvrX_yx = y_IntX_yx(yx)/sum(x_X_weight)
    end function y_AvrX_yx
Function :
y_IntX_yx :real(8), dimension(0:jm)
: (out) 積分された 1 次元(Y)格子点データ
yx :real(8), dimension(0:jm,0:im-1)
: (in) 2 次元格子点データ

X 方向積分

2 次元格子点データの X 方向積分

実際には格子点データ各点毎に x_X_Weight をかけた総和を計算している.

[Source]

    function y_IntX_yx(yx)  ! X 方向積分
      !
      ! 2 次元格子点データの X 方向積分
      !
      ! 実際には格子点データ各点毎に x_X_Weight をかけた総和を計算している.
      !
      real(8), dimension(0:jm,0:im-1)   :: yx
      !(in) 2 次元格子点データ

      real(8), dimension(0:jm)          :: y_IntX_yx
      !(out) 積分された 1 次元(Y)格子点データ

      integer :: i
      ! 作業変数

      y_IntX_yx = 0.0d0
      do i=0,im-1
         y_IntX_yx(:) = y_IntX_yx(:) + yx(:,i) * x_X_Weight(i)
      enddo
    end function y_IntX_yx
y_Y
Variable :
g_X(:) :real(8), allocatable
: 格子点座標 km 次のチェビシェフ多項式の零点から定まる格子点

Original external subprogram is at_module#g_X

y_Y
Variable :
g_x(:) :real(DP), allocatable
: 格子点座標(X)を格納した 1 次元配列.

Original external subprogram is ae_module#g_x

y_Y_Weight
Variable :
g_X_Weight(:) :real(8), allocatable
: 格子点重み座標 各格子点における積分のための重みが格納してある

Original external subprogram is at_module#g_X_Weight

y_Y_Weight
Variable :
g_x_weight(:) :real(DP), allocatable
: 重み座標を格納した 1 次元配列. X 方向の格子点の間隔が格納してある.

Original external subprogram is ae_module#g_x_weight

y_t( t_data ) result(g_t)
Function :
g_t :real(8), dimension(0:im)
: (out) 格子点データ
t_data :real(8), dimension(:), intent(in)
: (in) チェビシェフデータ

チェビシェフデータから格子データへ変換する(1 次元配列用).

Original external subprogram is at_module#g_t

yx_X
Variable :
yx_X :real(8), dimension(:,:), allocatable
yx_Y
Variable :
yx_Y :real(8), dimension(:,:), allocatable
Function :
yx_et :real(8), dimension(0:jm,0:im-1)
: (out) 格子点データ
et :real(8), dimension(-km:km,0:lm), intent(in)
: (in) スペクトルデータ

スペクトルデータから格子データへ変換する.

[Source]

    function yx_et(et)
      !
      ! スペクトルデータから格子データへ変換する.
      !
      real(8), dimension(0:jm,0:im-1)              :: yx_et
      !(out) 格子点データ

      real(8), dimension(-km:km,0:lm), intent(in)  :: et
      !(in) スペクトルデータ

      real(8), dimension(-km:km,0:jm)              :: ey
      real(8), dimension(0:jm,-km:km)              :: ye

      integer :: j, k
      
      !yx_et = ax_ae(transpose(ay_at(et)))
      !
      ! 本来上の書き方でいいはずだが, gfortran で通らないので下のように書き直す
      !
      ey = ay_at(et)
      do j=0,jm
         do k=-km,km
            ye(j,k) = ey(k,j)
         enddo
      enddo
      yx_et = ax_ae(ye)

    end function yx_et
Function :
yx_ey :real(8), dimension(0:jm,0:im-1)
: (out) 格子点データ
ey :real(8), dimension(-km:km,0:jm), intent(in)
: (in) スペクトルデータ

X 座標スペクトルデータから格子データへ変換する.

[Source]

    function yx_ey(ey)
      !
      ! X 座標スペクトルデータから格子データへ変換する.
      !
      real(8), dimension(0:jm,0:im-1)              :: yx_ey
      !(out) 格子点データ

      real(8), dimension(-km:km,0:jm), intent(in)  :: ey
      !(in) スペクトルデータ

      real(8), dimension(0:jm,-km:km)              :: ye

      integer :: j, k
      
      !yx_ey = ax_ae(transpose(ey))
      !
      ! 本来上の書き方でいいはずだが, gfortran で通らないので下のように書き直す
      !
      do j=0,jm
         do k=-km,km
            ye(j,k) = ey(k,j)
         enddo
      enddo
      yx_ey = ax_ae(ye)

    end function yx_ey