TABLE OF CONTENTS


ABINIT/m_dfptlw_pert [ Modules ]

[ Top ] [ Modules ]

NAME

  m_dfptlw_pert

FUNCTION

COPYRIGHT

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

PARENTS

CHILDREN

SOURCE

20 #if defined HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include "abi_common.h"
25 
26 module m_dfptlw_pert
27     
28  use defs_basis
29  use defs_abitypes
30  use defs_datatypes
31  use m_dtset
32  use m_dtfil
33  use m_errors
34  use m_profiling_abi
35  use m_hamiltonian
36  use m_cgtools
37  use m_pawcprj
38  use m_pawfgr
39  use m_wfk
40  use m_xmpi
41  use m_getgh1c
42  use m_mklocl
43  use m_initylmg,   only : initylmg
44  use m_fstrings,   only : itoa, sjoin
45  use m_io_tools,   only : file_exists
46  use m_time,       only : cwtime
47  use m_kg,         only : mkkpg
48  use m_mpinfo,     only : proc_distrb_cycle
49  use m_dfptlw_wf
50  use m_dfpt_mkvxc, only : dfpt_mkvxcggadq
51  use m_dfptlw_nv,  only : dfptlw_geom
52  use m_spacepar,   only : hartredq
53  use m_cgtools,    only : dotprod_vn
54  use m_mkffnl,     only : mkffnl
55 
56  implicit none
57 
58  public :: dfptlw_pert
59  public :: preca_ffnl
60 
61  private
62 
63 ! *************************************************************************
64 
65 contains 

ABINIT/m_dfptlw_pert/dfptlw_pert [ Functions ]

[ Top ] [ Functions ]

NAME

  dfptlw_pert

FUNCTION

 Compute first-order response function contributions to the spatial-dispersion
 3rd order energy derivatives of the longwave driver.
 The main inputs are :
   - GS WFs and Hamiltonian (cg,gs_hamkq)
   - 1st-order WFs for two perturbations i1pert/i1dir,i2pert/i2dir (cg1,cg2)
   - 1st-order Local+SCF potentials for i1pert and i2pert 
   - 1st-order WFs DDK and 2nd-order WF D2_DKDK (d2_dkdk_f)

COPYRIGHT

 Copyright (C) 2018-2024 ABINIT group (MR)
 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

  cg(2,mpw*nspinor*mband*mkmem_rbz*nsppol) = array for planewave
                                          coefficients of wavefunctions
  cg1 = first derivative of cg with respect the perturbation i1pert
  cg2 = first derivative of cg with respect the perturbation i2pert
  cplex= if 1, real space 1-order functions on FFT grid are REAL,
          if 2, COMPLEX
  dimffnl= third dimension of ffnl
  dtset <type(dataset_type)>=all input variables for this dataset
  eigen1(2*mband*mband*nkpt*nsppol)=1st-order eigenvalues for i1pert,i1dir (hartree)
  eigen2(2*mband*mband*nkpt*nsppol)=1st-order eigenvalues for i2pert,i2dir (hartree)
  ffnl(dtset%mkmem,dtset%mpw,dimffnl,psps%lmnmax,psps%ntypat)= Nonlocal projectors and their derivatives
  gmet(3,3)=reciprocal space metric tensor in bohr**-2
  gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q
  gsqcut=large sphere cut-off
  i1dir,i2dir,i3dir=directions of the corresponding perturbations
  i1pert,i2pert,i3pert = type of perturbation that has to be computed
  kg(3,mpw*mkmem_rbz)=reduced planewave coordinates
  kxc(nfft,nkxc)=exchange and correlation kernel
  mband = maximum number of bands
  mkmem_rbz = maximum number of k points which can fit in core memory
  mk1mem = maximum number of k points for first-order WF
           which can fit in core memory
  mpert =maximum number of ipert
  mpi_enreg=MPI-parallelisation information
  mpsang= 1+maximum angular momentum for nonlocal pseudopotentials
  mpw   = maximum number of planewaves in basis sphere (large number)
  natom = number of atoms in unit cell
  n1dq= third dimension of vlocal1_i1pertdq
  n2dq= third dimension of vlocal1_i2pertdq
  nfft= number of FFT grid points (for this proc) 
  ngfft(1:18)=integer array with FFT box dimensions and other 
  nkpt = number of k points
  nkxc=second dimension of the kxc array. If /=0, the XC kernel must be computed.
  nspden = number of spin-density components
  nspinor = number of spinorial components of the wavefunctions
  nsppol = number of channels for spin-polarization (1 or 2)
  npwarr(nkpt) = array holding npw for each k point
  nylmgr=second dimension of ylmgr_k
  occ(mband*nkpt*nsppol) = occupation number for each band and k
  pawfgr <type(pawfgr_type)>=fine grid parameters and related data
  psps <type(pseudopotential_type)> = variables related to pseudopotentials
  rho1g1(2,nfft)=G-space RF electron density in electrons/bohr**3 (i1pert)
  rho1r1(cplex*nfft,nspden)=RF electron density in electrons/bohr**3 (i1pert)
  rho2r1(cplex*nfft,nspden)=RF electron density in electrons/bohr**3 (i2pert)
  rmet(3,3)=real space metric tensor in bohr**2
  rprimd(3,3) = dimensional primitive translations (bohr)
  samepert= .true. if i1pert=i2pert and i1dir=i2dir
  ucvol=volume of the unit cell
  useylmgr= if 1 use the derivative of spherical harmonics
  vpsp1_i1pertdq(cplex*nfft,nspden,n1dq)= local potential of first-order
          gradient Hamiltonian for i1pert
  vpsp1_i1pertdq(cplex*nfft,nspden,n1dq)= local potential of second-order
          gradient Hamiltonian for i1pert
  vpsp1_i1pertdq_geom(cplex*nfft,nspden,3)= local potential of first-order
          gradient Hamiltonian for i1pert wrp to i3dir and i2dir
  vpsp1_i2pertdq(cplex*nfft,nspden,n2dq)= local potential of first-order
          gradient Hamiltonian for i2pert
  ddk_f = wf files
  d2_dkdk_f = wf files
  ylm(mpw*mkmem,psps%mpsang*psps%mpsang*psps%useylm)=real spherical harmonics
  ylmgr(mpw*mkmem,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr)= k-gradients of real spherical harmonics

