FFTW c2c Fortran中3-D的傅立叶空间对称性

时间:2013-11-17 17:39:24

标签: fortran fft fftw

我使用FFTW c2c逆傅立叶变换遇到了困难,我怀疑它与正确定义3-D复数阵列的复共轭部分有关。我在3-D周期域上生成傅里叶空间中湍流速度波动的表示,应用我认为是正确的复共轭项,然后调用FFTW c2c例程然后进行归一化。

我已经在运行centOS的64位Linux系统上安装了FFTW库,并且正在使用Intel 64位编译器(版本12.0.0.084 Build 20101006)。 FFTW库是使用英特尔编译器编译的。

以下是我假设周期域大小(1:Nx,1:Ny,1:Nz)初始化FFTW计划的方法:

INTEGER(8) :: plan_c2c_inv
COMPLEX(KIND(0.D0)),DIMENSION(:,:,:),ALLOCATABLE :: inv_in_c2c,inv_out_c2c
ALLOCATE( inv_in_c2c(Nx,Ny,Nz) )
ALLOCATE( inv_out_c2c(Nx,Ny,Nz) )
CALL dfftw_plan_dft_3d(plan_c2c_inv,Nx,Ny,Nz,inv_in_c2c,inv_out_c2c,FFTW_BACKWARD,FFTW_PATIENT)

然后我经历了一个有点冗长的过程来生成这部分三维复杂阵列上湍流波动的傅里叶空间表示:

DO ii=1,Nx/2+1
    DO jj=1,Ny
        DO kk=1,Nz
            calculations to populate the complex array uhat(ii,jj,kk)
        ENDDO
    ENDDO
ENDDO

然后我通过调用执行共轭的子程序来共轭复杂数组:

SUBROUTINE conjugate(uc)
    IMPLICIT NONE
    COMPLEX(KIND(0.D0)),DIMENSION(0:Nx-1,0:Ny-1,0:Nz-1),INTENT(INOUT) :: uc

    INTEGER :: i,j,k
    INTEGER :: ii,jj,kk

    uc(Nx/2,:,:) = (0.D0,0.D0)

    DO k=0,Nz-1,1
        DO j=0,Ny-1,1
            DO i=Nx/2+1,Nx-1,1
                ii = Nx - i
                jj = Ny - j
                kk = Nz - k
                IF (j.EQ.0) jj = 0
                IF (k.EQ.0) kk = 0
                uc(i,j,k) = CONJG(uc(ii,jj,kk))
            ENDDO
        ENDDO
    ENDDO
    DO k=0,Nz-1,1
        DO j=0,Ny-1,1
            i = 0
            ii = 0
            jj = Ny - j
            kk = Nz - k
            IF (j.EQ.0) jj = 0
            IF (k.EQ.0) kk = 0
            uc(i,j,k) = CONJG(uc(ii,jj,kk))
        ENDDO
    ENDDO

    RETURN
  END SUBROUTINE conjugate

我的波数被定义为:

  DO ii=1,Nx/2+1
    k1(ii) = DBLE(ii-1)
  ENDDO
  DO ii=1,Nx/2-1
    k1(Nx/2+1+ii) = DBLE(-Nx/2+ii)
  ENDDO

  DO ii=1,Ny/2+1
    k2(ii) = DBLE(ii-1)
  ENDDO
  DO ii=1,Ny/2-1
    k2(Ny/2+1+ii) = DBLE(-Ny/2+ii)
  ENDDO

  DO ii=1,Nz/2+1
    k3(ii) = DBLE(ii-1)
  ENDDO
  DO ii=1,Nz/2-1
    k3(Nz/2+1+ii) = DBLE(-Nz/2+ii)
  ENDDO

当我将uhat转换为真实空间时,我得到一个明显错误的湍流场,当我检查转换后的三维数组的虚构成分时,我得到非零值,这表明我可能在我的理解中遗漏了一些东西如何正确地共轭复傅立叶空间表示。以下是实际执行转换为真实空间的代码段:

SUBROUTINE FFTtoRealc2c(varhat_in,var_out)
  IMPLICIT NONE

  COMPLEX(KIND(0.D0)),DIMENSION(:,:,:),INTENT(IN) :: varhat_in
  REAL(KIND(0.D0)),DIMENSION(:,:,:),INTENT(INOUT) :: var_out

  inv_in_c2c = varhat_in
  CALL dfftw_execute_dft(plan_c2c_inv,inv_in_c2c,inv_out_c2c)
  var_out(1:Nx,1:Ny,1:Nz) = DBLE(inv_out_c2c)

  RETURN
END SUBROUTINE FFTtoRealc2c

当我发现检查结合时,它似乎是正确的(至少通过我对它的理解)。例如,如果我设置Nx = Ny = Nz = 16,那么我在uhat(13,15,11)处看到uhat(5,3,7)的共轭:

uhat(5,3,7) = (-5.137614165569777E-003,-4.527333137185095E-003)
uhat(13,15,11) = (-5.137614165569777E-003,4.527333137185095E-003)

波数幅度在这两点也显得一致:

sqrt(k1(5)*k1(5) + k2(3)*k2(3) + k3(7)*k3(7)) = 7.48331477354788
sqrt(k1(13)*k1(13) + k2(15)*k2(15) + k3(11)*k3(11)) = 7.48331477354788

回到我的问题:我是否正确理解如何定义傅里叶空间三维阵列的复共轭?

0 个答案:

没有答案