TABLE OF CONTENTS


ABINIT/getdc1 [ Functions ]

[ Top ] [ Functions ]

NAME

 getdc1

FUNCTION

 Compute |delta_C^(1)> from one wave function C - PAW ONLY
 Compute <G|delta_C^(1)> (dcwavef) and eventually <P_i| delta_C^(1)> (dcwaveprj) where P_i= non-local projector
 delta_C^(1) is the variation of wavefunction only due to variation of overlap operator S.
 delta_C^(1)=-1/2.Sum_j [ <C_j|S^(1)|C>.C_j
         see PRB 78, 035105 (2008) [[cite:Audouze2008]], Eq. (42 and 40, term 2)

INPUTS

  cgq(2,mcgq)=wavefunction coefficients for all bands j on present processor, at k+Q: cgq=< G |Cnk+q>
  cprjq(natom,mcprjq)= wave functions j at k+q projected with non-local projectors: cprjq=<P_i|Cnk+q>
  ibgq=shift to be applied on the location of data in the array cprjq
  icgq=shift to be applied on the location of data in the array cgq
  istwfk=option parameter that describes the storage of wfs
  mcgq=second dimension of the cgq array
  mcprjq=second dimension of the cprjq array
  mpi_enreg=information about MPI parallelization
  natom= number of atoms in cell
  nband=number of bands
  npw1=number of planewaves in basis sphere at k+Q
  nspinor=number of spinorial components of the wavefunctions
  opt_cprj=flag governing the computation of <P_i|delta_C^(1)> (P_i= non-local projector)
  s1cwave0(2,npw1*nspinor)=<G|S^(1)|C> where S^(1) is the first-order overlap operator

OUTPUT

  dcwavef(2,npw1*nspinor)=change of wavefunction due to change of overlap PROJECTED ON PLANE-WAVES:
         dcwavef is delta_C(1)=-1/2.Sum_{j}[<C0_k+q_j|S(1)|C0_k_i>.|C0_k+q_j>]
  === if optcprj=1 ===
  dcwaveprj(natom,nspinor*optcprj)=change of wavefunction due to change of overlap PROJECTED ON NL-PROJECTORS:

SOURCE

1274 subroutine getdc1(band,band_procs,bands_treated_now,cgq,cprjq,dcwavef,dcwaveprj,&
1275 &                 ibgq,icgq,istwfk,mcgq,mcprjq,&
1276 &                 mpi_enreg,natom,nband,nband_me,npw1,nspinor,optcprj,s1cwave0)
1277 
1278 !Arguments ------------------------------------
1279 !scalars
1280  integer,intent(in) :: ibgq,icgq,istwfk,mcgq,mcprjq,natom,nband,npw1,nspinor,optcprj
1281  integer,intent(in) :: band, nband_me
1282  type(MPI_type),intent(in) :: mpi_enreg
1283 !arrays
1284  integer,intent(in) :: band_procs(nband),bands_treated_now(nband)
1285  real(dp),intent(in) :: cgq(2,mcgq),s1cwave0(2,npw1*nspinor)
1286  real(dp),intent(out) :: dcwavef(2,npw1*nspinor)
1287  type(pawcprj_type),intent(in) :: cprjq(natom,mcprjq)
1288  type(pawcprj_type),intent(inout) :: dcwaveprj(natom,nspinor*optcprj)
1289 
1290 !Local variables-------------------------------
1291 !scalars
1292  integer, parameter :: tim_projbd=0
1293  integer :: ipw
1294  integer :: band_, ierr
1295  real(dp),parameter :: scal=-half
1296 !arrays
1297  real(dp), allocatable :: dummy(:,:),scprod(:,:)
1298  real(dp), allocatable :: dcwavef_tmp(:,:)
1299  type(pawcprj_type),allocatable :: dcwaveprj_tmp(:,:)
1300 
1301 ! *********************************************************************
1302 
1303  DBG_ENTER("COLL")
1304 
1305  ABI_MALLOC(dummy,(0,0))
1306  ABI_MALLOC(scprod,(2,nband_me))
1307  ABI_MALLOC(dcwavef_tmp,(2,npw1*nspinor))
1308  if (optcprj == 1) then
1309    ABI_MALLOC(dcwaveprj_tmp,(natom,nspinor*optcprj))
1310    call pawcprj_alloc(dcwaveprj_tmp, 0, dcwaveprj(:,1)%nlmn)
1311  end if
1312 
1313 !=== 1- COMPUTE: <G|S^(1)|C_k> - Sum_j [<C_k+q,j|S^(1)|C_k>.<G|C_k+q,j>]
1314 !!               using the projb routine
1315 !Note the subtlety: projbd is called with useoverlap=0 and s1cwave0
1316 !in order to get Sum[<cgq|s1|c>|cgq>]=Sum[<cgq|gs1>|cgq>]
1317 
1318 ! run over procs in my pool which have a dcwavef to projbd
1319  do band_ = 1, nband
1320    if (bands_treated_now(band_) == 0) cycle
1321    dcwavef_tmp = zero
1322 
1323 ! distribute dcwavef_tmp to my band pool
1324 ! everyone works on a single band s1cwave0 = <G|S^(1)|C_k>
1325    if (band_ == band) then
1326 !$OMP PARALLEL DO
1327      do ipw=1,npw1*nspinor
1328        dcwavef_tmp(1:2,ipw)=s1cwave0(1:2,ipw)
1329      end do
1330    end if
1331    call xmpi_bcast(dcwavef_tmp,band_procs(band_),mpi_enreg%comm_band,ierr)
1332 
1333 ! get the projbd onto my processor's bands dcwavef = dcwavef - <cgq|dcwavef>|cgq>
1334 ! dcwavef = <G|S^(1)|C_k> - Sum_{MYj} [<C_k+q,j|S^(1)|C_k>.<G|C_k+q,j>]
1335 ! scprod  =                            <C_k+q,j|S^(1)|C_k> for {MYj}
1336    call projbd(cgq,dcwavef_tmp,-1,icgq,0,istwfk,mcgq,0,nband_me,npw1,nspinor,&
1337 &   dummy,scprod,0,tim_projbd,0,mpi_enreg%me_g0,mpi_enreg%comm_fft)
1338 
1339 
1340 ! sum all of the corrections
1341 ! dcwavef = Nprocband * <G|S^(1)|C_k> - Sum_{ALLj} [<C_k+q,j|S^(1)|C_k>.<G|C_k+q,j>]
1342    call xmpi_sum(dcwavef_tmp,mpi_enreg%comm_band,ierr)
1343 
1344 ! save to my proc if it is my turn, and subtract Ntuple counted dcwavef
1345    if (band_ == band) then
1346 !=== 2- COMPUTE: <G|delta_C^(1)> = -1/2.Sum_j [<C_k+q,j|S^(1)|C_k>.<G|C_k+q,j>] by substraction
1347 ! tested this is equivalent to previous coding to within 1.e-18 accumulated error (probably in favor of this coding)
1348 !$OMP PARALLEL DO PRIVATE(ipw) SHARED(dcwavef,s1cwave0,dcwavef_tmp,npw1,nspinor)
1349      do ipw=1,npw1*nspinor
1350        dcwavef(1:2,ipw)= scal*(mpi_enreg%nproc_band*s1cwave0(1:2,ipw)-dcwavef_tmp(1:2,ipw))
1351      end do
1352    end if
1353 
1354 !=== 3- COMPUTE: <P_i|delta_C^(1)> = -1/2.Sum_j [<C_k+q,j|S^(1)|C_k>.<P_i|C_k+q,j>]
1355 ! as above everyone has to operate on each band band_
1356    if (optcprj==1.and.mcprjq>0) then
1357 !   cprjq         =                               <P_i|C_k+q,j>  for MYj
1358 !   dcwaveprj_tmp =  Sum_MYj [<C_k+q,j|S^(1)|C_k>.<P_i|C_k+q,j>]
1359      call pawcprj_lincom(scprod,cprjq(:,ibgq+1:ibgq+nspinor*nband_me),dcwaveprj_tmp,nband_me)
1360 
1361 ! still need to mpisum the dcwaveprj to get linear combination of all bands, not just mine
1362 !   dcwaveprj =  Sum_ALLj [<C_k+q,j|S^(1)|C_k,i>.<P_i|C_k+q,j>]
1363      call pawcprj_mpi_sum(dcwaveprj_tmp,mpi_enreg%comm_band,ierr)
1364 
1365      if (band_ == band) then
1366 ! dcwaveprj =  -1/2 dcwaveprj_tmp
1367 !TODO: check the correct order of scal and zero (alpha / beta) coefficients.
1368 !  Here dcwaveprj is squashed by the _tmp variable which is used in parallel
1369        call pawcprj_axpby(scal,zero,dcwaveprj_tmp,dcwaveprj)
1370      end if
1371    end if
1372 
1373  end do ! procs in my band pool
1374 
1375  ABI_FREE(dummy)
1376  ABI_FREE(scprod)
1377  ABI_FREE(dcwavef_tmp)
1378  if (optcprj == 1) then
1379    call pawcprj_free(dcwaveprj_tmp)
1380    ABI_FREE(dcwaveprj_tmp)
1381  end if
1382 
1383  DBG_EXIT("COLL")
1384 
1385 end subroutine getdc1

ABINIT/getgh1c [ Functions ]

[ Top ] [ Functions ]

NAME

 getgh1c

FUNCTION

 Compute <G|H^(1)|C> (or <G|H^(1)-lambda.S^(1)|C>) for input vector |C> expressed in reciprocal space.
 (H^(1) is the 1st-order pertubed Hamiltonian, S^(1) is the 1st-order perturbed overlap operator).
 Result is put in array gh1c.
 If required, part of <G|K(1)+Vnonlocal^(1)|C> not depending on VHxc^(1) is also returned in gvnlx1c.
 If required, <G|S^(1)|C> is returned in gs1c (S=overlap - PAW only)

INPUTS

  berryopt=option for Berry phase
  cwave(2,npw*nspinor)=input wavefunction, in reciprocal space
  cwaveprj(natom,nspinor*usecprj)=<p_lmn|C> coefficients for wavefunction |C> (and 1st derivatives)
     if not allocated or size=0, they are locally computed (and not sorted)
  dkinpw(npw)=derivative of the (modified) kinetic energy for each plane wave at k (Hartree)
  grad_berry(2,npw1*nspinor*(berryopt/4))= the gradient of the Berry phase term
  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q
  idir=direction of the perturbation
  ipert=type of the perturbation
  lambda=real use to apply H^(1)-lambda.S^(1)
  mpi_enreg=information about MPI parallelization
  npw=number of planewaves in basis sphere at given k.
  npw1=number of planewaves in basis sphere at k+q
  optlocal=0: local part of H^(1) is not computed in gh1c=<G|H^(1)|C>
           1: local part of H^(1) is computed in gh1c=<G|H^(1)|C>
  optnl=0: non-local part of H^(1) is not computed in gh1c=<G|H^(1)|C>
        1: non-local part of H^(1) depending on VHxc^(1) is not computed in gh1c=<G|H^(1)|C>
        2: non-local part of H^(1) is totally computed in gh1c=<G|H^(1)|C>
  opt_gvnlx1=option controlling the use of gvnlx1 array:
            0: used as an output
            1: used as an input:   (only for ipert=natom+2)
                 NCPP: contains the ddk 1-st order WF
                 PAW: contains frozen part of 1st-order hamiltonian
            2: used as input/ouput:    - used only for PAW and ipert=natom+2
                 At input: contains the ddk 1-st order WF (times i)
                 At output: contains frozen part of 1st-order hamiltonian
  rf_hamkq <type(rf_hamiltonian_type)>=all data for the 1st-order Hamiltonian at k,k+q
  sij_opt= -PAW ONLY-  if  0, only matrix elements <G|H^(1)|C> have to be computed
     (S=overlap)       if  1, matrix elements <G|S^(1)|C> have to be computed in gs1c in addition to gh1c
                       if -1, matrix elements <G|H^(1)-lambda.S^(1)|C> have to be computed in gh1c (gs1c not used)
  tim_getgh1c=timing code of the calling subroutine (can be set to 0 if not attributed)
  usevnl=1 if gvnlx1=(part of <G|K^(1)+Vnl^(1)-lambda.S^(1)|C> not depending on VHxc^(1)) has to be input/output

OUTPUT

 gh1c(2,npw1*nspinor)= <G|H^(1)|C> or  <G|H^(1)-lambda.S^(1)|C> on the k+q sphere
                     (only kinetic+non-local parts if optlocal=0)
 if (usevnl==1)
  gvnlx1(2,npw1*nspinor)=  part of <G|K^(1)+Vnl^(1)|C> not depending on VHxc^(1)              (sij_opt/=-1)
                       or part of <G|K^(1)+Vnl^(1)-lambda.S^(1)|C> not depending on VHxc^(1) (sij_opt==-1)
 if (sij_opt=1)
  gs1c(2,npw1*nspinor)=<G|S^(1)|C> (S=overlap) on the k+q sphere.

SOURCE

119 subroutine getgh1c(berryopt,cwave,cwaveprj,gh1c,grad_berry,gs1c,gs_hamkq,&
120                    gvnlx1,idir,ipert,lambda,mpi_enreg,optlocal,optnl,opt_gvnlx1,&
121                    rf_hamkq,sij_opt,tim_getgh1c,usevnl,conj)
122 
123 !Arguments ------------------------------------
124 !scalars
125  logical,intent(in),optional :: conj
126  integer,intent(in) :: berryopt,idir,ipert,optlocal,optnl,opt_gvnlx1,sij_opt,tim_getgh1c,usevnl
127  real(dp),intent(in) :: lambda
128  type(MPI_type),intent(in) :: mpi_enreg
129  type(gs_hamiltonian_type),intent(inout),target :: gs_hamkq
130  type(rf_hamiltonian_type),intent(inout),target :: rf_hamkq
131 !arrays
132  real(dp),intent(in) :: grad_berry(:,:)
133  real(dp),intent(inout) :: cwave(2,gs_hamkq%npw_k*gs_hamkq%nspinor)
134  real(dp),intent(out) :: gh1c(2,gs_hamkq%npw_kp*gs_hamkq%nspinor)
135  real(dp),intent(out) :: gs1c(2,gs_hamkq%npw_kp*gs_hamkq%nspinor)
136  real(dp),intent(inout),target :: gvnlx1(2,gs_hamkq%npw_kp*gs_hamkq%nspinor)
137  type(pawcprj_type),intent(inout),target :: cwaveprj(:,:)
138 
139 !Local variables-------------------------------
140 !scalars
141  integer,parameter :: level=16
142  integer :: choice,cplex1,cpopt,ipw,ipws,ispinor,istr,i1,i2,i3
143  integer :: my_nspinor,natom,ncpgr,nnlout=1,npw,npw1,paw_opt,signs
144  integer :: tim_fourwf,tim_nonlop,usecprj
145  logical :: compute_conjugate,has_kin,has_mGGA1,has_nd1,usevnl2
146  real(dp) :: weight !, cpu, wall, gflops
147  !character(len=500) :: msg
148 !arrays
149  real(dp) :: enlout(1),tsec(2),svectout_dum(1,1),vectout_dum(1,1)
150  real(dp),allocatable :: cwave_sp(:,:),cwavef1(:,:),cwavef2(:,:)
151  real(dp),allocatable :: gh1c_sp(:,:),gh1c1(:,:),gh1c2(:,:),gh1c3(:,:),gh1c4(:,:)
152  real(dp),allocatable :: gh1c_mGGA(:,:),gh1ndc(:,:),gvnl2(:,:)
153  real(dp),allocatable :: nonlop_out(:,:),vlocal1_tmp(:,:,:),work(:,:,:,:)
154  real(dp),ABI_CONTIGUOUS pointer :: gvnlx1_(:,:)
155  real(dp),pointer :: dkinpw(:),kinpw1(:)
156  type(pawcprj_type),allocatable,target :: cwaveprj_tmp(:,:)
157  type(pawcprj_type),pointer :: cwaveprj_ptr(:,:)
158 
159 ! *********************************************************************
160 
161  DBG_ENTER("COLL")
162 
163  ! Keep track of total time spent in getgh1c
164  call timab(196+tim_getgh1c,1,tsec)
165 
166 !======================================================================
167 !== Initialisations and compatibility tests
168 !======================================================================
169 
170  npw  =gs_hamkq%npw_k
171  npw1 =gs_hamkq%npw_kp
172  natom=gs_hamkq%natom
173 
174  ! Compatibility tests
175  if(gs_hamkq%usepaw==1.and.(ipert>=0.and.(ipert<=natom.or.ipert==natom+3.or.ipert==natom+4))) then
176    if ((optnl>=1.and.(.not.associated(rf_hamkq%e1kbfr))) .or. &
177        (optnl==2.and.(.not.associated(rf_hamkq%e1kbsc)))) then
178      ABI_BUG('ekb derivatives must be allocated for ipert<=natom or natom+3/4 !')
179    end if
180  end if
181  if(gs_hamkq%usepaw==1.and.(ipert==natom+2)) then
182    if ((optnl>=1.and.(.not.associated(rf_hamkq%e1kbfr))) .or. &
183        (optnl==2.and.(.not.associated(rf_hamkq%e1kbsc)))) then
184      ABI_BUG('ekb derivatives must be allocated for ipert=natom+2 !')
185    end if
186    if (usevnl==0) then
187      ABI_BUG('gvnlx1 must be allocated for ipert=natom+2 !')
188    end if
189  end if
190  if(ipert==natom+2.and.opt_gvnlx1==0) then
191    ABI_BUG('opt_gvnlx1=0 not compatible with ipert=natom+2 !')
192  end if
193  if (mpi_enreg%paral_spinor==1) then
194    ABI_BUG('Not compatible with parallelization over spinorial components !')
195  end if
196 
197  ! Check sizes
198  my_nspinor=max(1,gs_hamkq%nspinor/mpi_enreg%nproc_spinor)
199  if (size(cwave)<2*npw*my_nspinor) then
200    ABI_BUG('wrong size for cwave!')
201  end if
202  if (size(gh1c)<2*npw1*my_nspinor) then
203    ABI_BUG('wrong size for gh1c!')
204  end if
205  if (usevnl/=0) then
206    if (size(gvnlx1)<2*npw1*my_nspinor) then
207      ABI_BUG('wrong size for gvnlx1!')
208    end if
209  end if
210  if (sij_opt==1) then
211    if (size(gs1c)<2*npw1*my_nspinor) then
212      ABI_BUG('wrong size for gs1c!')
213    end if
214  end if
215  if (berryopt>=4) then
216    if (size(grad_berry)<2*npw1*my_nspinor) then
217      ABI_BUG('wrong size for grad_berry!')
218    end if
219  end if
220 
221  ! PAW: specific treatment for usecprj input arg
222  !      force it to zero if cwaveprj is not allocated
223  usecprj=gs_hamkq%usecprj ; ncpgr=0
224  if(gs_hamkq%usepaw==1) then
225    if (size(cwaveprj)==0) usecprj=0
226    if (usecprj/=0) then
227      ncpgr=cwaveprj(1,1)%ncpgr
228      if (size(cwaveprj)<gs_hamkq%natom*my_nspinor) then
229        ABI_BUG('wrong size for cwaveprj!')
230      end if
231      if(gs_hamkq%usepaw==1.and.(ipert>=0.and.(ipert<=natom.or.ipert==natom+3.or.ipert==natom+4))) then
232        if (ncpgr/=1)then
233          ABI_BUG('Projected WFs (cprj) derivatives are not correctly stored !')
234        end if
235      end if
236    end if
237  else
238    if(usecprj==1)then
239      ABI_BUG('usecprj==1 not allowed for NC psps !')
240    end if
241  end if
242 
243  tim_nonlop=8
244  if (tim_getgh1c==1.and.ipert<=natom) tim_nonlop=7
245  if (tim_getgh1c==2.and.ipert<=natom) tim_nonlop=5
246  if (tim_getgh1c==1.and.ipert> natom) tim_nonlop=8
247  if (tim_getgh1c==2.and.ipert> natom) tim_nonlop=5
248  if (tim_getgh1c==3                 ) tim_nonlop=0
249 
250  compute_conjugate = .false.
251  if(present(conj)) compute_conjugate = conj
252 
253 !======================================================================
254 !== Apply the 1st-order local potential to the wavefunction
255 !======================================================================
256 
257 !Phonon perturbation
258 !or Electric field perturbation
259 !or Strain perturbation
260 !-------------------------------------------
261  if (ipert<=natom+5.and.ipert/=natom+1.and.optlocal>0) then !SPr deb
262 
263    ABI_MALLOC(work,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
264 
265    if (gs_hamkq%nvloc==1) then
266 
267      weight=one ; tim_fourwf=4
268      call fourwf(rf_hamkq%cplex,rf_hamkq%vlocal1,cwave,gh1c,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
269        gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
270        npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight,&
271        gpu_option=gs_hamkq%gpu_option)
272      if(gs_hamkq%nspinor==2)then
273        ABI_MALLOC(cwave_sp,(2,npw))
274        ABI_MALLOC(gh1c_sp,(2,npw1))
275 !$OMP PARALLEL DO
276        do ipw=1,npw
277          cwave_sp(1,ipw)=cwave(1,ipw+npw)
278          cwave_sp(2,ipw)=cwave(2,ipw+npw)
279        end do
280        call fourwf(rf_hamkq%cplex,rf_hamkq%vlocal1,cwave_sp,gh1c_sp,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
281          gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
282          npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight,&
283          gpu_option=gs_hamkq%gpu_option)
284 !$OMP PARALLEL DO
285        do ipw=1,npw1
286          gh1c(1,ipw+npw1)=gh1c_sp(1,ipw)
287          gh1c(2,ipw+npw1)=gh1c_sp(2,ipw)
288        end do
289        ABI_FREE(cwave_sp)
290        ABI_FREE(gh1c_sp)
291      end if
292    else
293      ! Non-Collinear magnetism for nvloc=4
294      if (gs_hamkq%nspinor==2) then
295        weight=one ; tim_fourwf=4
296        ABI_MALLOC(gh1c1,(2,npw1))
297        ABI_MALLOC(gh1c2,(2,npw1))
298        ABI_MALLOC(gh1c3,(2,npw1))
299        ABI_MALLOC(gh1c4,(2,npw1))
300        gh1c1(:,:)=zero; gh1c2(:,:)=zero; gh1c3(:,:)=zero ;  gh1c4(:,:)=zero
301        ABI_MALLOC(vlocal1_tmp,(rf_hamkq%cplex*gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
302        !SPr: notation/dimension corrected vlocal_tmp -> vlocal1_tmp
303        ABI_MALLOC(cwavef1,(2,npw))
304        ABI_MALLOC(cwavef2,(2,npw))
305        do ipw=1,npw
306          cwavef1(1:2,ipw)=cwave(1:2,ipw)
307          cwavef2(1:2,ipw)=cwave(1:2,ipw+npw)
308        end do
309        ! gh1c1=v11*phi1
310        vlocal1_tmp(:,:,:)=rf_hamkq%vlocal1(:,:,:,1)
311        call fourwf(rf_hamkq%cplex,vlocal1_tmp,cwavef1,gh1c1,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
312          gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
313          npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight,&
314          gpu_option=gs_hamkq%gpu_option)
315        ! gh1c2=v22*phi2
316        vlocal1_tmp(:,:,:)=rf_hamkq%vlocal1(:,:,:,2)
317        call fourwf(rf_hamkq%cplex,vlocal1_tmp,cwavef2,gh1c2,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
318          gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
319          npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight,&
320          gpu_option=gs_hamkq%gpu_option)
321        ABI_FREE(vlocal1_tmp)
322        cplex1=2
323        ABI_MALLOC(vlocal1_tmp,(cplex1*gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
324        ! gh1c3=(re(v12)-im(v12))*phi1 => v^21*phi1
325        if(rf_hamkq%cplex==1) then
326          do i3=1,gs_hamkq%n6
327            do i2=1,gs_hamkq%n5
328              do i1=1,gs_hamkq%n4
329                vlocal1_tmp(2*i1-1,i2,i3)= rf_hamkq%vlocal1(i1,i2,i3,3)
330                vlocal1_tmp(2*i1  ,i2,i3)=-rf_hamkq%vlocal1(i1,i2,i3,4)
331              end do
332            end do
333          end do
334        else
335          !SPr: modified definition of local potential components for cplex=2 (see dotprod_vn)
336          !also, v21==v12* not always holds (e.g. magnetic field perturbation)
337          do i3=1,gs_hamkq%n6
338            do i2=1,gs_hamkq%n5
339              do i1=1,gs_hamkq%n4
340                vlocal1_tmp(2*i1-1,i2,i3)= rf_hamkq%vlocal1(2*i1  ,i2,i3,4)
341                vlocal1_tmp(2*i1  ,i2,i3)=-rf_hamkq%vlocal1(2*i1-1,i2,i3,4)
342              end do
343            end do
344          end do
345        end if
346        call fourwf(cplex1,vlocal1_tmp,cwavef1,gh1c3,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
347          gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
348          npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight,&
349          gpu_option=gs_hamkq%gpu_option)
350        ! gh1c4=(re(v12)+im(v12))*phi2 => v^12*phi2
351        if(rf_hamkq%cplex==1) then
352          do i3=1,gs_hamkq%n6
353            do i2=1,gs_hamkq%n5
354              do i1=1,gs_hamkq%n4
355                vlocal1_tmp(2*i1,i2,i3)=-vlocal1_tmp(2*i1,i2,i3)
356              end do
357            end do
358          end do
359        else
360          !for cplex=2 and time-reversal breaking perturbations,v21/=v12*
361          do i3=1,gs_hamkq%n6
362            do i2=1,gs_hamkq%n5
363              do i1=1,gs_hamkq%n4
364                vlocal1_tmp(2*i1-1,i2,i3)= rf_hamkq%vlocal1(2*i1-1,i2,i3,3)
365                vlocal1_tmp(2*i1  ,i2,i3)= rf_hamkq%vlocal1(2*i1  ,i2,i3,3)
366              end do
367            end do
368          end do
369        end if
370        call fourwf(cplex1,vlocal1_tmp,cwavef2,gh1c4,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
371          gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
372          npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight,&
373          gpu_option=gs_hamkq%gpu_option)
374        ABI_FREE(vlocal1_tmp)
375        ! Build gh1c from pieces
376        ! gh1c_1 = (v11, v12) (psi1) matrix vector product
377        ! gh1c_2 = (v12*,v22) (psi2)
378        do ipw=1,npw1
379          gh1c(1:2,ipw)     =gh1c1(1:2,ipw)+gh1c4(1:2,ipw)
380          gh1c(1:2,ipw+npw1)=gh1c3(1:2,ipw)+gh1c2(1:2,ipw)
381        end do
382        ABI_FREE(gh1c1)
383        ABI_FREE(gh1c2)
384        ABI_FREE(gh1c3)
385        ABI_FREE(gh1c4)
386        ABI_FREE(cwavef1)
387        ABI_FREE(cwavef2)
388      else
389        ABI_BUG('nspinor/=1 for Non-collinear calculations!')
390      end if
391    end if ! nvloc
392 
393    ABI_FREE(work)
394 
395 !  k-point perturbation (or no local part, i.e. optlocal=0)
396 !  -------------------------------------------
397  else if (ipert==natom+1.or.optlocal==0) then
398 
399 !  In the case of ddk operator, no local contribution (also because no self-consistency)
400 !$OMP PARALLEL DO
401    do ipw=1,npw1*my_nspinor
402      gh1c(:,ipw)=zero
403    end do
404 
405  end if
406 
407 !======================================================================
408 !== Apply the 1st-order non-local potential to the wavefunction
409 !======================================================================
410 
411 !Use of gvnlx1 depends on usevnl
412  if (usevnl==1) then
413    gvnlx1_ => gvnlx1
414  else
415    ABI_MALLOC(gvnlx1_,(2,npw1*my_nspinor))
416  end if
417 
418 !Phonon perturbation
419 !-------------------------------------------
420  if (ipert<=natom.and.(optnl>0.or.sij_opt/=0)) then
421 
422 !  PAW:
423    if (gs_hamkq%usepaw==1) then
424 
425      if (usecprj==1) then
426        cwaveprj_ptr => cwaveprj
427      else
428        ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor))
429        call pawcprj_alloc(cwaveprj_tmp,1,gs_hamkq%dimcprj)
430        cwaveprj_ptr => cwaveprj_tmp
431      end if
432 
433 !    1- Compute derivatives due to projectors |p_i>^(1)
434 !    Only displaced atom contributes
435      cpopt=-1+5*usecprj ; choice=2 ; signs=2
436      paw_opt=1;if (sij_opt/=0) paw_opt=sij_opt+3
437      call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
438 &     paw_opt,signs,gs1c,tim_nonlop,cwave,gvnlx1_,iatom_only=ipert)
439 
440 !    2- Compute derivatives due to frozen part of D_ij^(1) (independent of VHxc^(1))
441 !    All atoms contribute
442      if (optnl>=1) then
443        ABI_MALLOC(nonlop_out,(2,npw1*my_nspinor))
444        cpopt=1+3*usecprj ; choice=1 ; signs=2 ; paw_opt=1
445        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
446 &       paw_opt,signs,svectout_dum,tim_nonlop,cwave,nonlop_out,enl=rf_hamkq%e1kbfr)
447 !$OMP PARALLEL DO
448        do ipw=1,npw1*my_nspinor
449          gvnlx1_(:,ipw)=gvnlx1_(:,ipw)+nonlop_out(:,ipw)
450        end do
451        ABI_FREE(nonlop_out)
452      end if
453 
454 !    3- Compute derivatives due to self-consistent part of D_ij^(1) (depending on VHxc^(1))
455 !    All atoms contribute
456      if (optnl==2) then
457        ABI_MALLOC(gvnl2,(2,npw1*my_nspinor))
458        cpopt=4 ; choice=1 ; signs=2 ; paw_opt=1
459        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
460 &       paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl2,enl=rf_hamkq%e1kbsc)
461      end if
462 
463      if (usecprj==0) then
464        call pawcprj_free(cwaveprj_tmp)
465        ABI_FREE(cwaveprj_tmp)
466      end if
467      nullify(cwaveprj_ptr)
468 
469 !  Norm-conserving psps:
470    else
471 !    Compute only derivatives due to projectors |p_i>^(1)
472      cpopt=-1 ; choice=2 ; signs=2 ; paw_opt=0
473      call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
474 &     paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnlx1_,iatom_only=ipert)
475      if (sij_opt==1) then
476 !$OMP PARALLEL DO
477        do ipw=1,npw1*my_nspinor
478          gs1c(:,ipw)=zero
479        end do
480      end if
481    end if
482 
483 !  k-point perturbation
484 !  -------------------------------------------
485  else if (ipert==natom+1.and.(optnl>0.or.sij_opt/=0)) then
486 
487    tim_nonlop=8 ; signs=2 ; choice=5
488    if (gs_hamkq%usepaw==1) then
489      if (usecprj==1) then
490        cwaveprj_ptr => cwaveprj
491      else
492        ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor))
493        call pawcprj_alloc(cwaveprj_tmp,1,gs_hamkq%dimcprj)
494        cwaveprj_ptr => cwaveprj_tmp
495      end if
496      cpopt=-1+5*usecprj; paw_opt=1; if (sij_opt/=0) paw_opt=sij_opt+3
497 !    JLJ: BUG (wrong result) of H^(1) if stored cprj are used in PAW DDKs with nspinor==2 (==1 works fine).
498 !    To be debugged, if someone has time...
499      if(gs_hamkq%nspinor==2) cpopt=-1
500      if(associated(gs_hamkq%vectornd)) cpopt=-1
501      call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
502 &     paw_opt,signs,gs1c,tim_nonlop,cwave,gvnlx1_)
503      if (usecprj==0) then
504        call pawcprj_free(cwaveprj_tmp)
505        ABI_FREE(cwaveprj_tmp)
506      end if
507      nullify(cwaveprj_ptr)
508    else
509      cpopt=-1 ; paw_opt=0
510      call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
511 &     paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnlx1_)
512    end if
513 !DEBUG
514 !  gvnlx1_(:,:)=zero
515 !ENDDEBUG
516 
517 !  Electric field perturbation without Berry phase
518 !  -------------------------------------------
519  else if(ipert==natom+2 .and. &
520 &   (berryopt/=4 .and. berryopt/=6 .and. berryopt/=7 .and. &
521 &   berryopt/=14 .and. berryopt/=16 .and. berryopt/=17) .and.(optnl>0.or.sij_opt/=0))then
522 !  gvnlx1 was already initialized in the calling routine, by reading a ddk file
523 !  It contains |i du^(0)/dk_band>
524 
525    if (gs_hamkq%usepaw==1) then
526      if (usecprj==1) then
527        cwaveprj_ptr => cwaveprj
528      else
529        ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor))
530        call pawcprj_alloc(cwaveprj_tmp,1,gs_hamkq%dimcprj)
531        cwaveprj_ptr => cwaveprj_tmp
532      end if
533      if (opt_gvnlx1==2.and.optnl>=1) then
534 
535 !      PAW: Compute application of S^(0) to ddk WF
536        cpopt=-1 ; choice=1 ; paw_opt=3 ; signs=2
537        ABI_MALLOC(nonlop_out,(2,npw1*my_nspinor))
538        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,0,(/lambda/),mpi_enreg,1,nnlout,&
539 &       paw_opt,signs,nonlop_out,tim_nonlop,gvnlx1_,vectout_dum)
540 !$OMP PARALLEL DO
541        do ipw=1,npw1*my_nspinor
542          gvnlx1_(:,ipw)=nonlop_out(:,ipw)
543        end do
544 
545 !      PAW: Compute part of H^(1) due to derivative of S
546        cpopt=4*usecprj ; choice=51 ; paw_opt=3 ; signs=2
547        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
548 &       paw_opt,signs,nonlop_out,tim_nonlop,cwave,vectout_dum)
549        if(compute_conjugate) then
550 !$OMP PARALLEL DO
551          do ipw=1,npw1*my_nspinor ! Note the multiplication by -i
552            gvnlx1_(1,ipw)=gvnlx1_(1,ipw)+nonlop_out(2,ipw)
553            gvnlx1_(2,ipw)=gvnlx1_(2,ipw)-nonlop_out(1,ipw)
554          end do
555        else
556 !$OMP PARALLEL DO
557          do ipw=1,npw1*my_nspinor ! Note the multiplication by i
558            gvnlx1_(1,ipw)=gvnlx1_(1,ipw)-nonlop_out(2,ipw)
559            gvnlx1_(2,ipw)=gvnlx1_(2,ipw)+nonlop_out(1,ipw)
560          end do
561        end if
562 
563 !      PAW: Compute part of H^(1) due to derivative of electric field part of Dij
564        cpopt=2 ; choice=1 ; paw_opt=1 ; signs=2
565        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,0,(/lambda/),mpi_enreg,1,nnlout,&
566 &       paw_opt,signs,svectout_dum,tim_nonlop,cwave,nonlop_out,enl=rf_hamkq%e1kbfr)
567 !$OMP PARALLEL DO
568        do ipw=1,npw1*my_nspinor
569          gvnlx1_(:,ipw)=gvnlx1_(:,ipw)+nonlop_out(:,ipw)
570        end do
571        ABI_FREE(nonlop_out)
572 
573      end if ! opt_gvnlx1==2
574 
575 !    PAW: Compute derivatives due to part of D_ij^(1) depending on VHxc^(1)
576      if (optnl>=2) then
577        ABI_MALLOC(gvnl2,(2,npw1*my_nspinor))
578        cpopt=-1+3*usecprj;if (opt_gvnlx1==2) cpopt=2
579        choice=1 ; paw_opt=1 ; signs=2
580        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,0,(/lambda/),mpi_enreg,1,nnlout,&
581 &       paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl2,enl=rf_hamkq%e1kbsc)
582      end if
583 
584      if (sij_opt==1) then
585 !$OMP PARALLEL DO
586        do ipw=1,npw1*my_nspinor
587          gs1c(:,ipw)=zero
588        end do
589      end if
590      if (usecprj==0) then
591        call pawcprj_free(cwaveprj_tmp)
592        ABI_FREE(cwaveprj_tmp)
593      end if
594      nullify(cwaveprj_ptr)
595    end if  ! PAW
596 
597 !  Electric field perturbation with Berry phase
598 !  -------------------------------------------
599  else if(ipert==natom+2 .and. &
600 &   (berryopt==4 .or. berryopt==6 .or. berryopt==7 .or. &
601 &   berryopt==14 .or. berryopt==16 .or. berryopt==17 ) .and.(optnl>0.or.sij_opt/=0))then
602 
603    if (optnl>=1) then
604      do ipw=1,npw1*my_nspinor
605        gvnlx1_(1,ipw)=-grad_berry(2,ipw)
606        gvnlx1_(2,ipw)= grad_berry(1,ipw)
607      end do
608    end if
609    if (sij_opt==1) then
610 !$OMP PARALLEL DO
611      do ipw=1,npw1*my_nspinor
612        gs1c(:,ipw)=zero
613      end do
614    end if
615 
616 !  Strain perturbation
617 !  -------------------------------------------
618  else if ((ipert==natom+3.or.ipert==natom+4).and.(optnl>0.or.sij_opt/=0)) then
619 
620    istr=idir;if(ipert==natom+4) istr=istr+3
621 
622 !  PAW:
623    if (gs_hamkq%usepaw==1) then
624 
625      if (usecprj==1) then
626        cwaveprj_ptr => cwaveprj
627      else
628        ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor))
629        call pawcprj_alloc(cwaveprj_tmp,1,gs_hamkq%dimcprj)
630        cwaveprj_ptr => cwaveprj_tmp
631      end if
632 
633 !    1- Compute derivatives due to projectors |p_i>^(1)
634 !    All atoms contribute
635      cpopt=-1+5*usecprj ; choice=3 ; signs=2
636      paw_opt=1;if (sij_opt/=0) paw_opt=sij_opt+3
637      call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,istr,(/lambda/),mpi_enreg,1,nnlout,&
638 &     paw_opt,signs,gs1c,tim_nonlop,cwave,gvnlx1_)
639 
640 !    2- Compute derivatives due to frozen part of D_ij^(1) (independent of VHxc^(1))
641 !    All atoms contribute
642      if (optnl>=1) then
643        ABI_MALLOC(nonlop_out,(2,npw1*my_nspinor))
644        cpopt=1+3*usecprj ; choice=1 ; signs=2 ; paw_opt=1
645        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,istr,(/lambda/),mpi_enreg,1,nnlout,&
646 &       paw_opt,signs,svectout_dum,tim_nonlop,cwave,nonlop_out,enl=rf_hamkq%e1kbfr)
647 !$OMP PARALLEL DO
648        do ipw=1,npw1*my_nspinor
649          gvnlx1_(:,ipw)=gvnlx1_(:,ipw)+nonlop_out(:,ipw)
650        end do
651        ABI_FREE(nonlop_out)
652      end if
653 
654 !    3- Compute derivatives due to part of D_ij^(1) depending on VHxc^(1)
655 !    All atoms contribute
656      if (optnl>=2) then
657        ABI_MALLOC(gvnl2,(2,npw1*my_nspinor))
658        cpopt=4 ; choice=1 ; signs=2 ; paw_opt=1
659        call nonlop(choice,cpopt,cwaveprj_ptr,enlout,gs_hamkq,istr,(/lambda/),mpi_enreg,1,nnlout,&
660 &       paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl2,enl=rf_hamkq%e1kbsc)
661      end if
662 
663      if (usecprj==0) then
664        call pawcprj_free(cwaveprj_tmp)
665        ABI_FREE(cwaveprj_tmp)
666      end if
667      nullify(cwaveprj_ptr)
668 
669 !    Norm-conserving psps:
670    else
671 !    Compute only derivatives due to projectors |p_i>^(1)
672      choice=3 ; cpopt=-1 ; signs=2 ; paw_opt=0
673      call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,istr,(/lambda/),mpi_enreg,1,nnlout,&
674 &     paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnlx1_)
675      if (sij_opt==1) then
676 !$OMP PARALLEL DO
677        do ipw=1,npw1*my_nspinor
678          gs1c(:,ipw)=zero
679        end do
680      end if
681    end if
682 
683 !  No non-local part
684 !  -------------------------------------------
685  else if (usevnl>0.or.(sij_opt/=0)) then
686 
687    if (optnl>=1) then
688 !$OMP PARALLEL DO
689      do ipw=1,npw1*my_nspinor
690        gvnlx1_(:,ipw)=zero
691      end do
692    end if
693    if (sij_opt/=0) then
694 !$OMP PARALLEL DO
695      do ipw=1,npw1*my_nspinor
696        gs1c(:,ipw)=zero
697      end do
698    end if
699 
700  end if
701 
702 !======================================================================
703 !== Apply the 1st-order kinetic operator to the wavefunction
704 !== (add it to nl contribution)
705 !======================================================================
706 
707 !Phonon perturbation or Electric field perturbation
708 !-------------------------------------------
709 !No kinetic contribution
710 
711 !k-point perturbation or Strain perturbation
712 !-------------------------------------------
713 
714  usevnl2=allocated(gvnl2)
715  has_kin=(ipert==natom+1.or.ipert==natom+3.or.ipert==natom+4)
716  if (associated(gs_hamkq%kinpw_kp)) then
717    kinpw1 => gs_hamkq%kinpw_kp
718  else if (optnl>=1.or.usevnl2.or.has_kin) then
719    ABI_BUG('need kinpw1 allocated!')
720  end if
721  if (associated(rf_hamkq%dkinpw_k)) then
722    dkinpw => rf_hamkq%dkinpw_k
723  else if (has_kin) then
724    ABI_BUG('need dkinpw allocated!')
725  end if
726 
727  if (has_kin) then    ! This is the correct line
728 !DEBUG
729 !if (.false.)then
730 !ENDDEBUG
731 !  Remember that npw=npw1 for ddk perturbation
732    do ispinor=1,my_nspinor
733 !$OMP PARALLEL DO PRIVATE(ipw,ipws) SHARED(cwave,ispinor,gvnlx1_,dkinpw,kinpw1,npw,my_nspinor)
734      do ipw=1,npw
735        ipws=ipw+npw*(ispinor-1)
736        if(kinpw1(ipw)<huge(zero)*1.d-11)then
737          gvnlx1_(1,ipws)=gvnlx1_(1,ipws)+dkinpw(ipw)*cwave(1,ipws)
738          gvnlx1_(2,ipws)=gvnlx1_(2,ipws)+dkinpw(ipw)*cwave(2,ipws)
739        else
740          gvnlx1_(1,ipws)=zero
741          gvnlx1_(2,ipws)=zero
742        end if
743      end do
744    end do
745  end if
746 
747 !======================================================================
748 !== Apply the 1st-order nuclear dipole operator to the wavefunction
749 !== Only coded for DDK
750 !== (add it to nl contribution)
751 !======================================================================
752 
753  has_nd1=( (ipert .EQ. natom+1) .AND. ASSOCIATED(rf_hamkq%vectornd) )
754 
755  if (has_nd1) then
756    ABI_MALLOC(gh1ndc,(2,npw*my_nspinor))
757    ! this is hard coded for ndat = 1
758    call getgh1ndc(cwave,gh1ndc,gs_hamkq%gbound_k,gs_hamkq%istwf_k,gs_hamkq%kg_k,&
759      & gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,npw,gs_hamkq%nvloc,&
760      & gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,my_nspinor,rf_hamkq%vectornd,&
761      & gs_hamkq%gpu_option)
762    do ispinor=1,my_nspinor
763      do ipw=1,npw
764        ipws=ipw+npw*(ispinor-1)
765        gvnlx1_(1,ipws)=gvnlx1_(1,ipws)+gh1ndc(1,ipws)
766        gvnlx1_(2,ipws)=gvnlx1_(2,ipws)+gh1ndc(2,ipws)
767      end do
768    end do
769    ABI_FREE(gh1ndc)
770  end if
771 
772 !======================================================================
773 !== Apply the 1st-order mGGA operator to the wavefunction
774 !== Only coded for DDK
775 !== (add it to nl contribution)
776 !======================================================================
777 
778  has_mGGA1=( (ipert .EQ. natom+1) .AND. ASSOCIATED(rf_hamkq%vxctaulocal) )
779 
780  if (has_mGGA1) then
781    ABI_MALLOC(gh1c_mGGA,(2,npw*my_nspinor))
782    ! this is hard coded for ndat = 1
783    call getgh1c_mGGA(cwave,dkinpw,gs_hamkq%gbound_k,gh1c_mGGA,gs_hamkq%gprimd,idir,gs_hamkq%istwf_k,&
784         & gs_hamkq%kg_k,kinpw1,gs_hamkq%mgfft,mpi_enreg,my_nspinor,gs_hamkq%n4,gs_hamkq%n5,&
785         & gs_hamkq%n6,1,gs_hamkq%ngfft,npw,gs_hamkq%nvloc,rf_hamkq%vxctaulocal,&
786         & gs_hamkq%gpu_option)
787    do ispinor=1,my_nspinor
788      do ipw=1,npw
789        ipws=ipw+npw*(ispinor-1)
790        gvnlx1_(1,ipws)=gvnlx1_(1,ipws)+gh1c_mGGA(1,ipws)
791        gvnlx1_(2,ipws)=gvnlx1_(2,ipws)+gh1c_mGGA(2,ipws)
792      end do
793    end do
794    ABI_FREE(gh1c_mGGA)
795  end if
796 
797 !======================================================================
798 !== Sum contributions to get the application of H^(1) to the wf
799 !======================================================================
800 !Also filter the wavefunctions for large modified kinetic energy
801 
802 !Add non-local+kinetic to local part
803  if (optnl>=1.or.has_kin) then
804    do ispinor=1,my_nspinor
805      ipws=(ispinor-1)*npw1
806 !$OMP PARALLEL DO PRIVATE(ipw) SHARED(gh1c,gvnlx1_,kinpw1,ipws,npw1)
807      do ipw=1+ipws,npw1+ipws
808        if(kinpw1(ipw-ipws)<huge(zero)*1.d-11)then
809          gh1c(1,ipw)=gh1c(1,ipw)+gvnlx1_(1,ipw)
810          gh1c(2,ipw)=gh1c(2,ipw)+gvnlx1_(2,ipw)
811        else
812          gh1c(1,ipw)=zero
813          gh1c(2,ipw)=zero
814        end if
815      end do
816    end do
817  end if
818 
819 !PAW: add non-local part due to first order change of VHxc
820  if (usevnl2) then
821    do ispinor=1,my_nspinor
822      ipws=(ispinor-1)*npw1
823 !$OMP PARALLEL DO PRIVATE(ipw) SHARED(gh1c,gvnl2,kinpw1,ipws,npw1)
824      do ipw=1+ipws,npw1+ipws
825        if(kinpw1(ipw-ipws)<huge(zero)*1.d-11)then
826          gh1c(1,ipw)=gh1c(1,ipw)+gvnl2(1,ipw)
827          gh1c(2,ipw)=gh1c(2,ipw)+gvnl2(2,ipw)
828        end if
829      end do
830    end do
831    ABI_FREE(gvnl2)
832  end if
833 
834  if (usevnl==1) then
835    nullify(gvnlx1_)
836  else
837    ABI_FREE(gvnlx1_)
838  end if
839 
840  call timab(196+tim_getgh1c,2,tsec)
841 
842  DBG_EXIT("COLL")
843 
844 end subroutine getgh1c

