LCOV - code coverage report
Current view: top level - shared/common/src/28_numeric_noabirule - m_lib_four.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 57.6 % 85 49
Test Date: 2026-09-21 22:40:37 Functions: 66.7 % 3 2

            Line data    Source code
       1              : !!****f* ABINIT/nfourier
       2              : !! NAME
       3              : !!  nfourier
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 2014-2026 ABINIT group (XG)
       9              : !!  This file is distributed under the terms of the
      10              : !!  GNU General Public License, see ~abinit/COPYING
      11              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      12              : !!
      13              : !! SOURCE
      14              : 
      15              : #if defined HAVE_CONFIG_H
      16              : #include "config.h"
      17              : #endif
      18              : 
      19              : #include "abi_common.h"
      20              : 
      21              : MODULE m_lib_four
      22              : 
      23              :  use defs_basis
      24              :  use m_errors
      25              :  use m_abicore
      26              : 
      27              : contains
      28              : 
      29              : ! This routine contains direct and inverse fourier transformation
      30              : ! It is a modification of a routine of the GNU GPL
      31              : ! code available on http://dmft.rutgers.edu/ and
      32              : ! described in the RMP 2006 paper written by
      33              : ! G.Kotliar, S.Y.Savrasov, K.Haule, V.S.Oudovenko, O.Parcollet, C.A.Marianetti
      34              : !=======+=========+=========+=========+=========+=========+=========+=$
      35              : !       TYPE   : SUBROUTINE
      36              : !       PROGRAM: nfourier
      37              : !       PURPOSE: fourier-transform the natural-spline interpolation
      38              : !                of function Green(tau)
      39              : !                calculate function Green(omega)
      40              : !       I/O    :
      41              : !       VERSION: 2-16-92
      42              : !                29-Nov-95 removal of minimal bug concerning
      43              : !                          DIMENSION of rindata
      44              : !       COMMENT: cf J. Stoer R. Bulirsch, Introduction to numerical
      45              : !                analysis (Springer, New York, 1980)
      46              : !=======+=========+=========+=========+=========+=========+=========+=$
      47              : !
      48            0 :       SUBROUTINE nfourier(rindata,coutdata,iflag,Iwmax,L,Beta)
      49              : 
      50              : !include 'param.dat'
      51              :        IMPLICIT DOUBLE PRECISION (A-H,O-Z)
      52              :        IMPLICIT INTEGER(I-N)
      53              :        integer  Iwmax,L,iflag
      54              :        DIMENSION rindata(L)
      55            0 :        DIMENSION rincopy(L+1),a(L),b(L),c(L),d(L),u(L+1), q(L+1),XM(L+1)
      56              :        complex*16 :: coutdata(Iwmax+1)
      57              :        complex*16 cdummy,explus,ex
      58            0 :        xpi = ACOS(-One)
      59            0 :        delta = Beta/L
      60            0 :        DO i = 1,L
      61            0 :           rincopy(i) = rindata(i)
      62              :        ENDDO
      63            0 :        if(iflag==1) then
      64            0 :          rincopy(L+1) = -1-rindata(1)
      65              :        else
      66            0 :          rincopy(L+1) = -rindata(1)
      67              :        endif
      68              : !       Three = Two+One
      69              : !       six = Two*Three
      70              : 
      71              : !c
      72              : !c     spline interpolation:  the spline is given by
      73              : !c     G(tau) = a(i) + b(i) (tau-tau_i) + c(i) ( )^2 + d(i) ( )^3
      74              : !c     The following formulas are taken directly from  Stoer and
      75              : !c     Bulirsch p. 102
      76              : !c
      77            0 :        q(1) = Zero
      78            0 :        u(1) = Zero
      79            0 :        DO k = 2,L
      80            0 :           p = q(k-1)/Two+Two
      81            0 :           q(k)=-One/Two/p
      82            0 :           u(k)=Three/delta**2*(rincopy(k+1)+rincopy(k-1)-Two*rincopy(k))
      83            0 :           u(k)=(u(k)-u(k-1)/Two)/p
      84              :        ENDDO
      85            0 :        XM(L+1) = 0
      86            0 :        DO k = L,1,-1
      87            0 :           XM(k) = q(k)*XM(k+1)+u(k)
      88              :        ENDDO
      89              : !c
      90              : !c     The following formulas are taken directly from  Stoer and
      91              : !c     Bulirsch p. 98
      92              : !c
      93            0 :        DO j = 1, L
      94            0 :           a(j) = rincopy(j)
      95            0 :           c(j) = XM(j)/Two
      96              :           b(j) = (rincopy(j+1)-rincopy(j))/delta - &
      97            0 :      &       (Two*XM(j)+XM(j+1))*delta/6.
      98            0 :           d(j) = (XM(j+1)-XM(j))/(6.*delta)
      99              :        ENDDO
     100              : 
     101              : !c
     102              : !c     The Spline multiplied by the exponential can now be exlicitely
     103              : !c     integrated. The following formulas were obtained using
     104              : !c     MATHEMATICA
     105              : !c
     106            0 :         DO i = 0,Iwmax
     107            0 :            om = (Two*(i)+One)*xpi/Beta
     108            0 :            coutdata(i+1) = czero
     109            0 :            DO j = 1,L
     110            0 :               cdummy = j_dpc*om*delta*j
     111            0 :               explus = exp(cdummy)
     112            0 :               cdummy = j_dpc*om*delta*(j-1)
     113            0 :               ex = exp(cdummy)
     114              :               coutdata(i+1) = coutdata(i+1) + explus*(&
     115              :      &         ( -six* d(j) )/om**4 + &
     116              :      &         ( Two*j_dpc*c(j) + six*delta*j_dpc*d(j)  )/om**3 +&
     117              :      &         ( b(j)+ Two*delta*c(j)+ three*delta**2*d(j) )/om**2 +&
     118              :      &         (- j_dpc*a(j) - delta*j_dpc*b(j) - delta**2*j_dpc*c(j) -&
     119            0 :      &         delta**3*j_dpc*d(j))/om)
     120              : 
     121              :               coutdata(i+1) = coutdata(i+1) + ex*(&
     122              :      &        six*d(j)/om**4 - Two*j_dpc*c(j)/om**3 &
     123            0 :      &        -b(j)/om**2 + j_dpc*a(j)/om)
     124              :            ENDDO
     125              :         ENDDO
     126            0 :         end subroutine nfourier
     127              : !!***
     128              : 
     129              : ! This routine contains direct and inverse fourier transformation
     130              : ! It is a modification of a routine of the GNU GPL
     131              : ! code available on http://dmft.rutgers.edu/ and
     132              : ! described in the RMP 2006 paper written by
     133              : ! G.Kotliar, S.Y.Savrasov, K.Haule, V.S.Oudovenko, O.Parcollet, C.A.Marianetti
     134              : !=======+=========+=========+=========+=========+=========+=========+=$
     135              : !       TYPE   : SUBROUTINE
     136              : !       PROGRAM: nfourier
     137              : !       PURPOSE: fourier-transform the natural-spline interpolation
     138              : !                of function Green(tau)
     139              : !                calculate function Green(omega)
     140              : !       I/O    :
     141              : !       VERSION: 2-16-92
     142              : !                29-Nov-95 removal of minimal bug concerning
     143              : !                          DIMENSION of rindata
     144              : !       COMMENT: cf J. Stoer R. Bulirsch, Introduction to numerical
     145              : !                analysis (Springer, New York, 1980)
     146              : !=======+=========+=========+=========+=========+=========+=========+=$
     147              : !
     148         1600 :       SUBROUTINE nfourier2(rindata,coutdata,iflag,om,L,Beta)
     149              : !       include 'param.dat'
     150              :        IMPLICIT DOUBLE PRECISION (A-H,O-Z)
     151              :        IMPLICIT INTEGER(I-N)
     152              :        integer  L,iflag
     153              :        DIMENSION rindata(L)
     154         3200 :        DIMENSION rincopy(L+1),a(L),b(L),c(L),d(L),u(L+1), q(L+1),XM(L+1)
     155              :        complex*16 :: coutdata
     156              :        real*8 :: om
     157              :        complex*16 cdummy,explus,ex
     158         1600 :        xpi = ACOS(-One)
     159         1600 :        delta = Beta/L
     160       104000 :        DO i = 1,L
     161       104000 :           rincopy(i) = rindata(i)
     162              :        ENDDO
     163         1600 :        if(iflag==1 .and. L.ge.1) then
     164          320 :          rincopy(L+1) = -1-rindata(1)
     165         1280 :        elseif(iflag==0 .and. L.ge.1) then
     166         1280 :          rincopy(L+1) = -rindata(1)
     167              :        else
     168            0 :          write(std_out,*) "Warning : Check nfourier2"
     169              :        endif
     170              : !       Three = Two+One
     171              : !       six = Two*Three
     172              : 
     173              : !c
     174              : !c     spline interpolation:  the spline is given by
     175              : !c     G(tau) = a(i) + b(i) (tau-tau_i) + c(i) ( )^2 + d(i) ( )^3
     176              : !c     The following formulas are taken directly from  Stoer and
     177              : !c     Bulirsch p. 102
     178              : !c
     179         1600 :        q(1) = Zero
     180         1600 :        u(1) = Zero
     181       102400 :        DO k = 2,L
     182       100800 :           p = q(k-1)/Two+Two
     183       100800 :           q(k)=-One/Two/p
     184       100800 :           u(k)=Three/delta**2*(rincopy(k+1)+rincopy(k-1)-Two*rincopy(k))
     185       102400 :           u(k)=(u(k)-u(k-1)/Two)/p
     186              :        ENDDO
     187         1600 :        XM(L+1) = 0
     188       104000 :        DO k = L,1,-1
     189       104000 :           XM(k) = q(k)*XM(k+1)+u(k)
     190              :        ENDDO
     191              : !c
     192              : !c     The following formulas are taken directly from  Stoer and
     193              : !c     Bulirsch p. 98
     194              : !c
     195       104000 :        DO j = 1, L
     196       102400 :           a(j) = rincopy(j)
     197       102400 :           c(j) = XM(j)/Two
     198              :           b(j) = (rincopy(j+1)-rincopy(j))/delta - &
     199       102400 :      &       (Two*XM(j)+XM(j+1))*delta/6.
     200       104000 :           d(j) = (XM(j+1)-XM(j))/(6.*delta)
     201              :        ENDDO
     202              : 
     203              : !c
     204              : !c     The Spline multiplied by the exponential can now be exlicitely
     205              : !c     integrated. The following formulas were obtained using
     206              : !c     MATHEMATICA
     207              : !c
     208         1600 :         coutdata = czero
     209       104000 :         DO j = 1,L
     210       102400 :            cdummy = j_dpc*om*delta*j
     211       102400 :            explus = exp(cdummy)
     212       102400 :            cdummy = j_dpc*om*delta*(j-1)
     213       102400 :            ex = exp(cdummy)
     214              :            coutdata = coutdata + explus*(&
     215              :      &      ( -six* d(j) )/om**4 + &
     216              :      &      ( Two*j_dpc*c(j) + six*delta*j_dpc*d(j)  )/om**3 +&
     217              :      &      ( b(j)+ Two*delta*c(j)+ three*delta**2*d(j) )/om**2 +&
     218              :      &      (- j_dpc*a(j) - delta*j_dpc*b(j) - delta**2*j_dpc*c(j) -&
     219       102400 :      &         delta**3*j_dpc*d(j))/om)
     220              : 
     221              :            coutdata = coutdata + ex*(&
     222              :      &     six*d(j)/om**4 - Two*j_dpc*c(j)/om**3 &
     223       104000 :      &     -b(j)/om**2 + j_dpc*a(j)/om)
     224              :         ENDDO
     225         1600 :         end subroutine nfourier2
     226              : !=======+=========+=========+=========+=========+=========+=========+=$
     227              : !       TYPE   : SUBROUTINE
     228              : !       PROGRAM: invfourier
     229              : !       PURPOSE: inverse fourier transform
     230              : !                Greent, Greenw use physical definition
     231              : !                Greent(i) = G((i-1)*deltau) for i = 1,...,L
     232              : !                Greenw(n) = G(i w_n), for n = 0,L/2-1
     233              : !                       w_n = (2*n+1)pi/beta
     234              : !                Symmetry property:
     235              : !                G(iw_(-n) = G(iw_(n-1))*
     236              : !                coupled to the impurity
     237              : !       I/O    :
     238              : !       VERSION: 6-16-92
     239              : !       COMMENT:
     240              : !=======+=========+=========+=========+=========+=========+=========+=$
     241              : !
     242           50 :        SUBROUTINE invfourier(cindata,routdata,Iwmax,L,iflag,beta)
     243              : 
     244              : !       include 'param.dat'
     245              :        implicit none
     246              :        integer, intent(in) :: Iwmax
     247              :        complex*16, intent(in) :: cindata(1:Iwmax)    !vz_d
     248              :        integer, intent(in) :: L
     249              :        complex*16, intent(inout) :: routdata(1:L)    !vz_d
     250              :        integer, intent(in) :: iflag
     251              :        double precision, intent(in) :: beta
     252              : 
     253              :        double precision :: xpi
     254              :        double precision :: tau
     255              :        double precision :: om
     256              :        complex*16 :: cdummy,dummy
     257              :        integer :: i,j
     258              : 
     259           50 :        xpi = ACOS(-One)
     260         3250 :        DO 1 i = 1,L
     261         3200 :        routdata(i) = Zero
     262         3200 :           tau = (i-1)*beta/real(L)
     263     64003200 :           DO 2 j = 1,Iwmax
     264              : !               om = mod((2*(j)+One)*xpi/Beta*tau,2*xpi)
     265     64000000 :                 om =    ((2*(j)-One)*xpi/Beta*tau)
     266     64000000 :                cdummy = CMPLX(Zero,om)
     267     64000000 :                dummy = cindata(j)*exp(-cdummy)
     268     64000000 :            routdata(i) = routdata(i)+Two/beta*dummy
     269         3200 : 2         CONTINUE
     270              : !           write(std_out,*) "FT",i,routdata(i)
     271           50 : 1      CONTINUE
     272              : !c
     273              : !c     special treatment for tau = 0
     274              : !c
     275           50 :        if(iflag==1 .and. L.ge.1 ) then
     276           10 :          routdata(1) = -One/Two+routdata(1)
     277              :        endif
     278           50 :        END SUBROUTINE invfourier
     279              : 
     280              : END MODULE m_lib_four
     281              : !!***
        

Generated by: LCOV version 2.3-1