OUTPUT

  d3etot(2,3,mpert,3,mpert,3,mpert) = third derivatives of the energy tensor
  d3etot_t4(2,n2dq)= t4 term which might need to be converted to type-II
  d3etot_t5(2,n1dq)= t5 term which might need to be converted to type-II
  d3etot_tgeom(2,2)= Geometric term which needs to be converted to type-II

SIDE EFFECTS

  TO DO!

PARENTS

      m_dfptlw_loop

CHILDREN

      dotprod_vn

SOURCE

168 subroutine dfptlw_pert(cg,cg1,cg2,cplex,d3etot,d3etot_t4,d3etot_t5,d3etot_tgeom,&
169 & dimffnl,dtset,eigen1,eigen2,ffnl,gmet,gs_hamkq,gsqcut,i1dir,i2dir,i3dir,&
170 & i1pert,i2pert,i3pert,kg,kxc,mband,mkmem_rbz,mk1mem,mpert,mpi_enreg,mpsang,mpw,natom,&
171 & n1dq,n2dq,nfft,ngfft,nkpt,nkxc,&
172 & nspden,nspinor,nsppol,npwarr,nylmgr,occ,pawfgr,psps,rho1g1,rho1r1,rho2r1,rmet,rprimd,samepert,&
173 & ucvol,useylmgr,vpsp1_i1pertdq,vpsp1_i1pertdqdq,vpsp1_i1pertdq_geom,vpsp1_i2pertdq,ddk_f,d2_dkdk_f,d2_dkdk_f2,ylm,ylmgr)
174 
175 !Arguments ------------------------------------
176 !scalars
177  integer,intent(in) :: cplex,dimffnl,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert,mband
178  integer,intent(in) :: mk1mem,mkmem_rbz,mpert,mpsang,mpw,natom,n1dq,n2dq,nfft,nkpt,nkxc,nspden
179  integer,intent(in) :: nspinor,nsppol,nylmgr,useylmgr
180  real(dp),intent(in) :: gsqcut,ucvol
181  logical,intent(in) :: samepert
182  type(MPI_type),intent(inout) :: mpi_enreg
183  type(dataset_type),intent(in) :: dtset
184  type(pseudopotential_type),intent(in) :: psps
185  type(gs_hamiltonian_type),intent(inout) :: gs_hamkq
186  type(pawfgr_type),intent(in) :: pawfgr
187  type(wfk_t),intent(inout) :: ddk_f,d2_dkdk_f, d2_dkdk_f2
188 
189 !arrays
190  integer,intent(in) :: kg(3,mpw*mkmem_rbz),ngfft(18),npwarr(nkpt)
191  real(dp),intent(in) :: eigen1(2*mband*mband*nkpt*nsppol)
192  real(dp),intent(in) :: eigen2(2*mband*mband*nkpt*nsppol)
193  real(dp),intent(in) :: ffnl(mkmem_rbz,mpw,dimffnl,psps%lmnmax,psps%ntypat)
194  real(dp),intent(in) :: cg(2,mpw*nspinor*mband*mkmem_rbz*nsppol)
195  real(dp),intent(in) :: cg1(2,mpw*nspinor*mband*mk1mem*nsppol)
196  real(dp),intent(in) :: cg2(2,mpw*nspinor*mband*mk1mem*nsppol)
197  real(dp),intent(in) :: gmet(3,3),kxc(nfft,nkxc)
198  real(dp),intent(in) :: occ(mband*nkpt*nsppol)
199  real(dp),intent(in) :: rho1g1(2,nfft),rho1r1(cplex*nfft,dtset%nspden)
200  real(dp),intent(in) :: rho2r1(cplex*nfft,dtset%nspden)
201  real(dp),intent(in) :: rmet(3,3),rprimd(3,3)
202  real(dp),intent(in) :: vpsp1_i1pertdq(2*nfft,nspden,n1dq)
203  real(dp),intent(in) :: vpsp1_i1pertdqdq(2*nfft,nspden,n2dq)
204  real(dp),intent(in) :: vpsp1_i1pertdq_geom(2*nfft,nspden,3)
205  real(dp),intent(in) :: vpsp1_i2pertdq(2*nfft,nspden,n2dq)
206  real(dp),intent(inout) :: d3etot(2,3,mpert,3,mpert,3,mpert)
207  real(dp),intent(out) :: d3etot_t4(2,n2dq),d3etot_t5(2,n1dq)
208  real(dp),intent(out) :: d3etot_tgeom(2,n2dq)
209  real(dp),intent(in) :: ylm(mpw*mk1mem,psps%mpsang*psps%mpsang*psps%useylm)
210  real(dp),intent(in) :: ylmgr(mpw*mk1mem,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr)
211 
212 !Variables ------------------------------------
213 !scalars
214  integer :: bandtot,bd2tot,icg,idq,ierr,ii,ikc,ikg,ikpt,ilm,isppol,istwf_k,me,n1,n2,n3,n4,n5,n6 
215  integer :: nband_k,npw_k,spaceworld,tim_getgh1c
216  integer :: usepaw
217  real(dp) :: tmpim,tmpre,wtk_k
218  real(dp) :: cpu, wall, gflops
219  character(len=1000) :: msg
220  logical :: with_nonlocal_i1pert, with_nonlocal_i2pert
221 !arrays
222  integer,allocatable :: kg_k(:,:)
223  real(dp) :: d3etot_t1(2),d3etot_t1_k(2)
224  real(dp) :: d3etot_t2(2),d3etot_t2_k(2)
225  real(dp) :: d3etot_t3(2),d3etot_t3_k(2)
226  real(dp) :: d3etot_t4_k(2,n2dq)
227  real(dp) :: d3etot_t5_k(2,n1dq)
228  real(dp) :: d3etot_tgeom_k(2,n2dq)
229  real(dp) :: d3etot_telec(2)
230  real(dp) :: e3tot(2),kpt(3)
231  real(dp),allocatable :: eig1_k(:),eig2_k(:),occ_k(:)
232  real(dp),allocatable :: ylm_k(:,:),ylmgr_k(:,:,:)
233  real(dp),allocatable :: ffnl_k(:,:,:,:)
234  
235 ! *************************************************************************
236 
237  DBG_ENTER("COLL")
238 
239  write(msg,'(2a,3(a,i2,a,i1))') ch10,'LONGWAVE : ',&
240  ' perts : ',i1pert,'.',i1dir,' / ',i2pert,'.',i2dir,' / ',i3pert,'.',i3dir
241  call wrtout(std_out,msg,'COLL')
242  call wrtout(ab_out,msg,'COLL')
243 
244 !Init parallelism
245  spaceworld=mpi_enreg%comm_cell
246  me=mpi_enreg%me_kpt 
247 
248 !Additional definitions
249  tim_getgh1c=0
250  usepaw=dtset%usepaw
251  n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3)
252  n4=ngfft(4) ; n5=ngfft(5) ; n6=ngfft(6)
253  with_nonlocal_i1pert=.true. ; if (i1pert==natom+2) with_nonlocal_i1pert=.false.
254  with_nonlocal_i2pert=.true. ; if (i2pert==natom+2) with_nonlocal_i2pert=.false.
255 
256 !Initialize d3etot parts
257  d3etot_t1=zero
258  d3etot_t2=zero
259  d3etot_t3=zero
260  d3etot_t4=zero
261  d3etot_t5=zero
262  d3etot_telec=zero
263  d3etot_tgeom=zero
264 
265 !Calculate the electrostatic contribution 
266  call lw_elecstic(cplex,d3etot_telec,gmet,gs_hamkq%gprimd,gsqcut,&
267 & i3dir,kxc,mpi_enreg,nfft,ngfft,nkxc,nspden,rho1g1,rho1r1,rho2r1,ucvol)
268  
269 !Loop over spins
270  bandtot = 0
271  bd2tot = 0
272  icg=0
273  do isppol = 1, nsppol
274 
275 !  Loop over k-points
276    ikg = 0
277    ikc = 0
278    do ikpt = 1, nkpt
279 
280      nband_k = dtset%nband(ikpt+(isppol-1)*nkpt)
281      npw_k = npwarr(ikpt)
282      istwf_k = dtset%istwfk(ikpt)
283 
284      if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,mband,isppol,mpi_enreg%me)) then
285        bandtot = bandtot + nband_k
286        bd2tot = bd2tot + 2*nband_k**2
287        cycle ! Skip the rest of the k-point loop
288      end if
289      ikc= ikc + 1
290 
291      ABI_MALLOC(occ_k,(nband_k))
292      occ_k(:) = occ(1+bandtot:nband_k+bandtot)
293      wtk_k    = dtset%wtk(ikpt)
294      kpt(:) = dtset%kptns(:,ikpt)
295 
296      ABI_MALLOC(eig1_k,(2*nband_k**2))
297      ABI_MALLOC(eig2_k,(2*nband_k**2))
298      ABI_MALLOC(kg_k,(3,npw_k))
299      ABI_MALLOC(ylm_k,(npw_k,mpsang*mpsang*psps%useylm))
300      ABI_MALLOC(ylmgr_k,(npw_k,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr))
301      ABI_MALLOC(ffnl_k,(npw_k,dimffnl,psps%lmnmax,psps%ntypat))
302 
303      !Get plane-wave vectors and related data at k
304      kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
305      if (dtset%ffnl_lw==1) then
306        if (psps%useylm==1) then
307          do ilm=1,psps%mpsang*psps%mpsang
308            ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm)
309          end do
310          if (useylmgr==1) then
311            do ilm=1,psps%mpsang*psps%mpsang
312              do ii=1,nylmgr
313                ylmgr_k(1:npw_k,ii,ilm)=ylmgr(1+ikg:npw_k+ikg,ii,ilm)
314              end do
315            end do
316          end if
317        end if
318      else if (dtset%ffnl_lw==0) then
319        ffnl_k(1:npw_k,:,:,:)=ffnl(ikc,1:npw_k,:,:,:)
320      end if
321 
322      !Get matrix elements for uniform perturbations
323      eig1_k(:)=eigen1(1+bd2tot:2*nband_k**2+bd2tot)
324      eig2_k(:)=eigen2(1+bd2tot:2*nband_k**2+bd2tot)
325 
326      !Compute the stationary terms of d3etot depending on response functions
327      call dfpt_1wf(cg,cg1,cg2,cplex,ddk_f,d2_dkdk_f,d2_dkdk_f2,d3etot_t1_k,d3etot_t2_k,d3etot_t3_k,& 
328      & d3etot_t4_k,d3etot_t5_k,dimffnl,dtset,eig1_k,eig2_k,ffnl_k,gs_hamkq,icg,&
329      & i1dir,i2dir,i3dir,i1pert,i2pert,ikpt,isppol,istwf_k,&
330      & kg_k,kpt,mkmem_rbz,mpi_enreg,mpw,natom,nband_k,&
331      & n1dq,n2dq,nfft,ngfft,npw_k,nspden,nsppol,nylmgr,occ_k,&
332      & pawfgr,psps,rmet,rprimd,samepert,useylmgr,&
333      & vpsp1_i1pertdq,vpsp1_i2pertdq,&
334      & wtk_k,ylm_k,ylmgr_k)
335 
336 !    Add the contribution from each k-point. 
337      d3etot_t1=d3etot_t1 + d3etot_t1_k
338      d3etot_t2=d3etot_t2 + d3etot_t2_k
339      d3etot_t3=d3etot_t3 + d3etot_t3_k
340      d3etot_t4=d3etot_t4 + d3etot_t4_k
341      d3etot_t5=d3etot_t5 + d3etot_t5_k
342  
343      !Compute the nonvariational geometric term
344      call cwtime(cpu, wall, gflops, "start")
345      if (i1pert<=natom.and.(i2pert==natom+3.or.i2pert==natom+4)) then
346        call dfptlw_geom(cg,d3etot_tgeom_k,dimffnl,dtset, &
347        &  ffnl_k,gs_hamkq,icg, &
348        &  i1dir,i2dir,i3dir,i1pert,i2pert,ikpt, &
349        &  isppol,istwf_k,kg_k,kpt,mkmem_rbz,mpi_enreg,natom,mpw,nband_k,n2dq,nfft, &
350        &  ngfft,npw_k,nspden,nsppol,nylmgr,occ_k, &
351        &  psps,rmet,rprimd,useylmgr,vpsp1_i1pertdqdq,vpsp1_i1pertdq_geom,wtk_k,ylm_k,ylmgr_k)
352 
353        !Add the contribution from each k-point
354        d3etot_tgeom=d3etot_tgeom + d3etot_tgeom_k
355      end if
356      call cwtime(cpu, wall, gflops, "stop")
357 
358 !    Keep track of total number of bands
359      bandtot = bandtot + nband_k
360      bd2tot = bd2tot + 2*nband_k**2
361 
362 !    Shift arrays memory
363      icg=icg+npw_k*dtset%nspinor*nband_k
364      ikg=ikg+npw_k
365 
366      ABI_FREE(eig1_k)
367      ABI_FREE(eig2_k)
368      ABI_FREE(occ_k)
369      ABI_FREE(kg_k)
370      ABI_FREE(ylm_k)
371      ABI_FREE(ylmgr_k)
372      ABI_FREE(ffnl_k)
373 
374    end do !ikpt
375 
376  end do !isppol
377 
378 
379 !=== MPI communications ==================
380  if (xmpi_paral==1) then
381    call xmpi_sum(d3etot_t1,spaceworld,ierr)
382    call xmpi_sum(d3etot_t2,spaceworld,ierr)
383    call xmpi_sum(d3etot_t3,spaceworld,ierr)
384    call xmpi_sum(d3etot_t4,spaceworld,ierr)
385    call xmpi_sum(d3etot_t5,spaceworld,ierr)
386    call xmpi_sum(d3etot_tgeom,spaceworld,ierr)
387  end if
388 
389 !Apply +i or -i in case of strain perturbation.
390  if (i1pert==natom+3.or.i1pert==natom+4) then
391    tmpre=d3etot_telec(1);tmpim=d3etot_telec(2) ; d3etot_telec(1)=tmpim;d3etot_telec(2)=-tmpre
392    tmpre=d3etot_t1(1);tmpim=d3etot_t1(2) ; d3etot_t1(1)=tmpim;d3etot_t1(2)=-tmpre
393    tmpre=d3etot_t2(1);tmpim=d3etot_t2(2) ; d3etot_t2(1)=tmpim;d3etot_t2(2)=-tmpre
394    tmpre=d3etot_t3(1);tmpim=d3etot_t3(2) ; d3etot_t3(1)=tmpim;d3etot_t3(2)=-tmpre
395    do idq=1,n2dq
396      tmpre=d3etot_t4(1,idq);tmpim=d3etot_t4(2,idq) ; d3etot_t4(1,idq)=tmpim;d3etot_t4(2,idq)=-tmpre
397    end do
398    do idq=1,n1dq
399      tmpre=d3etot_t5(1,idq);tmpim=d3etot_t5(2,idq) ; d3etot_t5(1,idq)=tmpim;d3etot_t5(2,idq)=-tmpre
400    end do
401  end if
402  if (i2pert==natom+3.or.i2pert==natom+4) then
403    tmpre=d3etot_telec(1);tmpim=d3etot_telec(2) ; d3etot_telec(1)=-tmpim;d3etot_telec(2)=tmpre
404    tmpre=d3etot_t1(1);tmpim=d3etot_t1(2) ; d3etot_t1(1)=-tmpim;d3etot_t1(2)=tmpre
405    tmpre=d3etot_t2(1);tmpim=d3etot_t2(2) ; d3etot_t2(1)=-tmpim;d3etot_t2(2)=tmpre
406    tmpre=d3etot_t3(1);tmpim=d3etot_t3(2) ; d3etot_t3(1)=-tmpim;d3etot_t3(2)=tmpre
407    do idq=1,n2dq
408      tmpre=d3etot_t4(1,idq);tmpim=d3etot_t4(2,idq) ; d3etot_t4(1,idq)=-tmpim;d3etot_t4(2,idq)=tmpre
409      if (i1pert<=natom) then
410        tmpre=d3etot_tgeom(1,idq);tmpim=d3etot_tgeom(2,idq) ; d3etot_tgeom(1,idq)=-tmpim;d3etot_tgeom(2,idq)=tmpre
411      end if
412    end do
413    do idq=1,n1dq
414      tmpre=d3etot_t5(1,idq);tmpim=d3etot_t5(2,idq) ; d3etot_t5(1,idq)=-tmpim;d3etot_t5(2,idq)=tmpre
415    end do
416  end if
417 
418 !Join all the contributions in e3tot except t4 and t5 which may need to be
419 !converted to type-II in case of strain perturbation. 
420 !Apply here the two factor to the stationary wf1 contributions 
421 !(see PRB 105, 064101 (2022))
422  d3etot_t1(:)=two*d3etot_t1(:)
423  d3etot_t2(:)=two*d3etot_t2(:)
424  d3etot_t3(:)=two*d3etot_t3(:)
425  d3etot_t4(:,:)=two*d3etot_t4(:,:)
426  d3etot_t5(:,:)=two*d3etot_t5(:,:)
427  e3tot(:)=d3etot_t1(:)+d3etot_t2(:)+d3etot_t3(:)+d3etot_telec(:)
428 
429 
430 !Before printing, set small contributions to zero
431  !Real parts
432  if (abs(d3etot_t1(1))<tol8) d3etot_t1(1)= zero
433  if (abs(d3etot_t2(1))<tol8) d3etot_t2(1)= zero
434  if (abs(d3etot_t3(1))<tol8) d3etot_t3(1)= zero
435  do idq=1,n2dq
436    if (abs(d3etot_t4(1,idq))<tol8) d3etot_t4(1,idq)= zero
437    if (abs(d3etot_tgeom(1,idq))<tol8) d3etot_tgeom(1,idq)= zero
438  end do 
439  do idq=1,n1dq
440    if (abs(d3etot_t5(1,idq))<tol8) d3etot_t5(1,idq)= zero
441  end do 
442  if (abs(d3etot_telec(1))<tol8) d3etot_telec(1)= zero
443  if (abs(e3tot(1))    <tol8)     e3tot(1)= zero
444 
445  !Imaginary parts
446  if (abs(d3etot_t1(2))<tol8) d3etot_t1(2)= zero
447  if (abs(d3etot_t2(2))<tol8) d3etot_t2(2)= zero
448  if (abs(d3etot_t3(2))<tol8) d3etot_t3(2)= zero
449  do idq=1,n2dq
450    if (abs(d3etot_t4(2,idq))<tol8) d3etot_t4(2,idq)= zero
451    if (abs(d3etot_tgeom(2,idq))<tol8) d3etot_tgeom(2,idq)= zero
452  end do
453  do idq=1,n1dq
454    if (abs(d3etot_t5(2,idq))<tol8) d3etot_t5(2,idq)= zero
455  end do
456  if (abs(d3etot_telec(2))<tol8) d3etot_telec(2)= zero
457  if (abs(e3tot(2))    <tol8)     e3tot(2)= zero
458 
459  if (dtset%prtvol>=10) then
460    write(msg,'(4(a,2(a,f18.8)),a)') &
461    ch10,'          d3etot_telec = ',d3etot_telec(1),  ',',d3etot_telec(2),&
462    ch10,'             d3etot_t1 = ',d3etot_t1(1),  ',',d3etot_t1(2),&
463    ch10,'             d3etot_t2 = ',d3etot_t2(1),  ',',d3etot_t2(2),&
464    ch10,'             d3etot_t3 = ',d3etot_t3(1),  ',',d3etot_t3(2)
465    call wrtout(std_out,msg,'COLL')
466    call wrtout(ab_out,msg,'COLL')
467    if (n2dq==1) then
468      write(msg,'(2(a,f18.8))') &
469      '             d3etot_t4 = ',d3etot_t4(1,1),  ',',d3etot_t4(2,1)
470    else if (n2dq==2) then
471      write(msg,'(2(2(a,f18.8),a))') &
472      '   d3etot_t4(dw shear) = ',d3etot_t4(1,1),  ',',d3etot_t4(2,1),ch10,&
473      '   d3etot_t4(up shear) = ',d3etot_t4(1,2),  ',',d3etot_t4(2,2)
474    end if
475    call wrtout(std_out,msg,'COLL')
476    call wrtout(ab_out,msg,'COLL')
477    if (n1dq==1) then
478      write(msg,'(2(a,f18.8))') &
479      '             d3etot_t5 = ',d3etot_t5(1,1),  ',',d3etot_t5(2,1)
480    else if (n1dq==2) then
481      write(msg,'(2(2(a,f18.8),a))') &
482      '   d3etot_t5(dw shear) = ',d3etot_t5(1,1),  ',',d3etot_t5(2,1),ch10,&
483      '   d3etot_t5(up shear) = ',d3etot_t5(1,2),  ',',d3etot_t5(2,2)
484    end if
485    call wrtout(std_out,msg,'COLL')
486    call wrtout(ab_out,msg,'COLL')
487    if (i1pert<=natom.and.(i2pert==natom+3.or.i2pert==natom+4)) then
488      if (n2dq==1) then
489        write(msg,'(2(a,f18.8))') &
490        '          d3etot_tgeom = ',d3etot_tgeom(1,1),  ',',d3etot_tgeom(2,1)
491      else if (n2dq==2) then
492        write(msg,'(2(2(a,f18.8),a))') &
493        'd3etot_tgeom(dw shear) = ',d3etot_tgeom(1,1),  ',',d3etot_tgeom(2,1),ch10,&
494        'd3etot_tgeom(up shear) = ',d3etot_tgeom(1,2),  ',',d3etot_tgeom(2,2)
495      end if
496      call wrtout(std_out,msg,'COLL')
497      call wrtout(ab_out,msg,'COLL')
498    end if
499  end if
500 
501  d3etot(:,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)=e3tot(:)
502 
503 !Deallocations
504 
505  DBG_EXIT("COLL")
506 
507 end subroutine dfptlw_pert

