ae_module.f90
Go to the documentation of this file.
1 ! -*- mode: f90; coding: utf-8 -*-
2 !-----------------------------------------------------------------------
3 ! Copyright (c) 2019 SPMODEL Development Group. All rights reserved.
4 !-----------------------------------------------------------------------
78 module ae_module
79  use dc_message, only: messagenotify
80  use dc_types, only: dp
81  use spml_utils, only: pi
82  implicit none
83 
84  private
85  public ae_initial
86  public ag_ae
87  public ae_ag
88  public g_e
89  public e_g
90  public ae_dx_ae
91  public e_dx_e
92  public a_int_ag
93  public int_g
94  public a_avr_ag
95  public avr_g
96  public interpolate_e
97  public a_interpolate_ae
98  public g_x
99  public g_x_weight
100 
102  real(DP), allocatable :: g_x(:)
104  real(DP), allocatable :: g_x_weight(:)
105 
106  integer(8) :: im = 32 ! 格子点の数
107  integer(8) :: km = 10 ! 切断波数
108  real(DP) :: xl = 1.0d0 ! 領域の大きさ
109  integer(8), allocatable :: it(:)
110  real(DP), allocatable :: t(:)
111 
112  save im, km, it, t, xl, g_x, g_x_weight
113 
114 contains
115  !-----------------------------------------------------------------------
121  subroutine ae_initial(i,k,xmin,xmax)
123  integer, intent(in) :: i
125  integer, intent(in) :: k
127  real(DP),intent(in) :: xmin
129  real(DP),intent(in) :: xmax
130  integer(8) :: ii
131 
132  im = i
133  km = k
134  xl = xmax - xmin
135 
136  if ( im <= 0 .or. km <= 0 ) then
137  call messagenotify('E','ae_Initial', &
138  'Number of grid points and waves should be positive')
139  elseif ( mod(im,2_8) /= 0 ) then
140  call messagenotify('E','ae_Initial', &
141  'Number of grid points should be even')
142  elseif ( km > im/2 ) then
143  call messagenotify('E','ae_Initial', &
144  'KM shoud be less equal to IM/2')
145  endif
146 
147  allocate(it(im/2),t(im*3/2))
148 
149  call fxrini(im,it,t)
150 
151  allocate(g_x(0:im-1))
152  do ii=0,im-1
153  g_x(ii) = xmin + (xl/im)*ii
154  enddo
155 
156  allocate(g_x_weight(0:im-1))
157  g_x_weight = xl/im
158 
159  call messagenotify(&
160  'M','ae_initial','ae_module (2019/09/17) is initialized')
161 
162  end subroutine ae_initial
163 
164  !-----------------------------------------------------------------------
175  function ag_ae(ae)
177  real(DP), dimension(:,-km:), intent(in) :: ae
179  real(DP), dimension(size(ae,1),0:im-1) :: ag_ae
180 
181  integer(8) :: nm, k
182  nm=size(ae,1)
183 
184  if ( size(ae,2) < 2*km+1 ) then
185  call messagenotify('E','ag_ae', &
186  'The Fourier dimension of input data too small.')
187  elseif ( size(ae,2) > 2*km+1 ) then
188  call messagenotify('W','ag_ae', &
189  'The Fourier dimension of input data too large.')
190  endif
191 
192  ag_ae = 0.0d0
193  ag_ae(:,0) = ae(:,0)
194  do k=1,min(km,im/2-1)
195  ag_ae(:,2*k) = ae(:,k)
196  ag_ae(:,2*k+1) = ae(:,-k)
197  enddo
198  if ( km == im/2 ) then
199  ag_ae(:,1) = ae(:,km)
200  end if
201 
202  call fxrtba(nm,im,ag_ae,it,t)
203 
204  end function ag_ae
205 
206  !-----------------------------------------------------------------------
216  function g_e(e)
218  real(DP), dimension(-km:km), intent(in) :: e
220  real(DP), dimension(0:im-1) :: g_e
221 
222  real(DP), dimension(1,size(e)) :: ae_work
223  real(DP), dimension(1,0:im-1) :: ag_work
224 
225  ae_work(1,:) = e
226  ag_work = ag_ae(ae_work)
227  g_e = ag_work(1,:)
228 
229  end function g_e
230 
231  !-----------------------------------------------------------------------
244  function ae_ag(ag)
246  real(DP), dimension(:,:), intent(in) :: ag
248  real(DP), dimension(size(ag,1),-km:km) :: ae_ag
249 
250  real(DP), dimension(size(ag,1),0:im-1) :: ag_work
251  integer(8) :: nm, k
252 
253  nm = size(ag,1)
254  if ( size(ag,2) < im ) then
255  call messagenotify('E','ae_ag', &
256  'The Grid points of input data too small.')
257  elseif ( size(ag,2) > im ) then
258  call messagenotify('W','ae_ag', &
259  'The Grid points of input data too large.')
260  endif
261  ag_work = ag
262 
263  call fxrtfa(nm,im,ag_work,it,t)
264 
265  do k=1,min(km,im/2-1)
266  ae_ag(:, k) = ag_work(:,2*k)
267  ae_ag(:,-k) = ag_work(:,2*k+1)
268  enddo
269  ae_ag(:,0) = ag_work(:,0)
270  if ( km == im/2 ) then
271  ae_ag(:,km) = ag_work(:,1)
272  end if
273 
274  end function ae_ag
275 
276  !-----------------------------------------------------------------------
289  function e_g(g)
291  real(DP), dimension(0:im-1), intent(in) :: g
293  real(DP), dimension(-km:km) :: e_g
294 
295  real(DP), dimension(1,size(g)) :: ag_work
296  real(DP), dimension(1,-km:km) :: ae_work
297 
298  ag_work(1,:) = g
299  ae_work = ae_ag(ag_work)
300  e_g = ae_work(1,:)
301 
302  end function e_g
303 
304  !-----------------------------------------------------------------------
309  function ae_dx_ae(ae)
311  real(DP), dimension(:,-km:), intent(in) :: ae
313  real(DP), dimension(size(ae,1),-km:km) :: ae_dx_ae
314 
315  integer(8) :: k
316 
317  if ( size(ae,2) < 2*km+1 ) then
318  call messagenotify('W','ae_Dx_ae', &
319  'The Fourier dimension of input data too small.')
320  elseif ( size(ae,2) > 2*km+1 ) then
321  call messagenotify('W','ae_Dx_ae', &
322  'The Fourier dimension of input data too large.')
323  endif
324 
325  do k=-km,km
326  ae_dx_ae(:,k) = -(2*pi*k/xl)*ae(:,-k)
327  enddo
328  end function ae_dx_ae
329 
330  !-----------------------------------------------------------------------
335  function e_dx_e(e)
337  real(DP), dimension(-km:km), intent(in) :: e
339  real(DP), dimension(-km:km) :: e_Dx_e
340 
341  real(DP), dimension(1,-km:km) :: ae_work
342 
343  ae_work(1,:) = e
344  ae_work = ae_dx_ae(ae_work)
345  e_dx_e = ae_work(1,:)
346 
347  end function e_dx_e
348 
349  !-----------------------------------------------------------------------
351  function a_int_ag(ag)
353  real(DP), dimension(:,0:), intent(in) :: ag
355  real(DP), dimension(size(ag,1)) :: a_Int_ag
356 
357  integer(8) :: i
358 
359  if ( size(ag,2) < im ) then
360  call messagenotify('E','ae_Int_ag', &
361  'The Grid points of input data too small.')
362  elseif ( size(ag,2) > im ) then
363  call messagenotify('W','ae_Int_ag', &
364  'The Grid points of input data too large.')
365  endif
366 
367  a_int_ag = 0.0d0
368  do i=0,im-1
369  a_int_ag(:) = a_int_ag(:) + ag(:,i)*g_x_weight(i)
370  enddo
371  end function a_int_ag
372 
373  !-----------------------------------------------------------------------
375  function int_g(g)
377  real(DP), dimension(0:im-1), intent(in) :: g
379  real(DP) :: Int_g
380 
381  int_g = sum(g*g_x_weight)
382 
383  end function int_g
384 
385  !-----------------------------------------------------------------------
387  function a_avr_ag(ag)
389  real(DP), dimension(:,0:), intent(in) :: ag
391  real(DP), dimension(size(ag,1)) :: a_Avr_ag
392 
393  a_avr_ag = a_int_ag(ag)/sum(g_x_weight)
394 
395  end function a_avr_ag
396 
397  !-----------------------------------------------------------------------
399  function avr_g(g)
401  real(DP), dimension(0:im-1), intent(in) :: g
403  real(DP) :: Avr_g
404 
405  avr_g = int_g(g)/sum(g_x_weight)
406 
407  end function avr_g
408 
409  !-----------------------------------------------------------------------
411  function interpolate_e(e_data,xval)
413  real(DP), dimension(-km:km), intent(IN) :: e_data
415  real(DP), intent(in) :: xval
417  real(DP) :: Interpolate_e
418 
419  integer(8) :: k
420 
421  interpolate_e = e_data(0)
422  do k=1,km
423  interpolate_e = interpolate_e &
424  & + 2.0d0 * ( e_data(k) * cos(2*pi*k/xl*xval) &
425  & - e_data(-k) * sin(2*pi*k/xl*xval) )
426  end do
427 
428  end function interpolate_e
429 
430  !-----------------------------------------------------------------------
432  function a_interpolate_ae(ae_data,xval)
434  real(DP), dimension(:,-km:), intent(IN) :: ae_data
436  real(DP), intent(in) :: xval
438  real(DP), dimension(size(ae_data,1)) :: a_Interpolate_ae
439 
440  integer(8) :: k
441 
442  a_interpolate_ae = ae_data(:,0)
443 
444  do k=1,km
445  a_interpolate_ae = a_interpolate_ae &
446  & + 2.0d0 * ( ae_data(:,k) * cos(2*pi*k/xl*xval) &
447  & - ae_data(:,-k) * sin(2*pi*k/xl*xval) )
448  end do
449 
450  end function a_interpolate_ae
451 
452 end module ae_module
real(dp) function, dimension(size(ag, 1)), public a_avr_ag(ag)
1 次元格子点データが並んだ 2 次元配列の平均
Definition: ae_module.f90:388
real(dp) function, dimension(size(ae, 1), 0:im-1), public ag_ae(ae)
スペクトルデータから格子点データへ逆変換する(2 次元データ用)
Definition: ae_module.f90:176
real(dp), dimension(:), allocatable, save, public g_x_weight
重み座標を格納した 1 次元配列. X方向の格子点の間隔が格納してある.
Definition: ae_module.f90:104
real(dp) function, dimension(-km:km), public e_g(g)
格子点データからスペクトルデータへ正変換する(1 次元データ用)
Definition: ae_module.f90:290
real(dp) function, dimension(0:im-1), public g_e(e)
スペクトルデータから格子点データへ逆変換する(1 次元データ用)
Definition: ae_module.f90:217
real(dp) function, dimension(size(ag, 1),-km:km), public ae_ag(ag)
格子点データからスペクトルデータへ正変換する(2 次元データ用)
Definition: ae_module.f90:245
real(dp) function, public avr_g(g)
1 次元格子点データの平均
Definition: ae_module.f90:400
subroutine, public ae_initial(i, k, xmin, xmax)
スペクトル変換の格子点数, 波数, 領域の大きさを設定する.
Definition: ae_module.f90:122
real(dp) function, public interpolate_e(e_data, xval)
補間計算(1次元)
Definition: ae_module.f90:412
real(dp) function, dimension(size(ae_data, 1)), public a_interpolate_ae(ae_data, xval)
補間計算(2次元)
Definition: ae_module.f90:433
real(dp) function, dimension(-km:km), public e_dx_e(e)
入力スペクトルデータに X 微分を作用する(1 次元データ).
Definition: ae_module.f90:336
1 次元周期境界: 実フーリエ変換
Definition: ae_module.f90:78
real(dp) function, public int_g(g)
1 次元格子点データの積分
Definition: ae_module.f90:376
real(dp), dimension(:), allocatable, save, public g_x
格子点座標(X)を格納した1次元配列.
Definition: ae_module.f90:102
real(dp) function, dimension(size(ag, 1)), public a_int_ag(ag)
1 次元格子点データが並んだ 2 次元配列の積分
Definition: ae_module.f90:352
real(dp) function, dimension(size(ae, 1),-km:km), public ae_dx_ae(ae)
入力スペクトルデータに X 微分を作用する(2 次元データ).
Definition: ae_module.f90:310