ABINIT/getgh1c_mGGA [ Functions ]

[ Top ] [ Functions ]

NAME

 getgh1c_mGGA

FUNCTION

 Compute first order metaGGA contribution to <G|H|C> for input vector |C> expressed in reciprocal space.
 ONLY FOR DDK PERTURBATION

INPUTS

OUTPUT

  gh1c_mGGA(2,npw_k*my_nspinor*ndat)=metaGGA contribution to <G|H1|C>

SIDE EFFECTS

SOURCE

2008 subroutine getgh1c_mGGA(cwavein,dkinpw,gbound_k,gh1c_mGGA,gprimd,idir,istwf_k,kg_k,&
2009      & kinpw1,mgfft,mpi_enreg,my_nspinor,n4,n5,n6,ndat,ngfft,npw_k,nvloc,vxctaulocal,gpu_option)
2010 
2011 !Arguments ------------------------------------
2012 !scalars
2013  integer,intent(in) :: idir,istwf_k,mgfft,my_nspinor,n4,n5,n6,ndat,npw_k,nvloc
2014  integer,intent(in),optional :: gpu_option
2015  type(MPI_type),intent(in) :: mpi_enreg
2016 !arrays
2017  integer,intent(in) :: gbound_k(2*mgfft+4),kg_k(3,npw_k),ngfft(18)
2018  real(dp),intent(in) :: gprimd(3,3)
2019  real(dp),intent(inout) :: cwavein(2,npw_k*my_nspinor*ndat)
2020  real(dp),intent(inout) :: gh1c_mGGA(2,npw_k*my_nspinor*ndat)
2021  real(dp),intent(inout) :: vxctaulocal(n4,n5,n6,nvloc,4)
2022  real(dp),pointer,intent(in) :: dkinpw(:),kinpw1(:)
2023  
2024 !Local variables-------------------------------
2025  !scalars
2026  integer :: idat,ii,ipw,nspinortot,shift,gpu_option_
2027  integer,parameter :: tim_fourwf=1
2028  real(dp) :: weight=one
2029  logical :: nspinor1TreatedByThisProc,nspinor2TreatedByThisProc
2030  !arrays
2031  real(dp),allocatable :: cwavein1(:,:),cwavein2(:,:),dgcwavef(:,:)
2032  real(dp),allocatable :: ghc1(:,:),ghc2(:,:),work(:,:,:,:)
2033 
2034  if(present(gpu_option)) then
2035     gpu_option_=gpu_option
2036  else
2037     gpu_option_=0
2038  end if
2039   
2040  gh1c_mGGA(:,:)=zero
2041  if (nvloc/=1) return
2042 
2043  nspinortot=min(2,(1+mpi_enreg%paral_spinor)*my_nspinor)
2044  if (mpi_enreg%paral_spinor==0) then
2045    shift=npw_k
2046    nspinor1TreatedByThisProc=.true.
2047    nspinor2TreatedByThisProc=(nspinortot==2)
2048  else
2049    shift=0
2050    nspinor1TreatedByThisProc=(mpi_enreg%me_spinor==0)
2051    nspinor2TreatedByThisProc=(mpi_enreg%me_spinor==1)
2052  end if
2053 
2054  ABI_MALLOC(work,(2,n4,n5,n6*ndat))
2055 
2056  if (nspinortot==1) then
2057 
2058     ABI_MALLOC(ghc1,(2,npw_k*ndat))
2059     ABI_MALLOC(ghc2,(2,npw_k*ndat))
2060     ABI_MALLOC(dgcwavef,(2,npw_k*ndat))
2061 
2062     ! From -1/2 (grad vxctau) \cdot (grad \psi) =
2063     ! -1/2 (grad vxctau)\cdot(2\pi i (k + G)\psi), the
2064     do ii=1,3
2065       dgcwavef = zero
2066       do idat=1,ndat
2067         do ipw=1,npw_k
2068           dgcwavef(1,ipw+(idat-1)*npw_k)= cwavein(2,ipw+(idat-1)*npw_k)*two_pi*gprimd(ii,idir)
2069           dgcwavef(2,ipw+(idat-1)*npw_k)=-cwavein(1,ipw+(idat-1)*npw_k)*two_pi*gprimd(ii,idir)
2070         end do
2071       end do
2072       call fourwf(1,vxctaulocal(:,:,:,:,1+ii),dgcwavef,ghc1,work,gbound_k,gbound_k,&
2073         & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
2074         & tim_fourwf,weight,weight,gpu_option=gpu_option_)
2075       gh1c_mGGA(:,:) = gh1c_mGGA(:,:) - half*ghc1
2076     end do ! ii
2077 
2078     ! From -1/2 vxctau (grad . grad \psi), the k derivative is
2079     ! vxctau \times dkinpw_dir * \psi
2080     do ipw=1,npw_k
2081       if(kinpw1(ipw)<huge(zero)*1.d-11)then
2082         ghc1(:,ipw)=dkinpw(ipw)*cwavein(:,ipw)
2083       else
2084         ghc1(:,ipw) = zero
2085       end if
2086     end do
2087     call fourwf(1,vxctaulocal(:,:,:,:,1),ghc1,ghc2,work,gbound_k,gbound_k,&
2088       & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
2089       & tim_fourwf,weight,weight,gpu_option=gpu_option_)
2090 
2091     gh1c_mGGA = gh1c_mGGA + ghc2
2092 
2093     ! JWZ debug
2094     ! gh1c_mGGA = zero
2095 
2096     ABI_FREE(ghc1)
2097     ABI_FREE(ghc2)
2098     ABI_FREE(dgcwavef)
2099 
2100  else ! nspinortot==2
2101 
2102    ABI_MALLOC(cwavein1,(2,npw_k*ndat))
2103    ABI_MALLOC(cwavein2,(2,npw_k*ndat))
2104    do idat=1,ndat
2105      do ipw=1,npw_k
2106        cwavein1(1:2,ipw+(idat-1)*npw_k)=cwavein(1:2,ipw+(idat-1)*my_nspinor*npw_k)
2107        cwavein2(1:2,ipw+(idat-1)*npw_k)=cwavein(1:2,ipw+(idat-1)*my_nspinor*npw_k+shift)
2108      end do
2109    end do
2110 
2111    ABI_MALLOC(ghc1,(2,npw_k*ndat))
2112    ABI_MALLOC(ghc2,(2,npw_k*ndat))
2113 
2114    if (nspinor1TreatedByThisProc) then
2115 
2116       ! call fourwf(1,vxctaulocal(:,:,:,:,1+idir),cwavein1,ghc1,work,gbound_k,gbound_k,&
2117       !   & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
2118       !   & tim_fourwf,weight,weight,use_gpu_cuda=use_gpu_cuda_)
2119 
2120       ! ! scale by -1/2 * 2\pi i = -i \pi
2121       ! do idat = 1, ndat
2122       !   do ipw = 1, npw_k
2123       !     gh1c_mGGA(1,ipw+(idat-1)*npw_k) =  pi*ghc1(2,ipw+(idat-1)*npw_k)
2124       !     gh1c_mGGA(2,ipw+(idat-1)*npw_k) = -pi*ghc1(1,ipw+(idat-1)*npw_k)
2125       !   end do
2126       ! end do
2127 
2128       ! From -1/2 vxctau (grad . grad \psi), the k derivative is
2129       ! vxctau \times dkinpw_dir * \psi
2130       do idat = 1, ndat
2131         do ipw=1,npw_k
2132           if(kinpw1(ipw)<huge(zero)*1.d-11)then
2133             ghc1(1,ipw)=dkinpw(ipw)*cwavein1(1,ipw+(idat-1)*npw_k)
2134             ghc1(2,ipw)=dkinpw(ipw)*cwavein1(2,ipw+(idat-1)*npw_k)
2135           else
2136             ghc1(:,ipw+(idat-1)*npw_k) = zero
2137           end if
2138         end do
2139       end do
2140    
2141       call fourwf(1,vxctaulocal(:,:,:,:,1),ghc1,ghc2,work,gbound_k,gbound_k,&
2142         & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
2143         & tim_fourwf,weight,weight,gpu_option=gpu_option_)
2144 
2145       do idat = 1, ndat
2146         do ipw = 1, npw_k
2147            gh1c_mGGA(:,ipw+(idat-1)*npw_k) =  gh1c_mGGA(:,ipw+(idat-1)*npw_k) + &
2148                 & ghc2(:,ipw+(idat-1)*npw_k)
2149         end do
2150       end do
2151 
2152     end if ! end spinor 1
2153 
2154     if (nspinor2TreatedByThisProc) then
2155 
2156       ABI_MALLOC(ghc2,(2,npw_k*ndat))
2157 
2158       ! call fourwf(1,vxctaulocal(:,:,:,:,1+idir),cwavein2,ghc2,work,gbound_k,gbound_k,&
2159       !   & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
2160       !   & tim_fourwf,weight,weight,use_gpu_cuda=use_gpu_cuda_)
2161 
2162       ! ! scale by -1/2 * 2\pi i = -i \pi
2163       ! do idat = 1, ndat
2164       !   do ipw = 1, npw_k
2165       !     gh1c_mGGA(1,ipw+(idat-1)*npw_k) =  pi*ghc2(2,ipw+(idat-1)*npw_k)
2166       !     gh1c_mGGA(2,ipw+(idat-1)*npw_k) = -pi*ghc2(1,ipw+(idat-1)*npw_k)
2167       !   end do
2168       ! end do
2169 
2170       ! From -1/2 vxctau (grad . grad \psi), the k derivative is
2171       ! vxctau \times dkinpw_dir * \psi
2172       do idat = 1, ndat
2173         do ipw=1,npw_k
2174           if(kinpw1(ipw)<huge(zero)*1.d-11)then
2175             ghc1(1,ipw)=dkinpw(ipw)*cwavein2(1,ipw+(idat-1)*npw_k)
2176             ghc1(2,ipw)=dkinpw(ipw)*cwavein2(2,ipw+(idat-1)*npw_k)
2177           else
2178             ghc1(:,ipw+(idat-1)*npw_k) = zero
2179           end if
2180         end do
2181       end do
2182    
2183       call fourwf(1,vxctaulocal(:,:,:,:,1),ghc1,ghc2,work,gbound_k,gbound_k,&
2184         & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
2185         & tim_fourwf,weight,weight,gpu_option=gpu_option_)
2186 
2187       do idat = 1, ndat
2188         do ipw = 1, npw_k
2189            gh1c_mGGA(:,ipw+(idat-1)*npw_k) =  gh1c_mGGA(:,ipw+(idat-1)*npw_k) + &
2190                 & ghc2(:,ipw+(idat-1)*npw_k)
2191         end do
2192       end do
2193 
2194     end if ! end spinor 2
2195 
2196     ABI_FREE(ghc1)
2197     ABI_FREE(ghc2)
2198 
2199     ABI_FREE(cwavein1)
2200     ABI_FREE(cwavein2)
2201 
2202  end if ! nspinortot
2203 
2204  ABI_FREE(work)
2205 
2206 end subroutine getgh1c_mGGA

