module bremModule
    use MKL_DFTI
    implicit none

    contains

!----------Complex 1-D Double Precision Backward FFT----------
    ! https://software.intel.com/en-us/node/522290
    ! https://software.intel.com/en-us/articles/intel-mkl-link-line-advisor
    function FFTB(nListIn,nLength)
        integer status,nLength
        type(DFTI_DESCRIPTOR), POINTER :: My_Desc_Handle
        complex*16 nListIn(0:nLength),FFTB(0:nLength)
        real*8 scale

        scale=1.d0/sqrt(real(nLength))
        My_Desc_Handle => null()

        status=DftiCreateDescriptor(My_Desc_Handle,DFTI_DOUBLE,DFTI_COMPLEX,1,nLength)
        status=DftiSetValue(My_Desc_Handle,DFTI_PLACEMENT,DFTI_NOT_INPLACE)
        status=DftiSetValue(My_Desc_Handle,DFTI_BACKWARD_SCALE,scale)
        status=DftiCommitDescriptor(My_Desc_Handle)
        if (status .ne. 0) then
            if (.not. DftiErrorClass(status,DFTI_NO_ERROR)) then
                print *, 'Error: ', DftiErrorMessage(status)
            endif
        endif
        status=DftiComputeBackward(My_Desc_Handle,nListIn,FFTB)
        status=DftiFreeDescriptor(My_Desc_Handle)
        return
    end function FFTB

!----------Complex 1-D Double Precision Forward FFT----------
function FFTF(nListIn,nLength)
        integer status,nLength
        type(DFTI_DESCRIPTOR), POINTER :: My_Desc_Handle
        complex*16 nListIn(0:nLength),FFTF(0:nLength)
        real*8 scale

        scale=1.d0/sqrt(real(nLength))
        My_Desc_Handle => null()

        status=DftiCreateDescriptor(My_Desc_Handle,DFTI_DOUBLE,DFTI_COMPLEX,1,nLength)
        status=DftiSetValue(My_Desc_Handle,DFTI_PLACEMENT,DFTI_NOT_INPLACE)
        status=DftiSetValue(My_Desc_Handle,DFTI_FORWARD_SCALE,scale)
        status=DftiCommitDescriptor(My_Desc_Handle)
        if (status .ne. 0) then
            if (.not. DftiErrorClass(status,DFTI_NO_ERROR)) then
                print *, 'Error: ', DftiErrorMessage(status)
            endif
        endif
        status=DftiComputeForward(My_Desc_Handle,nListIn,FFTF)
        status=DftiFreeDescriptor(My_Desc_Handle)
        return
    end function FFTF

end module
