17 USE descriptor_mod,
ONLY: inhessian, diagonaldone
34 INTEGER,
PARAMETER ::
f_ds = 1
36 INTEGER,
PARAMETER ::
f_du = 2
38 INTEGER,
PARAMETER ::
f_dv = 4
47 INTEGER,
PARAMETER ::
b_ds = 0
49 INTEGER,
PARAMETER ::
b_du = 1
51 INTEGER,
PARAMETER ::
b_dv = 2
58 INTEGER,
PARAMETER ::
m0 = 0
60 INTEGER,
PARAMETER ::
m1 = 1
62 INTEGER,
PARAMETER ::
m2 = 2
65 INTEGER,
PARAMETER ::
n0 = 0
67 INTEGER,
PARAMETER ::
n1 = 1
79 REAL (dp),
DIMENSION(:,:),
POINTER :: orthonorm => null()
81 REAL (dp),
DIMENSION(:,:),
POINTER :: cosmu => null()
83 REAL (dp),
DIMENSION(:,:),
POINTER :: cosmum => null()
85 REAL (dp),
DIMENSION(:,:),
POINTER :: cosmui => null()
87 REAL (dp),
DIMENSION(:,:),
POINTER :: cosnv => null()
89 REAL (dp),
DIMENSION(:,:),
POINTER :: cosnvn => null()
91 REAL (dp),
DIMENSION(:,:),
POINTER :: sinmu => null()
93 REAL (dp),
DIMENSION(:,:),
POINTER :: sinmum => null()
95 REAL (dp),
DIMENSION(:,:),
POINTER :: sinmui => null()
97 REAL (dp),
DIMENSION(:,:),
POINTER :: sinnv => null()
99 REAL (dp),
DIMENSION(:,:),
POINTER :: sinnvn => null()
101 REAL (dp),
DIMENSION(:,:),
POINTER :: workmj1 => null()
103 REAL (dp),
DIMENSION(:,:),
POINTER :: workmj2 => null()
105 REAL (dp),
DIMENSION(:,:),
POINTER :: workin1 => null()
107 REAL (dp),
DIMENSION(:,:),
POINTER :: workin2 => null()
111 generic :: toijsp => toijsp_2d, toijsp_3d
119 generic :: tomnsp => tomnsp_2d, tomnsp_3d, tomnsp_2d_u,
120 tomnsp_2d_v, tomnsp_3d_pest,
121 tomnsp_2d_pest, tomnsp_2d_u_pest
185 INTEGER,
INTENT(in) :: mpol
186 INTEGER,
INTENT(in) :: ntor
187 INTEGER,
INTENT(in) :: ntheta
188 INTEGER,
INTENT(in) :: nzeta
189 INTEGER,
INTENT(in) :: nfp
190 LOGICAL,
INTENT(in) :: sym
200 REAL (dp),
PARAMETER :: nfactor = 1.41421356237310_dp
206 dnorm = one/(ntheta*nzeta)
207 pi_norm = twopi/ntheta
209 dnorm = one/((ntheta - 1)*nzeta)
210 pi_norm = pi/(ntheta - 1)
222 arg = pi_norm*(i - 1)
237 IF (.not.sym .and. (i .eq. 1 .or. i .eq. ntheta))
THEN
254 arg = (twopi*(i - 1))/nzeta
277 IF (ntheta .eq. mpol + 1)
THEN
304 TYPE (fourier_class),
INTENT(inout) :: this
307 IF (
ASSOCIATED(this%orthonorm))
THEN
308 DEALLOCATE(this%orthonorm)
309 this%orthonorm => null()
312 IF (
ASSOCIATED(this%cosmu))
THEN
313 DEALLOCATE(this%cosmu)
317 IF (
ASSOCIATED(this%cosmum))
THEN
318 DEALLOCATE(this%cosmum)
319 this%cosmum => null()
322 IF (
ASSOCIATED(this%cosmui))
THEN
323 DEALLOCATE(this%cosmui)
324 this%cosmui => null()
327 IF (
ASSOCIATED(this%cosnv))
THEN
328 DEALLOCATE(this%cosnv)
332 IF (
ASSOCIATED(this%cosnvn))
THEN
333 DEALLOCATE(this%cosnvn)
334 this%cosnvn => null()
337 IF (
ASSOCIATED(this%sinmu))
THEN
338 DEALLOCATE(this%sinmu)
342 IF (
ASSOCIATED(this%sinmum))
THEN
343 DEALLOCATE(this%sinmum)
344 this%sinmum => null()
347 IF (
ASSOCIATED(this%sinmui))
THEN
348 DEALLOCATE(this%sinmui)
349 this%sinmui => null()
352 IF (
ASSOCIATED(this%sinnv))
THEN
353 DEALLOCATE(this%sinnv)
357 IF (
ASSOCIATED(this%sinnvn))
THEN
358 DEALLOCATE(this%sinnvn)
359 this%sinnvn => null()
362 IF (
ASSOCIATED(this%workmj1))
THEN
363 DEALLOCATE(this%workmj1)
364 this%workmj1 => null()
367 IF (
ASSOCIATED(this%workmj2))
THEN
368 DEALLOCATE(this%workmj2)
369 this%workmj2 => null()
372 IF (
ASSOCIATED(this%workin1))
THEN
373 DEALLOCATE(this%workin1)
374 this%workin1 => null()
377 IF (
ASSOCIATED(this%workin2))
THEN
378 DEALLOCATE(this%workin2)
379 this%workin2 => null()
404 REAL (dp),
DIMENSION(:,:,:),
INTENT(in) :: xuv
405 REAL (dp),
DIMENSION(:,:,:),
INTENT(out) :: xmn
406 INTEGER,
INTENT(in) :: parity
416 DO js = 1, min(
SIZE(xmn,3),
SIZE(xuv,3))
417 CALL this%tomnsp(xuv(:,:,js), xmn(:,:,js), parity)
420 CALL second0(skstoff)
421 IF (diagonaldone .and. inhessian)
THEN
422 time_tomnsp = time_tomnsp + (skstoff - skston)
425 time_tomnsp = time_tomnsp + (skstoff - skston)
450 REAL (dp),
DIMENSION(:,:,:),
INTENT(in) :: xuv
451 REAL (dp),
DIMENSION(:,:,:),
INTENT(out) :: xmn
452 REAL (dp),
DIMENSION(:,:,:),
INTENT(in) :: lmns
453 REAL (dp),
DIMENSION(:,:,:),
INTENT(in) :: lmnc
454 INTEGER,
INTENT(in) :: parity
455 LOGICAL,
INTENT(in) :: asym
459 REAL (dp),
ALLOCATABLE,
DIMENSION(:,:,:) :: lambda
460 REAL (dp),
ALLOCATABLE,
DIMENSION(:,:,:) :: dupdu
468 ns = min(
SIZE(xmn,3),
SIZE(xuv,3),
SIZE(lmns, 3))
471 ALLOCATE(lambda(
SIZE(xuv,1),
SIZE(xuv,2),ns))
472 ALLOCATE(dupdu(
SIZE(xuv,1),
SIZE(xuv,2),ns))
475 CALL this%toijsp(lmns, dupdu,
f_du,
f_sin)
485 lambda(:,:,1) = lambda(:,:,2)
486 dupdu(:,:,1) = dupdu(:,:,2)
488 lambda(:,:,js) = 0.5*(lambda(:,:,js) + lambda(:,:,js + 1))
489 lambda(:,:,js) = 0.5*(lambda(:,:,js) + lambda(:,:,js + 1))
491 lambda(:,:,ns) = 2*lambda(:,:,ns) - lambda(:,:,ns - 1)
492 dupdu(:,:,ns) = 2*dupdu(:,:,ns) - dupdu(:,:,ns - 1)
495 CALL this%tomnsp(xuv(:,:,js), xmn(:,:,js), lambda(:,:,js),
496 dupdu(:,:,js), parity, asym)
503 IF (diagonaldone.AND.inhessian)
THEN
504 tomnsp_time = tomnsp_time + (toff - ton)
507 time_tomnsp = time_tomnsp + (toff - ton)
528 REAL (dp),
DIMENSION(:,:),
INTENT(in) :: xuv
529 REAL (dp),
DIMENSION(:,:),
INTENT(out) :: xmn
530 INTEGER,
INTENT(in) :: parity
534 CALL this%tomnsp(xuv)
536 CALL this%tomnsp(xmn, parity)
561 REAL (dp),
DIMENSION(:,:),
INTENT(in) :: xuv
562 REAL (dp),
DIMENSION(:,:),
INTENT(out) :: xmn
563 REAL (dp),
DIMENSION(:,:),
INTENT(in) :: lambda
564 REAL (dp),
DIMENSION(:,:),
INTENT(in) :: dupdu
565 INTEGER,
INTENT(in) :: parity
566 LOGICAL,
INTENT(in) :: asym
570 CALL this%tomnsp(xuv, lambda, dupdu, asym)
572 CALL this%tomnsp(xmn, parity)
592 REAL (dp),
DIMENSION(:,:),
INTENT(in) :: xuv
602 DO j = 1,
SIZE(xuv, 2)
603 DO m =
m0, ubound(this%cosmu, 2)
604 this%workmj1(m,j) = dot_product(xuv(:,j), this%cosmui(:,m))
605 this%workmj2(m,j) = dot_product(xuv(:,j), this%sinmui(:,m))
630 REAL (dp),
DIMENSION(:,:),
INTENT(in) :: xuv
631 REAL (dp),
DIMENSION(:,:),
INTENT(in) :: lambda
632 REAL (dp),
DIMENSION(:,:),
INTENT(in) :: dupdu
633 LOGICAL,
INTENT(in) :: asym
666 DO j = 1,
SIZE(xuv, 2)
667 DO m =
m0, ubound(this%cosmu, 2)
668 this%workmj1(m,j) = 0
669 this%workmj2(m,j) = 0
670 DO i = 1,
SIZE(xuv, 1)
674 ELSE IF (m .eq.
m1)
THEN
675 cosml = cos(lambda(i,j))*dupdu(i,j)
676 sinml = sin(lambda(i,j))*dupdu(i,j)
679 cosml = cosml*cos(lambda(i,j)) - sinml*sin(lambda(i,j)
680 sinml = sinml*cos(lambda(i,j)) + templ*sin(lambda(i,j)
683 cosmuip = this%cosmui(i,m)*cosml - this%sinmui(i,m)*sinml
684 sinmuip = this%sinmui(i,m)*cosml + this%cosmui(i,m)*sinml
686 this%workmj1(m,j) = this%workmj1(m,j) + xuv(i,j)*cosmuip
687 this%workmj2(m,j) = this%workmj2(m,j) + xuv(i,j)*sinmuip
712 REAL (dp),
DIMENSION(:,:),
INTENT(out) :: xmn
713 INTEGER,
INTENT(in) :: parity
726 noff = lbound(xmn,2) + ubound(this%cosnv,2)
730 DO n =
n0, ubound(this%cosnv, 2)
731 DO j = 1,
SIZE(this%cosnv, 1)
732 DO m =
m0, ubound(this%cosmu, 2)
733 IF (parity .eq.
f_cos)
THEN
734 workcos = this%workmj1(m,j)*this%cosnv(j,n)
735 worksin = this%workmj2(m,j)*this%sinnv(j,n)
737 xmn(m + moff,n + noff) = xmn(m + moff,n + noff)
740 IF (n .ne.
n0 .and. m .ne.
m0)
THEN
741 xmn(m + moff,-n + noff) = xmn(m + moff,-n + noff)
745 workcos = this%workmj2(m,j)*this%cosnv(j,n)
746 worksin = this%workmj1(m,j)*this%sinnv(j,n)
747 xmn(m + moff,n + noff) = xmn(m + moff,n + noff)
750 xmn(m + moff,-n + noff) = xmn(m + moff,-n + noff)
758 IF (parity .eq.
f_cos)
THEN
759 xmn(
m0 + moff,:-
n1 + noff) = zero
761 xmn(
m0 + moff,:
n0 + noff) = zero
764 xmn = this%orthonorm*xmn
788 REAL (dp),
DIMENSION(:,:,:),
INTENT(in) :: xmn
789 REAL (dp),
DIMENSION(:,:,:),
INTENT(inout) :: xuv
790 INTEGER,
INTENT(in) :: dflag
791 INTEGER,
INTENT(in) :: parity
801 DO js = 1, min(
SIZE(xmn,3),
SIZE(xuv,3))
802 CALL this%toijsp(xmn(:,:,js), xuv(:,:,js), dflag, parity)
805 CALL second0(skstoff)
806 IF (diagonaldone .AND. inhessian)
THEN
807 toijsp_time = toijsp_time + (skstoff - skston)
810 time_toijsp = time_toijsp + (skstoff - skston)
831 REAL (dp),
DIMENSION(:,:),
INTENT(in) :: xmn
832 REAL (dp),
DIMENSION(:,:),
INTENT(inout) :: xuv
833 INTEGER,
INTENT(in) :: parity
834 INTEGER,
INTENT(in) :: dflag
843 REAL (dp),
DIMENSION(:,:),
POINTER :: anglem1
844 REAL (dp),
DIMENSION(:,:),
POINTER :: anglem2
846 REAL (dp),
DIMENSION(:,:),
POINTER :: anglen1
847 REAL (dp),
DIMENSION(:,:),
POINTER :: anglen2
854 noff = lbound(xmn,2) + ubound(this%cosnv,2)
857 IF (btest(dflag,
b_du))
THEN
858 anglem1 => this%sinmum
859 anglem2 => this%cosmum
862 anglem1 => this%cosmu
863 anglem2 => this%sinmu
871 DO n = lbound(this%workin1, 2), ubound(this%workin1, 2)
872 DO m = 0, ubound(this%cosmu, 2)
873 workmn = this%orthonorm(m,n)*xmn(m + moff,n + noff)
875 this%workin1(:,n) = this%workin1(:,n) + msign*workmn*anglem1
876 this%workin2(:,n) = this%workin2(:,n) + workmn*anglem2(:,m)
880 IF (parity .eq.
f_cos)
THEN
882 IF (btest(dflag,
b_dv))
THEN
883 anglen1 => this%sinnvn
884 anglen2 => this%cosnvn
888 anglen1 => this%cosnv
889 anglen2 => this%sinnv
895 IF (btest(dflag,
b_dv))
THEN
896 anglen1 => this%cosnvn
897 anglen2 => this%sinnvn
901 anglen1 => this%sinnv
902 anglen2 => this%cosnv
908 IF (.not.btest(dflag,
b_sum))
THEN
913 IF (.not.btest(dflag,
b_dv))
THEN
914 IF (parity .eq.
f_cos)
THEN
915 DO j = 1,
SIZE(xuv, 2)
916 xuv(:,j) = this%workin1(:,
n0) + xuv(:,j)
919 DO j = 1,
SIZE(xuv, 2)
920 xuv(:,j) = this%workin2(:,
n0) + xuv(:,j)
926 DO n =
n1, ubound(this%cosnv, 2)
927 DO j = 1,
SIZE(xuv, 2)
929 + nsign1*(this%workin1(:,n) +
930 nsign3*this%workin1(:,-n))*anglen1(j,n)
931 + nsign2*(this%workin2(:,n) -
932 nsign3*this%workin2(:,-n))*anglen2(j,n)
954 REAL(dp),
DIMENSION(:,:,:),
ALLOCATABLE,
INTENT(inout) :: xuv
955 INTEGER,
INTENT(in) :: mode
956 LOGICAL,
INTENT(in) :: asym
959 REAL(dp),
DIMENSION(:,:),
ALLOCATABLE :: xmn_cos
960 REAL(dp),
DIMENSION(:,:),
ALLOCATABLE :: xmn_sin
963 INTEGER,
PARAMETER :: js1 = 1
964 integer,
PARAMETER :: js2 = 2
970 ALLOCATE(xmn_cos(0:ubound(this%cosmu,2),
971 -ubound(this%cosnv,2):ubound(this%cosnv,2)))
972 CALL this%tomnsp(xuv(:,:,js2), xmn_cos(:,:),
f_cos)
974 IF (mode .gt. 0)
THEN
975 xmn_cos(0:mode - 1,:) = 0
977 IF (mode .lt. ubound(this%cosmu,2))
THEN
978 xmn_cos(mode + 1,:) = 0
982 ALLOCATE(xmn_sin(0:ubound(this%cosmu,2),
983 -ubound(this%cosnv,2):ubound(this%cosnv,2)))
984 CALL this%tomnsp(xuv(:,:,js2), xmn_sin(:,:),
f_sin)
986 IF (mode .gt. 0)
THEN
987 xmn_sin(0:mode - 1,:) = 0
989 IF (mode .lt. ubound(this%cosmu,2))
THEN
990 xmn_sin(mode + 1,:) = 0
994 CALL this%toijsp(xmn_cos(:,:), xuv(:,:,js1),
f_cos,
f_none)
998 CALL this%toijsp(xmn_sin(:,:), xuv(:,:,js1),
f_sin,
f_sum)
1015 REAL (dp),
INTENT(inout) :: cosi
1016 REAL (dp),
INTENT(inout) :: sini
1022 eps = 10*epsilon(eps)
1024 IF (abs(cosi - 1) .le. eps)
THEN
1027 ELSE IF (abs(cosi + 1) .le. eps)
THEN
1030 ELSE IF (abs(sini - 1) .le. eps)
THEN
1033 ELSE IF (abs(sini + 1) .le. eps)
THEN
1050 USE timer_mod,
ONLY: test_fourier_time
1060 REAL(dp),
ALLOCATABLE,
DIMENSION(:,:) :: testij
1061 REAL(dp),
ALLOCATABLE,
DIMENSION(:,:) :: testmn
1062 REAL(dp),
ALLOCATABLE,
DIMENSION(:,:) :: result
1066 INTEGER,
PARAMETER :: pol = 10
1067 integer,
PARAMETER :: tor = 10
1068 INTEGER,
PARAMETER :: theta = 33
1069 INTEGER,
PARAMETER :: zeta = 34
1070 INTEGER,
PARAMETER :: nfp = 5
1073 ALLOCATE(testij(theta,zeta))
1074 ALLOCATE(testmn(0:pol,-tor:tor))
1075 ALLOCATE(result(0:pol,-tor:tor))
1082 IF (m .eq.
m0 .and. n .lt.
n0)
THEN
1090 CALL four%tomnsp(testij, result,
f_cos)
1092 check(testmn, result, pol, tor,
1093 'cosine_parity_test')
1096 IF (m .eq.
m0 .and. n .eq.
n0)
THEN
1102 CALL four%tomnsp(testij, result,
f_sin)
1104 check(testmn, result, pol, tor,
1110 CALL four%toijsp(testmn, testij,
f_du,
f_cos)
1111 CALL four%tomnsp(testij, result,
f_sin)
1114 check(testmn, result, pol, tor,
1115 'du_cosine_parity_test')
1120 CALL four%toijsp(testmn, testij,
f_dv,
f_cos)
1121 CALL four%tomnsp(testij, result,
f_sin)
1122 testmn(m,n) = -n*nfp
1124 check(testmn, result, pol, tor,
1125 'dv_cosine_parity_test')
1130 CALL four%toijsp(testmn, testij,
f_du,
f_sin)
1131 CALL four%tomnsp(testij, result,
f_cos)
1134 check(testmn, result, pol, tor,
1135 'du_sine_parity_test')
1140 CALL four%toijsp(testmn, testij,
f_dv,
f_sin)
1141 CALL four%tomnsp(testij, result,
f_cos)
1144 check(testmn, result, pol, tor,
1145 'dv_sine_parity_test')
1169 FUNCTION check_mn(expected, received, m, n, name)
1175 REAL (rprec),
INTENT(in) :: expected
1176 REAL (rprec),
INTENT(in) :: received
1177 INTEGER,
INTENT(in) :: m
1178 INTEGER,
INTENT(in) :: n
1179 CHARACTER (len=*),
INTENT(in) :: name
1182 REAL (rprec),
PARAMETER :: eps = 1.e-12_dp
1185 check_mn = abs(expected - received) .lt. eps
1187 WRITE (*,1000) trim(name), m, n, expected, received
1190 1000
FORMAT(
'fourier.f90: 'a,
' m = ',i3,
' n = ',i3,
' test failed.',/,
1191 'Expected ',e12.3,
' Recieved ',e12.3)
1202 FUNCTION check_all(expected, received, mpol, ntor, name)
1208 REAL (rprec),
DIMENSION(:,:),
INTENT(in) :: expected
1209 REAL (rprec),
DIMENSION(:,:),
INTENT(in) :: received
1210 INTEGER,
INTENT(in) :: mpol
1211 INTEGER,
INTENT(in) :: ntor
1212 CHARACTER (len=*),
INTENT(in) :: name
1221 moff = lbound(expected, 1)
1222 noff = lbound(expected, 2) + ntor
1229 received(m + moff, n + noff