LCOV - code coverage report
Current view: top level - shared/common/src/17_libtetra_ext - libtetrabz_common.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 49.0 % 298 146
Test Date: 2026-09-19 17:42:43 Functions: 45.0 % 20 9

            Line data    Source code
       1              : 
       2              : #if defined HAVE_CONFIG_H
       3              : #include "config.h"
       4              : #endif
       5              : 
       6              : #include "abi_common.h"
       7              : !
       8              : ! Copyright (C) 2014 Mitsuaki Kawamura
       9              : !
      10              : ! Permission is hereby granted, free of charge, to any person obtaining a
      11              : ! copy of this software and associated documentation files (the
      12              : ! "Software"), to deal in the Software without restriction, including
      13              : ! without limitation the rights to use, copy, modify, merge, publish,
      14              : ! distribute, sublicense, and/or sell copies of the Software, and to
      15              : ! permit persons to whom the Software is furnished to do so, subject to
      16              : ! the following conditions:
      17              : !
      18              : ! The above copyright notice and this permission notice shall be included
      19              : ! in all copies or substantial portions of the Software.
      20              : !
      21              : ! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22              : ! OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      23              : ! MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      24              : ! IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      25              : ! CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      26              : ! TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      27              : ! SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      28              : !
      29              : MODULE libtetrabz_common
      30              :   !
      31              :   use m_abicore
      32              :   use m_errors
      33              :   USE_MPI
      34              : 
      35              :   IMPLICIT NONE
      36              : 
      37              : #if defined HAVE_MPI1
      38              :  include 'mpif.h'
      39              : #endif
      40              :   !
      41              :   PRIVATE
      42              : 
      43              :   PUBLIC :: libtetrabz_initialize, libtetrabz_sort, libtetrabz_interpol_indx, &
      44              :   &      libtetrabz_tsmall_a1, libtetrabz_tsmall_b1, libtetrabz_tsmall_b2, libtetrabz_tsmall_b3, &
      45              :   &      libtetrabz_tsmall_c1, libtetrabz_tsmall_c2, libtetrabz_tsmall_c3, &
      46              :   &      libtetrabz_triangle_a1, libtetrabz_triangle_b1, &
      47              :   &      libtetrabz_triangle_b2, libtetrabz_triangle_c1, &
      48              :   &      libtetrabz_mpisum_d, libtetrabz_mpisum_dv, libtetrabz_mpisum_zv
      49              :   !
      50              : 
      51              : CONTAINS
      52              : !
      53              : ! define shortest diagonal line & define type of tetragonal
      54              : !
      55           35 : SUBROUTINE libtetrabz_initialize(ltetra,nge,ngw,bvec,linterpol,wlsm,nk_local,nt_local,nkBZ,ik_global,ik_local,kvec,comm)
      56              :   !
      57              :   !IMPLICIT NONE
      58              :   !
      59              :   INTEGER,INTENT(IN) :: ltetra, nge(3), ngw(3)
      60              :   REAL(8),INTENT(IN) :: bvec(3,3)
      61              :   LOGICAL,INTENT(OUT) :: linterpol
      62              :   REAL(8),INTENT(OUT) :: wlsm(4,20)
      63              :   INTEGER,INTENT(OUT) :: nk_local, nt_local, nkBZ
      64              :   INTEGER,INTENT(OUT),ALLOCATABLE :: ik_global(:,:), ik_local(:,:)
      65              :   REAL(8),INTENT(OUT),ALLOCATABLE :: kvec(:,:)
      66              :   INTEGER,INTENT(IN),OPTIONAL :: comm
      67              :   !
      68              :   INTEGER :: itype, i1, i2, i3, it, divvec(4,4), ivvec0(4), ivvec(3,20,6)
      69              :   REAL(8) :: l(4), bvec2(3,3), bvec3(3,4)
      70              :   !
      71          140 :   nkBZ = PRODUCT(nge(1:3))
      72          140 :   linterpol = .NOT. ALL(nge(1:3) == ngw(1:3))
      73              :   !
      74          140 :   DO i1 = 1, 3
      75          455 :      bvec2(1:3,i1) = bvec(1:3,i1) / DBLE(nge(i1))
      76              :   END DO
      77              :   !
      78          140 :   bvec3(1:3,1) = -bvec2(1:3,1) + bvec2(1:3,2) + bvec2(1:3,3)
      79          140 :   bvec3(1:3,2) =  bvec2(1:3,1) - bvec2(1:3,2) + bvec2(1:3,3)
      80          140 :   bvec3(1:3,3) =  bvec2(1:3,1) + bvec2(1:3,2) - bvec2(1:3,3)
      81          140 :   bvec3(1:3,4) =  bvec2(1:3,1) + bvec2(1:3,2) + bvec2(1:3,3)
      82              :   !
      83              :   ! length of delta bvec
      84              :   !
      85          175 :   DO i1 = 1, 4
      86          595 :      l(i1) = DOT_PRODUCT(bvec3(1:3,i1),bvec3(1:3,i1))
      87              :   END DO
      88              :   !
      89          210 :   itype = MINLOC(l(1:4),1)
      90              :   !
      91              :   ! start & last
      92              :   !
      93           35 :   ivvec0(1:4) = (/ 0, 0, 0, 0 /)
      94              :   !
      95          175 :   divvec(1:4,1) = (/ 1, 0, 0, 0 /)
      96          175 :   divvec(1:4,2) = (/ 0, 1, 0, 0 /)
      97          175 :   divvec(1:4,3) = (/ 0, 0, 1, 0 /)
      98              :   divvec(1:4,4) = (/ 0, 0, 0, 1 /)
      99              :   !
     100           35 :   ivvec0(itype) = 1
     101           35 :   divvec(itype, itype) = - 1
     102              :   !
     103              :   ! Corners of tetrahedra
     104              :   !
     105           35 :   it = 0
     106          140 :   DO i1 = 1, 3
     107          455 :      DO i2 = 1, 3
     108          315 :         IF(i2 == i1) CYCLE
     109          945 :         DO i3 = 1, 3
     110          630 :            IF(i3 == i1 .OR. i3 == i2) CYCLE
     111              :            !
     112          210 :            it = it + 1
     113              :            !
     114          840 :            ivvec(1:3,1,it) = ivvec0(1:3)
     115          840 :            ivvec(1:3,2,it) = ivvec(1:3,1,it) + divvec(1:3,i1)
     116          840 :            ivvec(1:3,3,it) = ivvec(1:3,2,it) + divvec(1:3,i2)
     117         1155 :            ivvec(1:3,4,it) = ivvec(1:3,3,it) + divvec(1:3,i3)
     118              :            !
     119              :         END DO
     120              :      END DO
     121              :   END DO
     122              :   !
     123              :   ! Additional points
     124              :   !
     125          875 :   ivvec(1:3, 5,1:6) = 2 * ivvec(1:3,1,1:6) - ivvec(1:3,2,1:6)
     126          875 :   ivvec(1:3, 6,1:6) = 2 * ivvec(1:3,2,1:6) - ivvec(1:3,3,1:6)
     127          875 :   ivvec(1:3, 7,1:6) = 2 * ivvec(1:3,3,1:6) - ivvec(1:3,4,1:6)
     128          875 :   ivvec(1:3, 8,1:6) = 2 * ivvec(1:3,4,1:6) - ivvec(1:3,1,1:6)
     129              :   !
     130          875 :   ivvec(1:3, 9,1:6) = 2 * ivvec(1:3,1,1:6) - ivvec(1:3,3,1:6)
     131          875 :   ivvec(1:3,10,1:6) = 2 * ivvec(1:3,2,1:6) - ivvec(1:3,4,1:6)
     132          875 :   ivvec(1:3,11,1:6) = 2 * ivvec(1:3,3,1:6) - ivvec(1:3,1,1:6)
     133          875 :   ivvec(1:3,12,1:6) = 2 * ivvec(1:3,4,1:6) - ivvec(1:3,2,1:6)
     134              :   !
     135          875 :   ivvec(1:3,13,1:6) = 2 * ivvec(1:3,1,1:6) - ivvec(1:3,4,1:6)
     136          875 :   ivvec(1:3,14,1:6) = 2 * ivvec(1:3,2,1:6) - ivvec(1:3,1,1:6)
     137          875 :   ivvec(1:3,15,1:6) = 2 * ivvec(1:3,3,1:6) - ivvec(1:3,2,1:6)
     138          875 :   ivvec(1:3,16,1:6) = 2 * ivvec(1:3,4,1:6) - ivvec(1:3,3,1:6)
     139              :   !
     140          875 :   ivvec(1:3,17,1:6) =  ivvec(1:3,4,1:6) - ivvec(1:3,1,1:6) + ivvec(1:3,2,1:6)
     141          875 :   ivvec(1:3,18,1:6) =  ivvec(1:3,1,1:6) - ivvec(1:3,2,1:6) + ivvec(1:3,3,1:6)
     142          875 :   ivvec(1:3,19,1:6) =  ivvec(1:3,2,1:6) - ivvec(1:3,3,1:6) + ivvec(1:3,4,1:6)
     143          875 :   ivvec(1:3,20,1:6) =  ivvec(1:3,3,1:6) - ivvec(1:3,4,1:6) + ivvec(1:3,1,1:6)
     144              :   !
     145           35 :   IF(ltetra == 1) THEN
     146              :      !
     147              :      !WRITE(*,*) "[libtetrabz] Linear tetrahedron method is used."
     148              :      !
     149            0 :      wlsm(1:4,1:20) = 0.0d0
     150            0 :      wlsm(1,1) = 1.0d0
     151            0 :      wlsm(2,2) = 1.0d0
     152            0 :      wlsm(3,3) = 1.0d0
     153            0 :      wlsm(4,4) = 1.0d0
     154              :      !
     155           35 :   ELSE IF(ltetra == 2) THEN
     156              :      !
     157              :      !WRITE(*,*) "[libtetrabz] Improved tetrahedron method is used."
     158              :      !
     159          175 :      wlsm(1, 1: 4) = DBLE((/1440,    0,   30,    0/))
     160          175 :      wlsm(2, 1: 4) = DBLE((/   0, 1440,    0,   30/))
     161          175 :      wlsm(3, 1: 4) = DBLE((/  30,    0, 1440,    0/))
     162          175 :      wlsm(4, 1: 4) = DBLE((/   0,   30,    0, 1440/))
     163              :      !
     164          175 :      wlsm(1, 5: 8) = DBLE((/ -38,    7,   17,  -28/))
     165          175 :      wlsm(2, 5: 8) = DBLE((/ -28,  -38,    7,   17/))
     166          175 :      wlsm(3, 5: 8) = DBLE((/  17,  -28,  -38,    7/))
     167          175 :      wlsm(4, 5: 8) = DBLE((/   7,   17,  -28,  -38/))
     168              :      !
     169          175 :      wlsm(1, 9:12) = DBLE((/ -56,    9,  -46,    9/))
     170          175 :      wlsm(2, 9:12) = DBLE((/   9,  -56,    9,  -46/))
     171          175 :      wlsm(3, 9:12) = DBLE((/ -46,    9,  -56,    9/))
     172          175 :      wlsm(4, 9:12) = DBLE((/   9,  -46,    9,  -56/))
     173              :      !
     174          175 :      wlsm(1,13:16) = DBLE((/ -38,  -28,   17,    7/))
     175          175 :      wlsm(2,13:16) = DBLE((/   7,  -38,  -28,   17/))
     176          175 :      wlsm(3,13:16) = DBLE((/  17,    7,  -38,  -28/))
     177          175 :      wlsm(4,13:16) = DBLE((/ -28,   17,    7,  -38/))
     178              :      !
     179          175 :      wlsm(1,17:20) = DBLE((/ -18,  -18,   12,  -18/))
     180          175 :      wlsm(2,17:20) = DBLE((/ -18,  -18,  -18,   12/))
     181          175 :      wlsm(3,17:20) = DBLE((/  12,  -18,  -18,  -18/))
     182          175 :      wlsm(4,17:20) = DBLE((/ -18,   12,  -18,  -18/))
     183              :      !
     184         3535 :      wlsm(1:4,1:20) = wlsm(1:4,1:20) / 1260d0
     185              :      !
     186              :   ELSE
     187              :      !
     188            0 :      ABI_ERROR("[libtetrabz] STOP! ltetrta is invalid.")
     189              :      !
     190              :   END IF
     191              :   !
     192           35 :   IF (PRESENT(comm)) THEN
     193           35 :      CALL libtetrabz_kgrid(linterpol,ivvec,nge,nkBZ,nk_local,nt_local,ik_global,ik_local,kvec,comm)
     194              :   ELSE
     195            0 :      CALL libtetrabz_kgrid(linterpol,ivvec,nge,nkBZ,nk_local,nt_local,ik_global,ik_local,kvec)
     196              :   END IF
     197              :   !
     198           35 : END SUBROUTINE libtetrabz_initialize
     199              : !
     200              : ! Initialize grid
     201              : !
     202           35 : SUBROUTINE libtetrabz_kgrid(linterpol,ivvec,ng,nkBZ,nk_local,nt_local,ik_global,ik_local,kvec,comm)
     203              :   !
     204              :   !IMPLICIT NONE
     205              :   !
     206              :   LOGICAL,INTENT(INOUT) :: linterpol
     207              :   INTEGER,INTENT(IN) :: ivvec(3,20,6), ng(3), nkBZ
     208              :   INTEGER,INTENT(OUT) :: nk_local, nt_local
     209              :   INTEGER,INTENT(OUT),ALLOCATABLE :: ik_global(:,:), ik_local(:,:)
     210              :   REAL(8),INTENT(OUT),ALLOCATABLE :: kvec(:,:)
     211              :   INTEGER,INTENT(IN),OPTIONAL :: comm
     212              :   !
     213           35 :   INTEGER :: it, i1, i2, i3, ii, ikv(3), nt, ik, nt_front, loc2glob(nkBZ), glob2loc(nkBZ)
     214              :   !
     215           35 :   IF(PRESENT(comm)) THEN
     216           35 :      CALL libtetrabz_divideMPI(comm,6 * nkBZ,nt_front,nt_local)
     217           35 :      linterpol = linterpol .OR. (6*nkBZ /= nt_local)
     218              :   ELSE
     219            0 :      nt_front = 0
     220            0 :      nt_local = 6 * nkBZ
     221              :   END IF
     222          105 :   ABI_MALLOC(ik_global, (20, nt_local))
     223           70 :   ABI_MALLOC(ik_local, (20, nt_local))
     224              :   !
     225              :   ! k-index for energy (Global index)
     226              :   !
     227           35 :   nt = 0
     228          315 :   DO i3 = 1, ng(3)
     229         2555 :      DO i2 = 1, ng(2)
     230        20440 :         DO i1 = 1, ng(1)
     231              :            !
     232       127680 :            DO it = 1, 6
     233              :               !
     234       107520 :               nt = nt + 1
     235       107520 :               IF(nt <= nt_front .OR. nt_front + nt_local < nt) CYCLE
     236              :               !
     237      2275840 :               DO ii = 1, 20
     238              :                  !
     239      8601600 :                  ikv(1:3) = (/i1, i2, i3/) + ivvec(1:3,ii,it) - 1
     240      8601600 :                  ikv(1:3) = MODULO(ikv(1:3), ng(1:3))
     241              :                  !
     242      2257920 :                  ik_global(ii,nt - nt_front) = 1 + ikv(1) + ng(1) * ikv(2) + ng(1) * ng(2) * ikv(3)
     243              :                  !
     244              :               END DO
     245              :               !
     246              :            END DO
     247              :            !
     248              :         END DO
     249              :      END DO
     250              :   END DO
     251              :   !
     252              :   ! k-index for weight (Local index)
     253              :   !
     254           35 :   IF(.NOT. linterpol) THEN
     255           35 :      nk_local = nkBZ
     256      2257955 :      ik_local(1:20,1:nt_local) = ik_global(1:20,1:nt_local)
     257              :      RETURN
     258              :   END IF
     259              :   !
     260            0 :   glob2loc(1:nkBZ) = 0
     261            0 :   nk_local = 0
     262            0 :   DO nt = 1, nt_local
     263            0 :      DO ii = 1, 20
     264              :         !
     265            0 :         IF(glob2loc(ik_global(ii,nt)) /= 0) THEN
     266            0 :            ik_local(ii,nt) = glob2loc(ik_global(ii,nt))
     267              :         ELSE
     268              :            !
     269            0 :            nk_local = nk_local + 1
     270            0 :            loc2glob(nk_local) = ik_global(ii,nt)
     271            0 :            glob2loc(ik_global(ii,nt)) = nk_local
     272            0 :            ik_local(ii,nt) = nk_local
     273              :            !
     274              :         END IF
     275              :         !
     276              :      END DO
     277              :   END DO
     278              :   !
     279              :   ! k-vector in the fractional coordinate
     280              :   !
     281            0 :   ABI_MALLOC(kvec, (3,nk_local))
     282            0 :   DO ik = 1, nk_local
     283              :      ! loc2glob(ik) - 1 = i1 + ng(1) * i2 + ng(1) * ng(2) * i3
     284            0 :      i1 = MOD(loc2glob(ik) - 1, ng(1))
     285            0 :      i2 = MOD((loc2glob(ik) - 1) / ng(1), ng(2))
     286            0 :      i3 = (loc2glob(ik) - 1) / (ng(1) * ng(2))
     287            0 :      kvec(1:3,ik) = DBLE((/i1, i2, i3/)) / DBLE(ng(1:3))
     288              :   END DO
     289              :   !
     290              : END SUBROUTINE libtetrabz_kgrid
     291              : !
     292              : ! Compute cnt and dsp
     293              : !
     294           35 : SUBROUTINE libtetrabz_divideMPI(comm,nt,nt_front,nt_local)
     295              :   !
     296              :   !IMPLICIT NONE
     297              :   !
     298              :   INTEGER,INTENT(IN) :: comm, nt
     299              :   INTEGER,INTENT(OUT) :: nt_front, nt_local
     300              :   !
     301              :   INTEGER :: petot = 1, my_rank = 0
     302              : #if defined(HAVE_MPI)
     303              :   INTEGER :: ierr
     304           35 :   CALL MPI_COMM_SIZE(comm, petot, ierr)
     305           35 :   CALL MPI_COMM_RANK(comm, my_rank, ierr)
     306              : #endif
     307              :   !
     308           35 :   IF(my_rank < MOD(nt, petot)) THEN
     309            0 :      nt_local = nt / petot + 1
     310            0 :      nt_front = my_rank * nt_local
     311              :   ELSE
     312           35 :      nt_local = nt / petot
     313           35 :      nt_front = my_rank * nt_local + MOD(nt, petot)
     314              :   END IF
     315              :   !
     316           35 : END SUBROUTINE libtetrabz_divideMPI
     317              : !
     318              : ! Simple sort
     319              : !
     320       364560 : pure SUBROUTINE libtetrabz_sort(n,key,indx)
     321              :   !
     322              :   !IMPLICIT NONE
     323              :   !
     324              :   integer,INTENT(IN) :: n
     325              :   REAL(8),INTENT(inout) :: key(n)
     326              :   INTEGER,INTENT(OUT) :: indx(n)
     327              :   !
     328              :   INTEGER :: i, i0, indx0
     329              :   REAL(8) :: key0
     330              :   !
     331      1673280 :   DO i = 1, n
     332      1673280 :      indx(i) = i
     333              :   END DO
     334              :   !
     335      1308720 :   DO i = 1, n - 1
     336      3627120 :      key0 = MINVAL(key(i+1:n))
     337      2682960 :      i0   = MINLOC(key(i+1:n),1) + i
     338      1308720 :      IF(key(i) > key0) THEN
     339       552154 :         key(i0) = key(i)
     340       552154 :         key(i) = key0
     341              :         !
     342       552154 :         indx0 = indx(i0)
     343       552154 :         indx(i0) = indx(i)
     344       552154 :         indx(i) = indx0
     345              :      END IF
     346              :   END DO
     347              :   !
     348       364560 : END SUBROUTINE libtetrabz_sort
     349              : !
     350              : ! Linear interpolation
     351              : !
     352            0 : pure SUBROUTINE libtetrabz_interpol_indx(nintp,ng,kvec,kintp,wintp)
     353              :   !
     354              :   !IMPLICIT NONE
     355              :   !
     356              :   INTEGER,INTENT(in) :: nintp, ng(3)
     357              :   REAL(8),INTENT(in) :: kvec(3)
     358              :   INTEGER,INTENT(out) :: kintp(nintp)
     359              :   REAL(8),INTENT(out) :: wintp(nintp)
     360              :   !
     361              :   INTEGER :: ikv(3,20), dikv(3,3), ii
     362              :   REAL(8) :: x, y, z, xv(3)
     363              :   !
     364              :   ! Search nearest neighbor grid points.
     365              :   !
     366            0 :   xv(1:3) = kvec(1:3) * DBLE(ng(1:3))
     367            0 :   ikv(1:3,1) = NINT(xv(1:3))
     368            0 :   dikv(1:3,1:3) = 0
     369            0 :   DO ii = 1, 3
     370            0 :      dikv(ii,ii) = ikv(ii,1) - FLOOR(xv(ii))
     371            0 :      dikv(ii,ii) = 1 - 2 * dikv(ii,ii)
     372              :   END DO
     373            0 :   xv(1:3) = ABS(xv(1:3) - DBLE(ikv(1:3,1)))
     374            0 :   x = xv(1)
     375            0 :   y = xv(2)
     376            0 :   z = xv(3)
     377              :   !
     378            0 :   ikv(1:3, 2) = ikv(1:3,1) + dikv(1:3,1)
     379            0 :   ikv(1:3, 3) = ikv(1:3,1) + dikv(1:3,2)
     380            0 :   ikv(1:3, 4) = ikv(1:3,1) + dikv(1:3,3)
     381              :   !
     382            0 :   IF(nintp == 4) THEN
     383              :      !
     384            0 :      wintp(1) = 1d0 - x - y - z
     385            0 :      wintp(2) = x
     386            0 :      wintp(3) = y
     387            0 :      wintp(4) = z
     388              :      !
     389              :   ELSE
     390              :      !
     391            0 :      ikv(1:3, 5) = ikv(1:3,1) + SUM(dikv(1:3,1:3), 2)
     392              :      !
     393            0 :      ikv(1:3, 6) = ikv(1:3,1) - dikv(1:3,1)
     394            0 :      ikv(1:3, 7) = ikv(1:3,1) - dikv(1:3,2)
     395            0 :      ikv(1:3, 8) = ikv(1:3,1) - dikv(1:3,3)
     396              :      !
     397            0 :      ikv(1:3, 9) = ikv(1:3,1) + 2*dikv(1:3,1)
     398            0 :      ikv(1:3,10) = ikv(1:3,1) + 2*dikv(1:3,2)
     399            0 :      ikv(1:3,11) = ikv(1:3,1) + 2*dikv(1:3,3)
     400              :      !
     401            0 :      ikv(1:3,12) = ikv(1:3,1) + dikv(1:3,2) + dikv(1:3,3)
     402            0 :      ikv(1:3,13) = ikv(1:3,1) + dikv(1:3,3) + dikv(1:3,1)
     403            0 :      ikv(1:3,14) = ikv(1:3,1) + dikv(1:3,1) + dikv(1:3,2)
     404              :      !
     405            0 :      ikv(1:3,15) = ikv(1:3,1) - dikv(1:3,1) + dikv(1:3,3)
     406            0 :      ikv(1:3,16) = ikv(1:3,1) - dikv(1:3,2) + dikv(1:3,1)
     407            0 :      ikv(1:3,17) = ikv(1:3,1) - dikv(1:3,3) + dikv(1:3,2)
     408              :      !
     409            0 :      ikv(1:3,18) = ikv(1:3,1) + dikv(1:3,1) - dikv(1:3,3)
     410            0 :      ikv(1:3,19) = ikv(1:3,1) + dikv(1:3,2) - dikv(1:3,1)
     411            0 :      ikv(1:3,20) = ikv(1:3,1) + dikv(1:3,3) - dikv(1:3,2)
     412              :      !
     413              :      wintp( 1) = ( (x - 2d0)*(x - 1d0)*(1d0 + x) &
     414              :      &           + (y - 2d0)*(y - 1d0)*(1d0 + y) &
     415              :      &           + (z - 2d0)*(z - 1d0)*(1d0 + z) &
     416              :      &           + 2d0*(x*y + y*z + z*x)*(x + y + z - 1d0) &
     417            0 :      &           - 8d0*x*y*z - 4d0) * 0.5d0
     418              :      wintp( 2) = x * ( 2d0 + x*(1d0 - x - y - z) &
     419              :      &               + y*(1d0 - 2d0*y + z) &
     420            0 :      &               + z*(1d0 - 2d0*z + y)) * 0.5d0
     421              :      wintp( 3) = y * ( 2d0 + y*(1d0 - x - y - z) &
     422              :      &               + x*(1d0 - 2d0*x + z) &
     423            0 :      &               + z*(1d0 - 2d0*z + x)) * 0.5d0
     424              :      wintp( 4) = z * ( 2d0 + z*(1d0 - x - y - z) &
     425              :      &               + y*(1d0 - 2d0*y + x) &
     426            0 :      &               + x*(1d0 - 2d0*x + y)) * 0.5d0
     427            0 :      wintp( 5) = x * y * z
     428            0 :      wintp( 6) = x * (1d0 - x) * (    x + 3d0*y + 3d0*z - 2d0) / 6d0
     429            0 :      wintp( 7) = y * (1d0 - y) * (3d0*x +     y + 3d0*z - 2d0) / 6d0
     430            0 :      wintp( 8) = z * (1d0 - z) * (3d0*x + 3d0*y +     z - 2d0) / 6d0
     431            0 :      wintp( 9) = x * (x - 1d0) * (x + 1d0) / 6d0
     432            0 :      wintp(10) = y * (y - 1d0) * (y + 1d0) / 6d0
     433            0 :      wintp(11) = z * (z - 1d0) * (z + 1d0) / 6d0
     434            0 :      wintp(12) = y * z * (y + z - 2d0 * x) * 0.5d0
     435            0 :      wintp(13) = z * x * (z + x - 2d0 * y) * 0.5d0
     436            0 :      wintp(14) = x * y * (x + y - 2d0 * z) * 0.5d0
     437            0 :      wintp(15) = x * z * (x - 1d0) * 0.5d0
     438            0 :      wintp(16) = x * y * (y - 1d0) * 0.5d0
     439            0 :      wintp(17) = y * z * (z - 1d0) * 0.5d0
     440            0 :      wintp(18) = x * z * (z - 1d0) * 0.5d0
     441            0 :      wintp(19) = x * y * (x - 1d0) * 0.5d0
     442            0 :      wintp(20) = y * z * (y - 1d0) * 0.5d0
     443              :      !
     444              :   END IF
     445              :   !
     446            0 :   DO ii = 1, nintp
     447            0 :      ikv(1:3,ii) = MODULO(ikv(1:3,ii), ng(1:3))
     448            0 :      kintp(ii) = 1 + ikv(1,ii) + ng(1) * ikv(2,ii) + ng(1) * ng(2) * ikv(3,ii)
     449              :   END DO
     450              :   !
     451            0 : END SUBROUTINE libtetrabz_interpol_indx
     452              : 
     453        74760 : pure function a_from_e(e) result(a)
     454              : 
     455              :   !IMPLICIT NONE
     456              :   REAL(8),INTENT(IN) :: e(4)
     457              :   REAL(8) :: a(4,4)
     458              : 
     459              :   INTEGER :: ii
     460              :   REAL(8) :: ediff(4)
     461              : 
     462       373800 :   DO ii = 1, 4
     463      1495200 :      ediff = e(1:4) - e(ii)
     464      1495200 :      where (abs(ediff) < 1.e-10)
     465              :         ediff = 1.e-10
     466              :      end where
     467      1569960 :      a(1:4,ii) = (0d0 - e(ii)) / ediff
     468              :   END DO
     469              : 
     470        74760 : end function a_from_e
     471              : 
     472              : !
     473              : ! Cut small tetrahedron A1
     474              : !
     475            0 : pure SUBROUTINE libtetrabz_tsmall_a1(e,V,tsmall)
     476              :   !
     477              :   !IMPLICIT NONE
     478              :   !
     479              :   REAL(8),INTENT(IN) :: e(4)
     480              :   REAL(8),INTENT(OUT) :: V
     481              :   REAL(8),INTENT(OUT) :: tsmall(4,4)
     482              :   !
     483              :   !INTEGER :: ii
     484              :   REAL(8) :: a(4,4)
     485              :   !
     486            0 :   a = a_from_e(e)
     487              :   !DO ii = 1, 4
     488              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     489              :   !END DO
     490              :   !
     491            0 :   V = a(2,1) * a(3,1) * a(4,1)
     492              :   !
     493            0 :   tsmall(1, 1:4) = (/   1d0,    0d0,    0d0,    0d0/)
     494            0 :   tsmall(2, 1:4) = (/a(1,2), a(2,1),    0d0,    0d0/)
     495            0 :   tsmall(3, 1:4) = (/a(1,3),    0d0, a(3,1),    0d0/)
     496            0 :   tsmall(4, 1:4) = (/a(1,4),    0d0,    0d0, a(4,1)/)
     497              :   !
     498            0 : END SUBROUTINE libtetrabz_tsmall_a1
     499              : !
     500              : ! Cut small tetrahedron B1
     501              : !
     502            0 : pure SUBROUTINE libtetrabz_tsmall_b1(e,V,tsmall)
     503              :   !
     504              :   !IMPLICIT NONE
     505              :   !
     506              :   REAL(8),INTENT(IN) :: e(4)
     507              :   REAL(8),INTENT(OUT) :: V
     508              :   REAL(8),INTENT(OUT) :: tsmall(4,4)
     509              :   !
     510              :   !INTEGER :: ii
     511              :   REAL(8) :: a(4,4)
     512              :   !
     513            0 :   a = a_from_e(e)
     514              :   !DO ii = 1, 4
     515              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     516              :   !END DO
     517              :   !
     518            0 :   V = a(3,1) * a(4,1) * a(2,4)
     519              :   !
     520            0 :   tsmall(1, 1:4) = (/   1d0,    0d0,    0d0,    0d0/)
     521            0 :   tsmall(2, 1:4) = (/a(1,3),    0d0, a(3,1),    0d0/)
     522            0 :   tsmall(3, 1:4) = (/a(1,4),    0d0,    0d0, a(4,1)/)
     523            0 :   tsmall(4, 1:4) = (/   0d0, a(2,4),    0d0, a(4,2)/)
     524              :   !
     525            0 : END SUBROUTINE libtetrabz_tsmall_b1
     526              : !
     527              : ! Cut small tetrahedron B2
     528              : !
     529            0 : pure SUBROUTINE libtetrabz_tsmall_b2(e,V,tsmall)
     530              :   !
     531              :   !IMPLICIT NONE
     532              :   !
     533              :   REAL(8),INTENT(IN) :: e(4)
     534              :   REAL(8),INTENT(OUT) :: V
     535              :   REAL(8),INTENT(OUT) :: tsmall(4,4)
     536              :   !
     537              :   !INTEGER :: ii
     538              :   REAL(8) :: a(4,4)
     539              :   !
     540            0 :   a = a_from_e(e)
     541              :   !DO ii = 1, 4
     542              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     543              :   !END DO
     544              :   !
     545            0 :   V = a(3,2) * a(4,2)
     546              :   !
     547            0 :   tsmall(1, 1:4) = (/1d0,    0d0,    0d0,    0d0/)
     548            0 :   tsmall(2, 1:4) = (/0d0,    1d0,    0d0,    0d0/)
     549            0 :   tsmall(3, 1:4) = (/0d0, a(2,3), a(3,2),    0d0/)
     550            0 :   tsmall(4, 1:4) = (/0d0, a(2,4),    0d0, a(4,2)/)
     551              :   !
     552            0 : END SUBROUTINE libtetrabz_tsmall_b2
     553              : !
     554              : ! Cut small tetrahedron B3
     555              : !
     556            0 : pure SUBROUTINE libtetrabz_tsmall_b3(e,V,tsmall)
     557              :   !
     558              :   !IMPLICIT NONE
     559              :   !
     560              :   REAL(8),INTENT(IN) :: e(4)
     561              :   REAL(8),INTENT(OUT) :: V
     562              :   REAL(8),INTENT(OUT) :: tsmall(4,4)
     563              :   !
     564              :   !INTEGER :: ii
     565              :   REAL(8) :: a(4,4)
     566              :   !
     567            0 :   a = a_from_e(e)
     568              :   !DO ii = 1, 4
     569              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     570              :   !END DO
     571              :   !
     572            0 :   V = a(2,3) * a(3,1) * a(4,2)
     573              :   !
     574            0 :   tsmall(1, 1:4) = (/   1d0,    0d0,    0d0,    0d0/)
     575            0 :   tsmall(2, 1:4) = (/a(1,3),    0d0, a(3,1),    0d0/)
     576            0 :   tsmall(3, 1:4) = (/   0d0, a(2,3), a(3,2),    0d0/)
     577            0 :   tsmall(4, 1:4) = (/   0d0, a(2,4),    0d0, a(4,2)/)
     578              :   !
     579            0 : END SUBROUTINE libtetrabz_tsmall_b3
     580              : !
     581              : ! Cut small tetrahedron C1
     582              : !
     583            0 : pure SUBROUTINE libtetrabz_tsmall_c1(e,V,tsmall)
     584              :   !
     585              :   !IMPLICIT NONE
     586              :   !
     587              :   REAL(8),INTENT(IN) :: e(4)
     588              :   REAL(8),INTENT(OUT) :: V
     589              :   REAL(8),INTENT(OUT) :: tsmall(4,4)
     590              :   !
     591              :   !INTEGER :: ii
     592              :   REAL(8) :: a(4,4)
     593              :   !
     594            0 :   a = a_from_e(e)
     595              :   !DO ii = 1, 4
     596              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     597              :   !END DO
     598              :   !
     599            0 :   V = a(4,3)
     600              :   !
     601            0 :   tsmall(1, 1:4) = (/1d0, 0d0,    0d0,    0d0/)
     602            0 :   tsmall(2, 1:4) = (/0d0, 1d0,    0d0,    0d0/)
     603            0 :   tsmall(3, 1:4) = (/0d0, 0d0,    1d0,    0d0/)
     604            0 :   tsmall(4, 1:4) = (/0d0, 0d0, a(3,4), a(4,3)/)
     605              :   !
     606            0 : END SUBROUTINE libtetrabz_tsmall_c1
     607              : !
     608              : ! Cut small tetrahedron C2
     609              : !
     610            0 : pure SUBROUTINE libtetrabz_tsmall_c2(e,V,tsmall)
     611              :   !
     612              :   !IMPLICIT NONE
     613              :   !
     614              :   REAL(8),INTENT(IN) :: e(4)
     615              :   REAL(8),INTENT(OUT) :: V
     616              :   REAL(8),INTENT(OUT) :: tsmall(4,4)
     617              :   !
     618              :   !INTEGER :: ii
     619              :   REAL(8) :: a(4,4)
     620              :   !
     621            0 :   a = a_from_e(e)
     622              :   !DO ii = 1, 4
     623              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     624              :   !END DO
     625              :   !
     626            0 :   V = a(3,4) * a(4,2)
     627              :   !
     628            0 :   tsmall(1, 1:4) = (/1d0,    0d0,    0d0,    0d0/)
     629            0 :   tsmall(2, 1:4) = (/0d0,    1d0,    0d0,    0d0/)
     630            0 :   tsmall(3, 1:4) = (/0d0, a(2,4),    0d0, a(4,2)/)
     631            0 :   tsmall(4, 1:4) = (/0d0,    0d0, a(3,4), a(4,3)/)
     632              :   !
     633            0 : END SUBROUTINE libtetrabz_tsmall_c2
     634              : !
     635              : ! Cut small tetrahedron C3
     636              : !
     637            0 : pure SUBROUTINE libtetrabz_tsmall_c3(e,V,tsmall)
     638              :   !
     639              :   !IMPLICIT NONE
     640              :   !
     641              :   REAL(8),INTENT(IN) :: e(4)
     642              :   REAL(8),INTENT(OUT) :: V
     643              :   REAL(8),INTENT(OUT) :: tsmall(4,4)
     644              :   !
     645              :   !INTEGER :: ii
     646              :   REAL(8) :: a(4,4)
     647              :   !
     648            0 :   a = a_from_e(e)
     649              :   !DO ii = 1, 4
     650              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     651              :   !END DO
     652              :   !
     653            0 :   V = a(3,4) * a(2,4) * a(4,1)
     654              :   !
     655            0 :   tsmall(1, 1:4) = (/   1d0,    0d0,    0d0,    0d0/)
     656            0 :   tsmall(2, 1:4) = (/a(1,4),    0d0,    0d0, a(4,1)/)
     657            0 :   tsmall(3, 1:4) = (/   0d0, a(2,4),    0d0, a(4,2)/)
     658            0 :   tsmall(4, 1:4) = (/   0d0,    0d0, a(3,4), a(4,3)/)
     659              :   !
     660            0 : END SUBROUTINE libtetrabz_tsmall_c3
     661              : !
     662              : ! Cut triangle A1
     663              : !
     664        28560 : pure SUBROUTINE libtetrabz_triangle_a1(e,V,tsmall)
     665              :   !
     666              :   !IMPLICIT NONE
     667              :   !
     668              :   REAL(8),INTENT(IN) :: e(4)
     669              :   REAL(8),INTENT(OUT) :: V
     670              :   REAL(8),INTENT(OUT) :: tsmall(3,4)
     671              :   !
     672              :   !INTEGER :: ii
     673              :   REAL(8) :: a(4,4)
     674              :   !
     675        28560 :   a = a_from_e(e)
     676              :   !DO ii = 1, 4
     677              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     678              :   !END DO
     679              :   !
     680              :   !V = 3d0 * a(2,1) * a(3,1) * a(4,1) / (0d0 - e(1))
     681        28560 :   V = 3d0 * a(2,1) * a(3,1)           / (e(4) - e(1))
     682              :   !
     683       142800 :   tsmall(1,1:4) = (/a(1,2), a(2,1),    0d0,    0d0/)
     684       142800 :   tsmall(2,1:4) = (/a(1,3),    0d0, a(3,1),    0d0/)
     685       142800 :   tsmall(3,1:4) = (/a(1,4),    0d0,    0d0, a(4,1)/)
     686              :   !
     687        28560 : END SUBROUTINE libtetrabz_triangle_a1
     688              : !
     689              : ! Cut triangle B1
     690              : !
     691        17640 : pure SUBROUTINE libtetrabz_triangle_b1(e,V,tsmall)
     692              :   !
     693              :   !IMPLICIT NONE
     694              :   !
     695              :   REAL(8),INTENT(IN) :: e(4)
     696              :   REAL(8),INTENT(OUT) :: V
     697              :   REAL(8),INTENT(OUT) :: tsmall(3,4)
     698              :   !
     699              :   !INTEGER :: ii
     700              :   REAL(8) :: a(4,4)
     701              :   !
     702        17640 :   a = a_from_e(e)
     703              :   !DO ii = 1, 4
     704              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     705              :   !END DO
     706              :   !
     707              :   !V = 3d0 * a(3,1) * a(4,1) * a(2,4) / (0d0 - e(1))
     708        17640 :   V = 3d0           * a(4,1) * a(2,4) / (e(3) - e(1))
     709              :   !
     710        88200 :   tsmall(1,1:4) = (/a(1,3),    0d0, a(3,1),    0d0/)
     711        88200 :   tsmall(2,1:4) = (/a(1,4),    0d0,    0d0, a(4,1)/)
     712        88200 :   tsmall(3,1:4) = (/   0d0, a(2,4),    0d0, a(4,2)/)
     713              :   !
     714        17640 : END SUBROUTINE libtetrabz_triangle_b1
     715              : !
     716              : ! Cut triangle B2
     717              : !
     718        17640 : pure SUBROUTINE libtetrabz_triangle_b2(e,V,tsmall)
     719              :   !
     720              :   !IMPLICIT NONE
     721              :   !
     722              :   REAL(8),INTENT(IN) :: e(4)
     723              :   REAL(8),INTENT(OUT) :: V
     724              :   REAL(8),INTENT(OUT) :: tsmall(3,4)
     725              :   !
     726              :   !INTEGER :: ii
     727              :   REAL(8) :: a(4,4)
     728              :   !
     729        17640 :   a = a_from_e(e)
     730              :   !DO ii = 1, 4
     731              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     732              :   !END DO
     733              :   !
     734              :   !V = 3d0 * a(2,3) * a(3,1) * a(4,2) / (0d0 - e(1))
     735        17640 :   V = 3d0 * a(2,3)           * a(4,2) / (e(3) - e(1))
     736              :   !
     737        88200 :   tsmall(1,1:4) = (/a(1,3),    0d0, a(3,1),    0d0/)
     738        88200 :   tsmall(2,1:4) = (/   0d0, a(2,3), a(3,2),    0d0/)
     739        88200 :   tsmall(3,1:4) = (/   0d0, a(2,4),    0d0, a(4,2)/)
     740              :   !
     741        17640 : END SUBROUTINE libtetrabz_triangle_b2
     742              : !
     743              : ! Cut triangle C1
     744              : !
     745        10920 : pure SUBROUTINE libtetrabz_triangle_c1(e,V,tsmall)
     746              :   !
     747              :   !IMPLICIT NONE
     748              :   !
     749              :   REAL(8),INTENT(IN) :: e(4)
     750              :   REAL(8),INTENT(OUT) :: V
     751              :   REAL(8),INTENT(OUT) :: tsmall(3,4)
     752              :   !
     753              :   !INTEGER :: ii
     754              :   REAL(8) :: a(4,4)
     755              :   !
     756        10920 :   a = a_from_e(e)
     757              :   !DO ii = 1, 4
     758              :   !   a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
     759              :   !END DO
     760              :   !
     761              :   !V = 3d0 * a(1,4) * a(2,4) * a(3,4) / (e(4) - 0d0)
     762        10920 :   V = 3d0 * a(1,4) * a(2,4)           / (e(4) - e(3))
     763              :   !
     764        54600 :   tsmall(1,1:4) = (/a(1,4),    0d0,    0d0, a(4,1)/)
     765        54600 :   tsmall(2,1:4) = (/   0d0, a(2,4),    0d0, a(4,2)/)
     766        54600 :   tsmall(3,1:4) = (/   0d0,    0d0, a(3,4), a(4,3)/)
     767              :   !
     768        10920 : END SUBROUTINE libtetrabz_triangle_c1
     769              : !
     770              : ! MPI_Allreduce for double scaler
     771              : !
     772            0 : SUBROUTINE libtetrabz_mpisum_d(comm,scaler)
     773              :   !
     774              :   !IMPLICIT NONE
     775              :   !
     776              :   INTEGER :: comm
     777              :   REAL(8) :: scaler
     778              :   !
     779              : #if defined(HAVE_MPI)
     780              :   INTEGER :: ierr
     781              :   REAL(8) :: arr_scaler(1)
     782              :   !
     783              :   CALL MPI_allREDUCE([scaler], arr_scaler, 1, &
     784            0 :   &                  MPI_DOUBLE_PRECISION, MPI_SUM, comm, ierr)
     785            0 :   scaler=arr_scaler(1)
     786              : #endif
     787              :   !
     788            0 : END SUBROUTINE libtetrabz_mpisum_d
     789              : !
     790              : ! MPI_Allreduce for double vector
     791              : !
     792            0 : SUBROUTINE libtetrabz_mpisum_dv(comm,ndim,vector)
     793              :   !
     794              :   !IMPLICIT NONE
     795              :   !
     796              :   INTEGER :: comm, ndim
     797              :   REAL(8) :: vector(ndim)
     798              :   !
     799              : #if defined(HAVE_MPI)
     800              :   INTEGER :: ierr
     801              : #ifndef HAVE_MPI2_INPLACE
     802              :   REAL(8) :: vector_out(ndim)
     803              : #endif
     804              :   !
     805              : #ifdef HAVE_MPI2_INPLACE
     806              :   CALL MPI_allREDUCE(MPI_IN_PLACE, vector, ndim, &
     807            0 :   &                  MPI_DOUBLE_PRECISION, MPI_SUM, comm, ierr)
     808              : #else
     809              :   CALL MPI_allREDUCE(vector, vector_out, ndim, &
     810              :   &                  MPI_DOUBLE_PRECISION, MPI_SUM, comm, ierr)
     811              :   vector(1:ndim)=vector_out(1:ndim)
     812              : #endif
     813              : #endif
     814              :   !
     815            0 : END SUBROUTINE libtetrabz_mpisum_dv
     816              : !
     817              : ! MPI_Allreduce for double complex vector
     818              : !
     819            0 : SUBROUTINE libtetrabz_mpisum_zv(comm,ndim,vector)
     820              :   !
     821              :   !IMPLICIT NONE
     822              :   !
     823              :   INTEGER :: comm, ndim
     824              :   COMPLEX(8) :: vector(ndim)
     825              :   !
     826              : #if defined(HAVE_MPI)
     827              :   INTEGER :: ierr
     828              : #ifndef HAVE_MPI2_INPLACE
     829              :   COMPLEX(8) :: vector_out(ndim)
     830              : #endif
     831              :   !
     832              : #ifdef HAVE_MPI2_INPLACE
     833              :   CALL MPI_allREDUCE(MPI_IN_PLACE, vector, ndim, &
     834            0 :   &                  MPI_DOUBLE_COMPLEX, MPI_SUM, comm, ierr)
     835              : #else
     836              :   CALL MPI_allREDUCE(vector, vector_out, ndim, &
     837              :   &                  MPI_DOUBLE_COMPLEX, MPI_SUM, comm, ierr)
     838              :   vector(1:ndim)=vector_out(1:ndim)
     839              : #endif
     840              : #endif
     841              :   !
     842            0 : END SUBROUTINE libtetrabz_mpisum_zv
     843              : !
     844              : END MODULE libtetrabz_common
        

Generated by: LCOV version 2.3-1