LCOV - code coverage report
Current view: top level - shared/common/src/17_libtetra_ext - libtetrabz_dbldelta_mod.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 86.6 % 82 71
Test Date: 2026-09-21 22:40:37 Functions: 100.0 % 3 3

            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_dbldelta_mod
      30              :   !
      31              : 
      32              :   use m_abicore
      33              :   use m_errors
      34              : 
      35              :   !IMPLICIT NONE
      36              :   !
      37              :   PRIVATE
      38              :   PUBLIC :: libtetrabz_dbldelta
      39              :   !
      40              : CONTAINS
      41              : !
      42              : ! Compute doubledelta
      43              : !
      44           35 : SUBROUTINE libtetrabz_dbldelta(ltetra,bvec,nb,nge,eig1,eig2,ngw,wght,comm)
      45              :   !
      46              :   use, intrinsic :: iso_c_binding
      47              :   USE libtetrabz_common, ONLY : libtetrabz_initialize, libtetrabz_interpol_indx, libtetrabz_mpisum_dv
      48              :   !IMPLICIT NONE
      49              :   !
      50              :   INTEGER(C_INT),INTENT(IN) :: ltetra, nb, nge(3), ngw(3)
      51              :   REAL(C_DOUBLE),INTENT(IN) :: bvec(9), eig1(nb,PRODUCT(nge(1:3))), eig2(nb,PRODUCT(nge(1:3)))
      52              :   REAL(C_DOUBLE),INTENT(OUT) :: wght(nb*nb,PRODUCT(ngw(1:3)))
      53              :   INTEGER(C_INT),INTENT(IN),OPTIONAL :: comm
      54              :   !
      55              :   LOGICAL :: linterpol
      56              :   INTEGER :: nt_local, nk_local, nkBZ, ik, kintp(20), nintp
      57           35 :   INTEGER,ALLOCATABLE :: ik_global(:,:), ik_local(:,:)
      58              :   REAL(8) :: wlsm(4,20), wintp(1,20)
      59           35 :   REAL(8),ALLOCATABLE :: wghtd(:,:,:), kvec(:,:)
      60              :   !
      61           35 :   nintp = 16 * ltetra - 12
      62              :   !
      63           35 :   IF(PRESENT(comm)) THEN
      64              :      CALL libtetrabz_initialize(ltetra,nge,ngw,bvec,linterpol,wlsm,nk_local,&
      65           35 :      &                          nt_local,nkBZ,ik_global,ik_local,kvec,comm)
      66              :   ELSE
      67              :      CALL libtetrabz_initialize(ltetra,nge,ngw,bvec,linterpol,wlsm,nk_local,&
      68            0 :      &                          nt_local,nkBZ,ik_global,ik_local,kvec)
      69              :   END IF
      70              :   !
      71           35 :   IF(linterpol) THEN
      72              :      !
      73            0 :      ABI_MALLOC(wghtd, (nb*nb,1,nk_local))
      74            0 :      CALL libtetrabz_dbldelta_main(wlsm,nt_local,ik_global,ik_local,nb,nkBZ,eig1,eig2,nk_local,wghtd)
      75              :      !
      76              :      ! Interpolation
      77              :      !
      78            0 :      wght(1:nb*nb,1:PRODUCT(ngw(1:3))) = 0d0
      79            0 :      DO ik = 1, nk_local
      80            0 :         CALL libtetrabz_interpol_indx(nintp,ngw,kvec(1:3,ik),kintp,wintp)
      81              :         wght(1:nb*nb,kintp(1:nintp)) = wght(1:nb*nb,             kintp(1:nintp)) &
      82            0 :         &                    + MATMUL(wghtd(1:nb*nb,1:1,ik), wintp(1:1,1:nintp))
      83              :      END DO ! ik = 1, nk_local
      84            0 :      ABI_FREE(wghtd)
      85            0 :      ABI_FREE(kvec)
      86              :      !
      87            0 :      IF(PRESENT(comm)) CALL libtetrabz_mpisum_dv(comm, nb*nb*PRODUCT(ngw(1:3)), wght)
      88              :      !
      89              :   ELSE
      90           35 :      CALL libtetrabz_dbldelta_main(wlsm,nt_local,ik_global,ik_local,nb,nkBZ,eig1,eig2,nk_local,wght)
      91              :   END IF
      92              :   !
      93           35 :   ABI_FREE(ik_global)
      94           35 :   ABI_FREE(ik_local)
      95              :   !
      96           35 : END SUBROUTINE libtetrabz_dbldelta
      97              : !
      98              : ! Main SUBROUTINE for Delta(E1) * Delta(E2)
      99              : !
     100           35 : SUBROUTINE libtetrabz_dbldelta_main(wlsm,nt_local,ik_global,ik_local,nb,nkBZ,eig1,eig2,nk_local,dbldelta)
     101              :   !
     102              :   USE libtetrabz_common, ONLY : libtetrabz_sort, &
     103              :   &                             libtetrabz_triangle_a1, libtetrabz_triangle_b1, &
     104              :   &                             libtetrabz_triangle_b2, libtetrabz_triangle_c1
     105              :   !IMPLICIT NONE
     106              :   !
     107              :   INTEGER,INTENT(IN) :: nt_local, nb, nkBZ, nk_local, &
     108              :   &                     ik_global(20,nt_local), ik_local(20,nt_local)
     109              :   REAL(8),INTENT(IN) :: wlsm(4,20), eig1(nb,nkBZ), eig2(nb,nkBZ)
     110              :   REAL(8),INTENT(OUT) :: dbldelta(nb,nb,nk_local)
     111              :   !
     112              :   INTEGER :: ib, indx(4), it
     113           70 :   REAL(8) :: e(4), ei1(4,nb), ej1(4,nb), ej2(3,nb), V, thr = 1d-10, &
     114           35 :   &          tsmall(3,4), w1(nb,4), w2(nb,3)
     115              :   !
     116       125475 :   dbldelta(1:nb,1:nb,1:nk_local) = 0d0
     117              :   !
     118              :   !$OMP PARALLEL DEFAULT(NONE) &
     119              :   !$OMP & SHARED(dbldelta,eig1,eig2,ik_global,ik_local,nb,nt_local,thr,wlsm) &
     120              :   !$OMP & PRIVATE(e,ei1,ej1,ej2,ib,indx,it,tsmall,V,w1,w2)
     121              :   !
     122       107555 :   DO it = 1, nt_local
     123              :      !
     124       322560 :      DO ib = 1, nb
     125     27095040 :         ei1(1:4,ib) = MATMUL(wlsm(1:4,1:20), eig1(ib, ik_global(1:20,it)))
     126     27417600 :         ej1(1:4,ib) = MATMUL(wlsm(1:4,1:20), eig2(ib, ik_global(1:20,it)))
     127              :      END DO
     128              :      !
     129              :      !$OMP DO
     130       322595 :      DO ib = 1, nb
     131              :         !
     132      2795520 :         w1(1:nb,1:4) = 0d0
     133      1075200 :         e(1:4) = ei1(1:4, ib)
     134       215040 :         CALL libtetrabz_sort(4,e,indx)
     135              :         !
     136       215040 :         IF(e(1) < 0d0 .AND. 0d0 <= e(2)) THEN
     137              :            !
     138        28560 :            CALL libtetrabz_triangle_a1(e,V,tsmall)
     139              :            !
     140        28560 :            IF(V > thr) THEN
     141              :               !
     142      1570800 :               ej2(1:3,1:nb) = MATMUL(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
     143        28560 :               CALL libtetrabz_dbldelta2(nb,ej2,w2)
     144              :               w1(1:nb,indx(1:4)) = w1(1:nb,            indx(1:4)) &
     145      1942080 :               &       + V * MATMUL(w2(1:nb,1:3), tsmall(1:3,1:4))
     146              :               !
     147              :            END IF
     148              :            !
     149       186480 :         ELSE IF( e(2) < 0d0 .AND. 0d0 <= e(3)) THEN
     150              :            !
     151        17640 :            CALL libtetrabz_triangle_b1(e,V,tsmall)
     152              :            !
     153        17640 :            IF(V > thr) THEN
     154              :               !
     155       970200 :               ej2(1:3,1:nb) = MATMUL(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
     156        17640 :               CALL libtetrabz_dbldelta2(nb,ej2,w2)
     157              :               w1(1:nb,indx(1:4)) = w1(1:nb,            indx(1:4)) &
     158      1199520 :               &       + V * MATMUL(w2(1:nb,1:3), tsmall(1:3,1:4))
     159              :               !
     160              :            END IF
     161              :            !
     162        17640 :            CALL libtetrabz_triangle_b2(e,V,tsmall)
     163              :            !
     164        17640 :            IF(V > thr) THEN
     165              :               !
     166       970200 :               ej2(1:3,1:nb) = MATMUL(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
     167        17640 :               CALL libtetrabz_dbldelta2(nb,ej2,w2)
     168              :               w1(1:nb,indx(1:4)) = w1(1:nb,            indx(1:4)) &
     169      1199520 :               &       + V * MATMUL(w2(1:nb,1:3), tsmall(1:3,1:4))
     170              :               !
     171              :            END IF
     172              :            !
     173       168840 :         ELSE IF(e(3) < 0d0 .AND. 0d0 < e(4)) THEN
     174              :            !
     175        10920 :            CALL libtetrabz_triangle_c1(e,V,tsmall)
     176              :            !
     177        10920 :            IF(V > thr) THEN
     178              :               !
     179       600600 :               ej2(1:3,1:nb) = MATMUL(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
     180        10920 :               CALL libtetrabz_dbldelta2(nb,ej2,w2)
     181              :               w1(1:nb,indx(1:4)) = w1(1:nb,            indx(1:4)) &
     182       742560 :               &       + V * MATMUL(w2(1:nb,1:3), tsmall(1:3,1:4))
     183              :               !
     184              :            END IF
     185              :            !
     186              :         END IF
     187              :         !
     188              :         dbldelta(1:nb,ib,ik_local(1:20,it)) = dbldelta(1:nb,ib,   ik_local(1:20,it)) &
     189     95800320 :         &                                  + MATMUL(w1(1:nb,1:4), wlsm(1:4,1:20))
     190              :         !
     191              :      END DO ! ib
     192              :      !$OMP END DO NOWAIT
     193              :      !
     194              :   END DO ! it
     195              :   !
     196              :   !$OMP END PARALLEL
     197              :   !
     198       125475 :   dbldelta(1:nb,1:nb,1:nk_local) = dbldelta(1:nb,1:nb,1:nk_local) / DBLE(6 * nkBZ)
     199              :   !
     200           35 : END SUBROUTINE libtetrabz_dbldelta_main
     201              : !
     202              : ! 2nd step of tetrahedra method.
     203              : !
     204        74760 : SUBROUTINE libtetrabz_dbldelta2(nb,ej,w)
     205              :   !
     206              :   USE libtetrabz_common, ONLY : libtetrabz_sort
     207              :   !IMPLICIT NONE
     208              :   !
     209              :   INTEGER,INTENT(IN) :: nb
     210              :   REAL(8),INTENT(IN) :: ej(3,nb)
     211              :   REAL(8),INTENT(INOUT) :: w(nb,3)
     212              :   !
     213              :   INTEGER :: ib, ii, indx(3)
     214              :   REAL(8) :: a(3,3), e(3), V
     215              :   REAL(8) :: ediff(3)
     216              :   !character(len=500) :: msg
     217              :   !
     218       224280 :   DO ib = 1, nb
     219              :      !
     220       747600 :      IF(maxval(ABS(ej(1:3,ib))) < 1d-10) then
     221              :      ! MG reduce tolerance wrt original version.
     222              :      !IF(maxval(ABS(ej(1:3,ib))) < 1d-22) then
     223              :       !write(std_out, ej(1:3,ib))
     224              :       !write(msg, *)"Nesting for band index:", ib, "ej:", ej(1:3,ib)
     225              :       !ABI_WARNING(msg)
     226              :       !ABI_ERROR(msg)
     227              :       !ABI_ERROR("STOP Nesting !!")
     228            0 :       w(ib,1:3) = 0d0
     229              :       cycle
     230              :      end if
     231              :      !
     232       598080 :      w(ib,1:3) = 0d0
     233       598080 :      e(1:3) = ej(1:3, ib)
     234       149520 :      CALL libtetrabz_sort(3,e,indx)
     235              :      !
     236       598080 :      DO ii = 1, 3
     237      1794240 :         ediff = e(1:3) - e(ii)
     238      1794240 :         where (abs(ediff) < 1.e-10)
     239              :           ediff = 1.e-10
     240              :         end where
     241      1943760 :         a(1:3,ii) = (0d0 - e(ii)) / ediff
     242              :         !a(1:3,ii) = (0d0 - e(ii)) / (e(1:3) - e(ii))
     243              :      END DO
     244              :      !
     245       224280 :      IF((e(1) < 0d0 .AND. 0d0 <= e(2)) .OR. (e(1) <= 0d0 .AND. 0d0 < e(2))) THEN
     246              :         !
     247              :         !V = a(2,1) * a(3,1) / (0d0 - e(1))
     248         7355 :         V = a(2,1)           / (e(3) - e(1))
     249              :         !
     250         7355 :         w(ib,indx(1)) = V * (a(1,2) + a(1,3))
     251         7355 :         w(ib,indx(2)) = V * a(2,1)
     252         7355 :         w(ib,indx(3)) = V * a(3,1)
     253              :         !
     254       142165 :      ELSE IF((e(2) <= 0d0 .AND. 0d0 < e(3)) .OR. (e(2) < 0d0 .AND. 0d0 <= e(3))) THEN
     255              :         !
     256              :         !V = a(1,3) * a(2,3) / (e(3) - 0d0)
     257         6848 :         V = a(2,3)           / (e(3) - e(1))
     258              :         !
     259         6848 :         w(ib,indx(1)) = V * a(1,3)
     260         6848 :         w(ib,indx(2)) = V * a(2,3)
     261         6848 :         w(ib,indx(3)) = V * (a(3,1) + a(3,2))
     262              :         !
     263              :      END IF
     264              :      !
     265              :   END DO ! ib
     266              :   !
     267        74760 : END SUBROUTINE libtetrabz_dbldelta2
     268              : !
     269       289800 : END MODULE libtetrabz_dbldelta_mod
        

Generated by: LCOV version 2.3-1