TABLE OF CONTENTS


ABINIT/opernl2 [ Functions ]

[ Top ] [ Functions ]

NAME

 opernl2

FUNCTION

 Operate with the non-local part of the hamiltonian,
 either from reciprocal space to projected quantities (sign=1),
 or from projected quantities to reciprocal space (sign=-1)

COPYRIGHT

 Copyright (C) 1998-2018 ABINIT group (DCA, XG, GMR, DRH)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .
 For the initials of contributors, see ~abinit/doc/developers/contributors.txt.

INPUTS

  if(sign==-1 .and. (choice==2 .or choice==4 .or. choice==5))
   dgxdt(2,ndgxdt,mlang3,mincat,mproj)= selected gradients of gxa wrt coords
    or with respect to ddk
  if(sign==-1 .and. choice==3)
   dgxds((2,mlang4,mincat,mproj) = gradients of projected scalars wrt strains
  ffnl(npw,nffnl,lmnmax,ntypat)=nonlocal form factors on basis sphere.
  gmet(3,3)=metric tensor for G vecs (in bohr**-2)
  ia3=gives the number of the first atom in the subset presently treated
  idir=direction of the perturbation (needed if choice==2 or 5, and ndgxdt=1)
  indlmn(6,i,ntypat)= array giving l,m,n,lm,ln,s for i=ln
  ispinor=1 or 2, gives the spinorial component of ffnl to be used
  istwf_k=option parameter that describes the storage of wfs
  itypat = type of atom, needed for ffnl
  jproj(nlang)=number of projectors for each angular momentum
  kg_k(3,npw)=integer coords of planewaves in basis sphere
  kpg_k(npw,npkg)= (k+G) components and related data
  kpt(3)=real components of k point in terms of recip. translations
  lmnmax=max. number of (l,n) components over all type of psps
  matblk=dimension of the array ph3d
  mincat= maximum increment of atoms
  mlang1 = dimensions for dgxdis1
  mlang3 = one of the dimensions of the array gxa
  mlang4 = dimension for dgxds
  mlang5 = dimensions for dgxdis2
  mlang6 = dimension for d2gxds2
  mproj=maximum dimension for number of projection operators for each
    angular momentum for nonlocal pseudopotential
  ndgxdt=second dimension of dgxdt
  nffnl=second dimension of ffnl
  nincat = number of atoms in the subset here treated
  nkpg=second size of array kpg_k
  nlang = number of angular momenta to be treated = 1 + highest ang. mom.
  nloalg(3)=governs the choice of the algorithm for non-local operator.
  npw  = number of plane waves in reciprocal space
  ntypat = number of type of atoms, dimension needed for ffnl
  sign : if  1, go from reciprocal space to projected scalars,
         if -1, go from projected scalars to reciprocal space.
  if(sign==1), vect(2*npw)=starting vector in reciprocal space
  if(sign==-1) gxa(2,mlang3,nincat,mproj)=modified projected scalars;
   NOTE that metric contractions have already been performed on the
   arrays gxa if sign=-1
  ph3d(2,npw,matblk)=three-dimensional phase factors

OUTPUT

  if(sign==1)
   gxa(2,mlang3,mincat,mproj)= projected scalars
  if(sign==1 .and. (choice==2 .or choice==4 .or. choice==5 .or. choice==23))
   dgxdt(2,ndgxdt,mlang3,mincat,mproj)= selected gradients of gxa wrt coords
    or with respect to ddk
  if(sign==1 .and. (choice==3 .or. choice==23))
   dgxds((2,mlang4,mincat,mproj) = gradients of projected scalars wrt strains
  if(sign==1 .and. choice==6)
   dgxdis((2,mlang1,mincat,mproj) = derivatives of projected scalars
    wrt coord. indexed for internal strain
   d2gxdis((2,mlang5,mincat,mproj) = 2nd derivatives of projected scalars
    wrt strain and coord
   d2gxds2((2,mlang6,mincat,mproj) = 2nd derivatives of projected scalars
    wrt strains
  if(sign==-1)
   vect(2*npw)=final vector in reciprocal space <G|V_nonlocal|vect_start>.

NOTES

 Operate with the non-local part of the hamiltonian for one type of
 atom, and within this given type of atom, for a subset
 of at most nincat atoms.

 This routine basically replaces getgla (gxa here is the former gla),
 except for the calculation of <G|dVnl/dk|C> or strain gradients.

PARENTS

      nonlop_pl

CHILDREN

      mkffkg

SOURCE

 96 #if defined HAVE_CONFIG_H
 97 #include "config.h"
 98 #endif
 99 
100 #include "abi_common.h"
101 
102 subroutine opernl2(choice,dgxdis,dgxds,d2gxdis,d2gxds2,dgxdt,&
103 &  ffnl,gmet,gxa,ia3,idir,indlmn,ispinor,istwf_k,itypat,&
104 &  jproj,kg_k,kpg_k,kpt,lmnmax,matblk,mincat,mlang1,mlang3,mlang4,&
105 &  mlang5,mlang6,mproj,ndgxdt,nffnl,nincat,nkpg,nlang,nloalg,npw,&
106 &  ntypat,ph3d,sign,vect)
107 
108  use defs_basis
109  use m_errors
110  use m_profiling_abi
111 
112 !This section has been created automatically by the script Abilint (TD).
113 !Do not modify the following lines by hand.
114 #undef ABI_FUNC
115 #define ABI_FUNC 'opernl2'
116  use interfaces_66_nonlocal, except_this_one => opernl2
117 !End of the abilint section
118 
119  implicit none
120 
121 !Arguments ------------------------------------
122 !scalars
123  integer,intent(in) :: choice,ia3,idir,ispinor,istwf_k,itypat,lmnmax,matblk
124  integer,intent(in) :: mincat,mlang1,mlang3,mlang4,mlang5,mlang6,mproj,ndgxdt
125  integer,intent(in) :: nffnl,nincat,nkpg,nlang,npw,ntypat,sign
126 !arrays
127  integer,intent(in) :: indlmn(6,lmnmax,ntypat),jproj(nlang),kg_k(3,npw)
128  integer,intent(in) :: nloalg(3)
129  real(dp),intent(in) :: ffnl(npw,nffnl,lmnmax,ntypat),gmet(3,3),kpg_k(npw,nkpg)
130  real(dp),intent(in) :: kpt(3),ph3d(2,npw,matblk)
131  real(dp),intent(inout) :: dgxds(2,mlang4,mincat,mproj)
132  real(dp),intent(inout) :: dgxdt(2,ndgxdt,mlang3,mincat,mproj)
133  real(dp),intent(inout) :: gxa(2,mlang3,mincat,mproj),vect(:,:)
134  real(dp),intent(out) :: d2gxdis(2,mlang5,mincat,mproj)
135  real(dp),intent(out) :: d2gxds2(2,mlang6,mincat,mproj)
136  real(dp),intent(out) :: dgxdis(2,mlang1,mincat,mproj)
137 
138 !Local variables-------------------------------
139 !scalars
140  integer :: ia,iaph3d,iffkg,iffkgk,iffkgs,iffkgs2,ig,ii,ilang,ilang2,ilang3
141  integer :: ilang4,ilang5,ilang6,ilangx,iproj,ipw,ipw1,ipw2,jffkg,jj,jjs,mblkpw
142  integer :: mmproj,mu,nffkg,nffkgd,nffkge,nffkgk,nffkgs,nffkgs2,nincpw,nproj,ntens
143  real(dp),parameter :: two_pi2=two_pi**2
144  character(len=500) :: message
145 !arrays
146  integer,allocatable :: parity(:)
147 !real(dp) :: tsec(2)
148  real(dp),allocatable :: ffkg(:,:),kpgx(:,:),scalars(:,:),teffv(:,:)
149 
150 ! *************************************************************************
151 
152 !call wrtout(std_out,"in opernl2","COLL")
153 
154 !mblkpw sets the size of blocks of planewaves
155  mblkpw=NLO_MBLKPW
156 
157 !Get the actual maximum number of projectors
158  mmproj=maxval(indlmn(3,:,itypat))
159 
160 !Initialisation before blocking on the plane waves
161 
162  if (sign==1) then
163 !  Put projected scalars to zero
164    gxa(:,:,:,1:mmproj)=0.0d0
165    if (choice==2 .or. choice==4 .or. choice==5 .or. choice==23) dgxdt(:,:,:,:,1:mmproj)=0.0d0
166    if (choice==3 .or. choice==6 .or. choice==23) dgxds(:,:,:,1:mmproj)=0.0d0
167    if (choice==6) then
168      dgxdis(:,:,:,1:mmproj)=0.0d0
169      d2gxdis(:,:,:,1:mmproj)=0.0d0
170      d2gxds2(:,:,:,1:mmproj)=0.0d0
171    end if
172  end if
173 
174 !Set up dimension of kpgx and allocate
175 !ntens sets the maximum number of independent tensor components
176 !over all allowed angular momenta; need 20 for spdf for tensors
177 !up to rank 3; to handle stress tensor, need up to rank 5
178  ntens=1
179  if(nlang>=2 .or. choice==2 .or. choice==4 .or. choice==5 .or. choice==23) ntens=4
180  if(nlang>=3 .or. (choice==3.or.choice==23))ntens=10
181  if(nlang>=4 .or. ((choice==3.or.choice==23) .and. nlang>=2) )ntens=20
182  if(((choice==3.or.choice==23) .and. nlang>=3) .or. choice==6)ntens=35
183  if(((choice==3.or.choice==23) .and. nlang==4) .or. (choice==6 .and. nlang>=2))ntens=56
184  if(choice==6 .and. nlang>=3)ntens=84
185  if(choice==6 .and. nlang==4)ntens=120
186 
187 !Set up second dimension of ffkg array, and allocate
188  nffkg=0 ; nffkge=0 ; nffkgd=0 ; nffkgk=0 ; nffkgs=0 ; nffkgs2=0
189  do ilang=1,nlang
190 !  Get the number of projectors for that angular momentum
191    nproj=jproj(ilang)
192 !  If there is a non-local part, accumulate the number of vectors needed
193 !  The variables ilang below are the number of independent tensors of
194 !  various ranks, the variable names being more historical than logical.
195 !  ilang2=number of rank ilang-1
196 !  ilang3=number of rank ilang+1
197 !  ilang4=number of rank ilang
198 !  ilang5=number of rank ilang+2
199 !  ilang6=number of rank ilang+3
200    if(nproj>0)then
201      ilang2=(ilang*(ilang+1))/2
202      nffkge=nffkge+nproj*ilang2
203      if(choice==5)nffkgk=nffkgk+nproj*(2*ilang2-ilang)
204      if(choice==2 .or. choice==4 .or. choice==23)nffkgd=nffkgd+ndgxdt*nproj*ilang2
205      if(choice==3 .or. choice==6 .or. choice==23)then
206        ilang3=((ilang+2)*(ilang+3))/2
207        nffkgs=nffkgs+nproj*ilang3
208      end if
209      if(choice==6)then
210        ilang4=((ilang+1)*(ilang+2))/2
211        ilang5=((ilang+3)*(ilang+4))/2
212        ilang6=((ilang+4)*(ilang+5))/2
213        nffkgs2=nffkgs2+nproj*(ilang4+ilang5+ilang6)
214      end if
215    end if
216  end do
217  nffkg=nffkge+nffkgd+nffkgs+nffkgs2+nffkgk
218 
219 !Loop on subsets of plane waves (blocking)
220 !Disabled by MG on Dec  6 2011, omp sections have to be tested, this coding causes a sigfault with nthreads==1
221 !Feb 16 2012: The code does not crash anymore but it's not efficient.
222 !
223 !!$OMP PARALLEL DEFAULT(PRIVATE) &
224 !!$OMP SHARED(choice,dgxdis,dgxds,d2gxdis,d2gxds2,dgxdt) &
225 !!$OMP SHARED(ffnl,gmet,gxa,ia3,idir,indlmn,ispinor,istwf_k,itypat) &
226 !!$OMP SHARED(jproj,kg_k,kpg_k,kpt,lmnmax,matblk,mincat,mlang1,mlang3,mlang4) &
227 !!$OMP SHARED(mlang5,mlang6,mproj,ndgxdt,nffnl,nincat,nkpg,nlang,nloalg,npw) &
228 !!$OMP SHARED(ntypat,ph3d,sign,vect) &
229 !!$OMP SHARED(mblkpw,nffkg,nffkgd,nffkge,nffkgs,ntens,mmproj)
230 
231  ABI_ALLOCATE(ffkg,(mblkpw,nffkg))
232  ABI_ALLOCATE(parity,(nffkg))
233  ABI_ALLOCATE(kpgx,(mblkpw,ntens))
234  ABI_ALLOCATE(scalars,(2,nffkg))
235  ABI_ALLOCATE(teffv,(2,mblkpw))
236 !!$OMP DO
237  do ipw1=1,npw,mblkpw
238 
239    ipw2=min(npw,ipw1+mblkpw-1)
240    nincpw=ipw2-ipw1+1
241 
242 !  call timab(74+choice,1,tsec)
243 
244 !  Initialize kpgx array related to tensors defined below
245    call mkffkg(choice,ffkg,ffnl,gmet,idir,indlmn,ipw1,ispinor,itypat,kg_k,&
246 &   kpg_k,kpgx,kpt,lmnmax,mblkpw,ndgxdt,nffkg,nffnl,nincpw,nkpg,nlang,&
247 &   npw,ntens,ntypat,parity)
248 
249 !  call timab(74+choice,2,tsec)
250 
251 !  Now treat the different signs
252    if (sign==1) then
253 
254      do ia=1,nincat
255 
256 !      Compute the shift eventually needed to get the phases in ph3d
257        iaph3d=ia
258        if(nloalg(2)>0)iaph3d=ia+ia3-1
259 
260 !      ******* Entering the first time-consuming part of the routine *******
261 
262 !      Multiply by the phase factor
263 !      This allows to be left with only real operations,
264 !      that are performed in the most inner loops
265        ig=ipw1
266        do ipw=1,nincpw
267          teffv(1,ipw)=vect(1,ig)*ph3d(1,ig,iaph3d)-vect(2,ig)*ph3d(2,ig,iaph3d)
268          teffv(2,ipw)=vect(2,ig)*ph3d(1,ig,iaph3d)+vect(1,ig)*ph3d(2,ig,iaph3d)
269          ig=ig+1
270        end do
271 
272        do iffkg=1,nffkg
273          scalars(1,iffkg)=0.0d0
274          scalars(2,iffkg)=0.0d0
275          do ipw=1,nincpw
276            scalars(1,iffkg)=scalars(1,iffkg)+teffv(1,ipw)*ffkg(ipw,iffkg)
277            scalars(2,iffkg)=scalars(2,iffkg)+teffv(2,ipw)*ffkg(ipw,iffkg)
278          end do
279        end do
280 
281 !      ******* Leaving the critical part *********************************
282 
283 !      DEBUG
284 !      write(std_out,*)' opernl2 : scalars'
285 !      do iffkg=1,10
286 !      write(std_out,*)'iffkg,scalars',iffkg,scalars(1:2,iffkg)
287 !      end do
288 !      stop
289 !      ENDDEBUG
290 
291        if(istwf_k>=2)then
292 !        Impose parity of resulting scalar (this operation could be
293 !        replaced by direct saving of CPU time in the preceeding section)
294          do iffkg=1,nffkg
295            scalars(parity(iffkg),iffkg)=0.0d0
296          end do
297        end if
298 
299        iffkg=0
300        iffkgs=nffkge+nffkgd
301        iffkgs2=nffkge+nffkgs
302        iffkgk=nffkge*2
303        do ilang=1,nlang
304          nproj=jproj(ilang)
305          if(nproj>0)then
306 !          ilang2 is the number of independent tensor components
307 !          for symmetric tensor of rank ilang-1
308            ilang2=(ilang*(ilang+1))/2
309 
310 !          Loop over projectors
311            do iproj=1,nproj
312 !            Multiply by the k+G factors (tensors of various rank)
313              do ii=1,ilang2
314 !              Get the starting address for the relevant tensor
315                jj=ii+((ilang-1)*ilang*(ilang+1))/6
316                iffkg=iffkg+1
317 !              !$OMP CRITICAL (OPERNL2_1)
318                gxa(1,jj,ia,iproj)=gxa(1,jj,ia,iproj)+scalars(1,iffkg)
319                gxa(2,jj,ia,iproj)=gxa(2,jj,ia,iproj)+scalars(2,iffkg)
320 !              !$OMP END CRITICAL (OPERNL2_1)
321 !              Now, compute gradients, if needed.
322                if ((choice==2.or.choice==23) .and. ndgxdt==3) then
323                  do mu=1,3
324                    jffkg=nffkge+(iffkg-1)*3+mu
325 !                  Pay attention to the use of reals and imaginary parts here ...
326 !                  !$OMP CRITICAL (OPERNL2_2)
327                    dgxdt(1,mu,jj,ia,iproj)=dgxdt(1,mu,jj,ia,iproj)-two_pi*scalars(2,jffkg)
328                    dgxdt(2,mu,jj,ia,iproj)=dgxdt(2,mu,jj,ia,iproj)+two_pi*scalars(1,jffkg)
329 !                  !$OMP END CRITICAL (OPERNL2_2)
330                  end do
331                end if
332                if (choice==2 .and. ndgxdt==1) then
333                  jffkg=nffkge+iffkg
334 !                Pay attention to the use of reals and imaginary parts here ...
335 !                !$OMP CRITICAL (OPERNL2_3)
336                  dgxdt(1,1,jj,ia,iproj)=dgxdt(1,1,jj,ia,iproj)-two_pi*scalars(2,jffkg)
337                  dgxdt(2,1,jj,ia,iproj)=dgxdt(2,1,jj,ia,iproj)+two_pi*scalars(1,jffkg)
338 !                !$OMP END CRITICAL (OPERNL2_3)
339                end if
340                if (choice==4) then
341                  do mu=1,3
342                    jffkg=nffkge+(iffkg-1)*9+mu
343 !                  Pay attention to the use of reals and imaginary parts here ...
344 !                  !$OMP CRITICAL (OPERNL2_4)
345                    dgxdt(1,mu,jj,ia,iproj)=dgxdt(1,mu,jj,ia,iproj)-two_pi*scalars(2,jffkg)
346                    dgxdt(2,mu,jj,ia,iproj)=dgxdt(2,mu,jj,ia,iproj)+two_pi*scalars(1,jffkg)
347 !                  !$OMP END CRITICAL (OPERNL2_4)
348                  end do
349                  do mu=4,9
350                    jffkg=nffkge+(iffkg-1)*9+mu
351 !                  Pay attention to the use of reals and imaginary parts here ...
352 !                  Also, note the multiplication by (2 pi)**2
353 !                  !$OMP CRITICAL (OPERNL2_5)
354                    dgxdt(1,mu,jj,ia,iproj)=dgxdt(1,mu,jj,ia,iproj)-two_pi2*scalars(1,jffkg)
355                    dgxdt(2,mu,jj,ia,iproj)=dgxdt(2,mu,jj,ia,iproj)-two_pi2*scalars(2,jffkg)
356 !                  !$OMP END CRITICAL (OPERNL2_5)
357                  end do
358                end if
359 !              End loop on ii=1,ilang2
360              end do
361 
362              if (choice==3 .or. choice==6 .or. choice==23) then
363 !              Compute additional tensors related to strain gradients
364 !              ilang3 is number of unique tensor components of rank ilang+1
365                ilang3=((ilang+2)*(ilang+3))/2
366                jjs=((ilang+1)*(ilang+2)*(ilang+3))/6
367 !              Compute strain gradient tensor components
368                do ii=1,ilang3
369 !                Note that iffkgs is also used by ddk and 2nd derivative parts
370                  iffkgs=iffkgs+1
371                  jj=ii+jjs
372 !                !$OMP CRITICAL (OPERNL2_6)
373                  dgxds(1,jj-4,ia,iproj)=dgxds(1,jj-4,ia,iproj)+scalars(1,iffkgs)
374                  dgxds(2,jj-4,ia,iproj)=dgxds(2,jj-4,ia,iproj)+scalars(2,iffkgs)
375 !                !$OMP END CRITICAL (OPERNL2_6)
376                end do
377              end if
378 
379              if (choice==6) then
380 !              Compute additional tensors related to strain 2nd derivatives
381 !              and internal strain derivatives
382 !              ilang6 is number of unique tensor components of rank ilang+3
383                ilang6=((ilang+4)*(ilang+5))/2
384                jjs=((ilang+3)*(ilang+4)*(ilang+5))/6
385 !              Compute strain gradient tensor components
386                do ii=1,ilang6
387                  iffkgs2=iffkgs2+1
388                  jj=ii+jjs
389 !                !$OMP CRITICAL (OPERNL2_6)
390                  d2gxds2(1,jj-20,ia,iproj)=d2gxds2(1,jj-20,ia,iproj)+scalars(1,iffkgs2)
391                  d2gxds2(2,jj-20,ia,iproj)=d2gxds2(2,jj-20,ia,iproj)+scalars(2,iffkgs2)
392 !                !$OMP END CRITICAL (OPERNL2_6)
393                end do
394 
395 !              ilang4 is number of unique tensor components of rank ilang
396                ilang4=((ilang+1)*(ilang+2))/2
397                jjs=((ilang)*(ilang+1)*(ilang+2))/6
398 !              Compute internal strain gradient tensor components
399                do ii=1,ilang4
400                  iffkgs2=iffkgs2+1
401                  jj=ii+jjs
402 !                !$OMP CRITICAL (OPERNL2_6)
403 !                Pay attention to the use of reals and imaginary parts here ...
404                  dgxdis(1,jj-1,ia,iproj)=dgxdis(1,jj-1,ia,iproj)-two_pi*scalars(2,iffkgs2)
405                  dgxdis(2,jj-1,ia,iproj)=dgxdis(2,jj-1,ia,iproj)+two_pi*scalars(1,iffkgs2)
406 !                !$OMP END CRITICAL (OPERNL2_6)
407                end do
408 
409 !              ilang5 is number of unique tensor components of rank ilang+2
410                ilang5=((ilang+3)*(ilang+4))/2
411                jjs=((ilang+2)*(ilang+3)*(ilang+4))/6
412 !              Compute internal strain gradient tensor components
413                do ii=1,ilang5
414                  iffkgs2=iffkgs2+1
415                  jj=ii+jjs
416 !                !$OMP CRITICAL (OPERNL2_6)
417 !                Pay attention to the use of reals and imaginary parts here ...
418                  d2gxdis(1,jj-10,ia,iproj)=d2gxdis(1,jj-10,ia,iproj)-two_pi*scalars(2,iffkgs2)
419                  d2gxdis(2,jj-10,ia,iproj)=d2gxdis(2,jj-10,ia,iproj)+two_pi*scalars(1,iffkgs2)
420 !                !$OMP END CRITICAL (OPERNL2_6)
421                end do
422              end if ! choice==6
423 
424              if (choice==5) then
425 !              Compute additional tensors related to ddk with ffnl(:,2,...)
426                ilangx=(ilang*(ilang+1))/2
427                jjs=((ilang-1)*ilang*(ilang+1))/6
428                do ii=1,ilangx
429 !                Note that iffkgs is also used by strain part
430                  iffkgs=iffkgs+1
431                  jj=ii+jjs
432 !                !$OMP CRITICAL (OPERNL2_7)
433                  dgxdt(1,1,jj,ia,iproj)=dgxdt(1,1,jj,ia,iproj)+scalars(1,iffkgs)
434                  dgxdt(2,1,jj,ia,iproj)=dgxdt(2,1,jj,ia,iproj)+scalars(2,iffkgs)
435 !                !$OMP END CRITICAL (OPERNL2_7)
436                end do
437 !              Compute additional tensors related to ddk with ffnl(:,1,...)
438                if(ilang>=2)then
439                  ilangx=((ilang-1)*ilang)/2
440                  jjs=((ilang-2)*(ilang-1)*ilang)/6
441                  do ii=1,ilangx
442                    iffkgk=iffkgk+1
443                    jj=ii+jjs
444 !                  !$OMP CRITICAL (OPERNL2_8)
445                    dgxdt(1,2,jj,ia,iproj)=dgxdt(1,2,jj,ia,iproj)+scalars(1,iffkgk)
446                    dgxdt(2,2,jj,ia,iproj)=dgxdt(2,2,jj,ia,iproj)+scalars(2,iffkgk)
447 !                  !$OMP END CRITICAL (OPERNL2_8)
448                  end do
449                end if
450              end if
451 
452 !            End projector loop
453            end do
454 
455 !          End condition of non-zero projectors
456          end if
457 
458 !        End angular momentum loop
459        end do
460 
461 !      End loop on atoms
462      end do
463 
464    else if (sign==-1) then
465 !    Application of non-local part from projected scalars
466 !    back to reciprocal space ...
467 !    [this section merely computes terms which add to <G|Vnl|C>;
468 !    nothing here is needed when various gradients are being computed]
469 
470 !    Loop on atoms
471      do ia=1,nincat
472 
473 !      Compute the shift eventually needed to get the phases in ph3d
474        iaph3d=ia
475        if(nloalg(2)>0)iaph3d=ia+ia3-1
476 
477 !      Transfer gxa (and eventually dgxdt) in scalars with different indexing
478        iffkg=0
479        iffkgk=nffkge*2
480        iffkgs=nffkge
481        do ilang=1,nlang
482          nproj=jproj(ilang)
483          if (nproj>0) then
484            ilang2=(ilang*(ilang+1))/2
485            ilang3=((ilang+2)*(ilang+3))/2
486            do iproj=1,nproj
487              do ii=1,ilang2
488                jj=ii+((ilang-1)*ilang*(ilang+1))/6
489                iffkg=iffkg+1
490                if(choice==1 .or. choice==3)then
491                  scalars(1,iffkg)=gxa(1,jj,ia,iproj)
492                  scalars(2,iffkg)=gxa(2,jj,ia,iproj)
493                else if (choice==2 .and. ndgxdt==1) then
494                  jffkg=nffkge+iffkg
495 !                Pay attention to the use of reals and imaginary parts here ...
496 !                Also, the gxa and dgxdt arrays are switched, in order
497 !                to give the correct combination when multiplying ffkg,
498 !                see Eq.(53) of PRB55,10337(1997)
499                  scalars(1,jffkg)= two_pi*gxa(2,jj,ia,iproj)
500                  scalars(2,jffkg)=-two_pi*gxa(1,jj,ia,iproj)
501                  scalars(1,iffkg)= dgxdt(1,1,jj,ia,iproj)
502                  scalars(2,iffkg)= dgxdt(2,1,jj,ia,iproj)
503                else if (choice==5) then
504                  jffkg=nffkge+iffkg
505 !                The gxa and dgxdt arrays are switched, in order
506 !                to give the correct combination when multiplying ffkg,
507                  scalars(1,jffkg)= gxa(1,jj,ia,iproj)
508                  scalars(2,jffkg)= gxa(2,jj,ia,iproj)
509                  scalars(1,iffkg)= dgxdt(1,1,jj,ia,iproj)
510                  scalars(2,iffkg)= dgxdt(2,1,jj,ia,iproj)
511                end if
512              end do
513              if(choice==3) then
514                do ii=1,ilang3
515                  iffkgs=iffkgs+1
516                  jj=ii+((ilang+1)*(ilang+2)*(ilang+3))/6
517                  scalars(1,iffkgs)=dgxds(1,jj-4,ia,iproj)
518                  scalars(2,iffkgs)=dgxds(2,jj-4,ia,iproj)
519                end do
520              end if
521              if(ilang>=2 .and. choice==5)then
522                do ii=1,((ilang-1)*ilang)/2
523                  jj=ii+((ilang-2)*(ilang-1)*ilang)/6
524                  iffkgk=iffkgk+1
525                  scalars(1,iffkgk)= dgxdt(1,2,jj,ia,iproj)
526                  scalars(2,iffkgk)= dgxdt(2,2,jj,ia,iproj)
527                end do
528              end if
529            end do
530          end if
531        end do
532 
533 !      DEBUG
534 !      if(choice==5)then
535 !      write(std_out,*)' opernl2 : write gxa(:,...) array '
536 !      do ii=1,10
537 !      write(std_out,'(i3,2es16.6)' )ii,gxa(:,ii,1,1)
538 !      end do
539 !      write(std_out,*)' opernl2 : write dgxdt(:,1,...) array '
540 !      do ii=1,10
541 !      write(std_out,'(i3,2es16.6)' )ii,dgxdt(:,1,ii,1,1)
542 !      end do
543 !      write(std_out,*)' opernl2 : write dgxdt(:,2,...) array '
544 !      do ii=1,4
545 !      write(std_out,'(i3,2es16.6)' )ii,dgxdt(:,2,ii,1,1)
546 !      end do
547 !      end if
548 
549 !      do iffkg=1,nffkg
550 !      write(std_out,*)'iffkg,scalars',iffkg,scalars(1:2,iffkg)
551 !      end do
552 !      stop
553 !      ENDDEBUG
554 
555 !      ******* Entering the critical part *********************************
556 
557        do ipw=1,nincpw
558          teffv(1,ipw)=0.0d0
559          teffv(2,ipw)=0.0d0
560        end do
561        do iffkg=1,nffkg
562          do ipw=1,nincpw
563            teffv(1,ipw)=teffv(1,ipw)+ffkg(ipw,iffkg)*scalars(1,iffkg)
564            teffv(2,ipw)=teffv(2,ipw)+ffkg(ipw,iffkg)*scalars(2,iffkg)
565          end do
566        end do
567 !      Multiplication by the complex conjugate of the phase
568        ig=ipw1
569        do ipw=1,nincpw
570          vect(1,ig)=vect(1,ig)+teffv(1,ipw)*ph3d(1,ig,iaph3d)+teffv(2,ipw)*ph3d(2,ig,iaph3d)
571          vect(2,ig)=vect(2,ig)+teffv(2,ipw)*ph3d(1,ig,iaph3d)-teffv(1,ipw)*ph3d(2,ig,iaph3d)
572          ig=ig+1
573        end do
574 
575 !      ******* Leaving the critical part *********************************
576 
577 !      End loop on atoms
578      end do
579 
580 !    End sign==-1
581    else
582 
583 !    Problem: sign and/or choice do not make sense
584      write(message,'(a,2i10,a,a)')&
585 &     ' Input sign, choice=',sign,choice,ch10,&
586 &     ' Are not compatible or allowed. '
587      MSG_BUG(message)
588    end if
589 
590 !  End loop on blocks of planewaves
591  end do
592 !!$OMP END DO
593  ABI_DEALLOCATE(ffkg)
594  ABI_DEALLOCATE(kpgx)
595  ABI_DEALLOCATE(parity)
596  ABI_DEALLOCATE(scalars)
597  ABI_DEALLOCATE(teffv)
598 !!$OMP END PARALLEL
599 
600 
601 !DEBUG
602 !if(choice==5)then
603 !write(std_out,*)'opernl2 : write vect(2*npw)'
604 !do ipw=1,2
605 !write(std_out,*)ipw,vect(1:2,ipw)
606 !end do
607 !write(std_out,*)'opernl2 : write ph3d'
608 !do ipw=1,npw
609 !write(std_out,*)ipw,ph3d(1:2,ipw,1)
610 !end do
611 !write(std_out,*)' opernl2 : write gxa array '
612 !write(std_out,*)' ang mom ,ia '
613 !do iproj=1,mproj
614 !do ia=1,1
615 !do ii=1,3
616 !do ii=1,10
617 !write(std_out,'(i3,2es16.6)' )ii,gxa(:,ii,1,1)
618 !end do
619 !end do
620 !end do
621 !end if
622 !if(choice==5)then
623 !write(std_out,*)' opernl2 : write dgxdt(:,1,...) array '
624 !do ii=1,10
625 !write(std_out,'(i3,2es16.6)' )ii,dgxdt(:,1,ii,1,1)
626 !end do
627 !write(std_out,*)' opernl2 : write dgxdt(:,2,...) array '
628 !do ii=1,4
629 !write(std_out,'(i3,2es16.6)' )ii,dgxdt(:,2,ii,1,1)
630 !end do
631 !stop
632 !end if
633 !ENDDEBUG
634 
635 end subroutine opernl2