ABINIT/getgh1dqc [ Functions ]

[ Top ] [ Functions ]

NAME

  getgh1dqc

FUNCTION

 Computes <G|dH^(1)/dq_{gamma}|C> or <G|d^2H^(1)/dq_{gamma}dq_{delta}|C>
 for input vector |C> expressed in reciprocal space.
 dH^(1)/dq_{gamma} and d^2H^(1)/dq_{gamma}dq_{delta} are the first
 and second q-gradient (at q=0) of the 1st-order perturbed Hamiltonian.
 The first (second) derivative direction is inferred from idir (qdir1).

INPUTS

  cwave(2,npw*nspinor)=input wavefunction, in reciprocal space
  cwaveprj(natom,nspinor*usecprj)=<p_lmn|C> coefficients for wavefunction |C> (and 1st derivatives)
     if not allocated or size=0, they are locally computed (and not sotred)
  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q
  idir=first index of the perturbation
  ipert=type of the perturbation
  mpi_enreg=information about MPI parallelization
  npw=number of planewaves in basis sphere at given k.
  npw1=number of planewaves in basis sphere at k+q
  optlocal=0: local part of H^(1) is not computed
           1: local part of H^(1) is computed in gvloc1dqc
  optnl=0: non-local part of H^(1) is not computed
        1: non-local part of H^(1) depending on VHxc^(1) is not computed in gvloc1dqc
        2: non-local part of H^(1) is totally computed in gvloc1dqc
  qdir1= direction of the 1st q-gradient
  rf_hamkq <type(rf_hamiltonian_type)>=all data for the 1st-order Hamiltonian at k,k+q
  qdir2= (optional) direction of the 2nd q-gradient

