5 #include <PB3D_macros.h>
58 module procedure fourier2real_1
60 module procedure fourier2real_2
65 integer function fourier2real_1(varf_c,varf_s,trigon_factors,varr,sym,&
68 character(*),
parameter :: rout_name =
'fourier2real_1'
71 real(
dp),
intent(in) :: varf_c(:,:)
72 real(
dp),
intent(in) :: varf_s(:,:)
73 real(
dp),
intent(in) :: trigon_factors(:,:,:,:,:)
74 real(
dp),
intent(inout) :: varr(:,:,:)
75 logical,
intent(in),
optional :: sym(2)
76 integer,
intent(in),
optional :: deriv(2)
79 character(len=max_str_ln) :: err_msg
82 integer :: deriv_loc(2)
91 sym_loc = [.true.,.true.]
92 if (
present(deriv)) deriv_loc = deriv
93 if (
present(sym)) sym_loc = sym
99 if (.not.sym_loc(1) .and. .not.sym_loc(2))
then
101 err_msg =
'Need at least the cosine or the sine factor'
104 if (
size(trigon_factors,1).ne.mnmax_v .and. &
105 &
size(trigon_factors,2).ne.dims(1) .and. &
106 &
size(trigon_factors,3).ne.dims(2) .and. &
107 &
size(trigon_factors,4).ne.dims(3) .and. &
108 &
size(trigon_factors,5).ne.2)
then
110 err_msg =
'Trigonometric factors are not set up'
120 deriv_fac =
mn_v(id,1)**deriv_loc(1)*(-
mn_v(id,2))**deriv_loc(2)*&
121 &(-1)**((sum(deriv_loc)+1)/2)
125 if (mod(sum(deriv_loc),2).eq.0)
then
127 varr(:,:,kd) = varr(:,:,kd) + &
128 &varf_c(id,kd) * deriv_fac * &
129 &trigon_factors(id,:,:,kd,1)
133 varr(:,:,kd) = varr(:,:,kd) + &
134 &varf_c(id,kd) * deriv_fac * &
135 &trigon_factors(id,:,:,kd,2)
141 deriv_fac =
mn_v(id,1)**deriv_loc(1)*(-
mn_v(id,2))**deriv_loc(2)*&
142 &(-1)**(sum(deriv_loc)/2)
146 if (mod(sum(deriv_loc),2).eq.0)
then
148 varr(:,:,kd) = varr(:,:,kd) + &
149 &varf_s(id,kd) * deriv_fac * &
150 &trigon_factors(id,:,:,kd,2)
154 varr(:,:,kd) = varr(:,:,kd) + &
155 &varf_s(id,kd) * deriv_fac * &
156 &trigon_factors(id,:,:,kd,1)
161 end function fourier2real_1
163 integer function fourier2real_2(varf_c,varf_s,theta,zeta,varr,sym,deriv) &
166 character(*),
parameter :: rout_name =
'fourier2real_2'
169 real(
dp),
intent(in) :: varf_c(:,:)
170 real(
dp),
intent(in) :: varf_s(:,:)
171 real(
dp),
intent(in) :: theta(:,:,:)
172 real(
dp),
intent(in) :: zeta(:,:,:)
173 real(
dp),
intent(inout) :: varr(:,:,:)
174 logical,
intent(in),
optional :: sym(2)
175 integer,
intent(in),
optional :: deriv(2)
179 character(len=max_str_ln) :: err_msg
182 integer :: deriv_loc(2)
183 logical :: sym_loc(2)
184 real(
dp) :: deriv_fac
185 real(
dp),
allocatable :: ang(:,:,:)
192 sym_loc = [.true.,.true.]
193 if (
present(deriv)) deriv_loc = deriv
194 if (
present(sym)) sym_loc = sym
197 if (.not.sym_loc(1) .and. .not.sym_loc(2))
then
199 err_msg =
'Need at least the cosine or the sine factor'
207 allocate(ang(dims(1),dims(2),dims(3)))
215 ang =
mn_v(id,1)*theta -
mn_v(id,2)*zeta
218 deriv_fac =
mn_v(id,1)**deriv_loc(1)*(-
mn_v(id,2))**deriv_loc(2)*&
219 &(-1)**((sum(deriv_loc)+1)/2)
223 if (mod(sum(deriv_loc),2).eq.0)
then
225 varr(:,:,kd) = varr(:,:,kd) + &
226 &varf_c(id,kd) * deriv_fac * cos(ang(:,:,kd))
230 varr(:,:,kd) = varr(:,:,kd) + &
231 &varf_c(id,kd) * deriv_fac * sin(ang(:,:,kd))
237 deriv_fac =
mn_v(id,1)**deriv_loc(1)*(-
mn_v(id,2))**deriv_loc(2)*&
238 &(-1)**(sum(deriv_loc)/2)
242 if (mod(sum(deriv_loc),2).eq.0)
then
244 varr(:,:,kd) = varr(:,:,kd) + &
245 &varf_s(id,kd) * deriv_fac * sin(ang(:,:,kd))
249 varr(:,:,kd) = varr(:,:,kd) + &
250 &varf_s(id,kd) * deriv_fac * cos(ang(:,:,kd))
255 end function fourier2real_2
276 character(*),
parameter :: rout_name =
'calc_trigon_factors'
279 real(
dp),
intent(in) :: theta(:,:,:)
280 real(
dp),
intent(in) :: zeta(:,:,:)
281 real(
dp),
intent(inout),
allocatable :: trigon_factors(:,:,:,:,:)
284 character(len=max_str_ln) :: err_msg
285 integer :: n_ang_1, n_ang_2, n_r
286 real(
dp),
allocatable :: cos_theta(:,:,:,:)
287 real(
dp),
allocatable :: sin_theta(:,:,:,:)
288 real(
dp),
allocatable :: cos_zeta(:,:,:,:)
289 real(
dp),
allocatable :: sin_zeta(:,:,:,:)
296 n_ang_1 =
size(theta,1)
297 n_ang_2 =
size(theta,2)
302 call writo(
'Calculate trigonometric factors for grid of size ['//&
303 &trim(
i2str(n_ang_1))//
','//trim(
i2str(n_ang_2))//
','//&
304 &trim(
i2str(n_r))//
']')
309 if (
size(zeta,1).ne.n_ang_1 .or.
size(zeta,2).ne.n_ang_2 .or. &
310 &
size(zeta,3).ne.n_r)
then
312 err_msg =
'theta and zeta need to have the same size'
317 allocate(cos_theta(0:mpol_v-1,n_ang_1,n_ang_2,n_r))
318 allocate(sin_theta(0:mpol_v-1,n_ang_1,n_ang_2,n_r))
319 allocate(cos_zeta(-ntor_v:ntor_v,n_ang_1,n_ang_2,n_r))
320 allocate(sin_zeta(-ntor_v:ntor_v,n_ang_1,n_ang_2,n_r))
325 call writo(
'Calculating for m = '//trim(
i2str(m))//&
326 &
' of [0..'//trim(
i2str(mpol_v-1))//
']')
329 cos_theta(m,:,:,:) = cos(m*theta)
330 sin_theta(m,:,:,:) = sin(m*theta)
332 do n = -ntor_v,ntor_v
335 call writo(
'Calculating for n = '//trim(
i2str(n))//&
336 &
' of ['//trim(
i2str(-ntor_v))//
'..'//&
337 &trim(
i2str(ntor_v))//
']')
340 cos_zeta(n,:,:,:) = cos(n*nfp_v*zeta)
341 sin_zeta(n,:,:,:) = sin(n*nfp_v*zeta)
345 allocate(trigon_factors(mnmax_v,n_ang_1,n_ang_2,n_r,2),stat=ierr)
346 chckerr(
'Failed to allocate trigonometric factors')
347 trigon_factors = 0.0_dp
357 call writo(
'Calculating for id = '//trim(
i2str(id))//&
358 &
' of [1..'//trim(
i2str(mnmax_v))//
']')
361 trigon_factors(id,:,:,:,1) = &
362 &cos_theta(
mn_v(id,1),:,:,:)*&
363 &cos_zeta(
mn_v(id,2)/nfp_v,:,:,:) + &
364 &sin_theta(
mn_v(id,1),:,:,:)*&
365 &sin_zeta(
mn_v(id,2)/nfp_v,:,:,:)
366 trigon_factors(id,:,:,:,2) = &
367 &sin_theta(
mn_v(id,1),:,:,:)*&
368 &cos_zeta(
mn_v(id,2)/nfp_v,:,:,:) - &
369 &cos_theta(
mn_v(id,1),:,:,:)*&
370 &sin_zeta(
mn_v(id,2)/nfp_v,:,:,:)
374 deallocate(cos_theta,sin_theta)
375 deallocate(cos_zeta,sin_zeta)