LCOV - code coverage report
Current view: top level - src/68_recursion - m_vtorhorec.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 68.4 % 1030 705
Test Date: 2026-09-19 17:42:43 Functions: 78.6 % 14 11

            Line data    Source code
       1              : !!****m* ABINIT/m_vtorhorec
       2              : !! NAME
       3              : !!  m_vtorhorec
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 2008-2026 ABINIT group (SLeroux, MMancini).
       9              : !!  This file is distributed under the terms of the
      10              : !!  GNU General Public License, see ~abinit/COPYING
      11              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      12              : !!
      13              : !! SOURCE
      14              : 
      15              : #if defined HAVE_CONFIG_H
      16              : #include "config.h"
      17              : #endif
      18              : 
      19              : #include "abi_common.h"
      20              : 
      21              : module m_vtorhorec
      22              : 
      23              :  use defs_basis
      24              :  use defs_rectypes
      25              :  use m_xmpi
      26              :  use m_pretty_rec
      27              :  use m_errors
      28              :  use m_abicore
      29              :  use m_per_cond
      30              :  use m_dtset
      31              : 
      32              :  use defs_datatypes,     only : pseudopotential_type
      33              :  use defs_abitypes,      only : MPI_type
      34              :  use m_time,             only : timein, timab
      35              :  use m_rec,              only : Calcnrec, init_nlpsprec, cpu_distribution
      36              :  use m_rec_tools,        only : reshape_pot, trottersum, get_pt0_pt1
      37              :  use m_spacepar,         only : symrhg
      38              :  use m_fourier_interpol, only : transgrid
      39              :  use m_fft,              only : fourdp
      40              : 
      41              : #ifdef HAVE_GPU_CUDA
      42              :  use m_gpu_toolbox
      43              :  use m_hidecudarec
      44              :  use m_xredistribute
      45              : #endif
      46              : 
      47              :  implicit none
      48              : 
      49              :  private
      50              : !!***
      51              : 
      52              :  public :: vtorhorec
      53              :  public :: first_rec
      54              : !!***
      55              : 
      56              : contains
      57              : !!***
      58              : 
      59              : !!****f* ABINIT/vtorhorec
      60              : !! NAME
      61              : !! vtorhorec
      62              : !!
      63              : !! FUNCTION
      64              : !! This routine computes the new density from a fixed potential (vtrial)
      65              : !! using a recursion method
      66              : !!
      67              : !! INPUTS
      68              : !!  deltastep= if 0 the iteration step is equal to dtset%nstep
      69              : !!  initialized= if 0 the initialization of the gstate run is not yet finished
      70              : !!  operator (ground-state symmetries)
      71              : !!  dtset <type(dataset_type)>=all input variables for this dataset
      72              : !!  irrzon(nfft**(1-1/nsym),2,(nspden/nsppol)-3*(nspden/4))=irreducible zone data
      73              : !!  nfftf=(effective) number of FFT grid points (for this processor)
      74              : !!  nspden=number of spin-density components
      75              : !!  nsppol=1 for unpolarized, 2 for spin-polarized
      76              : !!  nsym=number of symmetry elements in space group
      77              : !!  phnons(2,nfft**(1-1/nsym),(nspden/nsppol)-3*(nspden/4))=nonsymmorphic translation phases
      78              : !!  vtrial(nfft,nspden)=INPUT Vtrial(r).
      79              : !!  rset <type(recursion_type)> all variables for recursion
      80              : !!  rprimd(3,3)=dimensional primitive translations in real space (bohr)
      81              : !!  gprimd(3,3)=dimensional primitive translations in reciprocal space
      82              : !!
      83              : !! OUTPUT
      84              : !!  ek=kinetic energy part of total energy.
      85              : !!  enlx=nonlocal psp + potential Fock ACE part of total energy.
      86              : !!  entropy=entropy due to the occupation number smearing (if metal)
      87              : !!  e_eigenvalues=Sum of the eigenvalues - Band energy (Hartree)
      88              : !!  fermie=fermi energy (Hartree)
      89              : !!  grnl(3*natom)=stores grads of nonlocal energy wrt length scales
      90              : !!   (3x3 tensor) and grads wrt atomic coordinates (3*natom)
      91              : !!
      92              : !! SIDE EFFECTS
      93              : !!  rhog(2,nfft)=array for Fourier transform of electron density
      94              : !!  rhor(nfft,nspden)=array for electron density in electrons/bohr**3.
      95              : !!  rset%efermi= fermi energy
      96              : !!
      97              : !! NOTES
      98              : !!  at this time :
      99              : !!       - grnl in not implemented
     100              : !!       - symetrie usage not implemented (irrzon not used and nsym should be 1)
     101              : !!       - spin-polarized not implemented (nsppol must be 1, nspden ?)
     102              : !!       - phnons used only in symrhg
     103              : !!       - need a rectangular box (ngfft(1)=ngfft(2)=ngfft(3))
     104              : !!
     105              : !! SOURCE
     106              : 
     107           38 : subroutine vtorhorec(dtset,&
     108              : &  ek,enlx,entropy,e_eigenvalues,fermie,&
     109           76 : &  grnl,initialized,irrzon,nfftf,phnons,&
     110           76 : &  rhog, rhor, vtrial,rset,deltastep,rprimd,gprimd)
     111              : 
     112              : !Arguments -------------------------------
     113              : !scalars
     114              :  integer,intent(in) :: initialized
     115              :  integer,intent(in) :: nfftf,deltastep
     116              :  real(dp),intent(out) :: e_eigenvalues,ek,enlx,entropy,fermie
     117              :  type(dataset_type),intent(in) :: dtset
     118              :  type(recursion_type),intent(inout) :: rset
     119              : !arrays
     120              :  integer, intent(in) :: irrzon(:,:,:)
     121              :  real(dp),intent(in) :: rprimd(3,3),gprimd(3,3)
     122              :  real(dp),intent(in) :: phnons(:,:,:)
     123              :  real(dp),intent(in) :: vtrial(:,:)
     124              :  real(dp),intent(inout) :: rhog(:,:)
     125              :  real(dp),intent(out) :: grnl(:)  !vz_i
     126              :  real(dp),intent(inout) :: rhor(:,:) !vz_i
     127              : 
     128              : !Local variables-------------------------------
     129              : !scalars
     130              :  integer :: nfftrec, dim_entro,ii1,jj1,kk1
     131              :  integer :: ierr,ii,ilmn,ipsp,dim_trott
     132              :  integer :: ipoint,ipointlocal,jj,kk,irec
     133              :  integer :: n1,n2,n3,n4,n_pt_integ_entropy
     134              :  integer :: nrec,iatom,min_pt,max_pt,swt_tm
     135              :  integer ::  get_K_S_G
     136              :  integer :: tim_fourdp,trotter
     137              :  real(dp),parameter :: perc_vmin=one
     138              :  real(dp) :: beta,drho,drhomax
     139              :  real(dp) :: entropy1,entropy2,entropy3,entropy4
     140              :  real(dp) :: entropylocal,entropylocal1,entropylocal2
     141              :  real(dp) :: entropylocal3,entropylocal4,gran_pot,gran_pot1,gran_pot2
     142              :  real(dp) :: gran_pot3,gran_pot4,gran_pot_local,gran_pot_local1
     143              :  real(dp) :: gran_pot_local2,gran_pot_local3,gran_pot_local4
     144              :  real(dp) :: inf_ucvol,intrhov,factor
     145              :  real(dp) :: nelect,potmin,rtrotter,toldrho,tolrec,tsmear
     146              :  real(dp) :: xmax,nlpotmin,ratio1,ratio2,ratio4,ratio8
     147           38 :  type(recparall_type) :: recpar
     148              :  character(len=500) :: msg
     149              :  !arrays
     150              :  integer :: ngfftrec(18),trasl(3)
     151           38 :  integer,pointer :: gcart_loc(:,:)
     152           38 :  integer,allocatable :: bufsize(:), bufdispl(:)
     153              :  real(dp) :: tsec(2),tsec2(2)
     154           76 :  real(dp) :: exppot(0:dtset%ngfft(1)*dtset%ngfft(2)*dtset%ngfft(3)-1)
     155           76 :  real(dp),target :: rholocal(1:rset%par%ntranche)
     156           76 :  real(dp),target :: alocal(0:rset%min_nrec,1:rset%par%ntranche)
     157           76 :  real(dp),target :: b2local(0:rset%min_nrec,1:rset%par%ntranche)
     158           38 :  real(dp),pointer :: rho_wrk(:)
     159           38 :  real(dp),pointer :: a_wrk(:,:),b2_wrk(:,:)
     160           38 :  real(dp),allocatable :: rholocal_f(:), rholoc_2(:)
     161           38 :  real(dp),allocatable :: rhogf(:,:),rhogc(:,:),aloc_copy(:,:),b2loc_copy(:,:)
     162           38 :  real(dp),allocatable :: gran_pot_v_f(:,:),gran_pot_v_c(:,:),gran_pot_v_2(:,:)
     163           38 :  real(dp),allocatable :: entropy_v_f(:,:),entropy_v_c(:,:),entropy_v_2(:,:)
     164           38 :  real(dp),allocatable :: ablocal_1(:,:,:),ablocal_2(:,:,:),ablocal_f(:,:,:)
     165           38 :  real(dp),allocatable :: exppotloc(:)
     166           38 :  real(dp),allocatable :: projec(:,:,:,:,:)
     167              : #if defined HAVE_GPU_CUDA
     168              :  integer :: max_rec
     169              :  integer,allocatable :: vcount_0(:), displs_0(:)
     170              :  integer,allocatable :: vcount_1(:), displs_1(:)
     171              :  real(dp),allocatable,target :: rho_hyb(:)
     172              :  real(dp),allocatable,target :: a_hyb(:,:),b2_hyb(:,:)
     173              :  real(cudap),allocatable :: an_dev(:,:)
     174              :  real(cudap),allocatable :: bn2_dev(:,:)
     175              : #endif
     176              : 
     177              : ! *********************************************************************
     178           38 :  if(rset%debug)then
     179            0 :    write(msg,'(80a,a,a)') ('=',ii=1,80),ch10,' vtorhorec : enter '
     180            0 :    call wrtout(std_out,msg,'PERS')
     181              :  end if
     182              : 
     183           38 :  call timab(21,1,tsec)
     184           38 :  call timab(600,1,tsec2)
     185              : !##################################################################################################
     186              : !!--Initalization in the FIRST time in VTORHOREC is made in SCFCV by FIRST_REC routine
     187              : !!--Parameters for the recursion method AND  Initialisation
     188              : 
     189           38 :  trotter = dtset%recptrott  !--trotter parameter
     190           38 :  nelect  = dtset%nelect     !--number of electrons
     191              : 
     192           38 :  toldrho = dtset%rectolden  !--tollerance for density
     193           38 :  tolrec  = toldrho*1.d-2    !--tollerance for local density
     194              : 
     195           38 :  tsmear  = dtset%tsmear     !--temperature
     196           38 :  beta    = one/tsmear       !--inverse of temperature
     197              : 
     198           38 :  factor = real(dtset%recgratio**3*100*rset%mpi%nproc,dp)/real(nfftf,dp)
     199              : 
     200              : !--Assignation of the rset variable:
     201           38 :  nrec       = rset%min_nrec
     202           38 :  nfftrec    = rset%nfftrec
     203          722 :  ngfftrec   = rset%ngfftrec
     204           38 :  inf_ucvol  = rset%inf%ucvol
     205              : 
     206           38 :  min_pt = rset%par%displs(rset%mpi%me)+1
     207           38 :  max_pt = min_pt+rset%par%vcount(rset%mpi%me)-1
     208              : 
     209              : !--In the last self-constistent loop or if density is converged the
     210              : !thermodynamics quantities are calculated
     211           38 :  get_K_S_G = 0; if(deltastep==0 .or. rset%quitrec/=0) get_K_S_G = 1;
     212              : 
     213              : !--Rewriting the trotter parameter
     214           38 :  rtrotter  = max(half,real(trotter,dp))
     215           38 :  dim_trott = max(0,2*trotter-1)
     216              : 
     217              : !--Variables Optimisation
     218           38 :  ratio1 = beta/rtrotter
     219           38 :  ratio2 = ratio1/two
     220           38 :  ratio4 = ratio1/four
     221           38 :  ratio8 = ratio1/eight
     222              : 
     223              : !--Integration points for entropy
     224           38 :  n_pt_integ_entropy = max(25,dtset%recnpath)
     225              : 
     226              : !-- energies non-local: at day not implemented
     227           38 :  enlx = zero
     228          467 :  grnl = zero
     229              : !jmb
     230           38 :  ek = zero
     231              : 
     232              : !--only a copy of ngfft(1:3) and nfft  (to purge!!)
     233           38 :  n1 = dtset%ngfft(1) ; n2 = dtset%ngfft(2) ; n3 = dtset%ngfft(3)
     234           38 :  n4 = n3
     235              : 
     236              : !--time switch to measure gpu-cpu syncrhonisation
     237           38 :  swt_tm = 0 ; !no gpu initally
     238              : 
     239        65702 :  exppot = zero
     240           38 :  nullify(gcart_loc)
     241              : 
     242           38 :  if(dtset%rectesteg==1)then
     243              : !  --Free electron gas case
     244         5187 :    exppot = one
     245              :  else
     246           35 :    if(.not.(rset%nl%nlpsp)) then
     247              : !    --Local case
     248              : !    --COMPUTATION OF exp( -beta*pot/(4*rtrotter))
     249           35 :      ABI_MALLOC(gcart_loc,(0,0))
     250              :      gcart_loc = 0
     251        60515 :      exppot = exp( -(ratio4*vtrial(:,1)))
     252              :    else
     253              : !    --Non-Local case
     254              : !    --COMPUTATION OF exp(-beta*pot/(8*rtrotter))
     255            0 :      exppot = exp( -(ratio8*vtrial(:,1)))
     256              : 
     257            0 :      ABI_MALLOC(gcart_loc,(3,dtset%natom))
     258            0 :      gcart_loc = rset%inf%gcart
     259            0 :      ABI_MALLOC(projec,(0:ngfftrec(1)-1,0:ngfftrec(2)-1,0:ngfftrec(3)-1,rset%nl%lmnmax,dtset%natom))
     260            0 :      projec = zero
     261              : 
     262            0 :      if(.not.(rset%tronc)) then
     263            0 :        do iatom =1, dtset%natom
     264            0 :          ipsp = dtset%typat(iatom)
     265            0 :          do ilmn = 1,rset%nl%lmnmax
     266            0 :            projec(:,:,:,ilmn,iatom) = reshape(rset%nl%projec(:,ilmn,ipsp),shape=shape(projec(:,:,:,1,1)))
     267            0 :            do ii=1,3
     268            0 :              projec(:,:,:,ilmn,iatom) = cshift(projec(:,:,:,ilmn,iatom),shift=ngfftrec(ii)/2-gcart_loc(ii,iatom),dim=ii)
     269              :            end do
     270              :          end do
     271              :        end do
     272              :      end if
     273              :    end if
     274              :  end if
     275              : 
     276              : !###################################################################################
     277              : !MAIN LOOP
     278              : 
     279       955622 :  rholocal = zero; alocal = zero; b2local = zero
     280           38 :  ipointlocal = 1
     281              : 
     282              : !--Allocation: if hybrid calculation is done then I have to use
     283              : !balanced work on devices.
     284           38 :  nullify(rho_wrk,a_wrk,b2_wrk)
     285              : 
     286           38 :  if(rset%load == 1)then
     287              : #ifdef HAVE_GPU_CUDA
     288              :    ABI_MALLOC(rho_hyb,(1:rset%GPU%par%npt))
     289              :    ABI_MALLOC(a_hyb,(0:nrec,1:rset%GPU%par%npt))
     290              :    ABI_MALLOC(b2_hyb,(0:nrec,1:rset%GPU%par%npt))
     291              :    rho_hyb = zero; a_hyb = zero; b2_hyb = zero
     292              :    rho_wrk => rho_hyb
     293              :    a_wrk   => a_hyb
     294              :    b2_wrk  => b2_hyb
     295              :    recpar  = rset%GPU%par
     296              : #endif
     297              :  else
     298           38 :    rho_wrk => rholocal
     299           38 :    a_wrk   => alocal
     300           38 :    b2_wrk  => b2local
     301           38 :    recpar  = rset%par
     302              :  end if
     303              : 
     304              : !#if defined HAVE_GPU_CUDA
     305              : !if(rset%debug)then
     306              : !write (std_out,*) 'rset%recGPU%nptrec ',rset%recGPU%nptrec
     307              : !write (std_out,*) 'rset%gpudevice ',rset%gpudevice
     308              : !write (std_out,*) 'rset%ngfftrec ',rset%ngfftrec(1:3)
     309              : !write (std_out,*) 'rset%min_nrec ',rset%min_nrec
     310              : !write (std_out,*) 'rset%par%ntranche ',rset%par%ntranche
     311              : !write (std_out,*) 'rset%par%min_pt ',rset%par%min_pt,min_pt
     312              : !write (std_out,*) 'rset%par%max_pt ',rset%par%max_pt,max_pt
     313              : !write (std_out,*) 'pt0 ',rset%par%pt0%x,rset%par%pt0%y,rset%par%pt0%z
     314              : !write (std_out,*) 'pt1 ',rset%par%pt1%x,rset%par%pt1%y,rset%par%pt1%z
     315              : !end if
     316              : !#endif
     317              : 
     318           38 :  if(rset%gpudevice>=0) then
     319              : #if defined HAVE_GPU_CUDA
     320              :    swt_tm = 1;
     321              :    call timab(607,1,tsec2)
     322              :    ABI_MALLOC(an_dev,(0:recpar%npt-1,0:nrec))
     323              :    ABI_MALLOC(bn2_dev,(0:recpar%npt-1,0:nrec))
     324              :    an_dev = zero
     325              :    bn2_dev = zero; bn2_dev(:,0) = one
     326              : 
     327              :    call cudarec( rset, exppot,an_dev,bn2_dev,&
     328              : &   beta,trotter,tolrec,dtset%recgratio,dtset%ngfft(:3),max_rec)
     329              : 
     330              :    max_rec = min(max_rec,nrec)
     331              :    a_wrk(0:max_rec,1:recpar%npt)  = transpose(an_dev(0:,0:max_rec))
     332              :    b2_wrk(0:max_rec,1:recpar%npt) = transpose(bn2_dev(0:,0:max_rec))
     333              : 
     334              :    ABI_FREE(an_dev)
     335              :    ABI_FREE(bn2_dev)
     336              :    call timab(607,2,tsec2)
     337              : 
     338              :    ipointlocal = recpar%npt+1
     339              : 
     340              : !  !DEBUG CUDA
     341              : !  if(rset%debug)then
     342              : !  if( rset%mpi%me==0)then
     343              : !  do ipoint = 1,rset%par%npt,1
     344              : !  kk=ipoint/(product(dtset%ngfft(:2)))
     345              : !  jj=ipoint/dtset%ngfft(1)-kk*dtset%ngfft(2)
     346              : !  ii=ipoint-jj*dtset%ngfft(1)-kk*dtset%ngfft(2)*dtset%ngfft(1)
     347              : !  write(msg,'(a,4i8,2(a,a9,5f12.6))')&
     348              : !  & 'pt',ipoint,ii,jj,kk,&
     349              : !  & ch10,'an-gpu   ',real(alocal(:4,ipoint)),&
     350              : !  & ch10,'b2n-gpu  ',real(b2local(:4,ipoint))
     351              : !  call wrtout(std_out,msg,'COLL')
     352              : !  end do
     353              : !  endif
     354              : !  endif
     355              : !  !ENDDEBUG CUDA
     356              : #endif
     357              : 
     358              :  else
     359           38 :    if (.not.(rset%tronc)) then
     360          120 :      graou1 : do kk = recpar%pt0%z,recpar%pt1%z,dtset%recgratio
     361         1560 :        do jj = 0,n2-1,dtset%recgratio
     362        18778 :          do ii = 0,n1-1,dtset%recgratio
     363        17280 :            ipoint = ii+(jj+kk*n2)*n1
     364              : !          --Local position of atoms
     365        17280 :            if (ipoint<recpar%min_pt) cycle
     366              : !          --Computation done by that proc
     367        17280 :            tim_fourdp=6
     368              :            call recursion(exppot,ii,jj,kk, &
     369              : &           a_wrk(:,ipointlocal), &
     370              : &           b2_wrk(:,ipointlocal), &
     371              : &           rho_wrk(ipointlocal),&
     372              : &           nrec, rset%efermi,tsmear,rtrotter,dim_trott, &
     373              : &           rset%ZT_p, &
     374              : &           tolrec,dtset%typat,rset%nl,&
     375              : &           rset%mpi,nfftrec,ngfftrec,rset%inf,&
     376        17280 : &           tim_fourdp,dtset%natom,projec,1)
     377        17280 :            ipointlocal = ipointlocal + 1
     378              : !          write(std_out,*)'ipointlocal',ipoint,ipointlocal,ii,jj,kk
     379        17280 :            call prtwork(dtset%recgratio**3*ipointlocal*100*rset%mpi%nproc/nfftrec)
     380        18689 :            if(ipoint==recpar%max_pt) exit graou1
     381              :          end do
     382              :        end do
     383              :      end do graou1
     384              :    else !--We use a troncation
     385           21 :      ABI_MALLOC(exppotloc,(0:nfftrec-1))
     386           21 :      graou2 : do kk = recpar%pt0%z,recpar%pt1%z,dtset%recgratio
     387           84 :        do jj = 0,n2-1,dtset%recgratio
     388          259 :          do ii = 0,n1-1,dtset%recgratio
     389          189 :            ipoint = ii+(jj+kk*n2)*n1
     390          189 :            if (ipoint<recpar%min_pt) cycle
     391              : !          computation done by that proc
     392        12285 :            exppotloc = zero
     393              : !          --Traslation to move position on the ngfftrec grid center
     394          756 :            trasl = -(/ii,jj,kk/)+ngfftrec(:3)/2
     395          189 :            if(rset%nl%nlpsp) then
     396            0 :              do iatom=1,dtset%natom
     397              : !              --local position of atoms
     398            0 :                gcart_loc(:,iatom) = rset%inf%gcart(:,iatom)+trasl
     399            0 :                gcart_loc(:,iatom) = modulo(gcart_loc(:,iatom),(/n1,n2,n3/))
     400              : !              --Traslation of non-local projectors
     401            0 :                do ilmn = 1,rset%nl%lmnmax
     402            0 :                  projec(:,:,:,ilmn,iatom) = reshape(rset%nl%projec(:,ilmn,dtset%typat(iatom)),shape=shape(projec(:,:,:,1,1)))
     403            0 :                  do ii1=1,3
     404            0 :                    projec(:,:,:,ilmn,iatom) = eoshift(projec(:,:,:,ilmn,iatom),shift=ngfftrec(ii1)/2-gcart_loc(ii1,iatom),dim=ii1)
     405              :                  end do
     406              :                end do
     407              :              end do
     408              :            end if
     409              : 
     410              :            call reshape_pot(trasl,nfftf,nfftrec,&
     411              : &           dtset%ngfft(:3),ngfftrec(:3),&
     412          189 : &           exppot,exppotloc)
     413              : 
     414          189 :            tim_fourdp=6
     415              :            call recursion(exppotloc,ngfftrec(1)/2,ngfftrec(2)/2,ngfftrec(3)/2, &
     416              : &           a_wrk(:,ipointlocal), &
     417              : &           b2_wrk(:,ipointlocal), &
     418              : &           rho_wrk(ipointlocal),&
     419              : &           nrec, rset%efermi,tsmear,rtrotter,dim_trott, &
     420              : &           rset%ZT_p, &
     421              : &           tolrec,dtset%typat,rset%nl,&
     422              : &           rset%mpi,nfftrec,ngfftrec,rset%inf,&
     423          189 : &           tim_fourdp,dtset%natom,projec,1)
     424          189 :            ipointlocal = ipointlocal + 1
     425          189 :            call prtwork(factor*real(ipointlocal,dp))
     426          245 :            if(ipoint==recpar%max_pt) exit graou2
     427              :          end do
     428              :        end do
     429              :      end do graou2
     430            7 :      ABI_FREE(exppotloc)
     431              :    end if
     432              : 
     433              :  end if
     434           38 :  write(msg,'( a12,i12)')'ipointlocal',ipointlocal
     435           38 :  call wrtout(std_out,msg,'PERS')
     436           38 :  call timab(613+swt_tm,1,tsec2)  !!--start time-counter: sync gpu-cpu
     437           38 :  call xmpi_barrier(rset%mpi%comm_bandfft)
     438           38 :  call timab(613+swt_tm,2,tsec2)  !!--stop time-counter: sync gpu-cpu
     439              : 
     440              : !!#############################################################
     441              : !!--ASSIGNATION PARAMETERS TO MENAGE PARALLELISME OF TRANSGRID
     442           38 :  if((rset%load==1 .or. dtset%recgratio>1))then
     443              : !  --Bufsize contains the values of the number of points calculated
     444              : !  by any proc on the coarse grid; bufsize_f on the fine grid
     445            7 :    call timab(604,1,tsec2) !--start time-counter: transgrid
     446           21 :    ABI_MALLOC(bufsize,(0:rset%mpi%nproc-1))
     447           14 :    ABI_MALLOC(bufdispl,(0:rset%mpi%nproc-1))
     448           14 :    bufsize = 0;
     449            7 :    bufsize(rset%mpi%me) = rset%par%npt
     450            7 :    call xmpi_sum(bufsize,rset%mpi%comm_bandfft,ierr)
     451              : 
     452            7 :    bufdispl(0) = 0;
     453            7 :    if(rset%mpi%nproc>1) bufdispl(1:) = (/(sum(bufsize(:ii)),ii=0,rset%mpi%nproc-1)/)
     454           14 :    call timab(604,2,tsec2) !--stop time-counter: transgrid
     455              :  end if
     456              : !!####################################################################
     457              : !!--REDISTRIBUTION OF LOAD ON PROCS AFTER RECURSION IF CUDA IS USED
     458              : #ifdef HAVE_GPU_CUDA
     459              :  if(rset%load==1)then
     460              :    call timab(604,1,tsec2) !--start time-counter: transgrid
     461              :    call xredistribute(rho_hyb,rset%GPU%par%vcount,rset%GPU%par%displs,&
     462              : &   rholocal,bufsize,bufdispl,rset%mpi%me,&
     463              : &   rset%mpi%nproc,&
     464              : &   rset%mpi%comm_bandfft,ierr)
     465              : 
     466              : 
     467              :    ABI_MALLOC(vcount_0,(0:rset%mpi%nproc-1))
     468              :    ABI_MALLOC(displs_0,(0:rset%mpi%nproc-1))
     469              :    ABI_MALLOC(vcount_1,(0:rset%mpi%nproc-1))
     470              :    ABI_MALLOC(displs_1,(0:rset%mpi%nproc-1))
     471              : 
     472              :    vcount_0 = 0
     473              :    vcount_0(rset%mpi%me) = rset%par%npt*(nrec+1)
     474              :    call xmpi_sum(vcount_0,rset%mpi%comm_bandfft,ierr)
     475              :    displs_0 = 0
     476              :    if(rset%mpi%nproc>1) displs_0(1:) = (/(sum(vcount_0(:ii)),ii=0,rset%mpi%nproc-1)/)
     477              : 
     478              : 
     479              :    vcount_1 = 0
     480              :    vcount_1(rset%mpi%me) = rset%GPU%par%npt*(nrec+1)
     481              :    call xmpi_sum(vcount_1,rset%mpi%comm_bandfft,ierr)
     482              :    displs_1 = 0
     483              :    if(rset%mpi%nproc>1) displs_1(1:) = (/(sum(vcount_1(:ii)),ii=0,rset%mpi%nproc-1)/)
     484              : 
     485              : 
     486              :    call xredistribute(a_hyb,vcount_1,displs_1,&
     487              : &   alocal,vcount_0,displs_0,&
     488              : &   rset%mpi%me,rset%mpi%nproc,&
     489              : &   rset%mpi%comm_bandfft,ierr)
     490              : 
     491              :    call xredistribute(b2_hyb,vcount_1,displs_1,&
     492              : &   b2local,vcount_0,displs_0,&
     493              : &   rset%mpi%me,rset%mpi%nproc,&
     494              : &   rset%mpi%comm_bandfft,ierr)
     495              : 
     496              :    nullify(rho_wrk,a_wrk,b2_wrk)
     497              :    ABI_FREE(rho_hyb)
     498              :    ABI_FREE(a_hyb)
     499              :    ABI_FREE(b2_hyb)
     500              :    ABI_FREE(vcount_0)
     501              :    ABI_FREE(displs_0)
     502              :    ABI_FREE(vcount_1)
     503              :    ABI_FREE(displs_1)
     504              :    call timab(604,2,tsec2) !--start time-counter: transgrid
     505              :  end if
     506              : #endif
     507              : 
     508              : !#############################################################
     509              : !--TRANSGRID FOR THE DENSITY RHO AND THE COEFFICIENTS AN AND B2N
     510           38 :  if (dtset%recgratio>1) then
     511              : !  --variables allocation and initialisation-------
     512            7 :    write (msg,'(a)')' - TRANSGRID USING -----'
     513            7 :    call wrtout(std_out,msg,'COLL')
     514            7 :    call timab(604,1,tsec2) !--start time-counter: transgrid
     515              : 
     516           21 :    ABI_MALLOC(rholocal_f,(rset%pawfgr%nfft))
     517           21 :    ABI_MALLOC(rhogf,(2,rset%pawfgr%nfft))
     518           21 :    ABI_MALLOC(rhogc,(2,rset%pawfgr%nfftc))
     519           21 :    ABI_MALLOC(rholoc_2,(1:rset%pawfgr%nfftc))
     520           35 :    ABI_MALLOC(ablocal_2,(1:rset%pawfgr%nfftc,0:nrec,2))
     521           35 :    ABI_MALLOC(ablocal_f,(1:rset%pawfgr%nfft,0:nrec,2))
     522           35 :    ABI_MALLOC(ablocal_1,(1:rset%par%npt,0:nrec,2))
     523              : 
     524            7 :    call rset%mpi%distribfft%free()
     525            7 :    call rset%mpi%distribfft%init('c',rset%mpi%nproc_fft,rset%pawfgr%ngfftc(2) ,rset%pawfgr%ngfftc(3))
     526            7 :    call rset%mpi%distribfft%init('f',rset%mpi%nproc_fft,rset%pawfgr%ngfft(2) ,rset%pawfgr%ngfft(3))
     527              : 
     528       338933 :    rholocal_f = zero; ablocal_f = zero; ablocal_2 = zero
     529              : 
     530         2611 :    ablocal_1(:,:,1) = transpose(alocal(:,1:rset%par%npt))
     531         2611 :    ablocal_1(:,:,2) = transpose(b2local(:,1:rset%par%npt))
     532              : 
     533            7 :    if(get_K_S_G==1 .and. dtset%recgratio>1 ) then
     534            8 :      ABI_MALLOC(aloc_copy,(0:nrec,1:rset%par%npt))
     535            6 :      ABI_MALLOC(b2loc_copy,(0:nrec,1:rset%par%npt))
     536          436 :      aloc_copy = alocal(:,1:rset%par%npt)
     537          436 :      b2loc_copy = b2local(:,1:rset%par%npt)
     538              :    end if
     539              : 
     540            7 :    if(rset%mpi%nproc ==1) then
     541              : !    --SEQUENTIAL CASE--
     542          203 :      rholoc_2 = rholocal(1:rset%par%npt)
     543         5236 :      ablocal_2 = ablocal_1
     544              : !    --Transigrid: coarse->fine
     545        36862 :      rhogf = zero; rhogc = zero
     546            7 :      call transgrid(1,rset%mpi,dtset%nspden,1,0,0,1,rset%pawfgr,rhogc,rhogf,rholoc_2,rholocal_f)
     547           21 :      do jj1 = 1,2
     548          207 :        do ipoint = 0,nrec
     549       979476 :          rhogf = zero; rhogc = zero
     550              :          call transgrid(1,rset%mpi,dtset%nspden,1,0,0,1,rset%pawfgr,rhogc,rhogf,&
     551          200 : &         ablocal_2(:,ipoint,jj1),ablocal_f(:,ipoint,jj1))
     552              :        end do
     553              :      end do
     554              : !    --Assignation of the interpolated results on the fine grid--
     555        12103 :      rholocal = rholocal_f
     556       172807 :      alocal = transpose(ablocal_f(:,:,1))
     557       172807 :      b2local = transpose(ablocal_f(:,:,2))
     558              : 
     559              :    else
     560              : !    --PARALLEL CASE--
     561            0 :      rholoc_2 = zero
     562              : !    --Send on all procs rho,an,bn--
     563              :      call xmpi_allgatherv(rholocal(1:rset%par%npt),bufsize(rset%mpi%me),rholoc_2,&
     564            0 : &     bufsize,bufdispl,rset%mpi%comm_bandfft,ierr)
     565            0 :      do irec = 0,nrec
     566              :        call xmpi_allgatherv(ablocal_1(1:rset%par%npt,irec,1),bufsize(rset%mpi%me),&
     567            0 : &       ablocal_2(:,irec,1),bufsize,bufdispl,rset%mpi%comm_bandfft,ierr)
     568              :        call xmpi_allgatherv(ablocal_1(1:rset%par%npt,irec,2),bufsize(rset%mpi%me),&
     569            0 : &       ablocal_2(:,irec,2),bufsize,bufdispl,rset%mpi%comm_bandfft,ierr)
     570              :      end do
     571              : 
     572              : 
     573              : !    --Transigrid: coarse->fine on differents procs (with respect
     574              : !    the number of recursion)
     575            0 :      rhogf = zero;  rhogc = zero
     576            0 :      call transgrid(1,rset%mpi,dtset%nspden,1,0,0,1,rset%pawfgr,rhogc,rhogf,rholoc_2,rholocal_f)
     577              : 
     578            0 :      do irec = 0,2*(nrec+1)-1
     579            0 :        ii1 = modulo(irec,rset%mpi%nproc)
     580            0 :        jj1 = 1+modulo(irec,2)
     581            0 :        kk1 = floor(irec/2.)
     582            0 :        if(maxval(abs(ablocal_2(:,kk1,jj1))) > tol10 .and. rset%mpi%me == ii1) then
     583            0 :          rhogf = zero; rhogc = zero
     584              :          call transgrid(1,rset%mpi,dtset%nspden,1,0,0,1,rset%pawfgr,rhogc,&
     585            0 : &         rhogf,ablocal_2(:,kk1,jj1),ablocal_f(:,kk1,jj1))
     586              :        end if
     587              :      end do
     588              : 
     589              : !    --Recuperation of all interpolated results
     590              : !    from procs to allprocs
     591            0 :      call xmpi_sum(ablocal_f,rset%mpi%comm_bandfft,ierr)
     592              : 
     593              : !    --Assignation the interpolated results on the fine grid
     594              : !    any procs to obtain the same point as in the standard recursion
     595            0 :      do ii1 = 0, rset%mpi%nproc-1
     596            0 :        jj1 = rset%par%displs(ii1)+1
     597            0 :        if(ii1 == rset%mpi%me) then
     598            0 :          alocal = transpose(ablocal_f(jj1:jj1+rset%par%vcount(ii1)-1,:,1))
     599            0 :          b2local = transpose(ablocal_f(jj1:jj1+rset%par%vcount(ii1)-1,:,2))
     600            0 :          rholocal = rholocal_f(jj1:jj1+rset%par%vcount(ii1)-1)
     601              :        end if
     602              :      end do
     603              :    end if
     604            7 :    ABI_FREE(ablocal_f)
     605            7 :    ABI_FREE(ablocal_2)
     606            7 :    ABI_FREE(ablocal_1)
     607            7 :    ABI_FREE(rhogf)
     608            7 :    ABI_FREE(rholocal_f)
     609            7 :    ABI_FREE(rhogc)
     610            7 :    ABI_FREE(rholoc_2)
     611              : 
     612            7 :    call timab(604,2,tsec2) !--stop time-counter: transgrid
     613              :  else
     614           31 :    write(msg,'(a)')' - TRANSGRID NOT USED --'
     615           31 :    call wrtout(std_out,msg,'COLL')
     616              :  end if
     617              : !!--End transgrid
     618              : !!###############################################################
     619              : !###################################
     620              : !--Fermi energy computation
     621              : !--find the good mu by imposing the electrons number
     622              :  call fermisolverec(rset%efermi,rholocal,alocal,b2local,rset%debug,&
     623              : & rset%min_nrec,tsmear,trotter,nelect,tol10,100, &
     624              : & rset%par%ntranche,rset%mpi,inf_ucvol,& !.False. .and.&
     625           76 : & (rset%tp==2 .or. rset%tp==3) .and. trotter>1)
     626              : 
     627              : !#################################################################
     628              : !######### ENTROPY AND GRAN POTENTIAL COMPUTATION  ##################
     629           38 :  entropy = zero
     630           38 :  gran_pot = zero
     631           38 :  noentropie : if(get_K_S_G==1)then
     632           11 :    entropy1 = zero; entropy2 = zero ;entropy3 = zero; entropy4 = zero
     633           11 :    gran_pot1 = zero ; gran_pot2 = zero; gran_pot3 = zero; gran_pot4 = zero
     634              : 
     635              : !  --Seek for the min of the path integral
     636           11 :    potmin = zero;  nlpotmin = zero
     637        17301 :    if(dtset%rectesteg/=1) potmin = minval(vtrial(:,1))
     638           11 :    if(rset%nl%nlpsp)  nlpotmin = minval(rset%nl%eival(:,:,:))
     639           11 :    xmax = exp(-ratio2*(potmin+nlpotmin-rset%efermi))
     640              : 
     641           11 :    dim_entro = 0;  if(rset%debug) dim_entro = 4;
     642              : 
     643           11 :    if(dtset%recgratio>1) then
     644              : !    --Recgratio>1
     645            6 :      ABI_MALLOC(rhogf,(2,rset%pawfgr%nfft))
     646            6 :      ABI_MALLOC(rhogc,(2,rset%pawfgr%nfftc))
     647            6 :      ABI_MALLOC(entropy_v_f,(rset%pawfgr%nfft,0:4))
     648            6 :      ABI_MALLOC(entropy_v_c,(rset%pawfgr%nfftc,0:4))
     649            6 :      ABI_MALLOC(entropy_v_2,(1:rset%par%npt,0:4))
     650            4 :      ABI_MALLOC(gran_pot_v_f,(rset%pawfgr%nfft,0:4))
     651            4 :      ABI_MALLOC(gran_pot_v_c,(rset%pawfgr%nfftc,0:4))
     652            4 :      ABI_MALLOC(gran_pot_v_2,(1:rset%par%npt,0:4))
     653              : 
     654        17852 :      entropy_v_c = zero; entropy_v_f = zero; entropy_v_2 = zero
     655        17852 :      gran_pot_v_c = zero; gran_pot_v_f = zero; gran_pot_v_2 = zero
     656              : 
     657              : 
     658           56 :      do ipoint = 1,rset%par%npt
     659              :        call entropyrec(exp(rset%efermi*ratio2)*aloc_copy(:,ipoint), &
     660              : &       exp(rset%efermi*ratio1)*b2loc_copy(:,ipoint), &
     661              : &       nrec,trotter,entropy_v_2(ipoint,0),two,&
     662              : &       rset%debug,n_pt_integ_entropy,perc_vmin*xmax,&
     663              : &       entropy_v_2(ipoint,1),&
     664              : &       entropy_v_2(ipoint,2),&
     665              : &       entropy_v_2(ipoint,3),&
     666          810 : &       entropy_v_2(ipoint,4))
     667              : 
     668              :        call gran_potrec(exp(rset%efermi*ratio2)*aloc_copy(:,ipoint), &
     669              : &       exp(rset%efermi*ratio1)*b2loc_copy(:,ipoint), &
     670              : &       nrec,trotter,gran_pot_v_2(ipoint,0),two,&
     671              : &       rset%debug,n_pt_integ_entropy,perc_vmin*xmax,&
     672              : &       gran_pot_v_2(ipoint,1),&
     673              : &       gran_pot_v_2(ipoint,2),&
     674              : &       gran_pot_v_2(ipoint,3),&
     675          812 : &       gran_pot_v_2(ipoint,4))
     676              :      end do
     677            2 :      ABI_FREE(aloc_copy)
     678            2 :      ABI_FREE(b2loc_copy)
     679              : 
     680            2 :      call timab(613+swt_tm,1,tsec2)  !!--start time-counter: sync gpu-cpu
     681            2 :      call xmpi_barrier(rset%mpi%comm_bandfft)
     682            2 :      call timab(613+swt_tm,2,tsec2)  !!--stop time-counter: sync gpu-cpu
     683              : 
     684            2 :      call timab(604,1,tsec2) !--start time-counter: transgrid
     685            2 :      if(rset%mpi%nproc==1) then
     686          284 :        entropy_v_c = entropy_v_2
     687          284 :        gran_pot_v_c = gran_pot_v_2
     688              :      end if
     689            4 :      do ii1 = 0,dim_entro
     690              :        call xmpi_allgatherv(entropy_v_2(:,ii1),bufsize(rset%mpi%me),&
     691              : &       entropy_v_c(:,ii1),bufsize,bufdispl,&
     692            2 : &       rset%mpi%comm_bandfft,ierr)
     693              :        call xmpi_allgatherv(gran_pot_v_2(:,ii1),bufsize(rset%mpi%me),&
     694              : &       gran_pot_v_c(:,ii1),bufsize,bufdispl,&
     695            2 : &       rset%mpi%comm_bandfft,ierr)
     696              : 
     697           58 :        if(maxval(abs(entropy_v_c(:,ii1))) > tol10) then
     698        10532 :          rhogf = zero; rhogc = zero
     699              :          call transgrid(1,rset%mpi,dtset%nspden,1,0,0,1,&
     700            2 : &         rset%pawfgr,rhogc,rhogf,entropy_v_c(:,ii1),entropy_v_f(:,ii1))
     701              :        end if
     702           60 :        if(maxval(abs(gran_pot_v_c(:,ii1))) >tol10) then
     703        10532 :          rhogf = zero; rhogc = zero
     704              :          call transgrid(1,rset%mpi,dtset%nspden,1,0,0,1,&
     705            2 : &         rset%pawfgr,rhogc,rhogf,gran_pot_v_c(:,ii1),gran_pot_v_f(:,ii1))
     706              :        end if
     707              :      end do
     708            2 :      call timab(604,2,tsec2) !--stop time-counter: transgrid
     709              : 
     710         3458 :      entropy  = sum(entropy_v_f(:,0))
     711         3458 :      gran_pot  = sum(gran_pot_v_f(:,0))
     712              : 
     713            2 :      if(rset%debug)then
     714            0 :        entropy1 = sum(entropy_v_f(:,1))
     715            0 :        entropy2 = sum(entropy_v_f(:,2))
     716            0 :        entropy3 = sum(entropy_v_f(:,3))
     717            0 :        entropy4 = sum(entropy_v_f(:,4))
     718            0 :        gran_pot1 = sum(gran_pot_v_f(:,1))
     719            0 :        gran_pot2 = sum(gran_pot_v_f(:,2))
     720            0 :        gran_pot3 = sum(gran_pot_v_f(:,3))
     721            0 :        gran_pot4 = sum(gran_pot_v_f(:,4))
     722              :      end if
     723              : 
     724            2 :      ABI_FREE(entropy_v_f)
     725            2 :      ABI_FREE(entropy_v_c)
     726            2 :      ABI_FREE(entropy_v_2)
     727            2 :      ABI_FREE(rhogf)
     728            2 :      ABI_FREE(rhogc)
     729            2 :      ABI_FREE(gran_pot_v_f)
     730            2 :      ABI_FREE(gran_pot_v_c)
     731            2 :      ABI_FREE(gran_pot_v_2)
     732              : 
     733              : 
     734              :    else
     735              : !    --Recgratio=1
     736         5193 :      do ipoint = 1,rset%par%ntranche
     737              :        call entropyrec(exp(rset%efermi*ratio2)*alocal(:,ipoint), &
     738              : &       exp(rset%efermi*ratio1)*b2local(:,ipoint), &
     739              : &       nrec,trotter,entropylocal,two,&
     740              : &       rset%debug,n_pt_integ_entropy,perc_vmin*xmax,&
     741              : &       entropylocal1,entropylocal2,&
     742        77760 : &       entropylocal3,entropylocal4)
     743              :        call gran_potrec(exp(rset%efermi*ratio2)*alocal(:,ipoint), &
     744              : &       exp(rset%efermi*ratio1)*b2local(:,ipoint), &
     745              : &       nrec,trotter,gran_pot_local,two,& !/ucvol,&
     746              : &       rset%debug,n_pt_integ_entropy,perc_vmin*xmax,&
     747              : &       gran_pot_local1,gran_pot_local2,&
     748        77760 : &       gran_pot_local3,gran_pot_local4)
     749              : 
     750         5184 :        entropy = entropy + entropylocal
     751         5184 :        gran_pot = gran_pot + gran_pot_local
     752         5193 :        if(rset%debug)then
     753            0 :          entropy1 = entropy1 + entropylocal1
     754            0 :          entropy2 = entropy2 + entropylocal2
     755            0 :          entropy3 = entropy3 + entropylocal3
     756            0 :          entropy4 = entropy4 + entropylocal4
     757            0 :          gran_pot1 = gran_pot1 + gran_pot_local1
     758            0 :          gran_pot2 = gran_pot2 + gran_pot_local2
     759            0 :          gran_pot3 = gran_pot3 + gran_pot_local3
     760            0 :          gran_pot4 = gran_pot4 + gran_pot_local4
     761              :        end if
     762              : 
     763              :      end do
     764              : 
     765            9 :      call xmpi_sum(entropy,rset%mpi%comm_bandfft ,ierr)
     766            9 :      call xmpi_sum(gran_pot,rset%mpi%comm_bandfft ,ierr)
     767            9 :      if(rset%debug)then
     768            0 :        call xmpi_sum(entropy1,rset%mpi%comm_bandfft ,ierr)
     769            0 :        call xmpi_sum(entropy2,rset%mpi%comm_bandfft ,ierr)
     770            0 :        call xmpi_sum(entropy3,rset%mpi%comm_bandfft ,ierr)
     771            0 :        call xmpi_sum(entropy4,rset%mpi%comm_bandfft ,ierr)
     772            0 :        call xmpi_sum(gran_pot1,rset%mpi%comm_bandfft ,ierr)
     773            0 :        call xmpi_sum(gran_pot2,rset%mpi%comm_bandfft ,ierr)
     774            0 :        call xmpi_sum(gran_pot3,rset%mpi%comm_bandfft ,ierr)
     775            0 :        call xmpi_sum(gran_pot4,rset%mpi%comm_bandfft ,ierr)
     776              :      end if
     777              :    end if
     778              : 
     779           11 :    if(rset%debug)then
     780              :      write(msg,'(2(2a,4(2a,es11.4,a)))')&
     781            0 : &     ' --------------------------'        ,ch10, &
     782            0 : &     '  entropy, horiz path=',' ',entropy1,ch10, &
     783            0 : &     '  entropy, xmax  path=',' ',entropy2,ch10, &
     784            0 : &     '  entropy, xmin  path=',' ',entropy3,ch10, &
     785            0 : &     '  entropy, zero  path=',' ',entropy4,ch10, &
     786            0 : &     ' --------------------------'        ,ch10, &
     787            0 : &     ' -omega/T, horiz path=',' ',gran_pot1,ch10, &
     788            0 : &     ' -omega/T, xmax  path=',' ',gran_pot2,ch10, &
     789            0 : &     ' -omega/T, xmin  path=',' ',gran_pot3,ch10, &
     790            0 : &     ' -omega/T, zero  path=',' ',gran_pot4,ch10
     791            0 :      call wrtout(std_out,msg,'COLL')
     792              :    end if
     793              : 
     794           11 :    e_eigenvalues=tsmear*(entropy-gran_pot) + rset%efermi*nelect
     795              : !  --In reality gran_pot is not the gran potential but the
     796              : !  potential omega=-PV (Landau-potential or grand-potential)
     797              : !  divided by -T so the internal energy
     798              : !  U:=e_eigenvalues= TS+omega+muN = ST-T*sum(ln(1-n))+muN =
     799              : !  T(S-gran_pot)+muN
     800              : 
     801              : 
     802           11 :    if(rset%nl%nlpsp) then
     803              :      call nlenergyrec(rset,enlx,exppot,dtset%ngfft,dtset%natom,&
     804            0 : &     dtset%typat,tsmear,trotter,tolrec)
     805              :    end if
     806              :  end if noentropie
     807              : !##### END ENTROPY AND GRAN POTENTIAL COMPUTATION  ##################
     808              : !#################################################################
     809              : 
     810              : !if(associated(projec))
     811           38 :  if(rset%nl%nlpsp)  then
     812            0 :    ABI_FREE(projec)
     813              :  end if
     814           38 :  if(associated(gcart_loc))  then
     815           35 :    ABI_FREE(gcart_loc)
     816              :  end if
     817           38 :  if((dtset%recgratio/=1 .or. rset%load==1))  then
     818            7 :    ABI_FREE(bufdispl)
     819            7 :    ABI_FREE(bufsize)
     820              :  end if
     821              : !------------------------------------------------------------------
     822              : !--Check if the convergence is reached for rho
     823        29452 :  drho = maxval(abs(rhor(min_pt:max_pt,1)-rholocal(:)))
     824              :  drhomax = drho
     825           38 :  call xmpi_max(drho,drhomax,rset%mpi%comm_bandfft,ierr)
     826              : 
     827              : !write(std_out,*)'drhomax,toldrho',drhomax,toldrho
     828           38 :  if(drhomax<toldrho)then
     829           22 :    rset%quitrec = rset%quitrec+1
     830              :  else
     831           16 :    rset%quitrec = 0
     832              :  end if
     833              : 
     834              : !-------------------------------------------------------------------
     835              : !--Density on all procs
     836        29414 :  rhor(min_pt:max_pt,1) = rholocal(:)
     837           38 :  if(rset%mpi%nproc /= 1)then
     838              :    call xmpi_allgatherv(rholocal,rset%par%ntranche,rhor(:,1),&
     839              : &   rset%par%vcount,rset%par%displs,&
     840           28 : &   rset%mpi%comm_band,ierr)
     841              :  end if
     842              : 
     843              : !--------------------------------------------------------------------
     844              : !--2nd EKIN CALCULATION: this method is used
     845           38 :  noekin2 : if(get_K_S_G==1)then
     846         8651 :    intrhov = (inf_ucvol)*sum(rholocal*vtrial(min_pt:max_pt,1))
     847           11 :    call xmpi_sum(intrhov,rset%mpi%comm_bandfft ,ierr)
     848              : 
     849           11 :    ek = e_eigenvalues-intrhov-enlx
     850              : 
     851              : 
     852           11 :    if(rset%debug) then
     853            0 :      write (msg,'(2a,3f15.10,2a,3f15.10,2a,f15.10,a)') ch10,&
     854            0 : &     ' ek,int(rho*V),ek+int(rho*V) ', ek, intrhov,  ek+ intrhov,ch10, &
     855            0 : &     ' kT*S, kT*sum(ln(...)), diff ', tsmear*entropy, tsmear*gran_pot, tsmear*(entropy-gran_pot),ch10, &
     856            0 : &     ' kT(S-sum(ln(...)))+mu*nelect', tsmear*(entropy-gran_pot)+rset%efermi*nelect,ch10
     857            0 :      call wrtout(std_out,msg,'COLL')
     858              :    end if
     859              : 
     860              : 
     861              :  end if noekin2
     862              : !--------------------------------------------------------------------
     863           38 :  fermie = rset%efermi
     864              : 
     865              : !--------------------------------------------------------
     866              : !!--At the first step to find the max number of recursion
     867              : !!  needed to convergence, then redefine nrec.
     868           38 :  if(initialized==0 .and. dtset%ntime>0) then
     869            6 :    call  Calcnrec(rset,b2local)
     870              :  end if
     871              : 
     872              : !--------------------------------------------------------
     873           38 :  call rset%mpi%distribfft%free()
     874           38 :  call rset%mpi%distribfft%init('c',rset%mpi%nproc_fft,rset%ngfftrec(2),rset%ngfftrec(3))
     875           38 :  call rset%mpi%distribfft%init('f',rset%mpi%nproc_fft,dtset%ngfft(2),dtset%ngfft(3))
     876              : 
     877              : !--Printing results
     878              :  write(msg,'(3a,f15.10)')&
     879           38 : & ' -- Results: --------------------------------------',ch10,&
     880           76 : & ' mu          =',rset%efermi
     881           38 :  call wrtout(std_out,msg,'COLL')
     882           38 :  if(get_K_S_G==1)then
     883              :    write(msg,'(a,f15.10,6(2a,f15.10))')&
     884           11 : &   ' potmin      =',potmin,ch10,&
     885           11 : &   ' <V_eff>     =',intrhov,ch10,&
     886           11 : &   ' entropy     =',entropy,ch10,&
     887           11 : &   ' -omega/T    =',gran_pot,ch10,&
     888           11 : &   ' eigenvalues =',e_eigenvalues,ch10,&
     889           11 : &   ' kinetic     =',ek,ch10,&
     890           22 : &   ' non-loc ene =',enlx
     891           11 :    call wrtout(std_out,msg,'COLL')
     892              :  end if
     893         1938 :  write(msg,'(a,50a)')' ',('-',ii=1,50)
     894           38 :  call wrtout(std_out,msg,'COLL')
     895              : !write(std_out,*)'is the pressure ',gran_pot*tsmear/(rset%inf%ucvol*real(nfftrec,dp))
     896              : 
     897              : !--Structured debugging : if rset%debug=T, stop here.
     898              :  if(.false.)then !(rset%debug)
     899              :    call wrtout(std_out,'  rhor ','PERS')
     900              :    write(std_out,*)rhor(:,1)
     901              :    call wrtout(std_out,' ','COLL')
     902              :    write(msg,'(a,2d10.3)')'  temps recursion    ',tsec
     903              :    call wrtout(std_out,msg,'COLL')
     904              :    write(msg,'(a,l1,a)') ' vtorhorec : rset%debug=-',rset%debug,', debugging mode => stop '
     905              :    ABI_ERROR(msg)
     906              :  end if
     907              : 
     908           38 :  call timab(600,2,tsec2)
     909           38 :  call timab(21,2,tsec)
     910              : 
     911              :  call symrhg(1,gprimd,irrzon,rset%mpi,nfftf,&
     912              : & dtset%ngfft(1)*dtset%ngfft(2)*dtset%ngfft(3),dtset%ngfft,dtset%nspden,&
     913           38 : & dtset%nsppol,dtset%nsym,phnons,rhog,rhor,rprimd,dtset%symafm,dtset%symrel,dtset%tnons)
     914              : 
     915           76 : end subroutine vtorhorec
     916              : !!***
     917              : 
     918              : !!****f* ABINIT/entropyrec
     919              : !! NAME
     920              : !! entropyrec
     921              : !!
     922              : !! FUNCTION
     923              : !! This routine computes the local part of the entropy at a point using a path integral,
     924              : !! in the recursion method.
     925              : !!
     926              : !!  an, bn2 : coefficient given by the recursion.
     927              : !!  nrec=order of recursion
     928              : !!  trotter=trotter parameter
     929              : !!  multce=a multiplicator for computing entropy ; 2 for non-spin-polarized system
     930              : !!  debug_rec=debug variable
     931              : !!  n_pt_integ=number of points of integration for the path integral
     932              : !!  xmax =max point of integration on the real axis
     933              : 
     934              : !! OUTPUT
     935              : !!  ent_out=entropy at the point
     936              : !!  ent_out1,ent_out2,ent_out3,ent_out4=debug entropy at the point
     937              : !!
     938              : !! NOTES
     939              : !!  at this time :
     940              : !!       - multce should be not used
     941              : !!       - the routine should be integraly rewrited and use the routine recursion.
     942              : !!       - only modified for p /= 0
     943              : !!
     944              : !! SOURCE
     945              : 
     946         5238 : subroutine entropyrec(an,bn2,nrec,trotter,ent_out,multce,debug_rec, &
     947              : &                     n_pt_integ,xmax,&
     948              : &                     ent_out1,ent_out2,ent_out3,ent_out4)
     949              : 
     950              : !Arguments -------------------------------
     951              : !scalars
     952              :  integer,intent(in) :: n_pt_integ,nrec,trotter
     953              :  logical,intent(in) :: debug_rec
     954              :  real(dp), intent(in) :: multce,xmax
     955              :  real(dp),intent(out) :: ent_out,ent_out1,ent_out2,ent_out3,ent_out4
     956              : !arrays
     957              :  real(dp),intent(in) :: an(0:nrec),bn2(0:nrec)
     958              : 
     959              : !Local variables-------------------------------
     960              : !scalars
     961              :  integer, parameter :: level = 7
     962              :  integer, save :: first_en = 1
     963              :  integer :: ii,kk,n_pt_integ_path2,n_pt_integ_path3
     964              :  real(dp) :: arg,epsilo,step,twotrotter,xmin,dr_step
     965              :  complex(dp) :: D,Dnew,Dold,N,Nnew,Nold,dz_path,ent_acc,ent_acc1,ent_acc2
     966              :  complex(dp) :: ent_acc3,ent_acc4
     967              :  complex(dp) :: funczero,z_path,zj
     968              :  complex(dp) ::delta_calc
     969              :  character(len=500) :: msg
     970              : !arrays
     971              :  real(dp) :: tsec(2)
     972              :  real(dp) :: iif,factor
     973              : ! *************************************************************************
     974              : 
     975         5238 :  call timab(610,1,tsec)
     976              : 
     977              : !structured debugging if debug_rec=T : print detailled result the first time we enter entropyrec
     978              : 
     979         5238 :  if(debug_rec .and. first_en==1)then
     980            0 :    write(msg,'(a)')' '
     981            0 :    call wrtout(std_out,msg,'PERS')
     982            0 :    write(msg,'(a)')' entropyrec : enter '
     983            0 :    call wrtout(std_out,msg,'PERS')
     984            0 :    write(msg,'(a,i6)')'n_pt_integ ' , n_pt_integ
     985            0 :    call wrtout(std_out,msg,'COLL')
     986              :  end if
     987              : 
     988         5238 :  ent_out = zero
     989         5238 :  ent_out1 = zero
     990         5238 :  ent_out2 = zero
     991         5238 :  ent_out3 = zero
     992         5238 :  ent_out4 = zero
     993         5238 :  ent_acc = czero
     994         5238 :  ent_acc1 = czero
     995         5238 :  ent_acc2 = czero
     996         5238 :  ent_acc3 = czero
     997         5238 :  ent_acc4 = czero
     998              : 
     999              : !path parameters
    1000         5238 :  twotrotter = max(two*real(trotter,dp),one)
    1001         5238 :  if(trotter==0)then
    1002              :    factor = tol5
    1003              :    arg =pi*three_quarters
    1004              :    zj = cmplx(-one,one-sin(arg),dp)
    1005              :  else
    1006         5238 :    factor = xmax/ten
    1007         5238 :    arg = pi/twotrotter
    1008         5238 :    zj = cmplx( cos(arg) , sin(arg),dp )
    1009              :  end if
    1010              : 
    1011         5238 :  epsilo = factor*sin( arg )
    1012         5238 :  xmin = factor*cos( arg )
    1013         5238 :  step = (xmax-xmin)/real(n_pt_integ,dp)
    1014              : 
    1015              : !####################################################################
    1016              : ![xmax + i*epsilo,xmin + i*epsilo]
    1017         5238 :  dr_step = one/real(n_pt_integ,dp)
    1018       534276 :  path1:  do ii = 0,n_pt_integ
    1019       529038 :    z_path = cmplx(xmin+real(ii,dp)*(xmax-xmin)*dr_step,epsilo,dp)
    1020       529038 :    dz_path = -cmplx((xmax-xmin)*dr_step,zero,dp)
    1021              : 
    1022       529038 :    Nold = czero
    1023       529038 :    Dold = cone
    1024       529038 :    N = cone
    1025       529038 :    D = z_path - cmplx(an(0),zero,dp)
    1026              : 
    1027      2116152 :    do kk=1,nrec
    1028      2116152 :      Nnew = (z_path - cmplx(an(kk),zero,dp))*N - cmplx(bn2(kk),zero,dp)*Nold
    1029      2116152 :      Dnew = (z_path - cmplx(an(kk),zero,dp))*D - cmplx(bn2(kk),zero,dp)*Dold
    1030              : 
    1031      2116152 :      Nold = N
    1032      2116152 :      Dold = D
    1033      2116152 :      N = Nnew
    1034      2116152 :      D = Dnew
    1035              : 
    1036      2645190 :      if(kk/=nrec)then
    1037      2116152 :        if((bn2(kk+1)<tol14))exit
    1038              :      end if
    1039              :    end do
    1040              : 
    1041              : !  <r|1/(z-e**(-beta/(2p)*(H-mu)))|r> dz
    1042       529038 :    delta_calc = func1_rec(z_path**twotrotter)*(N/D)*dz_path
    1043       534276 :    if(ii==0.or.ii==n_pt_integ)then
    1044        10476 :      ent_acc  = ent_acc  + half*delta_calc
    1045        10476 :      ent_acc1 = ent_acc1 + half*delta_calc
    1046              :    else
    1047       518562 :      ent_acc  = ent_acc  + delta_calc
    1048       518562 :      ent_acc1 = ent_acc1 + delta_calc
    1049              :    end if
    1050              :  end do path1
    1051              : 
    1052              : 
    1053              : !####################################################################
    1054              : ![1/2zj,0]
    1055         5238 :  if(epsilo/step>100.d0)then
    1056            0 :    n_pt_integ_path2 = int((factor*abs(zj))/step)+1
    1057              :  else
    1058         5238 :    n_pt_integ_path2 = 100
    1059              :  end if
    1060              : 
    1061         5238 :  if(trotter/=0)then
    1062         5238 :    n_pt_integ_path3 = 0
    1063         5238 :    dr_step = one/real(n_pt_integ_path2,dp)
    1064         5238 :    dz_path = -cmplx(xmin,epsilo,dp)*dr_step
    1065       534276 :    path5:  do ii = 0,n_pt_integ_path2
    1066       529038 :      z_path = cmplx(real(ii,dp)*xmin,real(ii,dp)*epsilo,dp)*dr_step
    1067       534276 :      if(abs(z_path)>tol14)then
    1068       523800 :        Nold = czero
    1069       523800 :        Dold = cone
    1070       523800 :        N = cone
    1071       523800 :        D = z_path - cmplx(an(0),zero,dp)
    1072      2095200 :        do kk=1,nrec
    1073      2095200 :          Nnew = (z_path - cmplx(an(kk),zero,dp))*N - cmplx(bn2(kk),zero,dp)*Nold
    1074      2095200 :          Dnew = (z_path - cmplx(an(kk),zero,dp))*D - cmplx(bn2(kk),zero,dp)*Dold
    1075      2095200 :          Nold = N
    1076      2095200 :          Dold = D
    1077      2095200 :          N = Nnew
    1078      2095200 :          D = Dnew
    1079      2619000 :          if(kk/=nrec)then
    1080      2095200 :            if((bn2(kk+1)<tol14))exit
    1081              :          end if
    1082              :        end do
    1083              : 
    1084              : !      <r|1/(z-e**(-beta/(2p)*(H-mu)))|r> dz
    1085       523800 :        if(abs(z_path)**twotrotter>tiny(one)) then
    1086       523800 :          funczero = func1_rec(z_path**twotrotter)
    1087              :        else
    1088              :          funczero = czero
    1089              :        end if
    1090       523800 :        delta_calc = funczero*N/D*dz_path
    1091       523800 :        if(ii==0.or.ii==n_pt_integ_path2)then
    1092         5238 :          ent_acc  = ent_acc  + half*delta_calc
    1093         5238 :          if(debug_rec) ent_acc3 = ent_acc3 + half*delta_calc
    1094              :        else
    1095       518562 :          ent_acc  = ent_acc  + funczero*delta_calc
    1096       518562 :          if(debug_rec) ent_acc3 = ent_acc3 + funczero*delta_calc
    1097              :        end if
    1098              :      end if
    1099              :    end do path5
    1100              : 
    1101              :  else  ! trotter==0
    1102              : 
    1103            0 :    n_pt_integ_path3 = max(100,int((epsilo*half*pi)/real(step,dp))+1)
    1104            0 :    dr_step = one/real(n_pt_integ_path3,dp)
    1105            0 :    path6:  do ii = 0,n_pt_integ_path3
    1106            0 :      iif=half*pi*real(ii,dp)*dr_step
    1107            0 :      z_path = epsilo*cmplx(-cos(iif),1-sin(iif),dp)
    1108            0 :      dz_path = epsilo*cmplx(sin(iif),-cos(iif),dp)*half*pi*dr_step
    1109            0 :      if(abs(z_path)**twotrotter>tol14)then
    1110            0 :        Nold = czero
    1111            0 :        Dold = cone
    1112            0 :        N = cone
    1113            0 :        D = z_path - cmplx(an(0),zero,dp)
    1114            0 :        do kk=1,nrec
    1115            0 :          Nnew = (z_path - cmplx(an(kk),zero,dp))*N - cmplx(bn2(kk),zero,dp)*Nold
    1116            0 :          Dnew = (z_path - cmplx(an(kk),zero,dp))*D - cmplx(bn2(kk),zero,dp)*Dold
    1117            0 :          Nold = N
    1118            0 :          Dold = D
    1119            0 :          N = Nnew
    1120            0 :          D = Dnew
    1121            0 :          if(kk/=nrec .and. bn2(kk+1)<tol14) exit !-EXIT
    1122              :        end do
    1123              : 
    1124              : !      <r|1/(z-e**(-beta/(2p)*(H-mu)))|r> dz
    1125            0 :        delta_calc = func1_rec(z_path**twotrotter) * N/D * dz_path
    1126            0 :        if(ii==0.or.ii==n_pt_integ_path3)then
    1127            0 :          ent_acc  = ent_acc + half*delta_calc
    1128            0 :          if(debug_rec) ent_acc3 = ent_acc3 + half*delta_calc
    1129              :        else
    1130            0 :          ent_acc  = ent_acc + delta_calc    !<r|1/(z-e**(-beta/(2p)*(H-mu)))|r> dz
    1131            0 :          if(debug_rec) ent_acc3 = ent_acc3 + delta_calc  !<r|1/(z-e**(-beta/(2p)*(H-mu)))|r> dz
    1132              :        end if
    1133              :      end if
    1134              :    end do path6
    1135              : 
    1136              :  end if
    1137              : 
    1138         5238 :  if(first_en==1 .and. debug_rec) then
    1139              :    write(msg,'(a,i5,2a,i5,2a,i5,2a,es11.4,2a,es11.4,2a,es11.4)')&
    1140            0 : &   'n_pt_path  =',n_pt_integ,ch10,&
    1141            0 : &   'n_pt_path2 =',n_pt_integ_path2,ch10,&
    1142            0 : &   'n_pt_path3 =',n_pt_integ_path3,ch10,&
    1143            0 : &   'xmin       =',xmin,ch10,&
    1144            0 : &   'xmax       =',xmax,ch10,&
    1145            0 : &   'epsilon    =',epsilo
    1146            0 :    call wrtout(std_out,msg,'COLL')
    1147            0 :    first_en = 0
    1148              :  end if
    1149              : 
    1150              : !####################################################################
    1151              : ![xmax,xmax+i*epsilo]
    1152         5238 :  dr_step = one/real(n_pt_integ_path2,dp)
    1153         5238 :  dz_path = cmplx(zero,epsilo*dr_step,dp)
    1154       534276 :  path4:  do ii = 0,n_pt_integ_path2
    1155       529038 :    z_path = cmplx(xmax,real(ii,dp)*epsilo*dr_step,dp)
    1156              : 
    1157       529038 :    Nold = czero
    1158       529038 :    Dold = cone
    1159       529038 :    N = cone
    1160       529038 :    D = z_path - cmplx(an(0),zero,dp)
    1161              : 
    1162      2116152 :    do kk=1,nrec
    1163      2116152 :      Nnew = (z_path - cmplx(an(kk),zero,dp))*N - cmplx(bn2(kk),zero,dp)*Nold
    1164      2116152 :      Dnew = (z_path - cmplx(an(kk),zero,dp))*D - cmplx(bn2(kk),zero,dp)*Dold
    1165              : 
    1166      2116152 :      Nold = N
    1167      2116152 :      Dold = D
    1168      2116152 :      N = Nnew
    1169      2116152 :      D = Dnew
    1170              : 
    1171      2645190 :      if(kk/=nrec)then
    1172      2116152 :        if((bn2(kk+1)<tol14))exit
    1173              :      end if
    1174              :    end do
    1175              : 
    1176              : !  <r|1/(z-e**(-beta/(2p)*(H-mu)))|r> dz
    1177       529038 :    delta_calc = func1_rec(z_path**twotrotter)*N/D*dz_path
    1178       534276 :    if(ii==0.or.ii==n_pt_integ_path2)then
    1179              : 
    1180        10476 :      ent_acc =  ent_acc  + half*delta_calc
    1181        10476 :      if(debug_rec) ent_acc2 = ent_acc2 + half*delta_calc
    1182              :    else
    1183       518562 :      ent_acc  = ent_acc  + delta_calc
    1184       518562 :      if(debug_rec) ent_acc2 = ent_acc2 + delta_calc
    1185              :    end if
    1186              :  end do path4
    1187              : 
    1188              : 
    1189         5238 :  ent_out  = multce*real(ent_acc*cmplx(zero,-piinv,dp),dp)
    1190         5238 :  if(debug_rec) then
    1191            0 :    ent_out1 = multce*real(ent_acc1*cmplx(zero,-piinv,dp),dp)
    1192            0 :    ent_out2 = multce*real(ent_acc2*cmplx(zero,-piinv,dp),dp)
    1193            0 :    ent_out3 = multce*real(ent_acc3*cmplx(zero,-piinv,dp),dp)
    1194            0 :    ent_out4 = multce*real(ent_acc4*cmplx(zero,-piinv,dp),dp)
    1195              :  end if
    1196              : 
    1197         5238 :  call timab(610,2,tsec)
    1198              : 
    1199              :  contains
    1200              : 
    1201              : !function to integrate over the path
    1202              : !func1_rec(z_path,twotrotter) =  ( z_path**twotrotter/(1+z_path**twotrotter)*log(1+1/z_path**twotrotter)+&    !- f*ln(f)
    1203              : !&1/(1+z_path**twotrotter)*log(1+z_path**twotrotter))       !- (1-f)*ln(1-f)
    1204              : 
    1205              : !func1_rec(z_path_pow) =   z_path_pow/(cone+z_path_pow)*log(cone+cone/z_path_pow)+&    !- f*ln(f)
    1206              : !&cone/(cone+z_path_pow)*log(cone+z_path_pow)       !- (1-f)*ln(1-f)
    1207              : 
    1208              : !other expression of func for a path like ro(t)*exp(2*i*pi/(2*p)*(j+1/2))
    1209              : 
    1210      1581876 :    function func1_rec(z)
    1211              : 
    1212              :    complex(dp) :: func1_rec
    1213              :    complex(dp),intent(in) :: z
    1214              : 
    1215      1581876 :    func1_rec =   z/(cone+z)*log(cone+cone/z)+ cone/(cone+z)*log(cone+z)
    1216              : 
    1217      1581876 :  end function func1_rec
    1218              : 
    1219              : end subroutine entropyrec
    1220              : !!***
    1221              : 
    1222              : !!****f* ABINIT/fermisolverec
    1223              : !! NAME
    1224              : !! fermisolverec
    1225              : !!
    1226              : !! FUNCTION
    1227              : !! This routine computes the fermi energy in order to have a given number of
    1228              : !! valence electrons in the recursion method, using a Ridder s Method
    1229              : !!
    1230              : !! INPUTS
    1231              : !!  debug_rec=debugging variable
    1232              : !!  nb_rec=order of recursion
    1233              : !!  nb_point=number of discretization point in one dimension (=n1=n2=n3)
    1234              : !!  temperature=temperature (Hartree)
    1235              : !!  trotter=trotter parameter
    1236              : !!  nelect=number of valence electrons (dtset%nelect)
    1237              : !!  acc=accuracy for the fermi energy
    1238              : !!  max_it=maximum number of iteration for the Ridder's Method
    1239              : !!  long_tranche=number of point computed by thi proc
    1240              : !!  mpi_enreg=information about MPI parallelization
    1241              : !!  inf_ucvol=infinitesimal unit cell volume
    1242              : !!  gputopo=true if topology gpu-cpu= 2 or 3
    1243              : !!
    1244              : !! OUTPUT
    1245              : !!
    1246              : !! SIDE EFFECTS
    1247              : !!  fermie=fermi energy
    1248              : !!  rho=density, recomputed for the new fermi energy
    1249              : !!  a, b2 : coefficient given by recursion recomputed for the new fermi energy
    1250              : !!
    1251              : !! NOTES
    1252              : !!  at this time :
    1253              : !!
    1254              : !! SOURCE
    1255              : 
    1256           38 : subroutine fermisolverec(fermie,rho,a,b2,debug_rec,nb_rec, &
    1257              :   &                      temperature,trotter,nelect, &
    1258              :   &                      acc, max_it, &
    1259              :   &                      long_tranche,mpi_enreg,&
    1260              :   &                      inf_ucvol,gputopo)
    1261              : 
    1262              : !Arguments -------------------------------
    1263              :  !scalars
    1264              :  integer,intent(in) :: long_tranche,max_it,nb_rec,trotter
    1265              :  logical,intent(in) :: debug_rec,gputopo
    1266              :  real(dp),intent(in) :: acc,inf_ucvol,nelect,temperature
    1267              :  real(dp), intent(inout) :: fermie
    1268              :  type(MPI_type),intent(in) :: mpi_enreg
    1269              :  !arrays
    1270              :  real(dp), intent(inout) :: a(0:nb_rec,long_tranche), b2(0:nb_rec,long_tranche)
    1271              :  real(dp), intent(inout) :: rho(long_tranche)
    1272              : 
    1273              : !Local variables-------------------------------
    1274              :  !scalars
    1275              :  integer  ::  ierr,ii,ipointlocal,nn,dim_trott
    1276              :  real(dp) :: beta,fermieh,fermiel,fermiem,fermienew,nelecth,nelectl,nelectm
    1277              :  real(dp) :: nelectnew,res_nelecth,res_nelectl,res_nelectm,res_nelectnew
    1278              :  real(dp) :: rtrotter,ss,fermitol
    1279              :  character(len=500) :: msg
    1280              :  !arrays
    1281              :  real(dp) :: tsec(2)
    1282           76 :  real(dp) :: rhotry(long_tranche)
    1283              :  !no_abirules
    1284              : #ifdef HAVE_GPU_CUDA
    1285              :  integer :: swt_tm,npitch
    1286              :  real(cudap) :: rhocu(long_tranche)
    1287              :  real(dp) :: tsec2(2)
    1288              : #endif
    1289              : 
    1290              : ! *************************************************************************
    1291              : 
    1292              : #ifdef HAVE_GPU_CUDA
    1293              :  swt_tm = 0
    1294              : #endif
    1295              : 
    1296           38 :  call timab(609,1,tsec)
    1297              : 
    1298           38 :  beta = one/temperature
    1299           38 :  rtrotter  = max(half,real(trotter,dp))
    1300           38 :  dim_trott = max(0,2*trotter-1)
    1301              : 
    1302           38 :  write(msg,'(a)')' -- fermisolverec ---------------------------------'
    1303           38 :  call wrtout(std_out,msg,'COLL')
    1304           38 :  if(debug_rec) then
    1305            0 :    write (msg,'(a,d10.3)')' nelect= ',nelect
    1306            0 :    call wrtout(std_out,msg,'COLL')
    1307              :  end if
    1308              : !initialisation of fermiel
    1309           38 :  fermiel = fermie
    1310           38 :  call timab(609,2,tsec)
    1311              : 
    1312              : !initialisation fermitol
    1313           38 :  fermitol = acc
    1314              : #ifdef HAVE_GPU_CUDA_SP
    1315              :  if(gputopo)  fermitol = 1.d-3
    1316              : #endif
    1317              : 
    1318           38 :  if(gputopo) then
    1319              : #ifdef HAVE_GPU_CUDA
    1320              :    swt_tm = 1
    1321              : !  allocate array an and bn2 on gpu for computation of trotter formula
    1322              :    call alloc_dens_cuda(long_tranche,nb_rec,dim_trott,npitch,&
    1323              : &   real(a,cudap),real(b2,cudap))
    1324              : 
    1325              :    call timab(617,1,tsec)
    1326              :    call density_cuda(npitch,long_tranche,nb_rec,dim_trott,&
    1327              : &   real(fermiel,cudap),real(temperature,cudap),&
    1328              : &   real(rtrotter,cudap),real(inf_ucvol,cudap),&
    1329              : &   real(tol14,cudap),&
    1330              : &   rhocu)
    1331              :    rhotry = real(rhocu,dp)
    1332              :    call timab(617,2,tsec)
    1333              : #endif
    1334              :  else
    1335        29414 :    do ipointlocal = 1,long_tranche
    1336              :      call density_rec(a(:,ipointlocal),&
    1337              : &     b2(:,ipointlocal),&
    1338              : &     rhotry(ipointlocal),&
    1339              : &     nb_rec,fermiel,temperature,rtrotter,dim_trott, &
    1340        29414 : &     tol14,inf_ucvol)
    1341              :    end do
    1342              :  end if
    1343              : 
    1344           38 :  call timab(609,1,tsec)
    1345        29414 :  nelectl = sum(rhotry)
    1346           38 :  call xmpi_sum( nelectl,mpi_enreg%comm_bandfft,ierr)
    1347           38 :  res_nelectl = inf_ucvol*nelectl - nelect
    1348              : 
    1349           38 :  if (res_nelectl /= zero) then
    1350              : !  initialisation of fermih
    1351              : !  excess of electrons -> smaller fermi
    1352           38 :    res_nelecth = zero
    1353           38 :    ii = 1
    1354           38 :    fermieh = fermie - ten*sign(one,res_nelectl)*temperature
    1355           76 :    do while(ii<6 .and. res_nelecth*res_nelectl>=0)
    1356           38 :      fermieh = fermieh - ten*sign(one,res_nelectl)*temperature
    1357           38 :      call timab(609,2,tsec)
    1358              : 
    1359           38 :      if(gputopo) then
    1360              : #ifdef HAVE_GPU_CUDA
    1361              :        call timab(617,1,tsec)
    1362              :        call density_cuda(npitch,long_tranche,nb_rec,dim_trott,&
    1363              : &       real(fermieh,cudap),real(temperature,cudap),&
    1364              : &       real(rtrotter,cudap),real(inf_ucvol,cudap),&
    1365              : &       real(tol14,cudap),&
    1366              : &       rhocu)
    1367              :        rhotry = real(rhocu,dp)
    1368              :        call timab(617,2,tsec)
    1369              : #endif
    1370              :      else
    1371        29414 :        do ipointlocal = 1,long_tranche
    1372              :          call density_rec(a(:,ipointlocal),  &
    1373              : &         b2(:,ipointlocal), &
    1374              : &         rhotry(ipointlocal), &
    1375              : &         nb_rec,fermieh,temperature,rtrotter,dim_trott, &
    1376        29414 : &         tol14,inf_ucvol)
    1377              :        end do
    1378              :      end if
    1379           38 :      call timab(609,1,tsec)
    1380        29414 :      nelecth = sum(rhotry)
    1381           38 :      call xmpi_sum( nelecth,mpi_enreg%comm_bandfft ,ierr);
    1382           38 :      res_nelecth = inf_ucvol*nelecth - nelect
    1383              : 
    1384           38 :      if(debug_rec) then
    1385            0 :        write (msg,'(a,es11.4e2,a,es11.4e2)') ' Fermi energy interval',fermieh,' ',fermiel
    1386            0 :        call wrtout(std_out,msg,'COLL')
    1387              :      end if
    1388           76 :      ii = ii +1
    1389              :    end do
    1390              : 
    1391           38 :    if (res_nelecth*res_nelectl>0) then
    1392            0 :      write (msg,'(4a)')' fermisolverec : ERROR- ',ch10,&
    1393            0 : &     ' initial guess for fermi energy doesnt permit to  find solutions in solver',ch10
    1394            0 :      ABI_ERROR(msg)
    1395              :    end if
    1396              : 
    1397              : !  MAIN LOOP   ------------------------------------------------------
    1398          143 :    main : do nn=1,max_it
    1399              : !    fermiem computation
    1400          143 :      fermiem = 0.5d0*(fermiel+fermieh)
    1401              : 
    1402              : !    nelectm = zero
    1403          143 :      call timab(609,2,tsec)
    1404              : 
    1405          143 :      if(gputopo) then
    1406              : #ifdef HAVE_GPU_CUDA
    1407              :        call timab(617,1,tsec)
    1408              :        call density_cuda(npitch,long_tranche,nb_rec,dim_trott,&
    1409              : &       real(fermiem,cudap),real(temperature,cudap),&
    1410              : &       real(rtrotter,cudap),real(inf_ucvol,cudap),&
    1411              : &       real(tol14,cudap),&
    1412              : &       rhocu)
    1413              :        rhotry = real(rhocu,dp)
    1414              :        call timab(617,2,tsec)
    1415              : #endif
    1416              :      else
    1417       112463 :        do ipointlocal = 1,long_tranche
    1418              :          call density_rec(a(:,ipointlocal),  &
    1419              : &         b2(:,ipointlocal), &
    1420              : &         rhotry(ipointlocal), &
    1421              : &         nb_rec,fermiem,temperature,rtrotter,dim_trott, &
    1422       112463 : &         tol14,inf_ucvol)
    1423              :        end do
    1424              :      end if
    1425              : 
    1426          143 :      call timab(609,1,tsec)
    1427       112463 :      nelectm = sum(rhotry)
    1428          143 :      call xmpi_sum( nelectm,mpi_enreg%comm_bandfft,ierr)
    1429          143 :      res_nelectm = inf_ucvol*nelectm - nelect
    1430              : 
    1431              : !    new guess
    1432          143 :      ss = sqrt(res_nelectm**two-res_nelectl*res_nelecth)
    1433          143 :      fermienew = fermiem + (fermiem-fermiel)*sign(one, res_nelectl-res_nelecth)*res_nelectm/ss
    1434              : 
    1435          143 :      call timab(609,2,tsec)
    1436          143 :      if(gputopo) then
    1437              : #ifdef HAVE_GPU_CUDA
    1438              :        call timab(617,1,tsec)
    1439              :        call density_cuda(npitch,long_tranche,nb_rec,dim_trott,&
    1440              : &       real(fermienew,cudap),real(temperature,cudap),&
    1441              : &       real(rtrotter,cudap),real(inf_ucvol,cudap),&
    1442              : &       real(tol14,cudap),&
    1443              : &       rhocu)
    1444              :        rhotry = real(rhocu,dp)
    1445              :        call timab(617,2,tsec)
    1446              : #endif
    1447              :      else
    1448       112463 :        do ipointlocal = 1,long_tranche
    1449              :          call density_rec(a(:,ipointlocal),  &
    1450              : &         b2(:,ipointlocal), &
    1451              : &         rhotry(ipointlocal), &
    1452              : &         nb_rec,fermienew,temperature,rtrotter,dim_trott, &
    1453       112463 : &         tol14,inf_ucvol)
    1454              :        end do
    1455              :      end if
    1456              : 
    1457          143 :      call timab(609,1,tsec)
    1458       112463 :      nelectnew = sum(rhotry)
    1459          143 :      call xmpi_sum( nelectnew,mpi_enreg%comm_bandfft ,ierr);
    1460          143 :      res_nelectnew = inf_ucvol*nelectnew - nelect
    1461              : 
    1462              : !    fermiel et fermieh for new iteration
    1463          143 :      if (sign(res_nelectm,res_nelectnew) /= res_nelectm) then
    1464           30 :        fermiel = fermiem
    1465           30 :        res_nelectl = res_nelectm
    1466           30 :        fermieh = fermienew
    1467           30 :        res_nelecth = res_nelectnew
    1468          113 :      else if (sign(res_nelectl,res_nelectnew) /= res_nelectl) then
    1469           74 :        fermieh = fermienew
    1470           74 :        res_nelecth = res_nelectnew
    1471           39 :      else if (sign(res_nelecth,res_nelectnew) /= res_nelecth) then
    1472           39 :        fermiel = fermienew
    1473           39 :        res_nelectl = res_nelectnew
    1474              :      end if
    1475              : 
    1476              : !    are we within the tolerance ?
    1477          429 :      if ((abs(res_nelectnew) < fermitol).or.(nn == max_it)) then
    1478           38 :        fermie = fermienew
    1479        29414 :        rho = rhotry
    1480           38 :        if(debug_rec) then
    1481            0 :          write (msg,'(a,es11.4e2,a,i4)')' err, num_iter ', res_nelectnew, ' ',nn
    1482            0 :          call wrtout(std_out,msg,'COLL')
    1483            0 :          write(msg,'(a,50a)')' ',('-',ii=1,50)
    1484            0 :          call wrtout(std_out,msg,'COLL')
    1485              :        end if
    1486              :        exit main
    1487              :      end if
    1488              : 
    1489              :    end do main
    1490              : 
    1491              :  end if
    1492              : 
    1493              : #ifdef HAVE_GPU_CUDA
    1494              : !deallocate array on GPU
    1495              :  if(gputopo) then
    1496              :    call dealloc_dens_cuda()
    1497              :  end if
    1498              :  call timab(613+swt_tm,1,tsec2)  !!--start time-counter: sync gpu-cpu
    1499              :  call xmpi_barrier(mpi_enreg%comm_bandfft)
    1500              :  call timab(613+swt_tm,2,tsec2)  !!--stop time-counter: sync gpu-cpu
    1501              : #endif
    1502              : 
    1503           38 :  call timab(609,2,tsec)
    1504           38 : end subroutine fermisolverec
    1505              : !!***
    1506              : 
    1507              : !!****f* ABINIT/density_rec
    1508              : !! NAME
    1509              : !! density_rec
    1510              : !!
    1511              : !! FUNCTION
    1512              : !! This routine computes the density using  the coefficients corresponding to
    1513              : !! continued fraction at a point from a fixed potential.
    1514              : !!
    1515              : !! INPUTS
    1516              : !!  coordx, coordy, coordz=coordonnees of the computed point
    1517              : !!  an, bn2 : coefficient given by density_rec. Input if get_rec_coef=0, output else
    1518              : !!  nrec=order of density_rec
    1519              : !!  fermie=fermi energy (Hartree)
    1520              : !!  tsmear=temperature (Hartree)
    1521              : !!  rtrotter=real trotter parameter
    1522              : !!  tol=tolerance criteria for stopping density_rec
    1523              : !!  inf_ucvol=infinitesimal unit cell volume
    1524              : !!  dim_trott = max(0,2*trotter-1)
    1525              : !!
    1526              : !! OUTPUT
    1527              : !!  rho_out=result of the continued fraction multiplied by a multiplicator
    1528              : !!
    1529              : !! SIDE EFFECTS
    1530              : !!
    1531              : !! NOTES
    1532              : !!  at this time :
    1533              : !!       - exppot should be replaced by ?
    1534              : !!       - coord should be replaced by ?
    1535              : !!       - need a rectangular box (rmet diagonal matrix)
    1536              : !!
    1537              : !! SOURCE
    1538              : 
    1539       283392 : subroutine density_rec(an,bn2,rho_out,nrec, &
    1540              : &                     fermie,tsmear,rtrotter, &
    1541              : &                     dim_trott,tol,inf_ucvol)
    1542              : 
    1543              : !Arguments -------------------------------
    1544              : !scalars
    1545              :  integer,intent(in) :: nrec
    1546              :  integer,intent(in) :: dim_trott
    1547              :  real(dp),intent(in) :: fermie,tol,tsmear,inf_ucvol,rtrotter
    1548              :  real(dp), intent(out) :: rho_out
    1549              : !arrays
    1550              :  real(dp),intent(in) :: an(0:nrec),bn2(0:nrec)
    1551              : !Local variables-------------------------------
    1552              : !not used, debugging purpose only
    1553              : !for debugging purpose, detailled printing only once for density and ekin
    1554              : !scalars
    1555              :  integer, parameter :: minrec = 3
    1556              :  integer  :: irec
    1557              :  real(dp) :: beta,mult,prod_b2,error,errold
    1558              :  real(dp) :: pi_on_rtrotter,twortrotter,exp1,exp2
    1559              :  complex(dp) :: cinv2rtrotter,coeef_mu,facrec0
    1560              : ! character(len=500) :: msg
    1561              : !arrays
    1562              :  real(dp) :: tsec(2)
    1563       566784 :  complex(dp) :: acc_rho(0:nrec)
    1564       566784 :  complex(dp) :: D(0:dim_trott),Dold(0:dim_trott)
    1565       566784 :  complex(dp) :: N(0:dim_trott),Nold(0:dim_trott)
    1566              : !**************************************************************************
    1567              : 
    1568       283392 :  call timab(605,1,tsec)
    1569              : 
    1570              : !##############################################################
    1571              : !--Initialisation of metrics
    1572       283392 :  mult = two/inf_ucvol   !non-spined system
    1573       283392 :  beta = one/tsmear
    1574              : 
    1575              : !--Variables for optimisation
    1576       283392 :  pi_on_rtrotter = pi/rtrotter
    1577       283392 :  twortrotter = two*rtrotter
    1578       283392 :  exp1 = exp((beta*fermie)/(rtrotter))
    1579       283392 :  exp2 = exp(beta*fermie/(twortrotter))
    1580       283392 :  cinv2rtrotter = cmplx(one/twortrotter,zero,dp)
    1581       283392 :  coeef_mu = cmplx(one/exp2,zero,dp)
    1582              : 
    1583     11619072 :  N = czero;  D = cone
    1584       283392 :  facrec0 = cone
    1585     11619072 :  Nold = czero; Dold = czero
    1586              : !--Initialisation of accumulated density
    1587      5460480 :  acc_rho = czero
    1588              : !--Initialisation of estimated error
    1589       283392 :  prod_b2 = twortrotter/exp1
    1590       283392 :  errold = zero
    1591              : 
    1592              : 
    1593              : !##############################################################
    1594              : !--Main loop
    1595      1353567 :  maindo : do irec = 0, nrec
    1596              : 
    1597              : !  ######################################################
    1598              : !  --Density computation
    1599              : !  !--using the property that: sum_i(bi*c)^2|(z-ai*c)=1/c*sum_i(bi)^2|(z/c-ai)
    1600              : !  !and for c =exp(-beta*fermie/(two*rtrotter)
    1601              : 
    1602              :    call trottersum(dim_trott,error,prod_b2,pi_on_rtrotter,&
    1603              : &   facrec0,coeef_mu,exp1,&
    1604              : &   an(irec),bn2(irec),&
    1605      1353567 : &   N,D,Nold,Dold)
    1606              : 
    1607      1353567 :    if(irec/=nrec .and. irec>=minrec)then
    1608       503391 :      if((bn2(irec+1)<tol14).or.(mult*error<tol.and.errold<tol)) exit maindo
    1609              :    end if
    1610      1353567 :    errold = mult*error
    1611              :  end do maindo
    1612              : !--Accumulated density
    1613      5951232 :  rho_out = mult*real(cone-sum(N/D)*cinv2rtrotter,dp)
    1614              : 
    1615       283392 :  call timab(605,2,tsec)
    1616              : 
    1617       283392 :  end subroutine density_rec
    1618              : !!***
    1619              : 
    1620              : !!****f* ABINIT/gran_potrec
    1621              : !! NAME
    1622              : !! gran_potrec
    1623              : !!
    1624              : !! FUNCTION
    1625              : !! This routine computes the local part of the grand-potential at a point using a path integral,
    1626              : !! in the recursion method.
    1627              : !!
    1628              : !! INPUTS
    1629              : !!  an, bn2 : coefficient given by the recursion.
    1630              : !!  nrec=order of recursion
    1631              : !!  trotter=trotter parameter
    1632              : !!  mult=a multiplicator for computing grand-potential (2 for non-spin-polarized system)
    1633              : !!  debug_rec=debugging variable
    1634              : !!  n_pt_integ=points for computation of path integral
    1635              : !!  xmax= maximum point on the x-axis for integration
    1636              : !!
    1637              : !! OUTPUT
    1638              : !!  ene_out=grand-potential at the point
    1639              : !!  if debug_rec=T then ene_out1,ene_out2,ene_out3,ene_out4 are
    1640              : !!  the different path branch contriubutions to the grand-potential.
    1641              : !!  In reality it is not the gren potential but the
    1642              : !!  grand-potential (omega=-PV) divided by -T
    1643              : !!
    1644              : !! NOTES
    1645              : !!  in reality it is not the gren potential but the grand-potential (omega=-PV) divided by -T
    1646              : !!  at this time :
    1647              : !!       - mult should be not used
    1648              : !!       - the routine should be integraly rewrited and use the routine recursion.
    1649              : !!       - only modified for p /= 0
    1650              : !!
    1651              : !! SOURCE
    1652              : 
    1653         5238 : subroutine gran_potrec(an,bn2,nrec,trotter,ene_out, mult, &
    1654              : &                     debug_rec,n_pt_integ,xmax,&
    1655              : &                     ene_out1,ene_out2,ene_out3,ene_out4)
    1656              : 
    1657              : !Arguments -------------------------------
    1658              : !scalars
    1659              :  integer,intent(in) :: n_pt_integ,nrec,trotter
    1660              :  logical,intent(in) :: debug_rec
    1661              :  real(dp), intent(in) :: mult,xmax
    1662              :  real(dp),intent(inout) :: ene_out,ene_out1,ene_out2,ene_out3,ene_out4 !vz_i
    1663              : !arrays
    1664              :  real(dp), intent(in) :: an(0:nrec),bn2(0:nrec)
    1665              : 
    1666              : !Local variables-------------------------------
    1667              : !scalars
    1668              :  integer, parameter :: level = 7
    1669              :  integer, save :: first = 1
    1670              :  integer :: ii,kk,n_pt_integ_path2
    1671              :  real(dp) :: epsilon,step,twotrotter,xmin,dr_step
    1672              :  complex(dp) :: D,Dnew,Dold,N,Nnew,Nold,dz_path,ene_acc,ene_acc1,ene_acc2
    1673              :  complex(dp) :: ene_acc3,ene_acc4
    1674              :  complex(dp) :: z_path,delta_calc
    1675              :  character(len=500) :: message
    1676              : !arrays
    1677              :  real(dp) :: tsec(2)
    1678              : ! *************************************************************************
    1679              : 
    1680              : 
    1681         5238 :  call timab(611,1,tsec)
    1682              : 
    1683              : !structured debugging if debug_rec=T : print detailled result the first time we enter gran_potrec
    1684         5238 :  if(debug_rec .and. first==1)then
    1685            0 :    write(message,'(a)')' '
    1686            0 :    call wrtout(std_out,message,'PERS')
    1687            0 :    write(message,'(a)')' gran_potrec : enter '
    1688            0 :    call wrtout(std_out,message,'PERS')
    1689            0 :    write(message,'(a,i8)')'n_pt_integ ' , n_pt_integ
    1690            0 :    call wrtout(std_out,message,'COLL')
    1691            0 :    first=0
    1692              :  end if
    1693              : 
    1694         5238 :  ene_out = zero
    1695         5238 :  ene_acc = czero
    1696         5238 :  ene_acc1 = czero
    1697         5238 :  ene_acc2 = czero
    1698         5238 :  ene_acc3 = czero
    1699         5238 :  ene_acc4 = czero
    1700              : 
    1701              : 
    1702              : !path parameters
    1703              : !n_pt_integ = 2500
    1704         5238 :  xmin = -half
    1705         5238 :  step = (xmax-xmin)/real(n_pt_integ,dp)
    1706         5238 :  if(trotter==0)then
    1707            0 :    twotrotter = one
    1708            0 :    epsilon = .5d-1
    1709              :  else
    1710         5238 :    twotrotter = two*real(trotter,dp)
    1711         5238 :    epsilon = half*sin( pi/twotrotter)
    1712              :  end if
    1713              : 
    1714              : !xmin = -abs(xmin)**(1.d0/twotrotter)
    1715              : 
    1716              : !####################################################################
    1717              : ![xmax + i*epsilon,xmin + i*epsilon]
    1718         5238 :  dr_step = one/real(n_pt_integ,dp)
    1719         5238 :  dz_path = -cmplx((xmax-xmin)*dr_step,zero,dp)
    1720       534276 :  path1:  do ii = 0,n_pt_integ
    1721              : !  z_path = cmplx(xmin + real(ii,dp)*(xmax-xmin)*dr_step,epsilon,dp)
    1722       529038 :    z_path = cmplx(xmin,epsilon,dp) - real(ii,dp)*dz_path
    1723       529038 :    Nold = czero
    1724       529038 :    Dold = cone
    1725       529038 :    N = cone
    1726       529038 :    D = z_path - cmplx(an(0),zero,dp)
    1727              : 
    1728      2116152 :    do kk=1,nrec
    1729      2116152 :      Nnew = (z_path - cmplx(an(kk),zero,dp))*N - cmplx(bn2(kk),zero,dp)*Nold
    1730      2116152 :      Dnew = (z_path - cmplx(an(kk),zero,dp))*D - cmplx(bn2(kk),zero,dp)*Dold
    1731              : 
    1732      2116152 :      Nold = N
    1733      2116152 :      Dold = D
    1734      2116152 :      N = Nnew
    1735      2116152 :      D = Dnew
    1736              : 
    1737      2645190 :      if(kk/=nrec)then
    1738      2116152 :        if((bn2(kk+1)<tol14))exit
    1739              :      end if
    1740              : 
    1741              :    end do
    1742              : 
    1743              : !  <r|1/(z-e**(-beta/(2p)*(H-mu)))|r> dz
    1744       529038 :    delta_calc = func_rec(z_path,twotrotter)* N/D *dz_path
    1745       534276 :    if(ii==0.or.ii==n_pt_integ)then
    1746        10476 :      ene_acc = ene_acc + half*delta_calc
    1747        10476 :      if(debug_rec)  ene_acc1 = ene_acc1 + half*delta_calc
    1748              :    else
    1749       518562 :      ene_acc = ene_acc + delta_calc
    1750       518562 :      if(debug_rec)  ene_acc1 = ene_acc1 + delta_calc
    1751              :    end if
    1752              :  end do path1
    1753              : 
    1754              : !####################################################################
    1755              : ![xmin + i*epsilon,xmin]
    1756         5238 :  if(epsilon/step>4.d0)then
    1757              :    n_pt_integ_path2 = int(epsilon/step)+1
    1758              :  else
    1759              :    n_pt_integ_path2 = 5
    1760              :  end if
    1761         5238 :  n_pt_integ_path2 = n_pt_integ
    1762         5238 :  dr_step = one/real(n_pt_integ_path2,dp)
    1763         5238 :  dz_path = -cmplx(zero,epsilon*dr_step,dp)
    1764       534276 :  path2:  do ii = 0,n_pt_integ_path2
    1765              : !  z_path = cmplx(xmin,real(ii,dp)*epsilon*dr_step,dp)
    1766       529038 :    z_path = cmplx(xmin,zero,dp)-dz_path*real(ii,dp)
    1767       529038 :    Nold = czero
    1768       529038 :    Dold = cone
    1769       529038 :    N = cone
    1770       529038 :    D = z_path - cmplx(an(0),zero,dp)
    1771              : 
    1772      2116152 :    do kk=1,nrec
    1773      2116152 :      Nnew = (z_path - cmplx(an(kk),zero,dp))*N - cmplx(bn2(kk),zero,dp)*Nold
    1774      2116152 :      Dnew = (z_path - cmplx(an(kk),zero,dp))*D - cmplx(bn2(kk),zero,dp)*Dold
    1775              : 
    1776      2116152 :      Nold = N
    1777      2116152 :      Dold = D
    1778      2116152 :      N = Nnew
    1779      2116152 :      D = Dnew
    1780              : 
    1781      2645190 :      if(kk/=nrec)then
    1782      2116152 :        if((bn2(kk+1)<tol14))exit
    1783              :      end if
    1784              : 
    1785              :    end do
    1786              : 
    1787              : !  <r|1/(z-e**(-beta/(2p)*(H-mu)))|r> dz
    1788       529038 :    delta_calc = func_rec(z_path,twotrotter)* N/D *dz_path
    1789       534276 :    if(ii==0.or.ii==n_pt_integ_path2)then
    1790        10476 :      ene_acc = ene_acc + half*delta_calc
    1791        10476 :      if(debug_rec) ene_acc3 = ene_acc3 + half*delta_calc
    1792              :    else
    1793       518562 :      ene_acc = ene_acc + delta_calc
    1794       518562 :      if(debug_rec) ene_acc3 = ene_acc3 + delta_calc
    1795              :    end if
    1796              :  end do path2
    1797              : 
    1798              : 
    1799              : 
    1800              : !####################################################################
    1801              : ![xmin,0]
    1802              :  if(xmin/=czero)then
    1803         5238 :    dr_step = one/real(n_pt_integ,dp)
    1804         5238 :    dz_path = cmplx(xmin*dr_step,zero,dp)
    1805       529038 :    path3:  do ii = 1,n_pt_integ !the integrand is 0 at 0
    1806              : !    z_path = cmplx(real(ii,dp)*xmin*dr_step,zero,dp)
    1807       523800 :      z_path = real(ii,dp)*dz_path
    1808              : 
    1809       523800 :      Nold = czero
    1810       523800 :      Dold = cone
    1811       523800 :      N = cone
    1812       523800 :      D = z_path - cmplx(an(0),zero,dp)
    1813              : 
    1814      2095200 :      do kk=1,nrec
    1815      2095200 :        Nnew = (z_path - cmplx(an(kk),zero,dp))*N - cmplx(bn2(kk),zero,dp)*Nold
    1816      2095200 :        Dnew = (z_path - cmplx(an(kk),zero,dp))*D - cmplx(bn2(kk),zero,dp)*Dold
    1817              : 
    1818      2095200 :        Nold = N
    1819      2095200 :        Dold = D
    1820      2095200 :        N = Nnew
    1821      2095200 :        D = Dnew
    1822              : 
    1823      2619000 :        if(kk/=nrec)then
    1824      2095200 :          if((bn2(kk+1)<tol14))exit
    1825              :        end if
    1826              :      end do
    1827              : 
    1828              : !    <r|1/(z-e**(-beta/(2p)*(H-mu)))|r> dz
    1829       523800 :      delta_calc = func_rec(z_path,twotrotter) * N/D *dz_path
    1830       529038 :      if(ii==n_pt_integ)then
    1831         5238 :        ene_acc = ene_acc +half*delta_calc
    1832         5238 :        if(debug_rec) ene_acc4 = ene_acc4 + half*delta_calc
    1833              :      else
    1834       518562 :        ene_acc = ene_acc + delta_calc
    1835       518562 :        if(debug_rec) ene_acc4 = ene_acc4 +delta_calc
    1836              :      end if
    1837              :    end do path3
    1838              :  end if
    1839              : 
    1840              : !####################################################################
    1841              : ![xmax,xmax+i*epsilon]
    1842       534276 :  dr_step = one/real(n_pt_integ_path2,dp)
    1843       534276 :  dz_path = cmplx(zero,epsilon*dr_step,dp)
    1844       534276 :  path4:  do ii = 0,n_pt_integ_path2
    1845              : !  z_path = cmplx(xmax,real(ii,dp)*epsilon*dr_step,dp)
    1846       529038 :    z_path = cmplx(xmax,0,dp)+real(ii,dp)*dz_path
    1847              : 
    1848       529038 :    Nold = czero
    1849       529038 :    Dold = cone
    1850       529038 :    N = cone
    1851       529038 :    D = z_path - cmplx(an(0),zero,dp)
    1852              : 
    1853      2116152 :    do kk=1,nrec
    1854      2116152 :      Nnew = (z_path - cmplx(an(kk),zero,dp))*N - cmplx(bn2(kk),zero,dp)*Nold
    1855      2116152 :      Dnew = (z_path - cmplx(an(kk),zero,dp))*D - cmplx(bn2(kk),zero,dp)*Dold
    1856              : 
    1857      2116152 :      Nold = N
    1858      2116152 :      Dold = D
    1859      2116152 :      N = Nnew
    1860      2116152 :      D = Dnew
    1861              : 
    1862      2645190 :      if(kk/=nrec)then
    1863      2116152 :        if((bn2(kk+1)<tol14))exit
    1864              :      end if
    1865              : 
    1866              :    end do
    1867              : 
    1868              : !  <r|1/(z-e**(-beta/(2p)*(H-mu)))|r> dz
    1869       529038 :    delta_calc = func_rec(z_path,twotrotter) * N/D *dz_path
    1870       534276 :    if(ii==0.or.ii==n_pt_integ_path2)then
    1871        10476 :      ene_acc = ene_acc + half*delta_calc
    1872        10476 :      if(debug_rec) ene_acc2 = ene_acc2 + half*delta_calc
    1873              :    else
    1874       518562 :      ene_acc = ene_acc + delta_calc
    1875       518562 :      if(debug_rec) ene_acc2 = ene_acc2 + delta_calc
    1876              :    end if
    1877              :  end do path4
    1878              : 
    1879         5238 :  ene_out = mult*real(ene_acc*cmplx(zero,-piinv,dp),dp)
    1880         5238 :  if(debug_rec) then
    1881            0 :    ene_out1 = mult*real(ene_acc1*cmplx(zero,-piinv,dp),dp)
    1882            0 :    ene_out2 = mult*real(ene_acc2*cmplx(zero,-piinv,dp),dp)
    1883            0 :    ene_out3 = mult*real(ene_acc3*cmplx(zero,-piinv,dp),dp)
    1884            0 :    ene_out4 = mult*real(ene_acc4*cmplx(zero,-piinv,dp),dp)
    1885              :  end if
    1886              : 
    1887         5238 :  call timab(611,2,tsec)
    1888              : 
    1889              :  contains
    1890              : 
    1891              : !func_rec(z_path,twotrotter) = log(cone+z_path**twotrotter)
    1892              : 
    1893      2110914 :    function func_rec(z,x)
    1894              : 
    1895              :    complex(dp) :: func_rec
    1896              :    complex(dp),intent(in) :: z
    1897              :    real(dp),intent(in) :: x
    1898              : 
    1899      2110914 :    func_rec = log(cone+z**x)
    1900              : 
    1901      2110914 :  end function func_rec
    1902              : 
    1903              : end subroutine gran_potrec
    1904              : !!***
    1905              : 
    1906              : !!****f* ABINIT/nlenergyrec
    1907              : !! NAME
    1908              : !! nlenergyrec
    1909              : !!
    1910              : !! FUNCTION
    1911              : !! During recursion, it computes the non-local energy
    1912              : !!
    1913              : !! INPUTS
    1914              : !!  rset<recursion_type>=contains all recursion parameters
    1915              : !!  exppot=exponential of -1/tsmear*vtrial (computed only once in vtorhorec)
    1916              : !!  tsmear=temperature (Hartree)
    1917              : !!  trotter=trotter parameter
    1918              : !!  tol=tolerance criteria for stopping recursion_nl
    1919              : !!  ngfft=information about FFT(dtset%ngfft a priori different from ngfftrec)
    1920              : !!  mpi_enreg=information about MPI paralelisation
    1921              : !!  rset<recursion_type> contains all parameter of recursion
    1922              : !!  typat(natom)=type of pseudo potential associated to any atom
    1923              : !!  natom=number of atoms
    1924              : !!
    1925              : !! OUTPUT
    1926              : !!  enlx=non-local energy
    1927              : !!
    1928              : !! SIDE EFFECTS
    1929              : !!
    1930              : !! NOTES
    1931              : !!
    1932              : !! SOURCE
    1933              : 
    1934            0 : subroutine nlenergyrec(rset,enlx,exppot,ngfft,natom,typat,tsmear,trotter,tol)
    1935              : 
    1936              : !Arguments ------------------------------------
    1937              : !Scalar
    1938              :  integer , intent(in)  :: natom,trotter
    1939              :  real(dp), intent(in)  :: tsmear,tol
    1940              :  type(recursion_type),intent(in) :: rset
    1941              :  real(dp), intent(out) :: enlx
    1942              : !Arrays
    1943              :  integer , intent(in)  :: typat(natom),ngfft(18)
    1944              :  real(dp), intent(in)  :: exppot(0:ngfft(1)*ngfft(2)*ngfft(3)-1)
    1945              : !Local variables-------------------------------
    1946              :  integer :: iatom,jatom
    1947              :  integer :: ii,ipsp,dim_trott
    1948              :  integer :: ierr,me_count
    1949              :  integer :: ilmn,jlmn,ilm,jlm,in,jn,il
    1950              :  character(len=500) :: msg
    1951              :  logical  :: tronc
    1952              :  real(dp) :: rho_nl,normali,mult
    1953            0 :  type(mpi_type):: mpi_loc
    1954              : !Arrays
    1955            0 :  integer  :: gcart_loc(3,natom)
    1956              :  integer  :: ngfftrec(3),trasl(3)
    1957              :  real(dp) :: tsec(2)
    1958            0 :  real(dp) :: un0(0:rset%nfftrec)
    1959            0 :  real(dp),pointer :: projec(:,:,:,:,:)
    1960            0 :  real(dp),allocatable ::  exppotloc(:)
    1961            0 :  real(dp) :: proj_arr(0:rset%ngfftrec(1)-1,0:rset%ngfftrec(2)-1,0:rset%ngfftrec(3)-1)
    1962              : 
    1963              : ! *************************************************************************
    1964              : 
    1965              : 
    1966            0 :  call timab(612,1,tsec) !!--start time-counter: nlenergyrec
    1967              : 
    1968            0 :  if(rset%debug)then
    1969            0 :    write(msg,'(80a,a,a)') ('=',ii=1,80),ch10,' nlenergyrec : enter'
    1970            0 :    call wrtout(std_out,msg,'PERS')
    1971              :  end if
    1972              : 
    1973            0 :  write(msg,'(a)')' -- nlenergyrec -----------------------------------'
    1974            0 :  call wrtout(std_out,msg,'COLL')
    1975              : 
    1976              : !--Initialisation variables
    1977            0 :  enlx = zero
    1978            0 :  mult = two !--is twice for non-spinned systems
    1979            0 :  ngfftrec = rset%ngfftrec(:3)
    1980            0 :  gcart_loc = rset%inf%gcart
    1981            0 :  mpi_loc = rset%mpi
    1982            0 :  me_count = 0
    1983            0 :  dim_trott = max(0,2*trotter-1)
    1984              :  nullify(projec)
    1985            0 :  ABI_MALLOC(projec,(0:rset%ngfftrec(1)-1,0:rset%ngfftrec(2)-1,0:rset%ngfftrec(3)-1,rset%nl%lmnmax,natom))
    1986            0 :  projec = zero
    1987              : 
    1988            0 :  tronc = rset%tronc  !--True if troncation is used
    1989            0 :  if(tronc)   then
    1990            0 :    ABI_MALLOC(exppotloc,(0:rset%nfftrec-1))
    1991              :  end if
    1992              : 
    1993              : 
    1994              : !--LOOP ON ATOMS to create projectors-vector
    1995            0 :  atomloop1: do iatom = 1, natom
    1996            0 :    ipsp = typat(iatom)
    1997              : !  --Aquisition,reshape,translation,rotation of the projectors vector
    1998            0 :    do ilmn = 1,rset%nl%lmnmax
    1999            0 :      in = rset%nl%indlmn(3,ilmn,ipsp)
    2000              : !    --Projectors vector in 3-composant vector
    2001            0 :      projec(:,:,:,ilmn,iatom) = reshape(rset%nl%projec(:,ilmn,ipsp),shape=shape(projec(:,:,:,1,1)))
    2002              : !    --Moving the projectors vector on the center of the grid
    2003            0 :      do ii=1,3
    2004            0 :        projec(:,:,:,ilmn,iatom) = cshift(projec(:,:,:,ilmn,iatom),shift=ngfftrec(ii)/2-gcart_loc(ii,iatom),dim=ii)
    2005              :      end do
    2006              :    end do
    2007              : 
    2008              :  end do atomloop1
    2009              : 
    2010              : 
    2011              : !##################################################################
    2012              : !--LOOP ON ATOMS (MAIN LOOP)
    2013            0 :  atomloop: do iatom = 1, natom
    2014            0 :    ipsp = typat(iatom)
    2015              : 
    2016              : !  --If troncation is present, the considered atom has to be in the
    2017              : !  center of the grid so atoms, potential and projectors have to be translated
    2018            0 :    if(tronc) then
    2019            0 :      trasl = -rset%inf%gcart(:,iatom)+ngfftrec/2
    2020              : !    --Translation of atoms
    2021            0 :      do jatom=1,natom
    2022            0 :        gcart_loc(:,jatom) = rset%inf%gcart(:,jatom)+trasl
    2023            0 :        gcart_loc(:,jatom) = modulo(gcart_loc(:,jatom),ngfft(:3))
    2024              : !      --Translation of non-local projectors
    2025            0 :        do ilmn = 1,rset%nl%lmnmax
    2026            0 :          projec(:,:,:,ilmn,jatom) = reshape(rset%nl%projec(:,ilmn,typat(jatom)),shape=shape(projec(:,:,:,1,1)))
    2027            0 :          do ii=1,3
    2028            0 :            projec(:,:,:,ilmn,jatom) = eoshift(projec(:,:,:,ilmn,jatom),shift=ngfftrec(ii)/2-gcart_loc(ii,jatom),dim=ii)
    2029              :          end do
    2030              :        end do
    2031              :      end do
    2032              : 
    2033              : !    --Translation of the potential
    2034            0 :      call reshape_pot(trasl,ngfft(1)*ngfft(2)*ngfft(3),rset%nfftrec,ngfft(:3),ngfftrec,exppot,exppotloc)
    2035              :    end if
    2036              : 
    2037              : !  --Loop on projectors
    2038            0 :    projloop: do ilmn = 1,rset%nl%lmnmax
    2039            0 :      me_count = iatom+ilmn*natom-2 !--counter of the number of iteration
    2040              : !    --Only the proc me compute
    2041            0 :      if(mpi_loc%me==mod(me_count,mpi_loc%nproc)) then
    2042            0 :        ilm = rset%nl%indlmn(4,ilmn,ipsp)
    2043            0 :        proj_arr = zero
    2044            0 :        do jlmn = 1,rset%nl%lmnmax
    2045            0 :          jlm = rset%nl%indlmn(4,jlmn,ipsp)
    2046            0 :          if(ilm==jlm) then
    2047            0 :            in = rset%nl%indlmn(3,ilmn,ipsp)
    2048            0 :            jn = rset%nl%indlmn(3,jlmn,ipsp)
    2049            0 :            il = rset%nl%indlmn(1,ilmn,ipsp)+1
    2050            0 :            proj_arr(:,:,:) = proj_arr(:,:,:) + rset%nl%eivec(jn,in,il,ipsp)*projec(:,:,:,jlmn,iatom)
    2051              : !          write(std_out,*)'l,m,lm,n,n',il-1,rset%nl%indlmn(2,ilmn,ipsp),ilm,in,jn
    2052              : !          write(std_out,*)'eigevectors',rset%nl%eivec(jn,in,il,ipsp)
    2053              : 
    2054              :          end if
    2055              :        end do
    2056              : 
    2057            0 :        un0 = pack(proj_arr(:,:,:),mask=.true.)
    2058            0 :        normali = sum(un0*un0)*rset%inf%ucvol
    2059            0 :        un0 = (one/sqrt(normali))*un0
    2060              : 
    2061            0 :        if(tronc)then
    2062              :          call recursion_nl(exppotloc,un0,rho_nl,rset,rset%ngfftrec,&
    2063              : &         tsmear,trotter,dim_trott,tol,typat,&
    2064            0 : &         natom,projec)
    2065              :        else
    2066              :          call recursion_nl(exppot,un0,rho_nl,rset,rset%ngfftrec,&
    2067              : &         tsmear,trotter,dim_trott,tol,typat,&
    2068            0 : &         natom,projec)
    2069              :        end if
    2070              : 
    2071            0 :        enlx = enlx+mult*rho_nl*rset%nl%eival(in,il,ipsp)*normali
    2072              :      end if
    2073              : 
    2074              :    end do projloop
    2075              :  end do atomloop
    2076              : 
    2077              : !--Sum the contribution to the non-local energy computed by any procs
    2078            0 :  call xmpi_sum(enlx,mpi_loc%comm_bandfft,ierr)
    2079              : 
    2080            0 :  if(associated(projec))  then
    2081            0 :    ABI_FREE(projec)
    2082              :  end if
    2083            0 :  if(tronc)  then
    2084            0 :    ABI_FREE(exppotloc)
    2085              :  end if
    2086              : 
    2087            0 :  if(rset%debug)then
    2088            0 :    write(msg,'(80a,a,a)') ('=',ii=1,80),ch10,' nlenergyrec : exit'
    2089            0 :    call wrtout(std_out,msg,'PERS')
    2090              :  end if
    2091              : 
    2092            0 :  call timab(612,2,tsec)  !--stop  time-counter: nlenergyrec
    2093              : 
    2094            0 : end subroutine nlenergyrec
    2095              : !!***
    2096              : 
    2097              : 
    2098              : !!****f* ABINIT/first_rec
    2099              : !! NAME
    2100              : !! first_rec
    2101              : !!
    2102              : !! FUNCTION
    2103              : !! When recursion method is used, in the first step this routine
    2104              : !! compute some quantities which are used in the rest of the calculation.
    2105              : !!
    2106              : !! COPYRIGHT
    2107              : !!  Copyright (C) 2009-2026 ABINIT group (MMancini)
    2108              : !!  This file is distributed under the terms of the
    2109              : !!  GNU General Public License, see ~abinit/COPYING
    2110              : !!  or http://www.gnu.org/copyleft/gpl.txt .
    2111              : !!
    2112              : !! INPUTS
    2113              : !!  dtset <type(dataset_type)>=all input variables for this dataset:
    2114              : !!   | recgratio =fine/coarse grid ratio
    2115              : !!   | recptrott =trotter parameter
    2116              : !!   | tsmear    =temperature
    2117              : !!   | recrcut   =tut radius in recursion (range of iteration)
    2118              : !!   | ngfft(18) =FFT grid used as real (fine) grid in recursion
    2119              : !!  psps <type(pseudopotential_type)>=variables related to pseudo-potentials
    2120              : !!
    2121              : !! OUTPUT
    2122              : !!
    2123              : !! SIDE EFFECTS
    2124              : !!  rset <type(recursion_type)>=variables related to recursion method
    2125              : !!   | debug<logical> = T if debugging is used
    2126              : !!   | inf <type(metricrec_type)>=information concerning the infinitesimal metrics
    2127              : !!   | ngfftrec(18) =truncated (or not, if not ngfftrec=ngfft)FFT grid used as real grid in recursion.
    2128              : !!   | nfftrec =product(ngfftrec(1:3))
    2129              : !!   | tronc<logical> = T if truncation is effectively used
    2130              : !!   | ZT_p = fourier transform of the green_kernel calculated on the fine grid
    2131              : !!
    2132              : !!
    2133              : !! NOTES
    2134              : !!
    2135              : !! SOURCE
    2136              : 
    2137            6 : subroutine first_rec(dtset,psps,rset)
    2138              : 
    2139              : !Arguments ------------------------------------
    2140              : ! scalars
    2141              :  type(dataset_type),intent(in) :: dtset
    2142              :  type(pseudopotential_type),intent(in) :: psps
    2143              :  type(recursion_type),intent(inout) :: rset
    2144              : !Local variables-------------------------------
    2145              : !scalars
    2146              :  integer  :: nfftrec,trotter,ii,dim_trott
    2147              :  real(dp) :: tsmear,beta,rtrotter
    2148              :  character(len=500) :: msg
    2149              : !arrays
    2150              :  integer  :: ngfftrec(18)
    2151              :  real(dp) :: tsec(2)
    2152              : #ifdef HAVE_GPU_CUDA
    2153              :  integer  :: max_rec,ierr,testpts,swt_tm
    2154              :  real(dp) :: rho,tm_ratio
    2155              :  real(dp) :: time_cu,time_f
    2156              :  type(recursion_type) :: rset_test
    2157              :  type(recparall_type) :: parold
    2158              :  integer :: trasl(3)
    2159              :  real(dp) :: tsec2(2),tsec3(2)
    2160              :  real(dp) :: aloc(0,1),b2loc(0,1)
    2161              :  real(dp) :: dm_projec(0,0,0,1,1)
    2162              :  real(dp) :: exppot(0:dtset%nfft-1)
    2163              :  real(dp),allocatable :: exppotloc(:)
    2164              :  real(cudap),allocatable :: aloc_cu(:),b2loc_cu(:)
    2165              : #endif
    2166              : 
    2167              : ! *************************************************************************
    2168              : 
    2169            6 :  call timab(601,1,tsec)  !!--Start time-counter: initialisation
    2170              : 
    2171            6 :  ABI_WARNING("RECURSION")
    2172            6 :  if(dtset%recgratio>1) then
    2173            1 :    write(msg,'(a)')'COARSE GRID IS USED'
    2174            1 :    call wrtout(std_out,msg,'COLL')
    2175              :  end if
    2176              : 
    2177              : !--Initialisation
    2178            6 :  trotter = dtset%recptrott  !--Trotter parameter
    2179            6 :  tsmear  = dtset%tsmear     !--Temperature
    2180            6 :  beta    = one/tsmear       !--Inverse of temperature
    2181              : 
    2182              : !--Rewriting the trotter parameter
    2183            6 :  dim_trott = max(0,2*trotter-1)
    2184            6 :  rtrotter  = max(half,real(trotter,dp))
    2185              : 
    2186            6 :  write (msg,'(2a)')ch10,'==== FIRST CYCLE RECURSION ========================='
    2187            6 :  call wrtout(std_out,msg,'COLL')
    2188              : 
    2189              : 
    2190          114 :  ngfftrec = rset%ngfftrec
    2191            6 :  nfftrec = rset%nfftrec
    2192              : !------------------------------------------------
    2193              : !--TRONCATION OF THE BOX: determines new dimensions
    2194              : !--Now in InitRec
    2195              : !--------------------------------------------------------
    2196              : !--DEFINITION PAW VARIABLES COARSE-FINE GRID  TO USE TRANSGRID--INGRID FUNCTIONS
    2197              : !--Now these variables are defined into gstate by InitRec
    2198              : 
    2199              : !--------------------------------------------------------
    2200              : !--COMPUTATION OF THE FOURIER TRANSFORM OF THE GREEN KERNEL (only once)
    2201            6 :  write (msg,'(a)')' - green kernel calculation -----------------------'
    2202            6 :  call wrtout(std_out,msg,'COLL')
    2203           18 :  ABI_MALLOC(rset%ZT_p,(1:2,0: nfftrec-1))
    2204            6 :  call timab(601,2,tsec)
    2205            6 :  call green_kernel(rset%ZT_p,rset%inf%rmet,rset%inf%ucvol,rtrotter/beta,rset%mpi,ngfftrec,nfftrec)
    2206            6 :  call timab(601,1,tsec)
    2207          306 :  write(msg,'(a,50a)')' ',('-',ii=1,50)
    2208            6 :  call wrtout(std_out,msg,'COLL')
    2209              : !!--end computation of the fourier transform of the Green kernel
    2210              : 
    2211              : !!-----------------------------------
    2212              : !!--ROUTINE FOR THE CALCULATION OF THE NON-LOCAL PSEUDO
    2213              : !--Now these variables here by  Init_nlpspRec
    2214            6 :  call Init_nlpspRec(four*tsmear*rtrotter,psps,rset%nl,rset%inf,rset%ngfftrec,rset%debug)
    2215              : 
    2216              : !!-----------------------------------
    2217              : !--Load distribution on procs when GPU are present
    2218              : #if defined HAVE_GPU_CUDA
    2219              : 
    2220              : !--Test timing only if exists GPU and they are not equal to the cpus
    2221              :  if(rset%tp == 4) then
    2222              :    parold = rset%par
    2223              :    ii = 0
    2224              :    time_f = zero
    2225              :    time_cu = zero
    2226              :    call random_number(exppot)  !   exppot = one
    2227              : 
    2228              :    if(rset%gpudevice == -1) then
    2229              : !    --Test CPUS
    2230              :      swt_tm = 0
    2231              :      testpts = min(rset%par%npt, 20)
    2232              :      call timein(tsec2(1),tsec2(2))
    2233              :      if(rset%tronc) then
    2234              :        ABI_MALLOC(exppotloc,(0:nfftrec-1))
    2235              :        do while(ii< testpts)
    2236              :          trasl = -(/1,2,3/)+ngfftrec(:3)/2
    2237              :          call reshape_pot(trasl,dtset%nfft,nfftrec,dtset%ngfft(:3),ngfftrec(:3),&
    2238              : &         exppot,exppotloc)
    2239              :          call recursion(exppotloc,0,0,0, &
    2240              : &         aloc, &
    2241              : &         b2loc, &
    2242              : &         rho,&
    2243              : &         0, rset%efermi,tsmear,rtrotter,dim_trott, &
    2244              : &         rset%ZT_p, &
    2245              : &         dtset%rectolden,dtset%typat, &
    2246              : &         rset%nl,&
    2247              : &         rset%mpi,nfftrec,ngfftrec,rset%inf,&
    2248              : &         6,dtset%natom,dm_projec,0)
    2249              :          ii=ii+1
    2250              :        end do
    2251              :        ABI_FREE(exppotloc)
    2252              :      else
    2253              :        do while(ii< testpts)
    2254              :          call recursion(exppot,0,0,0, &
    2255              : &         aloc, &
    2256              : &         b2loc, &
    2257              : &         rho,&
    2258              : &         0, rset%efermi,tsmear,rtrotter,dim_trott, &
    2259              : &         rset%ZT_p, &
    2260              : &         dtset%rectolden,dtset%typat, &
    2261              : &         rset%nl,&
    2262              : &         rset%mpi,nfftrec,ngfftrec,rset%inf,&
    2263              : &         6,dtset%natom,dm_projec,0)
    2264              :          ii=ii+1
    2265              :        end do
    2266              :      end if
    2267              :      call timein(tsec3(1),tsec3(2))
    2268              :      time_f = (tsec3(1)-tsec2(1))/real(testpts,dp)
    2269              :      time_f = time_f*time_f
    2270              :    else
    2271              : !    --Test GPUS
    2272              :      swt_tm = 1
    2273              :      rset_test = rset
    2274              :      rset_test%GPU%par%npt = max(rset%GPU%nptrec,100)
    2275              :      rset_test%min_nrec = 0
    2276              :      call get_pt0_pt1(dtset%ngfft(:3),dtset%recgratio,0,&
    2277              : &     rset_test%GPU%par%npt,rset_test%GPU%par)
    2278              : 
    2279              : 
    2280              :      ABI_MALLOC(aloc_cu,(rset_test%GPU%par%npt))
    2281              :      ABI_MALLOC(b2loc_cu,(rset_test%GPU%par%npt))
    2282              :      call timein(tsec2(1),tsec2(2))
    2283              :      call cudarec(rset_test, exppot,aloc_cu,b2loc_cu,&
    2284              : &     beta,trotter,dtset%rectolden,dtset%recgratio,dtset%ngfft,max_rec)
    2285              :      call timein(tsec3(1),tsec3(2))
    2286              :      ABI_FREE(aloc_cu)
    2287              :      ABI_FREE(b2loc_cu)
    2288              : 
    2289              :      time_cu = (tsec3(1)-tsec2(1))/real(rset_test%GPU%par%npt,dp)
    2290              :      time_cu = time_cu*time_cu
    2291              :    end if
    2292              : 
    2293              : 
    2294              : !  --Get Total Times
    2295              :    call xmpi_sum(time_f,rset%mpi%comm_bandfft,ierr)
    2296              :    call xmpi_sum(time_cu,rset%mpi%comm_bandfft,ierr)
    2297              : 
    2298              : !  --Average Total Times
    2299              :    time_f   = sqrt(time_f/real(rset%mpi%nproc-rset%ngpu,dp))
    2300              :    time_cu  = sqrt(time_cu/real(rset%ngpu,dp))
    2301              :    tm_ratio = time_f/time_cu
    2302              : 
    2303              : 
    2304              :    write(msg,'(3(a25,f10.5,a))')&
    2305              : &   ' Time for cpu recursion ',time_f,ch10,&
    2306              : &   ' Time for gpu recursion ',time_cu,ch10,&
    2307              : &   ' Time ratio             ',tm_ratio,ch10
    2308              :    call wrtout(std_out,msg,'COLL')
    2309              : 
    2310              : 
    2311              : !  tm_ratio =1.20d2! 0.d0! 1.21d0
    2312              :    rset%par = parold
    2313              : !  --Compute the work-load distribution on devices (gpu,cpu)
    2314              :    if(tm_ratio>1.5d0 .and. time_cu>zero)then
    2315              :      rset%load = 1
    2316              :      call cpu_distribution(dtset%recgratio,rset,dtset%ngfft(:3),tm_ratio,1)
    2317              :    else
    2318              :      rset%gpudevice = -1
    2319              :    end if
    2320              :  end if
    2321              : 
    2322              : #endif
    2323              : 
    2324              : 
    2325              : !------------------------------------------------------------
    2326              : !--DETERMINING WHICH POINT WILL COMPUTE THAT PROC
    2327              : !--Now these variables are defined into gstate by Init_rec
    2328              : 
    2329            6 :  write (msg,'(2a)')ch10,'==== END FIRST CYCLE RECURSION ====================='
    2330            6 :  call wrtout(std_out,msg,'COLL')
    2331            6 :  call timab(601,2,tsec) !!--stop time-counter: initialisation
    2332              : 
    2333            6 : end subroutine first_rec
    2334              : !!***
    2335              : 
    2336              : 
    2337              : !!****f* ABINIT/green_kernel
    2338              : !! NAME
    2339              : !! green_kernel
    2340              : !!
    2341              : !! FUNCTION
    2342              : !! this routine compute the fourrier transform of the Green kernel for the
    2343              : !! recursion method
    2344              : !!
    2345              : !! INPUTS
    2346              : !!  inf_rmet=define the  infinitesimal metric : rprimd*(transpose(rprimd)) divided
    2347              : !!    by the number of discretisation point
    2348              : !!  inf_ucvol=volume of infinitesimal cell
    2349              : !!  mult=variance of the Gaussian (=rtrotter/beta)
    2350              : !!  mpi_enreg=information about MPI parallelization
    2351              : !!  ngfft=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
    2352              : !!  nfft=total number of fft grid points
    2353              : !!  debug_rec=debugging variable
    2354              : !!
    2355              : !! OUTPUT
    2356              : !!  ZT_p=fourier transforme of the Green kernel
    2357              : !!
    2358              : !! NOTES
    2359              : !!  at this time :
    2360              : !!       - need a rectangular box
    2361              : !!
    2362              : !! SOURCE
    2363              : 
    2364              : 
    2365            6 : subroutine green_kernel(ZT_p,inf_rmet,inf_ucvol,mult,mpi_enreg,ngfft,nfft)
    2366              : 
    2367              : !Arguments -------------------------------
    2368              : !scalars
    2369              :  integer,intent(in) :: nfft
    2370              :  real(dp),intent(in) :: inf_ucvol,mult
    2371              :  type(MPI_type),intent(in) :: mpi_enreg
    2372              : !arrays
    2373              :  integer,intent(in) :: ngfft(18)
    2374              :  real(dp),intent(in) :: inf_rmet(3,3)
    2375              :  real(dp),intent(out) :: ZT_p(1:2,0:nfft-1)
    2376              : 
    2377              : !Local variables-------------------------------
    2378              : !scalars
    2379              :  integer,parameter :: n_green_max=5
    2380              :  integer :: ii,isign,jj,kk,n_green,xx,yy,zz
    2381              :  real(dp) :: acc, norme
    2382              :  character(len=500) :: msg
    2383              : !arrays
    2384              :  real(dp) :: tsec(2)
    2385            6 :  real(dp),allocatable :: T_p(:)
    2386              : 
    2387              : ! *************************************************************************
    2388              : 
    2389            6 :  call timab(603,1,tsec)
    2390              : 
    2391            6 :  norme = (mult/pi)**(onehalf)
    2392              : 
    2393           18 :  ABI_MALLOC(T_p,(0:nfft-1))
    2394              : 
    2395              : !n_green should be better chosen for non rectangular cell
    2396            6 :  do xx=1, n_green_max
    2397            6 :    n_green = xx
    2398              :    if(exp(-mult*dsq_green(xx*ngfft(1),0,0,inf_rmet))<tol14 &
    2399              : &   .and. exp(-mult*dsq_green(0,xx*ngfft(2),0,inf_rmet))<tol14 &
    2400            6 : &   .and. exp(-mult*dsq_green(0,0,xx*ngfft(3),inf_rmet))<tol14 ) exit
    2401              :  end do
    2402              : 
    2403         8710 :  acc = zero
    2404         8710 :  T_p = zero
    2405           70 :  do kk = 0,ngfft(3)-1
    2406          806 :    do jj = 0,ngfft(2)-1
    2407         9504 :      do ii = 0,ngfft(1)-1
    2408              : 
    2409        26112 :        do xx=-n_green,n_green-1
    2410        60928 :          do yy=-n_green,n_green-1
    2411       121856 :            do zz=-n_green,n_green-1
    2412              : 
    2413              :              T_p(ii+ngfft(1)*jj+ngfft(1)*ngfft(2)*kk) = T_p(ii+ngfft(1)*jj+ngfft(1)*ngfft(2)*kk)+ &
    2414       104448 : &             exp(-mult*dsq_green(ii+xx*ngfft(1),jj+yy*ngfft(2),kk+zz*ngfft(3),inf_rmet))
    2415              : 
    2416              :            end do
    2417              :          end do
    2418              :        end do
    2419              : 
    2420         8704 :        T_p(ii+ngfft(1)*jj+ngfft(1)*ngfft(2)*kk) = norme*T_p(ii+ngfft(1)*jj+ngfft(1)*ngfft(2)*kk)
    2421         9440 :        acc = acc + inf_ucvol* T_p(ii+ngfft(1)*jj+ngfft(1)*ngfft(2)*kk)
    2422              : 
    2423              :      end do
    2424              :    end do
    2425              :  end do
    2426              : 
    2427         8710 :  T_p(:)= (one/acc)*T_p(:)
    2428              : 
    2429              : !if(debug_rec)then
    2430              :  write(msg,'(a,d12.3,2(2a,i8),2(2a,3d12.3),2a,d16.6)')&
    2431            6 : & ' on the boundary    ', exp(-mult*dsq_green(ngfft(1),0,0,inf_rmet)),ch10, &
    2432         8710 : & ' no zero            ', count(T_p>tol14),ch10, &
    2433            6 : & ' n_green            ', n_green,ch10, &
    2434            6 : & ' erreur_n_green     ', exp(-mult*dsq_green(n_green*ngfft(1),0,0,inf_rmet)), &
    2435            6 : & exp(-mult*dsq_green(0,n_green*ngfft(2),0,inf_rmet)), &
    2436            6 : & exp(-mult*dsq_green(0,0,n_green*ngfft(3),inf_rmet)),ch10,&
    2437            6 : & ' erreur_troncat     ', T_p(ngfft(1)/2),  &
    2438            6 : & T_p(ngfft(1)*(ngfft(2)/2)), &
    2439            6 : & T_P(ngfft(1)*ngfft(2)*(ngfft(3)/2)),ch10, &
    2440           12 : & ' erreurT_p          ',abs(acc-1.d0)
    2441            6 :  call wrtout(std_out,msg,'COLL')
    2442              : !endif
    2443              : 
    2444              : 
    2445            6 :  isign = -1
    2446            6 :  call fourdp(1,ZT_p,T_p,isign,mpi_enreg,nfft,1,ngfft,0)
    2447              : 
    2448            6 :  ABI_FREE(T_p)
    2449              : 
    2450        26118 :  ZT_p(:,:) = real(nfft,dp)*ZT_p
    2451              : 
    2452              : 
    2453            6 :  call timab(603,2,tsec)
    2454              : 
    2455              :  contains
    2456              : 
    2457        69674 :    function dsq_green(ii,jj,kk,inf_rmet)
    2458              : 
    2459              :    real(dp) :: dsq_green
    2460              :    integer,intent(in) :: ii,jj,kk
    2461              :    real(dp),intent(in) :: inf_rmet(3,3)
    2462              :    dsq_green= inf_rmet(1,1)*dble(ii**2)&
    2463              : &   +inf_rmet(2,2)*dble(jj**2)&
    2464              : &   +inf_rmet(3,3)*dble(kk**2)&
    2465              : &   +two*(inf_rmet(1,2)*dble(ii*jj)&
    2466              : &   +inf_rmet(2,3)*dble(jj*kk)&
    2467        69674 : &   +inf_rmet(3,1)*dble(kk*ii))
    2468        69674 :  end function dsq_green
    2469              : 
    2470              : end subroutine green_kernel
    2471              : !!***
    2472              : 
    2473              : 
    2474              : !!****f* ABINIT/recursion
    2475              : !! NAME
    2476              : !! recursion
    2477              : !!
    2478              : !! FUNCTION
    2479              : !! This routine computes the recursion coefficients and the corresponding
    2480              : !! continued fraction to get the density at a point from a fixed potential.
    2481              : !!
    2482              : !! INPUTS
    2483              : !!  exppot=exponential of -1/tsmear*vtrial (computed only once in vtorhorec)
    2484              : !!  coordx, coordy, coordz=coordonnees of the computed point
    2485              : !!  nrec=order of recursion
    2486              : !!  fermie=fermi energy (Hartree)
    2487              : !!  tsmear=temperature (Hartree)
    2488              : !!  dim_trott=dimension of the partial fraction decomposition
    2489              : !!  rtrotter=trotter parameter (real)
    2490              : !!  ZT_p=fourier transform of the Green krenel (computed only once in vtorhorec)
    2491              : !!  typat(:)=type of psp associated to any atom
    2492              : !!  tol=tolerance criteria for stopping recursion
    2493              : !!  debug=debugging variable
    2494              : !!  mpi_enreg=information about MPI paralelisation
    2495              : !!  nfft=number of points in FFT grid
    2496              : !!  ngfft=information about FFT
    2497              : !!  metrec<type(metricrec_type)>=information concerning the infinitesimal metrics
    2498              : !!  inf_ucvol=infinitesimal unit cell volume
    2499              : !!  tim_fourdp=time counter for fourdp
    2500              : !!  natom=number of atoms
    2501              : !!  projec(ngfftrec(1),ngfftrec(2),ngfftrec(3),lmnmax,natom) is the  vector, on the ngfftrec grid containing
    2502              : !!  the non-lacal projector $Y_{lm}(r-R_A)f_{lk}(r-R_A)
    2503              : !!  tim= 0 if the time spent in the routine is not taken into account,1 otherwise. For example
    2504              : !!  when measuring time for loading  balancing, we don't want to add the time spent in this to the
    2505              : !!  total time calculation
    2506              : !!
    2507              : !! OUTPUT
    2508              : !!  rho_out=result of the continued fraction multiplied by a multiplicator
    2509              : !!  an, bn2 : coefficient given by recursion.
    2510              : !!
    2511              : !! SIDE EFFECTS
    2512              : !!
    2513              : !! NOTES
    2514              : !!  at this time :
    2515              : !!       - exppot should be replaced by ?
    2516              : !!       - coord should be replaced by ?
    2517              : !!       - need a rectangular box (rmet diagonal matrix)
    2518              : !!
    2519              : !! SOURCE
    2520              : 
    2521        17469 : subroutine recursion(exppot,coordx,coordy,coordz,an,bn2,rho_out, &
    2522              : &                    nrec,fermie,tsmear,rtrotter,dim_trott, &
    2523        34938 : &                    ZT_p, tol,typat, &
    2524              : &                    nlrec,mpi_enreg,&
    2525              : &                    nfft,ngfft,metrec,&
    2526        17469 : &                    tim_fourdp,natom,projec,tim)
    2527              : 
    2528              : 
    2529              :  use m_linalg_interfaces
    2530              : 
    2531              : !Arguments -------------------------------
    2532              : !scalars
    2533              :  integer,intent(in) :: coordx,coordy,coordz,nfft,nrec,tim
    2534              :  integer,intent(in) :: tim_fourdp,natom,dim_trott
    2535              :  real(dp),intent(in) :: fermie,tol,tsmear,rtrotter
    2536              :  real(dp), intent(out) :: rho_out
    2537              :  type(MPI_type),intent(in) :: mpi_enreg
    2538              :  type(nlpsprec_type),intent(in) :: nlrec
    2539              :  type(metricrec_type),intent(in) :: metrec
    2540              : !arrays
    2541              :  integer, intent(in) :: ngfft(18)
    2542              :  integer, intent(in) :: typat(natom)
    2543              :  real(dp), intent(in) :: ZT_p(1:2, 0:nfft-1)
    2544              :  real(dp), intent(in) :: exppot(0:nfft-1)
    2545              :  real(dp), intent(in) :: projec(0:,0:,0:,1:,1:)
    2546              :  real(dp), intent(out) :: an(0:nrec),bn2(0:nrec)
    2547              : !Local variables-------------------------------
    2548              : !not used, debugging purpose only
    2549              : !for debugging purpose, detailled printing only once for density and ekin
    2550              : !scalars
    2551              :  integer, parameter :: level = 7, minrec = 3
    2552              :  integer  :: irec,isign,timab_id,ii
    2553              :  real(dp) :: switchimu,switchu
    2554              :  real(dp) :: bb,beta,mult,prod_b2,error,errold
    2555              :  real(dp) :: inf_ucvol,pi_on_rtrotter,twortrotter,exp1,exp2
    2556              :  complex(dp) :: cinv2rtrotter,coeef_mu,facrec0
    2557              : ! character(len=500) :: msg
    2558              : !arrays
    2559              :  real(dp) :: tsec(2)
    2560              :  real(dp) :: inf_tr(3)
    2561        34938 :  real(dp) :: Zvtempo(1:2, 0:nfft-1)
    2562        34938 :  real(dp) :: unold(0:nfft-1),vn(0:nfft-1),un(0:nfft-1)
    2563        34938 :  complex(dp) :: acc_rho(0:nrec)
    2564        34938 :  complex(dp) :: D(0:dim_trott),Dold(0:dim_trott)
    2565        34938 :  complex(dp) :: N(0:dim_trott),Nold(0:dim_trott)
    2566              : ! *************************************************************************
    2567              : 
    2568              : !--If count time or not
    2569        17469 :  timab_id = 616; if(tim/=0) timab_id = 606;
    2570              : 
    2571        17469 :  call timab(timab_id,1,tsec)
    2572              : 
    2573              : !##############################################################
    2574              : !--Initialisation of metrics
    2575        17469 :  inf_ucvol = metrec%ucvol
    2576              :  inf_tr = metrec%tr
    2577        17469 :  mult = two/inf_ucvol    !non-spined system
    2578              : 
    2579        17469 :  beta = one/tsmear
    2580              : !--Variables for optimisation
    2581        17469 :  pi_on_rtrotter = pi/rtrotter
    2582        17469 :  twortrotter = two*rtrotter
    2583        17469 :  exp1 = exp((beta*fermie)/(rtrotter))
    2584        17469 :  exp2 = exp(beta*fermie/(twortrotter))
    2585        17469 :  cinv2rtrotter = cmplx(one/twortrotter,zero,dp)
    2586        17469 :  coeef_mu = cmplx(one/exp2,zero,dp)
    2587              : 
    2588              : !--Initialisation of  an,bn,un....
    2589       716229 :  N = czero;  D = cone
    2590        17469 :  facrec0 = cone
    2591       716229 :  Nold = czero; Dold = czero
    2592              : 
    2593       568539 :  an = zero; bn2 = zero;  bn2(0) = one
    2594     59761341 :  bb = zero; vn  = zero;  unold  = zero
    2595              : !--u0 is a Dirac function
    2596     29889405 :  un = zero
    2597        17469 :  un(coordx+ngfft(1)*(coordy+ngfft(2)*coordz)) = one/sqrt(inf_ucvol)
    2598              : 
    2599              : !--Initialisation of accumulated density
    2600       293004 :  acc_rho = czero
    2601              : !--Initialisation of estimated error
    2602        17469 :  prod_b2 = twortrotter/exp1
    2603        17469 :  errold = zero
    2604              : 
    2605              : !##############################################################
    2606              : !--Main loop
    2607        69876 :  maindo : do irec = 0, nrec
    2608              : 
    2609              : !  --Get an and bn2 coef by the lanczos method
    2610              : 
    2611              : !  --Computation of exp(-beta*V/8*p)*un or exp(-beta*V/4*p)*un
    2612              : !  depending on if nl part has to be calculated or not.
    2613    119557620 :    vn = exppot * un
    2614              : 
    2615              : !  --First Non-local psp contribution: (Id+sum_atom int dr1(E(r,r1))vn(r1))
    2616              : !  --Computation of exp(-beta*V_NL/4*p)*vn
    2617        69876 :    if(nlrec%nlpsp) then
    2618            0 :      call timab(timab_id,2,tsec)
    2619            0 :      call vn_nl_rec(vn,natom,typat,ngfft(:3),inf_ucvol,nlrec,projec)
    2620            0 :      call timab(timab_id,1,tsec)
    2621              : 
    2622              : !    --Computation of exp(-beta*V/8*p)*vn in nonlocal case
    2623            0 :      vn = exppot * vn
    2624              :    end if !--End if on nlrec%nlpsp
    2625              : 
    2626              : !  --Convolution with the Green kernel
    2627              : !  --FFT of vn
    2628        69876 :    isign = -1
    2629        69876 :    call fourdp(1,Zvtempo,vn,isign,mpi_enreg,nfft,1,ngfft,tim_fourdp)
    2630              : 
    2631              : !  --F(T)F(vn)
    2632    119557620 :    do ii = 0,nfft-1
    2633    119487744 :      switchu   = Zvtempo(1,ii)
    2634    119487744 :      switchimu = Zvtempo(2,ii)
    2635    119487744 :      Zvtempo(1,ii) = switchu*ZT_p(1,ii) - switchimu*ZT_p(2,ii)
    2636    119557620 :      Zvtempo(2,ii) = switchu*ZT_p(2,ii) + switchimu*ZT_p(1,ii)
    2637              :    end do
    2638              : 
    2639              : !  --F^-1(F(T)F(vn))
    2640        69876 :    isign = 1
    2641        69876 :    call fourdp(1,Zvtempo,vn,isign,mpi_enreg,nfft,1,ngfft,tim_fourdp)
    2642              : 
    2643              : !  --Computation of exp(-beta*V/8*p)*un or exp(-beta*V/4*p)*un
    2644              : !  depending on if nl part has to be calculated or not.
    2645              : 
    2646    119557620 :    vn = inf_ucvol * exppot * vn
    2647              : 
    2648              : !  --Second Non-local psp contribution: (Id+sum_atom E(r,r1))vn
    2649        69876 :    if(nlrec%nlpsp) then
    2650            0 :      call timab(timab_id,2,tsec)
    2651            0 :      call vn_nl_rec(vn,natom,typat,ngfft(:3),inf_ucvol,nlrec,projec)
    2652            0 :      call timab(timab_id,1,tsec)
    2653              : 
    2654              : !    --Computation of exp(-beta*V/8*p)*vn in nonlocal case
    2655            0 :      vn = exppot * vn
    2656              :    end if !--End if on nlrec%nlpsp
    2657              : 
    2658              : !  --Multiplication of a and b2 coef by exp(beta*fermie/(two*rtrotter)) must be done in the continued fraction computation
    2659              : !  --Computation of a and b2
    2660        69876 :    an(irec) = inf_ucvol*ddot(nfft,vn,1,un,1)
    2661              : 
    2662              : !  --an must be positive real
    2663              : !  --We must compute bn2 and prepare for the next iteration
    2664        69876 :    if(irec<nrec)then
    2665    119557620 :      do ii = 0,nfft-1
    2666    119487744 :        switchu = un(ii)
    2667    119487744 :        un(ii) = vn(ii)-an(irec)*un(ii)-bb*unold(ii)
    2668    119487744 :        unold(ii) = switchu
    2669    119557620 :        bn2(irec+1) = bn2(irec+1)+inf_ucvol*un(ii)*un(ii)
    2670              :      end do
    2671        69876 :      bb = sqrt(bn2(irec+1))
    2672    119557620 :      un = (one/bb)*un
    2673              :    end if
    2674              : 
    2675              : !  ######################################################
    2676              : !  --Density computation
    2677              : !  density computation is done inside the main looping, juste after the calculus of a and b2, in order to make
    2678              : !  it possible to stop the recursion at the needed accuracy, without doing more recursion loop than needed -
    2679              : !  further developpement
    2680              : 
    2681              : !  !--using the property that: sum_i(bi*c)^2|(z-ai*c)=1/c*sum_i(bi)^2|(z/c-ai)
    2682              : !  !and for c =exp(-beta*fermie/(two*rtrotter)
    2683              : 
    2684              : 
    2685              :    call trottersum(dim_trott,error,prod_b2,pi_on_rtrotter,&
    2686              : &   facrec0,coeef_mu,exp1,&
    2687              : &   an(irec),bn2(irec),&
    2688        69876 : &   N,D,Nold,Dold)
    2689              : 
    2690              : 
    2691        69876 :    if(irec/=nrec .and. irec>=minrec)then
    2692        17469 :      if((bn2(irec+1)<tol14).or.(mult*error<tol.and.errold<tol)) exit
    2693              :    end if
    2694        69876 :    errold = mult*error
    2695              :  end do maindo
    2696              : !--Accumulated density
    2697       366849 :  rho_out = mult*real(cone-sum(N/D)*cinv2rtrotter,dp)
    2698              : 
    2699              : 
    2700        17469 :  call timab(timab_id,2,tsec)
    2701              : 
    2702        17469 :  end subroutine recursion
    2703              : !!***
    2704              : 
    2705              : 
    2706              : !!****f* ABINIT/recursion_nl
    2707              : !! NAME
    2708              : !! recursion_nl
    2709              : !!
    2710              : !! FUNCTION
    2711              : !! Given a $|un>$ vector on the real-space grid this routine calculates
    2712              : !! the density in  $|un>$ by recursion method.
    2713              : !!
    2714              : !! INPUTS
    2715              : !!  exppot=exponential of -1/tsmear*vtrial (computed only once in vtorhorec)
    2716              : !!  trotter=trotter parameter
    2717              : !!  dim_trott=dimension of the partial fraction decomposition
    2718              : !!  tsmear=temperature (Hartree)
    2719              : !!  tol=tolerance criteria for stopping recursion_nl
    2720              : !!  ngfft=information about FFT(dtset%ngfft a priori different from ngfftrec)
    2721              : !!  rset<recursion_type> contains all parameter of recursion
    2722              : !!  typat(natom)=type of pseudo potential associated to any atom
    2723              : !!  natom=number of atoms
    2724              : !!  projec(ngfftrec(1),ngfftrec(2),ngfftrec(3),lmnmax,natom) is the  vector, on the ngfftrec grid containing
    2725              : !!  the non-lacal projector $Y_{lm}(r-R_A)f_{lk}(r-R_A)
    2726              : !!
    2727              : !! OUTPUT
    2728              : !!  rho_out=result of the continued fraction multiplied by a multiplicator
    2729              : !!
    2730              : !! SIDE EFFECTS
    2731              : !!  un(:,:,:)=initial vector on the grid. it is changed in output
    2732              : !!
    2733              : !! NOTES
    2734              : !!  at this time :
    2735              : !!       - need a rectangular box (rmet diagonal matrix)
    2736              : !!
    2737              : !! SOURCE
    2738              : 
    2739            0 : subroutine recursion_nl(exppot,un,rho_out,rset,ngfft, &
    2740            0 :   &                     tsmear,trotter,dim_trott,tol,typat,&
    2741              :   &                     natom,projec)
    2742              : 
    2743              : 
    2744              :  use m_linalg_interfaces
    2745              : 
    2746              : !Arguments -------------------------------
    2747              : !scalars
    2748              :  integer,intent(in) :: trotter,natom,dim_trott
    2749              :  real(dp),intent(in) :: tol,tsmear
    2750              :  type(recursion_type),intent(in) :: rset
    2751              :  real(dp), intent(out) :: rho_out
    2752              : !arrays
    2753              :  integer,intent(in) ::  typat(natom),ngfft(18)
    2754              :  real(dp),intent(in) :: exppot(0:ngfft(1)*ngfft(2)*ngfft(3)-1)
    2755              :  real(dp),intent(inout) :: un(0:rset%nfftrec-1)
    2756              :  real(dp),pointer :: projec(:,:,:,:,:)
    2757              : !Local variables-------------------------------
    2758              : !scalars
    2759              :  integer, parameter ::  minrec = 3
    2760              :  integer  :: irec,isign,ii
    2761              :  real(dp) :: bb,beta,mult,prod_b2,rtrotter
    2762              :  real(dp) :: inf_ucvol,pi_on_rtrotter,twortrotter,exp1
    2763              :  real(dp) :: exp2,error,errold
    2764              :  real(dp) :: switchu,switchimu
    2765              :  complex(dp) :: facrec0,cinv2rtrotter,coeef_mu
    2766              :  character(len=500) :: msg
    2767              :  type(mpi_type),pointer:: mpi_loc
    2768              : !arrays
    2769              :  real(dp):: tsec(2)
    2770              :  real(dp):: inf_tr(3)
    2771            0 :  real(dp):: an(0:rset%min_nrec),bn2(0:rset%min_nrec)
    2772            0 :  real(dp):: vn(0:rset%nfftrec-1)
    2773            0 :  real(dp):: unold(0:rset%nfftrec-1)
    2774            0 :  real(dp):: Zvtempo(1:2,0:rset%nfftrec-1)
    2775            0 :  complex(dp) :: acc_rho(0:rset%min_nrec)
    2776            0 :  complex(dp) :: D(0:dim_trott),Dold(0:dim_trott)
    2777            0 :  complex(dp) :: N(0:dim_trott),Nold(0:dim_trott)
    2778              : 
    2779              : ! *************************************************************************
    2780              : 
    2781            0 :  call timab(608,1,tsec) !--start time-counter: recursion_nl
    2782            0 :  if(rset%debug)then
    2783            0 :    msg=' '
    2784            0 :    call wrtout(std_out,msg,'COLL')
    2785              :  end if
    2786              : 
    2787              : !##############################################################
    2788            0 :  beta = one/tsmear
    2789              : 
    2790              : !--Rewriting the trotter parameter
    2791            0 :  rtrotter  = max(half,real(trotter,dp))
    2792              : 
    2793              : !--Initialisation of mpi
    2794            0 :  mpi_loc => rset%mpi
    2795              : 
    2796              : !--Initialisation of metrics
    2797            0 :  inf_ucvol = rset%inf%ucvol
    2798            0 :  inf_tr = rset%inf%tr
    2799              :  mult = one   !--In the case of the calculus of the NL-energy
    2800              : 
    2801              : !--Initialisation of  an,bn,un....
    2802            0 :  N = czero;  D = cone
    2803            0 :  facrec0 = cone
    2804            0 :  Nold = czero; Dold = czero
    2805              : 
    2806            0 :  an = zero; bn2 = zero;  bn2(0) = one
    2807            0 :  bb = zero; vn  = zero;  unold  = zero
    2808              : 
    2809              : !--Variables for optimisation
    2810            0 :  pi_on_rtrotter = pi/rtrotter
    2811            0 :  twortrotter = two*rtrotter
    2812            0 :  exp1 = exp((beta*rset%efermi)/(rtrotter))
    2813            0 :  exp2 = exp(beta*rset%efermi/(twortrotter))
    2814            0 :  cinv2rtrotter = cmplx(one/twortrotter,zero,dp)
    2815            0 :  coeef_mu = cmplx(one/exp2,zero,dp)
    2816              : 
    2817              : !--Initialisation of accumulated density
    2818            0 :  acc_rho = czero
    2819              : !--Initialisation of estimated error
    2820            0 :  prod_b2 = twortrotter/exp1
    2821            0 :  errold = zero
    2822              : 
    2823              : !##############################################################
    2824              : !--Main loop
    2825            0 :  maindo : do irec = 0, rset%min_nrec
    2826              : !  --Get an and bn2 coef by the lanczos method
    2827              : 
    2828              : !  --Computation of exp(-beta*V/8*p)*un
    2829            0 :    vn = exppot * un
    2830              : 
    2831              : !  --First Non-local psp contribution: (Id+sum_atom E(r,r1))vn
    2832            0 :    call timab(608,2,tsec)
    2833            0 :    call vn_nl_rec(vn,natom,typat,rset%ngfftrec(:3),inf_ucvol,rset%nl,projec)
    2834            0 :    call timab(608,1,tsec)
    2835              : 
    2836              : !  --Computation of exp(-beta*V/8*p)*un
    2837            0 :    vn = exppot * vn
    2838              : 
    2839              : !  --Convolution with the Green kernel
    2840              : !  --FFT of vn
    2841            0 :    isign = -1
    2842            0 :    call fourdp(1,Zvtempo,vn,isign,mpi_loc,rset%nfftrec,1,rset%ngfftrec,6)
    2843              : 
    2844              : !  --F(T)F(vn)
    2845            0 :    do ii = 0,rset%nfftrec-1
    2846            0 :      switchu   = Zvtempo(1,ii)
    2847            0 :      switchimu = Zvtempo(2,ii)
    2848            0 :      Zvtempo(1,ii) = switchu*rset%ZT_p(1,ii) - switchimu*rset%ZT_p(2,ii)
    2849            0 :      Zvtempo(2,ii) = switchu*rset%ZT_p(2,ii) + switchimu*rset%ZT_p(1,ii)
    2850              :    end do
    2851              : 
    2852              : !  --F^-1(F(T)F(vn))
    2853            0 :    isign = 1
    2854            0 :    call fourdp(1,Zvtempo,vn,isign,mpi_loc,rset%nfftrec,1,rset%ngfftrec,6)
    2855              : 
    2856              : !  --Computation of exp(-beta*V/2*p)*vn
    2857            0 :    vn = inf_ucvol * exppot * vn
    2858              : 
    2859              : !  --Second Non-local psp contribution: (Id+sum_atom E(r,r1))vn
    2860            0 :    call timab(608,2,tsec)
    2861            0 :    call vn_nl_rec(vn,natom,typat,rset%ngfftrec(:3),inf_ucvol,rset%nl,projec)
    2862            0 :    call timab(608,1,tsec)
    2863              : 
    2864              : !  --Computation of exp(-beta*V/8*p)*vn
    2865            0 :    vn = exppot * vn
    2866              : 
    2867              : 
    2868              : !  --Multiplication of a and b2 coef by exp(beta*fermie/(2.d0*rtrotter)) must be done in the continued fraction computation
    2869              : !  --Computation of a and b2
    2870            0 :    an(irec) = inf_ucvol*ddot(rset%nfftrec,vn,1,un,1)      !--an must be positive real
    2871              : 
    2872              : !  --We must compute bn2 and prepare for the next iteration
    2873            0 :    if(irec<rset%min_nrec)then
    2874            0 :      do ii = 0,rset%nfftrec-1
    2875            0 :        switchu = un(ii)
    2876            0 :        un(ii) = vn(ii)-an(irec)*un(ii)-bb*unold(ii)
    2877            0 :        unold(ii) = switchu
    2878            0 :        bn2(irec+1) = bn2(irec+1)+inf_ucvol*un(ii)*un(ii)
    2879              :      end do
    2880            0 :      bb = sqrt(bn2(irec+1))
    2881            0 :      un = (one/bb)*un
    2882              :    end if
    2883              : 
    2884              : !  ######################################################
    2885              : !  --Density computation
    2886              : !  in order to make it possible to stop the recursion_nl at the
    2887              : !  needed accuracy, without doing more recursion_nl loop than needed further developpement
    2888              : 
    2889              :    call trottersum(dim_trott,error,&
    2890              : &   prod_b2,pi_on_rtrotter,&
    2891              : &   facrec0,coeef_mu,exp1,&
    2892              : &   an(irec),bn2(irec),&
    2893            0 : &   N,D,Nold,Dold)
    2894              : 
    2895              : 
    2896            0 :    if(irec/=rset%min_nrec .and. irec>=minrec)then
    2897            0 :      if((bn2(irec+1)<tol14).or.(mult*error<tol.and.errold<tol)) exit
    2898              :    end if
    2899            0 :    errold = mult*error
    2900              :  end do maindo
    2901              : !--Accumulated density
    2902            0 :  rho_out = mult*real(cone-sum(N/D)*cinv2rtrotter,dp)
    2903              : 
    2904            0 :  call timab(608,2,tsec) !--stop time-counter: recursion_nl
    2905              : 
    2906            0 : end subroutine recursion_nl
    2907              : !!***
    2908              : 
    2909              : 
    2910              : !!****f* ABINIT/vn_nl_rec
    2911              : !! NAME
    2912              : !! vn_nl_rec
    2913              : !!
    2914              : !! FUNCTION
    2915              : !! this routine computes the contribution to the vector vn, during
    2916              : !! recursion, due to the non-local psp.
    2917              : !!
    2918              : !! INPUTS
    2919              : !!  vn(:,:,:)=the vector on the real-space grid.
    2920              : !!  inf_ucvol=volume of infinitesimal cell
    2921              : !!  natom=number of atoms
    2922              : !!  typat(natom)=the type of psps associated to the atoms
    2923              : !!  ngfftrec(3)=first 3 components of ngfftrec (truncated box, if different from ngfft) for the real-space grid
    2924              : !!  nlrec<type(nlpsprec_type)> in recursion_type containing information concerning psp
    2925              : !!  projec(ngfftrec(1),ngfftrec(2),ngfftrec(3),lmnmax,natom) is the  vector, on the ngfftrec grid containing
    2926              : !!  the non-lacal projector $Y_{lm}(r-R_A)f_{lk}(r-R_A)
    2927              : !!
    2928              : !! OUTPUT
    2929              : !! vn_nl(:,:,:)=the non_local contribution to vn
    2930              : !!
    2931              : !! NOTES
    2932              : !!
    2933              : !! SOURCE
    2934              : 
    2935            0 : subroutine vn_nl_rec(vn,natom,typat,ngfftrec,inf_ucvol,nlrec,projec)
    2936              : 
    2937              : 
    2938              :  use m_linalg_interfaces
    2939              : 
    2940              : !Arguments -------------------------------
    2941              : !scalars
    2942              :  integer,intent(in) :: natom
    2943              :  real(dp),intent(in) :: inf_ucvol
    2944              :  type(nlpsprec_type),intent(in) :: nlrec
    2945              : !arrays
    2946              :  integer,intent(in) :: ngfftrec(3),typat(natom)
    2947              :  real(dp),intent(in) :: projec(0:,0:,0:,1:,1:)
    2948              :  real(dp),intent(inout):: vn(0:ngfftrec(1)*ngfftrec(2)*ngfftrec(3)-1)
    2949              : !Local variables-------------------------------
    2950              : !scalars
    2951              :  integer :: iatom,nfftrec
    2952              :  integer :: jlmn,il,in,jn
    2953              :  integer :: ipsp,ilmn
    2954              :  integer :: npsp,lmnmax
    2955              :  real(dp):: vn_nl_loc
    2956              : !arrays
    2957            0 :  real(dp):: vn_nl(0:ngfftrec(1)-1,0:ngfftrec(2)-1,0:ngfftrec(3)-1)
    2958            0 :  real(dp):: vtempo(0:ngfftrec(1)-1,0:ngfftrec(2)-1,0:ngfftrec(3)-1)
    2959              :  real(dp):: tsec(2)
    2960              : ! *************************************************************************
    2961              : 
    2962            0 :  call timab(615,1,tsec)
    2963              : !--Initialisation
    2964              : 
    2965            0 :  vn_nl = zero
    2966            0 :  npsp = nlrec%npsp
    2967            0 :  lmnmax = nlrec%lmnmax
    2968            0 :  nfftrec = product(ngfftrec)
    2969            0 :  vtempo(:,:,:) = reshape(source=vn,shape=ngfftrec(:3))
    2970              : 
    2971              : !--Sum_iatom \int dr1 E(r-r_a,r1-r_a)vn(r1) *infucvol
    2972            0 :  do iatom=1,natom !--Loop on atoms
    2973            0 :    ipsp = typat(natom)
    2974              : 
    2975              : !  --If psp(typat(iatom)) is local then cycle
    2976            0 :    if(all(nlrec%pspinfo(:,ipsp)==0))  cycle
    2977              : 
    2978              : 
    2979              : !  write(std_out,*)'lmnmax',nlrec%lmnmax,lmnmax
    2980              : 
    2981            0 :    do ilmn = 1, lmnmax
    2982            0 :      do jlmn = 1,lmnmax
    2983            0 :        if(nlrec%indlmn(4,ilmn,ipsp)==nlrec%indlmn(4,jlmn,ipsp)) then
    2984            0 :          il = 1+nlrec%indlmn(1,jlmn,ipsp)
    2985            0 :          in = nlrec%indlmn(3,ilmn,ipsp)
    2986            0 :          jn = nlrec%indlmn(3,jlmn,ipsp)
    2987            0 :          vn_nl_loc = ddot(nfftrec,projec(:,:,:,jlmn,iatom),1,vtempo,1)
    2988            0 :          vn_nl = vn_nl+projec(:,:,:,ilmn,iatom)*vn_nl_loc*nlrec%mat_exp_psp_nl(in,jn,il,ipsp)
    2989              :        end if
    2990              :      end do
    2991              :    end do
    2992              :  end do !--End loop on atoms
    2993            0 :  vtempo = vtempo + vn_nl*inf_ucvol
    2994              : 
    2995            0 :  vn = reshape(source=vtempo,shape=(/nfftrec/))
    2996              : 
    2997            0 :  call timab(615,2,tsec)
    2998              : 
    2999            0 : end subroutine vn_nl_rec
    3000              : !!***
    3001              : 
    3002              : end module m_vtorhorec
    3003              : !!***
        

Generated by: LCOV version 2.3-1