ABINIT/m_dfptlw_pert/lw_elecstic [ Functions ]

[ Top ] [ Functions ]

NAME

  lw_elecstic

FUNCTION

  This routine calculates the electrostatic term of the spatial-dispersion
  third-order energy derivative for a couple of perturbations and a gradient
  direction.

COPYRIGHT

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

INPUTS

  cplex= if 1, real space 1-order functions on FFT grid are REAL,
          if 2, COMPLEX
  gmet(3,3)=reciprocal space metric tensor in bohr**-2
  gprimd(3,3)=reciprocal space dimensional primitive translations
  gsqcut=large sphere cut-off
  i3dir= directions of the 3th perturbations
  kxc(nfft,nkxc)=exchange and correlation kernel
  mpi_enreg=information about MPI parallelization
  nfft= number of FFT grid points (for this proc) 
  ngfft(1:18)=integer array with FFT box dimensions and other 
  nkxc=second dimension of the kxc array. If /=0, the XC kernel must be computed.
  nspden = number of spin-density components
  rho1g1(2,nfft)=G-space RF electron density in electrons/bohr**3 (i1pert)
  rho1r1(cplex*nfft,nspden)=RF electron density in electrons/bohr**3 (i1pert)
  rho2r1(cplex*nfft,nspden)=RF electron density in electrons/bohr**3 (i2pert)
  ucvol=volume of the unit cell

