LCOV - code coverage report
Current view: top level - types - types_greensfContourData.f90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 114 127 89.8 %
Date: 2024-04-27 04:44:07 Functions: 3 5 60.0 %

          Line data    Source code
       1             : MODULE m_types_greensfContourData
       2             :    USE m_juDFT
       3             :    USE m_types_gfinp
       4             :    USE m_constants
       5             :    IMPLICIT NONE
       6             :    PRIVATE
       7             : 
       8             :    TYPE t_greensfContourData
       9             :       !This type is used in types_greensf for the storage of the energy points and weights
      10             :       !It is defined here, because we want to use it in eContour_gfinp, without importing types_greensf
      11             :       INTEGER :: nz = 0      !Number of points
      12             :       COMPLEX, ALLOCATABLE :: e(:)  !energy points
      13             :       COMPLEX, ALLOCATABLE :: de(:) !integration weights
      14             : 
      15             :    CONTAINS
      16             :       PROCEDURE,PASS :: init       => init_greensfContourData
      17             :       PROCEDURE      :: eContour   => eContour_greensfContourData
      18             :       PROCEDURE      :: mpi_bc     => mpi_bc_greensfContourData
      19             :    END TYPE t_greensfContourData
      20             : 
      21             :    PUBLIC t_greensfContourData
      22             : 
      23             :    CONTAINS
      24             : 
      25        1058 :    SUBROUTINE init_greensfContourData(this,contourInp,contour_in)
      26             : 
      27             :       CLASS(t_greensfContourData),           INTENT(INOUT)  :: this
      28             :       TYPE(t_contourInp),                    INTENT(IN)     :: contourInp
      29             :       TYPE(t_greensfContourData), OPTIONAL,  INTENT(IN)     :: contour_in
      30             :       !
      31             :       !Setting up parameters for the energy contour if one was passed
      32             :       !
      33        1058 :       IF(PRESENT(contour_in)) THEN
      34           0 :          this%nz = contour_in%nz
      35           0 :          ALLOCATE(this%e(this%nz),source=cmplx_0)
      36           0 :          ALLOCATE(this%de(this%nz),source=cmplx_0)
      37             : 
      38           0 :          this%e  = contour_in%e
      39           0 :          this%de = contour_in%de
      40             :       ELSE
      41        1062 :          SELECT CASE(contourInp%shape)
      42             :          CASE(CONTOUR_RECTANGLE_CONST)
      43           4 :             this%nz = contourInp%n1+contourInp%n2+contourInp%n3+contourInp%nmatsub
      44             :          CASE(CONTOUR_SEMICIRCLE_CONST)
      45        1050 :             this%nz = contourInp%ncirc
      46             :          CASE(CONTOUR_DOS_CONST)
      47           4 :             this%nz = contourInp%nDOS
      48             :          CASE DEFAULT
      49        1058 :             CALL juDFT_error("No valid energy contour mode",calledby="init_contourDataType")
      50             :          END SELECT
      51             : 
      52      159866 :          ALLOCATE(this%e(this%nz),source=cmplx_0)
      53      158808 :          ALLOCATE(this%de(this%nz),source=cmplx_0)
      54             :       ENDIF
      55             : 
      56        1058 :    END SUBROUTINE init_greensfContourData
      57             : 
      58        1018 :    SUBROUTINE mpi_bc_greensfContourData(this,mpi_comm,irank)
      59             :          USE m_mpi_bc_tool
      60             :          CLASS(t_greensfContourData), INTENT(INOUT)::this
      61             :          INTEGER, INTENT(IN):: mpi_comm
      62             :          INTEGER, INTENT(IN), OPTIONAL::irank
      63             :          INTEGER ::rank
      64        1018 :          IF (PRESENT(irank)) THEN
      65        1018 :             rank = irank
      66             :          ELSE
      67           0 :             rank = 0
      68             :          END IF
      69             : 
      70        1018 :          CALL mpi_bc(this%nz,rank,mpi_comm)
      71        1018 :          CALL mpi_bc(this%e,rank,mpi_comm)
      72        1018 :          CALL mpi_bc(this%de,rank,mpi_comm)
      73             : 
      74        1018 :    END SUBROUTINE mpi_bc_greensfContourData
      75             : 
      76          46 :    SUBROUTINE eContour_greensfContourData(this,contourInp,ef,irank)
      77             : 
      78             :       USE m_grule
      79             : 
      80             :       !Calculates the complex energy contour and
      81             :       !writes it into the corresponding arrays in gf
      82             : 
      83             :       CLASS(t_greensfContourData), INTENT(INOUT) :: this
      84             :       TYPE(t_contourInp),          INTENT(IN)    :: contourInp
      85             :       REAL,                        INTENT(IN)    :: ef
      86             :       INTEGER,                     INTENT(IN)    :: irank
      87             : 
      88             :       INTEGER iz,n
      89             :       REAL e1, e2, sigma
      90             :       COMPLEX del
      91             :       REAL r, xr, expo, ff
      92          46 :       REAL, ALLOCATABLE :: x(:), w(:)
      93             : 
      94             :       !Help arrays
      95       16660 :       ALLOCATE(x(this%nz),source=0.0)
      96       16614 :       ALLOCATE(w(this%nz),source=0.0)
      97             : 
      98             : 
      99             :       !Transform from relative to ef to absolute
     100          46 :       e1 = ef+contourInp%eb
     101          46 :       e2 = ef+contourInp%et
     102             : 
     103          48 :       SELECT CASE(contourInp%shape)
     104             : 
     105             :       CASE(CONTOUR_RECTANGLE_CONST)
     106           2 :          sigma = contourInp%sigma * pi_const
     107           2 :          IF(contourInp%nmatsub > 0) THEN
     108           2 :             n = 0
     109             : 
     110             :             !Left Vertical part (e1,0) -> (e1,sigma)
     111           2 :             del = contourInp%nmatsub * CMPLX(0.0,sigma)
     112           2 :             CALL grule(contourInp%n1,x(1:(contourInp%n1)/2),w(1:(contourInp%n1)/2))
     113         348 :             x = -x
     114          12 :             DO iz = 1, (contourInp%n1+3)/2-1
     115          10 :                x(contourInp%n1-iz+1) = -x(iz)
     116          12 :                w(contourInp%n1-iz+1) =  w(iz)
     117             :             ENDDO
     118          22 :             DO iz = 1, contourInp%n1
     119          20 :                n = n + 1
     120          20 :                IF(n.GT.this%nz) CALL juDFT_error("Dimension error in energy mesh",calledby="eContour_gfinp")
     121          20 :                this%e(n)  = e1 + del + del * x(iz)
     122          22 :                this%de(n) = w(iz)*del
     123             :             ENDDO
     124             : 
     125             :             !Horizontal Part (eb,sigma) -> (et,sigma)
     126           2 :             del = (ef-30*contourInp%sigma-e1)/2.0
     127           2 :             CALL grule(contourInp%n2,x(1:(contourInp%n2)/2),w(1:(contourInp%n2)/2))
     128         348 :             x = -x
     129         130 :             DO iz = 1, (contourInp%n2+3)/2-1
     130         128 :                x(contourInp%n2-iz+1) = -x(iz)
     131         130 :                w(contourInp%n2-iz+1) =  w(iz)
     132             :             ENDDO
     133         258 :             DO iz = 1, contourInp%n2
     134         256 :                n = n + 1
     135         256 :                IF(n.GT.this%nz) CALL juDFT_error("Dimension error in energy mesh",calledby="eContour_gfinp")
     136         256 :                this%e(n)  = del*x(iz) + del + e1 + 2 * contourInp%nmatsub * ImagUnit * sigma
     137         258 :                this%de(n) = del*w(iz)
     138             :             ENDDO
     139             : 
     140             :             !Right Vertical part (et,sigma) -> infty
     141           2 :             CALL grule(contourInp%n3,x(1:(contourInp%n3)/2),w(1:(contourInp%n3)/2))
     142         348 :             x = -x
     143          32 :             DO iz = 1, (contourInp%n3+3)/2-1
     144          30 :                x(contourInp%n3-iz+1) = -x(iz)
     145          32 :                w(contourInp%n3-iz+1) =  w(iz)
     146             :             ENDDO
     147           2 :             del = 30*contourInp%sigma
     148          62 :             DO iz = 1, contourInp%n3
     149          60 :                n = n + 1
     150          60 :                IF(n.GT.this%nz) CALL juDFT_error("Dimension error in energy mesh",calledby="eContour_gfinp")
     151          60 :                this%e(n)  = del*x(iz)+ef +  2 * contourInp%nmatsub * ImagUnit * sigma
     152          60 :                expo = -ABS(REAL(this%e(n))-ef)/contourInp%sigma
     153          60 :                expo = EXP(expo)
     154          60 :                IF(REAL(this%e(n))<ef) THEN
     155          30 :                   ff = 1.0/(expo+1.0)
     156             :                ELSE
     157          30 :                   ff = expo/(expo+1.0)
     158             :                ENDIF
     159          62 :                this%de(n) = w(iz)*del * ff
     160             :             ENDDO
     161             : 
     162             :             !Matsubara frequencies
     163          12 :             DO iz = contourInp%nmatsub , 1, -1
     164          10 :                n = n + 1
     165          10 :                IF(n.GT.this%nz) CALL juDFT_error("Dimension error in energy mesh",calledby="eContour_gfinp")
     166          10 :                this%e(n)  = ef + (2*iz-1) * ImagUnit *sigma
     167          12 :                this%de(n) = -2 * ImagUnit * sigma
     168             :             ENDDO
     169             :          ENDIF
     170             :       CASE(CONTOUR_SEMICIRCLE_CONST)
     171             : 
     172             :          !Radius
     173          42 :          r  = (e2-e1)*0.5
     174             :          !midpoint
     175          42 :          xr = (e2+e1)*0.5
     176             : 
     177          42 :          CALL grule(contourInp%ncirc,x(1:(contourInp%ncirc)/2),w(1:(contourInp%ncirc)/2))
     178             : 
     179        2730 :          DO iz = 1, contourInp%ncirc/2
     180        2688 :             x(contourInp%ncirc-iz+1) = -x(iz)
     181        2730 :             w(contourInp%ncirc-iz+1) =  w(iz)
     182             :          ENDDO
     183        5418 :          DO iz = 1, contourInp%ncirc
     184        5376 :             this%e(iz)  = xr + ImagUnit * r * EXP(ImagUnit*pi_const/2.0 * x(iz))
     185        5376 :             this%de(iz) = pi_const/2.0 * r * w(iz) * EXP(ImagUnit*pi_const/2.0 * x(iz))
     186             :             !Scale the imaginary part with the given factor alpha
     187        5376 :             this%e(iz)  = REAL(this%e(iz))  + ImagUnit * contourInp%alpha * AIMAG(this%e(iz))
     188        5418 :             this%de(iz) = REAL(this%de(iz)) + ImagUnit * contourInp%alpha * AIMAG(this%de(iz))
     189             :          ENDDO
     190             : 
     191             :       CASE(CONTOUR_DOS_CONST)
     192             : 
     193             :          !Equidistant contour (without vertical edges)
     194           2 :          del = (contourInp%et-contourInp%eb)/REAL(this%nz-1)
     195       10802 :          DO iz = 1, this%nz
     196       10800 :             this%e(iz) = (iz-1) * del + e1 + ImagUnit * contourInp%sigmaDOS
     197       10802 :             IF(contourInp%l_dosfermi) THEN
     198           0 :                expo = -ABS(REAL(this%e(iz))-ef)/contourInp%sigmaDOS
     199           0 :                expo = EXP(expo)
     200           0 :                IF(REAL(this%e(iz))<ef) THEN
     201           0 :                   ff = 1.0/(expo+1.0)
     202             :                ELSE
     203           0 :                   ff = expo/(expo+1.0)
     204             :                ENDIF
     205           0 :                this%de(iz) = del * ff
     206             :             ELSE
     207       10800 :                this%de(iz) = del
     208             :             ENDIF
     209             :          ENDDO
     210             : 
     211             :          !Not really important but for trapezian method
     212             :          !the weight is half at the edges
     213           2 :          this%de(1) = this%de(1)/2.0
     214           2 :          this%de(this%nz) = this%de(this%nz)/2.0
     215             : 
     216             :       CASE DEFAULT
     217          46 :          CALL juDFT_error("Invalid mode for energy contour in Green's function calculation", calledby="eContour_gfinp")
     218             :       END SELECT
     219             : 
     220          46 :       IF(irank.EQ.0) THEN
     221             :          !Write out the information about the energy contour
     222          23 :          WRITE(oUnit,"(A)") "---------------------------------------------"
     223          23 :          WRITE(oUnit,"(A)") " Green's function energy contour"
     224          23 :          WRITE(oUnit,"(A)") "---------------------------------------------"
     225          23 :          WRITE(oUnit,999)  TRIM(ADJUSTL(contourInp%label))
     226          23 :          WRITE(oUnit,1000) contourInp%shape
     227             : 
     228           1 :          SELECT CASE(contourInp%shape)
     229             : 
     230             :          CASE(CONTOUR_RECTANGLE_CONST)
     231           1 :             WRITE(oUnit,"(A)") "Rectangular Contour: "
     232           1 :             WRITE(oUnit,1010) this%nz, contourInp%nmatsub,contourInp%n1,contourInp%n2,contourInp%n3
     233           1 :             WRITE(oUnit,"(A)") "Energy limits (rel. to fermi energy): "
     234           1 :             WRITE(oUnit,1040) contourInp%eb,0.0
     235             :          CASE(CONTOUR_SEMICIRCLE_CONST)
     236          21 :             WRITE(oUnit,"(A)") "Semicircle Contour: "
     237          21 :             WRITE(oUnit,1020) this%nz, contourInp%alpha
     238          21 :             WRITE(oUnit,"(A)") "Energy limits (rel. to fermi energy): "
     239          21 :             WRITE(oUnit,1040) contourInp%eb,contourInp%et
     240             :          CASE(CONTOUR_DOS_CONST)
     241           1 :             WRITE(oUnit,"(A)") "Equidistant Contour for DOS calculations: "
     242           1 :             WRITE(oUnit,1030) this%nz, contourInp%sigmaDOS
     243           1 :             WRITE(oUnit,"(A)") "Energy limits (rel. to fermi energy): "
     244          24 :             WRITE(oUnit,1040) contourInp%eb,contourInp%et
     245             :          CASE DEFAULT
     246             : 
     247             :          END SELECT
     248             : 
     249             :          !Write out points and weights
     250          23 :          WRITE(oUnit,*)
     251          23 :          WRITE(oUnit,"(A)") " Energy points: "
     252          23 :          WRITE(oUnit,"(A)") "---------------------------------------------"
     253        8284 :          DO iz = 1, this%nz
     254        8284 :             WRITE(oUnit,1050) REAL(this%e(iz)), AIMAG(this%e(iz)), REAL(this%de(iz)), AIMAG(this%de(iz))
     255             :          ENDDO
     256             : 
     257             : 999      FORMAT("Name of the contour:", A)
     258             : 1000     FORMAT("Using energy contour mode: ", I1,/)
     259             : 1010     FORMAT("nz: ", I5.1,"; nmatsub: ", I5.1,"; n1: ", I5.1,"; n2: ", I5.1,"; n3: ", I5.1)
     260             : 1020     FORMAT("nz: ", I5.1," alpha: ", f8.4)
     261             : 1030     FORMAT("n: ", I5.1,"; sigma: ", f8.4)
     262             : 1040     FORMAT("eb: ", f8.4,"; et: ",f8.4)
     263             : 1050     FORMAT(2f8.4,"      weight: ",2e15.4)
     264             :       ENDIF
     265             : 
     266          46 :    END SUBROUTINE eContour_greensfContourData
     267             : 
     268             : 
     269           0 : END MODULE m_types_greensfContourData

Generated by: LCOV version 1.14