*IF DEF,C91_1B FOURIE2A.2
C ******************************COPYRIGHT****************************** FOURIE2A.3
C (c) CROWN COPYRIGHT 1995, METEOROLOGICAL OFFICE, All Rights Reserved. FOURIE2A.4
C FOURIE2A.5
C Use, duplication or disclosure of this code is subject to the FOURIE2A.6
C restrictions as set forth in the contract. FOURIE2A.7
C FOURIE2A.8
C Meteorological Office FOURIE2A.9
C London Road FOURIE2A.10
C BRACKNELL FOURIE2A.11
C Berkshire UK FOURIE2A.12
C RG12 2SZ FOURIE2A.13
C FOURIE2A.14
C If no contract has been raised with this copy of the code, the use, FOURIE2A.15
C duplication or disclosure of it is strictly prohibited. Permission FOURIE2A.16
C to do so must first be obtained in writing from the Head of Numerical FOURIE2A.17
C Modelling at the above address. FOURIE2A.18
C ******************************COPYRIGHT****************************** FOURIE2A.19
!+ Perform multiple fast fourier transforms FOURIE2A.20
! Subroutine Interface: FOURIE2A.21
SUBROUTINE FOURIER(A,TRIGS,IFAX,INC,JUMP,N,LOT,ISIGN) 8,6FOURIE2A.22
FOURIE2A.23
IMPLICIT NONE FOURIE2A.24
! Description: FOURIE2A.25
! FOURIE2A.26
! SUBROUTINE 'FOURIER' - MULTIPLE FAST REAL PERIODIC TRANSFORM FOURIE2A.27
! UNIFIED MODEL RE-WRITE OF ECMWF ROUTINE FFT991 FOURIE2A.28
! FOURIE2A.29
! Method: FOURIE2A.30
! REAL TRANSFORM OF LENGTH N PERFORMED BY REMOVING REDUNDANT FOURIE2A.31
! OPERATIONS FROM COMPLEX TRANSFORM OF LENGTH N FOURIE2A.32
! FOURIE2A.33
! INPUT INFORMATION ... FOURIE2A.34
! A IS THE ARRAY CONTAINING INPUT & OUTPUT DATA FOURIE2A.35
! TRIGS IS A PREVIOUSLY PREPARED LIST OF TRIG FUNCTION VALUES FOURIE2A.36
! IFAX IS A PREVIOUSLY PREPARED LIST OF FACTORS OF N FOURIE2A.37
! INC IS THE INCREMENT WITHIN EACH DATA 'VECTOR' FOURIE2A.38
! (E.G. INC=1 FOR CONSECUTIVELY STORED DATA) FOURIE2A.39
! JUMP IS THE INCREMENT BETWEEN THE START OF EACH DATA VECTOR FOURIE2A.40
! N IS THE LENGTH OF THE DATA VECTORS FOURIE2A.41
! LOT IS THE NUMBER OF DATA VECTORS FOURIE2A.42
! ISIGN = +1 FOR TRANSFORM FROM SPECTRAL TO GRIDPOINT FOURIE2A.43
! = -1 FOR TRANSFORM FROM GRIDPOINT TO SPECTRAL FOURIE2A.44
! FOURIE2A.45
! ORDERING OF COEFFICIENTS: FOURIE2A.46
! A(0),B(0),A(1),B(1),A(2),B(2),...,A(N/2),B(N/2) FOURIE2A.47
! WHERE B(0)=B(N/2)=0; (N+2) LOCATIONS REQUIRED FOURIE2A.48
! FOURIE2A.49
! ORDERING OF DATA: FOURIE2A.50
! X(0),X(1),X(2),...,X(N-1), 0 , 0 ; (N+2) LOCATIONS REQUIRED FOURIE2A.51
! FOURIE2A.52
! VECTORIZATION IS ACHIEVED ON CRAY BY DOING THE TRANSFORMS FOURIE2A.53
! IN PARALLEL FOURIE2A.54
! FOURIE2A.55
! N MUST BE COMPOSED OF FACTORS 2,3 & 5 BUT DOES NOT HAVE TO BE EVEN FOURIE2A.56
! FOURIE2A.57
! DEFINITION OF TRANSFORMS: FOURIE2A.58
! ------------------------- FOURIE2A.59
! FOURIE2A.60
! ISIGN=+1: X(J)=SUM(K=0,...,N-1)(C(K)*EXP(2*I*J*K*PI/N)) FOURIE2A.61
! WHERE C(K)=A(K)+I*B(K) AND C(N-K)=A(K)-I*B(K) FOURIE2A.62
! FOURIE2A.63
! ISIGN=-1: A(K)=(1/N)*SUM(J=0,...,N-1)(X(J)*COS(2*J*K*PI/N)) FOURIE2A.64
! B(K)=-(1/N)*SUM(J=0,...,N-1)(X(J)*SIN(2*J*K*PI/N)) FOURIE2A.65
! .................................................................. FOURIE2A.66
! MULTITASKING NOTE: ERROR TRAPPING NOT WORKING IN PRESENT FORM IF FOURIE2A.67
! CODE IS MULTITASKED. FOURIE2A.68
! FOURIE2A.69
! NOT SUITABLE FOR SINGLE COLUMN USE. FOURIE2A.70
! FOURIE2A.71
! Current code owner: M Mawson FOURIE2A.72
! FOURIE2A.73
! History: FOURIE2A.74
! Version Date Comment FOURIE2A.75
! ======= ==== ======= FOURIE2A.76
! 4.1 June 96 Original code at 4.1. Based on modification by FOURIE2A.77
! Cray Research to access Cray specific ffts FOURIE2A.78
! instead of those developed originally by FOURIE2A.79
! ECMWF. R.Rawlins FOURIE2A.80
! FOURIE2A.81
! Code description: FOURIE2A.82
! FORTRAN 77 + common Fortran 90 extensions. FOURIE2A.83
! Written to UM programming standards version 7. FOURIE2A.84
! DOCUMENTATION: NIL. FOURIE2A.85
! FOURIE2A.86
! System component covered: P142 FOURIE2A.87
! FOURIE2A.88
! Subroutine arguments FOURIE2A.89
FOURIE2A.90
FOURIE2A.91
! Scalar arguments with intent(in): FOURIE2A.92
INTEGER FOURIE2A.93
* INC ! IN INCREMENT BETWEEN ELEMENTS OF DATA VECTOR FOURIE2A.94
* ,JUMP ! IN INCREMENT BETWEEN START OF EACH DATA VECTOR FOURIE2A.95
* ,N ! IN LENGTH OF DATA VECTOR IN GRID-POINT SPACE FOURIE2A.96
* ! WITHOUT EXTRA ZEROES FOURIE2A.97
* ,LOT ! IN NUMBER OF DATA VECTORS FOURIE2A.98
* ,ISIGN ! IN DETERMINES TYPE OF TRANSFORM FOURIE2A.99
FOURIE2A.100
FOURIE2A.101
! Array arguments with intent(in): FOURIE2A.102
INTEGER FOURIE2A.103
* IFAX(10) ! IN LIST OF FACTORS OF N FOURIE2A.104
REAL FOURIE2A.105
* TRIGS(N) ! IN TRIGONOMETRICAL FUNCTIONS FOURIE2A.106
FOURIE2A.107
! Array arguments with intent(out): FOURIE2A.108
REAL FOURIE2A.109
* A(JUMP*LOT) ! INOUT DATA FOURIE2A.110
FOURIE2A.111
! Local parameters: FOURIE2A.112
FOURIE2A.113
real cri_work((2*n+4)*lot), cri_table, cri_scale, work FOURIE2A.114
c FOURIE2A.115
integer cri_flag, cri_fft_table, cri_isys, cri_lot FOURIE2A.116
c FOURIE2A.117
parameter (cri_fft_table=1024, cri_lot=128) FOURIE2A.118
c FOURIE2A.119
common/cri_fourier/cri_flag, cri_isys FOURIE2A.120
c FOURIE2A.121
common/cri_fft/cri_table(cri_fft_table) FOURIE2A.122
c FOURIE2A.123
data cri_flag/0/, cri_isys/0/ FOURIE2A.124
C* -------------------------------------------------------------- FOURIE2A.125
FOURIE2A.126
FOURIE2A.127
FOURIE2A.128
! Local scalars FOURIE2A.129
INTEGER FOURIE2A.130
* NFAX ! NUMBER OF FACTORS FOURIE2A.131
*, NX ! N+1 EXCEPT WHERE N IS ODD THEN HOLDS N FOURIE2A.132
*, NBLOX ! NUMBER OF BLOCKS LOT IS SPLIT INTO FOURIE2A.133
*, NVEXREM ! NUMBER OF DATA VECTORS IN BLOCK IF NOT 64 FOURIE2A.134
*, NB ! DO LOOP COUNTER FOURIE2A.135
*, ISTART ! START ADDRESS FOR A BLOCK FOURIE2A.136
*, NVEX ! NUMBER OF ELEMENTS IN VECTOR FOURIE2A.137
*, IA ! USED TO PASS ISTART TO RPASS AND QPASS FOURIE2A.138
*, KI ! VARIABLE USED FOR ADDRESSING FOURIE2A.139
*, IX ! VARIABLE USED FOR ADDRESSING FOURIE2A.140
*, LA ! VARIABLE USED FOR ADDRESSING FOURIE2A.141
*, IGO ! A CONTROL VARIABLE FOURIE2A.142
*, K ! DO LOOP COUNTER FOURIE2A.143
*, IFAC ! HOLDS CURRENT FACTOR FOURIE2A.144
*, IERR ! HOLDS ERROR STATUS FOURIE2A.145
FOURIE2A.146
! Function and subroutine calls: FOURIE2A.147
EXTERNAL FOURIE2A.148
* scfftm,csfftm FOURIE2A.149
FOURIE2A.150
!- End of Header ------------------------------------------------------ FOURIE2A.151
c FOURIE2A.152
if(cri_flag.eq.0) then FOURIE2A.153
if(cri_fft_table.lt.(100+2*n)) then FOURIE2A.154
write(6,'(/''Table for Cray Research FFT Routines '', FOURIE2A.155
2 '' is '',i5,'' Words Long, but needs to '',i5, FOURIE2A.156
3 '' Words Long'')') cri_fft_table, (100+2*n) FOURIE2A.157
call abort
() FOURIE2A.158
endif FOURIE2A.159
cri_scale=1.0 FOURIE2A.160
call scfftm(
0, n, lot, cri_scale, a, jump, a, jump/2, FOURIE2A.161
2 cri_table, cri_work, cri_isys) FOURIE2A.162
cri_flag=1 FOURIE2A.163
endif FOURIE2A.164
c FOURIE2A.165
CL FOURIE2A.166
CL ---------------------------------------------------------------- FOURIE2A.167
CL SECTION 1. SET UP INFORMATION FOR SECTIONS 2 AND 3. FOURIE2A.168
CL ---------------------------------------------------------------- FOURIE2A.169
FOURIE2A.170
C SET NUMBER OF FACTORS AND NX FOURIE2A.171
NFAX=IFAX(1) FOURIE2A.172
NX=N+1 FOURIE2A.173
IF (MOD(N,2).EQ.1) NX=N FOURIE2A.174
CL CALCULATE NUMBER OF BLOCKS OF 'cri_lot' DATA VECTORS ARE TO BE SPLIT FOURIE2A.175
NBLOX=1+(LOT-1)/cri_lot FOURIE2A.176
NVEXREM=LOT-(NBLOX-1)*cri_lot FOURIE2A.177
IF (ISIGN.EQ.1) THEN FOURIE2A.178
FOURIE2A.179
CL FOURIE2A.180
CL ---------------------------------------------------------------- FOURIE2A.181
CL SECTION 2. ISIGN=+1, SPECTRAL TO GRIDPOINT TRANSFORM FOURIE2A.182
CL ---------------------------------------------------------------- FOURIE2A.183
FOURIE2A.184
FOURIE2A.185
C LOOP OVER NUMBER OF BLOCKS. FOURIE2A.186
FOURIE2A.187
DO 200 NB=1,NBLOX FOURIE2A.188
IF(NB.EQ.1)THEN FOURIE2A.189
NVEX=LOT-(NBLOX-1)*cri_lot FOURIE2A.190
ISTART=1 FOURIE2A.191
ELSE FOURIE2A.192
NVEX=cri_lot FOURIE2A.193
ISTART=1+NVEXREM*JUMP+(NB-2)*NVEX*JUMP FOURIE2A.194
ENDIF FOURIE2A.195
IA=ISTART FOURIE2A.196
LA=1 FOURIE2A.197
IGO=+1 FOURIE2A.198
FOURIE2A.199
c--call the Cray Research Optimised FFT Routine FOURIE2A.200
cri_scale=1. FOURIE2A.201
call csfftm(
-1, n, nvex, cri_scale, a(ia), jump/2, FOURIE2A.202
2 a(ia), jump, cri_table, cri_work, cri_isys) FOURIE2A.203
FOURIE2A.204
C FILL IN ZEROS AT END FOURIE2A.205
C -------------------- FOURIE2A.206
FOURIE2A.207
IX=ISTART+N*INC FOURIE2A.208
DO 220 K=1,NVEX FOURIE2A.209
A(IX)=0.0 FOURIE2A.210
A(IX+INC)=0.0 FOURIE2A.211
IX=IX+JUMP FOURIE2A.212
220 CONTINUE FOURIE2A.213
FOURIE2A.214
200 CONTINUE FOURIE2A.215
ELSE FOURIE2A.216
FOURIE2A.217
CL FOURIE2A.218
CL ---------------------------------------------------------------- FOURIE2A.219
CL SECTION 3. ISIGN=-1, GRIDPOINT TO SPECTRAL TRANSFORM FOURIE2A.220
CL ---------------------------------------------------------------- FOURIE2A.221
FOURIE2A.222
FOURIE2A.223
DO 300 NB=1,NBLOX FOURIE2A.224
IF(NB.EQ.1)THEN FOURIE2A.225
NVEX=LOT-(NBLOX-1)*cri_lot FOURIE2A.226
ISTART=1 FOURIE2A.227
ELSE FOURIE2A.228
NVEX=cri_lot FOURIE2A.229
ISTART=1+NVEXREM*JUMP+(NB-2)*NVEX*JUMP FOURIE2A.230
ENDIF FOURIE2A.231
IA=ISTART FOURIE2A.232
LA=N FOURIE2A.233
IGO=+1 FOURIE2A.234
KI=1 FOURIE2A.235
c--call the Cray Research Optimised FFT Routine FOURIE2A.236
cri_scale=1./n FOURIE2A.237
call scfftm(
+1, n, nvex, cri_scale, a(ia), jump, FOURIE2A.238
2 a(ia), jump/2, cri_table, cri_work, cri_isys) FOURIE2A.239
FOURIE2A.240
FOURIE2A.241
300 CONTINUE FOURIE2A.242
END IF FOURIE2A.243
FOURIE2A.244
RETURN FOURIE2A.245
END FOURIE2A.246
FOURIE2A.247
!- End of subroutine code ------------------------------------------ FOURIE2A.248
*ENDIF FOURIE2A.249