OUTPUT

  d3etot_telec(2)= Electrostatic term of the third-order energy derivative

SIDE EFFECTS

NOTES

PARENTS

CHILDREN

SOURCE

556 #if defined HAVE_CONFIG_H
557 #include "config.h"
558 #endif
559 
560 #include "abi_common.h"
561 
562 
563 subroutine lw_elecstic(cplex,d3etot_telec,gmet,gprimd,gsqcut,&
564 & i3dir,kxc,mpi_enreg,nfft,ngfft,nkxc,nspden,rho1g1,rho1r1,rho2r1,ucvol)
565     
566  use defs_basis
567  use m_errors
568  use m_profiling_abi
569 
570  implicit none
571 
572 !Arguments ------------------------------------
573  integer,intent(in) :: cplex,i3dir
574  integer,intent(in) :: nfft,nkxc,nspden
575  real(dp),intent(in) :: gsqcut,ucvol
576  type(MPI_type),intent(inout) :: mpi_enreg
577 !arrays
578  integer,intent(in) :: ngfft(18)
579  real(dp),intent(in) :: gmet(3,3),gprimd(3,3)
580  real(dp),intent(in) :: rho1g1(2,nfft),rho1r1(cplex*nfft,nspden)
581  real(dp),intent(in) :: rho2r1(cplex*nfft,nspden),kxc(nfft,nkxc)
582  real(dp),intent(out) :: d3etot_telec(2)
583 
584 !Local variables-------------------------------
585 !scalars
586  integer :: ii,jj,nfftot,qcar
587  real(dp) :: doti,dotr
588 
589 !arrays
590  real(dp),allocatable :: rhor1_cplx(:,:)
591  real(dp),allocatable :: vxc1dq(:,:),vxc1dq_car(:,:,:),vqgradhart(:)
592  
593 ! *************************************************************************
594 
595  DBG_ENTER("COLL")
596  
597 !If GGA xc first calculate the Cartesian q gradient of the xc kernel
598  if (nkxc == 7) then
599    ABI_MALLOC(vxc1dq,(2*nfft,nspden))
600    ABI_MALLOC(vxc1dq_car,(2*nfft,nspden,3))
601    do qcar=1,3
602      call dfpt_mkvxcggadq(cplex,gprimd,kxc,mpi_enreg,nfft,ngfft,nkxc,nspden,qcar,rho1r1,vxc1dq)
603      vxc1dq_car(:,:,qcar)=vxc1dq(:,:)
604    end do
605  end if
606 
607 !Calculate the q gradient of the Hartree potential
608  ABI_MALLOC(vqgradhart,(2*nfft))
609  call hartredq(2,gmet,gsqcut,mpi_enreg,nfft,ngfft,i3dir,rho1g1,vqgradhart)
610 
611 !If GGA convert the gradient of xc kernel to reduced coordinates and incorporate it to the Hartree part
612  if (nkxc == 7) then
613    vxc1dq=zero
614    do qcar=1,3
615      vxc1dq(:,:)=vxc1dq(:,:) + gprimd(qcar,i3dir) * vxc1dq_car(:,:,qcar)
616    end do
617    vqgradhart(:)=vqgradhart(:)+vxc1dq(:,1)
618    ABI_FREE(vxc1dq_car)
619  end if
620 
621 !Calculate the electrostatic energy term with the i2pert density response
622 !I need a complex density for the dotprod_vn
623  ABI_MALLOC(rhor1_cplx,(2*nfft,nspden))
624  rhor1_cplx=zero
625  do ii=1,nfft
626    jj=ii*2
627    rhor1_cplx(jj-1,:)=rho2r1(ii,:)
628  end do
629 
630  nfftot=ngfft(1)*ngfft(2)*ngfft(3)
631  call dotprod_vn(2,rhor1_cplx,dotr,doti,nfft,nfftot,nspden,2,vqgradhart,ucvol)
632  
633  d3etot_telec(1)=dotr
634  d3etot_telec(2)=doti
635 
636 !Deallocations
637  ABI_SFREE(vxc1dq)
638  ABI_FREE(vqgradhart)
639  ABI_FREE(rhor1_cplx)
640 
641  DBG_EXIT("COLL")
642 
643 end subroutine lw_elecstic

