LCOV - code coverage report
Current view: top level - src/66_nonlocal - m_opernlc_ylm_allwf.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 15.0 % 674 101
Test Date: 2026-09-20 18:56:22 Functions: 33.3 % 3 1

            Line data    Source code
       1              : !!****m* ABINIT/m_opernlc_ylm_allwf
       2              : !! NAME
       3              : !!  m_opernlc_ylm_allwf
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 2008-2026 ABINIT group (MT)
       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_opernlc_ylm_allwf
      22              : 
      23              :  use defs_basis
      24              :  use m_errors
      25              :  use m_abicore
      26              :  use m_xmpi
      27              :  use m_gputk
      28              :  use m_abi_linalg
      29              :  use, intrinsic :: iso_c_binding
      30              : 
      31              :  use defs_abitypes, only : MPI_type
      32              :  use m_opernlc_ylm, only : ls_ylm
      33              : 
      34              :  implicit none
      35              : 
      36              :  private
      37              : !!***
      38              : 
      39              :  public :: opernlc_ylm_allwf
      40              : !!***
      41              : 
      42              : ! Work buffers to be used when iphase==2
      43              :  real(dp), allocatable, target :: d2gxdtfac_2ndphase(:,:,:,:,:)
      44              :  real(dp), allocatable, target :: dgxdtfac_2ndphase(:,:,:,:,:)
      45              :  real(dp), allocatable, target :: gxfac_2ndphase(:,:,:,:)
      46              : ! Work buffer for NC+SO L.S matrix (pointer pattern for compiler robustness)
      47              :  real(dp), allocatable, target :: ls_ylm_so_data(:,:,:)
      48              : 
      49              : !----------------------------------------------------------------------
      50              : 
      51              : contains
      52              : !!***
      53              : 
      54              : !----------------------------------------------------------------------
      55              : 
      56              : !!****f* m_opernlc_ylm_allwf/alloc_work_arrays
      57              : !! NAME
      58              : !! alloc_work_arrays
      59              : !!
      60              : !! FUNCTION
      61              : !! Allocation of work arrays
      62              : !!
      63              : !! INPUTS
      64              : !!
      65              : !! SOURCE
      66            0 :  subroutine alloc_work_arrays(optder,cplex_fac,ndgxdtfac,nd2gxdtfac,nprojs,nspinor,ndat,gpu_option)
      67              : 
      68              :   integer,intent(in) :: optder,cplex_fac,ndgxdtfac,nd2gxdtfac,nprojs,nspinor,ndat,gpu_option
      69              : 
      70              : ! *************************************************************************
      71              : 
      72            0 :    ABI_MALLOC(gxfac_2ndphase,(cplex_fac,nprojs,nspinor,ndat))
      73              : #ifdef HAVE_OPENMP_OFFLOAD
      74              :    !$OMP TARGET ENTER DATA MAP(alloc:gxfac_2ndphase) IF(gpu_option==ABI_GPU_OPENMP)
      75              : #endif
      76            0 :    if(gpu_option==ABI_GPU_OPENMP) then
      77            0 :      call gpu_set_to_zero(gxfac_2ndphase, int(cplex_fac,c_size_t)*nprojs*nspinor*ndat)
      78              :    else
      79            0 :      gxfac_2ndphase(:,:,:,:) = zero
      80              :    end if
      81            0 :    if (optder>=1) then
      82            0 :      ABI_MALLOC(dgxdtfac_2ndphase,(cplex_fac,ndgxdtfac,nprojs,nspinor,ndat))
      83              : #ifdef HAVE_OPENMP_OFFLOAD
      84              :      !$OMP TARGET ENTER DATA MAP(alloc:dgxdtfac_2ndphase) IF(gpu_option==ABI_GPU_OPENMP)
      85              : #endif
      86            0 :      if(gpu_option==ABI_GPU_OPENMP) then
      87            0 :        call gpu_set_to_zero(dgxdtfac_2ndphase, int(cplex_fac,c_size_t)*ndgxdtfac*nprojs*nspinor*ndat)
      88              :      else
      89            0 :        dgxdtfac_2ndphase(:,:,:,:,:) = zero
      90              :      end if
      91              :    end if
      92            0 :    if (optder>=2) then
      93            0 :      ABI_MALLOC(d2gxdtfac_2ndphase,(cplex_fac,nd2gxdtfac,nprojs,nspinor,ndat))
      94              : #ifdef HAVE_OPENMP_OFFLOAD
      95              :      !$OMP TARGET ENTER DATA MAP(alloc:dgxdtfac_2ndphase) IF(gpu_option==ABI_GPU_OPENMP)
      96              : #endif
      97            0 :      if(gpu_option==ABI_GPU_OPENMP) then
      98            0 :        call gpu_set_to_zero(d2gxdtfac_2ndphase, int(cplex_fac,c_size_t)*nd2gxdtfac*nprojs*nspinor*ndat)
      99              :      else
     100            0 :        d2gxdtfac_2ndphase(:,:,:,:,:) = zero
     101              :      end if
     102              :    end if
     103              : 
     104            0 :  end subroutine alloc_work_arrays
     105              : !!***
     106              : 
     107              : !----------------------------------------------------------------------
     108              : 
     109              : !!****f* m_opernlc_ylm_allwf/destroy_work_arrays
     110              : !! NAME
     111              : !! destroy_work_arrays
     112              : !!
     113              : !! FUNCTION
     114              : !! Destruction of work arrays
     115              : !!
     116              : !! INPUTS
     117              : !!
     118              : !! SOURCE
     119            0 :  subroutine destroy_work_arrays(gpu_option)
     120              : 
     121              :   integer,intent(in) :: gpu_option
     122              : 
     123              : ! *************************************************************************
     124              : 
     125              :   ABI_UNUSED(gpu_option) !Silent abirules
     126              : 
     127            0 :   if(allocated(gxfac_2ndphase)) then
     128              : #ifdef HAVE_OPENMP_OFFLOAD
     129              :     !$OMP TARGET EXIT DATA MAP(delete:gxfac_2ndphase) IF(gpu_option==ABI_GPU_OPENMP)
     130              : #endif
     131            0 :     ABI_FREE(gxfac_2ndphase)
     132              :   end if
     133            0 :   if(allocated(dgxdtfac_2ndphase)) then
     134              : #ifdef HAVE_OPENMP_OFFLOAD
     135              :     !$OMP TARGET EXIT DATA MAP(delete:dgxdtfac_2ndphase) IF(gpu_option==ABI_GPU_OPENMP)
     136              : #endif
     137            0 :     ABI_FREE(dgxdtfac_2ndphase)
     138              :   end if
     139            0 :   if(allocated(d2gxdtfac_2ndphase)) then
     140              : #ifdef HAVE_OPENMP_OFFLOAD
     141              :     !$OMP TARGET EXIT DATA MAP(delete:d2gxdtfac_2ndphase) IF(gpu_option==ABI_GPU_OPENMP)
     142              : #endif
     143            0 :     ABI_FREE(d2gxdtfac_2ndphase)
     144              :   end if
     145              : 
     146            0 :  end subroutine destroy_work_arrays
     147              : !!***
     148              : 
     149              : !----------------------------------------------------------------------
     150              : 
     151              : !!****f* ABINIT/opernlc_ylm_allwf
     152              : !! NAME
     153              : !! opernlc_ylm_allwf
     154              : !!
     155              : !! FUNCTION
     156              : !! * Operate with the non-local part of the hamiltonian,
     157              : !!   in order to reduce projected scalars
     158              : !! * Operate with the non-local projectors and the overlap matrix,
     159              : !!   in order to reduce projected scalars
     160              : !!
     161              : !! INPUTS
     162              : !!  atindx1(natom)=index table for atoms (gives the absolute index of
     163              : !!                 an atom from its rank in a block of atoms)
     164              : !!  cplex=1 if <p_lmn|c> scalars are real (equivalent to istwfk>1)
     165              : !!        2 if <p_lmn|c> scalars are complex
     166              : !!  cplex_dgxdt(ndgxdt) = used only when cplex = 1
     167              : !!             cplex_dgxdt(i) = 1 if dgxdt(1,i,:,:)   is real, 2 if it is pure imaginary
     168              : !!  cplex_enl=1 if enl factors are real, 2 if they are complex
     169              : !!  cplex_fac=1 if gxfac scalars are real, 2 if gxfac scalars are complex
     170              : !!  dgxdt(cplex,ndgxdt,nlmn,nincat)=grads of projected scalars (only if optder>0)
     171              : !!  dimenl1,dimenl2=dimensions of enl (see enl)
     172              : !!  dimekbq=1 if enl factors do not contain a exp(-iqR) phase, 2 is they do
     173              : !!  enl(cplex_enl*dimenl1,dimenl2,nspinortot**2,dimekbq)=
     174              : !!  ->Norm conserving : ==== when paw_opt=0 ====
     175              : !!                      (Real) Kleinman-Bylander energies (hartree)
     176              : !!                      dimenl1=lmnmax  -  dimenl2=ntypat
     177              : !!                      dimekbq is 2 if Enl contains a exp(-iqR) phase, 1 otherwise
     178              : !!  ->PAW :             ==== when paw_opt=1, 2 or 4 ====
     179              : !!                      (Real or complex, hermitian) Dij coefs to connect projectors
     180              : !!                      dimenl1=cplex_enl*lmnmax*(lmnmax+1)/2  -  dimenl2=natom
     181              : !!                      These are complex numbers if cplex_enl=2
     182              : !!                        enl(:,:,1) contains Dij^up-up
     183              : !!                        enl(:,:,2) contains Dij^dn-dn
     184              : !!                        enl(:,:,3) contains Dij^up-dn (only if nspinor=2)
     185              : !!                        enl(:,:,4) contains Dij^dn-up (only if nspinor=2)
     186              : !!                      dimekbq is 2 if Dij contains a exp(-iqR) phase, 1 otherwise
     187              : !!  gx(cplex,nlmn,nincat*abs(enl_opt))= projected scalars
     188              : !!  iatm=absolute rank of first atom of the current block of atoms
     189              : !!  indlmn(6,nlmn)= array giving l,m,n,lm,ln,s for i=lmn
     190              : !!  itypat=type of atoms
     191              : !!  lambda=factor to be used when computing (Vln-lambda.S) - only for paw_opt=2
     192              : !!  mpi_enreg=information about MPI parallelization
     193              : !!  natom=number of atoms in cell
     194              : !!  ndgxdt=second dimension of dgxdt
     195              : !!  ndgxdtfac=second dimension of dgxdtfac
     196              : !!  nincat=number of atoms in the subset here treated
     197              : !!  nlmn=number of (l,m,n) numbers for current type of atom
     198              : !!  nspinor= number of spinorial components of the wavefunctions (on current proc)
     199              : !!  nspinortot=total number of spinorial components of the wavefunctions
     200              : !!  optder=0=only gxfac is computed, 1=both gxfac and dgxdtfac are computed
     201              : !!         2=gxfac, dgxdtfac and d2gxdtfac are computed
     202              : !!  paw_opt= define the nonlocal operator concerned with:
     203              : !!           paw_opt=0 : Norm-conserving Vnl (use of Kleinman-Bylander ener.)
     204              : !!           paw_opt=1 : PAW nonlocal part of H (use of Dij coeffs)
     205              : !!           paw_opt=2 : PAW: (Vnl-lambda.Sij) (Sij=overlap matrix)
     206              : !!           paw_opt=3 : PAW overlap matrix (Sij)
     207              : !!           paw_opt=4 : both PAW nonlocal part of H (Dij) and overlap matrix (Sij)
     208              : !!  sij(nlm*(nlmn+1)/2)=overlap matrix components (only if paw_opt=2, 3 or 4)
     209              : !!
     210              : !! OUTPUT
     211              : !!  if (paw_opt=0, 1, 2 or 4)
     212              : !!    gxfac(cplex_fac,nlmn,nincat,nspinor)= reduced projected scalars related to Vnl (NL operator)
     213              : !!  if (paw_opt=3 or 4)
     214              : !!    gxfac_sij(cplex,nlmn,nincat,nspinor)= reduced projected scalars related to Sij (overlap)
     215              : !!  if (optder==1.and.paw_opt=0, 1, 2 or 4)
     216              : !!    dgxdtfac(cplex_fac,ndgxdtfac,nlmn,nincat,nspinor)= gradients of gxfac related to Vnl (NL operator)
     217              : !!  if (optder==1.and.paw_opt=3 or 4)
     218              : !!    dgxdtfac_sij(cplex,ndgxdtfac,nlmn,nincat,nspinor)= gradients of gxfac related to Sij (overlap)
     219              : !!
     220              : !! NOTES
     221              : !! This routine operates for one type of atom, and within this given type of atom,
     222              : !! for a subset of at most nincat atoms.
     223              : !!
     224              : !! About the non-local factors symmetry:
     225              : !!   - The lower triangular part of the Dij matrix can be deduced from the upper one
     226              : !!     with the following relation: D^s2s1_ji = (D^s1s2_ij)^*
     227              : !!     where s1,s2 are spinor components
     228              : !!   - The Dij factors can contain a exp(-iqR) phase
     229              : !!     This phase does not have to be included in the symmetry rule
     230              : !!     For that reason, we first apply the real part (cos(qR).D^s1s2_ij)
     231              : !!     then, we apply the imaginary part (-sin(qR).D^s1s2_ij)
     232              : !!
     233              : !! SOURCE
     234              : 
     235        36992 : subroutine opernlc_ylm_allwf(atindx1,cplex,cplex_dgxdt,cplex_d2gxdt,cplex_enl,cplex_fac,&
     236        36992 : &          dgxdt,dgxdtfac,dgxdtfac_sij,d2gxdt,d2gxdtfac,d2gxdtfac_sij,dimenl1,dimenl2,dimekbq,enl,&
     237        36992 : &          gx,gxfac,gxfac_sij,iatm,indlmn,itypat,lambda,mpi_enreg,natom,ndgxdt,ndgxdtfac,&
     238        18496 : &          nd2gxdt,nd2gxdtfac,nincat,nlmn,nspinor,nspinortot,optder,paw_opt,sij,ndat,ibeg,iend,nprojs,ndat_enl,gpu_option)
     239              : 
     240              : !Arguments ------------------------------------
     241              : !scalars
     242              :  integer,intent(in) :: cplex,cplex_enl,cplex_fac,dimenl1,dimenl2,dimekbq,iatm,itypat
     243              :  integer,intent(in) :: natom,ndgxdt,ndgxdtfac,nd2gxdt,nd2gxdtfac,nincat,nspinor,nspinortot,optder,paw_opt,gpu_option
     244              :  integer,intent(inout) :: nlmn
     245              :  integer,intent(in) :: ndat,ibeg,iend,nprojs,ndat_enl
     246              :  real(dp) :: lambda(ndat)
     247              :  type(MPI_type) , intent(in) :: mpi_enreg
     248              : !arrays
     249              :  integer,intent(in) :: atindx1(natom),indlmn(6,nlmn),cplex_dgxdt(ndgxdt),cplex_d2gxdt(nd2gxdt)
     250              :  real(dp),intent(in) :: dgxdt(cplex,ndgxdt,nprojs,nspinor,ndat)
     251              :  real(dp),intent(in) :: d2gxdt(cplex,nd2gxdt,nlmn,nincat,nspinor,ndat)
     252              :  real(dp),intent(in),target :: enl(dimenl1,dimenl2,nspinortot**2,ndat_enl,dimekbq)
     253              :  real(dp),intent(inout) :: gx(cplex,nprojs,nspinor,ndat)
     254              :  real(dp),intent(in) :: sij(:)
     255              :  real(dp),intent(out),target :: dgxdtfac(cplex_fac,ndgxdtfac,nprojs,nspinor,ndat)
     256              :  real(dp),intent(out) :: dgxdtfac_sij(cplex,ndgxdtfac,nprojs,nspinor,ndat*(paw_opt/3))
     257              :  real(dp),intent(out),target :: d2gxdtfac(cplex_fac,nd2gxdtfac,nprojs,nspinor,ndat)
     258              :  real(dp),intent(out) :: d2gxdtfac_sij(cplex,nd2gxdtfac,nprojs,nspinor,ndat*(paw_opt/3))
     259              :  real(dp),intent(out),target :: gxfac(cplex_fac,nprojs,nspinor,ndat)
     260              :  real(dp),intent(out) :: gxfac_sij(cplex,nprojs,nspinor,ndat)
     261              : 
     262              : !Local variables-------------------------------
     263              : !Arrays
     264              : !scalars
     265              :  integer :: cplex_,ia,ijlmn,ilm,ilmn,i0lmn,iln,index_enl,iphase,ispinor,ispinor_index,idat
     266              :  integer :: jlm,j0lmn,jjlmn,jlmn,jspinor,mu,shift,ii
     267              :  integer :: ll_so,klm_so,lmax_so,nlmso,sign_so
     268              :  real(dp) :: ekb_so_1,ekb_so_2,ls_uu_im,ls_ud_re,ls_ud_im
     269              : !arrays
     270        36992 :  real(dp) :: enl_(2),gxfi(2),gxi(cplex),gxj(cplex)
     271        18496 :  real(dp), ABI_CONTIGUOUS pointer :: d2gxdtfac_(:,:,:,:,:),dgxdtfac_(:,:,:,:,:),gxfac_(:,:,:,:)
     272        18496 :  real(dp), ABI_CONTIGUOUS pointer :: ls_ylm_so_(:,:,:)
     273        18496 :  real(dp), ABI_CONTIGUOUS pointer :: enl_ptr(:,:,:),enl_ptr2(:,:,:,:)
     274              : 
     275              : ! *************************************************************************
     276              : 
     277            0 :  if (gpu_option/=ABI_GPU_DISABLED.and.mpi_enreg%paral_spinor==1) then
     278            0 :    ABI_ERROR('parallelization over spinors (npspinor=2) not allowed with GPU!')
     279              :  end if
     280              : 
     281              :  ABI_UNUSED(iend)
     282              :  ABI_UNUSED(d2gxdt)
     283              :  ABI_UNUSED(cplex_d2gxdt)
     284              :  ABI_UNUSED(d2gxdtfac_sij)
     285              :  DBG_ENTER("COLL")
     286              : 
     287              : !Parallelization over spinors treatment
     288        18496 :  shift=0;if (mpi_enreg%paral_spinor==1) shift=mpi_enreg%me_spinor
     289              : !When Enl factors contain a exp(-iqR) phase:
     290              : ! - We loop over the real and imaginary parts
     291              : ! - We need an additional memory space
     292        36992 :  do iphase=1,dimekbq
     293        18496 :   if (paw_opt==3) cycle
     294        18496 :   if (iphase==1) then
     295        18496 :    gxfac_ => gxfac ; dgxdtfac_ => dgxdtfac ; d2gxdtfac_ => d2gxdtfac
     296              :   else
     297            0 :    ABI_CHECK(cplex_fac==2,"BUG: invalid cplex_fac==1 when dimekbq=2!")
     298            0 :    call alloc_work_arrays(optder,cplex_fac,ndgxdtfac,nd2gxdtfac,nprojs,nspinor,ndat,gpu_option)
     299            0 :    gxfac_ => gxfac_2ndphase
     300            0 :    if(optder>=1) dgxdtfac_ => dgxdtfac_2ndphase
     301            0 :    if(optder>=2) d2gxdtfac_ => d2gxdtfac_2ndphase
     302              :   end if
     303        18496 :   enl_ptr => enl(:,:,:,1,iphase)
     304        18496 :   enl_ptr2 => enl(:,:,:,:,iphase)
     305              : 
     306              : !NC+SO: precompute L.S matrix once
     307        18496 :  lmax_so = 0
     308        18496 :  if (paw_opt==0.and.nspinortot==2.and.nspinor==nspinortot) then
     309            0 :    if (any(indlmn(6,1:nlmn)==2)) then
     310            0 :      do ilmn=1,nlmn
     311            0 :        if (indlmn(6,ilmn)==2) lmax_so = max(lmax_so, indlmn(1,ilmn))
     312              :      end do
     313            0 :      if (lmax_so > 0) then
     314            0 :        nlmso = (lmax_so+1)**2*((lmax_so+1)**2+1)/2
     315            0 :        ABI_MALLOC(ls_ylm_so_data,(2,nlmso,2))
     316            0 :        call ls_ylm(ls_ylm_so_data, lmax_so)
     317              : #ifdef HAVE_OPENMP_OFFLOAD
     318              :        !$OMP TARGET ENTER DATA MAP(to:ls_ylm_so_data) IF(gpu_option==ABI_GPU_OPENMP)
     319              : #endif
     320            0 :        ls_ylm_so_ => ls_ylm_so_data
     321              :      end if
     322              :    end if
     323              :  end if
     324        18496 :  if (paw_opt==0.and.mpi_enreg%paral_spinor==1.and.lmax_so>0) then
     325            0 :    ABI_ERROR('parallelization over spinors, spin-orbit and norm-conserving psps not implemented!')
     326              :  end if
     327              : 
     328              : 
     329              : !Accumulate gxfac related to non-local operator (Norm-conserving)
     330              : !-------------------------------------------------------------------
     331        18496 :  if (paw_opt==0) then
     332              : 
     333              : !Enl is E(Kleinman-Bylander)
     334         3200 :    ABI_CHECK(cplex_enl/=2,"BUG: invalid cplex_enl=2!")
     335         3200 :    ABI_CHECK(cplex_fac==cplex,"BUG: invalid cplex_fac/=cplex!")
     336              : 
     337         3200 :    if (lmax_so == 0) then
     338              : 
     339              : !    NC+SR ---
     340              : #ifdef HAVE_OPENMP_OFFLOAD
     341              :      !$OMP TARGET TEAMS DISTRIBUTE &
     342              :      !$OMP& MAP(to:gxfac_,gx,enl_ptr2,indlmn) &
     343              :      !$OMP& PRIVATE(idat,ispinor) &
     344              :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     345              : #endif
     346        39552 :      do idat=1,ndat
     347        75904 :        do ispinor=1,nspinor
     348              :          !$OMP PARALLEL DO COLLAPSE(3) PRIVATE(ia,ilmn,iln,ii)
     349       236288 :          do ia=1,nincat
     350      2599168 :            do ilmn=1,nlmn
     351      6761472 :              do ii=1,cplex
     352      6597888 :                if (indlmn(6,ilmn)==2) then
     353            0 :                  gxfac_(ii,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat) = zero
     354              :                else
     355      4198656 :                  iln = indlmn(5,ilmn)
     356              :                  gxfac_(ii,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
     357      4198656 : &                  enl_ptr2(iln,itypat,ispinor+shift,min(ndat_enl,idat))*gx(ii,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     358              :                end if
     359              :              end do
     360              :            end do
     361              :          end do
     362              :        end do
     363              :      end do
     364              : 
     365              :    else
     366              : 
     367              : !    NC+SR+SO: real-Ylm L.S coupling ---
     368              : #ifdef HAVE_OPENMP_OFFLOAD
     369              :      !$OMP TARGET TEAMS DISTRIBUTE &
     370              :      !$OMP& MAP(to:gxfac_,gx,enl_ptr2,indlmn,ls_ylm_so_) &
     371              :      !$OMP& PRIVATE(idat) &
     372              :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     373              : #endif
     374            0 :      do idat=1,ndat
     375              :        !$OMP PARALLEL DO COLLAPSE(2) &
     376              :        !$OMP& PRIVATE(ia,ilmn,iln,ekb_so_1,ekb_so_2,ll_so,ilm,jlmn,jlm,klm_so,sign_so,ls_uu_im,ls_ud_re,ls_ud_im)
     377            0 :        do ia=1,nincat
     378            0 :          do ilmn=1,nlmn
     379            0 :            iln = indlmn(5,ilmn)
     380              :  
     381            0 :            if (indlmn(6,ilmn)/=2) then
     382            0 :              ekb_so_1 = enl_ptr2(iln,itypat,1,min(ndat_enl,idat))
     383            0 :              ekb_so_2 = enl_ptr2(iln,itypat,2,min(ndat_enl,idat))
     384            0 :              gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,1,idat)=ekb_so_1*gx(1,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     385            0 :              gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,1,idat)=ekb_so_1*gx(2,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     386            0 :              gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,2,idat)=ekb_so_2*gx(1,ilmn+(ia-1)*nlmn+ibeg,2,idat)
     387            0 :              gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,2,idat)=ekb_so_2*gx(2,ilmn+(ia-1)*nlmn+ibeg,2,idat)
     388              : 
     389              :            else
     390            0 :              gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,1,idat) = zero
     391            0 :              gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,1,idat) = zero
     392            0 :              gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,2,idat) = zero
     393            0 :              gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,2,idat) = zero
     394              : 
     395            0 :              ekb_so_1 = enl_ptr2(iln,itypat,1,min(ndat_enl,idat))
     396            0 :              if (abs(ekb_so_1)<tol16) cycle
     397            0 :              ll_so = indlmn(1,ilmn)
     398            0 :              ilm   = indlmn(4,ilmn)
     399            0 :              do jlmn=1,nlmn
     400            0 :                if (indlmn(6,jlmn)/=2) cycle
     401            0 :                if (indlmn(1,jlmn)/=ll_so) cycle
     402            0 :                if (indlmn(3,jlmn)/=indlmn(3,ilmn)) cycle
     403            0 :                jlm = indlmn(4,jlmn)
     404            0 :                if (ilm<=jlm) then
     405            0 :                  klm_so  = jlm*(jlm-1)/2 + ilm
     406            0 :                  sign_so = 1
     407              :                else
     408            0 :                  klm_so  = ilm*(ilm-1)/2 + jlm
     409            0 :                  sign_so = -1
     410              :                end if
     411            0 :                ls_uu_im = sign_so * ls_ylm_so_(2,klm_so,1)
     412            0 :                ls_ud_re = sign_so * ls_ylm_so_(1,klm_so,2)
     413            0 :                ls_ud_im = sign_so * ls_ylm_so_(2,klm_so,2)
     414              : 
     415              :                ! up-up
     416              :                gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,1,idat) &
     417            0 : &                 - ekb_so_1*ls_uu_im*gx(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)
     418              :                gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,1,idat) &
     419            0 : &                 + ekb_so_1*ls_uu_im*gx(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)
     420              :                ! up-dn
     421              :                gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,1,idat) &
     422            0 : &                 + ekb_so_1*(ls_ud_re*gx(1,jlmn+(ia-1)*nlmn+ibeg,2,idat) - ls_ud_im*gx(2,jlmn+(ia-1)*nlmn+ibeg,2,idat))
     423              :                gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,1,idat) &
     424            0 : &                 + ekb_so_1*(ls_ud_re*gx(2,jlmn+(ia-1)*nlmn+ibeg,2,idat) + ls_ud_im*gx(1,jlmn+(ia-1)*nlmn+ibeg,2,idat))
     425              :                ! dn-up
     426              :                gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,2,idat)=gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,2,idat) &
     427            0 : &                 + ekb_so_1*(-ls_ud_re*gx(1,jlmn+(ia-1)*nlmn+ibeg,1,idat) - ls_ud_im*gx(2,jlmn+(ia-1)*nlmn+ibeg,1,idat))
     428              :                gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,2,idat)=gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,2,idat) &
     429            0 : &                 + ekb_so_1*(-ls_ud_re*gx(2,jlmn+(ia-1)*nlmn+ibeg,1,idat) + ls_ud_im*gx(1,jlmn+(ia-1)*nlmn+ibeg,1,idat))
     430              :                ! dn-dn
     431              :                gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,2,idat)=gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,2,idat) &
     432            0 : &                 + ekb_so_1*ls_uu_im*gx(2,jlmn+(ia-1)*nlmn+ibeg,2,idat)
     433              :                gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,2,idat)=gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,2,idat) &
     434            0 : &                 - ekb_so_1*ls_uu_im*gx(1,jlmn+(ia-1)*nlmn+ibeg,2,idat)
     435              :              end do ! jlmn
     436              :            end if ! indlmn(:,6)==2
     437              :          end do ! ilmn
     438              :        end do ! ia
     439              :        !$OMP END PARALLEL DO
     440              : 
     441              :      end do ! idat
     442              :    end if ! NC+SO
     443              :  end if ! NC
     444              : 
     445              : !Accumulate gxfac related to nonlocal operator (PAW)
     446              : !-------------------------------------------------------------------
     447        18496 :  if (paw_opt==1.or.paw_opt==2.or.paw_opt==4) then
     448              :    !Enl is psp strength Dij or (Dij-lambda.Sij)
     449              : 
     450              : !  === Diagonal term(s) (up-up, down-down)
     451              : 
     452              : !  1-Enl is real
     453        15296 :    if (cplex_enl==1) then
     454        15296 :      if (paw_opt==2) then
     455              : #ifdef HAVE_OPENMP_OFFLOAD
     456              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
     457              :        !$OMP& MAP(to:gxfac_,enl_ptr2,atindx1,gx,sij,lambda) &
     458              :        !$OMP& PRIVATE(idat,ispinor) &
     459              :        !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     460              : #endif
     461         1576 :        do idat=1,ndat
     462         2568 :        do ispinor=1,nspinor
     463              :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,ispinor_index,index_enl,j0lmn,i0lmn,ii)
     464         3520 :          do ia=1,nincat
     465        19296 :            do jlmn=1,nlmn
     466        16768 :              ispinor_index=ispinor+shift
     467        16768 :              index_enl=atindx1(iatm+ia)
     468        16768 :              j0lmn=jlmn*(jlmn-1)/2
     469        46256 :              do ii=1,cplex
     470              :                gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
     471              : &                 gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat) + &
     472              : &                 (enl_ptr2(j0lmn+jlmn,index_enl,ispinor_index,min(ndat_enl,idat))-lambda(idat) * sij(j0lmn+jlmn)) * &
     473        46256 : &                 gx(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     474              :              end do
     475       115776 :              do ilmn=1,jlmn-1
     476       284504 :                do ii=1,cplex
     477              :                  gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
     478              : &                   gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat) + &
     479              : &                   (enl_ptr2(j0lmn+ilmn,index_enl,ispinor_index,min(ndat_enl,idat))-lambda(idat) * sij(j0lmn+ilmn)) * &
     480       267736 : &                   gx(ii,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     481              :                end do
     482              :              end do
     483        18304 :              if(jlmn<nlmn) then
     484       114240 :                do ilmn=jlmn+1,nlmn
     485        99008 :                  i0lmn=(ilmn*(ilmn-1)/2)
     486       282968 :                  do ii=1,cplex
     487              :                    gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
     488              : &                     gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat) + &
     489              : &                     (enl_ptr2(i0lmn+jlmn,index_enl,ispinor_index,min(ndat_enl,idat))-lambda(idat) * sij(i0lmn+jlmn)) *&
     490       267736 : &                     gx(ii,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     491              :                  end do
     492              :                end do
     493              :              end if
     494              :            end do
     495              :          end do
     496              :        end do
     497              :        end do
     498              : 
     499              :      else
     500              : #ifdef HAVE_OPENMP_OFFLOAD
     501              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
     502              :        !$OMP& MAP(to:enl_ptr2,atindx1,gx,gxfac_) &
     503              :        !$OMP& PRIVATE(idat,ispinor) &
     504              :        !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     505              : #endif
     506        47206 :        do idat=1,ndat
     507        79700 :        do ispinor=1,nspinor
     508              :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(jlmn,j0lmn,ii,ia,ispinor_index,index_enl)
     509       107874 :          do ia=1,nincat
     510       639488 :            do jlmn=1,nlmn
     511       564108 :              ispinor_index=ispinor+shift
     512       564108 :              index_enl=atindx1(iatm+ia)
     513       564108 :              j0lmn=jlmn*(jlmn-1)/2
     514      1559602 :              do ii=1,cplex
     515              :                gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
     516              : &                  gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat) + &
     517              : &                  enl_ptr2(j0lmn+jlmn,index_enl,ispinor_index,min(ndat_enl,idat)) * &
     518      1516716 : &                  gx(ii,ibeg+jlmn+(ia-1)*nlmn,ispinor,idat)
     519              :              end do
     520              :            end do
     521              :          end do
     522              :        end do
     523              :        end do
     524              : 
     525              : #ifdef HAVE_OPENMP_OFFLOAD
     526              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(3) &
     527              :        !$OMP& MAP(to:enl_ptr2,atindx1,gx,gxfac_) &
     528              :        !$OMP& PRIVATE(idat,ispinor,ia,ispinor_index,index_enl) &
     529              :        !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     530              : #endif
     531        47206 :        do idat=1,ndat
     532        79700 :        do ispinor=1,nspinor
     533       107874 :          do ia=1,nincat
     534        42886 :            ispinor_index=ispinor+shift
     535        42886 :            index_enl=atindx1(iatm+ia)
     536              :            !$OMP PARALLEL DO PRIVATE(j0lmn,jlmn,ilmn,i0lmn,ii)
     537       639488 :            do jlmn=1,nlmn
     538       564108 :              j0lmn=jlmn*(jlmn-1)/2
     539      4527666 :              do ilmn=1,jlmn-1
     540     11094594 :                do ii=1,cplex
     541              :                  gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat) + &
     542     10530486 : &                   enl_ptr2(j0lmn+ilmn,index_enl,ispinor_index,min(ndat_enl,idat)) * gx(ii,ibeg+ilmn+(ia-1)*nlmn,ispinor,idat)
     543              :                end do
     544              :              end do
     545       606994 :              if(jlmn<nlmn) then
     546      4484780 :                do ilmn=jlmn+1,nlmn
     547      3963558 :                  i0lmn=(ilmn*(ilmn-1)/2)
     548     11051708 :                  do ii=1,cplex
     549              :                    gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(ii,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat) &
     550              : &                     + enl_ptr2(i0lmn+jlmn,index_enl,ispinor_index,min(ndat_enl,idat)) &
     551     10530486 : &                     * gx(ii,ibeg+ilmn+(ia-1)*nlmn,ispinor,idat)
     552              :                  end do
     553              :                end do
     554              :              end if
     555              :            end do
     556              :          end do
     557              :        end do
     558              :        end do
     559              :      endif
     560              : 
     561              : 
     562              : !    2-Enl is complex  ===== D^ss'_ij=D^s's_ji^*
     563              :    else
     564            0 :      ABI_CHECK(cplex_fac==cplex_enl,"BUG: invalid cplex_fac/=cplex_enl!")
     565              : 
     566            0 :      if (nspinortot==1) then ! -------------> NO SPINORS
     567            0 :        if(paw_opt==2) then
     568              : #ifdef HAVE_OPENMP_OFFLOAD
     569              :          !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
     570              :          !$OMP& MAP(to:gxfac_,gx,gxi,atindx1,gxj,sij,enl_ptr2,lambda) &
     571              :          !$OMP& PRIVATE(idat,ia) &
     572              :          !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     573              : #endif
     574            0 :          do idat=1,ndat
     575            0 :          do ia=1,nincat
     576              :            !$OMP PARALLEL DO PRIVATE(index_enl,jlmn,j0lmn,enl_,gxj,ilmn,i0lmn,gxi)
     577            0 :            do jlmn=1,nlmn
     578            0 :              index_enl=atindx1(iatm+ia)
     579            0 :              j0lmn=jlmn*(jlmn-1)/2
     580            0 :              enl_(1)=enl_ptr2(2*j0lmn+jlmn-1,index_enl,1,min(ndat_enl,idat))-lambda(idat)*sij(j0lmn+jlmn)
     581            0 :              gxj(1    )=gx(1    ,jlmn+(ia-1)*nlmn+ibeg,1,idat)
     582            0 :              gxj(cplex)=gx(cplex,jlmn+(ia-1)*nlmn+ibeg,1,idat)
     583              :              gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat) = &
     584            0 : &               gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxj(1)
     585            0 :              if (cplex==2) then
     586              :                gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat) = &
     587            0 : &                 gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxj(2)
     588              :              end if
     589            0 :              do ilmn=1,jlmn-1
     590            0 :                enl_(1)=enl_ptr2(2*j0lmn+ilmn-1,index_enl,1,min(ndat_enl,idat))
     591            0 :                enl_(2)=enl_ptr2(2*j0lmn+ilmn  ,index_enl,1,min(ndat_enl,idat))
     592            0 :                enl_(1)=enl_(1)-lambda(idat)*sij(j0lmn+ilmn)
     593            0 :                gxi(1    )=gx(1    ,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     594            0 :                gxi(cplex)=gx(cplex,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     595              :                gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat) = &
     596            0 : &                 gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxi(1)
     597              :                gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat) = &
     598            0 : &                 gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)-enl_(2)*gxi(1)
     599              :                gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,1,idat) = &
     600            0 : &                 gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxj(1)
     601              :                gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,1,idat) = &
     602            0 : &                 gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(2)*gxj(1)
     603            0 :                if (cplex==2) then
     604              :                  gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat) = &
     605            0 : &                   gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(2)*gxi(2)
     606              :                  gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat) = &
     607            0 : &                   gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxi(2)
     608              :                  gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,1,idat) = &
     609            0 : &                   gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,1,idat)-enl_(2)*gxj(2)
     610              :                  gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,1,idat) = &
     611            0 : &                   gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxj(2)
     612              :                end if
     613              :              end do
     614            0 :              if(jlmn<nlmn) then
     615            0 :                do ilmn=jlmn+1,nlmn
     616            0 :                  i0lmn=ilmn*(ilmn-1)/2
     617            0 :                  enl_(1)=enl_ptr2(2*i0lmn+jlmn-1,index_enl,1,min(ndat_enl,idat))
     618            0 :                  enl_(2)=enl_ptr2(2*i0lmn+jlmn  ,index_enl,1,min(ndat_enl,idat))
     619            0 :                  enl_(1)=enl_(1)-lambda(idat)*sij(i0lmn+jlmn)
     620            0 :                  gxi(1    )=gx(1   ,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     621            0 :                  gxi(cplex)=gx(cplex,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     622              :                  gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat) = &
     623            0 : &                   gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxi(1)
     624              :                  gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)= &
     625            0 : &                   gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(2)*gxi(1)
     626            0 :                  if (cplex==2) then
     627              :                    gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat) = &
     628            0 : &                     gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)-enl_(2)*gxi(2)
     629              :                    gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat) = &
     630            0 : &                     gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxi(2)
     631              :                  end if
     632              :                end do
     633              :              end if
     634              :            end do
     635              :          end do
     636              :          end do
     637              :        else
     638              : #ifdef HAVE_OPENMP_OFFLOAD
     639              :          !$OMP TARGET TEAMS DISTRIBUTE &
     640              :          !$OMP& MAP(to:gxfac_,gx,gxi,atindx1,gxj,enl_ptr2) &
     641              :          !$OMP& PRIVATE(idat) &
     642              :          !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     643              : #endif
     644            0 :          do idat=1,ndat
     645              :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,index_enl,jlmn,j0lmn,enl_,gxj,ilmn,i0lmn,jjlmn,ijlmn,gxi)
     646            0 :          do ia=1,nincat
     647            0 :            do jlmn=1,nlmn
     648            0 :              index_enl=atindx1(iatm+ia)
     649            0 :              j0lmn=jlmn*(jlmn-1)/2
     650            0 :              jjlmn=j0lmn+jlmn
     651            0 :              enl_(1)=enl_ptr2(2*jjlmn-1,index_enl,1,min(ndat_enl,idat))
     652            0 :              gxj(1    )=gx(1    ,jlmn+(ia-1)*nlmn+ibeg,1,idat)
     653            0 :              gxj(cplex)=gx(cplex,jlmn+(ia-1)*nlmn+ibeg,1,idat)
     654            0 :              gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxj(1)
     655            0 :              if (cplex==2) gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxj(2)
     656            0 :              do ilmn=1,jlmn-1
     657            0 :                ijlmn=j0lmn+ilmn
     658            0 :                enl_(1)=enl_ptr2(2*ijlmn-1,index_enl,1,min(ndat_enl,idat))
     659            0 :                enl_(2)=enl_ptr2(2*ijlmn  ,index_enl,1,min(ndat_enl,idat))
     660            0 :                gxi(1    )=gx(1    ,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     661            0 :                gxi(cplex)=gx(cplex,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     662            0 :                gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxi(1)
     663            0 :                gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)-enl_(2)*gxi(1)
     664            0 :                if (cplex==2) then
     665            0 :                  gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(2)*gxi(2)
     666            0 :                  gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxi(2)
     667              :                end if
     668              :              end do
     669            0 :              if(jlmn<nlmn) then
     670            0 :                do ilmn=jlmn+1,nlmn
     671            0 :                  i0lmn=ilmn*(ilmn-1)/2
     672            0 :                  ijlmn=i0lmn+jlmn
     673            0 :                  enl_(1)=enl_ptr2(2*ijlmn-1,index_enl,1,min(ndat_enl,idat))
     674            0 :                  enl_(2)=enl_ptr2(2*ijlmn  ,index_enl,1,min(ndat_enl,idat))
     675            0 :                  gxi(1    )=gx(1    ,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     676            0 :                  gxi(cplex)=gx(cplex,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     677            0 :                  gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxi(1)
     678            0 :                  gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(2)*gxi(1)
     679            0 :                  if (cplex==2) then
     680            0 :                    gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,1,idat)-enl_(2)*gxi(2)
     681            0 :                    gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxi(2)
     682              :                  end if
     683              :                end do
     684              :              end if
     685              :            end do
     686              :          end do
     687              :          end do
     688              :        end if
     689              : 
     690              :      else ! -------------> SPINORIAL CASE
     691              : 
     692              : !  === Diagonal term(s) (up-up, down-down)
     693              : 
     694              : #ifdef HAVE_OPENMP_OFFLOAD
     695              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
     696              :        !$OMP& MAP(to:gxfac_,gx,enl_ptr,atindx1,sij) PRIVATE(idat,ispinor) &
     697              :        !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     698              : #endif
     699            0 :        do idat=1,ndat
     700            0 :          do ispinor=1,nspinor
     701              :            !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,ispinor_index,index_enl,j0lmn,jjlmn,i0lmn,ijlmn,gxi,gxj,enl_)
     702            0 :            do ia=1,nincat
     703            0 :              do jlmn=1,nlmn
     704            0 :                ispinor_index=ispinor+shift
     705            0 :                index_enl=atindx1(iatm+ia)
     706            0 :                j0lmn=jlmn*(jlmn-1)/2
     707            0 :                jjlmn=j0lmn+jlmn
     708            0 :                enl_(1)=enl_ptr(2*jjlmn-1,index_enl,ispinor_index)
     709            0 :                if (paw_opt==2) enl_(1)=enl_(1)-lambda(idat)*sij(jjlmn)
     710            0 :                gxj(1)    =gx(1    ,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     711            0 :                gxj(cplex)=gx(cplex,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     712            0 :                gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxj(1)
     713            0 :                if (cplex==2) then
     714            0 :                  gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxj(2)
     715              :                end if
     716            0 :                do ilmn=1,jlmn-1
     717            0 :                  ijlmn=j0lmn+ilmn
     718            0 :                  enl_(1)=enl_ptr(2*ijlmn-1,index_enl,ispinor_index)
     719            0 :                  enl_(2)=enl_ptr(2*ijlmn  ,index_enl,ispinor_index)
     720            0 :                  if (paw_opt==2) enl_(1)=enl_(1)-lambda(idat)*sij(ijlmn)
     721            0 :                  gxi(1)    =gx(1    ,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     722            0 :                  gxi(cplex)=gx(cplex,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     723            0 :                  gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxi(1)
     724            0 :                  gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)-enl_(2)*gxi(1)
     725            0 :                  if (cplex==2) then
     726            0 :                    gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(2)*gxi(2)
     727            0 :                    gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxi(2)
     728              :                  end if
     729              :                end do
     730              :              end do
     731              :            end do
     732              :          end do
     733              :        end do
     734              : #ifdef HAVE_OPENMP_OFFLOAD
     735              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
     736              :        !$OMP& MAP(to:gxfac_,gx,enl_ptr,atindx1) PRIVATE(idat,ispinor) &
     737              :        !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     738              : #endif
     739            0 :        do idat=1,ndat
     740            0 :          do ispinor=1,nspinor
     741              :            !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,ilmn,ispinor_index,index_enl,i0lmn,ijlmn,gxi,gxj,enl_)
     742            0 :            do ia=1,nincat
     743            0 :              do jlmn=1,nlmn-1
     744            0 :                do ilmn=jlmn+1,nlmn
     745            0 :                  ispinor_index=ispinor+shift
     746            0 :                  index_enl=atindx1(iatm+ia)
     747            0 :                  i0lmn=ilmn*(ilmn-1)/2
     748            0 :                  ijlmn=i0lmn+jlmn
     749            0 :                  enl_(1)=enl_ptr(2*ijlmn-1,index_enl,ispinor_index)
     750            0 :                  enl_(2)=enl_ptr(2*ijlmn  ,index_enl,ispinor_index)
     751            0 :                  if (paw_opt==2) enl_(1)=enl_(1)-lambda(idat)*sij(ijlmn)
     752            0 :                  gxi(1)    =gx(1    ,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     753            0 :                  gxi(cplex)=gx(cplex,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     754            0 :                  gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxi(1)
     755            0 :                  gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(2)*gxi(1)
     756            0 :                  if (cplex==2) then
     757            0 :                    gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)-enl_(2)*gxi(2)
     758            0 :                    gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxi(2)
     759              :                  end if
     760              :                end do
     761              :              end do
     762              :            end do
     763              :          end do
     764              :        end do
     765              :      end if !nspinortot
     766              :    end if !complex_enl
     767              : 
     768              : !  === Off-diagonal term(s) (up-down, down-up)
     769              : 
     770              : !  --- No parallelization over spinors ---
     771        15296 :    if (nspinortot==2.and.nspinor==nspinortot) then
     772            0 :      ABI_CHECK(cplex_enl==2,"BUG: invalid cplex_enl/=2!")
     773            0 :      ABI_CHECK(cplex_fac==cplex,"BUG: invalid cplex_fac/=cplex)!")
     774              : #ifdef HAVE_OPENMP_OFFLOAD
     775              :      !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
     776              :      !$OMP& MAP(to:gxfac_,gx,enl_ptr,atindx1) PRIVATE(idat,ispinor) &
     777              :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     778              : #endif
     779            0 :      do idat=1,ndat
     780            0 :        do ispinor=1,nspinortot
     781              :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,jspinor,index_enl,j0lmn,jjlmn,i0lmn,ijlmn,gxi,enl_)
     782            0 :          do ia=1,nincat
     783            0 :            do jlmn=1,nlmn
     784            0 :              jspinor=3-ispinor
     785            0 :              index_enl=atindx1(iatm+ia)
     786            0 :              j0lmn=jlmn*(jlmn-1)/2
     787            0 :              jjlmn=j0lmn+jlmn
     788            0 :              enl_(1)=enl_ptr(2*jjlmn-1,index_enl,2+ispinor )
     789            0 :              enl_(2)=enl_ptr(2*jjlmn  ,index_enl,2+ispinor )
     790            0 :              gxi(1)    =gx(1    ,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     791            0 :              gxi(cplex)=gx(cplex,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     792            0 :              gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(1)*gxi(1)
     793            0 :              gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)-enl_(2)*gxi(1)
     794            0 :              if (cplex==2) then
     795            0 :                gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(2)*gxi(2)
     796            0 :                gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(1)*gxi(2)
     797              :              end if
     798            0 :              do ilmn=1,jlmn-1
     799            0 :                j0lmn=jlmn*(jlmn-1)/2
     800            0 :                ijlmn=j0lmn+ilmn
     801            0 :                enl_(1)=enl_ptr(2*ijlmn-1,index_enl,2+ispinor)
     802            0 :                enl_(2)=enl_ptr(2*ijlmn  ,index_enl,2+ispinor)
     803            0 :                gxi(1)    =gx(1    ,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     804            0 :                gxi(cplex)=gx(cplex,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     805            0 :                gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(1)*gxi(1)
     806            0 :                gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)-enl_(2)*gxi(1)
     807            0 :                if (cplex==2) then
     808            0 :                  gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(2)*gxi(2)
     809            0 :                  gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(1)*gxi(2)
     810              :                end if
     811              :              end do
     812              :            end do
     813              :          end do
     814              :        end do
     815              :      end do
     816              : #ifdef HAVE_OPENMP_OFFLOAD
     817              :      !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
     818              :      !$OMP& MAP(to:gxfac_,gx,enl_ptr,atindx1) PRIVATE(idat,ispinor) &
     819              :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     820              : #endif
     821            0 :      do idat=1,ndat
     822            0 :        do ispinor=1,nspinortot
     823              :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,ilmn,jspinor,index_enl,i0lmn,ijlmn,gxi,enl_)
     824            0 :          do ia=1,nincat
     825            0 :            do jlmn=1,nlmn-1
     826            0 :              do ilmn=jlmn+1,nlmn
     827            0 :                jspinor=3-ispinor
     828            0 :                index_enl=atindx1(iatm+ia)
     829            0 :                i0lmn=ilmn*(ilmn-1)/2
     830            0 :                ijlmn=i0lmn+jlmn
     831            0 :                enl_(1)=enl_ptr(2*ijlmn-1,index_enl,2+ispinor)
     832            0 :                enl_(2)=enl_ptr(2*ijlmn  ,index_enl,2+ispinor)
     833            0 :                gxi(1)    =gx(1    ,ilmn+(ia-1)*nlmn+ibeg,jspinor,idat)
     834            0 :                gxi(cplex)=gx(cplex,ilmn+(ia-1)*nlmn+ibeg,jspinor,idat)
     835            0 :                gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxi(1)
     836            0 :                gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(2)*gxi(1)
     837            0 :                if (cplex==2) then
     838            0 :                  gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(1,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)-enl_(2)*gxi(2)
     839            0 :                  gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=gxfac_(2,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxi(2)
     840              :                end if
     841              :              end do
     842              :            end do
     843              :          end do
     844              :        end do
     845              :      end do
     846              : 
     847              : !    --- Parallelization over spinors ---
     848        15296 :    else if (nspinortot==2.and.nspinor/=nspinortot) then
     849            0 :      ABI_BUG("npspinor==2 not supported with OpenMP GPU")
     850              :    end if
     851              : 
     852              :   end if !paw_opt
     853              : 
     854              : 
     855              : !Accumulate dgxdtfac related to nonlocal operator (Norm-conserving)
     856              : !-------------------------------------------------------------------
     857        18496 :  if (optder>=1.and.paw_opt==0) then
     858              :    !Enl is E(Kleinman-Bylander)
     859            0 :    ABI_CHECK(cplex_enl==1,"BUG: invalid cplex_enl/=1!")
     860            0 :    ABI_CHECK(cplex_fac==cplex,"BUG: invalid cplex_fac/=cplex!")
     861              : 
     862            0 :    if (lmax_so == 0) then
     863              : 
     864              : !    NC+SR ---
     865              : #ifdef HAVE_OPENMP_OFFLOAD
     866              :      !$OMP TARGET TEAMS DISTRIBUTE &
     867              :      !$OMP& MAP(to:dgxdtfac_,dgxdt,enl_ptr2,indlmn) &
     868              :      !$OMP& PRIVATE(idat,ispinor,ispinor_index) &
     869              :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     870              : #endif
     871            0 :      do idat=1,ndat
     872            0 :        do ispinor=1,nspinor
     873            0 :          ispinor_index = ispinor + shift
     874              :          !$OMP PARALLEL DO COLLAPSE(3) PRIVATE(ia,ilmn,mu,ii)
     875            0 :          do ia=1,nincat
     876            0 :            do ilmn=1,nlmn
     877            0 :              do mu=1,ndgxdtfac
     878            0 :                do ii=1,cplex
     879            0 :                  if (indlmn(6,ilmn)==2) then
     880            0 :                    dgxdtfac_(ii,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat) = zero
     881              :                  else
     882              :                    dgxdtfac_(ii,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
     883              : &                    enl_ptr2(indlmn(5,ilmn),itypat,ispinor_index,min(ndat_enl,idat)) &
     884            0 : &                   *dgxdt(ii,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
     885              :                  end if
     886              :                end do
     887              :              end do
     888              :            end do
     889              :          end do
     890              :        end do
     891              :      end do
     892              : 
     893              :    else
     894              : 
     895              : !    NC+SR+SO: real-Ylm L.S coupling ---
     896              : #ifdef HAVE_OPENMP_OFFLOAD
     897              :      !$OMP TARGET TEAMS DISTRIBUTE &
     898              :      !$OMP& MAP(to:dgxdtfac_,dgxdt,enl_ptr2,indlmn,ls_ylm_so_) &
     899              :      !$OMP& PRIVATE(idat) &
     900              :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
     901              : #endif
     902            0 :      do idat=1,ndat
     903              :        !$OMP PARALLEL DO COLLAPSE(2) &
     904              :        !$OMP& PRIVATE(ia,ilmn,iln,ekb_so_1,ekb_so_2,ll_so,ilm,jlmn,jlm,klm_so,sign_so,ls_uu_im,ls_ud_re,ls_ud_im,mu)
     905            0 :        do ia=1,nincat
     906            0 :          do ilmn=1,nlmn
     907            0 :            iln = indlmn(5,ilmn)
     908              :  
     909            0 :            if (indlmn(6,ilmn)/=2) then
     910            0 :              ekb_so_1 = enl_ptr2(iln,itypat,1,min(ndat_enl,idat))
     911            0 :              ekb_so_2 = enl_ptr2(iln,itypat,2,min(ndat_enl,idat))
     912            0 :              do mu=1,ndgxdtfac
     913              :                dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)= &
     914            0 : &                    ekb_so_1*dgxdt(1,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     915              :                dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)= &
     916            0 : &                    ekb_so_1*dgxdt(2,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)
     917              :                dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat)= &
     918            0 : &                    ekb_so_2*dgxdt(1,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat)
     919              :                dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat)= &
     920            0 : &                    ekb_so_2*dgxdt(2,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat)
     921              :              end do
     922              : 
     923              :            else
     924              : 
     925            0 :              do mu=1,ndgxdtfac
     926            0 :                dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat) = zero
     927            0 :                dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat) = zero
     928            0 :                dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat) = zero
     929            0 :                dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat) = zero
     930              :              end do
     931              : 
     932            0 :              ekb_so_1 = enl_ptr2(iln,itypat,1,min(ndat_enl,idat))
     933            0 :              if (abs(ekb_so_1)<tol16) cycle
     934            0 :              ll_so = indlmn(1,ilmn)
     935            0 :              ilm   = indlmn(4,ilmn)
     936            0 :              do jlmn=1,nlmn
     937            0 :                if (indlmn(6,jlmn)/=2) cycle
     938            0 :                if (indlmn(1,jlmn)/=ll_so) cycle
     939            0 :                if (indlmn(3,jlmn)/=indlmn(3,ilmn)) cycle
     940            0 :                jlm = indlmn(4,jlmn)
     941            0 :                if (ilm<=jlm) then
     942            0 :                  klm_so  = jlm*(jlm-1)/2 + ilm
     943            0 :                  sign_so = 1
     944              :                else
     945            0 :                  klm_so  = ilm*(ilm-1)/2 + jlm
     946            0 :                  sign_so = -1
     947              :                end if
     948            0 :                ls_uu_im = sign_so * ls_ylm_so_(2,klm_so,1)
     949            0 :                ls_ud_re = sign_so * ls_ylm_so_(1,klm_so,2)
     950            0 :                ls_ud_im = sign_so * ls_ylm_so_(2,klm_so,2)
     951              : 
     952            0 :                do mu=1,ndgxdtfac
     953              :                  ! up-up
     954              :                  dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat) &
     955            0 : &                  - ekb_so_1*ls_uu_im*dgxdt(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)
     956              :                  dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat) &
     957            0 : &                  + ekb_so_1*ls_uu_im*dgxdt(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)
     958              :                  ! up-dn
     959              :                  dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat) &
     960            0 : &                  + ekb_so_1*(ls_ud_re*dgxdt(1,mu,jlmn+(ia-1)*nlmn+ibeg,2,idat) - ls_ud_im*dgxdt(2,mu,jlmn+(ia-1)*nlmn+ibeg,2,idat))
     961              :                  dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat) &
     962            0 : &                  + ekb_so_1*(ls_ud_re*dgxdt(2,mu,jlmn+(ia-1)*nlmn+ibeg,2,idat) + ls_ud_im*dgxdt(1,mu,jlmn+(ia-1)*nlmn+ibeg,2,idat))
     963              :                  ! dn-up
     964              :                  dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat)=dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat) &
     965            0 : &                  + ekb_so_1*(-ls_ud_re*dgxdt(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat) - ls_ud_im*dgxdt(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat))
     966              :                  dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat)=dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat) &
     967            0 : &                  + ekb_so_1*(-ls_ud_re*dgxdt(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat) + ls_ud_im*dgxdt(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat))
     968              :                  ! dn-dn
     969              :                  dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat)=dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat) &
     970            0 : &                  + ekb_so_1*ls_uu_im*dgxdt(2,mu,jlmn+(ia-1)*nlmn+ibeg,2,idat)
     971              :                  dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat)=dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,2,idat) &
     972            0 : &                  - ekb_so_1*ls_uu_im*dgxdt(1,mu,jlmn+(ia-1)*nlmn+ibeg,2,idat)
     973              :                end do ! mu
     974              :              end do ! jlmn
     975              :            end if ! indlmn(:,6)==2
     976              :          end do ! ilmn
     977              :        end do ! ia
     978              :        !$OMP END PARALLEL DO
     979              : 
     980              :      end do ! idat
     981              :    end if ! NC+SO
     982              :  end if ! NC
     983              : 
     984        18496 :  if (lmax_so > 0) then
     985              : #ifdef HAVE_OPENMP_OFFLOAD
     986              :    !$OMP TARGET EXIT DATA MAP(delete:ls_ylm_so_data) IF(gpu_option==ABI_GPU_OPENMP)
     987              : #endif
     988            0 :    ABI_FREE(ls_ylm_so_data)
     989              :  end if
     990              : 
     991              : !Accumulate dgxdtfac related to nonlocal operator (PAW)
     992              : !-------------------------------------------------------------------
     993        18496 :   if (optder>=1.and.(paw_opt==1.or.paw_opt==2.or.paw_opt==4)) then
     994              :    !Enl is psp strength Dij or (Dij-lambda.Sij)
     995              : 
     996              : !  === Diagonal term(s) (up-up, down-down)
     997              : 
     998              : !  1-Enl is real
     999            0 :    if (cplex_enl==1) then
    1000            0 :      if (paw_opt/=2) then
    1001              : #ifdef HAVE_OPENMP_OFFLOAD
    1002              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(3) &
    1003              :        !$OMP& MAP(to:dgxdtfac_,enl_ptr2,atindx1,dgxdt) &
    1004              :        !$OMP& PRIVATE(idat,ispinor,ia) &
    1005              :        !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1006              : #endif
    1007            0 :        do idat=1,ndat
    1008            0 :        do ispinor=1,nspinor
    1009            0 :          do ia=1,nincat
    1010              :            !$OMP PARALLEL DO &
    1011              :            !$OMP& PRIVATE(ispinor_index,index_enl,j0lmn,i0lmn,jlmn,ilmn,mu,ii)
    1012            0 :            do jlmn=1,nlmn
    1013            0 :              ispinor_index=ispinor+shift
    1014            0 :              index_enl=atindx1(iatm+ia)
    1015            0 :              j0lmn=jlmn*(jlmn-1)/2
    1016            0 :              do mu=1,ndgxdtfac
    1017            0 :                do ii=1,cplex
    1018              :                  dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1019              :                  &    dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)&
    1020              :                  &    + enl_ptr2(j0lmn+jlmn,index_enl,ispinor_index,min(ndat_enl,idat)) &
    1021            0 :                  &    * dgxdt(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1022              :                end do
    1023              :              end do
    1024            0 :              do ilmn=1,jlmn-1
    1025            0 :                do mu=1,ndgxdtfac
    1026            0 :                  do ii=1,cplex
    1027              :                    dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1028              :                    &    dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)&
    1029              :                    &    + enl_ptr2(j0lmn+ilmn,index_enl,ispinor_index,min(ndat_enl,idat)) &
    1030            0 :                    &    * dgxdt(ii,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1031              :                  end do
    1032              :                end do
    1033              :              end do
    1034            0 :              if(jlmn<nlmn) then
    1035            0 :                do ilmn=jlmn+1,nlmn
    1036            0 :                  do mu=1,ndgxdtfac
    1037            0 :                    do ii=1,cplex
    1038            0 :                      i0lmn=ilmn*(ilmn-1)/2
    1039              :                      dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1040              :                      &    dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)&
    1041              :                      &    + enl_ptr2(i0lmn+jlmn,index_enl,ispinor_index,min(ndat_enl,idat)) &
    1042            0 :                      &    * dgxdt(ii,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1043              :                    end do
    1044              :                  end do
    1045              :                end do
    1046              :              end if
    1047              :            end do
    1048              :          end do
    1049              :        end do
    1050              :        end do
    1051              :      else
    1052              : #ifdef HAVE_OPENMP_OFFLOAD
    1053              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
    1054              :        !$OMP& MAP(to:dgxdtfac_,enl_ptr2,atindx1,dgxdt,sij,lambda) &
    1055              :        !$OMP& PRIVATE(idat,ispinor) &
    1056              :        !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1057              : #endif
    1058            0 :        do idat=1,ndat
    1059            0 :        do ispinor=1,nspinor
    1060              :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ispinor_index,ia,index_enl,jlmn,j0lmn,ilmn,i0lmn,ii)
    1061            0 :          do ia=1,nincat
    1062            0 :            do jlmn=1,nlmn
    1063            0 :              ispinor_index=ispinor+shift
    1064            0 :              index_enl=atindx1(iatm+ia)
    1065            0 :              j0lmn=jlmn*(jlmn-1)/2
    1066            0 :              do mu=1,ndgxdtfac
    1067            0 :                do ii=1,cplex
    1068              :                  dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1069              :                  &    dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)&
    1070              :                  &    + (enl_ptr2(j0lmn+jlmn,index_enl,ispinor_index,min(ndat_enl,idat))-lambda(idat)*sij(j0lmn+jlmn)) &
    1071            0 :                  &    * dgxdt(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1072              :                end do
    1073              :              end do
    1074            0 :              do ilmn=1,jlmn-1
    1075            0 :                do mu=1,ndgxdtfac
    1076            0 :                  do ii=1,cplex
    1077              :                    dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1078              :                    &    dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)&
    1079              :                    &    + (enl_ptr2(j0lmn+ilmn,index_enl,ispinor_index,min(ndat_enl,idat))-lambda(idat)*sij(j0lmn+ilmn)) &
    1080            0 :                    &    * dgxdt(ii,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1081              :                  end do
    1082              :                end do
    1083              :              end do
    1084            0 :              if(jlmn<nlmn) then
    1085            0 :                do ilmn=jlmn+1,nlmn
    1086            0 :                  i0lmn=ilmn*(ilmn-1)/2
    1087            0 :                  do mu=1,ndgxdtfac
    1088            0 :                    do ii=1,cplex
    1089              :                      dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1090              :                      &    dgxdtfac_(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)&
    1091              :                      &    + (enl_ptr2(i0lmn+jlmn,index_enl,ispinor_index,min(ndat_enl,idat))-lambda(idat)*sij(i0lmn+jlmn)) &
    1092            0 :                      &    * dgxdt(ii,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1093              :                    end do
    1094              :                  end do
    1095              :                end do
    1096              :              end if
    1097              :            end do
    1098              :          end do
    1099              :        end do
    1100              :        end do
    1101              :      end if
    1102              : 
    1103              : !    2-Enl is complex  ===== D^ss'_ij=D^s's_ji^*
    1104              :    else
    1105            0 :      ABI_CHECK(cplex_fac==cplex_enl,"BUG: invalid cplex_fac/=cplex_enl!")
    1106              : 
    1107            0 :      if (nspinortot==1) then ! -------------> NO SPINORS
    1108              : 
    1109              : #ifdef HAVE_OPENMP_OFFLOAD
    1110              :        !$OMP TARGET TEAMS DISTRIBUTE &
    1111              :        !$OMP& MAP(to:dgxdtfac_,enl_,atindx1,dgxdt,sij,lambda,enl_ptr2,gxfi,gxj) &
    1112              :        !$OMP& PRIVATE(idat) &
    1113              :        !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1114              : #endif
    1115            0 :        do idat=1,ndat
    1116              :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,index_enl,jlmn,j0lmn,jjlmn,ilmn,i0lmn,ijlmn,gxfi,gxj,mu,cplex_,enl_)
    1117            0 :          do ia=1,nincat
    1118            0 :            do jlmn=1,nlmn
    1119            0 :              index_enl=atindx1(iatm+ia)
    1120            0 :              j0lmn=jlmn*(jlmn-1)/2
    1121            0 :              jjlmn=j0lmn+jlmn
    1122            0 :              enl_(1)=enl_ptr2(2*jjlmn-1,index_enl,1,min(ndat_enl,idat))
    1123            0 :              if (paw_opt==2) enl_(1)=enl_(1)-lambda(idat)*sij(jjlmn)
    1124            0 :              do mu=1,ndgxdtfac
    1125            0 :                if(cplex_dgxdt(mu)==2)then
    1126            0 :                  cplex_ = 2 ; gxj(1) = zero ; gxj(2) = dgxdt(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)
    1127              :                else
    1128            0 :                  cplex_ = cplex ;
    1129            0 :                  gxj(1    )=dgxdt(1    ,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)
    1130            0 :                  gxj(cplex)=dgxdt(cplex,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)
    1131              :                end if
    1132            0 :                dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxj(1)
    1133            0 :                if (cplex_==2) then
    1134            0 :                  dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxj(2)
    1135              :                end if
    1136              :              end do
    1137            0 :              do ilmn=1,jlmn-1
    1138            0 :                ijlmn=j0lmn+ilmn
    1139            0 :                enl_(1)=enl_ptr2(2*ijlmn-1,index_enl,1,min(ndat_enl,idat))
    1140            0 :                enl_(2)=enl_ptr2(2*ijlmn  ,index_enl,1,min(ndat_enl,idat))
    1141            0 :                if (paw_opt==2) enl_(1)=enl_(1)-lambda(idat)*sij(ijlmn)
    1142            0 :                do mu=1,ndgxdtfac
    1143            0 :                  if(cplex_dgxdt(mu)==2)then
    1144            0 :                    cplex_ = 2 ; gxfi(1) = zero ; gxfi(2) = dgxdt(1,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)
    1145              :                  else
    1146            0 :                    cplex_ = cplex ;
    1147            0 :                    gxfi(1    )=dgxdt(1    ,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)
    1148            0 :                    gxfi(cplex)=dgxdt(cplex,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)
    1149              :                  end if
    1150            0 :                  dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxfi(1)
    1151            0 :                  dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)-enl_(2)*gxfi(1)
    1152            0 :                  if (cplex_==2) then
    1153            0 :                    dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(2)*gxfi(2)
    1154            0 :                    dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxfi(2)
    1155              :                  end if
    1156              :                end do
    1157              :              end do
    1158            0 :              if(jlmn<nlmn) then
    1159            0 :                do ilmn=jlmn+1,nlmn
    1160            0 :                  i0lmn=ilmn*(ilmn-1)/2
    1161            0 :                  ijlmn=i0lmn+jlmn
    1162            0 :                  enl_(1)=enl_ptr2(2*ijlmn-1,index_enl,1,min(ndat_enl,idat))
    1163            0 :                  enl_(2)=enl_ptr2(2*ijlmn  ,index_enl,1,min(ndat_enl,idat))
    1164            0 :                  if (paw_opt==2) enl_(1)=enl_(1)-lambda(idat)*sij(ijlmn)
    1165            0 :                  do mu=1,ndgxdtfac
    1166            0 :                    if(cplex_dgxdt(mu)==2)then
    1167            0 :                      cplex_ = 2 ; gxfi(1) = zero ; gxfi(2) = dgxdt(1,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)
    1168              :                    else
    1169            0 :                      cplex_ = cplex ;
    1170            0 :                      gxfi(1    )=dgxdt(1    ,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)
    1171            0 :                      gxfi(cplex)=dgxdt(cplex,mu,ilmn+(ia-1)*nlmn+ibeg,1,idat)
    1172              :                    end if
    1173            0 :                    dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxfi(1)
    1174            0 :                    dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(2)*gxfi(1)
    1175            0 :                    if (cplex_==2) then
    1176            0 :                      dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)-enl_(2)*gxfi(2)
    1177            0 :                      dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,1,idat)+enl_(1)*gxfi(2)
    1178              :                    end if
    1179              :                  end do
    1180              :                end do
    1181              :              end if
    1182              :            end do
    1183              :          end do
    1184              :        end do
    1185              :      else ! -------------> SPINORIAL CASE
    1186              : 
    1187              : !  === Diagonal term(s) (up-up, down-down)
    1188              : 
    1189              : #ifdef HAVE_OPENMP_OFFLOAD
    1190              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
    1191              :        !$OMP& MAP(to:atindx1,dgxdtfac_,enl_ptr,dgxdt,sij,lambda) PRIVATE(idat,ispinor) &
    1192              :        !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1193              : #endif
    1194            0 :        do idat=1,ndat
    1195            0 :          do ispinor=1,nspinor
    1196              :            !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,ispinor_index,index_enl,j0lmn,jjlmn,ilmn,ijlmn,cplex_,enl_,gxj,gxfi)
    1197            0 :            do ia=1,nincat
    1198            0 :              do jlmn=1,nlmn
    1199            0 :                ispinor_index = ispinor + shift
    1200            0 :                index_enl=atindx1(iatm+ia)
    1201            0 :                j0lmn=jlmn*(jlmn-1)/2
    1202            0 :                jjlmn=j0lmn+jlmn
    1203            0 :                enl_(1)=enl_ptr(2*jjlmn-1,index_enl,ispinor_index)
    1204            0 :                if (paw_opt==2) enl_(1)=enl_(1)-lambda(idat)*sij(jjlmn)
    1205            0 :                do mu=1,ndgxdtfac
    1206            0 :                  if(cplex_dgxdt(mu)==2)then
    1207            0 :                    cplex_ = 2
    1208            0 :                    gxj(1) = zero ; gxj(2) = dgxdt(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1209              :                  else
    1210            0 :                    cplex_ = cplex
    1211            0 :                    gxj(1    )=dgxdt(1    ,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1212            0 :                    gxj(cplex)=dgxdt(cplex,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1213              :                  end if
    1214            0 :                  dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxj(1)
    1215            0 :                  if (cplex_==2) then
    1216            0 :                    dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxj(2)
    1217              :                  end if
    1218              :                end do
    1219            0 :                do ilmn=1,jlmn-1
    1220            0 :                  ijlmn=j0lmn+ilmn
    1221            0 :                  enl_(1)=enl_ptr(2*ijlmn-1,index_enl,ispinor_index)
    1222            0 :                  enl_(2)=enl_ptr(2*ijlmn  ,index_enl,ispinor_index)
    1223            0 :                  if (paw_opt==2) enl_(1)=enl_(1)-lambda(idat)*sij(ijlmn)
    1224            0 :                  do mu=1,ndgxdtfac
    1225            0 :                    if(cplex_dgxdt(mu)==2)then
    1226            0 :                      cplex_ = 2 ; gxfi(1) = zero ; gxfi(2) = dgxdt(1,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1227              :                    else
    1228            0 :                      cplex_ = cplex
    1229            0 :                      gxfi(1)    =dgxdt(1    ,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1230            0 :                      gxfi(cplex)=dgxdt(cplex,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1231              :                    end if
    1232            0 :                    dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxfi(1)
    1233            0 :                    dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)-enl_(2)*gxfi(1)
    1234            0 :                    if (cplex_==2) then
    1235            0 :                      dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(2)*gxfi(2)
    1236            0 :                      dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxfi(2)
    1237              :                    end if
    1238              :                  end do
    1239              :                end do
    1240              :              end do
    1241              :            end do
    1242              :          end do
    1243              :        end do
    1244              : #ifdef HAVE_OPENMP_OFFLOAD
    1245              :        !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
    1246              :        !$OMP& MAP(to:atindx1,dgxdtfac_,enl_ptr,dgxdt,sij,lambda) PRIVATE(idat,ispinor) &
    1247              :        !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1248              : #endif
    1249            0 :        do idat=1,ndat
    1250            0 :          do ispinor=1,nspinor
    1251              :            !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,ispinor_index,index_enl,i0lmn,ilmn,ijlmn,cplex_,enl_,gxfi)
    1252            0 :            do ia=1,nincat
    1253            0 :              do jlmn=1,nlmn-1
    1254            0 :                do ilmn=jlmn+1,nlmn
    1255            0 :                  ispinor_index = ispinor + shift
    1256            0 :                  index_enl=atindx1(iatm+ia)
    1257            0 :                  i0lmn=ilmn*(ilmn-1)/2
    1258            0 :                  ijlmn=i0lmn+jlmn
    1259            0 :                  enl_(1)=enl_ptr(2*ijlmn-1,index_enl,ispinor_index)
    1260            0 :                  enl_(2)=enl_ptr(2*ijlmn  ,index_enl,ispinor_index)
    1261            0 :                  if (paw_opt==2) enl_(1)=enl_(1)-lambda(idat)*sij(ijlmn)
    1262            0 :                  do mu=1,ndgxdtfac
    1263            0 :                    if(cplex_dgxdt(mu)==2)then
    1264            0 :                      cplex_ = 2 ; gxfi(1) = zero ; gxfi(2) = dgxdt(1,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1265              :                    else
    1266            0 :                      cplex_ = cplex ;
    1267            0 :                      gxfi(1    )=dgxdt(1    ,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1268            0 :                      gxfi(cplex)=dgxdt(cplex,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1269              :                    end if
    1270            0 :                    dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxfi(1)
    1271            0 :                    dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(2)*gxfi(1)
    1272            0 :                    if (cplex_==2) then
    1273            0 :                      dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)-enl_(2)*gxfi(2)
    1274            0 :                      dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxfi(2)
    1275              :                    end if
    1276              :                  end do
    1277              :                end do
    1278              :              end do
    1279              :            end do
    1280              :          end do
    1281              :        end do
    1282              :      end if !nspinortot
    1283              :    end if !complex
    1284              : 
    1285              : !  === Off-diagonal term(s) (up-down, down-up)
    1286              : 
    1287              : !  --- No parallelization over spinors ---
    1288            0 :    if (nspinortot==2.and.nspinor==nspinortot) then
    1289            0 :      ABI_CHECK(cplex_enl==2,"BUG: invalid cplex_enl/=2!")
    1290            0 :      ABI_CHECK(cplex_fac==2,"BUG: invalid cplex_fac/=2!")
    1291              : #ifdef HAVE_OPENMP_OFFLOAD
    1292              :      !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
    1293              :      !$OMP& MAP(to:atindx1,dgxdtfac_,enl_ptr,dgxdt) PRIVATE(idat,ispinor) &
    1294              :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1295              : #endif
    1296            0 :      do idat=1,ndat
    1297            0 :        do ispinor=1,nspinor
    1298              :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,jspinor,index_enl,j0lmn,jjlmn,ilmn,ijlmn,cplex_,enl_,gxj,gxfi)
    1299            0 :          do ia=1,nincat
    1300            0 :            do jlmn=1,nlmn
    1301            0 :              jspinor=3-ispinor
    1302            0 :              index_enl=atindx1(iatm+ia)
    1303            0 :              j0lmn=jlmn*(jlmn-1)/2
    1304            0 :              jjlmn=j0lmn+jlmn
    1305            0 :              enl_(1)=enl_ptr(2*jjlmn-1,index_enl,2+ispinor)
    1306            0 :              enl_(2)=enl_ptr(2*jjlmn  ,index_enl,2+ispinor)
    1307            0 :              do mu=1,ndgxdtfac
    1308            0 :                if(cplex_dgxdt(mu)==2)then
    1309            0 :                  cplex_ = 2 ;
    1310            0 :                  gxfi(1)    = zero ; gxfi(2)    = dgxdt(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1311              :                else
    1312            0 :                  cplex_ = cplex ;
    1313            0 :                  gxfi(1)    =dgxdt(1    ,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1314            0 :                  gxfi(cplex)=dgxdt(cplex,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1315              :                end if
    1316            0 :                dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(1)*gxfi(1)
    1317            0 :                dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)-enl_(2)*gxfi(1)
    1318            0 :                if (cplex_==2) then
    1319            0 :                  dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(2)*gxfi(2)
    1320            0 :                  dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(1)*gxfi(2)
    1321              :                end if
    1322              :              end do
    1323            0 :              do ilmn=1,jlmn-1
    1324            0 :                ijlmn=j0lmn+ilmn
    1325            0 :                enl_(1)=enl_ptr(2*ijlmn-1,index_enl,2+ispinor)
    1326            0 :                enl_(2)=enl_ptr(2*ijlmn  ,index_enl,2+ispinor)
    1327            0 :                do mu=1,ndgxdtfac
    1328            0 :                  if(cplex_dgxdt(mu)==2)then
    1329            0 :                    cplex_ = 2 ; gxfi(1) = zero ; gxfi(2) = dgxdt(1,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1330              :                  else
    1331            0 :                    cplex_ = cplex
    1332            0 :                    gxfi(1)    =dgxdt(1    ,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1333            0 :                    gxfi(cplex)=dgxdt(cplex,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1334              :                  end if
    1335            0 :                  dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(1)*gxfi(1)
    1336            0 :                  dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)-enl_(2)*gxfi(1)
    1337            0 :                  if (cplex_==2) then
    1338            0 :                    dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(2)*gxfi(2)
    1339            0 :                    dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,jspinor,idat)+enl_(1)*gxfi(2)
    1340              :                  end if
    1341              :                end do !mu
    1342              :              end do !ilmn
    1343              :            end do !jmln
    1344              :          end do !ia
    1345              :        end do !ispinor
    1346              :      end do !idat
    1347              : #ifdef HAVE_OPENMP_OFFLOAD
    1348              :      !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
    1349              :      !$OMP& MAP(to:atindx1,dgxdtfac_,enl_ptr,dgxdt) PRIVATE(idat,ispinor) &
    1350              :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1351              : #endif
    1352            0 :      do idat=1,ndat
    1353            0 :        do ispinor=1,nspinor
    1354              :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,jspinor,index_enl,i0lmn,ilmn,ijlmn,cplex_,enl_,gxfi)
    1355            0 :          do ia=1,nincat
    1356            0 :            do jlmn=1,nlmn
    1357            0 :              do ilmn=jlmn+1,nlmn
    1358            0 :                jspinor=3-ispinor
    1359            0 :                index_enl=atindx1(iatm+ia)
    1360            0 :                i0lmn=ilmn*(ilmn-1)/2
    1361            0 :                ijlmn=i0lmn+jlmn
    1362            0 :                enl_(1)=enl_ptr(2*ijlmn-1,index_enl,2+ispinor)
    1363            0 :                enl_(2)=enl_ptr(2*ijlmn  ,index_enl,2+ispinor)
    1364            0 :                do mu=1,ndgxdtfac
    1365            0 :                  if(cplex_dgxdt(mu)==2)then
    1366            0 :                    cplex_ = 2 ; gxfi(1) = zero ; gxfi(2) = dgxdt(1,mu,ilmn+(ia-1)*nlmn+ibeg,jspinor,idat)
    1367              :                  else
    1368            0 :                    cplex_ = cplex
    1369            0 :                    gxfi(1)    =dgxdt(1    ,mu,ilmn+(ia-1)*nlmn+ibeg,jspinor,idat)
    1370            0 :                    gxfi(cplex)=dgxdt(cplex,mu,ilmn+(ia-1)*nlmn+ibeg,jspinor,idat)
    1371              :                  end if
    1372            0 :                  dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxfi(1)
    1373            0 :                  dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(2)*gxfi(1)
    1374            0 :                  if (cplex_==2) then
    1375            0 :                    dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(1,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)-enl_(2)*gxfi(2)
    1376            0 :                    dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=dgxdtfac_(2,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)+enl_(1)*gxfi(2)
    1377              :                  end if
    1378              :                end do !mu
    1379              :              end do !ilmn
    1380              :            end do !jmln
    1381              :          end do !ia
    1382              :        end do !ispinor
    1383              :      end do !idat
    1384              : 
    1385              : !    --- Parallelization over spinors ---
    1386            0 :    else if (nspinortot==2.and.nspinor/=nspinortot) then
    1387            0 :      ABI_BUG("nspinor==2 not supported with OpenMP GPU")
    1388              :    end if !nspinortot
    1389              : 
    1390              :   end if ! pawopt & optder
    1391              : 
    1392              : !End of loop when a exp(-iqR) phase is present
    1393              : !------------------------------------------- ------------------------
    1394              : 
    1395              : !When iphase=1, gxfac and gxfac_ point to the same memory space
    1396              : !When iphase=2, we add i.gxfac_ to gxfac
    1397        36992 :   if (iphase==2) then
    1398              : #ifdef HAVE_OPENMP_OFFLOAD
    1399              :     !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(3) &
    1400              :     !$OMP& PRIVATE(idat,ia) MAP(to:gxfac,gxfac_) &
    1401              :     !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1402              : #endif
    1403            0 :     do idat=1,ndat
    1404            0 :       do ispinor=1,nspinor
    1405            0 :         do ia=1,nincat
    1406              :           !$OMP PARALLEL DO PRIVATE(ilmn)
    1407            0 :           do ilmn=1,nlmn
    1408              :             gxfac(1,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1409            0 :             &    gxfac(1,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)-gxfac_(2,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1410              :             gxfac(2,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1411            0 :             &    gxfac(2,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)+gxfac_(1,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1412              :           end do
    1413              :         end do
    1414              :       end do
    1415              :     end do
    1416            0 :     if (optder>=1) then
    1417              : #ifdef HAVE_OPENMP_OFFLOAD
    1418              :       !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(3) &
    1419              :       !$OMP& PRIVATE(idat,ia,ilmn,mu) MAP(to:dgxdtfac,dgxdtfac_) &
    1420              :       !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1421              : #endif
    1422            0 :       do idat=1,ndat
    1423            0 :         do ispinor=1,nspinor
    1424            0 :           do ia=1,nincat
    1425              :             !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ilmn,mu)
    1426            0 :             do ilmn=1,nlmn
    1427            0 :               do mu=1,ndgxdtfac
    1428              :                 dgxdtfac(1,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1429            0 :                 &    dgxdtfac(1,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)-dgxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1430              :                 dgxdtfac(2,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1431            0 :                 &    dgxdtfac(2,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)+dgxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1432              :               end do
    1433              :             end do
    1434              :           end do
    1435              :         end do
    1436              :       end do
    1437              :     end if
    1438            0 :     if (optder>=2) then
    1439              : #ifdef HAVE_OPENMP_OFFLOAD
    1440              :       !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(3) &
    1441              :       !$OMP& PRIVATE(idat,ia) MAP(to:d2gxdtfac,d2gxdtfac_) &
    1442              :       !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1443              : #endif
    1444            0 :       do idat=1,ndat
    1445            0 :         do ispinor=1,nspinor
    1446            0 :           do ia=1,nincat
    1447              :             !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ilmn,mu)
    1448            0 :             do ilmn=1,nlmn
    1449            0 :               do mu=1,nd2gxdtfac
    1450              :                 d2gxdtfac(1,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1451            0 :                 &    d2gxdtfac(1,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)-d2gxdtfac_(2,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1452              :                 d2gxdtfac(2,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1453            0 :                 &    d2gxdtfac(2,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)+d2gxdtfac_(1,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1454              :               end do
    1455              :             end do
    1456              :           end do
    1457              :         end do
    1458              :       end do
    1459              :     end if
    1460            0 :     call destroy_work_arrays(gpu_option)
    1461              :   end if
    1462              : 
    1463              : !End loop over real/imaginary part of the exp(-iqR) phase
    1464              :  end do
    1465              : 
    1466              : 
    1467              : !Accumulate gxfac related to overlap (Sij) (PAW)
    1468              : !------------------------------------------- ------------------------
    1469        18496 :  if (paw_opt==3.or.paw_opt==4) then ! Use Sij, overlap contribution
    1470              : #ifdef HAVE_OPENMP_OFFLOAD
    1471              :    !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
    1472              :    !$OMP& MAP(to:sij,gx,gxfac_sij) &
    1473              :    !$OMP& PRIVATE(idat,ispinor) &
    1474              :    !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1475              : #endif
    1476        43782 :    do idat=1,ndat
    1477        73844 :    do ispinor=1,nspinor
    1478              :      !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,j0lmn,jjlmn,ilmn,i0lmn,ijlmn,ii)
    1479        98850 :      do ia=1,nincat
    1480       592576 :        do jlmn=1,nlmn
    1481       523788 :          j0lmn=jlmn*(jlmn-1)/2
    1482       523788 :          jjlmn=j0lmn+jlmn
    1483      1400508 :          do ii=1,cplex
    1484              :            gxfac_sij(ii,ibeg+jlmn+(ia-1)*nlmn,ispinor,idat)= &
    1485              :              gxfac_sij(ii,ibeg+jlmn+(ia-1)*nlmn,ispinor,idat) &
    1486      1400508 :              + sij(jjlmn) * gx(ii,ibeg+jlmn+(ia-1)*nlmn,ispinor,idat)
    1487              :          end do
    1488      4282866 :          do ilmn=1,jlmn-1
    1489      3759078 :            ijlmn=j0lmn+ilmn
    1490     10481226 :            do ii=1,cplex
    1491              :              gxfac_sij(ii,ibeg+jlmn+(ia-1)*nlmn,ispinor,idat)= &
    1492              :                gxfac_sij(ii,ibeg+jlmn+(ia-1)*nlmn,ispinor,idat) &
    1493      9957438 :                + sij(ijlmn) * gx(ii,ibeg+ilmn+(ia-1)*nlmn,ispinor,idat)
    1494              :            end do
    1495              :          end do
    1496       562514 :          if(jlmn<nlmn) then
    1497      4244140 :            do ilmn=jlmn+1,nlmn
    1498      3759078 :              i0lmn=ilmn*(ilmn-1)/2
    1499      3759078 :              ijlmn=i0lmn+jlmn
    1500     10442500 :              do ii=1,cplex
    1501              :                gxfac_sij(ii,ibeg+jlmn+(ia-1)*nlmn,ispinor,idat)=&
    1502              :                  gxfac_sij(ii,ibeg+jlmn+(ia-1)*nlmn,ispinor,idat) &
    1503      9957438 :                  + sij(ijlmn) * gx(ii,ibeg+ilmn+(ia-1)*nlmn,ispinor,idat)
    1504              :              end do
    1505              :            end do
    1506              :          end if
    1507              :        end do
    1508              :      end do
    1509              :    end do
    1510              :    end do
    1511              :  end if
    1512              : 
    1513              : !Accumulate dgxdtfac related to overlap (Sij) (PAW)
    1514              : !-------------------------------------------------------------------
    1515        18496 :  if (optder>=1.and.(paw_opt==3.or.paw_opt==4)) then ! Use Sij, overlap contribution
    1516              : #ifdef HAVE_OPENMP_OFFLOAD
    1517              :    !$OMP TARGET TEAMS DISTRIBUTE COLLAPSE(2) &
    1518              :    !$OMP& MAP(to:sij,dgxdt,dgxdtfac_sij) &
    1519              :    !$OMP& PRIVATE(idat,ispinor) &
    1520              :    !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1521              : #endif
    1522            0 :    do idat=1,ndat
    1523            0 :    do ispinor=1,nspinor
    1524              :      !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(ia,jlmn,j0lmn,jjlmn,ilmn,i0lmn,ijlmn,ii)
    1525            0 :      do ia=1,nincat
    1526            0 :        do jlmn=1,nlmn
    1527            0 :          j0lmn=jlmn*(jlmn-1)/2
    1528            0 :          jjlmn=j0lmn+jlmn
    1529            0 :          do mu=1,ndgxdtfac
    1530            0 :            do ii=1,cplex
    1531              :              dgxdtfac_sij(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1532              :              &    dgxdtfac_sij(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)&
    1533            0 :              &    + sij(jjlmn) * dgxdt(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1534              :            end do
    1535              :          end do
    1536            0 :          do ilmn=1,jlmn-1
    1537            0 :            ijlmn=j0lmn+ilmn
    1538            0 :            do mu=1,ndgxdtfac
    1539            0 :              do ii=1,cplex
    1540              :                dgxdtfac_sij(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1541              :                &    dgxdtfac_sij(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)&
    1542            0 :                &    + sij(ijlmn) * dgxdt(ii,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1543              :              end do
    1544              :            end do
    1545              :          end do
    1546            0 :          if(jlmn<nlmn) then
    1547            0 :            do ilmn=jlmn+1,nlmn
    1548            0 :              i0lmn=ilmn*(ilmn-1)/2
    1549            0 :              ijlmn=i0lmn+jlmn
    1550            0 :              do mu=1,ndgxdtfac
    1551            0 :                do ii=1,cplex
    1552              :                  dgxdtfac_sij(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)=&
    1553              :                  &    dgxdtfac_sij(ii,mu,jlmn+(ia-1)*nlmn+ibeg,ispinor,idat)&
    1554            0 :                  &    + sij(ijlmn) * dgxdt(ii,mu,ilmn+(ia-1)*nlmn+ibeg,ispinor,idat)
    1555              :                end do
    1556              :              end do
    1557              :            end do
    1558              :          end if
    1559              :        end do
    1560              :      end do
    1561              :    end do
    1562              :    end do
    1563              :  end if
    1564              : 
    1565        18496 : end subroutine opernlc_ylm_allwf
    1566              : !!***
    1567              : 
    1568              : end module m_opernlc_ylm_allwf
    1569              : !!***
        

Generated by: LCOV version 2.3-1