LCOV - code coverage report
Current view: top level - src/70_gw - m_gwls_DielectricArray.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 81.8 % 748 612
Test Date: 2026-11-09 22:30:52 Functions: 100.0 % 6 6
Branches: 55.8 % 1556 869

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_gwls_DielectricArray
       2                 :             : !! NAME
       3                 :             : !! m_gwls_DielectricArray
       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_DielectricArray
      24                 :             : !----------------------------------------------------------------------------------------------------
      25                 :             : ! This module generates and stores the arrays
      26                 :             : !
      27                 :             : !        { eps^{-1}(iw)-eps_model^{-1}(iw) }  in Lanczos basis
      28                 :             : !        { eps_model^{-1}(iw) - 1 }           in model Lanczos basis
      29                 :             : !
      30                 :             : ! It makes sense to build these only once, as they do not depend on the external frequency.
      31                 :             : !
      32                 :             : !----------------------------------------------------------------------------------------------------
      33                 :             : 
      34                 :             : ! local modules
      35                 :             : use m_gwls_utility
      36                 :             : use m_gwls_wf
      37                 :             : use m_gwls_valenceWavefunctions
      38                 :             : use m_gwls_hamiltonian
      39                 :             : use m_gwls_lineqsolver
      40                 :             : use m_gwls_polarisability
      41                 :             : use m_gwls_model_polarisability
      42                 :             : use m_gwls_GenerateEpsilon
      43                 :             : use m_gwls_TimingLog
      44                 :             : use m_gwls_QR_factorization
      45                 :             : use m_gwls_LanczosBasis
      46                 :             : 
      47                 :             : ! abinit modules
      48                 :             : use defs_basis
      49                 :             : use m_abicore
      50                 :             : use m_xmpi
      51                 :             : use m_cgtools
      52                 :             : 
      53                 :             : use m_time,                only : timab
      54                 :             : use m_io_tools,            only: get_unit
      55                 :             : use m_gaussian_quadrature, only: get_frequencies_and_weights_legendre
      56                 :             : 
      57                 :             : 
      58                 :             : implicit none
      59                 :             : save
      60                 :             : 
      61                 :             : private
      62                 :             : !!***
      63                 :             : 
      64                 :             : ! Frequencies and weights for Legendre integration
      65                 :             : real(dp), public, allocatable :: list_omega(:)
      66                 :             : real(dp), public, allocatable :: list_weights(:)
      67                 :             : 
      68                 :             : ! Arrays to store the combinations of dielectric operators
      69                 :             : complex(dp), public, allocatable :: model_dielectric_Lanczos_basis(:,:,:)
      70                 :             : complex(dp), public, allocatable :: projected_dielectric_Lanczos_basis(:,:,:)
      71                 :             : complex(dp), public, allocatable :: eps_m1_minus_eps_model_m1(:,:,:)
      72                 :             : 
      73                 :             : complex(dp), public, allocatable :: eps_model_m1_minus_one(:,:,:)
      74                 :             : complex(dp),public, allocatable :: eps_model_m1_minus_one_DISTR(:,:,:)
      75                 :             : 
      76                 :             : 
      77                 :             : ! dimensions of blocks in the model dielectric matrix
      78                 :             : integer,public :: nbdblock_epsilon
      79                 :             : integer,public :: blocksize_epsilon
      80                 :             : logical,public, allocatable :: model_lanczos_vector_belongs_to_this_node(:)
      81                 :             : integer,public, allocatable :: model_lanczos_vector_index(:)
      82                 :             : 
      83                 :             : 
      84                 :             : ! Arrays necessary to project the Sternheimer equation within
      85                 :             : ! the computation of the dielectric matrix.
      86                 :             : complex(dp), public, allocatable :: projected_epsilon_M_matrix(:,:,:)
      87                 :             : complex(dp), public, allocatable :: projected_epsilon_B_matrix(:,:,:)
      88                 :             : complex(dp), public, allocatable :: projected_epsilon_G_matrix(:,:,:)
      89                 :             : 
      90                 :             : integer,public, allocatable  :: list_lsolutions_EpsilonProjected(:)
      91                 :             : !!***
      92                 :             : 
      93                 :             : public :: generate_frequencies_and_weights
      94                 :             : public :: cleanup_projected_Sternheimer_epsilon
      95                 :             : public :: compute_eps_m1_minus_eps_model_m1
      96                 :             : public :: compute_eps_m1_minus_one
      97                 :             : public :: compute_eps_model_m1_minus_one
      98                 :             : public :: ProjectedSternheimerEpsilon
      99                 :             : !!***
     100                 :             : 
     101                 :             : contains
     102                 :             : 
     103                 :             : !!****f* m_hamiltonian/generate_frequencies_and_weights
     104                 :             : !! NAME
     105                 :             : !!  generate_frequencies_and_weights
     106                 :             : !!
     107                 :             : !! FUNCTION
     108                 :             : !!  .
     109                 :             : !!
     110                 :             : !! INPUTS
     111                 :             : !!
     112                 :             : !! OUTPUT
     113                 :             : !!
     114                 :             : !! SOURCE
     115                 :             : 
     116                 :           7 : subroutine generate_frequencies_and_weights(npt_gauss)
     117                 :             : !--------------------------------------------------------------------------------
     118                 :             : !
     119                 :             : ! This subroutine computes the frequencies and weights necessary for Gauss-Legendre
     120                 :             : ! quadrature, and stores the results in module arrays.
     121                 :             : !
     122                 :             : !--------------------------------------------------------------------------------
     123                 :             : integer, intent(in)  :: npt_gauss
     124                 :             : 
     125                 :             : 
     126                 :           7 : real(dp), allocatable ::   list_omega_tmp(:)
     127                 :           7 : real(dp), allocatable :: list_weights_tmp(:)
     128                 :             : 
     129                 :             : integer     :: i
     130                 :             : 
     131                 :             : ! *************************************************************************
     132                 :             : 
     133   [ -  +  +  -  :          21 : ABI_MALLOC(list_omega_tmp,   (npt_gauss))
          +  -  +  -  -  
                +  -  + ]
     134   [ -  +  +  -  :          14 : ABI_MALLOC(list_weights_tmp, (npt_gauss))
             -  +  -  + ]
     135                 :             : 
     136                 :           7 : call get_frequencies_and_weights_legendre(npt_gauss,list_omega_tmp,list_weights_tmp)
     137                 :             : 
     138                 :             : 
     139   [ +  -  -  +  :          21 : ABI_MALLOC(list_omega,   (npt_gauss+1))
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
     140   [ -  +  +  -  :          14 : ABI_MALLOC(list_weights, (npt_gauss+1))
          -  +  -  +  -  
                      + ]
     141                 :             : 
     142                 :             : ! make sure the first frequency in zero!
     143                 :           7 : list_omega(1)   = zero
     144                 :           7 : list_weights(1) = zero
     145                 :             : 
     146         [ +  + ]:          77 : do i = 1,npt_gauss
     147                 :             : 
     148                 :             : ! inverse the order of the frequency points, as they come out
     149                 :             : ! in reverse order from the generating subroutine
     150                 :          70 : list_omega  (i+1) = list_omega_tmp  (npt_gauss+1-i)
     151                 :          77 : list_weights(i+1) = list_weights_tmp(npt_gauss+1-i)
     152                 :             : 
     153                 :             : end do
     154                 :             : 
     155                 :             : 
     156         [ -  + ]:           7 : ABI_FREE(list_omega_tmp)
     157         [ -  + ]:           7 : ABI_FREE(list_weights_tmp)
     158                 :             : 
     159                 :             : 
     160                 :           7 : end subroutine generate_frequencies_and_weights
     161                 :             : !!***
     162                 :             : 
     163                 :             : !!****f* m_hamiltonian/compute_eps_m1_minus_eps_model_m1
     164                 :             : !! NAME
     165                 :             : !!  compute_eps_m1_minus_eps_model_m1
     166                 :             : !!
     167                 :             : !! FUNCTION
     168                 :             : !!  .
     169                 :             : !!
     170                 :             : !! INPUTS
     171                 :             : !!
     172                 :             : !! OUTPUT
     173                 :             : !!
     174                 :             : !! SOURCE
     175                 :             : 
     176                 :           6 : subroutine compute_eps_m1_minus_eps_model_m1(lmax, npt_gauss)
     177                 :             : !----------------------------------------------------------------------------------------------------
     178                 :             : !
     179                 :             : ! This subroutine computes the array
     180                 :             : !
     181                 :             : !                eps^{-1}(iw) - eps_model^{-1}(iw),
     182                 :             : !
     183                 :             : ! for all relevant frequencies in the Lanczos basis.
     184                 :             : !----------------------------------------------------------------------------------------------------
     185                 :             : integer ,     intent(in)  :: lmax, npt_gauss
     186                 :             : 
     187                 :             : character(256) :: timing_string
     188                 :             : real(dp)       :: time1, time2
     189                 :             : real(dp)       :: time
     190                 :             : 
     191                 :             : integer        :: iw, l
     192                 :           6 : complex(dp),allocatable  :: dummy_matrix(:,:)
     193                 :           6 : complex(dp),allocatable  :: iden(:,:)
     194                 :             : ! *************************************************************************
     195                 :             : 
     196                 :           6 : timing_string = "#"
     197                 :           6 : call write_text_block_in_Timing_log(timing_string)
     198                 :           6 : timing_string = "#        Computing eps^{-1}(iw) - eps_model^{-1}(iw) "
     199                 :           6 : call write_text_block_in_Timing_log(timing_string)
     200                 :           6 : timing_string = "#"
     201                 :           6 : call write_text_block_in_Timing_log(timing_string)
     202                 :             : 
     203                 :             : 
     204                 :           6 : call cpu_time(time1)
     205                 :             : ! Allocate the module array
     206   [ -  +  +  -  :          30 : ABI_MALLOC(eps_m1_minus_eps_model_m1, (lmax,lmax,npt_gauss+1))
          -  +  +  -  +  
          -  -  +  +  -  
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     207   [ -  +  +  -  :          24 : ABI_MALLOC(dummy_matrix, (lmax,lmax))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     208   [ -  +  +  -  :          18 : ABI_MALLOC(iden, (lmax,lmax))
          -  +  +  -  -  
                +  +  - ]
     209                 :             : 
     210                 :             : 
     211   [ +  +  +  + ]:         438 : iden = cmplx_0
     212                 :             : 
     213         [ +  + ]:          54 : do l = 1, lmax
     214                 :          54 : iden(l,l) = cmplx_1
     215                 :             : end do
     216                 :             : 
     217         [ +  + ]:          72 : do iw = 1, npt_gauss + 1
     218                 :             : 
     219                 :             : 
     220   [ +  +  +  + ]:        4818 : dummy_matrix(:,:) = projected_dielectric_Lanczos_basis(:,:,iw)
     221                 :             : 
     222                 :          66 : call driver_invert_positive_definite_hermitian_matrix(dummy_matrix,lmax)
     223                 :             : 
     224                 :             : 
     225   [ +  +  +  + ]:        4818 : eps_m1_minus_eps_model_m1(:,:,iw) = dummy_matrix(:,:)
     226                 :             : 
     227   [ +  +  +  + ]:        4818 : dummy_matrix(:,:) = model_dielectric_Lanczos_basis(:,:,iw)
     228                 :             : 
     229                 :             : 
     230                 :             : 
     231                 :          66 : call driver_invert_positive_definite_hermitian_matrix(dummy_matrix,lmax)
     232                 :             : 
     233   [ +  +  +  + ]:        4824 : eps_m1_minus_eps_model_m1(:,:,iw) = eps_m1_minus_eps_model_m1(:,:,iw) - dummy_matrix(:,:)
     234                 :             : 
     235                 :             : 
     236                 :             : end do
     237                 :             : 
     238                 :             : 
     239                 :             : 
     240                 :             : 
     241                 :             : ! Deallocate the arrays which are no longer needed
     242         [ -  + ]:           6 : ABI_FREE(model_dielectric_Lanczos_basis)
     243         [ -  + ]:           6 : ABI_FREE(projected_dielectric_Lanczos_basis)
     244                 :             : 
     245                 :             : 
     246                 :             : 
     247         [ -  + ]:           6 : ABI_FREE(dummy_matrix)
     248         [ -  + ]:           6 : ABI_FREE(iden)
     249                 :             : 
     250                 :             : 
     251                 :             : 
     252                 :           6 : call cpu_time(time2)
     253                 :           6 : time = time2-time1
     254                 :             : 
     255                 :           6 : timing_string = "#        Total time   :   "
     256                 :           6 : call write_timing_log(timing_string,time)
     257                 :             : 
     258                 :             : 
     259                 :             : 
     260                 :             : 
     261                 :           6 : end subroutine compute_eps_m1_minus_eps_model_m1
     262                 :             : !!***
     263                 :             : 
     264                 :             : !!****f* m_hamiltonian/compute_eps_m1_minus_one
     265                 :             : !! NAME
     266                 :             : !!  compute_eps_m1_minus_one
     267                 :             : !!
     268                 :             : !! FUNCTION
     269                 :             : !!  .
     270                 :             : !!
     271                 :             : !! INPUTS
     272                 :             : !!
     273                 :             : !! OUTPUT
     274                 :             : !!
     275                 :             : !! SOURCE
     276                 :             : 
     277                 :           1 : subroutine compute_eps_m1_minus_one(lmax, npt_gauss)
     278                 :             : !----------------------------------------------------------------------------------------------------
     279                 :             : !
     280                 :             : ! This subroutine computes the array
     281                 :             : !
     282                 :             : !                eps^{-1}(iw) - I
     283                 :             : !
     284                 :             : ! for all relevant frequencies in the Lanczos basis.
     285                 :             : !----------------------------------------------------------------------------------------------------
     286                 :             : integer ,     intent(in)  :: lmax, npt_gauss
     287                 :             : 
     288                 :             : character(256) :: timing_string
     289                 :             : real(dp)       :: time1, time2
     290                 :             : real(dp)       :: time
     291                 :             : 
     292                 :             : integer        :: iw, l
     293                 :           1 : complex(dp),allocatable  :: dummy_matrix(:,:)
     294                 :           1 : complex(dp),allocatable  :: iden(:,:)
     295                 :             : ! *************************************************************************
     296                 :             : 
     297                 :           1 : timing_string = "#"
     298                 :           1 : call write_text_block_in_Timing_log(timing_string)
     299                 :           1 : timing_string = "#        Computing eps^{-1}(iw) - I "
     300                 :           1 : call write_text_block_in_Timing_log(timing_string)
     301                 :           1 : timing_string = "#"
     302                 :           1 : call write_text_block_in_Timing_log(timing_string)
     303                 :             : 
     304                 :           1 : call cpu_time(time1)
     305                 :             : ! Allocate the module array
     306                 :             : 
     307                 :             : ! The array eps_m1_minus_eps_model_m1 will be used to store
     308                 :             : ! eps^{-1}-1; we can think of eps_model = I in this case.
     309   [ -  +  +  -  :           5 : ABI_MALLOC(eps_m1_minus_eps_model_m1, (lmax,lmax,npt_gauss+1))
          -  +  +  -  +  
          -  -  +  +  -  
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     310                 :             : 
     311   [ -  +  +  -  :           4 : ABI_MALLOC(dummy_matrix, (lmax,lmax))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     312   [ -  +  +  -  :           3 : ABI_MALLOC(iden, (lmax,lmax))
          -  +  +  -  -  
                +  +  - ]
     313                 :             : 
     314   [ +  +  +  + ]:          73 : iden = cmplx_0
     315                 :             : 
     316         [ +  + ]:           9 : do l = 1, lmax
     317                 :           9 : iden(l,l) = cmplx_1
     318                 :             : end do
     319                 :             : 
     320                 :             : 
     321         [ +  + ]:          12 : do iw = 1, npt_gauss + 1
     322                 :             : 
     323   [ +  +  +  + ]:         803 : dummy_matrix(:,:) = projected_dielectric_Lanczos_basis(:,:,iw)
     324                 :             : 
     325                 :          11 : call driver_invert_positive_definite_hermitian_matrix(dummy_matrix,lmax)
     326                 :             : 
     327   [ +  +  +  + ]:         804 : eps_m1_minus_eps_model_m1(:,:,iw) = dummy_matrix(:,:)-iden(:,:)
     328                 :             : 
     329                 :             : end do
     330                 :             : 
     331                 :             : 
     332                 :             : ! Deallocate the arrays which are no longer needed
     333         [ -  + ]:           1 : ABI_FREE(projected_dielectric_Lanczos_basis)
     334                 :             : 
     335         [ -  + ]:           1 : ABI_FREE(dummy_matrix)
     336         [ -  + ]:           1 : ABI_FREE(iden)
     337                 :             : 
     338                 :           1 : call cpu_time(time2)
     339                 :           1 : time = time2-time1
     340                 :             : 
     341                 :           1 : timing_string = "#        Total time   :   "
     342                 :           1 : call write_timing_log(timing_string,time)
     343                 :             : 
     344                 :           1 : end subroutine compute_eps_m1_minus_one
     345                 :             : !!***
     346                 :             : 
     347                 :             : !!****f* m_hamiltonian/compute_eps_model_m1_minus_one
     348                 :             : !! NAME
     349                 :             : !!  compute_eps_model_m1_minus_one
     350                 :             : !!
     351                 :             : !! FUNCTION
     352                 :             : !!  .
     353                 :             : !!
     354                 :             : !! INPUTS
     355                 :             : !!
     356                 :             : !! OUTPUT
     357                 :             : !!
     358                 :             : !! SOURCE
     359                 :             : 
     360                 :           6 : subroutine compute_eps_model_m1_minus_one(lmax_model, npt_gauss, second_model_parameter, epsilon_model_eigenvalues_0)
     361                 :             : !----------------------------------------------------------------------------------------------------
     362                 :             : !
     363                 :             : ! This subroutine computes the array
     364                 :             : !
     365                 :             : !                eps_model^{-1}(iw) - 1
     366                 :             : !
     367                 :             : ! for all relevant frequencies in the model Lanczos basis.
     368                 :             : !
     369                 :             : ! This array can potentially get very large, as the complementary basis gets big to achieve
     370                 :             : ! convergence. Correspondingly, it makes sense to DISTRIBUTE this array on all processors.
     371                 :             : !
     372                 :             : ! The algorithm will go as follows:
     373                 :             : !
     374                 :             : !               eps_m = 1 - V . P . V, V = sqrt{vc}
     375                 :             : !
     376                 :             : !       I ) compute VPV, storing blocks on different processors:
     377                 :             : !
     378                 :             : !               VPV = [ ------- --------      ]  = VPV[lc, nB, nW]
     379                 :             : !                  |  [| block |  block |     ]
     380                 :             : !                 lc  [|   1   |    2   | ... ]
     381                 :             : !                  |  [|       |        |     ]
     382                 :             : !                  |  [|       |        |     ]
     383                 :             : !                  |  [ ------- ---------     ]
     384                 :             : !                        bsize
     385                 :             : !
     386                 :             : !               This construction *does* involve a fair bit of communications, but it takes
     387                 :             : !               a lot less RAM!
     388                 :             : !
     389                 :             : !       II) once VPV is constructed, do, one frequency at a time:
     390                 :             : !               - import all blocks to the HEAD processor
     391                 :             : !               - compute eps_m = 1- VPV
     392                 :             : !               - invert eps_m^{-1}
     393                 :             : !               - subtract identity eps_m^{-1} - 1
     394                 :             : !               - redistribute, block by block
     395                 :             : !
     396                 :             : !               Doing this frequency by frequency will reduce the RAM weight on the head node.
     397                 :             : !
     398                 :             : !
     399                 :             : !----------------------------------------------------------------------------------------------------
     400                 :             : integer,  intent(in) :: lmax_model, npt_gauss
     401                 :             : real(dp), intent(in) :: second_model_parameter
     402                 :             : real(dp), intent(in) :: epsilon_model_eigenvalues_0(lmax_model)
     403                 :             : 
     404                 :             : integer  :: l, l1, l2
     405                 :             : integer  :: iw
     406                 :             : integer  :: v
     407                 :             : integer  :: ierr
     408                 :             : 
     409                 :           6 : real(dp),    allocatable :: psikg_valence(:,:)
     410                 :           6 : real(dp),    allocatable :: psir_valence(:,:,:,:)
     411                 :             : 
     412                 :             : 
     413                 :           6 : real(dp),    allocatable :: psik_wrk(:,:)
     414                 :           6 : real(dp),    allocatable :: psikb_wrk(:,:)
     415                 :           6 : real(dp),    allocatable :: psikg_wrk(:,:)
     416                 :           6 : real(dp),    allocatable :: psikg_tmp(:,:)
     417                 :             : 
     418                 :           6 : complex(dp),allocatable :: local_Lbasis_conjugated(:,:)
     419                 :             : 
     420                 :             : 
     421                 :           6 : complex(dp),allocatable :: VPV(:,:,:)
     422                 :           6 : real(dp),    allocatable :: re_buffer(:,:), im_buffer(:,:)
     423                 :             : 
     424                 :           6 : complex(dp),allocatable :: vpv_row(:)
     425                 :             : 
     426                 :             : 
     427                 :           6 : complex(dp),allocatable :: epsilon_head(:,:)
     428                 :             : 
     429                 :           6 : real(dp), allocatable :: re_BUFFER_head(:,:)
     430                 :           6 : real(dp), allocatable :: im_BUFFER_head(:,:)
     431                 :             : 
     432                 :             : 
     433                 :             : 
     434                 :           6 : complex(dp),allocatable :: YL(:)
     435                 :             : 
     436                 :             : character(256) :: timing_string
     437                 :             : real(dp)       :: time1, time2, time
     438                 :             : real(dp)       :: fft_time1, fft_time2, fft_time
     439                 :             : real(dp)       :: prod_time1, prod_time2, prod_time
     440                 :             : 
     441                 :             : complex(dp)   :: z
     442                 :             : 
     443                 :             : 
     444                 :             : integer   :: iblk_lanczos, nbdblock_lanczos
     445                 :             : integer   :: mb
     446                 :             : integer   :: lb
     447                 :             : integer   :: ik
     448                 :             : 
     449                 :             : integer   :: mpi_communicator
     450                 :             : integer   :: mpi_nproc
     451                 :             : integer   :: mpi_rank
     452                 :             : integer   :: mpi_head_rank
     453                 :             : 
     454                 :             : 
     455                 :           6 : integer,allocatable   :: sendcounts(:), displs(:)
     456                 :             : 
     457                 :             : integer   :: sendcount, recvcount
     458                 :             : 
     459                 :             : 
     460                 :             : logical   :: head
     461                 :             : 
     462                 :             : 
     463                 :             : ! timing
     464                 :             : real(dp) :: tsec(2)
     465                 :             : integer :: GWLS_TIMAB, OPTION_TIMAB
     466                 :             : 
     467                 :             : ! *************************************************************************
     468                 :             : 
     469                 :             : 
     470                 :           6 : GWLS_TIMAB   = 1541
     471                 :           6 : OPTION_TIMAB = 1
     472                 :           6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     473                 :             : 
     474                 :             : 
     475                 :             : 
     476                 :           6 : timing_string = "#"
     477                 :           6 : call write_text_block_in_Timing_log(timing_string)
     478                 :           6 : timing_string = "#        computing eps_model_m1_minus_one"
     479                 :           6 : call write_text_block_in_Timing_log(timing_string)
     480                 :           6 : timing_string = "#"
     481                 :           6 : call write_text_block_in_Timing_log(timing_string)
     482                 :             : 
     483                 :             : 
     484                 :             : ! Number of blocks of lanczos vectors (blocksize = npband)
     485                 :           6 : nbdblock_lanczos = lmax_model/blocksize
     486         [ -  + ]:           6 : if (modulo(lmax_model,blocksize) /= 0) nbdblock_lanczos = nbdblock_lanczos + 1
     487                 :             : 
     488                 :             : 
     489                 :             : ! communicator
     490                 :           6 : mpi_communicator = mpi_enreg%comm_bandfft
     491                 :             : 
     492                 :             : ! total number of processors in the communicator
     493                 :           6 : mpi_nproc        = xmpi_comm_size(mpi_communicator )
     494                 :             : 
     495                 :             : ! what is the rank of this processor?
     496                 :           6 : mpi_rank         = xmpi_comm_rank(mpi_communicator )
     497                 :             : 
     498                 :             : ! rank of the "head" processor
     499                 :           6 : mpi_head_rank    = 0
     500                 :             : 
     501                 :             : 
     502                 :             : ! number of blocks in the model dielectric matrix, which is equal to the number of processors
     503                 :           6 : nbdblock_epsilon = mpi_nproc
     504                 :             : 
     505                 :             : 
     506                 :             : ! number of vectors in every block
     507                 :           6 : blocksize_epsilon =  lmax_model/mpi_nproc
     508         [ -  + ]:           6 : if (modulo(lmax_model,mpi_nproc) /= 0) blocksize_epsilon = blocksize_epsilon + 1
     509                 :             : 
     510                 :             : ! attribute blocks to every nodes, and tabulate ownership in logical array
     511                 :             : ! This is not *the most efficient* implementation possible, but it is convenient
     512   [ -  +  +  -  :          18 : ABI_MALLOC( model_lanczos_vector_belongs_to_this_node, (lmax_model))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     513   [ -  +  +  -  :          12 : ABI_MALLOC( model_lanczos_vector_index, (lmax_model))
          -  +  -  +  -  
                      + ]
     514                 :             : 
     515                 :             : 
     516         [ +  + ]:          54 : model_lanczos_vector_index = 0
     517         [ +  + ]:          54 : model_lanczos_vector_belongs_to_this_node = .false.
     518                 :             : 
     519         [ +  + ]:          54 : do l =1, lmax_model
     520         [ +  + ]:          54 : if (mpi_rank == (l-1)/blocksize_epsilon) then
     521                 :          24 :   model_lanczos_vector_belongs_to_this_node(l) = .true.
     522                 :          24 :   model_lanczos_vector_index(l) = l-mpi_rank*blocksize_epsilon
     523                 :             : end if
     524                 :             : end do
     525                 :             : 
     526                 :             : !write(100+mpi_rank,*) "model_lanczos_vector_belongs_to_this_node = ",model_lanczos_vector_belongs_to_this_node(:)
     527                 :             : !write(100+mpi_rank,*) "model_lanczos_vector_index                = ",model_lanczos_vector_index(:)
     528                 :             : !flush(100+mpi_rank)
     529                 :             : 
     530                 :             : ! Prepare the array that will contain the matrix elements of the model operator
     531   [ -  +  +  -  :          30 : ABI_MALLOC(VPV, (lmax_model,blocksize_epsilon,npt_gauss+1))
          -  +  +  -  +  
          -  -  +  +  -  
          +  -  +  -  -  
                +  -  + ]
     532                 :             : 
     533   [ +  +  +  +  :        2448 : VPV(:,:,:) = cmplx_0
                   +  + ]
     534                 :             : 
     535   [ -  +  +  -  :          18 : ABI_MALLOC(vpv_row, (lmax_model))
          +  -  +  -  -  
                +  -  + ]
     536                 :             : 
     537                 :             : 
     538                 :             : ! various working arrays
     539                 :           6 : GWLS_TIMAB   = 1542
     540                 :             : OPTION_TIMAB = 1
     541                 :           6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     542                 :             : 
     543   [ -  +  +  -  :          18 : ABI_MALLOC(psikg_valence,(2,npw_g))
          +  -  +  -  -  
                +  -  + ]
     544   [ -  +  +  -  :          30 : ABI_MALLOC(psir_valence ,(2,n4,n5,n6))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
     545                 :             : 
     546                 :             : 
     547   [ -  +  +  -  :          18 : ABI_MALLOC(psik_wrk,  (2,npw_k))
          +  -  +  -  -  
                +  -  + ]
     548   [ -  +  +  -  :          18 : ABI_MALLOC(psikb_wrk, (2,npw_kb))
          +  -  +  -  -  
                +  -  + ]
     549   [ -  +  +  -  :          12 : ABI_MALLOC(psikg_wrk, (2,npw_g))
             -  +  -  + ]
     550   [ -  +  +  -  :          12 : ABI_MALLOC(psikg_tmp, (2,npw_g))
             -  +  -  + ]
     551                 :             : 
     552   [ -  +  +  -  :          24 : ABI_MALLOC(local_Lbasis_conjugated,(npw_k,lmax_model))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     553   [ -  +  +  -  :          18 : ABI_MALLOC(YL,(npw_k))
          +  -  +  -  -  
                +  -  + ]
     554                 :             : 
     555                 :           6 : OPTION_TIMAB = 2
     556                 :           6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     557                 :             : 
     558                 :             : 
     559                 :             : 
     560                 :           6 : fft_time  = zero
     561                 :           6 : prod_time = zero
     562                 :             : 
     563                 :             : 
     564                 :           6 : call cpu_time(time1)
     565                 :             : ! loop on all valence bands
     566                 :             : 
     567         [ +  + ]:          30 : do v = 1, nbandv
     568                 :             : 
     569                 :             : 
     570                 :             : ! copy pre-calculated valence state in this covenient local array
     571   [ +  +  +  + ]:       12360 : psikg_valence(:,:) = kernel_wavefunctions_FFT(:,:,v)
     572                 :             : 
     573                 :             : ! compute fourier transform of valence state, and conjugate
     574                 :          24 : call g_to_r(psir_valence,psikg_valence)
     575   [ +  +  +  +  :      164616 : psir_valence(2,:,:,:) = -psir_valence(2,:,:,:)
                   +  + ]
     576                 :             : 
     577                 :             : !--------------------------------------------------------------------------
     578                 :             : !
     579                 :             : ! Step 1: build the modified basis Pc . [ (V^{1/2} l) . psi_v^*].
     580                 :             : !
     581                 :             : !--------------------------------------------------------------------------
     582                 :          24 : GWLS_TIMAB   = 1543
     583                 :          24 : OPTION_TIMAB = 1
     584                 :          24 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     585                 :             : 
     586                 :             : ! loop on all blocks of lanczos vectors
     587         [ +  + ]:         152 : do iblk_lanczos = 1, nbdblock_lanczos
     588                 :             : ! loop on all states within this block
     589         [ +  + ]:         320 : do mb = 1, blocksize
     590                 :             : 
     591                 :             : ! Determine the index of the Lanczos vector
     592                 :         192 : l = (iblk_lanczos-1)*blocksize + mb
     593                 :             : 
     594         [ -  + ]:         192 : if ( l <= lmax_model) then
     595         [ +  + ]:       24864 :   psik_wrk(1,:) = dble (Lbasis_model_lanczos(:,l))
     596         [ +  + ]:       24864 :   psik_wrk(2,:) = dimag(Lbasis_model_lanczos(:,l))
     597                 :             : else
     598   [ #  #  #  # ]:           0 :   psik_wrk(:,:) = zero
     599                 :             : end if
     600                 :             : 
     601                 :             : ! apply Coulomb potential
     602                 :         192 : call sqrt_vc_k(psik_wrk)
     603                 :             : 
     604                 :             : ! Store in array of blocks of wavefunctions
     605   [ +  +  +  + ]:       74336 : psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k) = psik_wrk(:,:)
     606                 :             : 
     607                 :             : end do ! mb
     608                 :             : 
     609                 :         128 : call cpu_time(fft_time1)
     610                 :             : 
     611                 :             : ! Transform to FFT representation
     612                 :         128 : call wf_block_distribute(psikb_wrk,  psikg_wrk,1) ! LA -> FFT
     613                 :             : 
     614                 :             : 
     615                 :             : !  generate the vector  Pc [ (sqrt_V_c.l) psi_v^*]
     616                 :             : 
     617                 :             : ! Compute the real space product, and return to k space, in FFT configuration
     618                 :         128 : call gr_to_g(psikg_tmp,psir_valence, psikg_wrk)
     619                 :             : 
     620                 :             : 
     621                 :         128 : call cpu_time(fft_time2)
     622                 :         128 : fft_time = fft_time + fft_time2-fft_time1
     623                 :             : 
     624                 :             : ! project
     625                 :         128 : call pc_k_valence_kernel(psikg_tmp)
     626                 :             : 
     627                 :             : ! Return to LA configuration
     628                 :             : 
     629                 :             : ! Transform to FFT representation
     630                 :         128 : call wf_block_distribute(psikb_wrk,  psikg_tmp, 2) ! FFT -> LA
     631                 :             : 
     632         [ +  + ]:         344 : do mb = 1, blocksize
     633                 :             : 
     634                 :             : ! Determine the index of the Lanczos vector
     635                 :         192 : l = (iblk_lanczos-1)*blocksize + mb
     636                 :             : 
     637                 :             : 
     638         [ +  - ]:         320 : if ( l <= lmax_model) then
     639   [ +  +  +  + ]:       74208 :   psik_wrk(:,:) = psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k)
     640         [ +  + ]:       24864 :   local_Lbasis_conjugated(:,l) = cmplx_1*psik_wrk(1,:)+cmplx_i*psik_wrk(2,:)
     641                 :             : end if
     642                 :             : 
     643                 :             : 
     644                 :             : end do ! mb
     645                 :             : 
     646                 :             : end do !iblk_lanczos
     647                 :          24 : OPTION_TIMAB = 2
     648                 :          24 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     649                 :             : 
     650                 :             : 
     651                 :             : !--------------------------------------------------------------------------
     652                 :             : ! Step 2: Now that we have the modified basis, compute the matrix
     653                 :             : !             elements of the model dielectric operator
     654                 :             : !
     655                 :             : !
     656                 :             : !--------------------------------------------------------------------------
     657                 :          24 : GWLS_TIMAB   = 1544
     658                 :          24 : OPTION_TIMAB = 1
     659                 :          24 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     660                 :             : 
     661         [ +  + ]:         264 : do iw = 2, npt_gauss+1
     662                 :             : 
     663                 :         240 : call setup_Pk_model(list_omega(iw),second_model_parameter)
     664                 :             : 
     665                 :         240 : call cpu_time(prod_time1)
     666         [ +  + ]:        2160 : do l1 = 1, lmax_model
     667                 :             : 
     668                 :             : ! Apply core function Y to left-vector; conjugate
     669         [ +  + ]:      248640 : do ik = 1, npw_k
     670                 :      248640 : YL(ik) = model_Y_LA(ik)*conjg(local_Lbasis_conjugated(ik,l1))
     671                 :             : end do
     672                 :             : 
     673                 :             : ! Only compute lower diagonal part of matrix; epsilon is hermitian conjugate!
     674         [ +  + ]:       17280 : vpv_row = cmplx_0
     675         [ +  + ]:       10560 : do l2 = 1, l1
     676         [ +  + ]:     1120800 : do ik = 1, npw_k
     677                 :     1118880 : vpv_row(l2) = vpv_row(l2) + YL(ik)*local_Lbasis_conjugated(ik,l2)
     678                 :             : end do
     679                 :             : end do
     680                 :             : 
     681                 :             : ! the code below is twice as long!
     682                 :             : !call ZGEMV ( TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA, Y, INCY )
     683                 :             : !call ZGEMV ( 'T', npw_k, lmax_model, cmplx_1, local_Lbasis_conjugated, npw_k, YL, 1, cmplx_0, vpv_row, 1)
     684                 :             : 
     685                 :             : !do l2 = 1, l1
     686                 :             : !        eps_model_m1_minus_one(l1,l2,iw) = eps_model_m1_minus_one(l1,l2,iw)     &
     687                 :             : !                       -complex_vector_product(YL, local_Lbasis_conjugated(:,l2),npw_k)
     688                 :             : !end do
     689                 :             : 
     690                 :             : ! Sum on all processors, making sure all processors have the total vpv_row
     691                 :        1920 : call xmpi_sum(vpv_row, mpi_communicator, ierr) ! sum on all processors for LA configuration
     692                 :             : 
     693                 :             : ! Each processor takes its slice!
     694         [ +  + ]:       10800 : do l2 =1, l1
     695         [ +  + ]:       10560 : if ( model_lanczos_vector_belongs_to_this_node(l2) ) then
     696                 :        4320 :   lb = model_lanczos_vector_index(l2)
     697                 :        4320 :   VPV(l1,lb,iw) = VPV(l1,lb,iw) + vpv_row(l2)
     698                 :             : end if
     699                 :             : end do
     700                 :             : 
     701                 :             : end do
     702                 :         240 : call cpu_time(prod_time2)
     703                 :             : 
     704                 :         264 : prod_time = prod_time + prod_time2-prod_time1
     705                 :             : 
     706                 :             : end do ! iw
     707                 :          24 : OPTION_TIMAB = 2
     708                 :          30 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     709                 :             : 
     710                 :             : end do ! v
     711                 :             : 
     712                 :           6 : call cpu_time(time2)
     713                 :             : 
     714                 :           6 : time = time2-time1
     715                 :           6 : timing_string = "#        computing VPV                          : "
     716                 :           6 : call write_timing_log(timing_string,time)
     717                 :             : 
     718                 :           6 : timing_string = "#                --- of which is FFT transforms : "
     719                 :           6 : call write_timing_log(timing_string,fft_time)
     720                 :             : 
     721                 :           6 : timing_string = "#                --- of which is products       : "
     722                 :           6 : call write_timing_log(timing_string,prod_time)
     723                 :             : 
     724                 :             : 
     725                 :             : 
     726                 :             : 
     727                 :             : 
     728                 :           6 : GWLS_TIMAB   = 1542
     729                 :           6 : OPTION_TIMAB = 1
     730                 :           6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     731         [ -  + ]:           6 : ABI_FREE(local_Lbasis_conjugated)
     732         [ -  + ]:           6 : ABI_FREE(YL)
     733         [ -  + ]:           6 : ABI_FREE(psikg_valence)
     734         [ -  + ]:           6 : ABI_FREE(psir_valence)
     735         [ -  + ]:           6 : ABI_FREE(psik_wrk)
     736         [ -  + ]:           6 : ABI_FREE(psikb_wrk)
     737         [ -  + ]:           6 : ABI_FREE(psikg_wrk)
     738         [ -  + ]:           6 : ABI_FREE(psikg_tmp)
     739         [ -  + ]:           6 : ABI_FREE(vpv_row)
     740                 :             : 
     741                 :           6 : OPTION_TIMAB = 2
     742                 :           6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     743                 :             : 
     744                 :             : 
     745                 :             : 
     746                 :           6 : call cpu_time(time1)
     747                 :           6 : GWLS_TIMAB   = 1547
     748                 :           6 : OPTION_TIMAB = 1
     749                 :           6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     750                 :             : 
     751                 :             : 
     752                 :             : !--------------------------------------------------------------------------------
     753                 :             : !
     754                 :             : !
     755                 :             : ! Gather dielectric matrix on head node, invert, and re-distribute. This
     756                 :             : ! Saves a lot of RAM, without needing the full machinery of ScaLAPACK.
     757                 :             : !
     758                 :             : !--------------------------------------------------------------------------------
     759                 :             : 
     760                 :             : 
     761   [ -  +  +  -  :          30 : ABI_MALLOC(eps_model_m1_minus_one_DISTR, (lmax_model,blocksize_epsilon,npt_gauss+1))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     762   [ -  +  +  -  :          24 : ABI_MALLOC(re_buffer, (lmax_model,blocksize_epsilon))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     763   [ -  +  +  -  :          18 : ABI_MALLOC(im_buffer, (lmax_model,blocksize_epsilon))
          -  +  +  -  -  
                +  -  + ]
     764                 :             : 
     765   [ +  +  +  +  :        2448 : eps_model_m1_minus_one_DISTR(:,:,:) = cmplx_0
                   +  + ]
     766                 :             : 
     767                 :             : ! Define the head node, which will invert the dielectric matrices
     768                 :           6 : head = mpi_rank == mpi_head_rank
     769                 :             : 
     770                 :             : ! Amount of data received and sent
     771                 :           6 : sendcount = lmax_model*blocksize_epsilon
     772                 :           6 : recvcount = lmax_model*blocksize_epsilon
     773                 :             : 
     774   [ -  +  +  -  :          18 : ABI_MALLOC(sendcounts,(mpi_nproc))
          +  -  +  -  -  
                +  -  + ]
     775   [ -  +  +  -  :          12 : ABI_MALLOC(displs    ,(mpi_nproc))
             -  +  -  + ]
     776         [ +  + ]:          24 : sendcounts(:) = sendcount
     777                 :             : 
     778         [ +  + ]:          24 : do l =1, mpi_nproc
     779                 :          24 : displs(l) = (l-1)*sendcount
     780                 :             : end do
     781                 :             : 
     782         [ +  + ]:           6 : if (head) then
     783                 :             :   ! build and invert the dielectric array
     784                 :             :   ! careful!  lmax_model not necessarily equal to blocksize_epsilon*nbdblock_epsilon
     785   [ -  +  +  -  :          12 :   ABI_MALLOC(re_BUFFER_head, (lmax_model, blocksize_epsilon*nbdblock_epsilon))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     786   [ -  +  +  -  :           9 :   ABI_MALLOC(im_BUFFER_head, (lmax_model, blocksize_epsilon*nbdblock_epsilon))
          -  +  +  -  -  
                +  -  + ]
     787   [ -  +  +  -  :          12 :   ABI_MALLOC(epsilon_head, (lmax_model, lmax_model))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     788                 :             : else
     789                 :             :   !This looks superfluous and it is on large number of systems, but sending these
     790                 :             :   !unallocated in xmpi_scatterv caused 'cannot allocate memory' cryptic errors on
     791                 :             :   !several parallel test farm computers (cronos_gcc46_paral, petrus_nag, inca_gcc44_sdebug)
     792         [ -  + ]:           3 :   ABI_MALLOC(re_BUFFER_head, (1,1))
     793         [ -  + ]:           3 :   ABI_MALLOC(im_BUFFER_head, (1,1))
     794         [ -  + ]:           3 :   ABI_MALLOC(epsilon_head, (1,1))
     795                 :             : end if
     796                 :             : 
     797                 :             : ! Do  one frequency at a time, to avoid overflowing the RAM
     798         [ +  + ]:          72 : do iw = 1, npt_gauss+1
     799                 :             : ! Gather, except for static case
     800         [ +  + ]:          66 : if ( iw /=1 ) then
     801                 :             :   ! Gather VPV on head node, for this frequency
     802   [ +  -  +  +  :        2220 :   call xmpi_gather(dble(VPV(:,:,iw)),  sendcount , re_BUFFER_head, recvcount, mpi_head_rank, mpi_communicator,ierr)
                   +  + ]
     803   [ +  +  +  + ]:        2220 :   call xmpi_gather(dimag(VPV(:,:,iw)), sendcount , im_BUFFER_head, recvcount, mpi_head_rank, mpi_communicator,ierr)
     804                 :             : end if
     805                 :             : 
     806         [ +  + ]:          66 : if ( head ) then
     807                 :             : 
     808                 :             :   ! fill the dielectric matrix
     809                 :             : 
     810   [ +  +  +  + ]:        2409 :   epsilon_head(:,:) = cmplx_0
     811         [ +  + ]:          33 :   if (iw ==1) then
     812                 :             :     ! STATIC CASE, diagonal matrix
     813         [ +  + ]:          27 :     do l= 1, lmax_model
     814                 :          27 :     epsilon_head(l,l) = cmplx_1/epsilon_model_eigenvalues_0(l)-cmplx_1
     815                 :             :     end do
     816                 :             : 
     817                 :             :   else
     818                 :             :     ! DYNAMIC CASE, compute
     819         [ +  + ]:         270 :     do l1 =1, lmax_model
     820         [ +  + ]:        1320 :     do l2 =1, l1
     821                 :        1080 :     z = -cmplx_1*re_BUFFER_head(l1,l2)-cmplx_i*im_BUFFER_head(l1,l2)
     822                 :        1080 :     epsilon_head(l1,l2) = z
     823                 :        1320 :     epsilon_head(l2,l1) = conjg(z)
     824                 :             :     end do
     825                 :         270 :     epsilon_head(l1,l1) = epsilon_head(l1,l1) + cmplx_1
     826                 :             :     end do
     827                 :             : 
     828                 :             :     ! invert the matrix
     829                 :          30 :     call driver_invert_positive_definite_hermitian_matrix(epsilon_head,lmax_model)
     830                 :             : 
     831                 :             :     ! subtract identity
     832         [ +  + ]:         270 :     do l =1, lmax_model
     833                 :         270 :     epsilon_head(l,l) = epsilon_head(l,l) - cmplx_1
     834                 :             :     end do
     835                 :             :   end if
     836                 :             : 
     837                 :             :   ! copy in head buffer
     838   [ +  +  +  + ]:        2409 :   re_BUFFER_head(:,:) = zero
     839   [ +  +  +  + ]:        2409 :   im_BUFFER_head(:,:) = zero
     840         [ +  + ]:         297 :   do l1 =1, lmax_model
     841         [ +  + ]:        2409 :   do l2 =1, lmax_model
     842                 :        2112 :   z = epsilon_head(l1,l2)
     843                 :        2112 :   re_BUFFER_head(l1,l2) = dble(z)
     844                 :        2376 :   im_BUFFER_head(l1,l2) = dimag(z)
     845                 :             :   end do
     846                 :             :   end do
     847                 :             : 
     848                 :             : end if
     849                 :             : 
     850                 :             : ! Scatter back the data on the head to all processors
     851                 :          66 : call xmpi_scatterv(re_BUFFER_head, sendcounts, displs, re_buffer, recvcount, mpi_head_rank, mpi_communicator, ierr)
     852                 :          66 : call xmpi_scatterv(im_BUFFER_head, sendcounts, displs, im_buffer, recvcount, mpi_head_rank, mpi_communicator, ierr)
     853                 :             : 
     854   [ +  +  +  + ]:        2448 : eps_model_m1_minus_one_DISTR(:,:,iw) = cmplx_1*re_buffer(:,:) + cmplx_i*im_buffer(:,:)
     855                 :             : 
     856                 :             : end do
     857                 :             : 
     858         [ -  + ]:           6 : ABI_FREE(re_BUFFER_head)
     859         [ -  + ]:           6 : ABI_FREE(im_BUFFER_head)
     860         [ -  + ]:           6 : ABI_FREE(epsilon_head)
     861                 :             : 
     862                 :             : 
     863                 :             : 
     864                 :             : !================================================================================
     865                 :             : !
     866                 :             : ! For debugging purposes, store distributed dielectric matrix back in the
     867                 :             : ! complete local copies, to insure the rest of the code works.
     868                 :             : !
     869                 :             : !================================================================================
     870                 :             : 
     871                 :             : if (.false.) then
     872                 :             :   ! Prepare the array that will contain the matrix elements of the model operator
     873                 :             :   ! THIS IS ONLY FOR THE REST OF THE CODE TO WORK; WE WILL REMOVE THIS
     874                 :             :   ! TO SAVE RAM LATER
     875                 :             :   ABI_MALLOC(eps_model_m1_minus_one, (lmax_model,lmax_model,npt_gauss+1))
     876                 :             : 
     877                 :             :   ! initialize the array with zeros
     878                 :             :   eps_model_m1_minus_one = cmplx_0
     879                 :             : 
     880                 :             :   ! Amount of data received and sent
     881                 :             :   sendcount = lmax_model*blocksize_epsilon
     882                 :             :   recvcount = lmax_model*blocksize_epsilon*nbdblock_epsilon
     883                 :             : 
     884                 :             : 
     885                 :             :   ABI_MALLOC(re_BUFFER_head, (lmax_model,blocksize_epsilon*nbdblock_epsilon))
     886                 :             :   ABI_MALLOC(im_BUFFER_head, (lmax_model,blocksize_epsilon*nbdblock_epsilon))
     887                 :             : 
     888                 :             :   do iw = 1, npt_gauss+1
     889                 :             : 
     890                 :             :   re_buffer(:,:) = dble( eps_model_m1_minus_one_DISTR(:,:,iw))
     891                 :             :   im_buffer(:,:) = dimag(eps_model_m1_minus_one_DISTR(:,:,iw))
     892                 :             : 
     893                 :             :   call xmpi_allgather(re_buffer,sendcount,re_BUFFER_head,mpi_communicator,ierr)
     894                 :             :   call xmpi_allgather(im_buffer,sendcount,im_BUFFER_head,mpi_communicator,ierr)
     895                 :             : 
     896                 :             :   do l = 1, lmax_model
     897                 :             :   eps_model_m1_minus_one(:,l,iw) =  cmplx_1*re_BUFFER_head(:,l)+ cmplx_i*im_BUFFER_head(:,l)
     898                 :             :   end do
     899                 :             :   end do
     900                 :             : 
     901                 :             :   ABI_FREE(re_BUFFER_head)
     902                 :             :   ABI_FREE(im_BUFFER_head)
     903                 :             : end if
     904                 :             : 
     905                 :           6 : call cpu_time(time2)
     906                 :           6 : OPTION_TIMAB = 2
     907                 :           6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     908                 :             : 
     909                 :             : !================================================================================
     910                 :             : !
     911                 :             : !================================================================================
     912                 :             : 
     913                 :             : 
     914                 :           6 : time = time2-time1
     915                 :           6 : timing_string = "#        inverting / distributing               :  "
     916                 :             : 
     917                 :           6 : call write_timing_log(timing_string,time)
     918                 :             : 
     919                 :             : 
     920                 :             : 
     921         [ -  + ]:           6 : ABI_FREE(re_buffer )
     922         [ -  + ]:           6 : ABI_FREE(im_buffer )
     923         [ -  + ]:           6 : ABI_FREE(sendcounts)
     924         [ -  + ]:           6 : ABI_FREE(displs    )
     925         [ -  + ]:           6 : ABI_FREE(VPV       )
     926                 :             : 
     927                 :             : 
     928                 :             : 
     929                 :           6 : GWLS_TIMAB   = 1541
     930                 :             : OPTION_TIMAB = 2
     931                 :           6 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     932                 :             : 
     933                 :             : 
     934                 :           6 : end subroutine compute_eps_model_m1_minus_one
     935                 :             : !!***
     936                 :             : 
     937                 :             : !!****f* m_hamiltonian/cleanup_projected_Sternheimer_epsilon
     938                 :             : !! NAME
     939                 :             : !!  cleanup_projected_Sternheimer_epsilon
     940                 :             : !!
     941                 :             : !! FUNCTION
     942                 :             : !!  .
     943                 :             : !!
     944                 :             : !! INPUTS
     945                 :             : !!
     946                 :             : !! OUTPUT
     947                 :             : !!
     948                 :             : !! SOURCE
     949                 :             : 
     950                 :           7 : subroutine cleanup_projected_Sternheimer_epsilon
     951                 :             : 
     952                 :             : ! *************************************************************************
     953                 :             : 
     954         [ -  + ]:           7 : ABI_SFREE(projected_epsilon_M_matrix)
     955         [ -  + ]:           7 : ABI_SFREE(projected_epsilon_B_matrix)
     956         [ -  + ]:           7 : ABI_SFREE(projected_epsilon_G_matrix)
     957         [ +  - ]:           7 : ABI_SFREE(eps_m1_minus_eps_model_m1)
     958         [ +  - ]:           7 : ABI_SFREE(list_omega)
     959         [ +  - ]:           7 : ABI_SFREE(list_weights)
     960         [ +  + ]:           7 : ABI_SFREE(eps_model_m1_minus_one_DISTR)
     961         [ +  + ]:           7 : ABI_SFREE(model_lanczos_vector_belongs_to_this_node)
     962         [ +  + ]:           7 : ABI_SFREE(model_lanczos_vector_index)
     963                 :             : 
     964                 :           7 : end subroutine cleanup_projected_Sternheimer_epsilon
     965                 :             : !!***
     966                 :             : 
     967                 :             : 
     968                 :             : !!****f* m_hamiltonian/ProjectedSternheimerEpsilon
     969                 :             : !! NAME
     970                 :             : !!  ProjectedSternheimerEpsilon
     971                 :             : !!
     972                 :             : !! FUNCTION
     973                 :             : !!  .
     974                 :             : !!
     975                 :             : !! INPUTS
     976                 :             : !!
     977                 :             : !! OUTPUT
     978                 :             : !!
     979                 :             : !! SOURCE
     980                 :             : 
     981                 :           7 : subroutine ProjectedSternheimerEpsilon(lmax, npt_gauss, second_model_parameter, &
     982                 :           7 : list_projection_frequencies,nfrequencies,&
     983                 :           7 : epsilon_eigenvalues_0,debug,use_model)
     984                 :             : !----------------------------------------------------------------------------------------------------
     985                 :             : ! This subroutine combines in a single subprogram the jobs of previous routines
     986                 :             : !
     987                 :             : !               - setup_projected_Sternheimer_epsilon
     988                 :             : !               - compute_projected_Sternheimer_epsilon
     989                 :             : !
     990                 :             : ! The purpose of this combination is to avoid independent loops on nbandv, requiring the
     991                 :             : ! arrays
     992                 :             : !               projected_epsilon_M_matrix
     993                 :             : !               projected_epsilon_B_matrix
     994                 :             : !               projected_epsilon_G_matrix
     995                 :             : !
     996                 :             : ! from scaling like N^3, which grows very large with problem size.
     997                 :             : !
     998                 :             : ! Thus, this routine:
     999                 :             : !
    1000                 :             : !       -  Computes the frequency-dependent dielectric matrix in the Lanczos basis, using
    1001                 :             : !          the projected Sternheimer equations.
    1002                 :             : !
    1003                 :             : !       -  Computes the frequency-dependent MODEL dielectric matrix in the complementary Lanczos basis.
    1004                 :             : !
    1005                 :             : !
    1006                 :             : ! This routine will be verbose and write log files; indeed, large jobs crash in here, it will
    1007                 :             : ! be important to know where/why!
    1008                 :             : !
    1009                 :             : ! The subroutine also computes the matrix elements on epsilon_model(iw) in the Lanczos basis;
    1010                 :             : ! this is done here to avoid preforming direct products with the valence states again later.
    1011                 :             : !----------------------------------------------------------------------------------------------------
    1012                 :             : real(dp), parameter     :: svd_tolerance = 1.0e-16_dp
    1013                 :             : 
    1014                 :             : integer,     intent(in) :: lmax, npt_gauss
    1015                 :             : integer,     intent(in) :: nfrequencies
    1016                 :             : real(dp),    intent(in) :: list_projection_frequencies(nfrequencies)
    1017                 :             : logical,     intent(in) :: debug
    1018                 :             : real(dp),    intent(in) :: epsilon_eigenvalues_0(lmax)
    1019                 :             : 
    1020                 :             : logical,optional,intent(in) :: use_model
    1021                 :             : 
    1022                 :             : real(dp),    intent(in) :: second_model_parameter
    1023                 :             : 
    1024                 :             : 
    1025                 :             : integer :: l, l1, l2
    1026                 :             : integer :: i, iw, v
    1027                 :             : integer :: recy_i
    1028                 :             : integer :: lsolutions_max, lsolutions, ls
    1029                 :             : integer :: projection
    1030                 :             : 
    1031                 :           7 : complex(dp), allocatable :: sternheimer_A0(:,:)
    1032                 :           7 : complex(dp), allocatable :: sternheimer_A(:,:)
    1033                 :           7 : complex(dp), allocatable :: sternheimer_B(:,:)
    1034                 :           7 : complex(dp), allocatable :: sternheimer_X(:,:)
    1035                 :           7 : complex(dp), allocatable :: sternheimer_G(:,:)
    1036                 :             : 
    1037                 :             : 
    1038                 :           7 : complex(dp), allocatable :: dummy_tmp_1(:,:)
    1039                 :           7 : complex(dp), allocatable :: dummy_tmp_2(:,:)
    1040                 :             : 
    1041                 :           7 : integer, allocatable      :: ipiv(:)
    1042                 :             : 
    1043                 :             : 
    1044                 :             : 
    1045                 :           7 : complex(dp),allocatable :: local_Lbasis(:,:)
    1046                 :           7 : complex(dp),allocatable :: local_Lbasis_conjugated(:,:)
    1047                 :           7 : complex(dp),allocatable :: YL(:)
    1048                 :             : 
    1049                 :           7 : real(dp), allocatable :: psikg_in(:,:), psikg_out(:,:)
    1050                 :             : 
    1051                 :           7 : real(dp), allocatable :: psik_wrk(:,:), psikg_wrk(:,:), psikb_wrk(:,:)
    1052                 :           7 : real(dp), allocatable :: psi_gamma_l1(:,:), psi_gamma_l2(:,:)
    1053                 :             : 
    1054                 :           7 : real(dp), allocatable :: psikg_valence(:,:)
    1055                 :           7 : real(dp), allocatable :: psir_valence(:,:,:,:)
    1056                 :             : 
    1057                 :           7 : real(dp), allocatable :: psi_rhs(:,:,:)
    1058                 :             : 
    1059                 :           7 : real(dp), allocatable :: psikg_VL(:,:)
    1060                 :             : 
    1061                 :             : 
    1062                 :           7 : complex(dp), allocatable :: check_matrix(:,:), check_matrix2(:,:)
    1063                 :           7 : complex(dp), allocatable :: c_sternheimer_solutions(:,:)
    1064                 :           7 : complex(dp), allocatable :: QR_orthonormal_basis(:,:)
    1065                 :             : 
    1066                 :           7 : complex(dp), allocatable :: svd_matrix(:,:)
    1067                 :           7 : real   (dp ), allocatable :: svd_values(:)
    1068                 :             : 
    1069                 :             : 
    1070                 :             : integer                   :: iblk_lanczos, nbdblock_lanczos
    1071                 :             : integer                   :: iblk_solutions, nbdblock_solutions
    1072                 :             : integer                   :: mb
    1073                 :             : 
    1074                 :             : character(128) :: filename
    1075                 :             : logical        :: file_exists
    1076                 :             : integer        :: io_unit
    1077                 :             : 
    1078                 :             : character(128) :: filename_log
    1079                 :             : integer        :: io_unit_log
    1080                 :             : 
    1081                 :             : 
    1082                 :             : real(dp)      :: omega
    1083                 :             : 
    1084                 :             : character(256) :: timing_string
    1085                 :             : real(dp)       :: time1, time2
    1086                 :             : real(dp)       :: time_exact
    1087                 :             : 
    1088                 :             : 
    1089                 :             : integer  :: info
    1090                 :             : integer  :: ierr
    1091                 :             : 
    1092                 :             : real(dp)  ::  z(2)
    1093                 :             : 
    1094                 :             : 
    1095                 :             : logical        :: omega_is_imaginary
    1096                 :             : real(dp)       :: omega0
    1097                 :             : 
    1098                 :             : logical        :: model
    1099                 :             : logical        :: write_debug
    1100                 :             : 
    1101                 :             : 
    1102                 :             : integer        :: mpi_communicator, mpi_rank, mpi_group
    1103                 :             : 
    1104                 :             : ! *************************************************************************
    1105                 :             : 
    1106                 :             : 
    1107                 :             : !================================================================================
    1108                 :             : ! Prepare MPI information
    1109                 :             : !================================================================================
    1110                 :             : 
    1111                 :             : ! for LA configuration ,The processors communicate over band+FFT
    1112                 :           7 : mpi_communicator = mpi_enreg%comm_bandfft
    1113                 :             : 
    1114                 :             : ! what is the rank of this processor, within its group?
    1115                 :           7 : mpi_rank  = mpi_enreg%me_fft
    1116                 :             : 
    1117                 :             : ! Which group does this processor belong to, given the communicator?
    1118                 :           7 : mpi_group = mpi_enreg%me_band
    1119                 :             : 
    1120                 :             : 
    1121                 :             : 
    1122                 :             : 
    1123                 :             : !================================================================================
    1124                 :             : ! Setup a log file, to keep track of the algorithm
    1125                 :             : !================================================================================
    1126                 :             : 
    1127                 :             : 
    1128                 :           7 : write(filename_log,'(A,I4.4,A)') 'ProjectedSternheimerEpsilon_PROC=',mpi_enreg%me,'.log'
    1129                 :             : 
    1130                 :           7 : io_unit_log = get_unit()
    1131                 :           7 : open(io_unit_log,file=filename_log,status=files_status_new)
    1132                 :           7 : write(io_unit_log,10) ''
    1133                 :           7 : write(io_unit_log,10) '#===================================================================================================='
    1134                 :           7 : write(io_unit_log,10) "#                     ProjectedSternheimerEpsilon: log file                                          "
    1135                 :           7 : write(io_unit_log,10) "#                     -------------------------------------------------------------------            "
    1136                 :           7 : write(io_unit_log,10) "#                                                                                                    "
    1137                 :           7 : write(io_unit_log,10) "# This file tracks the algorithm in the routine ProjectedSternheimerEpsilon. The goal is to          "
    1138                 :           7 : write(io_unit_log,10) "# establish where the algorithm crashes if it does, and/or  to track are far along the code is.      "
    1139                 :           7 : write(io_unit_log,10) '#'
    1140                 :           7 : write(io_unit_log,10) '#  MPI data for this process:'
    1141                 :           7 : write(io_unit_log,10) '#'
    1142                 :           7 : write(io_unit_log,22) '#    mpi_rank :',mpi_rank,'  (rank of this processor in its band group)'
    1143                 :           7 : write(io_unit_log,22) '#    mpi_group:',mpi_group,' (band group to which this processor belongs)'
    1144                 :           7 : write(io_unit_log,10) '#===================================================================================================='
    1145                 :           7 : flush(io_unit_log)
    1146                 :             : 
    1147                 :             : 
    1148                 :             : !================================================================================
    1149                 :             : ! Setup timing; prepare arrays
    1150                 :             : !================================================================================
    1151                 :             : 
    1152                 :           7 : write(io_unit_log,10) " - Preparing and allocating arrays ...."
    1153                 :           7 : flush(io_unit_log)
    1154                 :             : 
    1155                 :             : 
    1156                 :             : 
    1157                 :           7 : timing_string = "#"
    1158                 :           7 : call write_text_block_in_Timing_log(timing_string)
    1159                 :           7 : timing_string = "#        ProjectedSternheimerEpsilon "
    1160                 :           7 : call write_text_block_in_Timing_log(timing_string)
    1161                 :           7 : timing_string = "#"
    1162                 :           7 : call write_text_block_in_Timing_log(timing_string)
    1163                 :             : 
    1164                 :             : ! Allocate the module array
    1165   [ -  +  +  -  :          35 : ABI_MALLOC(projected_dielectric_Lanczos_basis, (lmax,lmax,npt_gauss+1))
          -  +  +  -  +  
          -  -  +  +  -  
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1166                 :             : 
    1167   [ +  +  +  +  :        5628 : projected_dielectric_Lanczos_basis(:,:,:) = cmplx_0
                   +  + ]
    1168                 :             : 
    1169                 :             : ! initialize zero frequency with exact solution
    1170         [ +  + ]:          63 : do l = 1, lmax
    1171                 :          63 : projected_dielectric_Lanczos_basis(l,l,1) = cmplx_1*epsilon_eigenvalues_0(l)
    1172                 :             : end do
    1173                 :             : 
    1174                 :             : 
    1175                 :             : ! initialize other frequencies with the identity
    1176         [ +  + ]:          77 : do iw = 2, npt_gauss + 1
    1177         [ +  + ]:         637 : do l = 1, lmax
    1178                 :         630 : projected_dielectric_Lanczos_basis(l,l,iw) = cmplx_1
    1179                 :             : end do
    1180                 :             : end do
    1181                 :             : 
    1182                 :           7 : time_exact = zero
    1183                 :             : 
    1184                 :             : 
    1185                 :             : !================================================================================
    1186                 :             : ! Parallelisation of the code is subtle; Hamiltonian must act over
    1187                 :             : ! FFT rows, we must be careful with memory, etc...
    1188                 :             : !
    1189                 :             : ! We will parallelise in block of Lanczos vectors, not over bands.
    1190                 :             : !================================================================================
    1191                 :             : 
    1192                 :             : ! Number of blocks of lanczos vectors
    1193                 :           7 : nbdblock_lanczos = lmax/blocksize
    1194         [ -  + ]:           7 : if (modulo(lmax,blocksize) /= 0) nbdblock_lanczos = nbdblock_lanczos + 1
    1195                 :             : 
    1196                 :             : 
    1197         [ +  - ]:           7 : if (present(use_model)) then
    1198                 :           7 :   model = use_model
    1199                 :             : else
    1200                 :             :   model = .true.
    1201                 :             : end if
    1202                 :             : 
    1203         [ +  + ]:           7 : if (model) then
    1204                 :             :   ! Prepare the array that will contain the matrix elements of the model operator
    1205   [ -  +  +  -  :          24 :   ABI_MALLOC(model_dielectric_Lanczos_basis, (lmax,lmax,npt_gauss+1))
          -  +  +  -  -  
          +  +  -  -  +  
             -  +  -  + ]
    1206                 :             : 
    1207                 :             :   ! initialize with zero. NOT with the identity, in order to avoid extra communications
    1208                 :             :   ! (see below)
    1209   [ +  +  +  +  :        4824 :   model_dielectric_Lanczos_basis(:,:,:) = cmplx_0
                   +  + ]
    1210                 :             : 
    1211                 :             : end if
    1212                 :             : 
    1213                 :             : ! various working arrays
    1214                 :             : 
    1215   [ -  +  +  -  :          21 : ABI_MALLOC(psikg_valence    ,(2,npw_g))
          +  -  +  -  -  
                +  -  + ]
    1216   [ -  +  +  -  :          35 : ABI_MALLOC(psir_valence     ,(2,n4,n5,n6))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
    1217                 :             : 
    1218                 :             : 
    1219   [ -  +  +  -  :          14 : ABI_MALLOC(psikg_VL ,(2,npw_g))
             -  +  -  + ]
    1220                 :             : 
    1221                 :             : 
    1222   [ -  +  +  -  :          21 : ABI_MALLOC(psik_wrk         ,(2,npw_k))
          +  -  +  -  -  
                +  -  + ]
    1223   [ -  +  +  -  :          21 : ABI_MALLOC(psikb_wrk        ,(2,npw_kb))
          +  -  +  -  -  
                +  -  + ]
    1224   [ -  +  +  -  :          14 : ABI_MALLOC(psikg_wrk        ,(2,npw_g))
             -  +  -  + ]
    1225                 :             : 
    1226                 :             : 
    1227   [ -  +  +  -  :          14 : ABI_MALLOC(psi_gamma_l1     ,(2,npw_k))
             -  +  -  + ]
    1228   [ -  +  +  -  :          14 : ABI_MALLOC(psi_gamma_l2     ,(2,npw_k))
             -  +  -  + ]
    1229                 :             : 
    1230   [ -  +  +  -  :          28 : ABI_MALLOC(psi_rhs          ,(2,npw_k,lmax))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1231                 :             : 
    1232                 :             : 
    1233   [ -  +  +  -  :          14 : ABI_MALLOC(psikg_in   ,(2,npw_g))
             -  +  -  + ]
    1234   [ -  +  +  -  :          14 : ABI_MALLOC(psikg_out  ,(2,npw_g))
             -  +  -  + ]
    1235                 :             : 
    1236                 :             : 
    1237                 :             : ! maximal possible dimension of the solution space
    1238                 :             : ! +1 because the solutions at $\omega=\infty$ are free.
    1239                 :             : ! +1 if recycling is activated, because the solutions at $\omega=0$ are then available.
    1240                 :           7 : i=1
    1241         [ +  - ]:           7 : if(dtset%gwls_recycle == 1 .or. dtset%gwls_recycle == 2) then
    1242                 :           7 :   i=2
    1243                 :             : end if
    1244                 :           7 : lsolutions_max = lmax*(nfrequencies+i)
    1245                 :             : 
    1246                 :             : 
    1247   [ -  +  +  -  :          28 : ABI_MALLOC(local_Lbasis,           (npw_k,lmax))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1248   [ -  +  +  -  :          21 : ABI_MALLOC(local_Lbasis_conjugated,(npw_k,lmax))
          -  +  +  -  -  
                +  -  + ]
    1249   [ -  +  +  -  :          21 : ABI_MALLOC(YL,(npw_k))
          +  -  +  -  -  
                +  -  + ]
    1250                 :             : 
    1251   [ -  +  +  -  :          28 : ABI_MALLOC(c_sternheimer_solutions,(npw_k,lsolutions_max))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1252   [ -  +  +  -  :          21 : ABI_MALLOC(QR_orthonormal_basis   ,(npw_k,lsolutions_max))
          -  +  +  -  -  
                +  -  + ]
    1253                 :             : 
    1254                 :             : 
    1255                 :           7 : omega_is_imaginary = .true.
    1256                 :             : 
    1257                 :             : 
    1258   [ -  +  +  -  :          21 : ABI_MALLOC(svd_matrix,(npw_k,lsolutions_max))
          -  +  +  -  -  
                +  -  + ]
    1259   [ -  +  +  -  :          21 : ABI_MALLOC(svd_values,(lsolutions_max))
          +  -  +  -  -  
                +  -  + ]
    1260                 :             : 
    1261                 :             : 
    1262                 :             : ! Prepare files for writing
    1263   [ -  +  -  - ]:           7 : write_debug = debug .and. mpi_enreg%me == 0
    1264                 :             : 
    1265                 :             : if ( write_debug ) then
    1266                 :             : 
    1267                 :           0 :   write(filename,'(A)') "ProjectedSternheimerEpsilon.log"
    1268                 :           0 :   inquire(file=filename,exist=file_exists)
    1269                 :             : 
    1270                 :           0 :   i = 0
    1271         [ #  # ]:           0 :   do while (file_exists)
    1272                 :           0 :   i = i+1
    1273                 :           0 :   write (filename,'(A,I0.4,A)') "ProjectedSternheimerEpsilon_",i,".log"
    1274                 :           0 :   inquire(file=filename,exist=file_exists)
    1275                 :             :   end do
    1276                 :             : 
    1277                 :             : 
    1278                 :           0 :   io_unit = get_unit()
    1279                 :           0 :   open(io_unit,file=filename,status=files_status_new)
    1280                 :           0 :   write(io_unit,10) ''
    1281                 :           0 :   write(io_unit,10) '#===================================================================================================='
    1282                 :           0 :   write(io_unit,10) "#                     Building the dielectic matrix using projected Sternheimer equation             "
    1283                 :           0 :   write(io_unit,10) "#                     -------------------------------------------------------------------            "
    1284                 :           0 :   write(io_unit,10) "#                                                                                                    "
    1285                 :           0 :   write(io_unit,10) '# This file contains some tests to check if the various elements entering the projected  '
    1286                 :           0 :   write(io_unit,10) '# dielectric matrix have the right properties. At this point, this is mostly for debugging.'
    1287                 :           0 :   write(io_unit,10) '# The wavefunctions and other related arrays are stored in reciprocal space.'
    1288                 :           0 :   write(io_unit,10) '#'
    1289                 :           0 :   write(io_unit,10) '#===================================================================================================='
    1290                 :           0 :   write(io_unit,10) ''
    1291                 :           0 :   flush(io_unit)
    1292                 :             : end if
    1293                 :             : 
    1294         [ -  + ]:           7 : if (debug) then
    1295   [ #  #  #  #  :           0 :   ABI_MALLOC(check_matrix ,(lsolutions_max,lsolutions_max))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1296   [ #  #  #  #  :           0 :   ABI_MALLOC(check_matrix2,(lsolutions_max,lsolutions_max))
          #  #  #  #  #  
                #  #  # ]
    1297                 :             : end if
    1298                 :             : 
    1299                 :             : !================================================================================
    1300                 :             : !  Loop on all valence bands
    1301                 :             : !================================================================================
    1302                 :             : 
    1303                 :             : 
    1304                 :             : 
    1305                 :             : 
    1306         [ +  + ]:          35 : do v = 1, nbandv
    1307                 :          28 : write(io_unit_log,10) '#===================================================================================================='
    1308                 :          28 : write(io_unit_log,20) '#  valence band index:', v
    1309                 :          28 : write(io_unit_log,10) '#===================================================================================================='
    1310                 :          28 : flush(io_unit_log)
    1311                 :             : 
    1312                 :             : 
    1313                 :             : 
    1314                 :             : 
    1315         [ -  + ]:          28 : if ( write_debug ) then
    1316                 :           0 :   write(io_unit,10) '#===================================================================================================='
    1317                 :           0 :   write(io_unit,20) '#  valence band index:', v
    1318                 :           0 :   write(io_unit,10) '#===================================================================================================='
    1319                 :           0 :   flush(io_unit)
    1320                 :             : end if
    1321                 :             : 
    1322                 :          28 : write(io_unit_log,10) '   - Fourier transform valence state ...'
    1323                 :          28 : flush(io_unit_log)
    1324                 :             : 
    1325                 :             : 
    1326                 :             : ! copy pre-calculated valence state in this covenient local array
    1327   [ +  +  +  + ]:       15448 : psikg_valence(:,:) = kernel_wavefunctions_FFT(:,:,v)
    1328                 :             : 
    1329                 :             : ! compute fourier transform of valence state, and conjugate
    1330                 :          28 : call g_to_r(psir_valence,psikg_valence)
    1331   [ +  +  +  +  :      192052 : psir_valence(2,:,:,:) = -psir_valence(2,:,:,:)
                   +  + ]
    1332                 :             : 
    1333                 :             : ! loop on all blocks of lanczos vectors
    1334                 :          28 : write(io_unit_log,10) '   - Loop on all lanczos blocks to generate modified basis and Sternheimer RHS:'
    1335                 :          28 : flush(io_unit_log)
    1336         [ +  + ]:         188 : do iblk_lanczos = 1, nbdblock_lanczos
    1337                 :             : !--------------------------------------------------------------------------
    1338                 :             : ! Below, we build the modified basis, [ (V^{1/2} l)^* . psi_v],
    1339                 :             : ! as well as conjugated, projected form, Pc . [ (V^{1/2} l) . psi_v^*].
    1340                 :             : !
    1341                 :             : ! It is very irritating to have to do it this way, but I don't
    1342                 :             : ! see an alternative; see discussion below.
    1343                 :             : !
    1344                 :             : !--------------------------------------------------------------------------
    1345                 :             : 
    1346                 :         160 : write(io_unit_log,23) '       iblk_lanczos  = ',iblk_lanczos," / ",nbdblock_lanczos
    1347                 :             : 
    1348                 :             : 
    1349                 :         160 : write(io_unit_log,10) '          -- Prepare modified basis computation...'
    1350                 :         160 : flush(io_unit_log)
    1351                 :             : 
    1352                 :             : 
    1353                 :             : 
    1354                 :             : ! loop on all states within this block
    1355         [ +  + ]:         384 : do mb = 1, blocksize
    1356                 :             : 
    1357                 :             : ! Determine the index of the Lanczos vector
    1358                 :         224 : l = (iblk_lanczos-1)*blocksize + mb
    1359                 :             : 
    1360                 :             : ! take a single lanczos vector
    1361                 :             : 
    1362         [ +  - ]:         224 : if ( l <= lmax) then
    1363         [ +  + ]:       33120 :   psik_wrk(1,:) = dble (Lbasis_lanczos(:,l))
    1364         [ +  + ]:       33120 :   psik_wrk(2,:) = dimag(Lbasis_lanczos(:,l))
    1365                 :             : else
    1366   [ #  #  #  # ]:           0 :   psik_wrk(:,:) =  zero
    1367                 :             : end if
    1368                 :             : 
    1369                 :             : 
    1370                 :             : ! Apply coulomb potential
    1371                 :         224 : call sqrt_vc_k(psik_wrk)
    1372                 :             : 
    1373                 :             : ! Store in array of blocks of wavefunctions
    1374   [ +  +  +  + ]:       99072 : psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k) = psik_wrk(:,:)
    1375                 :             : 
    1376                 :             : end do ! mb
    1377                 :             : 
    1378                 :             : ! Transform to FFT representation
    1379                 :         160 : call wf_block_distribute(psikb_wrk,  psikg_VL,1) ! LA -> FFT
    1380                 :             : 
    1381                 :             : ! psikg_VL now contains | V^1/2 . l >, in FFT configuration
    1382                 :             : 
    1383                 :             : 
    1384                 :             : !----------------------------------------------------------
    1385                 :             : ! i) Compute the modified basis
    1386                 :             : !----------------------------------------------------------
    1387                 :         160 : write(io_unit_log,10) '          -- compute modified basis ...'
    1388                 :         160 : flush(io_unit_log)
    1389                 :             : 
    1390                 :             : 
    1391                 :             : 
    1392                 :             : ! Fourier transform to real space, and conjugate (psir1 is a global work array)
    1393                 :         160 : call g_to_r(psir1,psikg_VL)
    1394   [ +  +  +  +  :     1097440 : psir1(2,:,:,:) = -psir1(2,:,:,:) ! IS THIS STACK-DANGEROUS?
                   +  + ]
    1395                 :             : 
    1396                 :             : ! Compute the real space product, and return to k space, in FFT configuration
    1397                 :         160 : call gr_to_g(psikg_wrk,psir1,psikg_valence)
    1398                 :             : 
    1399                 :             : ! psikg_wrk contains | (V^1/2 . l)^* phi_v >, in FFT configuration
    1400                 :             : 
    1401                 :             : ! return to LA representation
    1402                 :         160 : call wf_block_distribute(psikb_wrk,  psikg_wrk,2) ! FFT -> LA
    1403                 :             : 
    1404                 :             : ! store data, in LA representation
    1405         [ +  + ]:         384 : do mb = 1, blocksize
    1406                 :         224 : l = (iblk_lanczos-1)*blocksize + mb
    1407                 :             : 
    1408         [ +  - ]:         384 : if ( l <= lmax) then
    1409                 :             :   ! local_Lbasis
    1410   [ +  +  +  + ]:       98912 :   psik_wrk(:,:)     = psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k)
    1411         [ +  + ]:       33120 :   local_Lbasis(:,l) = cmplx_1*psik_wrk(1,:)+cmplx_i*psik_wrk(2,:)
    1412                 :             : end if
    1413                 :             : 
    1414                 :             : end do !mb
    1415                 :             : 
    1416                 :             : !--------------------------------------------------------------------------
    1417                 :             : ! ii) Build the Sternheimer coefficients, at various frequencies,
    1418                 :             : !     to define the Sternheimer basis.
    1419                 :             : !--------------------------------------------------------------------------
    1420                 :         160 : write(io_unit_log,20) '          -- Compute Sternheimer RHS...'
    1421                 :         160 : flush(io_unit_log)
    1422                 :             : 
    1423                 :             : 
    1424                 :             : ! psikg_wrk still contains | (V^1/2 . l)^* phi_v >, in FFT configuration
    1425                 :             : 
    1426                 :             : !  Create right-hand-side of Sternheimer equation, in FFT configuration
    1427                 :         160 : call pc_k_valence_kernel(psikg_wrk)
    1428                 :         160 : call Hpsik(psikg_in,psikg_wrk,eig(v))
    1429                 :         160 : call pc_k_valence_kernel(psikg_in)
    1430   [ +  +  +  + ]:       98848 : psikg_in(:,:) = -psikg_in(:,:) ! IS THIS STACK-DANGEROUS?
    1431                 :             : 
    1432                 :             : ! return RHS  to LA representation, for explicit storage
    1433                 :         160 : call wf_block_distribute(psikb_wrk,  psikg_in,2) ! FFT -> LA
    1434                 :             : 
    1435                 :             : ! store data, in LA representation
    1436         [ +  + ]:         384 : do mb = 1, blocksize
    1437                 :         224 : l = (iblk_lanczos-1)*blocksize + mb
    1438                 :             : 
    1439         [ +  - ]:         384 : if ( l <= lmax) then
    1440                 :             :   ! psi_rhs
    1441   [ +  +  +  + ]:       98912 :   psi_rhs(:,:,l)    = psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k)
    1442                 :             : end if
    1443                 :             : 
    1444                 :             : end do !mb
    1445                 :             : 
    1446                 :             : !----------------------------------------------------------
    1447                 :             : ! iii) extract solutions for all projection frequencies
    1448                 :             : !----------------------------------------------------------
    1449                 :         160 : write(io_unit_log,20) '          -- Extract solutions for all projection frequencies...'
    1450                 :         160 : flush(io_unit_log)
    1451                 :             : 
    1452                 :             : 
    1453                 :             : 
    1454         [ -  + ]:         160 : do iw = 1, nfrequencies
    1455                 :             : 
    1456                 :           0 : omega0 = list_projection_frequencies(iw)
    1457                 :             : ! Solve Sternheimer equation
    1458                 :             : 
    1459                 :           0 : projection = 0
    1460         [ #  # ]:           0 : if(omega0 < 1d-12) projection=1
    1461                 :             : 
    1462                 :             : ! solve A x = b, over the whole lanczos block
    1463                 :           0 : call sqmr(psikg_in, psikg_out, eig(v), projection, omega0, omega_is_imaginary)
    1464                 :             : 
    1465                 :             : ! return LA representation, for explicit storage
    1466                 :           0 : call wf_block_distribute(psikb_wrk,  psikg_out, 2) ! FFT -> LA
    1467                 :             : 
    1468         [ -  - ]:         160 : do mb = 1, blocksize
    1469                 :           0 : l = (iblk_lanczos-1)*blocksize + mb
    1470                 :             : 
    1471         [ #  # ]:           0 : if ( l <= lmax) then
    1472                 :           0 :   ls = (l-1)*nfrequencies+iw
    1473                 :             : 
    1474   [ #  #  #  # ]:           0 :   psik_wrk(:,:)     = psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k)
    1475                 :             : 
    1476         [ #  # ]:           0 :   c_sternheimer_solutions(:,ls)= cmplx_1*psik_wrk(1,:)+cmplx_i*psik_wrk(2,:)
    1477                 :             : end if
    1478                 :             : 
    1479                 :             : end do ! mb
    1480                 :             : 
    1481                 :             : end do ! iw
    1482                 :             : 
    1483                 :             : !----------------------------------------------------------
    1484                 :             : ! iv) Compute the conjugated, projected modified basis
    1485                 :             : !----------------------------------------------------------
    1486                 :             : 
    1487                 :         160 : write(io_unit_log,20) '          -- compute the conjugated, projected modified basis...'
    1488                 :         160 : flush(io_unit_log)
    1489                 :             : 
    1490                 :             : 
    1491                 :             : 
    1492                 :             : 
    1493                 :             : ! Compute the real space product, | (V^1/2. l) phi_v^* > and return to k space, in FFT configuration
    1494                 :         160 : call gr_to_g(psikg_wrk, psir_valence, psikg_VL)
    1495                 :             : 
    1496                 :             : ! project on conduction states
    1497                 :         160 : call pc_k_valence_kernel(psikg_wrk)
    1498                 :             : 
    1499                 :             : ! return to LA representation
    1500                 :         160 : call wf_block_distribute(psikb_wrk,  psikg_wrk,2) ! FFT -> LA
    1501                 :             : 
    1502                 :             : ! store back, in LA configuration
    1503         [ +  + ]:         412 : do mb = 1, blocksize
    1504                 :         224 : l = (iblk_lanczos-1)*blocksize + mb
    1505                 :             : 
    1506         [ +  - ]:         384 : if ( l <= lmax) then
    1507   [ +  +  +  + ]:       98912 :   psik_wrk(:,:) = psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k)
    1508         [ +  + ]:       33120 :   local_Lbasis_conjugated(:,l) = cmplx_1*psik_wrk(1,:)+cmplx_i*psik_wrk(2,:)
    1509                 :             : end if
    1510                 :             : 
    1511                 :             : end do !mb
    1512                 :             : 
    1513                 :             : end do ! iblk_lanczos
    1514                 :             : 
    1515                 :             : 
    1516                 :             : 
    1517                 :          28 : write(io_unit_log,10) '   - Read in solutions at w=0 and/or w = infinity, if appropriate...'
    1518                 :          28 : flush(io_unit_log)
    1519                 :             : 
    1520                 :             : ! Begin with the storage of the solutions at $\omega = 0.$, which are free.
    1521         [ +  + ]:          28 : if(dtset%gwls_recycle == 1) then
    1522                 :             :   c_sternheimer_solutions(:,lsolutions_max-2*lmax+1:lsolutions_max-lmax) = cmplx_1*Sternheimer_solutions_zero(1,:,:,v) + &
    1523   [ +  +  +  + ]:        8368 :   &                                                                             cmplx_i*Sternheimer_solutions_zero(2,:,:,v)
    1524                 :             : end if
    1525         [ +  + ]:          28 : if(dtset%gwls_recycle == 2) then
    1526         [ +  + ]:         108 :   do i=1,lmax
    1527                 :          96 :   recy_i = (i-1)*nbandv + v
    1528                 :             :   !BUG : On petrus, NAG 5.3.1 + OpenMPI 1.6.2 cause read(...,rec=i) to read the data written by write(...,rec=i+1).
    1529                 :          96 :   read(recy_unit,rec=recy_i) psik_wrk
    1530         [ +  + ]:       24780 :   c_sternheimer_solutions(:,lsolutions_max-2*lmax+i) = cmplx_1*psik_wrk(1,:) + cmplx_i*psik_wrk(2,:)
    1531                 :             :   end do
    1532                 :             : end if
    1533                 :             : 
    1534                 :             : ! and then continue with the storage of the vectors on which the Sternheimer solutions will be projected.
    1535   [ +  +  +  + ]:       33148 : c_sternheimer_solutions(:,lsolutions_max-lmax+1:lsolutions_max) = cmplx_1*psi_rhs(1,:,:) + cmplx_i*psi_rhs(2,:,:)
    1536                 :             : ! Previously was = local_Lbasis; but analysis in the Lanczos article reveals psi_rhs should be better.
    1537                 :             : ! Furthermore, tests show that, with psi_rhs, silane@1Ha has Sigma_c 0.01mHa away from the result with
    1538                 :             : ! gwls_list_proj_freq 0.0 1.0, in contrast with local_Lbasis, which has Sigma_c 0.3mHa away from the same result.
    1539                 :             : 
    1540         [ +  + ]:          28 : if ( model ) then
    1541                 :             : 
    1542                 :          24 :   write(io_unit_log,10) '   - USE MODEL: model = .true., hence compute model model dielectric matrix...'
    1543                 :          24 :   flush(io_unit_log)
    1544                 :             : 
    1545                 :             : 
    1546                 :             : 
    1547                 :             :   !--------------------------------------------------------------------------
    1548                 :             :   ! Now that we have the modified basis, compute the matrix
    1549                 :             :   ! elements of the model dielectric operator
    1550                 :             :   !
    1551                 :             :   ! CAREFUL!
    1552                 :             :   !
    1553                 :             :   !        The model is given by
    1554                 :             :   !
    1555                 :             :   !                P_model(iw) = sum_{v} phi_v(r) P_c.Y(iw).P_c phi_v^*(r')
    1556                 :             :   !
    1557                 :             :   !    such that
    1558                 :             :   !
    1559                 :             :   !    <l1 | eps_model(iw) | l2 >  = delta_{l1,l2}
    1560                 :             :   !    - sum_{v} < (V^{1/2}.l1).phi_v^*| Pc . Y . Pc | (V^{1/2}.l2).phi_v^* >
    1561                 :             :   !
    1562                 :             :   ! But local_Lbasis defined above corresponds to
    1563                 :             :   !                                Pc | (V^{1/2} .l )^* phi_v >.
    1564                 :             :   !
    1565                 :             :   ! This is why we must define local_Lbasis_conjugated, of the form
    1566                 :             :   !                                Pc | (V^{1/2} .l ) phi_v^* >.
    1567                 :             :   !
    1568                 :             :   !--------------------------------------------------------------------------
    1569                 :             : 
    1570         [ +  + ]:         288 :   do iw = 1, npt_gauss+1
    1571                 :             : 
    1572                 :         264 :   call setup_Pk_model(list_omega(iw),second_model_parameter)
    1573                 :             : 
    1574                 :             :   ! Only build the lower triangular part; the upper triangular part is obtained from the Hermitian conjugate
    1575         [ +  + ]:        2400 :   do l1 = 1, lmax
    1576                 :             : 
    1577         [ +  + ]:      273504 :   YL(:) = model_Y_LA(:)*local_Lbasis_conjugated(:,l1)
    1578         [ +  + ]:       11880 :   do l2 = 1, l1
    1579                 :             :   model_dielectric_Lanczos_basis(l1,l2,iw) = model_dielectric_Lanczos_basis(l1,l2,iw)  &
    1580                 :       11616 :   -complex_vector_product(YL, local_Lbasis_conjugated(:,l2),npw_k)
    1581                 :             : 
    1582                 :             :   end do
    1583                 :             :   end do
    1584                 :             : 
    1585                 :             :   end do ! iw
    1586                 :             : 
    1587                 :             : 
    1588                 :             : end if
    1589                 :             : 
    1590                 :             : 
    1591                 :             : !--------------------------------------------------------------------------
    1592                 :             : ! Check explicitly that solutions satisfy the Sternheimer equations
    1593                 :             : !--------------------------------------------------------------------------
    1594                 :             : 
    1595         [ -  + ]:          28 : if ( debug ) then
    1596                 :             : 
    1597         [ #  # ]:           0 :   if (write_debug) then
    1598                 :           0 :     write(io_unit,10) "#--------------------------------------------------------------------------------"
    1599                 :           0 :     write(io_unit,10) "# Check explicitly that solutions satisfy the Sternheimer equation.              "
    1600                 :           0 :     write(io_unit,10) "#                                                                                "
    1601                 :           0 :     write(io_unit,10) "# Define:                                                                        "
    1602                 :           0 :     write(io_unit,10) "# E_l = || (omega^2+[H-Ev]^2) |phi_l> + Pc.[H-Ev].Pc |(V^1/2.q_l)^*.phi_v >  ||  "
    1603                 :           0 :     write(io_unit,10) "#--------------------------------------------------------------------------------"
    1604                 :           0 :     write(io_unit,10) '#  l                Im[omega] (Ha)                  E_l'
    1605                 :           0 :     write(io_unit,10) "#--------------------------------------------------------------------------------"
    1606                 :           0 :     flush(io_unit)
    1607                 :             :   end if
    1608                 :             : 
    1609                 :             : 
    1610         [ #  # ]:           0 :   do iblk_lanczos = 1, nbdblock_lanczos
    1611                 :             : 
    1612                 :             :   ! loop on all states within this block
    1613         [ #  # ]:           0 :   do mb = 1, blocksize
    1614                 :             : 
    1615                 :           0 :   l = (iblk_lanczos-1)*blocksize + mb
    1616                 :             : 
    1617                 :             : 
    1618         [ #  # ]:           0 :   if ( l <= lmax) then
    1619                 :             :     ! psik_wrk = | (V^{1/2} .l )^* phi_v >
    1620         [ #  # ]:           0 :     psik_wrk(1,:) = dble (local_Lbasis(:,l))
    1621         [ #  # ]:           0 :     psik_wrk(2,:) = dimag(local_Lbasis(:,l))
    1622                 :             :   else
    1623   [ #  #  #  # ]:           0 :     psik_wrk(:,:) = zero
    1624                 :             :   end if
    1625                 :             : 
    1626                 :             :   ! Store in array of blocks of wavefunctions
    1627   [ #  #  #  # ]:           0 :   psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k) = psik_wrk(:,:)
    1628                 :             :   end do ! mb
    1629                 :             : 
    1630                 :             :   ! Transform to FFT representation
    1631                 :           0 :   call wf_block_distribute(psikb_wrk,  psikg_wrk, 1) ! LA -> FFT
    1632                 :             : 
    1633                 :             :   !  Create right-hand-side of Sternheimer equation
    1634                 :           0 :   call pc_k_valence_kernel(psikg_wrk)
    1635                 :           0 :   call Hpsik(psikg_in,psikg_wrk,eig(v))
    1636                 :           0 :   call pc_k_valence_kernel(psikg_in)
    1637   [ #  #  #  # ]:           0 :   psikg_in(:,:)  = -psikg_in(:,:) ! IS THIS STACK-DANGEROUS?
    1638                 :             : 
    1639         [ #  # ]:           0 :   do iw = 1, nfrequencies
    1640                 :             :   ! loop on all states within this block
    1641         [ #  # ]:           0 :   do mb = 1, blocksize
    1642                 :             : 
    1643                 :           0 :   l = (iblk_lanczos-1)*blocksize + mb
    1644                 :             : 
    1645                 :           0 :   ls = (l-1)*nfrequencies+iw
    1646                 :             : 
    1647         [ #  # ]:           0 :   if ( l <= lmax) then
    1648         [ #  # ]:           0 :     psik_wrk(1,:) = dble (c_sternheimer_solutions(:,ls))
    1649         [ #  # ]:           0 :     psik_wrk(2,:) = dimag(c_sternheimer_solutions(:,ls))
    1650                 :             :   else
    1651   [ #  #  #  # ]:           0 :     psik_wrk(:,:) = zero
    1652                 :             :   end if
    1653                 :             : 
    1654                 :             :   ! Store in array of blocks of wavefunctions
    1655   [ #  #  #  # ]:           0 :   psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k) = psik_wrk(:,:)
    1656                 :             :   end do
    1657                 :             : 
    1658                 :             :   ! Transform to FFT representation
    1659                 :           0 :   call wf_block_distribute(psikb_wrk,  psikg_wrk, 1) ! LA -> FFT
    1660                 :             : 
    1661                 :             : 
    1662                 :           0 :   omega0 = list_projection_frequencies(iw)
    1663                 :             : 
    1664   [ #  #  #  # ]:           0 :   psikg_out(:,:) = omega0**2*psikg_wrk(:,:)
    1665                 :             : 
    1666                 :           0 :   call Hpsik(psikg_wrk,cte=eig(v))
    1667                 :           0 :   call Hpsik(psikg_wrk,cte=eig(v))
    1668                 :             : 
    1669                 :             : 
    1670   [ #  #  #  # ]:           0 :   psikg_out(:,:) = psikg_out(:,:) + psikg_wrk(:,:)-psikg_in(:,:)
    1671                 :             :   ! psikg_out now contains [ w0^2 + [H-epsilon_v]^2 ] | x > - |RHS>, in FFT configuration.
    1672                 :             : 
    1673                 :             :   ! bring it back to LA configuration
    1674                 :             : 
    1675                 :             :   ! Transform to FFT representation
    1676                 :           0 :   call wf_block_distribute(psikb_wrk,  psikg_out, 2) ! FFT -> LA
    1677                 :             : 
    1678         [ #  # ]:           0 :   do mb = 1, blocksize
    1679                 :           0 :   l = (iblk_lanczos-1)*blocksize + mb
    1680                 :             : 
    1681         [ #  # ]:           0 :   if ( l <= lmax) then
    1682   [ #  #  #  # ]:           0 :     psik_wrk(:,:) = psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k)
    1683                 :             : 
    1684                 :           0 :     z(:) = cg_zdotc(npw_k ,psik_wrk, psik_wrk)
    1685                 :             : 
    1686                 :           0 :     call xmpi_sum(z, mpi_communicator,ierr) ! sum on all processors working on FFT!
    1687         [ #  # ]:           0 :     if (write_debug) write(io_unit,21)  l, omega0, sqrt(z(1))
    1688                 :             :   end if
    1689                 :             :   end do ! mb
    1690                 :             : 
    1691                 :             :   end do ! iw
    1692                 :             :   end do ! iblk_lanczos
    1693                 :             : 
    1694                 :             : end if
    1695                 :             : 
    1696                 :             : !--------------------------------------------------------------------------
    1697                 :             : ! Step 5: Perform a singular value decomposition to extract a
    1698                 :             : !         linearly independent basis for the solution space.
    1699                 :             : !
    1700                 :             : !--------------------------------------------------------------------------
    1701                 :          28 : write(io_unit_log,10) '   - Perform SVD to extract linearly independent basis to Sternheimer equation...'
    1702                 :          28 : flush(io_unit_log)
    1703                 :             : 
    1704                 :             : 
    1705                 :             : 
    1706                 :             : 
    1707   [ +  +  +  + ]:       66268 : svd_matrix(:,:) =  c_sternheimer_solutions(:,:)
    1708                 :             : 
    1709                 :          28 : call extract_SVD(mpi_communicator, npw_k,lsolutions_max,svd_matrix,svd_values)
    1710                 :             : 
    1711         [ -  + ]:          28 : if ( write_debug ) then
    1712                 :           0 :   write(io_unit,10) "#--------------------------------------------------------------------------------"
    1713                 :           0 :   write(io_unit,10) "# Check the singular value decomposition of the arrays"
    1714                 :           0 :   write(io_unit,10) '#  l                          svd'
    1715                 :           0 :   write(io_unit,10) "#--------------------------------------------------------------------------------"
    1716                 :           0 :   flush(io_unit)
    1717                 :             : end if
    1718                 :             : 
    1719                 :          28 : lsolutions = 0
    1720   [ +  +  +  + ]:       66268 : QR_orthonormal_basis(:,:) = cmplx_0
    1721         [ +  + ]:         476 : do l=1, lsolutions_max
    1722         [ +  - ]:         476 : if (svd_values(l) > svd_tolerance ) then
    1723                 :         448 :   lsolutions = lsolutions + 1
    1724                 :             : 
    1725         [ -  + ]:         448 :   if ( write_debug ) then
    1726                 :           0 :     write(io_unit,14)   l,svd_values(l)
    1727                 :           0 :     flush(io_unit)
    1728                 :             :   end if
    1729         [ +  + ]:       66240 :   QR_orthonormal_basis(:,l) = svd_matrix(:,l)
    1730                 :             : 
    1731                 :             : else
    1732         [ #  # ]:           0 :   if ( write_debug ) then
    1733                 :           0 :     write(io_unit,15)   l,svd_values(l),' SVD value too small! Vector to be discarded!'
    1734                 :           0 :     flush(io_unit)
    1735                 :             :   end if
    1736                 :             : end if
    1737                 :             : end do
    1738                 :             : 
    1739                 :             : !--------------------------------------------------------------------------
    1740                 :             : ! Step 6: project all relevant arrays onto the newly defined orthonormal
    1741                 :             : !         basis.
    1742                 :             : !--------------------------------------------------------------------------
    1743                 :          28 : write(io_unit_log,10) '   - Compute the B matrix...'
    1744                 :          28 : flush(io_unit_log)
    1745                 :             : 
    1746         [ -  + ]:          28 : if (debug) then
    1747   [ #  #  #  # ]:           0 :   check_matrix(:,:) = cmplx_0
    1748         [ #  # ]:           0 :   do l = 1, lsolutions
    1749                 :           0 :   check_matrix(l,l) = -cmplx_1
    1750                 :             :   end do
    1751                 :             : end if
    1752                 :             : 
    1753   [ -  +  +  -  :          84 : ABI_MALLOC(ipiv                ,(lsolutions))
          +  -  +  -  -  
                +  -  + ]
    1754   [ -  +  +  -  :         112 : ABI_MALLOC(sternheimer_A0      ,(lsolutions,lsolutions))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1755   [ -  +  +  -  :         112 : ABI_MALLOC(sternheimer_B       ,(lsolutions,lmax))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1756   [ -  +  +  -  :         112 : ABI_MALLOC(sternheimer_G       ,(lmax,lsolutions))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1757                 :             : 
    1758                 :             : ! Compute the X matrix and the check_matrix
    1759         [ +  + ]:         476 : do l1 = 1, lsolutions
    1760                 :             : 
    1761         [ +  + ]:       66240 : psi_gamma_l1(1,:) = real (QR_orthonormal_basis(:,l1))
    1762         [ +  + ]:       66240 : psi_gamma_l1(2,:) = dimag(QR_orthonormal_basis(:,l1))
    1763                 :             : 
    1764         [ +  + ]:        7644 : do l2 = 1, lsolutions
    1765                 :             : 
    1766         [ +  + ]:        7168 : if (l2 <= lmax) then
    1767                 :        3584 :   z(:) = cg_zdotc(npw_k, psi_gamma_l1,  psi_rhs(:,:,l2))
    1768                 :        3584 :   call xmpi_sum(z, mpi_communicator,ierr) ! sum on all processors for LA configuration
    1769                 :             : 
    1770                 :        3584 :   sternheimer_B(l1,l2) = cmplx_1*z(1)+cmplx_i*z(2)
    1771                 :             : end if
    1772                 :             : 
    1773         [ -  + ]:        7616 : if (debug)  then
    1774         [ #  # ]:           0 :   psi_gamma_l2(1,:) = dble (QR_orthonormal_basis(:,l2))
    1775         [ #  # ]:           0 :   psi_gamma_l2(2,:) = dimag(QR_orthonormal_basis(:,l2))
    1776                 :             : 
    1777                 :           0 :   z(:) = cg_zdotc(npw_k, psi_gamma_l1,  psi_gamma_l2)
    1778                 :           0 :   call xmpi_sum(z, mpi_communicator,ierr) ! sum on all processors
    1779                 :             : 
    1780                 :           0 :   check_matrix(l1,l2) = check_matrix(l1,l2) + cmplx_1*z(1)+cmplx_i*z(2)
    1781                 :             : end if
    1782                 :             : 
    1783                 :             : end do ! l2
    1784                 :             : end do ! l1
    1785                 :             : 
    1786                 :             : 
    1787                 :             : ! Number of blocks of solution vectors
    1788                 :          28 : nbdblock_solutions = lsolutions/blocksize
    1789                 :             : 
    1790         [ -  + ]:          28 : if (modulo(lsolutions,blocksize) /= 0) nbdblock_solutions = nbdblock_solutions + 1
    1791                 :             : 
    1792                 :             : 
    1793                 :          28 : write(io_unit_log,10) '   - Compute the A0 matrix...'
    1794                 :          28 : flush(io_unit_log)
    1795                 :             : 
    1796                 :             : ! Compute the A matrix
    1797         [ +  + ]:         348 : do iblk_solutions =1, nbdblock_solutions
    1798                 :             : 
    1799         [ +  + ]:         768 : do mb = 1, blocksize
    1800                 :         448 : l2 = (iblk_solutions-1)*blocksize + mb
    1801                 :             : 
    1802         [ +  - ]:         448 : if ( l2 <= lsolutions) then
    1803         [ +  + ]:       66240 :   psik_wrk(1,:) = dble (QR_orthonormal_basis(:,l2))
    1804         [ +  + ]:       66240 :   psik_wrk(2,:) = dimag(QR_orthonormal_basis(:,l2))
    1805                 :             : else
    1806   [ #  #  #  # ]:           0 :   psik_wrk(:,:) =  zero
    1807                 :             : end if
    1808                 :             : 
    1809                 :             : ! Store in array of blocks of wavefunctions
    1810   [ +  +  +  + ]:      198144 : psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k) = psik_wrk(:,:)
    1811                 :             : end do
    1812                 :             : 
    1813                 :             : ! Transform to FFT representation
    1814                 :         320 : call wf_block_distribute(psikb_wrk,  psikg_wrk,1) ! LA -> FFT
    1815                 :             : 
    1816                 :             : ! act twice with the Hamiltonian operator
    1817                 :         320 : call Hpsik(psikg_out,psikg_wrk,eig(v))
    1818                 :         320 : call Hpsik(psikg_out,cte=eig(v))
    1819                 :             : 
    1820                 :             : ! return to LA representation
    1821                 :         320 : call wf_block_distribute(psikb_wrk,  psikg_out,2) ! FFT -> LA
    1822                 :             : 
    1823         [ +  + ]:         796 : do mb = 1, blocksize
    1824                 :         448 : l2 = (iblk_solutions-1)*blocksize + mb
    1825                 :             : 
    1826         [ +  - ]:         448 : if ( l2 <= lsolutions) then
    1827   [ +  +  +  + ]:      197824 :   psik_wrk(:,:)     = psikb_wrk(:,(mb-1)*npw_k+1:mb*npw_k)
    1828                 :             : else
    1829   [ #  #  #  # ]:           0 :   psik_wrk(:,:)     = zero
    1830                 :             : end if
    1831                 :             : 
    1832         [ +  + ]:        7936 : do l1 = 1, lsolutions
    1833                 :             : 
    1834         [ +  + ]:     1059840 : psi_gamma_l1(1,:) = real (QR_orthonormal_basis(:,l1))
    1835         [ +  + ]:     1059840 : psi_gamma_l1(2,:) = dimag(QR_orthonormal_basis(:,l1))
    1836                 :             : 
    1837                 :        7168 : z(:) = cg_zdotc(npw_k, psi_gamma_l1,  psik_wrk)
    1838                 :        7168 : call xmpi_sum(z,mpi_communicator,ierr) ! sum on all processors working on FFT!
    1839                 :             : 
    1840                 :             : 
    1841         [ +  - ]:        7616 : if ( l2 <= lsolutions ) then
    1842                 :        7168 :   sternheimer_A0(l1,l2) = cmplx_1*z(1)+cmplx_i*z(2)
    1843                 :             : end if
    1844                 :             : 
    1845                 :             : 
    1846                 :             : end do ! l1
    1847                 :             : end do ! mb
    1848                 :             : end do ! iblk_solutions
    1849                 :             : 
    1850                 :             : 
    1851         [ -  + ]:          28 : if (debug) then
    1852                 :             :   ! HERE we use a dummy variable to avoid operations which might blow the stack!
    1853                 :             :   ! Stack overflows lead to hard-to-find bugs; let's avoid putting them in here.
    1854   [ #  #  #  #  :           0 :   ABI_MALLOC(dummy_tmp_1,(lsolutions,lsolutions))
          #  #  #  #  #  
                #  #  # ]
    1855   [ #  #  #  #  :           0 :   ABI_MALLOC(dummy_tmp_2,(lsolutions,lsolutions))
          #  #  #  #  #  
                #  #  # ]
    1856                 :             : 
    1857                 :             : 
    1858   [ #  #  #  # ]:           0 :   dummy_tmp_1(:,:)= transpose(sternheimer_A0(:,:))
    1859   [ #  #  #  # ]:           0 :   dummy_tmp_2(:,:)= conjg(dummy_tmp_1(:,:))
    1860                 :             : 
    1861   [ #  #  #  # ]:           0 :   check_matrix2(:,:) = sternheimer_A0(:,:)-dummy_tmp_2(:,:)
    1862                 :             : 
    1863         [ #  # ]:           0 :   ABI_FREE(dummy_tmp_1)
    1864         [ #  # ]:           0 :   ABI_FREE(dummy_tmp_2)
    1865                 :             : end if
    1866                 :             : 
    1867                 :          28 : write(io_unit_log,10) '   - Compute the GAMMA matrix...'
    1868                 :          28 : flush(io_unit_log)
    1869                 :             : 
    1870                 :             : 
    1871                 :             : ! Compute the GAMMA matrices
    1872         [ +  + ]:         252 : do l1 = 1, lmax
    1873                 :             : 
    1874                 :             : ! psik_wrk = | (V^{1/2} . l )^* phi_v >
    1875         [ +  + ]:       33120 : psik_wrk(1,:) = dble (local_Lbasis(:,l1) )
    1876         [ +  + ]:       33120 : psik_wrk(2,:) = dimag(local_Lbasis(:,l1))
    1877                 :             : 
    1878                 :             : 
    1879         [ +  + ]:        3836 : do l2 = 1, lsolutions
    1880                 :             : 
    1881         [ +  + ]:      529920 : psi_gamma_l2(1,:) = real (QR_orthonormal_basis(:,l2))
    1882         [ +  + ]:      529920 : psi_gamma_l2(2,:) = dimag(QR_orthonormal_basis(:,l2))
    1883                 :             : 
    1884                 :             : 
    1885                 :             : ! Note that G_{lJ} = < l | Vc^{1/2}.(gamma_J^*.phi_v)>
    1886                 :             : !                  = < gamma_J | (Vc^{1/2}.l^*).phi_v >
    1887                 :             : 
    1888                 :        3584 : z(:) = cg_zdotc(npw_k,psi_gamma_l2, psik_wrk)
    1889                 :        3584 : call xmpi_sum(z,mpi_communicator,ierr) ! sum on all processors working on FFT!
    1890                 :        3808 : sternheimer_G(l1,l2) = cmplx_1*z(1)+cmplx_i*z(2)
    1891                 :             : 
    1892                 :             : end do ! l1
    1893                 :             : end do ! l2
    1894                 :             : 
    1895                 :             : 
    1896                 :             : 
    1897         [ -  + ]:          28 : if ( write_debug ) then
    1898   [ #  #  #  # ]:           0 :   write(io_unit,19)   '<gamma| gamma>', sqrt(sum(abs(check_matrix(:,:))**2))
    1899   [ #  #  #  # ]:           0 :   write(io_unit,19)   '  M hermitian ',sqrt(sum(abs(check_matrix2(:,:))**2))
    1900                 :           0 :   write(io_unit,10)   " "
    1901                 :           0 :   write(io_unit,10)   "# GAMMA Matrix:"
    1902                 :           0 :   write(io_unit,10)   " "
    1903                 :             : 
    1904         [ #  # ]:           0 :   do l1 = 1, lmax
    1905                 :           0 :   write(io_unit,30) sternheimer_G(l1,:)
    1906                 :             :   end do
    1907                 :           0 :   flush(io_unit)
    1908                 :             : end if
    1909                 :             : 
    1910                 :             : !--------------------------------------------------------------------------
    1911                 :             : ! Step 7: Compute the solutions
    1912                 :             : !--------------------------------------------------------------------------
    1913                 :             : 
    1914                 :          28 : write(io_unit_log,10) '   - Compute the Projected Sternheimer solutions and build approximate dielectric operator...'
    1915                 :          28 : flush(io_unit_log)
    1916                 :             : 
    1917                 :             : 
    1918                 :             : 
    1919   [ -  +  +  -  :          84 : ABI_MALLOC(sternheimer_A ,(lsolutions,lsolutions))
          -  +  +  -  -  
                +  -  + ]
    1920   [ -  +  +  -  :          84 : ABI_MALLOC(sternheimer_X       ,(lsolutions,lmax))
          -  +  +  -  -  
                +  -  + ]
    1921         [ +  + ]:         308 : do iw = 2, npt_gauss + 1
    1922                 :             : 
    1923                 :         280 : write(io_unit_log,23) '        -- iw = ',iw,' / ',npt_gauss+1
    1924                 :         280 : flush(io_unit_log)
    1925                 :             : 
    1926                 :             : 
    1927                 :         280 : omega = list_omega(iw)
    1928                 :             : 
    1929   [ +  +  +  + ]:       76440 : sternheimer_A(:,:) = sternheimer_A0(:,:)
    1930                 :             : 
    1931         [ +  + ]:        4760 : do l = 1, lsolutions
    1932                 :        4760 : sternheimer_A(l,l) = sternheimer_A(l,l) + omega**2
    1933                 :             : end do
    1934                 :             : 
    1935   [ +  +  +  + ]:       38360 : sternheimer_X(:,:) = sternheimer_B(:,:)
    1936                 :             : 
    1937                 :             : !--------------------------------------------------------------------------
    1938                 :             : ! Step 2:  solve A*X = B, a projected form of the Sternheimer equation
    1939                 :             : !--------------------------------------------------------------------------
    1940                 :         280 : write(io_unit_log,10) '        -- Solve A*X = B'
    1941                 :         280 : flush(io_unit_log)
    1942                 :             : 
    1943                 :             : 
    1944                 :             : 
    1945                 :         280 : call cpu_time(time1)
    1946                 :             : call zgesv(lsolutions,      & ! number of rows of A matrix
    1947                 :             : lmax,            & ! number of columns of B matrix
    1948                 :             : sternheimer_A,   & ! The A matrix on input, the LU factorization on output
    1949                 :             : lsolutions,      & ! leading dimension of A
    1950                 :             : ipiv,            & ! array of pivots
    1951                 :             : sternheimer_X,   & ! B matrix on input, solution X on output
    1952                 :             : lsolutions,      & ! leading dimension of B
    1953                 :         280 : info )
    1954                 :         280 : call cpu_time(time2)
    1955                 :             : 
    1956                 :         280 : time_exact = time_exact + time2-time1
    1957                 :             : 
    1958                 :             : !--------------------------------------------------------------------------
    1959                 :             : ! Step 3: Add contribution to projected epsilon
    1960                 :             : !--------------------------------------------------------------------------
    1961                 :             : ! perform E = E  -4 sum_l Gamma_v*X^*_v
    1962                 :             : 
    1963                 :         280 : write(io_unit_log,10) '        -- add contribution to dielectric matrix at this frequency'
    1964                 :         280 : flush(io_unit_log)
    1965                 :             : 
    1966                 :             : 
    1967                 :             : 
    1968   [ -  +  +  -  :        1120 : ABI_MALLOC(dummy_tmp_1,(lsolutions,lmax))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    1969   [ +  +  +  + ]:       38360 : dummy_tmp_1(:,:) = conjg(sternheimer_X) ! DO THIS to avoid potential stack problems
    1970                 :             : 
    1971                 :         280 : call cpu_time(time1)
    1972                 :             : call zgemm(     'N',    & ! A matrix is in normal order
    1973                 :             : 'N',    & ! B matrix is in normal order
    1974                 :             : lmax,    & ! number of rows of A
    1975                 :             : lmax,    & ! number of columns of B
    1976                 :             : lsolutions,    & ! number of columns of A
    1977                 :             : -4.0_dp*cmplx_1,    & ! premultiply A*B by this scalar
    1978                 :             : sternheimer_G,    & ! GAMMA matrix
    1979                 :             : lmax,    & ! leading dimension of A
    1980                 :             : dummy_tmp_1,    & ! B matrix
    1981                 :             : lsolutions,    & ! leading dimension of B
    1982                 :             : cmplx_1,    & ! beta  is one
    1983                 :             : projected_dielectric_Lanczos_basis(:,:,iw),    & ! C matrix
    1984                 :         280 : lmax)      ! leading dimension of C
    1985                 :             : 
    1986         [ -  + ]:         280 : ABI_FREE(dummy_tmp_1)
    1987                 :             : 
    1988                 :         280 : call cpu_time(time2)
    1989                 :         308 : time_exact = time_exact + time2-time1
    1990                 :             : 
    1991                 :             : end do ! iw
    1992                 :             : 
    1993                 :          28 : write(io_unit_log,10) '   - Deallocate tmp arrays...'
    1994                 :          28 : flush(io_unit_log)
    1995                 :             : 
    1996                 :             : 
    1997                 :             : 
    1998                 :             : 
    1999         [ -  + ]:          28 : ABI_FREE(ipiv           )
    2000         [ -  + ]:          28 : ABI_FREE(sternheimer_A  )
    2001         [ -  + ]:          28 : ABI_FREE(sternheimer_A0 )
    2002         [ -  + ]:          28 : ABI_FREE(sternheimer_B  )
    2003         [ -  + ]:          28 : ABI_FREE(sternheimer_X  )
    2004         [ -  + ]:          35 : ABI_FREE(sternheimer_G  )
    2005                 :             : 
    2006                 :             : end do ! v
    2007                 :             : 
    2008                 :             : !--------------------------------------------------------------------------
    2009                 :             : ! Finalize, post v loop
    2010                 :             : !--------------------------------------------------------------------------
    2011                 :           7 : write(io_unit_log,10) " - Finalize, after band iterations...."
    2012                 :           7 : flush(io_unit_log)
    2013                 :             : 
    2014                 :             : 
    2015                 :             : 
    2016                 :             : 
    2017                 :             : 
    2018                 :           7 : timing_string = "#        Exact Sector :   "
    2019                 :           7 : call write_timing_log(timing_string,time_exact)
    2020                 :             : 
    2021                 :             : 
    2022   [ -  +  +  -  :          28 : ABI_MALLOC(dummy_tmp_1,(lmax,lmax))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    2023   [ -  +  +  -  :          21 : ABI_MALLOC(dummy_tmp_2,(lmax,lmax))
          -  +  +  -  -  
                +  -  + ]
    2024                 :             : 
    2025         [ +  + ]:          77 : do iw = 2, npt_gauss+1
    2026                 :             : ! finally, make sure matrix is hermitian
    2027                 :             : 
    2028                 :             : ! play this little game to avoid STACK problems
    2029   [ +  +  +  + ]:        5110 : dummy_tmp_1(:,:) = 0.5_dp*transpose(projected_dielectric_Lanczos_basis(:,:,iw))
    2030   [ +  +  +  + ]:        5110 : dummy_tmp_2(:,:) = conjg(dummy_tmp_1(:,:))
    2031   [ +  +  +  + ]:        5110 : dummy_tmp_1(:,:) = dummy_tmp_2(:,:) +0.5_dp*projected_dielectric_Lanczos_basis(:,:,iw)
    2032                 :             : 
    2033   [ +  +  +  + ]:        5117 : projected_dielectric_Lanczos_basis(:,:,iw) =    dummy_tmp_1(:,:)
    2034                 :             : end do
    2035                 :             : 
    2036         [ -  + ]:           7 : ABI_FREE(dummy_tmp_1)
    2037         [ -  + ]:           7 : ABI_FREE(dummy_tmp_2)
    2038                 :             : 
    2039                 :             : 
    2040                 :             : 
    2041         [ -  + ]:           7 : if ( write_debug ) then
    2042                 :             :   !write some results to a file
    2043                 :             : 
    2044                 :           0 :   write(io_unit,10) '#===================================================================================================='
    2045                 :           0 :   write(io_unit,10) "#                     Projected dielectric matrices                                                  "
    2046                 :           0 :   write(io_unit,10) "#                     -------------------------------------------------------                        "
    2047                 :           0 :   write(io_unit,10) "# This file contains the various projected dielectric matrices as a function of frequency.           "
    2048                 :           0 :   write(io_unit,10) '#===================================================================================================='
    2049                 :           0 :   write(io_unit,10) ''
    2050                 :           0 :   flush(io_unit)
    2051                 :             : 
    2052         [ #  # ]:           0 :   do iw = 1, npt_gauss+1
    2053                 :           0 :   write(io_unit,10) "#"
    2054                 :           0 :   write(io_unit,12) "# omega = ",list_omega(iw), " i Ha"
    2055                 :           0 :   write(io_unit,10) "#"
    2056                 :             : 
    2057         [ #  # ]:           0 :   do l =1, lmax
    2058                 :           0 :   write(io_unit,30)  projected_dielectric_Lanczos_basis(l,:,iw)
    2059                 :             :   end do
    2060                 :             :   end do
    2061                 :             : 
    2062                 :             : end if
    2063                 :             : 
    2064                 :             : 
    2065         [ +  + ]:           7 : if ( model ) then
    2066                 :             : 
    2067                 :             : 
    2068                 :             :   ! Add all components on the processors
    2069                 :           6 :   call xmpi_sum(model_dielectric_Lanczos_basis,mpi_communicator,ierr) ! sum on all processors
    2070                 :             : 
    2071                 :             :   ! add the identity
    2072         [ +  + ]:          72 :   do iw = 1, npt_gauss+1
    2073         [ +  + ]:         600 :   do l= 1, lmax
    2074                 :         594 :   model_dielectric_Lanczos_basis(l,l,iw) = model_dielectric_Lanczos_basis(l,l,iw) + cmplx_1
    2075                 :             :   end do
    2076                 :             :   end do
    2077                 :             : 
    2078                 :             :   ! hermitian the operator
    2079         [ +  + ]:          72 :   do iw = 1, npt_gauss+1
    2080                 :             : 
    2081         [ +  + ]:         600 :   do l1 = 1, lmax
    2082         [ +  + ]:        2970 :   do l2 = 1, l1
    2083                 :             :   ! operator is hermitian
    2084                 :        2904 :   model_dielectric_Lanczos_basis(l2,l1,iw) = conjg(model_dielectric_Lanczos_basis(l1,l2,iw))
    2085                 :             :   end do
    2086                 :             :   end do
    2087                 :             : 
    2088                 :             :   end do ! iw
    2089                 :             : 
    2090                 :             : end if
    2091                 :             : 
    2092                 :             : 
    2093                 :             : 
    2094         [ -  + ]:           7 : if ( write_debug ) then
    2095                 :           0 :   close(io_unit)
    2096                 :             : end if
    2097                 :             : 
    2098                 :           7 : write(io_unit_log,10) " - Deallocate and exit...."
    2099                 :           7 : flush(io_unit_log)
    2100                 :             : 
    2101                 :             : 
    2102                 :             : 
    2103         [ -  + ]:           7 : if (debug) then
    2104         [ #  # ]:           0 :   ABI_FREE(check_matrix)
    2105         [ #  # ]:           0 :   ABI_FREE(check_matrix2)
    2106                 :             : end if
    2107                 :             : 
    2108                 :             : 
    2109         [ -  + ]:           7 : ABI_FREE(psikg_valence)
    2110         [ -  + ]:           7 : ABI_FREE(psir_valence)
    2111         [ -  + ]:           7 : ABI_FREE(psikg_VL)
    2112                 :             : 
    2113                 :             : 
    2114         [ -  + ]:           7 : ABI_FREE(YL)
    2115                 :             : 
    2116         [ -  + ]:           7 : ABI_FREE(local_Lbasis_conjugated)
    2117         [ -  + ]:           7 : ABI_FREE(local_Lbasis)
    2118                 :             : 
    2119                 :             : 
    2120         [ -  + ]:           7 : ABI_FREE(svd_matrix)
    2121         [ -  + ]:           7 : ABI_FREE(svd_values)
    2122         [ -  + ]:           7 : ABI_FREE(psi_gamma_l1)
    2123         [ -  + ]:           7 : ABI_FREE(psi_gamma_l2)
    2124                 :             : 
    2125         [ -  + ]:           7 : ABI_FREE(psikg_in)
    2126         [ -  + ]:           7 : ABI_FREE(psikg_out)
    2127                 :             : 
    2128         [ -  + ]:           7 : ABI_FREE(psi_rhs)
    2129                 :             : 
    2130         [ -  + ]:           7 : ABI_FREE(c_sternheimer_solutions)
    2131         [ -  + ]:           7 : ABI_FREE(QR_orthonormal_basis)
    2132                 :             : 
    2133         [ -  + ]:           7 : ABI_FREE(psik_wrk)
    2134         [ -  + ]:           7 : ABI_FREE(psikb_wrk)
    2135         [ -  + ]:           7 : ABI_FREE(psikg_wrk)
    2136                 :             : 
    2137                 :             : 
    2138                 :           7 : close(io_unit_log)
    2139                 :             : 
    2140                 :             : 
    2141                 :             : 10 format(A)
    2142                 :             : 12 format(A,F12.8,A)
    2143                 :             : 14 format(I5,10X,ES24.12)
    2144                 :             : 15 format(I5,10X,ES24.12,10X,A)
    2145                 :             : 
    2146                 :             : 19 format(20X,A,15X,E24.16)
    2147                 :             : 
    2148                 :             : 20 format(A,I5)
    2149                 :             : 21 format(I5,10X,F8.4,15X,ES24.12)
    2150                 :             : 22 format(A,I5,A)
    2151                 :             : 23 format(A,I5,A,I5)
    2152                 :             : 30 format(2X,1000(ES12.4,2X,ES12.4,5X))
    2153                 :             : 
    2154   [ -  +  -  + ]:           7 : end subroutine ProjectedSternheimerEpsilon
    2155                 :             : !!***
    2156                 :             : 
    2157                 :             : 
    2158                 :             : end module m_gwls_DielectricArray
    2159                 :             : !!***
        

Generated by: LCOV version 2.3-1