ABINIT/m_dfptlw_pert/preca_ffnl [ Functions ]

[ Top ] [ Functions ]

NAME

  preca_ffnl

FUNCTION

  Calculates the nonlocal form factors and derivatives for all the atoms
  and k points.

COPYRIGHT

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

INPUTS

  dimffnl= second dimension of ffnl
  gmet(3,3)= reciprocal-space metric tensor
  gprimd(3,3)= dimensional reciprocal space primitive translations (b^-1)
  ider= if 1 first order derivatives of ffnl are calculated
        if 2 first and second order derivatives of ffnl are calculated
  idir0= variable that controls the way in which the derivatives of ffnl are
         calculated and saved
  kg(3,mpw)=integer coordinates of G vectors in basis sphere
  kptns(3,nkpt)=k points in terms of reciprocal translations
  mband= masimum number of bands
  mkmem= maximum number of k points which can fit in core memory
  mpi_enreg=information about MPI parallelization
  mpw   = maximum number of planewaves in basis sphere (large number)
  nkpt = number of k point
  npwarr(nkpt)=array holding npw for each k point
  nylmgr=second dimension of ylmgr
  psps <type(pseudopotential_type)> = variables related to pseudopotentials
  rmet(3,3)= real-space metric tensor
  useylmgr= if 1 use the derivative of spherical harmonics
  ylm(mpw*mkmem,psps%mpsang*psps%mpsang*psps%useylm)=real spherical harmonics
  ylmgr(mpw*mkmem,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr)= k-gradients of real spherical harmonics

