Class | at_af_galerkin_MM |
In: |
libsrc/at_galerkin_module/at_af_galerkin_MM.f90
|
Authors: | Shin-ichi Takehiro, Youhei SASAKI |
Version: | $Id: at_af_galerkin_MM.f90 590 2013-08-19 08:48:21Z uwabami $ |
Copyright&License: | See COPYRIGHT |
spml/at_af_galerkin_MM モジュールはチェビシェフ−ガラーキン法, ディリクレ・ノイマン混合境界条件
cfdx1_xmax f'(:,i=0) + cfdx0_xmax f(:,i=0) = 0, cfdx1_xmin f'(:,i=im) + cfdx0_xmin f(:,i=im) = 0,
を k 次のガラーキン基底が
\phi_k(x)=T_k(x) + C_1 T_1(x) + C_0 T_0(x)
の型式(Type2)を用いて計算するためのモジュールである.
定式化については解説文書「チェビシェフ関数展開を利用したガラーキン法」 (cheb_gal.pdf)を参照のこと.
Function : | |||
af_Dx_af(size(af_data,1),ks:km) : | real(8)
| ||
af_data(:,ks:) : | real(8), intent(IN)
|
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件
X 微分計算(2 次元)
function af_Dx_af(af_data) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件 ! ! X 微分計算(2 次元) ! real(8), intent(IN) :: af_data(:,ks:) !(in) ガラーキン係数 real(8) :: af_Dx_af(size(af_data,1),ks:km) !(out) 微分ガラーキン af_Dx_af = af_at(at_Dx_at(at_af(af_data))) end function af_Dx_af
Function : | |||
af_ag(size(ag_data,1),ks:km) : | real(8)
| ||
ag_data(:,0:) : | real(8), intent(IN)
|
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件
格子点データ -> ガラーキン係数変換(2次元データ)
function af_ag(ag_data) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件 ! ! 格子点データ -> ガラーキン係数変換(2次元データ) ! real(8), intent(IN) :: ag_data(:,0:) !(in) 格子点データ real(8) :: af_ag(size(ag_data,1),ks:km) !(out) ガラーキン係数 af_ag = af_at(at_ag(ag_data)) end function af_ag
Function : | |||
af_at(size(at_data,1),ks:km) : | real(8)
| ||
at_data(:,0:) : | real(8), intent(IN)
|
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件
チェビシェフ係数 -> ガラーキン係数変換(2次元データ)
function af_at(at_data) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件 ! ! チェビシェフ係数 -> ガラーキン係数変換(2次元データ) ! real(8), intent(IN) :: at_data(:,0:) !(in) チェビシェフ係数 real(8) :: af_at(size(at_data,1),ks:km) !(out) ガラーキン係数 real(8) :: af_work(size(at_data,1),ks:km) ! 作業用配列 integer :: k,m if ( .not. MM_Initialized ) call MessageNotify('E','af_at', 'at_af_galerkin_MM_module not initialized') af_work =0.0 do m=ks,km do k=0,km af_work(:,m) = af_work(:,m) + alpha(k) * beta(k) * at_data(:,k) * TF(k,m) enddo enddo af_at = LUSolve(FT,kp,af_work) end function af_at
Function : | |||
ag_af(size(af_data,1),0:im) : | real(8)
| ||
af_data(:,ks:) : | real(8), intent(IN)
|
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件
ガラーキン係数 -> 格子点データ変換(2次元データ)
function ag_af(af_data) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件 ! ! ガラーキン係数 -> 格子点データ変換(2次元データ) ! real(8), intent(IN) :: af_data(:,ks:) !(in) ガラーキン係数 real(8) :: ag_af(size(af_data,1),0:im) !(out) 格子点データ ag_af = ag_at(at_af(af_data)) end function ag_af
Function : | |||
at_af(size(af_data,1),0:km) : | real(8)
| ||
af_data(:,ks:) : | real(8), intent(IN)
|
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件
ガラーキン係数 -> チェビシェフ係数変換(2次元データ)
function at_af(af_data) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件 ! ! ガラーキン係数 -> チェビシェフ係数変換(2次元データ) ! real(8), intent(IN) :: af_data(:,ks:) !(in) ガラーキン係数 real(8) :: at_af(size(af_data,1),0:km) !(out) チェビシェフ係数 integer :: m, n if ( .not. MM_Initialized ) call MessageNotify('E','at_af', 'at_af_galerkin_MM_module not initialized') at_af = 0.0D0 do m=0,km do n=ks,km at_af(:,m) = at_af(:,m) + TF(m,n)*af_data(:,n)/beta(m) enddo enddo end function at_af
Subroutine : | |||
i_in : | integer, intent(IN)
| ||
k_in : | integer, intent(IN)
| ||
cfdx0_xmax : | real(8), intent(IN),optional
| ||
cfdx1_xmax : | real(8), intent(IN),optional
| ||
cfdx0_xmin : | real(8), intent(IN),optional
| ||
cfdx1_xmin : | real(8), intent(IN),optional
|
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件用モジュール
初期化サブルーチン
subroutine at_af_galerkin_MM_Initial(i_in,k_in, cfdx0_xmax,cfdx1_xmax, cfdx0_xmin,cfdx1_xmin ) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件用モジュール ! ! 初期化サブルーチン ! integer, intent(IN) :: i_in ! (in)格子点数 integer, intent(IN) :: k_in ! (in)チェビシェフ切断波数 real(8), intent(IN),optional :: cfdx0_xmin ! 境界条件係数(0階微分@x=xmin) real(8), intent(IN),optional :: cfdx1_xmin ! 境界条件係数(1階微分@x=xmin) real(8), intent(IN),optional :: cfdx0_xmax ! 境界条件係数(0階微分@x=xmax) real(8), intent(IN),optional :: cfdx1_xmax ! 境界条件係数(1階微分@x=xmax) real(8) :: Dfac ! 微分変換係数 real(8) :: Delta ! 係数行列の行列式 real(8) :: a, b, c, d, e, f integer :: k, l, m, n !---------- 格子点数・切断波数設定 ---------- im=i_in km=k_in !---------- 境界条件係数設定 ---------- Dfac = (g_X(0)-g_X(im))/2.0D0 if( present(cfdx0_xmin) ) then cfd0_xmin = cfdx0_xmin else call MessageNotify('M','at_af_galerkin_MM_Initial', 'cfdx0_xmin set to zero internally.') cfd0_xmin = 0.0D0 endif if( present(cfdx0_xmax) ) then cfd0_xmax = cfdx0_xmax else call MessageNotify('M','at_af_galerkin_MM_Initial', 'cfdx0_xmax set to zero internally.') cfd0_xmax = 0.0D0 endif if( present(cfdx1_xmin) ) then cfd1_xmin = cfdx1_xmin/Dfac else call MessageNotify('M','at_af_galerkin_MM_Initial', 'cfdx1_xmin set to zero internally.') cfd1_xmin = 0.0D0 endif if( present(cfdx1_xmax) ) then cfd1_xmax = cfdx1_xmax/Dfac else call MessageNotify('M','at_af_galerkin_MM_Initial', 'cfdx1_xmax set to zero internally.') cfd1_xmax = 0.0D0 endif !---------- 境界条件係数チェック ---------- Delta = cfd1_xmin*cfd0_xmax-cfd1_xmax*cfd0_xmin -2 * cfd0_xmin*cfd0_xmax if ( abs(Delta) /max(abs(cfd1_xmin),abs(cfd0_xmin),abs(cfd1_xmax),abs(cfd0_xmax)) .LT. EPS ) then MM_Delta0 = .true. call MessageNotify('W','at_af_galerkin_MM_Initial', 'Determinant of coefficent matrix equals zero.' ) call MessageNotify('M','at_af_galerkin_MM_Initial', 'T2 and T1 are used for Galerkin base functions' ) else MM_Delta0 = .false. endif !---------- ディリクレ・ノイマン混合条件用変換行列設定 ---------- if ( allocated(TF) ) deallocate(TF) if ( allocated(FT) ) deallocate(FT) if ( allocated(kp) ) deallocate(kp) if ( allocated(alpha) ) deallocate(alpha) if ( allocated(beta) ) deallocate(beta) allocate(TF(0:km,ks:km),FT(ks:km,ks:km),kp(ks:km)) allocate(alpha(0:km),beta(0:km)) TF = 0.0D0 if ( MM_Delta0 ) then a = 4 * cfd1_xmax + cfd0_xmax b = cfd1_xmax + cfd0_xmax c = -4 * cfd1_xmin + cfd0_xmin d = cfd1_xmin - cfd0_xmin Delta = a*d - b*c TF(0,2) = cfd1_xmax + cfd0_xmax TF(1,2) = -cfd0_xmax do k=ks+1,km e = cfd1_xmax * k**2 + cfd0_xmax f = cfd1_xmin * (-1)**(k+1) * k**2 + cfd0_xmin*(-1)**k TF(1,k) = -1.0D0/Delta*(-c*e+a*f) TF(2,k) = -1.0D0/Delta*(d*e-b*f) TF(k,k) = 1.0D0 enddo else do k=ks,km TF(0,k) = 1.0D0/Delta * ( (-cfd1_xmin+cfd0_xmin)*(cfd1_xmax*k**2+cfd0_xmax) + (cfd1_xmax+cfd0_xmax) *( cfd1_xmin*(-1)**(k+1)*k**2 + (-1)**k*cfd0_xmin ) ) TF(1,k) = 1.0D0/Delta * ( cfd0_xmin*(cfd1_xmax*k**2+cfd0_xmax) - cfd0_xmax*( cfd1_xmin*(-1)**(k+1)*k**2 + (-1)**k*cfd0_xmin ) ) TF(k,k) = 1.0D0 enddo endif beta=1.0 beta(0)=0.5D0 if (im .eq. km ) beta(km)=0.5D0 ! ディリクレ・ノイマン混合条件用変換逆行列 alpha=1.0 alpha(0)=2.0D0 FT = 0.0D0 do m=ks,km do n=ks,km do l=0,km FT(m,n) = FT(m,n) + alpha(l)*TF(l,m)*TF(l,n) enddo enddo enddo call LUDecomp(FT,kp) call MessageNotify('M','at_af_galerkin_MM_Initial', 'Conversion matrices initialized') MM_Initialized=.true. end subroutine at_af_galerkin_MM_Initial
Function : | |
f_Dx_f(ks:km) : | real(8) |
f_data(ks:km) : | real(8), intent(IN) |
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件
X 微分計算(1 次元)
function f_Dx_f(f_data) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件 ! ! X 微分計算(1 次元) ! real(8), intent(IN) :: f_data(ks:km) real(8) :: f_Dx_f(ks:km) f_Dx_f = f_t(t_Dx_t(t_f(f_data))) end function f_Dx_f
Function : | |||
f_g(ks:km) : | real(8)
| ||
g_data(0:im) : | real(8), intent(IN)
|
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件
格子点データ -> ガラーキン係数変換(1次元データ)
function f_g(g_data) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件 ! ! 格子点データ -> ガラーキン係数変換(1次元データ) ! real(8), intent(IN) :: g_data(0:im) !(in) 格子点データ real(8) :: f_g(ks:km) !(out) ガラーキン係数 f_g = f_t(t_g(g_data)) end function f_g
Function : | |||
f_t(ks:km) : | real(8)
| ||
t_data(0:km) : | real(8), intent(IN)
|
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件
チェビシェフ係数 -> ガラーキン係数変換(1次元データ)
function f_t(t_data) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件 ! ! チェビシェフ係数 -> ガラーキン係数変換(1次元データ) ! real(8), intent(IN) :: t_data(0:km) !(in) チェビシェフ係数 real(8) :: f_t(ks:km) !(out) ガラーキン係数 real(8) :: f_work(ks:km) ! 作業用配列 integer :: k,m if ( .not. MM_Initialized ) call MessageNotify('E','f_t', 'at_af_galerkin_MM_module not initialized') f_work =0.0 do m=ks,km do k=0,km f_work(m) = f_work(m) + alpha(k) * beta(k) * t_data(k) * TF(k,m) enddo enddo f_t = LUSolve(FT,kp,f_work) end function f_t
Function : | |||
g_f(0:im) : | real(8)
| ||
f_data(ks:km) : | real(8), intent(IN)
|
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件
ガラーキン係数 -> 格子点データ変換(1次元データ)
function g_f(f_data) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件 ! ! ガラーキン係数 -> 格子点データ変換(1次元データ) ! real(8), intent(IN) :: f_data(ks:km) !(in) ガラーキン係数 real(8) :: g_f(0:im) !(out) 格子点データ g_f = g_t(t_f(f_data)) end function g_f
Function : | |||
t_f(0:km) : | real(8)
| ||
f_data(ks:km) : | real(8), intent(IN)
|
チェビシェフ−ガラーキン法 ディリクレ・ノイマン混合境界条件
ガラーキン係数 -> チェビシェフ係数変換(1次元データ)
function t_f(f_data) ! ! チェビシェフ−ガラーキン法 ! ディリクレ・ノイマン混合境界条件 ! ! ガラーキン係数 -> チェビシェフ係数変換(1次元データ) ! real(8), intent(IN) :: f_data(ks:km) !(in) ガラーキン係数 real(8) :: t_f(0:km) !(out) チェビシェフ係数 integer :: m, n if ( .not. MM_Initialized ) call MessageNotify('E','t_f', 'at_af_galerkin_MM_module not initialized') t_f = 0.0D0 do m=0,km do n=ks,km t_f(m) = t_f(m) + TF(m,n)*f_data(n)/beta(m) enddo enddo end function t_f