LCOV - code coverage report
Current view: top level - src/70_gw - m_gwls_LanczosBasis.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.1 % 68 66
Test Date: 2026-09-21 13:49:52 Functions: 100.0 % 3 3

            Line data    Source code
       1              : !!****m* ABINIT/m_gwls_LanczosBasis
       2              : !! NAME
       3              : !! m_gwls_LanczosBasis
       4              : !!
       5              : !! FUNCTION
       6              : !!  .
       7              : !!
       8              : !! COPYRIGHT
       9              : !! Copyright (C) 2009-2026 ABINIT group (JLJ, BR, MC)
      10              : !! This file is distributed under the terms of the
      11              : !! GNU General Public License, see ~abinit/COPYING
      12              : !! or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : 
      23              : module m_gwls_LanczosBasis
      24              : !----------------------------------------------------------------------------------------------------
      25              : ! This module contains the static Lanczos basis, which should be computed once and for all,
      26              : ! and then be made available to other modules.
      27              : !----------------------------------------------------------------------------------------------------
      28              : ! local modules
      29              : use m_gwls_utility
      30              : use m_gwls_wf
      31              : use m_gwls_hamiltonian
      32              : use m_gwls_GenerateEpsilon
      33              : use m_dtset
      34              : 
      35              : ! Abinit modules
      36              : use defs_basis
      37              : use m_abicore
      38              : 
      39              : implicit none
      40              : save
      41              : private
      42              : !!***
      43              : 
      44              : ! Global arrays
      45              : 
      46              : ! basis which diagonalizes the static dielectric matrix
      47              : complex(dp), public, allocatable :: Lbasis_lanczos(:,:)  ! complex array which contains the Lanczos basis
      48              : 
      49              : ! basis which diagonalizes the model static dielectric matrix
      50              : complex(dp), public, allocatable :: Lbasis_model_lanczos(:,:)  ! complex array which contains the Lanczos basis
      51              : 
      52              : 
      53              : !------------------------------------------------------------
      54              : !
      55              : ! OBSOLETE STRUCTURES, KEPT AROUND TO NOT BREAK THE CODE
      56              : !    Some cleaning will eventually have to be done!
      57              : !
      58              : !------------------------------------------------------------
      59              : ! Lanczos basis which puts the static dielectric matrix in bands (OBSOLETE)
      60              : real(dp), public, allocatable :: lanczos_basis_0(:,:,:,:)
      61              : 
      62              : ! modified basis, of the form (V^{1/2}. l^*) psie (OBSOLETE)
      63              : real(dp), public, allocatable :: basis_0(:,:,:,:)
      64              : 
      65              : 
      66              : ! modified basis, of the form (V^{1/2}. l^*) psie
      67              : complex(dp), public, allocatable :: Lbasis_modified(:,:)
      68              : 
      69              : 
      70              : integer, public  :: lanczos_basis_size
      71              : !!***
      72              : 
      73              : public :: setup_Lanczos_basis
      74              : public :: cleanup_Lanczos_basis
      75              : public :: modify_Lbasis_Coulomb
      76              : !!***
      77              : contains
      78              : 
      79              : !!****f* m_hamiltonian/setup_Lanczos_basis
      80              : !! NAME
      81              : !!  setup_Lanczos_basis
      82              : !!
      83              : !! FUNCTION
      84              : !!  .
      85              : !!
      86              : !! INPUTS
      87              : !!
      88              : !! OUTPUT
      89              : !!
      90              : !! SOURCE
      91              : 
      92            7 : subroutine setup_Lanczos_basis(lmax,lmax_model)
      93              : !----------------------------------------------------------------------------------------------------
      94              : ! Set up the lanczos basis
      95              : !----------------------------------------------------------------------------------------------------
      96              : 
      97              : integer, intent(in) :: lmax, lmax_model
      98              : 
      99              : ! *************************************************************************
     100              : 
     101           28 : ABI_MALLOC(Lbasis_lanczos,(npw_k,lmax))
     102              : 
     103            7 : if (lmax_model > 0) then
     104           24 :   ABI_MALLOC(Lbasis_model_lanczos,(npw_k,lmax_model))
     105              : end if
     106              : 
     107            7 : end subroutine setup_Lanczos_basis
     108              : !!***
     109              : 
     110              : !!****f* m_hamiltonian/cleanup_Lanczos_basis
     111              : !! NAME
     112              : !!  cleanup_Lanczos_basis
     113              : !!
     114              : !! FUNCTION
     115              : !!  .
     116              : !!
     117              : !! INPUTS
     118              : !!
     119              : !! OUTPUT
     120              : !!
     121              : !! SOURCE
     122              : 
     123            7 : subroutine cleanup_Lanczos_basis()
     124              : 
     125              : 
     126              : ! *************************************************************************
     127              : 
     128              : ! if(allocated()) ABI_FREE() can cause a segfault if used in this form, without the THEN.
     129              : ! This is because ABI_MALLOC is expanded at compilation time in many statements; and the if() can only prevent the execution of
     130              : ! the first.
     131              : ! So, the deallocation takes place even if allocated() returns .false. without the THEN.
     132            7 : if (allocated(Lbasis_lanczos))  then
     133            7 :   ABI_FREE(Lbasis_lanczos)
     134              : end if
     135            7 : if (allocated(Lbasis_model_lanczos))  then
     136            6 :   ABI_FREE(Lbasis_model_lanczos)
     137              : end if
     138              : 
     139            7 : end subroutine cleanup_Lanczos_basis
     140              : !!***
     141              : 
     142              : !!****f* m_hamiltonian/modify_Lbasis_Coulomb
     143              : !! NAME
     144              : !!  modify_Lbasis_Coulomb
     145              : !!
     146              : !! FUNCTION
     147              : !!  .
     148              : !!
     149              : !! INPUTS
     150              : !!
     151              : !! OUTPUT
     152              : !!
     153              : !! SOURCE
     154              : 
     155            7 : subroutine modify_Lbasis_Coulomb(psie_k, lmax, lmax_model)
     156              : !----------------------------------------------------------------------------------------------------
     157              : ! This subroutine computes, once and for all, the vectors (V^1/2.L)^*.psie
     158              : !----------------------------------------------------------------------------------------------------
     159              : real(dp),intent(in)  :: psie_k(2,npw_k)
     160              : integer ,intent(in)  :: lmax, lmax_model
     161              : 
     162              : 
     163            7 : real(dp), allocatable  :: psik_wrk(:,:), psikb_wrk(:,:), psikg_wrk(:,:)
     164            7 : real(dp), allocatable  :: psikg_e(:,:)
     165              : 
     166              : integer  :: iblk_lanczos, nbdblock_lanczos
     167              : 
     168              : integer   :: l, mb
     169              : 
     170              : ! *************************************************************************
     171              : 
     172           21 : ABI_MALLOC(psik_wrk  ,(2,npw_k))
     173           21 : ABI_MALLOC(psikb_wrk ,(2,npw_kb))
     174           21 : ABI_MALLOC(psikg_wrk ,(2,npw_g))
     175           14 : ABI_MALLOC(psikg_e ,(2,npw_g))
     176              : 
     177              : ! copy the valence state on every row of FFT processors
     178           18 : do mb = 1, blocksize
     179         3873 : psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k) = psie_k(:,:)
     180              : end do ! mb
     181              : ! Transform to FFT representation
     182            7 : call wf_block_distribute(psikb_wrk,  psikg_e,1) ! LA -> FFT
     183              : 
     184              : 
     185              : ! Number of blocks of lanczos vectors
     186            7 : nbdblock_lanczos = lmax/blocksize
     187            7 : if (modulo(lmax,blocksize) /= 0) nbdblock_lanczos = nbdblock_lanczos + 1
     188              : 
     189              : ! loop on all blocks of lanczos vectors
     190           47 : do iblk_lanczos = 1, nbdblock_lanczos
     191              : 
     192              : ! loop on all states within this block
     193           96 : do mb = 1, blocksize
     194              : ! Determine the index of the Lanczos vector
     195           56 : l = (iblk_lanczos-1)*blocksize + mb
     196              : 
     197           56 : if ( l <= lmax) then
     198         8280 :   psik_wrk(1,:) = dble (Lbasis_lanczos(:,l))
     199         8280 :   psik_wrk(2,:) = dimag(Lbasis_lanczos(:,l))
     200              : else
     201            0 :   psik_wrk(:,:) = zero
     202              : end if
     203              : ! Apply coulomb potential
     204           56 : call sqrt_vc_k(psik_wrk)
     205              : 
     206              : ! Store in array of blocks of wavefunctions
     207        24768 : psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k) = psik_wrk(:,:)
     208              : 
     209              : end do ! mb
     210              : 
     211              : ! Transform to FFT representation
     212           40 : call wf_block_distribute(psikb_wrk,  psikg_wrk,1) ! LA -> FFT
     213              : 
     214              : ! fourier transform, conjugate
     215           40 : call g_to_r(psir1,psikg_wrk)
     216       274360 : psir1(2,:,:,:) = -psir1(2,:,:,:)
     217              : 
     218              : ! compute the product with the state "e"
     219           40 : call gr_to_g(psikg_wrk, psir1, psikg_e)
     220              : 
     221              : ! return to LA configuration
     222              : 
     223              : ! Transform to LA representation
     224           40 : call wf_block_distribute(psikb_wrk,  psikg_wrk, 2) ! FFT -> LA
     225              : 
     226          103 : do mb = 1, blocksize
     227              : ! Determine the index of the Lanczos vector
     228           56 : l = (iblk_lanczos-1)*blocksize + mb
     229              : 
     230           96 : if ( l <= lmax) then
     231        24728 :   psik_wrk(:,:) = psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k)
     232         8280 :   Lbasis_lanczos(:,l) = cmplx_1*psik_wrk(1,:)+cmplx_i*psik_wrk(2,:)
     233              : end if
     234              : 
     235              : end do ! mb
     236              : 
     237              : end do ! iblk_lanczos
     238              : 
     239              : ! repeat, for model basis!
     240              : ! Number of blocks of lanczos vectors
     241            7 : nbdblock_lanczos = lmax_model/blocksize
     242            7 : if (modulo(lmax_model,blocksize) /= 0) nbdblock_lanczos = nbdblock_lanczos + 1
     243              : 
     244              : ! loop on all blocks of lanczos vectors
     245           39 : do iblk_lanczos = 1, nbdblock_lanczos
     246              : 
     247              : ! loop on all states within this block
     248           80 : do mb = 1, blocksize
     249              : ! Determine the index of the Lanczos vector
     250           48 : l = (iblk_lanczos-1)*blocksize + mb
     251              : 
     252           48 : if ( l <= lmax_model) then
     253         6216 :   psik_wrk(1,:) = dble (Lbasis_model_lanczos(:,l))
     254         6216 :   psik_wrk(2,:) = dimag(Lbasis_model_lanczos(:,l))
     255              : else
     256            0 :   psik_wrk(:,:) = zero
     257              : end if
     258              : ! Apply coulomb potential
     259           48 : call sqrt_vc_k(psik_wrk)
     260              : 
     261              : ! Store in array of blocks of wavefunctions
     262        18584 : psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k) = psik_wrk(:,:)
     263              : 
     264              : end do ! mb
     265              : 
     266              : ! Transform to FFT representation
     267           32 : call wf_block_distribute(psikb_wrk,  psikg_wrk,1) ! LA -> FFT
     268              : 
     269              : ! fourier transform, conjugate
     270           32 : call g_to_r(psir1,psikg_wrk)
     271       219488 : psir1(2,:,:,:) = -psir1(2,:,:,:)
     272              : 
     273              : ! compute the product with the state "e"
     274           32 : call gr_to_g(psikg_wrk, psir1, psikg_e)
     275              : 
     276              : ! return to LA configuration
     277              : ! Transform to LA representation
     278           32 : call wf_block_distribute(psikb_wrk,  psikg_wrk, 2) ! FFT -> LA
     279              : 
     280           87 : do mb = 1, blocksize
     281              : ! Determine the index of the Lanczos vector
     282           48 : l = (iblk_lanczos-1)*blocksize + mb
     283              : 
     284           80 : if ( l <= lmax_model) then
     285        18552 :   psik_wrk(:,:) = psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k)
     286         6216 :   Lbasis_model_lanczos(:,l) = cmplx_1*psik_wrk(1,:)+cmplx_i*psik_wrk(2,:)
     287              : end if
     288              : 
     289              : end do ! mb
     290              : 
     291              : end do
     292              : 
     293            7 : ABI_FREE(psik_wrk  )
     294            7 : ABI_FREE(psikb_wrk )
     295            7 : ABI_FREE(psikg_wrk )
     296            7 : ABI_FREE(psikg_e )
     297              : 
     298              : 
     299            7 : end subroutine modify_Lbasis_Coulomb
     300              : !!***
     301              : 
     302              : end module m_gwls_LanczosBasis
     303              : !!***
        

Generated by: LCOV version 2.3-1