LCOV - code coverage report
Current view: top level - src/70_gw - m_gwls_GenerateEpsilon.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.1 % 279 271
Test Date: 2026-09-19 15:24:51 Functions: 100.0 % 3 3

            Line data    Source code
       1              : !!****m* ABINIT/m_gwls_GenerateEpsilon
       2              : !! NAME
       3              : !! m_gwls_GenerateEpsilon
       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_GenerateEpsilon
      24              : !----------------------------------------------------------------------------------------------------
      25              : ! This module contains routines to compute and store the dielectric matrix, which plays a
      26              : ! central role in the self energy computations. In particular, global arrays are used to store
      27              : ! the static dielectric matrix.
      28              : !----------------------------------------------------------------------------------------------------
      29              : ! local modules
      30              : use m_gwls_utility
      31              : use m_gwls_wf
      32              : use m_gwls_hamiltonian
      33              : use m_gwls_lineqsolver
      34              : use m_gwls_TimingLog
      35              : use m_gwls_polarisability
      36              : use m_gwls_model_polarisability
      37              : use m_gwls_GWlanczos
      38              : ! Abinit modules
      39              : use m_abicore
      40              : use defs_basis
      41              : use m_dtset
      42              : 
      43              : use m_io_tools,    only : get_unit
      44              : 
      45              : implicit none
      46              : save
      47              : private
      48              : !!***
      49              : 
      50              : ! Global arrays
      51              : 
      52              : real(dp), public, allocatable  :: epsilon_eigenvalues_0(:)     ! eigenvalues of the static dielectric matrix
      53              : 
      54              : complex(dp), public, allocatable  :: epsilon_inverse_0(:,:)   ! eps^{-1}-1 in diagonal basis
      55              : 
      56              : integer, public ::  kmax, nseeds, lmax
      57              : integer, public ::  first_seed
      58              : !!***
      59              : 
      60              : public :: driver_generate_dielectric_matrix
      61              : public :: GeneratePrintDielectricEigenvalues
      62              : public :: Driver_GeneratePrintDielectricEigenvalues
      63              : !!***
      64              : 
      65              : contains
      66              : 
      67              : !!****f* m_gwls_GenerateEpsilon/driver_generate_dielectric_matrix
      68              : !! NAME
      69              : !!  driver_generate_dielectric_matrix
      70              : !!
      71              : !! FUNCTION
      72              : !!  .
      73              : !!
      74              : !! INPUTS
      75              : !!
      76              : !! OUTPUT
      77              : !!
      78              : !! SOURCE
      79              : 
      80           13 : subroutine driver_generate_dielectric_matrix(epsilon_matrix_function,nseeds,kmax,&
      81           13 : epsilon_eigenvalues,Lbasis,debug)
      82              : !----------------------------------------------------------------------
      83              : ! This routine computes the Lanczos approximate representation of the
      84              : ! implicit dielectic operator and then diagonalizes the banded
      85              : ! Lanczos matrix.
      86              : !----------------------------------------------------------------------
      87              : interface
      88              :   subroutine epsilon_matrix_function(v_out,v_in,l)
      89              :   use defs_basis
      90              : 
      91              :   integer,     intent(in)  :: l
      92              :   complex(dp), intent(out) :: v_out(l)
      93              :   complex(dp), intent(in)  :: v_in(l)
      94              : 
      95              :   end subroutine epsilon_matrix_function
      96              : end interface
      97              : 
      98              : integer,       intent(in) :: nseeds, kmax
      99              : logical,       intent(in) :: debug
     100              : 
     101              : real   (dp),  intent(out) :: epsilon_eigenvalues(nseeds*kmax)
     102              : complex(dp), intent(out) :: Lbasis(npw_k,nseeds*kmax)  ! array containing the Lanczos basis
     103              : 
     104              : 
     105              : ! local variables
     106              : 
     107           13 : complex(dp), allocatable :: seeds(:,:)
     108           13 : complex(dp),allocatable :: alpha(:,:,:)
     109           13 : complex(dp),allocatable :: beta (:,:,:)
     110              : 
     111              : integer :: mpi_communicator
     112              : 
     113              : ! *************************************************************************
     114              : 
     115              : 
     116              : ! The epsilon operator will act in LA mode.
     117           13 : mpi_communicator = mpi_enreg%comm_bandfft
     118              : 
     119              : 
     120              : !Create seeds
     121           52 : ABI_MALLOC(seeds,(npw_k,nseeds))
     122           13 : call get_seeds(first_seed, nseeds, seeds)
     123              : 
     124              : ! compute the Lanczos basis
     125           65 : ABI_MALLOC(alpha,(nseeds,nseeds,kmax))
     126           52 : ABI_MALLOC(beta ,(nseeds,nseeds,kmax))
     127              : 
     128              : call block_lanczos_algorithm(mpi_communicator,epsilon_matrix_function,kmax,nseeds,npw_k,        &
     129           13 : seeds,alpha,beta,Lbasis)
     130              : 
     131              : ! Diagonalize the epsilon matrix, which is banded
     132           13 : call diagonalize_lanczos_banded(kmax,nseeds,npw_k,alpha,beta,Lbasis,epsilon_eigenvalues,debug)
     133              : 
     134           13 : if (debug) then
     135            0 :   call ritz_analysis_general(mpi_communicator, epsilon_matrix_function,nseeds*kmax,npw_k,Lbasis,epsilon_eigenvalues)
     136              : end if
     137              : 
     138           13 : ABI_FREE(seeds)
     139           13 : ABI_FREE(alpha)
     140           13 : ABI_FREE(beta)
     141              : 
     142           13 : end subroutine driver_generate_dielectric_matrix
     143              : !!***
     144              : 
     145              : !!****f* m_gwls_GenerateEpsilon/GeneratePrintDielectricEigenvalues
     146              : !! NAME
     147              : !!  GeneratePrintDielectricEigenvalues
     148              : !!
     149              : !! FUNCTION
     150              : !!  .
     151              : !!
     152              : !! INPUTS
     153              : !!
     154              : !! OUTPUT
     155              : !!
     156              : !! SOURCE
     157              : 
     158            2 : subroutine GeneratePrintDielectricEigenvalues(epsilon_matrix_function,nseeds,kmax,output_filename,Lbasis,alpha,beta)
     159              : !----------------------------------------------------------------------
     160              : ! This routine computes the Lanczos approximate representation of the
     161              : ! implicit dielectic operator and then diagonalizes the banded
     162              : ! Lanczos matrix.
     163              : !----------------------------------------------------------------------
     164              : interface
     165              :   subroutine epsilon_matrix_function(v_out,v_in,l)
     166              :   use defs_basis
     167              : 
     168              :   integer,     intent(in)  :: l
     169              :   complex(dp), intent(out) :: v_out(l)
     170              :   complex(dp), intent(in)  :: v_in(l)
     171              : 
     172              :   end subroutine epsilon_matrix_function
     173              : end interface
     174              : 
     175              : integer,       intent(in) :: nseeds, kmax
     176              : 
     177              : character(*),  intent(in) :: output_filename
     178              : 
     179              : 
     180              : complex(dp), intent(out) :: Lbasis(:,:)
     181              : complex(dp), intent(out) :: alpha(:,:,:)
     182              : complex(dp), intent(out) :: beta (:,:,:)
     183              : 
     184              : 
     185              : ! local variables
     186              : 
     187              : 
     188            2 : complex(dp),allocatable :: seeds(:,:)
     189            2 : complex(dp),allocatable :: Lbasis_diag(:,:)
     190              : 
     191              : 
     192            2 : real(dp),    allocatable :: psik(:,:)
     193            2 : real(dp),    allocatable :: psir(:,:,:,:)
     194              : 
     195            2 : real(dp),    allocatable :: epsilon_eigenvalues(:)
     196              : 
     197              : 
     198              : integer :: mpi_communicator
     199              : integer :: io_unit
     200              : integer :: lmax
     201              : integer :: l
     202              : integer :: ir1, ir2, ir3
     203              : integer :: n1, n2, n3
     204              : 
     205              : real(dp) :: R, G
     206              : real(dp) :: sigma_R, sigma_G
     207              : real(dp) :: x, y, z
     208              : 
     209            2 : real(dp),allocatable :: G_array(:)
     210            2 : real(dp),allocatable :: R_array(:,:,:)
     211              : 
     212              : logical :: debug
     213              : 
     214              : ! *************************************************************************
     215              : 
     216              : 
     217            2 : debug = .false.
     218            2 : lmax = kmax*nseeds
     219            2 : mpi_communicator = mpi_enreg%comm_bandfft
     220              : !Create seeds
     221            8 : ABI_MALLOC(seeds,(npw_k,nseeds))
     222            2 : call get_seeds(first_seed, nseeds, seeds)
     223              : 
     224              : ! compute the Lanczos basis
     225            8 : ABI_MALLOC(Lbasis_diag,(npw_k,lmax))
     226            6 : ABI_MALLOC(epsilon_eigenvalues,(lmax))
     227              : 
     228            6 : ABI_MALLOC(psik,(2,npw_k))
     229           10 : ABI_MALLOC(psir,(2,n4,n5,n6))
     230            6 : ABI_MALLOC(G_array,(npw_k))
     231           10 : ABI_MALLOC(R_array,(n4,n5,n6))
     232              : 
     233        39710 : psir = zero
     234        13718 : R_array = zero
     235              : 
     236            2 : n1 = n4-1
     237            2 : n2 = n5-1
     238            2 : n3 = n6
     239              : 
     240              : ! Generate the Lanczos basis and banded eigenvalue representation
     241            2 : call block_lanczos_algorithm(mpi_communicator, epsilon_matrix_function,kmax,nseeds,npw_k,        seeds,alpha,beta,Lbasis)
     242              : 
     243         4132 : Lbasis_diag = Lbasis
     244              : 
     245              : ! Diagonalize the epsilon matrix, which is banded
     246            2 : call diagonalize_lanczos_banded(kmax,nseeds,npw_k,alpha,beta,Lbasis_diag,epsilon_eigenvalues,debug)
     247              : 
     248            2 : call ritz_analysis_general(mpi_communicator, epsilon_matrix_function,lmax,npw_k,Lbasis_diag,epsilon_eigenvalues)
     249              : 
     250            2 : io_unit = get_unit()
     251            2 : open(file=output_filename,status=files_status_new,unit=io_unit)
     252            2 : write(io_unit,10) '#----------------------------------------------------------------------------'
     253            2 : write(io_unit,10) '#                                                                            '
     254            2 : write(io_unit,10) '#                       Partial eigenvalues                                  '
     255            2 : write(io_unit,10) '#           ==========================================                       '
     256            2 : write(io_unit,10) '#                                                                            '
     257            2 : write(io_unit,10) '#  Tabulate the eigenvalues of the dielectic matrix, as well as some         '
     258            2 : write(io_unit,10) '#  information regarding the eigenstates.                                    '
     259            2 : write(io_unit,10) '#                                                                            '
     260            2 : write(io_unit,10) '#                                                                            '
     261            2 : write(io_unit,10) '#  definitions:                                                              '
     262            2 : write(io_unit,10) '#                l      index of the eigenvalue                              '
     263            2 : write(io_unit,10) '#                eig    eigenvalue                                           '
     264            2 : write(io_unit,10) '#                                                                            '
     265            2 : write(io_unit,10) '#                                                                            '
     266            2 : write(io_unit,10) '#                (the following vectors are expressed in crystal units)      '
     267            2 : write(io_unit,10) '#                                                                            '
     268            2 : write(io_unit,10) '#                R       =   < l | |r| | l >                                 '
     269            2 : write(io_unit,10) '#                sigma_R = sqrt{< l | (|r|-R)^2 | l > }                      '
     270            2 : write(io_unit,10) '#                                                                            '
     271            2 : write(io_unit,10) '#                G       =   < l | |G| | l >                                 '
     272            2 : write(io_unit,10) '#                sigma_G = sqrt{< l | (|G|-G)^2 | l > }                      '
     273            2 : write(io_unit,10) '#                                                                            '
     274            2 : write(io_unit,10) '#                                                                            '
     275            2 : write(io_unit,10) '#  l            eig                r         sigma_r       G         sigma_G '
     276            2 : write(io_unit,10) '#----------------------------------------------------------------------------'
     277            2 : flush(io_unit)
     278              : 
     279              : 
     280          516 : G_array(:) = kg_k(1,:)**2+ kg_k(2,:)**2+ kg_k(3,:)**2
     281              : 
     282          516 : G_array(:) = sqrt(G_array(:))
     283              : 
     284        13718 : R_array  = zero
     285              : 
     286           38 : do ir3=1,n3
     287              : 
     288           36 : if (ir3 <= n3/2 ) then
     289           18 :   z = (one*ir3)/(one*n3)
     290              : else
     291           18 :   z = (one*ir3)/(one*n3)-one
     292              : end if
     293              : 
     294          686 : do ir2=1,n2
     295              : 
     296          648 : if (ir2 <= n2/2 ) then
     297          324 :   y = (one*ir2)/(one*n2)
     298              : else
     299          324 :   y = (one*ir2)/(one*n2)-one
     300              : end if
     301              : 
     302        12348 : do ir1=1,n1
     303              : 
     304        11664 : if (ir1 <= n1/2 ) then
     305         5832 :   x = (one*ir1)/(one*n1)
     306              : else
     307         5832 :   x = (one*ir1)/(one*n1)-one
     308              : end if
     309              : 
     310              : 
     311        12312 : R_array(ir1,ir2,ir3)  = sqrt(x**2+y**2+z**2)
     312              : end do
     313              : end do
     314              : end do
     315              : 
     316              : 
     317              : 
     318           18 : do l=1, lmax
     319              : 
     320         4128 : psik(1,:) = dble (Lbasis_diag(:,l))
     321         4128 : psik(2,:) = dimag(Lbasis_diag(:,l))
     322              : 
     323           16 : call g_to_r(psir ,psik)
     324              : 
     325              : 
     326         4128 : G       = sum(G_array(:)*(psik(1,:)**2+psik(2,:)**2))
     327       109744 : R       = sum(R_array(:,:,:)*(psir(1,:,:,:)**2+psir(2,:,:,:)**2) )*ucvol/nfft
     328              : 
     329         4128 : sigma_G = sqrt(sum((G_array(:)    -G)**2*(psik(1,:)**2    +psik(2,:)**2)))
     330       109744 : sigma_R = sqrt(sum((R_array(:,:,:)-R)**2*(psir(1,:,:,:)**2+psir(2,:,:,:)**2))*ucvol/nfft)
     331              : 
     332              : 
     333              : 
     334           18 : write(io_unit,20) l, epsilon_eigenvalues(l), R,sigma_R, G,sigma_G
     335              : 
     336              : end do
     337              : 
     338            2 : close(io_unit)
     339              : 
     340            2 : ABI_FREE(seeds)
     341            2 : ABI_FREE(Lbasis_diag)
     342            2 : ABI_FREE(psik)
     343            2 : ABI_FREE(psir)
     344            2 : ABI_FREE(G_array)
     345            2 : ABI_FREE(R_array)
     346              : 
     347            2 : ABI_FREE(epsilon_eigenvalues)
     348              : 
     349              : 
     350              : 10 format(A)
     351              : 20 format(I5,ES24.16,4F12.8)
     352              : 
     353            2 : end subroutine GeneratePrintDielectricEigenvalues
     354              : !!***
     355              : 
     356              : !!****f* m_gwls_GenerateEpsilon/Driver_GeneratePrintDielectricEigenvalues
     357              : !! NAME
     358              : !!  Driver_GeneratePrintDielectricEigenvalues
     359              : !!
     360              : !! FUNCTION
     361              : !!  .
     362              : !!
     363              : !! INPUTS
     364              : !!
     365              : !! OUTPUT
     366              : !!
     367              : !! SOURCE
     368              : 
     369            1 : subroutine Driver_GeneratePrintDielectricEigenvalues(dtset)
     370              : !----------------------------------------------------------------------
     371              : ! Compute the eigenvalues of the various dielectric operators
     372              : !----------------------------------------------------------------------
     373              : type(dataset_type),intent(in) :: dtset
     374              : 
     375              : integer  ::  kmax_exact, kmax_model, kmax
     376              : real(dp) :: second_model_parameter
     377              : 
     378              : 
     379              : integer  ::  lm, k, lmax, l1, l2
     380              : integer  ::  io_unit
     381              : integer  ::  io_unit2
     382              : 
     383              : real(dp) :: time1, time2, time
     384              : ! local variables
     385              : character(128)  :: output_filename
     386              : character(256)  :: timing_string
     387              : 
     388              : 
     389              : complex(dp), allocatable :: Lbasis_exact(:,:)
     390              : complex(dp), allocatable :: Lbasis_model(:,:)
     391            1 : complex(dp), allocatable :: sub_Lbasis_exact(:,:)
     392            1 : complex(dp), allocatable :: sub_Lbasis_model(:,:)
     393            1 : complex(dp), allocatable :: dummy(:,:)
     394            1 : complex(dp), allocatable :: dummy2(:,:)
     395            1 : complex(dp), allocatable :: dummy3(:,:)
     396              : complex(dp), allocatable :: alpha_exact(:,:,:)
     397              : complex(dp), allocatable :: beta_exact (:,:,:)
     398              : complex(dp), allocatable :: alpha_model(:,:,:)
     399              : complex(dp), allocatable :: beta_model (:,:,:)
     400              : 
     401            1 : real(dp), allocatable :: eig_exact(:)
     402            1 : real(dp), allocatable :: eig_model(:)
     403              : 
     404            1 : complex(dp), allocatable :: model_epsilon_matrix(:,:)
     405            1 : complex(dp), allocatable :: vector(:)
     406              : 
     407              : real(dp) :: tr_eps_1, tr_eps_2, tr_eps_3
     408              : 
     409              : 
     410              : integer   ::  lwork, lrwork, liwork, info
     411            1 : complex(dp), allocatable :: work(:)
     412            1 : real(dp)    , allocatable :: rwork(:)
     413            1 : integer     , allocatable :: iwork(:)
     414              : 
     415              : integer        :: debug_unit
     416              : character(50)  :: debug_filename
     417              : ! *************************************************************************
     418              : 
     419            1 : kmax_exact   = dtset%gwls_stern_kmax
     420            1 : kmax_model   = dtset%gwls_kmax_complement
     421              : 
     422              : !second_model_parameter  = dtset%gwls_second_model_parameter
     423            1 : second_model_parameter  = zero
     424              : 
     425              : 
     426              : ! global stuff
     427            1 : nseeds       = dtset%gwls_nseeds
     428            1 : first_seed   = dtset%gwls_first_seed
     429            1 : e            = dtset%gwls_band_index
     430              : 
     431              : 
     432              : 
     433            4 : ABI_MALLOC(Lbasis_exact,(npw_k,kmax_exact*nseeds))
     434            4 : ABI_MALLOC(Lbasis_model,(npw_k,kmax_model*nseeds))
     435              : 
     436            5 : ABI_MALLOC(alpha_exact, (nseeds,nseeds,kmax_exact))
     437            4 : ABI_MALLOC(beta_exact , (nseeds,nseeds,kmax_exact))
     438            5 : ABI_MALLOC(alpha_model, (nseeds,nseeds,kmax_model))
     439            4 : ABI_MALLOC(beta_model , (nseeds,nseeds,kmax_model))
     440              : 
     441              : 
     442              : ! set omega=0 for exact dielectric operator
     443            1 : call set_dielectric_function_frequency([zero,zero])
     444              : 
     445              : 
     446              : 
     447            1 : call cpu_time(time1)
     448            1 : output_filename = 'EIGENVALUES_EXACT.dat'
     449              : call GeneratePrintDielectricEigenvalues(matrix_function_epsilon_k, nseeds, kmax_exact, &
     450            1 : output_filename, Lbasis_exact, alpha_exact, beta_exact)
     451              : 
     452              : 
     453              : 
     454            1 : call cpu_time(time2)
     455            1 : time = time2-time1
     456            1 : write(timing_string,'(A)')  "Time to compute the EXACT Static Dielectric Matrix  :   "
     457            1 : call write_timing_log(timing_string,time)
     458              : 
     459              : 
     460              : 
     461            1 : call cpu_time(time1)
     462            1 : call setup_Pk_model(zero,second_model_parameter)
     463            1 : output_filename = 'EIGENVALUES_MODEL.dat'
     464              : call GeneratePrintDielectricEigenvalues(matrix_function_epsilon_model_operator, nseeds, kmax_model, &
     465            1 : &output_filename, Lbasis_model, alpha_model, beta_model)
     466            1 : call cpu_time(time2)
     467            1 : time = time2-time1
     468            1 : write(timing_string,'(A)')  "Time to compute the MODEL Static Dielectric Matrix  :   "
     469            1 : call write_timing_log(timing_string,time)
     470              : 
     471              : 
     472            1 : call cpu_time(time1)
     473            1 : if (kmax_exact <= kmax_model) then
     474              :   kmax  = kmax_exact
     475              : else
     476              :   kmax  = kmax_model
     477              : end if
     478            1 : lmax = nseeds*kmax
     479              : 
     480              : ! Build model operator matrix elements in the exact basis
     481            4 : ABI_MALLOC(model_epsilon_matrix, (lmax,lmax))
     482            3 : ABI_MALLOC(vector, (npw_k))
     483              : 
     484           73 : model_epsilon_matrix = cmplx_0
     485              : 
     486            9 : do l2 =1 , lmax
     487            8 : call matrix_function_epsilon_model_operator(vector ,Lbasis_exact(:,l2),npw_k)
     488              : 
     489              : 
     490           73 : do l1 =1, lmax
     491              : 
     492           72 : model_epsilon_matrix(l1, l2) = complex_vector_product(Lbasis_exact(:,l1),vector,npw_k)
     493              : 
     494              : end do
     495              : 
     496              : 
     497              : end do
     498              : 
     499            1 : ABI_FREE(vector)
     500              : 
     501            1 : call cpu_time(time2)
     502            1 : time = time2-time1
     503            1 : write(timing_string,'(A)')  "Compute MODEL matrix elements in EXACT basis        :   "
     504            1 : call write_timing_log(timing_string,time)
     505              : 
     506              : 
     507              : 
     508              : 
     509              : ! Compare the traces
     510              : 
     511              : 
     512            1 : io_unit = get_unit()
     513            1 : open(file='DIELECTRIC_TRACE.dat',status=files_status_new,unit=io_unit)
     514            1 : write(io_unit,10) '#----------------------------------------------------------------------------'
     515            1 : write(io_unit,10) '#                                                                            '
     516            1 : write(io_unit,10) '#                       Partial traces                                       '
     517            1 : write(io_unit,10) '#           ==========================================                       '
     518            1 : write(io_unit,10) '#                                                                            '
     519            1 : write(io_unit,10) '#  Tabulate the trace of various operators, as function of the number        '
     520            1 : write(io_unit,10) '#  of lanczos steps performed.                                               '
     521            1 : write(io_unit,10) '#                                                                            '
     522            1 : write(io_unit,10) '#                                                                            '
     523            1 : write(io_unit,10) '#  NOTES:                                                                    '
     524            1 : write(io_unit,10) '#         Tr[1-eps^{-1}] is evaluated in the Lanczos basis of eps            '
     525            1 : write(io_unit,10) '#         Tr[1-eps_m^{-1}] is evaluated in the Lanczos basis of eps_m        '
     526            1 : write(io_unit,10) '#         Tr[eps_m^{-1}-eps^{-1}] is evaluated in the Lanczos basis of eps   '
     527            1 : write(io_unit,10) '#                                                                            '
     528            1 : write(io_unit,10) '#                                                                            '
     529            1 : write(io_unit,10) '#  k       Tr[1-eps^{-1}]        Tr[1-eps_m^{-1}]     Tr[eps_m^{-1}-eps^{-1}]'
     530            1 : write(io_unit,10) '#----------------------------------------------------------------------------'
     531            1 : flush(io_unit)
     532              : 
     533              : 
     534            1 : io_unit2 = get_unit()
     535            1 : open(file='RPA_ENERGY.dat',status=files_status_new,unit=io_unit2)
     536            1 : write(io_unit2,10) '#----------------------------------------------------------------------------'
     537            1 : write(io_unit2,10) '#                                                                            '
     538            1 : write(io_unit2,10) '#                       RPA TOTAL ENERGY                                     '
     539            1 : write(io_unit2,10) '#           ==========================================                       '
     540            1 : write(io_unit2,10) '#                                                                            '
     541            1 : write(io_unit2,10) '#  It can be shown that the correlation energy, within the RPA, is given     '
     542            1 : write(io_unit2,10) '#  by:                                                                       '
     543            1 : write(io_unit2,10) '#       E_c = int_0^{infty} dw/(2pi) Tr[ ln(eps{iw)}+1-eps(iw)]              '
     544            1 : write(io_unit2,10) '#                                                                            '
     545            1 : write(io_unit2,10) '#  As a gauge of what can be expected as far as convergence is concerned,    '
     546            1 : write(io_unit2,10) '#  the following will be printed.                                            '
     547            1 : write(io_unit2,10) '#                                                                            '
     548            1 : write(io_unit2,10) '#  I_1 = Tr[  ln(eps)  + 1 - eps   ]                                         '
     549            1 : write(io_unit2,10) '#  I_2 = Tr[ ln(eps_m) + 1 - eps_m ]                                         '
     550            1 : write(io_unit2,10) '#  I_3 = Tr[ ln(eps^{-1}_m . eps ) + eps_m - eps ]                           '
     551            1 : write(io_unit2,10) '#                                                                            '
     552            1 : write(io_unit2,10) '#                                                                            '
     553            1 : write(io_unit2,10) '#                                                                            '
     554            1 : write(io_unit2,10) '#  k       I_1                   I_2                  I_3                    '
     555            1 : write(io_unit2,10) '#----------------------------------------------------------------------------'
     556            1 : flush(io_unit2)
     557              : 
     558              : 
     559              : ! Iterate every 10 values of k max, or else the linear algebra gets too expensive...
     560            1 : do k = 4, kmax, 4
     561              : 
     562            8 : ABI_MALLOC(sub_Lbasis_exact,(npw_k,k*nseeds))
     563            6 : ABI_MALLOC(sub_Lbasis_model,(npw_k,k*nseeds))
     564              : 
     565              : 
     566            6 : ABI_MALLOC(eig_exact,(k*nseeds))
     567            4 : ABI_MALLOC(eig_model,(k*nseeds))
     568            8 : ABI_MALLOC(dummy,(k*nseeds,k*nseeds))
     569            6 : ABI_MALLOC(dummy2,(k*nseeds,k*nseeds))
     570              : 
     571         3098 : sub_Lbasis_exact(:,:) = Lbasis_exact(:,1:k*nseeds)
     572         3098 : sub_Lbasis_model(:,:) = Lbasis_model(:,1:k*nseeds)
     573              : 
     574              : ! Diagonalize the epsilon matrix, which is banded
     575            2 : call diagonalize_lanczos_banded(k,nseeds,npw_k,alpha_exact(:,:,1:k),beta_exact(:,:,1:k),sub_Lbasis_exact,eig_exact,.false.)
     576            2 : call diagonalize_lanczos_banded(k,nseeds,npw_k,alpha_model(:,:,1:k),beta_model(:,:,1:k),sub_Lbasis_model,eig_model,.false.)
     577              : 
     578           14 : tr_eps_1 = sum(one-one/eig_exact(:))
     579           14 : tr_eps_2 = sum(one-one/eig_model(:))
     580              : 
     581           14 : tr_eps_3 = -sum(one/eig_exact(:))
     582              : 
     583           94 : dummy(:,:) = model_epsilon_matrix(1:k*nseeds, 1:k*nseeds)
     584              : 
     585            2 : call driver_invert_positive_definite_hermitian_matrix(dummy,k*nseeds)
     586              : 
     587           14 : do lm = 1, k*nseeds
     588              : 
     589           14 : tr_eps_3 = tr_eps_3 +  dble(dummy(lm,lm))
     590              : end do
     591              : 
     592              : 
     593            2 : write(io_unit,20) k, tr_eps_1, tr_eps_2, tr_eps_3
     594            2 : flush(io_unit)
     595              : 
     596              : 
     597              : 
     598           14 : tr_eps_1 = sum(log(eig_exact(:))+one-eig_exact(:))
     599           14 : tr_eps_2 = sum(log(eig_model(:))+one-eig_model(:))
     600              : 
     601           94 : dummy2(:,:) = zero
     602            2 : tr_eps_3    = zero
     603           14 : do lm = 1, k*nseeds
     604           12 : dummy2(lm,lm) = eig_exact(lm)
     605           14 : tr_eps_3 = tr_eps_3 + dble(model_epsilon_matrix(lm,lm)) - dble(eig_exact(lm))
     606              : end do
     607              : 
     608            8 : ABI_MALLOC(dummy3,(k*nseeds,k*nseeds))
     609              : call ZGEMM(      'N',   & ! Hermitian conjugate the first array
     610              : 'N',   & ! Leave second array as is
     611              : k*nseeds,   & ! the number of rows of the  matrix op( A )
     612              : k*nseeds,   & ! the number of columns of the  matrix op( B )
     613              : k*nseeds,   & ! the number of columns of the  matrix op( A ) == rows of matrix op( B )
     614              : cmplx_1,   & ! alpha constant
     615              : dummy2,   & ! matrix A
     616              : k*nseeds,   & ! LDA
     617              : dummy,   & ! matrix B
     618              : k*nseeds,   & ! LDB
     619              : cmplx_0,   & ! beta constant
     620              : dummy3,   & ! matrix C
     621            2 : k*nseeds)     ! LDC
     622              : 
     623           94 : dummy2(:,:) = dummy3(:,:)
     624            2 : ABI_FREE(dummy3)
     625              : 
     626              : ! find eigenvalues
     627              : !call heevd(dummy2, eig_exact)
     628              : 
     629            2 : lwork  = k*nseeds+1
     630            2 : lrwork = k*nseeds
     631            2 : liwork = 1
     632              : 
     633            6 : ABI_MALLOC(work,(lwork))
     634            6 : ABI_MALLOC(rwork,(lrwork))
     635            2 : ABI_MALLOC(iwork,(liwork))
     636              : 
     637            2 : call zheevd('N', 'U',k*nseeds, dummy2, k*nseeds, eig_exact, work, lwork, rwork, lrwork, iwork, liwork, info)
     638            2 : if ( info /= 0) then
     639            0 :   debug_unit = get_unit()
     640            0 :   write(debug_filename,'(A,I4.4,A)') 'LAPACK_DEBUG_PROC=',mpi_enreg%me,'.log'
     641              : 
     642            0 :   open(debug_unit,file=trim(debug_filename),status='unknown')
     643              : 
     644            0 :   write(debug_unit,'(A)')      '*************************************************************************************'
     645            0 :   write(debug_unit,'(A,I4,A)') '*      ERROR: info = ',info,' in ZHEEVD(1), gwls_GenerateEpsilon'
     646            0 :   write(debug_unit,'(A)')      '*************************************************************************************'
     647              : 
     648            0 :   close(debug_unit)
     649              : 
     650              : end if
     651              : 
     652              : 
     653              : 
     654              : 
     655              : 
     656           14 : tr_eps_3 =  tr_eps_3 + sum(log(eig_exact))
     657              : 
     658            2 : write(io_unit2,20) k, tr_eps_1, tr_eps_2, tr_eps_3
     659            2 : flush(io_unit2)
     660              : 
     661              : 
     662              : 
     663            2 : ABI_FREE(work)
     664            2 : ABI_FREE(rwork)
     665            2 : ABI_FREE(iwork)
     666              : 
     667              : 
     668              : 
     669            2 : ABI_FREE(sub_Lbasis_exact)
     670            2 : ABI_FREE(sub_Lbasis_model)
     671              : 
     672            2 : ABI_FREE(eig_exact)
     673            2 : ABI_FREE(eig_model)
     674            2 : ABI_FREE(dummy)
     675            2 : ABI_FREE(dummy2)
     676              : end do
     677              : 
     678            1 : close(io_unit)
     679            1 : close(io_unit2)
     680              : 
     681            1 : call cpu_time(time2)
     682            1 : time = time2-time1
     683            1 : write(timing_string,'(A)')  "Time to compute the TRACES of the Dielectric Matrices:   "
     684            1 : call write_timing_log(timing_string,time)
     685              : 
     686            1 : ABI_FREE(Lbasis_exact)
     687            1 : ABI_FREE(Lbasis_model)
     688            1 : ABI_FREE(alpha_exact)
     689            1 : ABI_FREE(beta_exact )
     690            1 : ABI_FREE(alpha_model)
     691            1 : ABI_FREE(beta_model )
     692            1 : ABI_FREE(model_epsilon_matrix)
     693              : 
     694              : 
     695              : 
     696              : 10 format(A)
     697              : 20 format(I5,3ES24.16)
     698              : 
     699            1 : end subroutine Driver_GeneratePrintDielectricEigenvalues
     700              : !!***
     701              : 
     702              : end module m_gwls_GenerateEpsilon
     703              : !!***
        

Generated by: LCOV version 2.3-1