ee_mpi_module.f90
Go to the documentation of this file.
1 !--
2 !----------------------------------------------------------------------
3 ! Copyright (c) 2016-2020 SPMODEL Development Group. All rights reserved.
4 !----------------------------------------------------------------------
5 !
6 !表題 ee_mpi_module
7 !
8 ! spml/ee_module モジュールは周期境界条件の下での 2 次元矩形領域の
9 ! 流体運動をスペクトル法により数値計算するための Fortran90 関数を
10 ! 提供する.
11 !
12 ! 内部で ISPACK3/FXPACK の Fortran77 サブルーチンを呼んでいる.
13 ! スペクトルデータおよび格子点データの格納方法については...
14 !
15 !履歴 2016/08/08 竹広真一 eee_mpi_module より改造
16 ! 2016/09/22 竹広真一 ef_Lapla_ef, ef_Laplainv_ef 初期化
17 ! 2020/04/10 竹広真一 MPI_Send, MPI_Recv 関数を MPI_AlltoAll へ変更
18 ! 2020/05/24 竹広真一 MPI_AlltoAllV へ変更
19 !
20 !++
22  !
23  != ee_mpi_module
24  !
25  ! Authors:: Shin-ichi Takehiro, Youhei SASAKI
26  ! Version:: $Id$
27  ! Copyright&License:: See COPYRIGHT[link:../../COPYRIGHT]
28  !
29  !== 概要
30  !
31  ! spml/ee_module モジュールは周期境界条件の下での 2 次元矩形領域の
32  ! 流体運動をスペクトル法により数値計算するための Fortran90 関数を
33  ! 提供する.
34  !
35  ! 内部で ISPACK/FTPACKI の Fortran77 サブルーチンを呼んでいる.
36  ! スペクトルデータおよび格子点データの格納方法については...
37  !
38  !== 関数・変数の名前と型について
39  !
40  !=== 命名法
41  !
42  ! * 関数名の先頭 (ef_, vx_, x_, v_) は, 返す値の形を示している.
43  ! ef_ :: スペクトルデータ
44  ! (第 1,2 次元がそれぞれ Y,X 方向波数(X について分割配置))
45  ! vx_ :: XY 方向 2 次元格子点データ(Y について分散配置
46  ! x_ :: X 方向 1 次元格子点データ
47  ! v_ :: Y 方向 1 次元格子点データ(分散配置)
48  !
49  ! * 関数名の間の文字列(Dx, Dy, Lapla, LaplaInv)は,
50  ! その関数の作用を表している.
51  !
52  ! * 関数名の最後 (_ef_ef,_ef,_vx, _x, _v) は, 入力変数の形が
53  ! スペクトルデータおよび格子点データであることを示している.
54  ! _ef :: スペクトルデータ
55  ! _ef_ef :: 2 つのスペクトルデータ
56  ! _vx :: 2 次元格子点データ
57  ! _x :: X 方向 1 次元格子点データ
58  ! _v :: Y 方向 1 次元格子点データ
59  !
60  !=== 各データの種類の説明
61  !
62  ! * vx : 2 次元格子点データ.
63  ! * 変数の種類と次元は real(8), dimension(,js(ip):je(ip),0:im-1).
64  ! * im は X 座標の格子点数であり, サブルーチン ee_mpi_initial にて
65  ! Y 方向の全格子点数 jm とともにあらかじめ設定しておく.
66  ! * ee_mpi_Initial によってプロセス毎に Y 方向の
67  ! 分割配置が設定され, その情報が public 変数 js,je,jc に設定される.
68  ! * js が分割配置の最小格子点, je が最大格子点, jc が格子点数である.
69  !
70  ! * ef : スペクトルデータ.
71  ! * 変数の種類と次元は real(8), dimension(-lm:lm,2*kc).
72  ! * mm は Y 方向の最大波数であり, サブルーチン ee_mpi_initial にて
73  ! X 方向の最大波数 km とともにあらかじめ設定しておく.
74  ! (X, Y 方向波数の順ではない)ことに注意.
75  ! * ee_mpi_Initial によってプロセス毎に X 方向波数の
76  ! 分割配置が設定され, その情報が public 変数 ls,le,lc に設定される.
77  ! * ks が分割配置の最小波数, ke が最大波数, kc が波数の数である.
78  ! 実際の格納のされ方は ks, ks+1,...,ke,-ke,-ke+1,...,-ks の順である.
79  ! * 分割配置される前のスペクトルデータの格納のされかたは IPSACK の
80  ! P2PACK に基づく.
81  ! ee_S( L, K) : s_{kl} の実部
82  ! ee_S(-L,-K) : s_{kl} の虚部
83  ! ee_S(-L, K) : s_{k(-l)} の実部
84  ! ee_S( L,-K) : s_{k(-l)} の虚部
85  ! ee_S( L, 0) : s_{0l} の実部
86  ! ee_S(-L, 0) : s_{0l} の虚部
87  ! ee_S( 0, K) : s_{k0} の実部
88  ! ee_S( 0,-K) : s_{k0} の虚部
89  ! ee_S( 0, 0) : s_{00} (実数)
90  ! * 元の格子点データが実数であるため, s_{-k-l} = s^*_{kl} なる関係がある.
91  ! ただし ^* は複素共役を表す.
92  !
93  ! * x, v : X, Y 方向 1 次元格子点データ.
94  ! * 変数の種類と次元はそれぞれ real(8), dimension(0:im-1),
95  ! real(8), dimension(js(ip):je(ip))
96  !
97  ! * ef_ で始まる関数が返す値はスペクトルデータに同じ.
98  !
99  ! * vx_ で始まる関数が返す値は 3 次元格子点データに同じ.
100  !
101  ! * x_, v_ で始まる関数が返す値は 1 次元格子点データに同じ.
102  !
103  ! * スペクトルデータに対する微分等の作用とは, 対応する格子点データに
104  ! 微分などを作用させたデータをスペクトル変換したものことである.
105  !
106  !== 変数・手続き群の要約
107  !
108  !==== 初期化
109  !
110  ! ee_mpi_Initial :: スペクトル変換の格子点数, 切断波数の設定
111  ! kf_k :: X 方向波数の位置情報
112  !
113  !==== 座標変数
114  !
115  ! x_X, v_Y :: 格子点座標(X,Y座標)を格納した 1 次元配列
116  ! x_X_Weight, v_Y_Weight :: 重み座標を格納した 1 次元配列
117  ! vx_X, vx_Y_Z :: 格子点データの XY 座標(X,Y)
118  ! (格子点データ型 3 次元配列)
119  !
120  !==== 基本変換
121  !
122  ! vx_ef :: スペクトルデータから格子データへの変換
123  ! ef_vx :: 格子データからスペクトルデータへの変換
124  ! xy_vx :: 分散格子点データの集積
125  ! ee_ef :: 分散スペクトルデータの集積
126  ! ef_ee :: 集積スペクトルデータの分散
127  !
128  !==== 微分
129  !
130  ! ef_Lapla_ef :: スペクトルデータにラプラシアンを作用させる
131  ! ef_LaplaInv_ef :: スペクトルデータにラプラシアンの逆変換を作用させる
132  ! ef_Dx_ef :: スペクトルデータに X 微分を作用させる
133  ! ef_Dy_ef :: スペクトルデータに Y 微分を作用させる
134  !
135  !==== 非線形計算
136  !
137  ! ef_Joacobian_ef_ef :: 2 つのスペクトルデータからヤコビアンを計算する.
138  ! ef_JoacobianZ_ef :: 渦度スペクトルデータから非発散方程式の非線形項を計算する
139  !
140  !==== 積分・平均
141  !
142  ! IntVX_vx, AvrVX_vx :: 2 次元(XY)格子点データの X,Y 方向積分および平均
143  ! v_IntX_vx, v_AvrX_vx :: 2 次元(XY)格子点データの X 方向積分および平均
144  ! x_IntV_vx, x_AvrV_vx :: 2 次元(XY)格子点データの Y 方向積分および平均
145  !
146  ! IntX_x, AvrX_x :: 1 次元(X)格子点データの X 方向積分および平均
147  ! IntV_v, AvrV_v :: 1 次元(Y)格子点データの Y 方向積分および平均
148  !
149  !==== スペクトル解析
150  !
151  ! ef_EnergyFromStreamfunc_ef :: 流れ関数からエネルギースペクトルを計算
152  ! ef_EnstrophyFromStreamfunc_ef :: 流れ函数からエンストロフィースペクトルを計算
153  !
154  !==== 補間計算
155  !
156  ! Interpolate_ef :: 任意の点の値をスペクトルデータから計算する
157  !
158  use dc_message, only : messagenotify
159  use mpi
160  implicit none
161 
162  private
163  public ks, ke, kc
164  public js, je, jc
165  public kf_k
166  public ee_mpi_initial ! 初期化ルーチン
167  public vx_ef, ef_vx ! 基本変換
168 !!$ public xy_vx ! 基本変換
169 !!$ public ee_ef, ef_ee ! 基本変換
170  public ef_dx_ef, ef_dy_ef ! 微分
171  public ef_lapla_ef, ef_laplainv_ef ! 微分
172  public ef_jacobian_ef_ef ! ヤコビアン
173  public ef_jacobianz_ef ! ヤコビアン
174 
175  public intyx_vx, avryx_vx ! 積分・平均
176  public v_intx_vx, v_avrx_vx ! 積分・平均
177  public x_inty_vx, x_avry_vx ! 積分・平均
178 
179  public intx_x, avrx_x ! 積分・平均
180  public inty_v, avry_v ! 積分・平均
181 
182  public interpolate_ef ! 補間
183 
184  public x_x, v_y ! 座標変数
185  public x_x_weight, v_y_weight ! 座標変数
186  public vx_x, vx_y ! 座標変数
187 
188  public ef_energyfromstreamfunc_ef ! エネルギー
189  public ef_enstrophyfromstreamfunc_ef ! エンストロフィー
190 
191  public vax_fay, fay_vax
192 
193  integer :: im=32, jm=32 ! 格子点の設定(X,Y)
194  integer :: km=10, lm=10 ! 切断波数の設定(X,Y)
195 
196  integer, dimension(:), allocatable :: ke ! X 最大波数
197  integer, dimension(:), allocatable :: ks ! X 最小波数
198  integer, dimension(:), allocatable :: kc ! X 波数の数
199  integer, dimension(:), allocatable :: je ! Y 座標最大格子点
200  integer, dimension(:), allocatable :: js ! Y 座標最小格子点
201  integer, dimension(:), allocatable :: jc ! Y 座標格子点数
202  integer :: np ! MPI プロセス数
203  integer :: ip ! MPI プロセス ID
204 
205  integer(8), dimension(:), allocatable :: itj ! FFT 用配列(Y)
206  real(8), dimension(:), allocatable :: tj ! FFT 用配列(Y)
207  integer(8), dimension(:), allocatable :: iti ! FFT 用配列(X)
208  real(8), dimension(:), allocatable :: ti ! FFT 用配列(X)
209 
210  real(8), dimension(:), allocatable :: x_x ! 格子点座標(X)
211  real(8), dimension(:), allocatable :: v_y ! 格子点座標(Y)
212 
213  real(8), dimension(:), allocatable :: x_x_weight ! 格子点重み(X)
214  real(8), dimension(:), allocatable :: v_y_weight ! 格子点重み(Y)
215 
216  real(8), dimension(:,:), allocatable :: vx_x ! 格子点(X)座標(2 次元)
217  real(8), dimension(:,:), allocatable :: vx_y ! 格子点(Y)座標(2 次元)
218 
219  real(8) :: xmin, xmax ! X 座標範囲
220  real(8) :: ymin, ymax ! Y 座標範囲
221  real(8) :: xl, yl ! 領域の大きさ(X,Y)
222 
223  real(8), parameter :: pi=3.1415926535897932385d0
224 
225  save im, jm, km, lm, itj, tj, iti, ti
226  save ks, ke, kc, js, je, jc, np, ip
228  save xmin, xmax, ymin, ymax, xl, yl
229 
230 contains
231  !--------------- 初期化 -----------------
232  subroutine ee_mpi_initial(i_in,j_in,k_in,l_in,xmin_in,xmax_in,ymin_in,ymax_in)
233  !
234  ! スペクトル変換の格子点数, 波数を設定する.
235  ! 領域の範囲は [0,2pi]x[0,2pi] に決め打ち
236  !
237  ! 他の関数や変数を呼ぶ前に, 最初にこのサブルーチンを呼んで
238  ! 初期設定をしなければならない.
239  !
240  integer,intent(in) :: i_in ! 格子点数(X)
241  integer,intent(in) :: j_in ! 格子点数(Y)
242  integer,intent(in) :: k_in ! 切断波数(X)
243  integer,intent(in) :: l_in ! 切断波数(Y)
244 
245  real(8),intent(in) :: xmin_in, xmax_in ! X 座標範囲
246  real(8),intent(in) :: ymin_in, ymax_in ! Y 座標範囲
247 
248  integer :: ii, jj
249  integer :: iip
250  integer :: kp, jp
251  integer :: kint, kmod
252  integer :: jint, jmod
253  integer :: ierr
254 
255  im = i_in ; jm = j_in
256  km = k_in ; lm = l_in
257 
258  xmin = xmin_in ; xmax = xmax_in
259  ymin = ymin_in ; ymax = ymax_in
260  xl = xmax-xmin ; yl = ymax-ymin
261 
262  CALL mpi_comm_rank(mpi_comm_world,ip,ierr)
263  CALL mpi_comm_size(mpi_comm_world,np,ierr)
264 
265  ! x 波数 MPI分割情報
266  allocate(ks(0:np-1))
267  allocate(ke(0:np-1))
268  allocate(kc(0:np-1))
269 
270  kint = km/np
271  kmod = mod(km,np)
272  kc = kint
273  do iip=0,kmod
274  kc(iip) = kc(iip) + 1
275  end do
276 
277  ks(0)=0 ; ke(0) = ks(0) + kc(0) -1
278  do iip=1,np-1
279  ks(iip) = ks(iip-1) + kc(iip-1)
280  ke(iip) = ks(iip) + kc(iip) - 1
281  end do
282 
283  ! Y 軸 MPI分割情報
284  allocate(js(0:np-1))
285  allocate(je(0:np-1))
286  allocate(jc(0:np-1))
287 
288  jint = jm/np
289  jmod = mod(jm,np)
290  jc = jint
291  do iip=0,jmod-1
292  jc(iip) = jc(iip) + 1
293  end do
294 
295  js(0)=0 ; je(0) = js(0) + jc(0) -1
296  do iip=1,np-1
297  js(iip) = js(iip-1) + jc(iip-1)
298  je(iip) = js(iip) + jc(iip) - 1
299  end do
300 
301  allocate(itj(jm))
302  allocate(iti(im/2))
303  allocate(tj(jm*2))
304  allocate(ti(im*3/2))
305 
306  allocate(x_x(0:im-1))
307  allocate(x_x_weight(0:im-1))
308  allocate(v_y(jc(ip)))
309  allocate(v_y_weight(jc(ip)))
310  allocate(vx_x(jc(ip),0:im-1))
311  allocate(vx_y(jc(ip),0:im-1))
312 
313  call fxrini(int(im,8),iti,ti)
314  call fxzini(int(jm,8),itj,tj)
315 
316 
317  do ii=0,im-1
318  x_x(ii) = xmin + xl/im*ii
319  enddo
320  x_x_weight = xl/im
321 
322  do jj=1,jc(ip)
323  v_y(jj) = ymin + yl/jm*(js(ip)+jj-1)
324  enddo
325  v_y_weight = yl/jm
326 
327  vx_x = spread(x_x,1,jc(ip))
328  vx_y = spread(v_y,2,im)
329 
330  call messagenotify('M','ee_mpi_initial', &
331  'ee_mpi_module (2021/04/27) is initialized')
332 
333  end subroutine ee_mpi_initial
334 
335  !--------------- 波数位置問い合わせ -----------------
336  function kf_k(k)
337  !
338  ! スペクトルデータ eef(-lm,lm,2*kc) での
339  ! X 方向波数 L の位置情報(第 2 添え字)を調べる.
340  !
341  ! X 方向波数については ls,ls+1,... le, -le,-le+1,...,-ls
342  ! の順に格納されている.
343  !
344  integer, intent(IN) :: k ! X 方向波数
345  integer :: kf_k ! スペクトルデータ第 2 添え字
346 
347  if ( abs(k) < ks(ip) .OR. ke(ip) < abs(k) ) then
348  kf_k = -1
349  else if ( k >= 0 ) then
350  kf_k = k-ks(ip)+1
351  else
352  kf_k = ks(ip)+2*kc(ip)-abs(k)
353  endif
354 
355  end function kf_k
356 
357  !--------------- 基本変換 -----------------
358  function vx_ef(ef)
359  !
360  ! スペクトルデータから格子データへ変換する.
361  !
362  real(8), dimension(js(ip):je(ip),0:im-1) :: vx_ef
363  !(out) 格子点データ
364  real(8), dimension(-lm:lm,2*kc(ip)), intent(in) :: ef
365  !(in) スペクトルデータ
366  real(8), dimension(js(ip):je(ip),2,0:im/2-1) :: vax_work
367  real(8), dimension(kc(ip),2,0:jm-1) :: fay_work
368 
369  integer :: k, l
370 
371  fay_work = 0.0d0
372 
373  do k=1,kc(ip)
374  do l=1,lm
375  fay_work(k,1,l) = ef(l,k)
376  fay_work(k,2,l) = ef(-l,2*kc(ip)-k+1)
377  fay_work(k,1,jm-l) = ef(-l,k)
378  fay_work(k,2,jm-l) = ef(l,2*kc(ip)-k+1)
379  enddo
380  enddo
381 
382  do k=1,kc(ip)
383  fay_work(k,1,0) = ef(0,k)
384  fay_work(k,2,0) = ef(0,2*kc(ip)-k+1)
385  enddo
386 
387  if ( ip == 0 ) then
388  do l=1,lm
389  fay_work(1,1,l) = ef(l,1)
390  fay_work(1,2,l) = ef(-l,1)
391  fay_work(1,1,jm-l) = ef(l,1)
392  fay_work(1,2,jm-l) = -ef(-l,1)
393  end do
394  fay_work(1,1,0) = ef(0,1)
395  endif
396 
397  call fxztba(int(kc(ip),8),int(jm,8),fay_work,itj,tj)
398 
399  vax_work = vax_fay(fay_work)
400 
401  call fxrtba(int(jc(ip),8),int(im,8),vax_work,iti,ti)
402 
403  vx_ef = reshape(vax_work,(/jc(ip),im/))
404 
405  end function vx_ef
406 
407  function ef_vx(vx)
408  !
409  ! 格子データからスペクトルデータへ変換する.
410  !
411  real(8), dimension(-lm:lm,2*kc(ip)) :: ef_vx
412  !(out) スペクトルデータ
413  real(8), dimension(js(ip):je(ip),0:im-1), intent(in) :: vx
414  !(in) 格子点データ
415  real(8), dimension(js(ip):je(ip),2,0:im/2-1) :: vax_work
416  real(8), dimension(kc(ip),2,0:jm-1) :: fay_work
417  integer :: k, l
418 
419  vax_work = reshape(vx,(/jc(ip),2,im/2/))
420 
421  call fxrtfa(int(jc(ip),8),int(im,8),vax_work,iti,ti)
422 
423  fay_work = fay_vax(vax_work)
424 
425  if ( ip == 0 ) fay_work(1,2,:) = 0.0d0
426 
427  call fxztfa(int(kc(ip),8),int(jm,8),fay_work,itj,tj)
428 
429  do k=1,kc(ip)
430  do l=1,lm
431  ef_vx(l,k) = fay_work(k,1,l)
432  ef_vx(-l,2*kc(ip)-k+1) = fay_work(k,2,l)
433  ef_vx(-l,k) = fay_work(k,1,jm-l)
434  ef_vx(l,2*kc(ip)-k+1) = fay_work(k,2,jm-l)
435  enddo
436  enddo
437 
438  do k=1,kc(ip)
439  ef_vx(0,k) = fay_work(k,1,0)
440  ef_vx(0,2*kc(ip)-k+1) = fay_work(k,2,0)
441  enddo
442 
443  if ( ip == 0 ) then
444  do l=1,lm
445  ef_vx(l,1) = fay_work(1,1,l)
446  ef_vx(-l,1) = fay_work(1,2,l)
447  ef_vx(l,2*kc(0)) = 0.0d0
448  ef_vx(-l,2*kc(0)) = 0.0d0
449  end do
450  ef_vx(0,1) = fay_work(1,1,0)
451  ef_vx(0,2*kc(0)) = 0.0d0
452  endif
453 
454  end function ef_vx
455 
456  function vax_fay(fay)
457  real(8), dimension(kc(ip),2,0:jm-1),intent(IN) :: fay
458  real(8), dimension(jc(ip),2,0:im/2-1) :: vax_fay
459 
460  integer :: j, k, iip
461  integer :: ierr
462  integer :: isndc(0:np-1)
463  integer :: isdsp(0:np-1)
464  integer :: ircvc(0:np-1)
465  integer :: irdsp(0:np-1)
466  real(8), allocatable :: aa_work(:,:)
467 !!$ real(8), allocatable :: xava_work(:,:,:,:)
468  integer :: kcm
469  integer :: ind1, ind2
470 
471  vax_fay = 0.0d0
472 
473  kcm = maxval(kc)
474  allocate(aa_work(kcm*2*jc(ip),0:np-1))
475  aa_work = 0.0d0
476 !!$ kcm = maxval(kc)
477 !!$ allocate(xava_work(kcm,2,jc(ip),0:np-1))
478 !!$ xava_work = 0.0D0
479 
480  isndc = kc(ip)*2*jc
481  ircvc = jc(ip)*2*kc
482  do iip=0,np-1
483  isdsp(iip) = sum(isndc(0:iip-1))
484  irdsp(iip) = kcm*2*jc(ip)*iip
485  end do
486 
487  call mpi_alltoallv(fay,isndc,isdsp,mpi_real8,&
488  aa_work,ircvc,irdsp,mpi_real8,mpi_comm_world,ierr)
489 !!$ call MPI_AlltoAllV(fay,isndc,isdsp,MPI_REAL8,&
490 !!$ xava_work,ircvc,irdsp,MPI_REAL8,MPI_COMM_WORLD,IERR)
491 
492  do iip=0,np-1
493  do k=1,kc(iip)
494  do j=1,jc(ip)
495  ind1 = k + kc(iip)*2*(j-1)
496  ind2 = k + kc(iip) + kc(iip)*2*(j-1)
497  vax_fay(j,1,ks(iip)-1+k) = aa_work(ind1,iip)
498  vax_fay(j,2,ks(iip)-1+k) = aa_work(ind2,iip)
499 !!$ vax_fay(j,:,ks(iip)-1+k) = xava_work(k,:,j,iip)
500  end do
501  end do
502  end do
503 
504  deallocate(aa_work)
505 !!$ deallocate(xava_work)
506 
507  end function vax_fay
508 
509  function fay_vax(vax)
510  real(8), dimension(jc(ip),2,0:im/2-1),intent(IN) :: vax
511  real(8), dimension(kc(ip),2,0:jm-1) :: fay_vax
512 
513  integer :: j, k, iip
514  integer :: ierr
515  integer :: isndc(0:np-1)
516  integer :: isdsp(0:np-1)
517  integer :: ircvc(0:np-1)
518  integer :: irdsp(0:np-1)
519  real(8), allocatable :: aa_work(:,:)
520 !!$ real(8), allocatable :: vafa_work(:,:,:,:)
521  integer :: jcm
522  integer :: ind1, ind2
523 
524  fay_vax = 0.0d0
525 
526  jcm = maxval(jc)
527  allocate(aa_work(jcm*2*kc(ip),0:np-1))
528  aa_work = 0.0d0
529 !!$ allocate(vafa_work(jcm,2,kc(ip),0:np-1))
530 !!$ vafa_work = 0.0D0
531 
532  isndc = jc(ip)*2*kc
533  ircvc = kc(ip)*2*jc
534  do iip=0,np-1
535  isdsp(iip) = sum(isndc(0:iip-1))
536  irdsp(iip) = jcm*2*kc(ip)*iip
537  end do
538 
539  call mpi_alltoallv(vax,isndc,isdsp,mpi_real8,&
540  aa_work,ircvc,irdsp,mpi_real8,mpi_comm_world,ierr)
541 !!$ call MPI_AlltoAllV(vax,isndc,isdsp,MPI_REAL8,&
542 !!$ vafa_work,ircvc,irdsp,MPI_REAL8,MPI_COMM_WORLD,IERR)
543 
544  do iip=0,np-1
545  do j=1,jc(iip)
546  do k=1,kc(ip)
547  ind1 = j + jc(iip)*2*(k-1)
548  ind2 = j + jc(iip) + jc(iip)*2*(k-1)
549  fay_vax(k,1,js(iip)+j-1) = aa_work(ind1,iip)
550  fay_vax(k,2,js(iip)+j-1) = aa_work(ind2,iip)
551 !!$ fay_vax(k,:,js(iip)+j-1) = vafa_work(j,:,k,iip)
552  end do
553  end do
554  end do
555 
556  deallocate(aa_work)
557 !!$ deallocate(vafa_work)
558 
559  end function fay_vax
560 
561 
562  !--------------- 微分計算 -----------------
563  function ef_lapla_ef(ef)
564  !
565  ! 入力スペクトルデータにラプラシアン(∂xx+∂yy)を作用する.
566  !
567  ! スペクトルデータのラプラシアンとは, 対応する格子点データに
568  ! ラプラシアンを作用させたデータのスペクトル変換のことである.
569  !
570  ! 実際にはスペクトルデータに全波数 (k**2 + l**2) をかける
571  ! 計算を行っている.
572  !
573  real(8), dimension(-lm:lm,2*kc(ip)) :: ef_Lapla_ef
574  !(out) スペクトルデータのラプラシアン
575 
576  real(8), dimension(-lm:lm,2*kc(ip)), intent(in) :: ef
577  !(in) 入力スペクトルデータ
578 
579  integer kf, k,l
580  ! 作業変数
581 
582  ef_lapla_ef = 0.0d0
583  do kf=1,kc(ip)
584  k = ks(ip) + kf - 1
585  do l=-lm,lm
586  ef_lapla_ef(l,kf) = -((2*pi*k/xl)**2+(2*pi*l/yl)**2)*ef(l,kf)
587  ef_lapla_ef(l,2*kc(ip)-kf+1) &
588  = -((2*pi*k/xl)**2+(2*pi*l/yl)**2)*ef(l,2*kc(ip)-kf+1)
589  enddo
590  enddo
591  end function ef_lapla_ef
592 
593  function ef_laplainv_ef(ef)
594  !
595  ! 入力スペクトルデータに逆ラプラシアン(∂xx+∂yy)**(-1)を作用する.
596  !
597  ! スペクトルデータの逆ラプラシアンとは, 対応する格子点データに
598  ! 逆ラプラシアンを作用させたデータのスペクトル変換のことである.
599  !
600  ! 実際にはスペクトルデータに全波数 (k**2 + l**2) で割る
601  ! 計算を行っている. k=l=0 成分には 0 を代入している.
602  !
603  real(8), dimension(-lm:lm,2*kc(ip)) :: ef_LaplaInv_ef
604  !(out) スペクトルデータの逆ラプラシアン
605 
606  real(8), dimension(-lm:lm,2*kc(ip)), intent(in) :: ef
607  !(in) スペクトルデータ
608 
609  integer kf, k, l
610 
611  ef_laplainv_ef = 0.0d0
612  do kf=1,kc(ip)
613  k = ks(ip) + kf - 1
614  do l=-lm,lm
615  if ( k == 0 .AND. l == 0 ) then
616  ef_laplainv_ef(l,kf) = 0.0
617  else
618  ef_laplainv_ef(l,kf) = -ef(l,kf)/((2*pi*k/xl)**2+(2*pi*l/yl)**2)
619  ef_laplainv_ef(l,2*kc(ip)-kf+1) &
620  = -ef(l,2*kc(ip)-kf+1)/((2*pi*k/xl)**2+(2*pi*l/yl)**2)
621  endif
622  enddo
623  enddo
624  end function ef_laplainv_ef
625 
626  function ef_dx_ef(ef)
627  !
628  ! 入力スペクトルデータに X 微分(∂x)を作用する.
629  !
630  ! スペクトルデータの X 微分とは, 対応する格子点データに X 微分を
631  ! 作用させたデータのスペクトル変換のことである.
632  !
633  ! 実際にはスペクトルデータに X 方向波数 k をかけて
634  ! sin(kx) <-> cos(kx) 成分に入れ換える計算を行っている.
635  !
636  real(8), dimension(-lm:lm,2*kc(ip)) :: ef_Dx_ef
637  !(out) スペクトルデータの X 微分
638 
639  real(8), dimension(-lm:lm,2*kc(ip)), intent(in) :: ef
640  !(in) 入力スペクトルデータ
641 
642  integer kf, k, l
643  ! 作業変数
644 
645  do kf=1,kc(ip)
646  k = ks(ip) + kf - 1
647  do l=-lm,lm
648  ef_dx_ef(l,kf) = -(2*pi*k/xl)*ef(-l,2*kc(ip)-kf+1)
649  ef_dx_ef(l,2*kc(ip)-kf+1) = -(2*pi*(-k)/xl)*ef(-l,kf)
650  enddo
651  enddo
652  end function ef_dx_ef
653 
654  function ef_dy_ef(ef)
655  !
656  ! 入力スペクトルデータに Y 微分(∂y)を作用する.
657  !
658  ! スペクトルデータの X 微分とは, 対応する格子点データに Y 微分を
659  ! 作用させたデータのスペクトル変換のことである.
660  !
661  ! 実際にはスペクトルデータに X 方向波数 l をかけて
662  ! sin(ky) <-> cos(ky) 成分に入れ換える計算を行っている.
663  !
664  real(8), dimension(-lm:lm,2*kc(ip)) :: ef_Dy_ef
665  !(out) スペクトルデータの Y 微分
666 
667  real(8), dimension(-lm:lm,2*kc(ip)), intent(in) :: ef
668  !(in) 入力スペクトルデータ
669 
670  integer kf,l
671  ! 作業変数
672 
673  do kf=1,kc(ip)
674  if ( ip == 0 .AND. kf == 1 ) then
675  do l=-lm,lm
676  ef_dy_ef(l,kf) = -(2*pi*l/yl)*ef(-l,kf)
677  ef_dy_ef(l,2*kc(ip)-kf+1) = 0.0d0
678  enddo
679  else
680  do l=-lm,lm
681  ef_dy_ef(l,kf) = -(2*pi*l/yl)*ef(-l,2*kc(ip)-kf+1)
682  ef_dy_ef(l,2*kc(ip)-kf+1) = -(2*pi*l/yl)*ef(-l,kf)
683  enddo
684  endif
685  enddo
686 
687  end function ef_dy_ef
688 
689  function ef_jacobian_ef_ef(ef_a,ef_b)
690  !
691  ! 2 つのスペクトルデータからヤコビアン
692  !
693  ! J(A,B)=(∂xA)(∂yB)-(∂yA)(∂xB)
694  !
695  ! を計算する.
696  !
697  ! 2 つのスペクトルデータのヤコビアンとは, 対応する 2 つの
698  ! 格子点データのヤコビアンのスペクトル変換のことである.
699  !
700  real(8), dimension(-lm:lm,2*kc(ip)) :: ef_Jacobian_ef_ef
701  !(out) 2 つのスペクトルデータのヤコビアン
702 
703  real(8), dimension(-lm:lm,2*kc(ip)), intent(in) :: ef_a
704  !(in) 1つ目の入力スペクトルデータ
705 
706  real(8), dimension(-lm:lm,2*kc(ip)), intent(in) :: ef_b
707  !(in) 2つ目の入力スペクトルデータ
708 
709  ef_jacobian_ef_ef = ef_vx( vx_ef(ef_dx_ef(ef_a))*vx_ef(ef_dy_ef(ef_b)) &
710  - vx_ef(ef_dy_ef(ef_a))*vx_ef(ef_dx_ef(ef_b)) )
711 
712  end function ef_jacobian_ef_ef
713 
714  function ef_jacobianz_ef(ef_zeta)
715  !
716  ! 渦度スペクトルデータ ζ から流線関数と渦度のヤコビアン
717  !
718  ! -J(ψ,ζ)=-[(∂xψ)(∂yζ)-(∂yψ)(∂xζ)]
719  !
720  ! を計算する. ただしψ は (∂xx+∂yy)ψ=ζ を満たす流線関数である.
721  !
722  real(8), dimension(-lm:lm,2*kc(ip)) :: ef_JacobianZ_ef
723  !(out) 流線関数と渦度のヤコビアン
724 
725  real(8), dimension(-lm:lm,2*kc(ip)), intent(in) :: ef_Zeta
726  !(in) 渦度スペクトルデータ
727 
728  real(8), dimension(jc(ip),0:im-1) :: vx_U ! 速度 X 成分
729  real(8), dimension(jc(ip),0:im-1) :: vx_V ! 速度 Y 成分
730  real(8), dimension(-lm:lm,2*kc(ip)) :: ef_UV !
731 
732  vx_u = - vx_ef(ef_dy_ef(ef_laplainv_ef(ef_zeta)))
733  vx_v = vx_ef(ef_dx_ef(ef_laplainv_ef(ef_zeta)))
734  ef_uv = ef_vx(vx_u*vx_v)
735 
736  ef_jacobianz_ef = - ( ef_dx_ef(ef_dx_ef(ef_uv))-ef_dy_ef(ef_dy_ef(ef_uv)) )&
737  - ef_dx_ef(ef_dy_ef(ef_vx(vx_v**2 - vx_u**2)))
738 
739  end function ef_jacobianz_ef
740 
741 
742  !--------------- 積分計算 -----------------
743  function intyx_vx(vx)
744  !
745  ! 2 次元格子点データの全領域積分および平均.
746  !
747  ! 実際には格子点データ各点毎に x_X_Weight, y_Y_Weight をかけた
748  ! 総和を計算している.
749  !
750  real(8), dimension(jc(ip),0:im-1) :: vx
751  !(in) 2 次元格子点データ
752 
753  real(8) :: IntYX_vx
754  !(out) 積分値
755 
756  real(8) :: IntYXTmp
757  integer :: i, j, ierr
758  ! 作業変数
759 
760  intyxtmp = 0.0d0
761  do i=0,im-1
762  do j=1,jc(ip)
763  intyxtmp = intyxtmp + vx(j,i) * v_y_weight(j) * x_x_weight(i)
764  enddo
765  enddo
766 
767  CALL mpi_allreduce(intyxtmp,intyx_vx,1,mpi_real8, &
768  mpi_sum,mpi_comm_world,ierr)
769 
770  end function intyx_vx
771 
772  function v_intx_vx(vx)
773  !
774  ! 2 次元格子点データの X 方向積分
775  !
776  ! 実際には格子点データ各点毎に x_X_Weight をかけた総和を計算している.
777  !
778  real(8), dimension(jc(ip),0:im-1) :: vx
779  !(in) 2 次元格子点データ
780 
781  real(8), dimension(jc(ip)) :: v_IntX_vx
782  !(out) 積分された 1 次元(Y)格子点データ
783 
784  integer :: i
785  ! 作業変数
786 
787  v_intx_vx = 0.0d0
788  do i=0,im-1
789  v_intx_vx(:) = v_intx_vx(:) + vx(:,i) * x_x_weight(i)
790  enddo
791  end function v_intx_vx
792 
793  function x_inty_vx(vx)
794  !
795  ! 2 次元格子点データの Y 方向積分
796  !
797  ! 実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算している.
798  !
799  real(8), dimension(jc(ip),0:im-1) :: vx
800  !(in) 2 次元格子点データ
801 
802  real(8), dimension(0:im-1) :: x_IntY_vx
803  !(out) 積分された 1 次元(X)格子点データ
804 
805  real(8), dimension(0:im-1) :: x_IntYTmp
806  integer :: j, ierr
807  ! 作業変数
808 
809  x_intytmp = 0.0d0
810  do j=1,jc(ip)
811  x_intytmp(:) = x_intytmp(:) + vx(j,:) * v_y_weight(j)
812  enddo
813 
814  CALL mpi_allreduce(x_intytmp,x_inty_vx,im,mpi_real8, &
815  mpi_sum,mpi_comm_world,ierr)
816 
817  end function x_inty_vx
818 
819  function intx_x(x)
820  !
821  ! 1 次元(X)格子点データの X 方向積分
822  !
823  ! 実際には格子点データ各点毎に x_X_Weight をかけた総和を計算している.
824  !
825  real(8), dimension(0:im-1) :: x !(in) 1 次元格子点データ
826  real(8) :: IntX_x !(out) 積分値
827 
828  intx_x = sum(x*x_x_weight)
829  end function intx_x
830 
831  function inty_v(v) ! Y 方向積分
832  !
833  ! 1 次元(Y)格子点データの Y 方向積分
834  !
835  ! 実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算している.
836  !
837  real(8), dimension(jc(ip)) :: v !(in) 1 次元格子点データ
838  real(8) :: IntY_v !(out) 積分値
839 
840  real(8) :: IntYTmp !(out) 積分値
841  integer :: ierr
842 
843  intytmp = sum(v*v_y_weight)
844 
845  CALL mpi_allreduce(intytmp,inty_v,1,mpi_real8, &
846  mpi_sum,mpi_comm_world,ierr)
847 
848  end function inty_v
849 
850  !--------------- 平均計算 -----------------
851  function avryx_vx(vx)
852  !
853  ! 2 次元格子点データの全領域平均
854  !
855  ! 実際には格子点データ各点毎に x_X_Weight, y_Y_Weight をかけた
856  ! 総和を計算し, x_X_Weight*y_Y_Weight の総和で割ることで平均している.
857  !
858  real(8), dimension(jc(ip),0:im-1) :: vx
859  !(in) 2 次元格子点データ
860 
861  real(8) :: AvrYX_vx
862  !(out) 平均値
863 
864  avryx_vx = intyx_vx(vx)/(xl*yl)
865 
866  end function avryx_vx
867 
868  function v_avrx_vx(vx)
869  !
870  ! 2 次元格子点データの X 方向平均
871  !
872  ! 実際には格子点データ各点毎に x_X_Weight をかけた総和を計算し,
873  ! x_X_Weight の総和で割ることで平均している.
874  !
875  real(8), dimension(jc(ip),0:im-1) :: vx
876  !(in) 2 次元格子点データ
877 
878  real(8), dimension(jc(ip)) :: v_AvrX_vx
879  !(out) 平均された 1 次元(Y)格子点データ
880 
881  v_avrx_vx = v_intx_vx(vx)/xl
882 
883  end function v_avrx_vx
884 
885  function x_avry_vx(vx)
886  !
887  ! 2 次元格子点データの Y 方向平均
888  !
889  ! 実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算し,
890  ! y_Y_Weight の総和で割ることで平均している.
891  !
892  real(8), dimension(jc(ip),0:im-1) :: vx
893  !(in) 2 次元格子点データ
894 
895  real(8), dimension(0:im-1) :: x_AvrY_vx
896  !(out) 平均された 1 次元(X)格子点データ
897 
898  x_avry_vx = x_inty_vx(vx)/yl
899 
900  end function x_avry_vx
901 
902  function avrx_x(x)
903  !
904  ! 1 次元(X)格子点データの X 方向平均
905  !
906  ! 実際には格子点データ各点毎に x_X_Weight をかけた総和を計算し,
907  ! x_X_Weight の総和で割ることで平均している.
908  !
909  real(8), dimension(0:im-1) :: x !(in) 1 次元格子点データ
910  real(8) :: AvrX_x !(out) 平均値
911 
912  avrx_x = intx_x(x)/xl
913 
914  end function avrx_x
915 
916  function avry_v(v)
917  !
918  ! 1 次元(Y)格子点データの Y 方向平均
919  !
920  ! 実際には格子点データ各点毎に y_Y_Weight をかけた総和を計算し,
921  ! y_Y_Weight の総和で割ることで平均している.
922  !
923  real(8), dimension(jc(ip)) :: v !(in) 1 次元格子点データ
924  real(8) :: AvrY_v !(out) 平均値
925 
926  avry_v = inty_v(v)/yl
927 
928  end function avry_v
929 
930 
931  !--------------- スペクトル計算 -----------------
932  function ef_energyfromstreamfunc_ef(ef_StrFunc)
933  !
934  ! 流線関数からエネルギースペクトルを計算する.
935  !
936  ! E_kl = (1/2)(k^2+l^2)|\psi_kl|^2
937  !
938  ! * E_kl の総和が場の平均運動エネルギーとなる.
939  ! * それに領域の面積をかけると全運動エネルギーとなる.
940  !
941  real(8), dimension(-lm:lm,2*kc(ip)) :: ef_EnergyFromStreamfunc_ef
942  ! エネルギースペクトル
943 
944  real(8), dimension(-lm:lm,2*kc(ip)), intent(in) :: ef_StrFunc
945  ! 流線関数
946 
947  integer kf, k,l
948  ! 作業変数
949 
950  do kf=1,kc(ip)
951  k = ks(ip) + kf -1
952  do l=-lm,lm
953  ef_energyfromstreamfunc_ef(l,kf) &
954  = 0.5 * ( (2*pi*k/xl)**2 + (2*pi*l/yl)**2 ) &
955  * (ef_strfunc(l,kf)**2 + ef_strfunc(-l,2*kc(ip)-kf+1)**2)
956  ef_energyfromstreamfunc_ef(l,2*kc(ip)-kf+1) &
957  = ef_energyfromstreamfunc_ef(l,kf)
958  enddo
959  enddo
960 
961  end function ef_energyfromstreamfunc_ef
962 
963  function ef_enstrophyfromstreamfunc_ef(ef_StrFunc)
964  !
965  ! 流線関数からエンストロフィースペクトルを計算する.
966  !
967  ! Q_kl = (1/2)(k^2+l^2)^2|\psi_kl|^2
968  !
969  ! * Q_kl の総和が場の平均エンストロフィーとなる.
970  ! * それに領域の面積をかけると全エンストロフィーとなる.
971  !
972 
973  real(8), dimension(-lm:lm,2*kc(ip)) :: ef_EnstrophyFromStreamfunc_ef
974  ! エンストロフィーースペクトル
975 
976  real(8), dimension(-lm:lm,2*kc(ip)), intent(in) :: ef_StrFunc
977  ! 流線関数
978 
979  integer kf, k,l
980  ! 作業変数
981 
982  do kf=1,kc(ip)
983  k = ks(ip) + kf -1
984  do l=-lm,lm
985  ef_enstrophyfromstreamfunc_ef(l,kf) &
986  = 0.5 * ( (2*pi*k/xl)**2 + (2*pi*l/yl)**2 )**2 &
987  * (ef_strfunc(l,kf)**2 + ef_strfunc(-l,2*kc(ip)-kf+1)**2)
988  ef_enstrophyfromstreamfunc_ef(l,2*kc(ip)-kf+1) &
989  = ef_enstrophyfromstreamfunc_ef(l,kf)
990  enddo
991  enddo
992 
993  end function ef_enstrophyfromstreamfunc_ef
994 
995 
996  !--------------- 補間計算 -----------------
997  function interpolate_ef( ef_Data, x, y )
998  real(8), intent(IN) :: ef_data(-lm:lm,2*kc(ip)) ! スペクトルデータ
999  real(8), intent(IN) :: x ! 補間する点の x 座標
1000  real(8), intent(IN) :: y ! 補間する点の y 座標
1001  real(8) :: Interpolate_ef ! 補間した値
1002  real(8) :: InterpolateTmp ! 作業変数
1003 
1004  integer :: kf, k, l, ierr
1005  real(8) :: xx, yy
1006 
1007  xx =(2*pi/xl)*(x - xmin)
1008  yy =(2*pi/yl)*(y - ymin)
1009 
1010  if ( ip == 0 ) then
1011  interpolatetmp = ef_data(0,1)
1012  else
1013  interpolatetmp = 0.0d0
1014  endif
1015 
1016  ! l=0
1017  if ( ip == 0 ) then
1018  do kf=2,kc(ip)
1019  k = ks(ip) + kf -1
1020  interpolatetmp = interpolatetmp &
1021  + 2*( ef_data(0,kf)*cos(k*xx) - ef_data(0,kf_k(-k))*sin(k*xx) )
1022  end do
1023  else
1024  do kf=1,kc(ip)
1025  k = ks(ip) + kf -1
1026  interpolatetmp = interpolatetmp &
1027  + 2*( ef_data(0,kf)*cos(k*xx) - ef_data(0,kf_k(-k))*sin(k*xx) )
1028  end do
1029  endif
1030 
1031  ! k=0
1032  if ( ip == 0 ) then
1033  do l=1,lm
1034  interpolatetmp = interpolatetmp &
1035  + 2*( ef_data(l,kf_k(0))*cos(l*yy) - ef_data(-l,kf_k(0))*sin(l*yy) )
1036  end do
1037  end if
1038 
1039  ! k*l > 0
1040  do l=1,lm
1041  if ( ip == 0 ) then
1042  do kf=2,kc(ip)
1043  k = ks(ip) + kf -1
1044  interpolatetmp = interpolatetmp &
1045  + 2*( ef_data(l,kf)*( cos(k*xx)*cos(l*yy) &
1046  - sin(k*xx)*sin(l*yy) ) &
1047  -ef_data(-l,kf_k(-k))*( sin(k*xx)*cos(l*yy) &
1048  + cos(k*xx)*sin(l*yy) ) )
1049  end do
1050  else
1051  do kf=1,kc(ip)
1052  k = ks(ip) + kf - 1
1053  interpolatetmp = interpolatetmp &
1054  + 2*( ef_data(l,kf)*( cos(k*xx)*cos(l*yy) &
1055  - sin(k*xx)*sin(l*yy) ) &
1056  -ef_data(-l,kf_k(-k))*( sin(k*xx)*cos(l*yy) &
1057  + cos(k*xx)*sin(l*yy) ) )
1058  end do
1059  endif
1060  end do
1061 
1062  ! k*l < 0
1063  do l=1,lm
1064  if ( ip == 0 ) then
1065  do kf=2,kc(ip)
1066  k = ks(ip) + kf - 1
1067  interpolatetmp = interpolatetmp &
1068  + 2*( ef_data(-l,kf)*( cos(k*xx)*cos(l*yy) &
1069  + sin(k*xx)*sin(l*yy) ) &
1070  -ef_data(l,kf_k(-k))*( sin(k*xx)*cos(l*yy) &
1071  - cos(k*xx)*sin(l*yy) ) )
1072  end do
1073  else
1074  do kf=1,kc(ip)
1075  k = ks(ip) + kf - 1
1076  interpolatetmp = interpolatetmp &
1077  + 2*( ef_data(-l,kf)*( cos(k*xx)*cos(l*yy) &
1078  + sin(k*xx)*sin(l*yy) ) &
1079  -ef_data(l,kf_k(-k))*( sin(k*xx)*cos(l*yy) &
1080  - cos(k*xx)*sin(l*yy) ) )
1081  end do
1082  endif
1083  end do
1084 
1085  CALL mpi_allreduce(interpolatetmp,interpolate_ef,1,mpi_real8, &
1086  mpi_sum,mpi_comm_world,ierr)
1087 
1088  end function interpolate_ef
1089 
1090 end module ee_mpi_module
real(8) function, dimension(kc(ip), 2, 0:jm-1), public fay_vax(vax)
integer, dimension(:), allocatable, save, public kc
real(8) function, dimension(jc(ip)), public v_intx_vx(vx)
integer, dimension(:), allocatable, save, public je
real(8) function, public inty_v(v)
integer function, public kf_k(k)
real(8) function, dimension(jc(ip), 2, 0:im/2-1), public vax_fay(fay)
real(8) function, dimension(0:im-1), public x_inty_vx(vx)
real(8), dimension(:), allocatable, save, public v_y_weight
real(8) function, dimension(-lm:lm, 2 *kc(ip)), public ef_energyfromstreamfunc_ef(ef_StrFunc)
integer, dimension(:), allocatable, save, public ks
integer, dimension(:), allocatable, save, public js
real(8) function, public avry_v(v)
real(8), dimension(:), allocatable, save, public v_y
real(8) function, dimension(jc(ip)), public v_avrx_vx(vx)
real(8), dimension(:), allocatable, save, public x_x
real(8) function, public intx_x(x)
real(8) function, public interpolate_ef(ef_Data, x, y)
real(8) function, dimension(-lm:lm, 2 *kc(ip)), public ef_vx(vx)
real(8) function, dimension(-lm:lm, 2 *kc(ip)), public ef_enstrophyfromstreamfunc_ef(ef_StrFunc)
real(8) function, public intyx_vx(vx)
real(8) function, dimension(0:im-1), public x_avry_vx(vx)
real(8) function, dimension(-lm:lm, 2 *kc(ip)), public ef_jacobian_ef_ef(ef_a, ef_b)
real(8) function, public avryx_vx(vx)
real(8) function, dimension(js(ip):je(ip), 0:im-1), public vx_ef(ef)
real(8), dimension(:,:), allocatable, save, public vx_x
real(8), dimension(:,:), allocatable, save, public vx_y
real(8) function, dimension(-lm:lm, 2 *kc(ip)), public ef_laplainv_ef(ef)
real(8) function, dimension(-lm:lm, 2 *kc(ip)), public ef_lapla_ef(ef)
real(8) function, public avrx_x(x)
real(8), dimension(:), allocatable, save, public x_x_weight
subroutine, public ee_mpi_initial(i_in, j_in, k_in, l_in, xmin_in, xmax_in, ymin_in, ymax_in)
integer, dimension(:), allocatable, save, public jc
integer, dimension(:), allocatable, save, public ke
real(8) function, dimension(-lm:lm, 2 *kc(ip)), public ef_dy_ef(ef)
real(8) function, dimension(-lm:lm, 2 *kc(ip)), public ef_dx_ef(ef)
real(8) function, dimension(-lm:lm, 2 *kc(ip)), public ef_jacobianz_ef(ef_zeta)