Search code examples
fortranfftfortran90subroutinefftw

Passing an FFTW plan to a Fortran subroutine


I have the following, seemingly simple issue, but I haven't been able to find any information on it:

In fortran90, is it possible to pass an FFTW plan to a subroutine, so as to allow reusing a plan in different "places" of the code? The naive approach of simply passing it as an INTEGER*8 variable yields mayhem, suggesting the code needs more than the plain integer plan to execute the Fourier Transform.


Solution

  • To this end, I usually write a Fortran module in which I put plans and allocatable arrays that will contain the in and out of FFTW3. Then, I can simply USE the module wherever I want.

    Here is an example for 3dimensional FFT of real data:

    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
    

    Note that this uses the old Fortran interface.