OUTPUT

  gh1dqc(2,npw1*nspinor)= <G|dH^(1)/dq_{\gamma}|C> on the k+q sphere
  gvloc1dqc(2,npw1*nspinor)= local potential part of gh1dqc
  gvnl1dqc(2,npw1*nspinor)= non local potential part of gh1dqc

SIDE EFFECTS

NOTES

  Currently two Hamiltonian gradients at (q=0) are implemented:
     ipert<=natom ->              first q-derivative along reduced coordinates directions
                                  of the atomic displacement perturbation hamiltonian
     ipert==natom+3 or natom+4 -> second q-derivative along cartesian coordinates
                                  of the metric perturbation hamiltonian.
                                  Which is equivalent (except for an i factor) to the first
                                  q-derivative along cartesian coordinates of the strain
                                  perturbation hamiltonian.

SOURCE

1438 subroutine getgh1dqc(cwave,cwaveprj,gh1dqc,gvloc1dqc,gvnl1dqc,gs_hamkq,&
1439 &          idir,ipert,mpi_enreg,optlocal,optnl,qdir1,rf_hamkq,&
1440 &          qdir2)                                                        !optional
1441 
1442 !Arguments ------------------------------------
1443 !scalars
1444  integer,intent(in) :: idir,ipert,optlocal,optnl,qdir1
1445  integer,intent(in),optional :: qdir2
1446  type(MPI_type),intent(in) :: mpi_enreg
1447  type(gs_hamiltonian_type),intent(inout),target :: gs_hamkq
1448  type(rf_hamiltonian_type),intent(inout),target :: rf_hamkq
1449 
1450 !arrays
1451  real(dp),intent(inout) :: cwave(2,gs_hamkq%npw_k*gs_hamkq%nspinor)
1452  real(dp),intent(out) :: gh1dqc(2,gs_hamkq%npw_kp*gs_hamkq%nspinor)
1453  real(dp),intent(out) :: gvloc1dqc(2,gs_hamkq%npw_kp*gs_hamkq%nspinor)
1454  real(dp),intent(out) :: gvnl1dqc(2,gs_hamkq%npw_kp*gs_hamkq%nspinor)
1455  real(dp),pointer :: dqdqkinpw(:),kinpw1(:)
1456  type(pawcprj_type),intent(inout),target :: cwaveprj(:,:)
1457 
1458 !Local variables-------------------------------
1459 !scalars
1460  integer :: choice,cpopt,iidir,ipw,ipws,ispinor,my_nspinor,natom,nnlout
1461  integer :: npw,npw1,paw_opt,signs,tim_fourwf,tim_nonlop
1462  logical :: has_kin
1463  character(len=500) :: msg
1464  real(dp) :: lambda,weight
1465 
1466 !arrays
1467  integer,parameter :: ngamma(3,3)=reshape((/1,6,5,9,2,4,8,7,3/),(/3,3/))
1468  real(dp) :: enlout(1),svectout_dum(1,1)
1469  real(dp),ABI_CONTIGUOUS pointer :: gvnl1dqc_(:,:)
1470  real(dp), allocatable :: work(:,:,:,:)
1471 
1472 ! *************************************************************************
1473 
1474  DBG_ENTER("COLL")
1475 
1476 !======================================================================
1477 !== Initialisations and compatibility tests
1478 !======================================================================
1479 
1480  npw  =gs_hamkq%npw_k
1481  npw1 =gs_hamkq%npw_kp
1482  natom=gs_hamkq%natom
1483 
1484 !Compatibility tests
1485  if (mpi_enreg%paral_spinor==1) then
1486    msg='Not compatible with parallelization over spinorial components !'
1487    ABI_BUG(msg)
1488  end if
1489 
1490 !Check sizes
1491  my_nspinor=max(1,gs_hamkq%nspinor/mpi_enreg%nproc_spinor)
1492  if (size(cwave)<2*npw*my_nspinor) then
1493    msg='wrong size for cwave!'
1494    ABI_BUG(msg)
1495  end if
1496  if (size(gh1dqc)<2*npw1*my_nspinor) then
1497    msg='wrong size for gh1dqc!'
1498    ABI_BUG(msg)
1499  end if
1500 
1501 !=============================================================================
1502 !== Apply the q-gradients of the 1st-order local potential to the wavefunction
1503 !=============================================================================
1504 
1505 !Phonon and metric (strain) perturbation
1506  if (ipert<=natom+5.and.ipert/=natom+1.and.ipert/=natom+2.and.optlocal>0) then
1507 
1508    ABI_MALLOC(work,(2,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6))
1509 
1510    weight=one ; tim_fourwf=4
1511    call fourwf(rf_hamkq%cplex,rf_hamkq%vlocal1,cwave,gvloc1dqc,work,gs_hamkq%gbound_k,gs_hamkq%gbound_kp,&
1512  & gs_hamkq%istwf_k,gs_hamkq%kg_k,gs_hamkq%kg_kp,gs_hamkq%mgfft,mpi_enreg,1,gs_hamkq%ngfft,&
1513  & npw,npw1,gs_hamkq%n4,gs_hamkq%n5,gs_hamkq%n6,2,tim_fourwf,weight,weight,&
1514  & gpu_option=gs_hamkq%gpu_option)
1515 
1516    ABI_FREE(work)
1517 
1518  else
1519 
1520 !$OMP PARALLEL DO
1521    do ipw=1,npw1*my_nspinor
1522      gvloc1dqc(:,ipw)=zero
1523    end do
1524 
1525  end if
1526 
1527 !================================================================================
1528 !== Apply the q-gradients of the 1st-order non-local potential to the wavefunction
1529 !================================================================================
1530 
1531 !Initializations
1532 lambda=zero
1533 nnlout=1
1534 tim_nonlop=0
1535 
1536 !Allocations
1537 ABI_MALLOC(gvnl1dqc_,(2,npw1*my_nspinor))
1538 
1539 !Phonon perturbation
1540 !-------------------------------------------
1541  !1st q-gradient
1542  if (ipert<=natom.and..not.present(qdir2).and.optnl>0) then
1543    cpopt=-1 ; choice=22 ; signs=2 ; paw_opt=0
1544    call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
1545 &  paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl1dqc_,iatom_only=ipert,qdir=qdir1)
1546 
1547 !$OMP PARALLEL DO
1548    do ipw=1,npw1*my_nspinor
1549      gvnl1dqc(1,ipw)=gvnl1dqc_(1,ipw)
1550      gvnl1dqc(2,ipw)=gvnl1dqc_(2,ipw)
1551    end do
1552 
1553  !2nd q-gradient
1554  else if (ipert<=natom.and.present(qdir2).and.optnl>0) then
1555    iidir=ngamma(idir,qdir2)
1556    cpopt=-1 ; choice=25 ; signs=2 ; paw_opt=0
1557    call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,iidir,(/lambda/),mpi_enreg,1,nnlout,&
1558 &  paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl1dqc_,iatom_only=ipert,qdir=qdir1)
1559 
1560 !$OMP PARALLEL DO
1561    do ipw=1,npw1*my_nspinor
1562      gvnl1dqc(1,ipw)=gvnl1dqc_(1,ipw)
1563      gvnl1dqc(2,ipw)=gvnl1dqc_(2,ipw)
1564    end do
1565 
1566 !Metric (strain) perturbation
1567 !-------------------------------------------
1568  else if ((ipert==natom+3.or.ipert==natom+4).and.optnl>0) then
1569    cpopt=-1 ; choice=33 ; signs=2 ; paw_opt=0
1570    call nonlop(choice,cpopt,cwaveprj,enlout,gs_hamkq,idir,(/lambda/),mpi_enreg,1,nnlout,&
1571 &  paw_opt,signs,svectout_dum,tim_nonlop,cwave,gvnl1dqc_,qdir=qdir1)
1572 
1573 !$OMP PARALLEL DO
1574    do ipw=1,npw1*my_nspinor
1575      gvnl1dqc(1,ipw)=gvnl1dqc_(1,ipw)
1576      gvnl1dqc(2,ipw)=gvnl1dqc_(2,ipw)
1577    end do
1578 
1579  else
1580 
1581 !$OMP PARALLEL DO
1582    do ipw=1,npw1*my_nspinor
1583      gvnl1dqc(:,ipw)=zero
1584    end do
1585 
1586  end if
1587 
1588 !==============================================================================
1589 !== Apply the q-gradients of the 1st-order kinetic operator to the wavefunction
1590 !== (add it to nl contribution)
1591 !==============================================================================
1592 
1593 !Strain (metric) perturbation
1594 !-------------------------------------------
1595  has_kin=(ipert==natom+3.or.ipert==natom+4)
1596  if (associated(gs_hamkq%kinpw_kp)) then
1597    kinpw1 => gs_hamkq%kinpw_kp
1598  else if (has_kin) then
1599    msg='need kinpw1 allocated!'
1600    ABI_BUG(msg)
1601  end if
1602  if (associated(rf_hamkq%dkinpw_k)) then
1603    dqdqkinpw => rf_hamkq%dkinpw_k
1604  else if (has_kin) then
1605    msg='need dqdqkinpw allocated!'
1606    ABI_BUG(msg)
1607  end if
1608 
1609  if (has_kin) then
1610 !  Remember that npw=npw1
1611    do ispinor=1,my_nspinor
1612 !$OMP PARALLEL DO PRIVATE(ipw,ipws) SHARED(cwave,ispinor,gvnl1dqc,dqdqkinpw,kinpw1,npw,my_nspinor)
1613      do ipw=1,npw
1614        ipws=ipw+npw*(ispinor-1)
1615        if(kinpw1(ipw)<huge(zero)*1.d-11)then
1616          gvnl1dqc(1,ipws)=gvnl1dqc(1,ipws)+dqdqkinpw(ipw)*cwave(1,ipws)
1617          gvnl1dqc(2,ipws)=gvnl1dqc(2,ipws)+dqdqkinpw(ipw)*cwave(2,ipws)
1618        else
1619          gvnl1dqc(1,ipws)=zero
1620          gvnl1dqc(2,ipws)=zero
1621        end if
1622      end do
1623    end do
1624  end if
1625 
1626 !===================================================================================
1627 !== Sum contributions to get the application of dH^(1)/dq or d^2H^(1)/dqdq to the wf
1628 !===================================================================================
1629 
1630  do ispinor=1,my_nspinor
1631    ipws=(ispinor-1)*npw1
1632 !$OMP PARALLEL DO PRIVATE(ipw) SHARED(gh1dqc,gvnl1dqc,kinpw1,ipws,npw1)
1633    do ipw=1+ipws,npw1+ipws
1634      if(kinpw1(ipw-ipws)<huge(zero)*1.d-11)then
1635        gh1dqc(1,ipw)=gvloc1dqc(1,ipw)+gvnl1dqc(1,ipw)
1636        gh1dqc(2,ipw)=gvloc1dqc(2,ipw)+gvnl1dqc(2,ipw)
1637      else
1638        gh1dqc(1,ipw)=zero
1639        gh1dqc(2,ipw)=zero
1640      end if
1641    end do
1642  end do
1643 
1644  ABI_FREE(gvnl1dqc_)
1645  DBG_EXIT("COLL")
1646 
1647 end subroutine getgh1dqc

