LCOV - code coverage report
Current view: top level - src/70_gw - m_gwls_lineqsolver.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 78.6 % 360 283
Test Date: 2026-09-21 19:39:32 Functions: 100.0 % 2 2

            Line data    Source code
       1              : !!****m* ABINIT/m_gwls_lineqsolver
       2              : !! NAME
       3              : !! m_gwls_lineqsolver
       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              : 
      24              : !---------------------------------------------------------------------
      25              : !  Module to solve A.x = b efficiently, where A will involve
      26              : !  the Hamiltonian.
      27              : !---------------------------------------------------------------------
      28              : 
      29              : 
      30              : module m_gwls_lineqsolver
      31              : !----------------------------------------------------------------------------------------------------
      32              : ! This module contains routines to solve A x = b interatively to solve the Sternheimer equation
      33              : ! in various contexts...
      34              : !----------------------------------------------------------------------------------------------------
      35              : 
      36              : 
      37              : ! local modules
      38              : use m_gwls_utility
      39              : use m_gwls_wf
      40              : use m_gwls_hamiltonian
      41              : 
      42              : ! abinit modules
      43              : use defs_basis
      44              : use m_abicore
      45              : use m_xmpi
      46              : use m_bandfft_kpt
      47              : use m_cgtools
      48              : 
      49              : use m_time,      only : timab
      50              : use m_io_tools,  only : get_unit
      51              : 
      52              : implicit none
      53              : save
      54              : private
      55              : !!***
      56              : 
      57              : logical :: activate_inf_shift_poles = .false.
      58              : real(dp) :: inf_shift_poles = 1.0d-4
      59              : !!***
      60              : 
      61              : public :: sqmr, qmr, activate_inf_shift_poles, inf_shift_poles
      62              : !!***
      63              : 
      64              : contains
      65              : 
      66              : !!****f* m_hamiltonian/sqmr
      67              : !! NAME
      68              : !!  sqmr
      69              : !!
      70              : !! FUNCTION
      71              : !!  .
      72              : !!
      73              : !! INPUTS
      74              : !!
      75              : !! OUTPUT
      76              : !!
      77              : !! SOURCE
      78              : 
      79         1840 : subroutine sqmr(b,x,lambda,project_on_what,omega,omega_imaginary,kill_Pc_x)
      80              : !--------------------------------------------------------------------------------
      81              : ! This subroutine solves the linear algebra problem
      82              : !
      83              : !                                 A x = b
      84              : !
      85              : ! Where:
      86              : !                INPUT
      87              : !                -----
      88              : !        real(dp) b                          right-hand-side of the equation to be solved
      89              : !     real(dp) omega                         *OPTIONAL* frequency used in building A
      90              : !     logical  omega_imaginary               *OPTIONAL* is the frequency imaginary?
      91              : !     real(dp) lambda                        value to be subtracted from the Hamiltonian
      92              : !     integer  project_on_what               flag which determines the projection scheme.
      93              : !
      94              : !                OUTPUT
      95              : !                -----
      96              : !        real(dp) x                          solution
      97              : !
      98              : !    Note that blocksize corresponds to the number of band processors; it is a global
      99              : !    variable defined in gwls_hamiltonian. The name is inspired from lobpcgwf.F90.
     100              : !
     101              : ! with:
     102              : !        omega     omega_imaginary      Operator
     103              : !        ------------------------------------------------------
     104              : !     absent          -            A =   (H - lambda)
     105              : !     present         -            A =   (H - lambda)^2 - omega^2
     106              : !     present    present, true     A =   (H - lambda)^2 + omega^2
     107              : !
     108              : !        project_on_what                        action
     109              : !        ------------------------------------------------------
     110              : !                0                no projection
     111              : !                1                projection on conduction states
     112              : !                2                projection out of subspace degenerate with lambda
     113              : !                3                projection on states beyond all the states explicitly stored
     114              : !
     115              : ! NOTE: It is the developper's responsibility to apply (H-ev) on the input
     116              : !       if the frequency is not zero.
     117              : !--------------------------------------------------------------------------------
     118              : 
     119              : !External variables
     120              : real(dp), intent(in)  :: b(2,npw_g)
     121              : real(dp), intent(in)  :: lambda
     122              : real(dp), intent(out) :: x(2,npw_g)
     123              : integer, intent(in)   :: project_on_what
     124              : real(dp), intent(in), optional :: omega
     125              : logical, optional     :: omega_imaginary, kill_Pc_x
     126              : 
     127              : !Local variables
     128              : real(dp) :: norm, tmp(2), residual
     129         1840 : real(dp), allocatable :: g(:), theta(:), rho(:), sigma(:), c(:)
     130         1840 : real(dp), allocatable :: t(:,:), delta(:,:), r(:,:), d(:,:), w(:,:), wmb(:,:)
     131              : integer :: ii,ipw, k, l
     132              : real(dp):: signe
     133              : real(dp):: norm_Axb
     134              : 
     135              : 
     136              : real(dp):: norm_b, tol14
     137              : 
     138              : integer :: min_index
     139              : logical :: singular
     140              : logical :: precondition_on
     141              : logical :: has_omega
     142              : 
     143              : integer :: pow
     144              : 
     145              : logical :: imaginary
     146              : 
     147              : integer,save :: counter = 0
     148              : integer      :: io_unit
     149              : character(128) :: filename
     150              : logical        :: file_exists
     151              : logical        :: head_node
     152              : 
     153              : integer      :: ierr
     154              : 
     155              : integer      :: mpi_communicator, mpi_rank, mpi_group
     156              : 
     157              : 
     158              : 
     159              : ! timing
     160              : real(dp) :: tsec(2)
     161              : integer :: GWLS_TIMAB, OPTION_TIMAB
     162              : 
     163              : ! *************************************************************************
     164              : 
     165              : ! The processors communicate over FFT!
     166         1840 : mpi_communicator = mpi_enreg%comm_fft
     167              : 
     168              : ! what is the rank of this processor, within its group?
     169         1840 : mpi_rank  = mpi_enreg%me_fft
     170              : 
     171              : ! Which group does this processor belong to, given the communicator?
     172         1840 : mpi_group = mpi_enreg%me_band
     173              : 
     174              : ! Do we have omega?
     175         1840 : has_omega=present(omega)
     176              : 
     177              : ! Test if the input has finite norm
     178         1840 : tol14 = 1.0D-14
     179         1840 : tmp  = cg_zdotc(npw_g,b,b)
     180         1840 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
     181         1840 : norm_b = tmp(1)
     182              : 
     183         1840 : if (norm_b < tol14) then
     184              :   ! Because of band parallelism, it is possible that sqmr gets a zero norm argument.
     185              :   ! A | x>  = 0 implies |x > = 0.
     186       667248 :   x(:,:) = zero
     187              :   return
     188              : end if
     189              : 
     190          736 : GWLS_TIMAB   = 1523
     191          736 : OPTION_TIMAB = 1
     192          736 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     193              : 
     194              : ! only the head node should write to the log file
     195          736 : head_node = ( mpi_rank == 0 )
     196              : 
     197              : !Memory allocation for local variables
     198         2208 : ABI_MALLOC(g,    (nline))
     199         1472 : ABI_MALLOC(theta,(nline))
     200         1472 : ABI_MALLOC(rho,  (nline))
     201         1472 : ABI_MALLOC(sigma,(nline))
     202         1472 : ABI_MALLOC(c,    (nline))
     203              : 
     204         2208 : ABI_MALLOC(t,    (2,npw_g))
     205         1472 : ABI_MALLOC(delta,(2,npw_g))
     206         1472 : ABI_MALLOC(r,    (2,npw_g))
     207         1472 : ABI_MALLOC(d,    (2,npw_g))
     208         1472 : ABI_MALLOC(w,    (2,npw_g))
     209         1472 : ABI_MALLOC(wmb,  (2,npw_g))
     210              : 
     211              : 
     212              : 
     213              : !Some vectors won't be filled (first iteration missing) so it's useful to initialise them.
     214        74336 : g        = zero
     215        74336 : theta    = zero
     216        74336 : rho      = zero
     217        74336 : sigma    = zero
     218        74336 : c        = zero
     219       444832 : x        = zero
     220       444832 : delta    = zero
     221       444832 : r        = zero
     222       444832 : d        = zero
     223       444832 : w        = zero
     224              : 
     225              : 
     226              : ! Determine if the frequency is imaginary
     227          736 : if (has_omega .and. present(omega_imaginary)) then
     228            0 :   imaginary = omega_imaginary
     229              : else
     230              :   imaginary = .false.
     231              : end if
     232              : 
     233              : 
     234              : ! Define the sign in front of (H-eig(v))**2.
     235              : ! If omega_imaginary is not given, we assume that omega is real (and sign=-1).
     236          736 : if (has_omega) then
     237            0 :   if ( imaginary ) then
     238              :     signe = one
     239              :   else
     240            0 :     signe =-one
     241              :   end if
     242              : end if
     243              : 
     244              : 
     245              : !Check for singularity problems
     246              : if (has_omega) then
     247            0 :   norm      = minval(abs((eig(1:nbandv)-lambda)**2 + signe*(omega)**2))
     248            0 :   min_index = minloc(abs((eig(1:nbandv)-lambda)**2 + signe*(omega)**2),1)
     249              : else
     250         4416 :   norm      = minval(abs(eig(1:nbandv)-lambda))
     251         3680 :   min_index = minloc(abs(eig(1:nbandv)-lambda),1)
     252              : end if
     253          736 : singular = norm < 1.0d-12
     254              : 
     255              : !--------------------------------------------------------------------------------
     256              : ! If the linear operator has a kernel, then the intermediate vectors obtained in
     257              : ! SQMR must be projected out of this subspace several time at each iterations,
     258              : ! otherwise SQMR is unstable.
     259              : !
     260              : ! This is true even if the seed vector has been initially projected out of this
     261              : ! subspace, since the preconditionning will re-introduce a non-zero component in
     262              : ! the subspace of the kernel of the linear operator.
     263              : !                 ===>   Use project_on_what==2 in such cases.
     264              : !
     265              : ! Here, test if the operator is singular and if we are NOT projecting out of
     266              : ! the kernel.
     267              : !                ===>   If true, stop the code.
     268              : !
     269              : !--------------------------------------------------------------------------------
     270              : 
     271              : ! Quit if the operator has an uncontrolled kernel, a sign that the routine is being
     272              : ! misused by a developper...
     273          736 : if (singular .and. ( (project_on_what==1 .and. (min_index > nbandv)) .or. project_on_what==0 ))  then
     274            0 :   write(std_out,*) "ERROR - SQMR: Quasi-singuar problem treated, min. eigenvalue of A is ", norm," < 1d-12."
     275            0 :   write(std_out,*) "              Yet, there is no projection out of the kernel of A.                      "
     276              : 
     277            0 :   if (project_on_what==1 .and. (min_index > nbandv)) then
     278            0 :     write(std_out,*) " "
     279            0 :     write(std_out,*) "              There is a projection on the conduction states, but A is singular in this "
     280            0 :     write(std_out,*) "              subspace (the kernel contains state i=",min_index," > ",nbandv,"=# of valence states)."
     281              :   end if
     282              : 
     283            0 :   write(std_out,*) " "
     284            0 :   write(std_out,*) "              In this situation, SQMR will be unstable. Use project_on_what==2 as an   "
     285            0 :   write(std_out,*) "              input argument of SQMR."
     286            0 :   write(std_out,*) " "
     287            0 :   write(std_out,*) "                                      Decision taken to exit..."
     288            0 :   stop
     289              : end if
     290              : 
     291              : !--------------------------------------------------------------------------------
     292              : ! Open a log file for the output of SQMR; only write if head of group!
     293              : !--------------------------------------------------------------------------------
     294          736 : if (head_node) then
     295              : 
     296          576 :   io_unit  = get_unit()
     297              : 
     298          576 :   write(filename,'(A,I0.4,A)') "SQMR_GROUP=",mpi_group,".log"
     299              : 
     300          576 :   inquire(file=filename,exist=file_exists)
     301              : 
     302          576 :   if (file_exists) then
     303          573 :     open( io_unit,file=filename,position='append',status=files_status_old)
     304              :   else
     305            3 :     open( io_unit,file=filename,status=files_status_new)
     306            3 :     write(io_unit,10) "#======================================================================================="
     307            3 :     write(io_unit,10) "#                                                                                       "
     308            3 :     write(io_unit,10) "#   This file contains information regarding the application of the SQMR scheme,        "
     309            3 :     write(io_unit,10) "#   for this MPI group.                                                                 "
     310            3 :     write(io_unit,10) "#======================================================================================="
     311            3 :     flush(io_unit)
     312              :   end if
     313              : 
     314          576 :   counter = counter + 1
     315          576 :   write(io_unit,10) "#                                                                                       "
     316          576 :   write(io_unit,11) "#   Call # ", counter
     317          576 :   write(io_unit,12) "#                 lambda = ",lambda," Ha                                                "
     318          576 :   if (has_omega) then
     319            0 :     write(io_unit,12) "#                 omega  = ",omega," Ha                                          "
     320            0 :     if (imaginary) then
     321            0 :       write(io_unit,10) "#                 omega is imaginary                                             "
     322              :     else
     323            0 :       write(io_unit,10) "#                 omega is real                                                  "
     324              :     end if
     325              :   else
     326          576 :     write(io_unit,10) "#                 omega is absent                                                 "
     327              :   end if
     328              : 
     329          576 :   write(io_unit,13) "#        project_on_what = ",project_on_what,"                                                 "
     330          576 :   write(io_unit,13) "#                                                                                               "
     331          576 :   if (has_omega ) then
     332            0 :     if (imaginary) then
     333            0 :       write(io_unit,10) "#                SOLVE ((H-lambda)^2 + omega^2) x = b"
     334              :     else
     335            0 :       write(io_unit,10) "#                SOLVE ((H-lambda)^2 - omega^2) x = b"
     336              :     end if
     337              :   else
     338          576 :     write(io_unit,10) "#                SOLVE  (H-lambda) x = b"
     339              :   end if
     340              : 
     341          576 :   flush(io_unit)
     342              : end if ! head_node
     343              : !--------------------------------------------------------------------------------
     344              : ! Precondition to accelerate convergence
     345              : !--------------------------------------------------------------------------------
     346          736 : precondition_on = .true.
     347          736 : if(imaginary) then
     348            0 :   if(omega > 10.0_dp) then
     349              :     precondition_on = .false.
     350              :   end if
     351              : end if
     352              : 
     353              : ! DEBUG
     354          736 : pow             = project_on_what
     355              : !precondition_on = .false.
     356              : 
     357              : !Prepare to precondition
     358              : if (precondition_on) then
     359          736 :   if ( imaginary ) then
     360            0 :     call set_precondition(lambda,omega)
     361              :   else
     362          736 :     call set_precondition()
     363              :   end if
     364              : else
     365            0 :   call unset_precondition()
     366              : end if
     367              : 
     368              : !--------------------------------------------------------------------------------
     369              : !Initialisation
     370              : !--------------------------------------------------------------------------------
     371              : 
     372          736 : k = 1
     373          736 : l = 1
     374              : 
     375       148768 : do ipw=1,npw_g
     376       444832 :   do ii=1,2
     377       444096 :     r(ii,ipw) = b(ii,ipw)
     378              :   end do
     379              : end do
     380              : 
     381          736 : if (head_node) then
     382          576 :   write(io_unit,10) "# "
     383          576 :   write(io_unit,10) "# iteration          approximate residual"
     384          576 :   write(io_unit,10) "#----------------------------------------"
     385          576 :   flush(io_unit)
     386              : end if
     387              : 
     388              : do ! outer loop
     389          736 : call precondition(d,r)
     390              : 
     391              : ! g(k)   = norm_k(r)
     392          736 : tmp    = cg_zdotc(npw_g,r,r)
     393          736 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
     394          736 : g(k)   = dsqrt(tmp(1))
     395              : 
     396              : 
     397              : !tmp    = scprod_k(r,d)
     398          736 : tmp    = cg_zdotc(npw_g,r,d)
     399          736 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
     400          736 : rho(k) = tmp(1)
     401              : 
     402          736 : if (head_node)  then
     403          576 :   write(io_unit,16) k, g(k)**2
     404          576 :   flush(io_unit)
     405              : end if
     406              : 
     407              : do ! inner loop
     408        16285 : k=k+1
     409        16285 : l=l+1
     410              : 
     411              : ! Apply the A operator
     412        16285 : if (has_omega) then
     413            0 :   call Hpsik(w,d,lambda)
     414            0 :   call Hpsik(w,cte=lambda)
     415            0 :   do ipw=1,npw_g
     416            0 :     do ii=1,2
     417            0 :       w(ii,ipw) = w(ii,ipw) + d(ii,ipw)*signe*omega**2
     418              :     end do
     419              :   end do
     420              : else
     421        16285 :   call Hpsik(w,d,lambda)
     422              : end if
     423              : 
     424              : ! Apply projections, if requested
     425              : !if(dtset%gwcalctyp /= 2) then !This is a test to obtain the time taken by the orthos.
     426        16285 : if(pow == 1) call pc_k_valence_kernel(w)
     427              : !if(pow == 2) call pc_k(w,eig_e=lambda)
     428              : !if(pow == 3) call pc_k(w,n=nband,above=.true.)
     429              : !end if
     430              : 
     431              : ! Apply SQMR scheme
     432              : !tmp        = scprod_k(d,w)
     433        16285 : tmp    = cg_zdotc(npw_g,d,w)
     434        16285 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
     435              : 
     436        16285 : sigma(k-1) = tmp(1)
     437      3274274 : do ipw=1,npw_g
     438      9790252 :   do ii=1,2
     439      9773967 :     r(ii,ipw) = r(ii,ipw)-(rho(k-1)/sigma(k-1))*w(ii,ipw)
     440              :   end do
     441              : end do
     442              : 
     443              : ! The following two lines must have a bug! We cannot distribute the norm this way!
     444              : ! theta(k)   = norm_k(r)/g(k-1)
     445              : ! call xmpi_sum(theta(k), mpi_communicator,ierr) ! sum on all processors working on FFT!
     446        16285 : tmp    = cg_zdotc(npw_g,r,r)
     447        16285 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
     448        16285 : theta(k)   = dsqrt(tmp(1))/g(k-1)
     449              : 
     450        16285 : c(k)       = one/dsqrt(one+theta(k)**2)
     451        16285 : g(k)       = g(k-1)*theta(k)*c(k)
     452      3274274 : do ipw=1,npw_g
     453      9790252 :   do ii=1,2
     454      6515978 :     delta(ii,ipw) = delta(ii,ipw)*(c(k)*theta(k-1))**2+d(ii,ipw)*rho(k-1)/sigma(k-1)*c(k)**2
     455      9773967 :     x(ii,ipw) = x(ii,ipw)+delta(ii,ipw)
     456              :   end do
     457              : end do
     458              : 
     459        16285 : if (head_node) then
     460        12677 :   write(io_unit,16) k, g(k)**2
     461        12677 :   flush(io_unit)
     462              : end if
     463              : 
     464              : ! Test exit condition
     465        16285 : if(g(k)**2<tolwfr .or. k>= nline) exit
     466              : !if(k>=nline) exit
     467              : 
     468              : ! Safety test every 100 iterations, check that estimated residual is of the right order of magnitude.
     469              : ! If not, restart SQMR.
     470        15549 : if(mod(l,100)==0) then
     471            0 :   if(has_omega) then
     472            0 :     call Hpsik(w,x,lambda)
     473            0 :     call Hpsik(w,cte=lambda)
     474            0 :     do ipw=1,npw_g
     475            0 :       do ii=1,2
     476            0 :         w(ii,ipw) = w(ii,ipw) + x(ii,ipw)*signe*omega**2
     477              :       end do
     478              :     end do
     479              :   else
     480            0 :     call Hpsik(w,x,lambda)
     481              :   end if
     482              : 
     483            0 :   if(pow == 1) call pc_k_valence_kernel(w)
     484              :   !if(pow == 2) call pc_k(w,eig_e=lambda)
     485              :   !if(pow == 3) call pc_k(w,n=nband,above=.true.)
     486              : 
     487              :   !if(norm_k(w-b)**2 > 10*g(k)**2) exit
     488            0 :   do ipw=1,npw_g
     489            0 :     do ii=1,2
     490            0 :       wmb(ii,ipw) = w(ii,ipw) - b(ii,ipw)
     491              :     end do
     492              :   end do
     493            0 :   tmp   = cg_zdotc(npw_g,wmb,wmb)
     494            0 :   call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
     495            0 :   if(tmp(1) > 10*g(k)**2) exit
     496              : 
     497              : end if
     498              : 
     499              : ! Get ready for next cycle
     500        15549 : call precondition(w,r)
     501              : !if(dtset%gwcalctyp /= 2) then
     502        15549 : if(pow == 1) call pc_k_valence_kernel(w)
     503              : !if(pow == 2) call pc_k(w,eig_e=lambda)
     504              : !if(pow == 3) call pc_k(w,n=nband,above=.true.)
     505              : !end if
     506              : 
     507              : !tmp    = scprod_k(r,w)
     508        15549 : tmp   = cg_zdotc(npw_g,r,w)
     509        15549 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
     510        15549 : rho(k) = tmp(1)
     511              : 
     512      3126242 : do ipw=1,npw_g
     513      9345420 :   do ii=1,2
     514      9329871 :     d(ii,ipw) = w(ii,ipw)+d(ii,ipw)*rho(k)/rho(k-1)
     515              :   end do
     516              : end do
     517              : 
     518              : end do ! end inner loop
     519              : 
     520              : ! Exit condition
     521          736 : if(g(k)**2<tolwfr .or. k>=nline) exit
     522              : !if(k>=nline) exit
     523              : 
     524            0 : if (head_node) write(io_unit,10) "  ----     RESTART of SQMR -----"
     525              : 
     526              : !norm_Axb = norm_k(w-b)**2
     527            0 : do ipw=1,npw_g
     528            0 :   do ii=1,2
     529            0 :     wmb(ii,ipw) = w(ii,ipw) - b(ii,ipw)
     530              :   end do
     531              : end do
     532            0 : tmp  = cg_zdotc(npw_g,wmb,wmb)
     533            0 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
     534            0 : norm_Axb = tmp(1)
     535              : 
     536            0 : if (head_node) then
     537            0 :   write(io_unit,*) "|Ax-b|^2 :",norm_Axb
     538            0 :   write(io_unit,*) "g(k)^2 :",g(k)**2
     539            0 :   flush(io_unit)
     540              : end if
     541              : 
     542            0 : k = k+1
     543            0 : l = 1
     544              : 
     545              : ! Apply the operator
     546            0 : if(has_omega) then
     547            0 :   call Hpsik(r,x,lambda)
     548            0 :   call Hpsik(r,cte=lambda)
     549            0 :   do ipw=1,npw_g
     550            0 :     do ii=1,2
     551            0 :       r(ii,ipw) = r(ii,ipw) + x(ii,ipw)*signe*omega**2
     552              :     end do
     553              :   end do
     554              : else
     555            0 :   call Hpsik(r,x,lambda)
     556              : end if
     557              : 
     558            0 : if(pow == 1) call pc_k_valence_kernel(r)
     559              : !if(pow == 2) call pc_k(r,eig_e=lambda)
     560              : !if(pow == 3) call pc_k(r,n=nband,above=.true.)
     561              : 
     562          736 : do ipw=1,npw_g
     563            0 :   do ii=1,2
     564            0 :     r(ii,ipw) = b(ii,ipw) - r(ii,ipw)
     565              :   end do
     566              : end do
     567              : 
     568              : end do ! outer loop
     569              : 
     570              : 
     571          736 : ktot = ktot+k
     572          736 : if(k >= nline .and. head_node ) then
     573            0 :   write(io_unit,10) " **** Iterations were not enough to converge!  ****"
     574              : end if
     575              : 
     576          736 : if( present(kill_Pc_x) ) then
     577            0 :   if (.not. kill_Pc_x .and. pow == 1) call pc_k_valence_kernel(x)
     578              : end if
     579              : 
     580          736 : if( .not. present(kill_Pc_x) .and. pow == 1 ) call pc_k_valence_kernel(x)
     581              : 
     582              : 
     583              : 
     584              : 
     585              : !if(pow == 2) call pc_k(x,eig_e=lambda)
     586              : !if(pow == 3) call pc_k(x,n=nband,above=.true.)
     587              : 
     588          736 : if(has_omega) then
     589            0 :   call Hpsik(w,x,lambda)
     590            0 :   call Hpsik(w,cte=lambda)
     591            0 :   do ipw=1,npw_g
     592            0 :     do ii=1,2
     593            0 :       w(ii,ipw) = w(ii,ipw) + x(ii,ipw)*signe*omega**2
     594              :     end do
     595              :   end do
     596              : else
     597          736 :   call Hpsik(w,x,lambda)
     598              : end if
     599          736 : if(pow == 1) call pc_k_valence_kernel(w)
     600              : !if(pow == 2) call pc_k(w,eig_e=lambda)
     601              : !if(pow == 3) call pc_k(w,n=nband,above=.true.)
     602              : 
     603              : !residual = norm_k(w-b)**2
     604       148768 : do ipw=1,npw_g
     605       444832 :   do ii=1,2
     606       444096 :     wmb(ii,ipw) = w(ii,ipw) - b(ii,ipw)
     607              :   end do
     608              : end do
     609          736 : tmp      = cg_zdotc(npw_g,wmb,wmb)
     610          736 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
     611          736 : residual = tmp(1)
     612              : 
     613          736 : if (head_node) then
     614          576 :   write(io_unit,15) "iterations            :", k
     615          576 :   write(io_unit,14) "tolwfr                :", tolwfr
     616          576 :   write(io_unit,14) "residuals (estimated) :", g(k)**2
     617          576 :   write(io_unit,14) "residuals : |Ax-b|^2  :", residual
     618          576 :   close(io_unit)
     619              : end if
     620              : 
     621              : 
     622              : 
     623          736 : ABI_FREE(g)
     624          736 : ABI_FREE(theta)
     625          736 : ABI_FREE(rho)
     626          736 : ABI_FREE(sigma)
     627          736 : ABI_FREE(c)
     628          736 : ABI_FREE(t)
     629          736 : ABI_FREE(delta)
     630          736 : ABI_FREE(r)
     631          736 : ABI_FREE(d)
     632          736 : ABI_FREE(w)
     633          736 : ABI_FREE(wmb)
     634              : 
     635              : 
     636          736 : OPTION_TIMAB = 2
     637          736 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
     638              : 
     639              : 
     640              : 
     641              : 10 format(A)
     642              : 11 format(A,I8)
     643              : 12 format(A,E24.16,A)
     644              : 13 format(A,I2,A)
     645              : 14 format(20X,A,E24.16)
     646              : 15 format(20X,A,I8)
     647              : 16 format(5X,I5,15X,E12.3)
     648              : 
     649              : end subroutine sqmr
     650              : !!***
     651              : 
     652              : !!****f* m_hamiltonian/qmr
     653              : !! NAME
     654              : !!  qmr
     655              : !!
     656              : !! FUNCTION
     657              : !!  .
     658              : !!
     659              : !! INPUTS
     660              : !!
     661              : !! OUTPUT
     662              : !!
     663              : !! SOURCE
     664              : 
     665          320 : subroutine qmr(b,x,lambda) !,project_on_what)
     666              : !--------------------------------------------------------------------------------
     667              : ! This subroutine solves the linear algebra problem
     668              : !
     669              : !                                 A x = b
     670              : !
     671              : ! where A :=  (H - lambda)  can be non-hermitian.
     672              : ! Thus, complex values of lambda are allowed and
     673              : ! non-hermitian operators could be handled instead of H.
     674              : !
     675              : ! Arguments :
     676              : !                INPUT
     677              : !                -----
     678              : !        real(dp) b(2,npw_k)                right-hand-side of the equation to be solved
     679              : !     real(dp) lambda(2)                value to be subtracted from the Hamiltonian (complex).
     680              : !     integer  project_on_what        flag which determines the projection scheme.
     681              : !
     682              : !                OUTPUT
     683              : !                -----
     684              : !        real(dp) x(2,npw_k)                solution
     685              : !
     686              : !        project_on_what                        action
     687              : !        ------------------------------------------------------
     688              : !                0                no projection
     689              : !                1                projection on conduction states
     690              : !                2                projection out of subspace degenerate with lambda
     691              : !                3                projection on states beyond all the states explicitly stored
     692              : !--------------------------------------------------------------------------------
     693              : 
     694              : !External variables
     695              : real(dp), intent(in)  :: b(2,npw_k)
     696              : real(dp), intent(in)  :: lambda(2)
     697              : real(dp), intent(out) :: x(2,npw_k)
     698              : !integer, intent(in)   :: project_on_what !Unused yet, no projections done.
     699              : 
     700              : !Local variables
     701          320 : complex(dp), allocatable :: xc(:), r(:), v(:), w(:), z(:), p(:), q(:), y(:), t(:), d(:), s(:)
     702          320 : complex(dp), allocatable :: beta(:), eta(:), delta(:), epsilonn(:)
     703              : complex(dp) :: lambdac
     704          320 : real(dp), allocatable :: rho(:), zeta(:), gama(:), theta(:), resid(:)
     705              : integer :: i
     706              : integer :: ierr
     707              : 
     708              : integer :: mpi_communicator
     709              : !logical :: precondition_on
     710              : 
     711              : ! *************************************************************************
     712              : 
     713       247040 : if(sum(b**2) < tol12) then
     714       148224 :   x=zero
     715              : else
     716              : 
     717              :   !Allocation
     718          384 :   ABI_MALLOC(xc,(npw_k))
     719          256 :   ABI_MALLOC(r ,(npw_k))
     720          256 :   ABI_MALLOC(v ,(npw_k))
     721          256 :   ABI_MALLOC(w ,(npw_k))
     722          256 :   ABI_MALLOC(z ,(npw_k))
     723          256 :   ABI_MALLOC(p ,(npw_k))
     724          256 :   ABI_MALLOC(q ,(npw_k))
     725          256 :   ABI_MALLOC(y ,(npw_k))
     726          256 :   ABI_MALLOC(t ,(npw_k))
     727          256 :   ABI_MALLOC(d ,(npw_k))
     728          256 :   ABI_MALLOC(s ,(npw_k))
     729              : 
     730          384 :   ABI_MALLOC(beta    ,(nline))
     731          384 :   ABI_MALLOC(rho     ,(nline+1))
     732          256 :   ABI_MALLOC(zeta    ,(nline+1))
     733          256 :   ABI_MALLOC(gama    ,(nline+1))
     734          384 :   ABI_MALLOC(eta     ,(nline+1))
     735          256 :   ABI_MALLOC(theta   ,(nline+1))
     736          256 :   ABI_MALLOC(delta   ,(nline))
     737          256 :   ABI_MALLOC(epsilonn,(nline))
     738          256 :   ABI_MALLOC(resid   ,(nline+1))
     739              : 
     740              :   !Initialization
     741        98816 :   x  = zero
     742        33024 :   xc = zero
     743        33024 :   r  = zero
     744        33024 :   v  = zero
     745        33024 :   w  = zero
     746        33024 :   z  = zero
     747        33024 :   p  = zero
     748        33024 :   q  = zero
     749        33024 :   y  = zero
     750        33024 :   t  = zero
     751        33024 :   d  = zero
     752        33024 :   s  = zero
     753              : 
     754        12928 :   beta     = zero
     755        13056 :   rho      = zero
     756        13056 :   zeta     = zero
     757        13056 :   gama     = zero
     758        13056 :   eta      = zero
     759        13056 :   theta    = zero
     760        12928 :   delta    = zero
     761        12928 :   epsilonn = zero
     762        13056 :   resid    = zero
     763              : 
     764          128 :   call unset_precondition()
     765              : 
     766              : 
     767              :   !mpi_communicator = mpi_enreg%comm_fft
     768          128 :   mpi_communicator = mpi_enreg%comm_bandfft
     769              : 
     770          128 :   lambdac  = dcmplx(lambda(1),lambda(2))
     771              : 
     772          128 :   i = 1
     773        33152 :   r = dcmplx(b(1,:),b(2,:))
     774        33152 :   v = r
     775              : 
     776          128 :   rho(i) = norm_kc(v)
     777          128 :   call xmpi_sum(rho(i),mpi_communicator ,ierr) ! sum on all processors working on FFT!
     778              : 
     779        33152 :   w = r
     780          128 :   call precondition_cplx(z,w)
     781          128 :   zeta(i) = norm_kc(z)
     782          128 :   call xmpi_sum(zeta(i),mpi_communicator,ierr) ! sum on all processors working on FFT!
     783              : 
     784          128 :   gama(i) = one
     785          128 :   eta(i) = -one
     786              :   !theta(i) = zero
     787              :   !p = zero
     788              :   !q = zero
     789              : 
     790         3612 :   do i=1,nline
     791       931896 :   v = v/rho(i)
     792       931896 :   w = w/zeta(i)
     793       931896 :   z = z/zeta(i)
     794         3612 :   delta(i) = scprod_kc(z,v)
     795         3612 :   call xmpi_sum(delta(i),mpi_communicator,ierr) ! sum on all processors working on FFT!
     796              : 
     797         3612 :   call precondition_cplx(y,v)
     798         3612 :   if(i/=1) then
     799       902356 :     p = y - (zeta(i)*delta(i)/epsilonn(i-1))*p
     800       902356 :     q = z - ( rho(i)*delta(i)/epsilonn(i-1))*q
     801              :   else
     802        33152 :     p = y
     803        33152 :     q = z
     804              :   end if
     805         3612 :   call Hpsikc(t,p,lambdac)
     806         3612 :   epsilonn(i) = scprod_kc(q,t)
     807         3612 :   call xmpi_sum(epsilonn(i),mpi_communicator,ierr) ! sum on all processors working on FFT!
     808              : 
     809         3612 :   beta(i) = epsilonn(i)/delta(i)
     810       935508 :   v = t - beta(i)*v
     811         3612 :   rho(i+1) = norm_kc(v)
     812         3612 :   call xmpi_sum(rho(i+1),mpi_communicator,ierr) ! sum on all processors working on FFT!
     813              : 
     814       935508 :   call Hpsikc(z,q,conjg(lambdac)) ; w = z - beta(i)*w
     815         3612 :   call precondition_cplx(z,w)
     816         3612 :   zeta(i+1) = norm_kc(z)
     817         3612 :   call xmpi_sum(zeta(i+1), mpi_communicator,ierr) ! sum on all processors working on FFT!
     818              : 
     819         3612 :   theta(i+1) = rho(i+1)/(gama(i)*abs(beta(i)))
     820         3612 :   gama(i+1) = 1./sqrt(1+theta(i+1)**2)
     821         3612 :   eta(i+1) = -eta(i)*rho(i)*gama(i+1)**2/(beta(i)*gama(i)**2)
     822       935508 :   d = eta(i+1)*p + ((theta(i)*gama(i+1))**2)*d
     823       935508 :   s = eta(i+1)*t + ((theta(i)*gama(i+1))**2)*s
     824       935508 :   xc = xc + d
     825       935508 :   r = r - s
     826         3612 :   resid(i) = norm_kc(r)**2
     827         3612 :   call xmpi_sum(resid(i), mpi_communicator,ierr) ! sum on all processors working on FFT!
     828              : 
     829              :   !write(std_out,*) "QMR residual**2 = ",resid(i),"; i = ",i-1
     830        18060 :   if(resid(i) < tolwfr) exit
     831              :   end do
     832              : 
     833          128 :   if(i>=nline) then
     834            0 :     write(std_out,*) " **** Iterations were not enough to converge!  ****"
     835              :   end if
     836              : 
     837          128 :   call Hpsikc(r,xc,lambdac)
     838        33152 :   v = dcmplx(b(1,:),b(2,:))
     839        33024 :   resid(nline+1) = norm_kc(r - v)**2
     840          128 :   call xmpi_sum(resid(nline+1),  mpi_communicator,ierr) ! sum on all processors working on FFT!
     841              : 
     842          128 :   write(std_out,*) "QMR residual**2 (at end) = ",resid(nline+1),"; # iterations = ",i-1
     843              : 
     844        33024 :   x(1,:) = dble(xc)
     845        33024 :   x(2,:) = dimag(xc)
     846              : 
     847              :   !Deallocate
     848          128 :   ABI_FREE(xc)
     849          128 :   ABI_FREE(r)
     850          128 :   ABI_FREE(v)
     851          128 :   ABI_FREE(w)
     852          128 :   ABI_FREE(z)
     853          128 :   ABI_FREE(p)
     854          128 :   ABI_FREE(q)
     855          128 :   ABI_FREE(y)
     856          128 :   ABI_FREE(t)
     857          128 :   ABI_FREE(d)
     858          128 :   ABI_FREE(s)
     859              : 
     860          128 :   ABI_FREE(beta    )
     861          128 :   ABI_FREE(rho     )
     862          128 :   ABI_FREE(zeta    )
     863          128 :   ABI_FREE(gama    )
     864          128 :   ABI_FREE(eta     )
     865          128 :   ABI_FREE(theta   )
     866          128 :   ABI_FREE(delta   )
     867          128 :   ABI_FREE(epsilonn)
     868          512 :   ABI_FREE(resid   )
     869              : 
     870              : end if
     871              : 
     872          320 : end subroutine qmr
     873              : !!***
     874              : 
     875              : end module m_gwls_lineqsolver
     876              : !!***
        

Generated by: LCOV version 2.3-1