OUTPUT

  ffnl(mkmem,npw_k,dimffnl,psps%lmnmax,psps%ntypat)= Nonlocal projectors and their derivatives

SIDE EFFECTS

NOTES

PARENTS

CHILDREN

SOURCE

696 #if defined HAVE_CONFIG_H
697 #include "config.h"
698 #endif
699 
700 #include "abi_common.h"
701 
702 
703 subroutine preca_ffnl(dimffnl,ffnl,gmet,gprimd,ider,idir0,kg,kptns,mband,mkmem,mpi_enreg,mpw,nkpt, &
704 & npwarr,nylmgr,psps,rmet,useylmgr,ylm,ylmgr)
705     
706  use defs_basis
707  use m_errors
708  use m_profiling_abi
709 
710  implicit none
711 
712 !Arguments ------------------------------------
713 !scalars
714  integer , intent(in)  :: dimffnl,ider,idir0,mband,mkmem,mpw,nkpt,nylmgr,useylmgr
715  type(pseudopotential_type),intent(in) :: psps
716  type(MPI_type),intent(in) :: mpi_enreg
717 !arrays
718  integer,intent(in) :: kg(3,mpw*mkmem)
719  integer,intent(in) :: npwarr(nkpt)
720  real(dp),intent(in) :: gmet(3,3),gprimd(3,3),kptns(3,nkpt),rmet(3,3)
721  real(dp),intent(in) :: ylm(mpw*mkmem,psps%mpsang*psps%mpsang*psps%useylm)
722  real(dp),intent(in) :: ylmgr(mpw*mkmem,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr)
723  real(dp),intent(out) :: ffnl(mkmem,mpw,dimffnl,psps%lmnmax,psps%ntypat)                       
724 
725 !Local variables-------------------------------
726 !scalars
727  integer :: ii,ikc,ikg,ikpt,ilm,nkpg,npw_k
728  character(len=500) :: msg
729 !arrays
730  integer,allocatable :: kg_k(:,:)
731  real(dp) :: kpt(3)
732  real(dp),allocatable :: ffnl_k(:,:,:,:),kpg_k(:,:)
733  real(dp),allocatable :: ylm_k(:,:),ylmgr_k(:,:,:),ylmgr_k_part(:,:,:)
734  
735 ! *************************************************************************
736 
737  DBG_ENTER("COLL")
738 
739  !Loop over k-points
740  ikg=0
741  ikc=0
742  do ikpt = 1, nkpt
743  
744    npw_k = npwarr(ikpt)
745    if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,mband,1,mpi_enreg%me)) then
746      cycle ! Skip the rest of the k-point loop
747    end if
748    ikc= ikc + 1
749 
750    ABI_MALLOC(kg_k,(3,npw_k))
751    ABI_MALLOC(ylm_k,(npw_k,psps%mpsang*psps%mpsang*psps%useylm))
752    ABI_MALLOC(ylmgr_k,(npw_k,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr))
753 
754    kpt(:)= kptns(:,ikpt)
755 
756    !Get plane-wave vectors and related data at k
757    kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
758    if (psps%useylm==1) then
759      do ilm=1,psps%mpsang*psps%mpsang
760        ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm)
761      end do
762      if (useylmgr==1) then
763        do ilm=1,psps%mpsang*psps%mpsang
764          do ii=1,nylmgr
765            ylmgr_k(1:npw_k,ii,ilm)=ylmgr(1+ikg:npw_k+ikg,ii,ilm)
766          end do
767        end do
768      end if
769    end if
770 
771    if (dimffnl==2.or.dimffnl==4) then
772      ABI_MALLOC(ylmgr_k_part,(npw_k,3,psps%mpsang*psps%mpsang*psps%useylm*useylmgr))
773      ylmgr_k_part(:,:,:)=ylmgr_k(:,1:3,:)
774    else if (dimffnl==10) then
775      ABI_MALLOC(ylmgr_k_part,(npw_k,nylmgr,psps%mpsang*psps%mpsang*psps%useylm*useylmgr))
776      ylmgr_k_part(:,:,:)=ylmgr_k(:,:,:)
777    else 
778      msg='wrong size for ffnl via dimffnl!'
779      ABI_BUG(msg)
780    end if
781 
782 
783    nkpg=0
784    ABI_MALLOC(kpg_k,(npw_k,nkpg))
785    ABI_MALLOC(ffnl_k,(npw_k,dimffnl,psps%lmnmax,psps%ntypat))
786    call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnl_k,psps%ffspl,gmet,gprimd,ider,idir0,&
787  & psps%indlmn,kg_k,kpg_k,kpt,psps%lmnmax,psps%lnmax,psps%mpsang,psps%mqgrid_ff,nkpg,&
788  & npw_k,psps%ntypat,psps%pspso,psps%qgrid_ff,rmet,psps%usepaw,psps%useylm,ylm_k,ylmgr_k_part)
789 
790    ffnl(ikc,1:npw_k,:,:,:)=ffnl_k(1:npw_k,:,:,:)
791 
792    ABI_FREE(kg_k)
793    ABI_FREE(ylm_k)
794    ABI_FREE(ylmgr_k)
795    ABI_FREE(ylmgr_k_part)
796    ABI_FREE(ffnl_k)
797    ABI_FREE(kpg_k)
798 
799    !Shift arrays memory
800    ikg=ikg+npw_k
801 
802  end do
803 
804  DBG_EXIT("COLL")
805 
806 end subroutine preca_ffnl