ABINIT/getgh1ndc [ Functions ]

[ Top ] [ Functions ]

NAME

 getgh1ndc

FUNCTION

 Compute 1st order magnetic nuclear dipole moment contribution to <G|H|C>
 for input vector |C> expressed in reciprocal space.
 Only for DDK perturbation

INPUTS

OUTPUT

  gh1ndc(2,npw_k*my_nspinor*ndat)=1st order A.p contribution to <G|H|C> for array of nuclear dipoles

SIDE EFFECTS

NOTES

 This codes only the DDK response for A.p, so effectively A_ipert|C>. The nuclear dipole Hamiltonian
 (to first order in the nuclear dipole strength) is A.p where in atomic units
 A.p=\alpha^2 m x (r-R)/(r-R)^3 . p. Here the components of A have been precomputed in real space
 by make_vectornd. The first-order DDK contribution is d A.p/dk = A_idir where idir is the
 direction of the DDK perturbation, or 2\pi A_idir when k is given in reduced coords as is usual

SOURCE

1877 subroutine getgh1ndc(cwavein,gh1ndc,gbound_k,istwf_k,kg_k,mgfft,mpi_enreg,&
1878 &                      ndat,ngfft,npw_k,nvloc,n4,n5,n6,my_nspinor,vectornd,gpu_option)
1879 
1880 !Arguments ------------------------------------
1881 !scalars
1882  integer,intent(in) :: istwf_k,mgfft,my_nspinor,ndat,npw_k,nvloc,n4,n5,n6,gpu_option
1883  type(MPI_type),intent(in) :: mpi_enreg
1884 !arrays
1885  integer,intent(in) :: gbound_k(2*mgfft+4),kg_k(3,npw_k),ngfft(18)
1886  real(dp),intent(inout) :: cwavein(2,npw_k*my_nspinor*ndat)
1887  real(dp),intent(inout) :: gh1ndc(2,npw_k*my_nspinor*ndat)
1888  real(dp),intent(inout) :: vectornd(n4,n5,n6,nvloc)
1889 
1890 !Local variables-------------------------------
1891 !scalars
1892  integer,parameter :: tim_fourwf=1
1893  integer :: idat,ipw,nspinortot,shift
1894  logical :: nspinor1TreatedByThisProc,nspinor2TreatedByThisProc
1895  real(dp) :: weight=one
1896  !arrays
1897  real(dp),allocatable :: cwavein1(:,:),cwavein2(:,:)
1898  real(dp),allocatable :: ghc1(:,:),ghc2(:,:)
1899  real(dp),allocatable :: work(:,:,:,:)
1900 
1901 ! *********************************************************************
1902 
1903  gh1ndc(:,:)=zero
1904  if (nvloc/=1) return
1905 
1906  nspinortot=min(2,(1+mpi_enreg%paral_spinor)*my_nspinor)
1907  if (mpi_enreg%paral_spinor==0) then
1908    shift=npw_k
1909    nspinor1TreatedByThisProc=.true.
1910    nspinor2TreatedByThisProc=(nspinortot==2)
1911  else
1912    shift=0
1913    nspinor1TreatedByThisProc=(mpi_enreg%me_spinor==0)
1914    nspinor2TreatedByThisProc=(mpi_enreg%me_spinor==1)
1915  end if
1916 
1917  ABI_MALLOC(work,(2,n4,n5,n6*ndat))
1918 
1919  if (nspinortot==1) then
1920 
1921     ABI_MALLOC(ghc1,(2,npw_k*ndat))
1922 
1923     ! apply vector potential in direction ipert to input wavefunction
1924     call fourwf(1,vectornd,cwavein,ghc1,work,gbound_k,gbound_k,&
1925       & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
1926       & tim_fourwf,weight,weight,gpu_option=gpu_option)
1927 
1928     ! scale by 2\pi\alpha^2
1929     gh1ndc=two_pi*FineStructureConstant2*ghc1
1930 
1931     ABI_FREE(ghc1)
1932 
1933  else ! nspinortot==2
1934 
1935     ABI_MALLOC(cwavein1,(2,npw_k*ndat))
1936     ABI_MALLOC(cwavein2,(2,npw_k*ndat))
1937     do idat=1,ndat
1938        do ipw=1,npw_k
1939           cwavein1(1:2,ipw+(idat-1)*npw_k)=cwavein(1:2,ipw+(idat-1)*my_nspinor*npw_k)
1940           cwavein2(1:2,ipw+(idat-1)*npw_k)=cwavein(1:2,ipw+(idat-1)*my_nspinor*npw_k+shift)
1941        end do
1942     end do
1943 
1944     if (nspinor1TreatedByThisProc) then
1945 
1946        ABI_MALLOC(ghc1,(2,npw_k*ndat))
1947 
1948        call fourwf(1,vectornd,cwavein1,ghc1,work,gbound_k,gbound_k,&
1949          & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
1950          & tim_fourwf,weight,weight,gpu_option=gpu_option)
1951 
1952        do idat=1,ndat
1953          do ipw=1,npw_k
1954            gh1ndc(1:2,ipw+(idat-1)*npw_k)=two_pi*FineStructureConstant2*ghc1(1:2,ipw+(idat-1)*npw_k)
1955          end do
1956        end do
1957 
1958        ABI_FREE(ghc1)
1959 
1960     end if ! end spinor 1
1961 
1962     if (nspinor2TreatedByThisProc) then
1963 
1964        ABI_MALLOC(ghc2,(2,npw_k*ndat))
1965 
1966        call fourwf(1,vectornd,cwavein2,ghc2,work,gbound_k,gbound_k,&
1967          & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,ndat,ngfft,npw_k,npw_k,n4,n5,n6,2,&
1968          & tim_fourwf,weight,weight,gpu_option=gpu_option)
1969 
1970        do idat=1,ndat
1971          do ipw=1,npw_k
1972            gh1ndc(1:2,ipw+(idat-1)*npw_k+shift)=two_pi*FineStructureConstant2*ghc2(1:2,ipw+(idat-1)*npw_k)
1973          end do
1974        end do
1975 
1976        ABI_FREE(ghc2)
1977 
1978     end if ! end spinor 2
1979 
1980     ABI_FREE(cwavein1)
1981     ABI_FREE(cwavein2)
1982 
1983  end if ! nspinortot
1984 
1985  ABI_FREE(work)
1986 
1987 end subroutine getgh1ndc

