将FFTW计划传递给Fortran子例程

时间:2014-06-06 12:29:18

标签: fortran fft fortran90 subroutine fftw

我有以下看似简单的问题,但我还没有找到相关信息:

在fortran90中,是否可以将FFTW计划传递给子程序,以便允许在不同的地方重复使用计划"的代码?简单地将其作为INTEGER * 8变量传递的简单方法会产生混乱,这表明代码需要的不仅仅是普通的整数计划来执行傅里叶变换。

2 个答案:

答案 0 :(得分:2)

FFTW有两种不同的Fortran接口。我假设FFTW3作为版本2已被弃用。

我强烈推荐使用Fortran 2003与C互操作性的现代Fortran接口。然后该平面的类型为type(c_ptr),它在内部模块iso_c_binding中定义。

在旧版界面中,计划在最常见的64位平台上确实是integer*8

有许多示例如何在手册中使用该计划。有关旧版界面,请参阅http://www.fftw.org/doc/Fortran-Examples.html#Fortran-Examples,现代界面请参阅http://fftw.org/doc/Overview-of-Fortran-interface.html#Overview-of-Fortran-interface

无论您选择哪种界面,都可以将plan变量作为伪参数传递给子例程,函数以及您需要使用或存储的任何位置。

如果您在执行之前工作的计划时遇到问题,请确保它所引用的工作数组存在且已正确分配。在这方面,本地未保存的子程序数组是不安全的。

小心伪参数数组。它们可能仅在执行创建计划的子例程期间有效,因为它们作为副本传递。 target参数对100%没有帮助,因为它可能仅在定义过程中有效。

- 重要编辑

http://www.fftw.org/doc/FFTW-Execution-in-Fortran.html#FFTW-Execution-in-Fortran

中解释了另一个问题

尝试使用

call dfftw_execute_dft(plan, in, out)

(在传统界面中,现代界面中有一个等效物)。它也可能改善我之前解释过的两个段落的可能问题,因为即使在原始数组的副本的情况下,新的指针也会被传递并且也可以。

答案 1 :(得分:1)

为此,我经常编写一个Fortran模块,在其中放置计划和可分配的数组,这些数组将包含FFTW3的输入和输出。然后,我可以随便在任何地方使用模块。

以下是实际数据的三维FFT的示例:

MODULE modfft  

    IMPLICIT NONE  

    TYPE :: fftw3Needs  
        INTEGER(i4b) :: plan_forward, plan_backward ! plans for forward and inverse fft
        REAL(dp), ALLOCATABLE, DIMENSION (:,:,:) :: in_forward, out_backward ! input of FFT and output (result) of inverse FFT  
        COMPLEX(dp), ALLOCATABLE, DIMENSION (:,:,:) :: out_forward, in_backward ! output (result) of FFT and input of inverse FFT          
    END TYPE  
    TYPE (fftw3Needs) :: fftw3  

CONTAINS

    SUBROUTINE init
        CALL init_fftw3_plans! Where you initialize your plans with, e.g., dfftw_plan_dft_r2c_3d.
    END SUBROUTINE init

    SUBROUTINE deallocate_everything_fft
        CALL dfftw_destroy_plan ( fftw3%plan_forward ) ! destroy FFTW3 plans 
        CALL dfftw_destroy_plan ( fftw3%plan_backward ) ! destroy FFTW3 plans 
    END SUBROUTINE deallocate_everything_fft


END MODULE modfft

请注意,这使用旧的Fortran界面。