ABINIT/m_getgh1c [ Modules ]

[ Top ] [ Modules ]

NAME

  m_getgh1c

FUNCTION

COPYRIGHT

  Copyright (C) 1998-2024 ABINIT group (XG, DRH, MT, SPr)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .

SOURCE

16 #if defined HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include "abi_common.h"
21 
22 module m_getgh1c
23 
24  use defs_basis
25  use m_abicore
26  use m_errors
27  use m_dtset
28  use m_xmpi
29 
30  use defs_abitypes, only : MPI_type
31  use defs_datatypes, only : pseudopotential_type
32  use m_time,        only : timab
33  use m_pawcprj,     only : pawcprj_type, pawcprj_alloc, pawcprj_free, &
34       & pawcprj_copy, pawcprj_lincom, pawcprj_axpby, pawcprj_mpi_sum
35  use m_kg,          only : kpgstr, mkkin, mkkpg, mkkin_metdqdq
36  use m_mkffnl,      only : mkffnl
37  use m_pawfgr,      only : pawfgr_type
38  use m_fft,         only : fftpac, fourwf
39  use m_hamiltonian, only : gs_hamiltonian_type, rf_hamiltonian_type
40  use m_cgtools,          only : projbd
41  use m_nonlop,           only : nonlop
42  use m_fourier_interpol, only : transgrid
43 
44  implicit none
45 
46  private

m_hamiltonian/getgh1c_setup [ Functions ]

[ Top ] [ m_hamiltonian ] [ Functions ]

NAME

  getgh1c_setup

FUNCTION

INPUTS

OUTPUT

SOURCE

 968 subroutine getgh1c_setup(gs_hamkq, rf_hamkq, dtset, psps, kpoint, kpq, idir, ipert,&              ! In
 969                          natom, rmet, gprimd, gmet, istwf_k, npw_k, npw1_k, &                     ! In
 970                          useylmgr1, kg_k, ylm_k, kg1_k, ylm1_k, ylmgr1_k, &                       ! In
 971                          dkinpw, nkpg, nkpg1, kpg_k, kpg1_k, kinpw1, ffnlk, ffnl1, ph3d, ph3d1,&  ! Out
 972                          ddkinpw, dkinpw2, rf_hamk_dir2, ffnl1_test, &                            ! Optional
 973                          reuse_kpg_k, reuse_kpg1_k, reuse_ffnlk, reuse_ffnl1)                     ! Optional
 974 
 975 !Arguments ------------------------------------
 976 !scalars
 977  integer,intent(in) :: idir,ipert,istwf_k,npw_k,npw1_k,natom,useylmgr1
 978  integer,intent(out) :: nkpg,nkpg1
 979  type(gs_hamiltonian_type),intent(inout) :: gs_hamkq
 980  type(rf_hamiltonian_type),intent(inout) :: rf_hamkq
 981  type(rf_hamiltonian_type),intent(inout),optional :: rf_hamk_dir2
 982  type(dataset_type),intent(in) :: dtset
 983  type(pseudopotential_type),intent(in) :: psps
 984  integer,optional,intent(in) :: reuse_kpg_k, reuse_kpg1_k, reuse_ffnlk, reuse_ffnl1
 985 !arrays
 986  integer,intent(in) :: kg_k(3,npw_k),kg1_k(3,npw1_k)
 987  real(dp),intent(in) :: kpoint(3),kpq(3),gmet(3,3),gprimd(3,3),rmet(3,3)
 988  real(dp),intent(in) :: ylm_k(npw_k,psps%mpsang*psps%mpsang*psps%useylm)
 989  real(dp),intent(in) :: ylmgr1_k(npw1_k,3+6*((ipert-natom)/10),psps%mpsang*psps%mpsang*psps%useylm*useylmgr1)
 990  real(dp),intent(in) :: ylm1_k(npw1_k,psps%mpsang*psps%mpsang*psps%useylm)
 991  real(dp),allocatable,intent(out) :: dkinpw(:),kinpw1(:)
 992  real(dp),allocatable,intent(inout) :: ffnlk(:,:,:,:),ffnl1(:,:,:,:), kpg_k(:,:), kpg1_k(:,:)
 993  real(dp),allocatable,intent(out),optional :: dkinpw2(:),ddkinpw(:),ffnl1_test(:,:,:,:)
 994  real(dp),allocatable,intent(out) :: ph3d(:,:,:),ph3d1(:,:,:)
 995 
 996 !Local variables-------------------------------
 997 !scalars
 998  integer :: dimffnl1,dimffnlk,ider,idir0,idir1,idir2,istr,ntypat,print_info
 999  integer :: reuse_ffnlk_, reuse_ffnl1_, reuse_kpg_k_, reuse_kpg1_k_
1000  logical :: qne0
1001  !real(dp) :: cpu, wall, gflops
1002 !arrays
1003  real(dp) :: ylmgr_dum(1,1,1), tsec(2)
1004 
1005 ! *************************************************************************
1006 
1007  ! MG: This routine is called **many times** in the EPH code for phonon and DDK perturbations
1008  ! Please, be extremely careful when adding extra stuff that may affect performance.
1009 
1010  ! Keep track of total time spent in getgh1c_setup (use 195 slot)
1011  call timab(195, 1, tsec)
1012  !call cwtime(cpu, wall, gflops, "start")
1013 
1014  reuse_ffnlk_ = 0; if (present(reuse_ffnlk)) reuse_ffnlk_ = reuse_ffnlk
1015  reuse_ffnl1_ = 0; if (present(reuse_ffnl1)) reuse_ffnl1_ = reuse_ffnl1
1016  reuse_kpg_k_ = 0; if (present(reuse_kpg_k)) reuse_kpg_k_ = reuse_kpg_k
1017  reuse_kpg1_k_ = 0; if (present(reuse_kpg1_k)) reuse_kpg1_k_ = reuse_kpg1_k
1018 
1019  if(.not.present(ddkinpw) .and. ipert==natom+10) then
1020    ABI_BUG("ddkinpw is not optional for ipert=natom+10.")
1021  end if
1022  if(.not.present(dkinpw2) .and. ipert==natom+10 .and. idir>3) then
1023    ABI_BUG("dkinpw2 is not optional for ipert=natom+10 and idir>3.")
1024  end if
1025  if(.not.present(rf_hamk_dir2) .and. ((ipert==natom+10 .and. idir>3) .or. ipert==natom+11)) then
1026    ABI_BUG("rf_hamk_dir2 is not optional for ipert=natom+10 (with idir>3) or ipert=natom+11.")
1027  end if
1028 
1029  ntypat = psps%ntypat
1030  qne0 = ((kpq(1)-kpoint(1))**2+(kpq(2)-kpoint(2))**2+(kpq(3)-kpoint(3))**2>=tol14)
1031 
1032  ! Compute k+G vectors
1033  nkpg = 0; if (ipert >= 1 .and. ipert <= natom) nkpg = 3*dtset%nloalg(3)
1034  if (reuse_kpg_k_ == 0) then
1035    ABI_MALLOC(kpg_k, (npw_k,  nkpg))
1036    if (nkpg > 0) call mkkpg(kg_k, kpg_k, kpoint, nkpg, npw_k)
1037  else
1038    ABI_CHECK(all(shape(kpg_k) == [npw_k,  nkpg]), "Wrong shape in input kpg_k")
1039  endif
1040 
1041  ! Compute k+q+G vectors
1042  nkpg1 = 0; if (ipert >= 1 .and. ipert <= natom) nkpg1 = 3*dtset%nloalg(3)
1043  if (reuse_kpg1_k_ == 0) then
1044    ABI_MALLOC(kpg1_k, (npw1_k, nkpg1))
1045    if (nkpg1 > 0) call mkkpg(kg1_k, kpg1_k, kpq(:), nkpg1, npw1_k)
1046  else
1047    ABI_CHECK(all(shape(kpg1_k) == [npw1_k,  nkpg1]), "Wrong shape in input kpg1_k")
1048  endif
1049 
1050  ! ===== Preparation of the non-local contributions
1051  dimffnlk =0; if (ipert<=natom) dimffnlk=1
1052 
1053  ! Compute nonlocal form factors ffnlk at (k+G)
1054  ! (only for atomic displacement perturbation)
1055  if (reuse_ffnlk_ == 0) then
1056    ABI_MALLOC(ffnlk, (npw_k, dimffnlk, psps%lmnmax, ntypat))
1057    if (ipert<=natom) then
1058      ider=0;idir0=0
1059      call mkffnl(psps%dimekb,dimffnlk,psps%ekb,ffnlk,psps%ffspl,&
1060        gmet,gprimd,ider,idir0,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,&
1061        psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,npw_k,ntypat,&
1062        psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm_k,ylmgr_dum)
1063    end if
1064  else
1065    ABI_CHECK(all(shape(ffnlk) == [npw_k, dimffnlk, psps%lmnmax, ntypat]), "Wrong shape in input ffnlk")
1066  end if
1067 
1068  ! Compute nonlocal form factors ffnl1 at (k+q+G)
1069  !-- Atomic displacement perturbation
1070  if (ipert<=natom) then
1071    ider=0;idir0=0
1072  !-- k-point perturbation (1st-derivative)
1073  else if (ipert==natom+1) then
1074    ider=1;idir0=idir
1075  !-- k-point perturbation (2nd-derivative)
1076  else if (ipert==natom+10.or.ipert==natom+11) then
1077    ider=2;idir0=4
1078  !-- Electric field perturbation
1079  else if (ipert==natom+2) then
1080    if (psps%usepaw==1) then
1081      ider=1;idir0=idir
1082    else
1083      ider=0;idir0=0
1084    end if
1085  !-- Strain perturbation
1086  else if (ipert==natom+3.or.ipert==natom+4) then
1087    if (ipert==natom+3) istr=idir
1088    if (ipert==natom+4) istr=idir+3
1089    ider=1;idir0=-istr
1090  !-- Magnetic field perturbation ( SPr, Zeeman )
1091  else if(ipert==natom+5)then
1092    ider=0;idir0=0
1093  end if
1094 
1095  ! Compute nonlocal form factors ffnl1 at (k+q+G), for all atoms
1096  dimffnl1=1+ider
1097  if (ider==1.and.idir0==0) dimffnl1=2+2*psps%useylm
1098  if (ider==2.and.idir0==4) dimffnl1=3+7*psps%useylm
1099 
1100  if (reuse_ffnl1_ == 0) then
1101    ABI_MALLOC(ffnl1, (npw1_k, dimffnl1, psps%lmnmax, ntypat))
1102 
1103    call mkffnl(psps%dimekb,dimffnl1,psps%ekb,ffnl1,psps%ffspl,gmet,gprimd,ider,idir0,&
1104      psps%indlmn,kg1_k,kpg1_k,kpq,psps%lmnmax,psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg1,&
1105      npw1_k,ntypat,psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm1_k,ylmgr1_k)
1106  else
1107    ABI_CHECK(all(shape(ffnl1) == [npw1_k, dimffnl1, psps%lmnmax, ntypat]), "Wrong shape in input ffnl1")
1108  end if
1109 
1110  ! Compute ffnl for nonlop with signs = 1
1111  print_info = 0
1112  if (dtset%prtvol==-19.or.dtset%prtvol==-20.or.dtset%prtvol==-21.or.dtset%nonlinear_info>=3) then
1113    print_info = 1
1114  end if
1115  if (present(ffnl1_test).and.print_info/=0.and.(ipert==natom+10.or.ipert==natom+11)) then
1116    ABI_MALLOC(ffnl1_test,(npw1_k,dimffnl1,psps%lmnmax,psps%ntypat))
1117    idir0 = 0 ! for nonlop with signs = 1
1118    call mkffnl(psps%dimekb,dimffnl1,psps%ekb,ffnl1_test,psps%ffspl,gs_hamkq%gmet,gs_hamkq%gprimd,ider,idir0,&
1119      psps%indlmn,kg1_k,kpg1_k,kpq,psps%lmnmax,psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg1,&
1120      npw1_k,psps%ntypat,psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm1_k,ylmgr1_k)
1121  end if
1122 
1123  !===== Preparation of the kinetic contributions
1124  ! Note that not all these arrays should be allocated in the general case when wtk_k vanishes
1125 
1126  ! Compute (1/2) (2 Pi)**2 (k+q+G)**2:
1127  ABI_MALLOC(kinpw1, (npw1_k))
1128  kinpw1(:)=zero
1129  call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg1_k,kinpw1,kpq,npw1_k,0,0)
1130 
1131  ABI_MALLOC(dkinpw,(npw_k)) ! 1st derivative (1st direction)
1132  dkinpw(:)=zero
1133  if(ipert==natom+10 .and. idir>3) then
1134    ABI_MALLOC(dkinpw2,(npw_k)) ! 1st derivative (2nd directions)
1135    dkinpw2(:)=zero
1136  end if
1137  if(ipert==natom+10) then
1138    ABI_MALLOC(ddkinpw,(npw_k)) ! 2nd derivative
1139    ddkinpw(:)=zero
1140  end if
1141 
1142  ! -- k-point perturbation (1st-derivative)
1143  if (ipert==natom+1) then
1144    ! Compute the derivative of the kinetic operator vs k
1145    call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,dkinpw,kpoint,npw_k,idir,0) ! 1st derivative
1146  end if
1147 
1148  !-- k-point perturbation (2nd-derivative)
1149  if (ipert==natom+10.or.ipert==natom+11) then
1150    ! Compute the derivative of the kinetic operator vs k in kinpw, second and first orders
1151    if(ipert==natom+10 .and. idir<=3) then
1152      call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,dkinpw,kpoint,npw_k,idir,0) ! 1st derivative
1153      call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,ddkinpw,kpoint,npw_k,idir,idir) ! 2nd derivative
1154    else
1155      select case(idir)
1156      ! Diagonal terms:
1157      case(1)
1158        idir1 = 1
1159        idir2 = 1
1160      case(2)
1161        idir1 = 2
1162        idir2 = 2
1163      case(3)
1164        idir1 = 3
1165        idir2 = 3
1166      ! Upper triangular terms:
1167      case(4)
1168        idir1 = 2
1169        idir2 = 3
1170      case(5)
1171        idir1 = 1
1172        idir2 = 3
1173      case(6)
1174        idir1 = 1
1175        idir2 = 2
1176      ! Lower triangular terms:
1177      case(7)
1178        idir1 = 3
1179        idir2 = 2
1180      case(8)
1181        idir1 = 3
1182        idir2 = 1
1183      case(9)
1184        idir1 = 2
1185        idir2 = 1
1186      end select
1187      call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,dkinpw,kpoint,npw_k,idir1,0) !  1st derivative, idir1
1188      if(ipert==natom+10) then
1189        call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,dkinpw2,kpoint,npw_k,idir2,0) ! 1st derivative, idir2
1190        call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg_k,ddkinpw,kpoint,npw_k,idir1,idir2) ! 2nd derivative
1191      end if
1192    end if
1193  end if
1194 
1195  !-- Strain perturbation
1196  if (ipert==natom+3.or.ipert==natom+4) then
1197    if (ipert==natom+3) istr=idir
1198    if (ipert==natom+4) istr=idir+3
1199    ! Compute the derivative of the kinetic operator vs strain
1200    call kpgstr(dkinpw,dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,gprimd,istr,kg_k,kpoint,npw_k)
1201  end if
1202 
1203  !===== Load the k/k+q dependent parts of the Hamiltonian
1204  ! Load k-dependent part in the Hamiltonian datastructure
1205  ABI_MALLOC(ph3d,(2,npw_k,gs_hamkq%matblk))
1206  call gs_hamkq%load_k(kpt_k=kpoint,npw_k=npw_k,istwf_k=istwf_k,kg_k=kg_k,kpg_k=kpg_k,&
1207                       ph3d_k=ph3d,compute_ph3d=.true.,compute_gbound=.true.)
1208 
1209  if (size(ffnlk)>0) then
1210    call gs_hamkq%load_k(ffnl_k=ffnlk)
1211  else
1212    call gs_hamkq%load_k(ffnl_k=ffnl1)
1213  end if
1214 
1215   ! Load k+q-dependent part in the Hamiltonian datastructure
1216   ! Note: istwf_k is imposed to 1 for RF calculations (should use istwf_kq instead)
1217  call gs_hamkq%load_kprime(kpt_kp=kpq,npw_kp=npw1_k,istwf_kp=istwf_k,&
1218    kinpw_kp=kinpw1,kg_kp=kg1_k,kpg_kp=kpg1_k,ffnl_kp=ffnl1,compute_gbound=.true.)
1219 
1220  if (qne0) then
1221    ABI_MALLOC(ph3d1,(2,npw1_k,gs_hamkq%matblk))
1222    call gs_hamkq%load_kprime(ph3d_kp=ph3d1,compute_ph3d=.true.)
1223  end if
1224 
1225  ! Load k-dependent part in the 1st-order Hamiltonian datastructure
1226  call rf_hamkq%load_k(npw_k=npw_k,dkinpw_k=dkinpw)
1227 
1228  if (ipert==natom+10) then
1229    call rf_hamkq%load_k(ddkinpw_k=ddkinpw)
1230    if (idir>3) call rf_hamk_dir2%load_k(dkinpw_k=dkinpw2,ddkinpw_k=ddkinpw)
1231  end if
1232 
1233  call timab(195, 2, tsec)
1234 
1235 end subroutine getgh1c_setup

m_hamiltonian/getgh1dqc_setup [ Functions ]

[ Top ] [ m_hamiltonian ] [ Functions ]

NAME

  getgh1dqc_setup

FUNCTION

INPUTS

OUTPUT

SOURCE

1663 subroutine getgh1dqc_setup(gs_hamkq,rf_hamkq,dtset,psps,kpoint,kpq,idir,ipert,qdir1,&    ! In
1664 &                natom,rmet,rprimd,gprimd,gmet,istwf_k,npw_k,npw1_k,nylmgr,&             ! In
1665 &                useylmgr1,kg_k,ylm_k,kg1_k,ylm1_k,ylmgr1_k,&                            ! In
1666 &                nkpg,nkpg1,kpg_k,kpg1_k,dqdqkinpw,kinpw1,ffnlk,ffnl1,ph3d,ph3d1,&       ! Out
1667 &                reuse_ffnlk,reuse_ffnl1,qdir2)                                          ! Optional
1668 
1669 !Arguments ------------------------------------
1670 !scalars
1671  integer,intent(in) :: idir,ipert,istwf_k,natom,npw_k,npw1_k,nylmgr,qdir1,useylmgr1
1672  integer,intent(in),optional :: reuse_ffnlk,reuse_ffnl1,qdir2
1673  integer,intent(out) :: nkpg,nkpg1
1674  type(gs_hamiltonian_type),intent(inout) :: gs_hamkq
1675  type(rf_hamiltonian_type),intent(inout) :: rf_hamkq
1676  type(dataset_type),intent(in) :: dtset
1677  type(pseudopotential_type),intent(in) :: psps
1678 !arrays
1679  integer,intent(in) :: kg_k(3,npw_k),kg1_k(3,npw1_k)
1680  real(dp),intent(in) :: kpoint(3),kpq(3),gmet(3,3),gprimd(3,3),rmet(3,3),rprimd(3,3)
1681  real(dp),intent(in) :: ylm_k(npw_k,psps%mpsang*psps%mpsang*psps%useylm)
1682 ! real(dp),intent(in) :: ylmgr1_k(npw1_k,3+6*((ipert-natom)/10),psps%mpsang*psps%mpsang*psps%useylm*useylmgr1)
1683  real(dp),intent(in) :: ylmgr1_k(npw1_k,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr1)
1684  real(dp),intent(in) :: ylm1_k(npw1_k,psps%mpsang*psps%mpsang*psps%useylm)
1685  real(dp),allocatable,intent(out) :: dqdqkinpw(:),kinpw1(:)
1686  real(dp),allocatable,intent(inout) :: ffnlk(:,:,:,:),ffnl1(:,:,:,:)
1687  real(dp),allocatable,intent(out) :: kpg_k(:,:),kpg1_k(:,:),ph3d(:,:,:),ph3d1(:,:,:)
1688 
1689 !Local variables-------------------------------
1690 !scalars
1691  integer :: dimffnl1,dimffnlk,ider,idir0,ig,mu,mua,mub,ntypat
1692  integer :: nu,nua,nub
1693  integer :: reuse_ffnlk_,reuse_ffnl1_
1694  logical :: qne0
1695 !arrays
1696  integer,parameter :: alpha(6)=(/1,2,3,3,3,2/),beta(6)=(/1,2,3,2,1,1/)
1697  integer,parameter :: gamma(3,3)=reshape((/1,6,5,6,2,4,5,4,3/),(/3,3/))
1698  real(dp) :: ylmgr_dum(1,1,1)
1699  real(dp),allocatable :: ffnl1_tmp(:,:,:,:)
1700 
1701 
1702 ! *************************************************************************
1703 
1704  reuse_ffnlk_ = 0; if (present(reuse_ffnlk)) reuse_ffnlk_ = reuse_ffnlk
1705  reuse_ffnl1_ = 0; if (present(reuse_ffnl1)) reuse_ffnl1_ = reuse_ffnl1
1706 
1707  ntypat = psps%ntypat
1708  qne0=((kpq(1)-kpoint(1))**2+(kpq(2)-kpoint(2))**2+(kpq(3)-kpoint(3))**2>=tol14)
1709 
1710 !Compute (k+G) vectors
1711  nkpg=0;if(ipert>=1.and.ipert<=natom) nkpg=3*dtset%nloalg(3)
1712  ABI_MALLOC(kpg_k,(npw_k,nkpg))
1713  if (nkpg>0) then
1714    call mkkpg(kg_k,kpg_k,kpoint,nkpg,npw_k)
1715  end if
1716 
1717 !Compute (k+q+G) vectors
1718  nkpg1=0;if(ipert>=1.and.ipert<=natom) nkpg1=3*dtset%nloalg(3)
1719  ABI_MALLOC(kpg1_k,(npw1_k,nkpg1))
1720  if (nkpg1>0) then
1721    call mkkpg(kg1_k,kpg1_k,kpq(:),nkpg1,npw1_k)
1722  end if
1723 
1724 !===== Preparation of the non-local contributions
1725 
1726  dimffnlk=0;if (ipert<=natom) dimffnlk=1
1727 
1728 !Compute nonlocal form factors ffnlk at (k+G)
1729  if (reuse_ffnlk_ == 0) then
1730    ABI_MALLOC(ffnlk,(npw_k,dimffnlk,psps%lmnmax,ntypat))
1731    if (ipert<=natom) then
1732      ider=0;idir0=0
1733      call mkffnl(psps%dimekb,dimffnlk,psps%ekb,ffnlk,psps%ffspl,&
1734    & gmet,gprimd,ider,idir0,psps%indlmn,kg_k,kpg_k,kpoint,psps%lmnmax,&
1735    & psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,npw_k,ntypat,&
1736    & psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm_k,ylmgr_dum)
1737    end if
1738  else 
1739    ABI_CHECK(all(shape(ffnlk) == [npw_k, dimffnlk, psps%lmnmax, ntypat]), "Wrong shape in input ffnlk")
1740  end if
1741 
1742 !Compute nonlocal form factors ffnl1 at (k+q+G)
1743 !TODO: For the second order gradients, this routine is called for each 3 directions of the
1744 !derivative and every time it calculates all the form factors derivatives. This could be
1745 !done just once.
1746  !-- 1st q-grad of atomic displacement perturbation
1747  if (ipert<=natom.and..not.present(qdir2)) then
1748    ider=1;idir0=qdir1
1749  !-- 2nd q-grad of atomic displacement perturbation
1750  else if (ipert<=natom.and.present(qdir2)) then
1751    ider=2;idir0=4
1752  !-- 2nd q-grad of metric (1st q-grad of strain) perturbation
1753  else if (ipert==natom+3.or.ipert==natom+4) then
1754    ider=2;idir0=4
1755  end if
1756 
1757 !Compute nonlocal form factors ffnl1 at (k+q+G), for all atoms
1758  dimffnl1=1+ider
1759  if (ider==2.and.(idir0==0.or.idir0==4)) dimffnl1=3+7*psps%useylm
1760 
1761  if (reuse_ffnl1_ == 0) then
1762    ABI_MALLOC(ffnl1,(npw1_k,dimffnl1,psps%lmnmax,ntypat))
1763    call mkffnl(psps%dimekb,dimffnl1,psps%ekb,ffnl1,psps%ffspl,gmet,gprimd,ider,idir0,&
1764   & psps%indlmn,kg1_k,kpg1_k,kpq,psps%lmnmax,psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg1,&
1765   & npw1_k,ntypat,psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm1_k,ylmgr1_k)
1766  else
1767    ABI_CHECK(all(shape(ffnl1) == [npw1_k, dimffnl1, psps%lmnmax, ntypat]), "Wrong shape in input ffnl1")
1768  end if
1769  
1770 
1771 !Convert nonlocal form factors to cartesian coordinates.
1772 !For metric (strain) perturbation only.
1773  if (ipert==natom+3.or.ipert==natom+4) then
1774    ABI_MALLOC(ffnl1_tmp,(npw1_k,dimffnl1,psps%lmnmax,ntypat))
1775    ffnl1_tmp=ffnl1
1776 
1777    !First q-derivative
1778    ffnl1(:,2:4,:,:)=zero
1779    do mu=1,3
1780      do ig=1,npw1_k
1781        do nu=1,3
1782          ffnl1(ig,1+mu,:,:)=ffnl1(ig,1+mu,:,:)+ffnl1_tmp(ig,1+nu,:,:)*rprimd(mu,nu)
1783        end do
1784      end do
1785    end do
1786 
1787    !Second q-derivative
1788    ffnl1(:,5:10,:,:)=zero
1789    do mu=1,6
1790      mua=alpha(mu);mub=beta(mu)
1791      do ig=1,npw1_k
1792        do nua=1,3
1793          do nub=1,3
1794            nu=gamma(nua,nub)
1795            ffnl1(ig,4+mu,:,:)=ffnl1(ig,4+mu,:,:)+ &
1796          & ffnl1_tmp(ig,4+nu,:,:)*rprimd(mua,nua)*rprimd(mub,nub)
1797          end do
1798        end do
1799      end do
1800    end do
1801 
1802    ABI_FREE(ffnl1_tmp)
1803  end if
1804 
1805 !===== Preparation of the kinetic contributions
1806 ! Compute (1/2) (2 Pi)**2 (k+q+G)**2:
1807  ABI_MALLOC(kinpw1,(npw1_k))
1808  kinpw1(:)=zero
1809  call mkkin(dtset%ecut,dtset%ecutsm,dtset%effmass_free,gmet,kg1_k,kinpw1,kpq,npw1_k,0,0)
1810 
1811  ABI_MALLOC(dqdqkinpw,(npw_k))
1812  !-- Metric (strain) perturbation
1813  if (ipert==natom+3.or.ipert==natom+4) then
1814    call mkkin_metdqdq(dqdqkinpw,dtset%effmass_free,gprimd,idir,kg_k,kpoint,npw_k,qdir1)
1815  else
1816    dqdqkinpw(:)=zero
1817  end if
1818 
1819 !===== Load the k/k+q dependent parts of the Hamiltonian
1820 
1821 !Load k-dependent part in the Hamiltonian datastructure
1822  ABI_MALLOC(ph3d,(2,npw_k,gs_hamkq%matblk))
1823  call gs_hamkq%load_k(kpt_k=kpoint,npw_k=npw_k,istwf_k=istwf_k,kg_k=kg_k,kpg_k=kpg_k,&
1824 & ph3d_k=ph3d,compute_ph3d=.true.,compute_gbound=.true.)
1825 
1826  if (size(ffnlk)>0) then
1827    call gs_hamkq%load_k(ffnl_k=ffnlk)
1828  else
1829    call gs_hamkq%load_k(ffnl_k=ffnl1)
1830  end if
1831 
1832 !Load k+q-dependent part in the Hamiltonian datastructure
1833 !    Note: istwf_k is imposed to 1 for RF calculations (should use istwf_kq instead)
1834  call gs_hamkq%load_kprime(kpt_kp=kpq,npw_kp=npw1_k,istwf_kp=istwf_k,&
1835 & kinpw_kp=kinpw1,kg_kp=kg1_k,kpg_kp=kpg1_k,ffnl_kp=ffnl1,&
1836 & compute_gbound=.true.)
1837 
1838  if (qne0) then
1839    ABI_MALLOC(ph3d1,(2,npw1_k,gs_hamkq%matblk))
1840    call gs_hamkq%load_kprime(ph3d_kp=ph3d1,compute_ph3d=.true.)
1841  end if
1842 
1843 !Load k-dependent part in the 1st-order Hamiltonian datastructure
1844  call rf_hamkq%load_k(npw_k=npw_k,dkinpw_k=dqdqkinpw)
1845 
1846 end subroutine getgh1dqc_setup

m_hamiltonian/rf_transgrid_and_pack [ Functions ]

[ Top ] [ m_hamiltonian ] [ Functions ]

NAME

  rf_transgrid_and_pack

FUNCTION

 Set up local potential vlocal1 with proper dimensioning, from vtrial1
 taking into account the spin. Same thing for vlocal from vtrial.

INPUTS

  isppol=Spin index.
  nspden=Number of density components
  usepaw=1 if PAW, 0 for NC.
  cplex=1 if DFPT potential is real, 2 for complex
  nfftf=Number of FFT points on the FINE grid treated by this processor
  nfft=Number of FFT points on the COARSE grid treated by this processor
  ngfft(18)=Info on the coarse grid.
  pawfgr <type(pawfgr_type)>=fine grid parameters and related data
  mpi_enreg=information about MPI parallelization
  vtrial(nfftf,nspden)=GS Vtrial(r) on the DENSE mesh
  vtrial1(cplex*nfftf,nspden)=INPUT RF Vtrial(r) on the DENSE mesh

OUTPUT

  vlocal(n4,n5,n6,nvloc)= GS local potential in real space, on the augmented coarse fft grid
  vlocal1(cplex*n4,n5,n6,nvloc)= RF local potential in real space, on the augmented coarse fft grid

SOURCE

876 subroutine rf_transgrid_and_pack(isppol,nspden,usepaw,cplex,nfftf,nfft,ngfft,nvloc,&
877 &                                pawfgr,mpi_enreg,vtrial,vtrial1,vlocal,vlocal1)
878 
879 !Arguments ------------------------------------
880 !scalars
881  integer,intent(in) :: isppol,nspden,usepaw,cplex,nfftf,nfft,nvloc
882  type(pawfgr_type),intent(in) :: pawfgr
883  type(MPI_type),intent(in) :: mpi_enreg
884 !arrays
885  integer,intent(in) :: ngfft(18)
886  real(dp),intent(in),target :: vtrial(nfftf,nspden)
887  real(dp),intent(inout),target :: vtrial1(cplex*nfftf,nspden)
888  real(dp),intent(out) :: vlocal(ngfft(4),ngfft(5),ngfft(6),nvloc)
889  real(dp),intent(out) :: vlocal1(cplex*ngfft(4),ngfft(5),ngfft(6),nvloc)
890 
891 !Local variables-------------------------------
892 !scalars
893  integer :: n1,n2,n3,n4,n5,n6,paral_kgb,ispden
894 !arrays
895  real(dp) :: rhodum(1) !, tsec(2)
896  real(dp), ABI_CONTIGUOUS pointer :: vtrial_ptr(:,:),vtrial1_ptr(:,:)
897  real(dp),allocatable :: cgrvtrial(:,:),cgrvtrial1(:,:),vlocal_tmp(:,:,:),vlocal1_tmp(:,:,:)
898 
899 ! *************************************************************************
900 
901  n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
902  n4=ngfft(4); n5=ngfft(5); n6=ngfft(6)
903  paral_kgb = mpi_enreg%paral_kgb
904 
905  if (nspden/=4) then
906    vtrial_ptr => vtrial
907    if (usepaw==0.or.pawfgr%usefinegrid==0) then
908      call fftpac(isppol,mpi_enreg,nspden,n1,n2,n3,n4,n5,n6,ngfft,vtrial_ptr,vlocal(:,:,:,1),2)
909      call fftpac(isppol,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,vtrial1,vlocal1(:,:,:,1),2)
910    else
911      ABI_MALLOC(cgrvtrial,(nfft,nspden))
912      call transgrid(1,mpi_enreg,nspden,-1,0,0,paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vtrial_ptr)
913      call fftpac(isppol,mpi_enreg,nspden,n1,n2,n3,n4,n5,n6,ngfft,cgrvtrial,vlocal(:,:,:,1),2)
914      ABI_REMALLOC(cgrvtrial, (cplex*nfft, nspden))
915      call transgrid(cplex,mpi_enreg,nspden,-1,0,0,paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vtrial1)
916      call fftpac(isppol,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,cgrvtrial,vlocal1(:,:,:,1),2)
917      ABI_FREE(cgrvtrial)
918    end if
919    nullify(vtrial_ptr)
920  else
921    ! nspden==4 non-collinear magnetism
922    vtrial_ptr => vtrial
923    vtrial1_ptr => vtrial1
924    ABI_MALLOC(vlocal_tmp,(n4,n5,n6))
925    ABI_MALLOC(vlocal1_tmp,(cplex*n4,n5,n6))
926    if (usepaw==0.or.pawfgr%usefinegrid==0) then
927      do ispden=1,nspden
928        call fftpac(ispden,mpi_enreg,nspden,n1,n2,n3,n4,n5,n6,ngfft,vtrial_ptr,vlocal_tmp,2)
929        vlocal(:,:,:,ispden)=vlocal_tmp(:,:,:)
930        call fftpac(ispden,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,ngfft,vtrial1_ptr,vlocal1_tmp,2)
931        vlocal1(:,:,:,ispden)=vlocal1_tmp(:,:,:)
932      end do
933    else
934      ! TODO FR EB check the correctness of the following lines for PAW calculations
935      ABI_MALLOC(cgrvtrial,(nfft,nspden))
936      ABI_MALLOC(cgrvtrial1,(nfft,nspden))
937      call transgrid(cplex,mpi_enreg,nspden,-1,0,0,paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial,vtrial_ptr)
938      call transgrid(cplex,mpi_enreg,nspden,-1,0,0,paral_kgb,pawfgr,rhodum,rhodum,cgrvtrial1,vtrial1_ptr)
939      do ispden=1,nspden
940        call fftpac(ispden,mpi_enreg,nspden,n1,n2,n3,n4,n5,n6,ngfft,vtrial_ptr,vlocal_tmp,2)
941        vlocal(:,:,:,ispden)=vlocal_tmp(:,:,:)
942        call fftpac(ispden,mpi_enreg,nspden,n1,n2,n3,n4,n5,n6,ngfft,vtrial1_ptr,vlocal1_tmp,2)
943        vlocal1(:,:,:,ispden)=vlocal1_tmp(:,:,:)
944      end do
945      ABI_FREE(cgrvtrial)
946    end if
947    ABI_FREE(vlocal_tmp)
948    ABI_FREE(vlocal1_tmp)
949  end if !nspden
950 
951 end subroutine rf_transgrid_and_pack