Line data Source code
1 : !!****m* ABINIT/m_getgh2c
2 : !! NAME
3 : !! m_getgh2c
4 : !!
5 : !! FUNCTION
6 : !!
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2015-2026 ABINIT group (MT,JLJ)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : ! nvtx related macro definition
23 : #include "nvtx_macros.h"
24 :
25 : module m_getgh2c
26 :
27 : use defs_basis
28 : use m_abicore
29 : use m_errors
30 :
31 : use defs_abitypes, only : mpi_type
32 : use m_pawcprj, only : pawcprj_type,pawcprj_alloc,pawcprj_free
33 : use m_hamiltonian, only : gs_hamiltonian_type,rf_hamiltonian_type
34 : use m_nonlop, only : nonlop
35 :
36 : #if defined(HAVE_GPU_MARKERS)
37 : use m_nvtx_data
38 : #endif
39 :
40 : implicit none
41 :
42 : private
43 : !!***
44 :
45 : public :: getgh2c
46 : !!***
47 :
48 : contains
49 : !!***
50 :
51 : !!****f* ABINIT/getgh2c
52 : !! NAME
53 : !! getgh2c
54 : !!
55 : !! FUNCTION
56 : !! Compute <G|H^(2)|C> (or <G|H^(2)-Eps.S^(2)|C>) for input vector |C> expressed in reciprocal space.
57 : !! (H^(2) is the 2nd-order pertubed Hamiltonian, S^(2) is the 2nd-order perturbed overlap operator).
58 : !! Result is put in array gh2c.
59 : !! If required, part of <G|K(2)+Vnonlocal^(2)|C> not depending on VHxc^(2) is also returned in gvnl2.
60 : !! If required, <G|S^(2)|C> is returned in gs2c (S=overlap - PAW only)
61 : !! Available for the following cases :
62 : !! ipert = natom+10 (dkdk) : 2nd derivative w.r.t wavevector
63 : !! natom+11 (dkdE) : mixed 2nd derivative w.r.t wavector and eletric field
64 : !! also if natom+12<=ipert<=2*natom+11 :
65 : !! (dtaudE) : mixed 2nd derivative w.r.t atom. displ. and eletric field (nonlocal only)
66 : !!
67 : !! INPUTS
68 : !! cwavef(2,npw*nspinor)=input wavefunction, in reciprocal space
69 : !! cwaveprj(natom,nspinor*usecprj)=<p_lmn|C> coefficients for wavefunction |C>
70 : !! gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian
71 : !! idir=direction of the perturbation
72 : !! ipert=type of the perturbation
73 : !! lambda=real use to apply H^(2)-lambda.S^(2)
74 : !! mpi_enreg=information about MPI parallelization
75 : !! optlocal=0: local part of H^(2) is not computed in gh2c=<G|H^(2)|C>
76 : !! 1: local part of H^(2) is computed in gh2c=<G|H^(2)|C>
77 : !! optnl=0: non-local part of H^(2) is not computed in gh2c=<G|H^(2)|C>
78 : !! 1: non-local part of H^(2) depending on VHxc^(2) is not computed in gh2c=<G|H^(2)|C>
79 : !! 2: non-local part of H^(2) is totally computed in gh2c=<G|H^(2)|C>
80 : !! opt_gvnl2=option controlling the use of gvnl2 array:
81 : !! 0: not used
82 : !! 1: used as input: - used only for PAW and ipert=natom+11/+12
83 : !! At input: contains the derivative w.r.t wavevector of cwavef (times i)
84 : !! rf_hamkq <type(rf_hamiltonian_type)>=all data for the 2nd-order Hamiltonian at k,k+q
85 : !! sij_opt= -PAW ONLY- if 0, only matrix elements <G|H^(2)|C> have to be computed
86 : !! (S=overlap) if 1, matrix elements <G|S^(2)|C> have to be computed in gs2c in addition to gh2c
87 : !! if -1, matrix elements <G|H^(2)-lambda.S^(2)|C> have to be computed in gh2c (gs2c not used)
88 : !! tim_getgh2c=timing code of the calling subroutine (can be set to 0 if not attributed)
89 : !! usevnl=1 if gvnl2=(part of <G|K^(2)+Vnl^(2)-lambda.S^(2)|C> not depending on VHxc^(2)) has to be input/output
90 : !!
91 : !! OUTPUT
92 : !! gh2c(2,npw1*nspinor)= <G|H^(2)|C> or <G|H^(2)-lambda.S^(2)|C>
93 : !! (only kinetic+non-local parts if optlocal=0)
94 : !! if (usevnl==1)
95 : !! gvnl2(2,npw1*nspinor)= part of <G|K^(2)+Vnl^(2)|C> not depending on VHxc^(2) (sij_opt/=-1)
96 : !! or part of <G|K^(2)+Vnl^(2)-lambda.S^(2)|C> not depending on VHxc^(2) (sij_opt==-1)
97 : !! if (sij_opt=1)
98 : !! gs2c(2,npw1*nspinor)=<G|S^(2)|C> (S=overlap).
99 : !!
100 : !! SOURCE
101 :
102 72096 : subroutine getgh2c(cwavef,cwaveprj,gh2c,gs2c,gs_hamkq,gvnl2,idir,ipert,lambda,&
103 23040 : & mpi_enreg,optlocal,optnl,opt_gvnl2,rf_hamkq,sij_opt,tim_getgh2c,usevnl,conj,enl,optkin)
104 :
105 : !Arguments ------------------------------------
106 : !scalars
107 : logical,intent(in),optional :: conj
108 : integer,intent(in) :: idir,ipert,optlocal,optnl,opt_gvnl2,sij_opt,tim_getgh2c,usevnl
109 : integer,intent(in),optional :: optkin
110 : real(dp),intent(in) :: lambda
111 : type(MPI_type),intent(in) :: mpi_enreg
112 : type(gs_hamiltonian_type),intent(inout),target :: gs_hamkq
113 : type(rf_hamiltonian_type),intent(inout),target :: rf_hamkq
114 : !arrays
115 : real(dp),intent(in),optional,target :: enl(gs_hamkq%dimekb1,gs_hamkq%dimekb2,gs_hamkq%nspinor**2,gs_hamkq%dimekbq)
116 : real(dp),intent(inout) :: cwavef(:,:)
117 : real(dp),intent(inout),target :: gvnl2(:,:)
118 : real(dp),intent(out) :: gh2c(:,:),gs2c(:,:)
119 : type(pawcprj_type),intent(inout),target :: cwaveprj(:,:)
120 :
121 : !Local variables-------------------------------
122 : !scalars
123 : integer,parameter :: tim_nonlop=0
124 : integer :: choice,cpopt,iatm,idir1,idir2,idirc,ipw,ipws,ispinor,my_nspinor
125 : integer :: natom,ncpgr,nnlout=1,npw,npw1,paw_opt,signs,usecprj
126 : logical :: compute_conjugate,has_kin,has_vnl,pert_phon_elfd
127 : real(dp) :: enlout_dum(1)
128 : character(len=500) :: msg
129 : !arrays
130 : ! integer,parameter :: alpha(6)=(/1,2,3,3,3,2/),beta(6)=(/1,2,3,2,1,1/)
131 : integer,parameter :: alpha(9)=(/1,2,3,2,1,1,3,3,2/),beta(9)=(/1,2,3,3,3,2,2,1,1/)
132 : !real(dp) :: tsec(2)
133 : real(dp) :: svectout_dum(1,1),vectout_dum(1,1)
134 72096 : real(dp),allocatable :: nonlop_out(:,:)
135 72096 : real(dp), pointer :: gvnl2_(:,:)
136 72096 : real(dp), pointer :: ddkinpw(:),kinpw1(:),enl_ptr(:,:,:,:)
137 72096 : real(dp),allocatable,target :: enl_temp(:,:,:,:)
138 72096 : type(pawcprj_type),allocatable,target :: cwaveprj_tmp(:,:)
139 72096 : type(pawcprj_type),pointer :: cwaveprj_ptr(:,:)
140 :
141 : ! *********************************************************************
142 :
143 : DBG_ENTER("COLL")
144 : ABI_UNUSED(tim_getgh2c)
145 : ABI_NVTX_START_RANGE(NVTX_GETGH2C)
146 :
147 : !Keep track of total time spent in getgh2c
148 : !call timab(196+tim_getgh2c,1,tsec)
149 :
150 : !======================================================================
151 : !== Initialisations and compatibility tests
152 : !======================================================================
153 :
154 72096 : npw =gs_hamkq%npw_k
155 72096 : npw1 =gs_hamkq%npw_kp
156 72096 : natom=gs_hamkq%natom
157 :
158 : !Compatibility tests
159 25920 : if(ipert/=natom+10.and.ipert/=natom+11.and.ipert>2*natom+11)then
160 0 : msg='only ipert==natom+10/+11 and natom+11<=ipert<=2*natom+11 implemented!'
161 0 : ABI_BUG(msg)
162 : end if
163 72096 : pert_phon_elfd = .false.
164 72096 : if (ipert>natom+11.and.ipert<=2*natom+11) pert_phon_elfd = .true.
165 72096 : if (mpi_enreg%paral_spinor==1) then
166 0 : msg='Not compatible with parallelization over spinorial components!'
167 0 : ABI_BUG(msg)
168 : end if
169 72096 : if (gs_hamkq%nvloc>1) then
170 0 : msg='Not compatible with nvloc=4 (non-coll. magnetism)!'
171 0 : ABI_BUG(msg)
172 : end if
173 72096 : if((ipert==natom+11.or.pert_phon_elfd).and.gs_hamkq%usepaw==1.and.optnl>=1) then
174 25920 : if (gs_hamkq%nvloc>1) then
175 0 : msg='Not compatible with nvloc=4 (non-coll. magnetism)!'
176 0 : ABI_BUG(msg)
177 : end if
178 25920 : if (present(enl)) then
179 23040 : enl_ptr => enl
180 2880 : else if (associated(rf_hamkq%e1kbfr).and.associated(rf_hamkq%e1kbsc).and.optnl==2) then
181 2880 : ABI_CHECK(size(rf_hamkq%e1kbfr,4)==1,'BUG in getgh2c: qphase>1!')
182 2880 : ABI_CHECK(size(rf_hamkq%e1kbsc,4)==1,'BUG in getgh2c: qphase>1!')
183 17280 : ABI_MALLOC(enl_temp,(gs_hamkq%dimekb1,gs_hamkq%dimekb2,gs_hamkq%nspinor**2,gs_hamkq%dimekbq))
184 221760 : enl_temp(:,:,:,:) = rf_hamkq%e1kbfr(:,:,:,:) + rf_hamkq%e1kbsc(:,:,:,:)
185 2880 : enl_ptr => enl_temp
186 0 : else if (associated(rf_hamkq%e1kbfr)) then
187 0 : ABI_CHECK(size(rf_hamkq%e1kbfr,4)==1,'BUG in getgh2c: qphase>1!')
188 0 : enl_ptr => rf_hamkq%e1kbfr
189 : else
190 0 : msg='For ipert=natom+11/pert_phon_elfd : e1kbfr and/or e1kbsc must be associated or enl optional input must be present.'
191 0 : ABI_BUG(msg)
192 : end if
193 25920 : if (usevnl==0) then
194 0 : msg='gvnl2 must be allocated for ipert=natom+11/pert_phon_elfd !'
195 0 : ABI_BUG(msg)
196 : end if
197 25920 : if(opt_gvnl2==0) then
198 0 : msg='opt_gvnl2=0 not compatible with ipert=natom+11/pert_phon_elfd !'
199 0 : ABI_BUG(msg)
200 : end if
201 : end if
202 :
203 : !Check sizes
204 72096 : my_nspinor=max(1,gs_hamkq%nspinor/mpi_enreg%nproc_spinor)
205 216288 : if (size(cwavef)<2*npw*my_nspinor) then
206 0 : msg='wrong size for cwavef!'
207 0 : ABI_BUG(msg)
208 : end if
209 216288 : if (size(gh2c)<2*npw1*my_nspinor) then
210 0 : msg='wrong size for gh2c!'
211 0 : ABI_BUG(msg)
212 : end if
213 72096 : if (usevnl/=0) then
214 77760 : if (size(gvnl2)<2*npw1*my_nspinor) then
215 0 : msg='wrong size for gvnl2!'
216 0 : ABI_BUG(msg)
217 : end if
218 : end if
219 72096 : if (sij_opt==1) then
220 14400 : if (size(gs2c)<2*npw1*my_nspinor) then
221 0 : msg='wrong size for gs2c!'
222 0 : ABI_BUG(msg)
223 : end if
224 : end if
225 :
226 : !PAW: specific treatment for usecprj input arg
227 : ! force it to zero if cwaveprj is not allocated
228 72096 : usecprj=gs_hamkq%usecprj ; ncpgr=0
229 72096 : if(gs_hamkq%usepaw==1) then
230 83520 : if (size(cwaveprj)==0) usecprj=0
231 960 : if (usecprj/=0) then
232 960 : ncpgr=cwaveprj(1,1)%ncpgr
233 2880 : if (size(cwaveprj)<gs_hamkq%natom*my_nspinor) then
234 0 : msg='wrong size for cwaveprj!'
235 0 : ABI_BUG(msg)
236 : end if
237 : end if
238 : else
239 44256 : if(usecprj==1)then
240 0 : msg='usecprj==1 not allowed for NC psps !'
241 0 : ABI_BUG(msg)
242 : end if
243 : end if
244 :
245 : ! tim_nonlop=8
246 : ! if (tim_getgh2c==1.and.ipert<=natom) tim_nonlop=7
247 : ! if (tim_getgh2c==2.and.ipert<=natom) tim_nonlop=5
248 : ! if (tim_getgh2c==1.and.ipert> natom) tim_nonlop=8
249 : ! if (tim_getgh2c==2.and.ipert> natom) tim_nonlop=5
250 : ! if (tim_getgh2c==3 ) tim_nonlop=0
251 :
252 72096 : idir1=alpha(idir);idir2=beta(idir)
253 :
254 72096 : compute_conjugate = .false.
255 72096 : if(present(conj)) compute_conjugate = conj
256 :
257 : !======================================================================
258 : !== Apply the 2nd-order local potential to the wavefunction
259 : !======================================================================
260 :
261 72096 : if (ipert/=natom+10.and.ipert/=natom+11.and.optlocal>0) then
262 0 : msg='local part not implemented'
263 0 : ABI_BUG(msg)
264 : else
265 : ! In the case of ddk operator, no local contribution (also because no self-consistency)
266 : !$OMP PARALLEL DO
267 8760796 : do ipw=1,npw1*my_nspinor
268 26138196 : gh2c(:,ipw)=zero
269 : end do
270 :
271 : end if
272 :
273 : !======================================================================
274 : !== Apply the 2st-order non-local potential to the wavefunction
275 : !======================================================================
276 :
277 72096 : has_vnl=(ipert==natom+10.or.ipert==natom+11.or.pert_phon_elfd)
278 :
279 : !Use of gvnl2 depends on usevnl
280 72096 : if (usevnl==1) then
281 25920 : gvnl2_ => gvnl2
282 : else
283 138528 : ABI_MALLOC(gvnl2_,(2,npw1*my_nspinor))
284 : end if
285 :
286 72096 : if (has_vnl.and.(optnl>0.or.sij_opt/=0)) then
287 :
288 72096 : idirc=3*(idir1-1)+idir2 !xx=1, xy=2, xz=3, yx=4, yy=5, yz=6, zx=7, zy=8, zz=9, (xyz,xyz)=(idir1,idir2)
289 :
290 : ! d^2[H_nl]/dk1dk2
291 : ! -------------------------------------------
292 72096 : if (ipert==natom+10) then
293 46176 : if (gs_hamkq%usepaw==1) then
294 1920 : if (usecprj==1) then
295 384 : cwaveprj_ptr => cwaveprj
296 : else
297 10752 : ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor))
298 1536 : call pawcprj_alloc(cwaveprj_tmp,0,gs_hamkq%dimcprj)
299 1536 : cwaveprj_ptr => cwaveprj_tmp
300 : end if
301 1920 : cpopt=-1+5*usecprj
302 1920 : choice=8; signs=2; paw_opt=1; if (sij_opt/=0) paw_opt=sij_opt+3
303 : call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idirc,(/lambda/),mpi_enreg,1,nnlout,&
304 3840 : & paw_opt,signs,gs2c,tim_nonlop,cwavef,gvnl2_)
305 1920 : if (usecprj==0) then
306 1536 : call pawcprj_free(cwaveprj_tmp)
307 4608 : ABI_FREE(cwaveprj_tmp)
308 : end if
309 1920 : nullify(cwaveprj_ptr)
310 : else
311 44256 : choice=8; signs=2; cpopt=-1 ; paw_opt=0
312 : call nonlop(choice,cpopt,cwaveprj,enlout_dum,gs_hamkq,idirc,(/zero/),mpi_enreg,1,nnlout,&
313 44256 : & paw_opt,signs,svectout_dum,tim_nonlop,cwavef,gvnl2_)
314 : end if
315 :
316 : ! d^2[H_nl]/dk1dE2 : Non-zero only in PAW
317 : ! -------------------------------------------
318 25920 : else if (ipert==natom+11.and.gs_hamkq%usepaw==1) then
319 :
320 8640 : ABI_MALLOC(nonlop_out,(2,npw1*my_nspinor))
321 :
322 2880 : if (usecprj==1) then
323 576 : cwaveprj_ptr => cwaveprj
324 : else
325 16128 : ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor))
326 2304 : call pawcprj_alloc(cwaveprj_tmp,2,gs_hamkq%dimcprj)
327 2304 : cwaveprj_ptr => cwaveprj_tmp
328 : end if
329 :
330 2880 : if (opt_gvnl2==1.and.optnl>=1) then
331 :
332 : ! Compute application of dS/dk1 to i*d[cwavef]/dk2
333 : ! sum_{i,j} s_ij d(|p_i><p_j|)/dk(idir1) | i*psi^(k(idir2)) >
334 2880 : cpopt=-1 ; choice=5 ; paw_opt=3 ; signs=2
335 : call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idir1,(/zero/),mpi_enreg,1,nnlout,&
336 2880 : & paw_opt,signs,nonlop_out,tim_nonlop,gvnl2_,vectout_dum)
337 :
338 : !$OMP PARALLEL DO
339 274320 : do ipw=1,npw1*my_nspinor
340 817200 : gvnl2_(:,ipw)=nonlop_out(:,ipw)
341 : end do
342 :
343 : ! Compute part of H^(2) due to derivative of projectors (idir1) and derivative of Dij (idir2)
344 : ! sum_{i,j} chi_ij(idir2) d(|p_i><p_j|)/dk(idir1) | psi^(0) >
345 2880 : cpopt=4*usecprj ; choice=5 ; paw_opt=1 ; signs=2
346 : call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idir1,(/zero/),mpi_enreg,1,nnlout,&
347 2880 : & paw_opt,signs,svectout_dum,tim_nonlop,cwavef,nonlop_out,enl=enl_ptr)
348 :
349 : !$OMP PARALLEL DO
350 274320 : do ipw=1,npw1*my_nspinor
351 817200 : gvnl2_(:,ipw)=gvnl2_(:,ipw)+nonlop_out(:,ipw)
352 : end do
353 :
354 : else
355 :
356 : !$OMP PARALLEL DO
357 0 : do ipw=1,npw1*my_nspinor
358 0 : gvnl2_(:,ipw)=zero
359 : end do
360 :
361 : end if ! opt_gvnl2==1
362 :
363 : ! Compute derivatives due to projectors |d^2[p_i]/dk1dk2>,|d[p_i]/dk1>,|d[p_i]/dk2>
364 : ! i * sum_{i,j} (d(|p_i><dp_j/dk(idir2)|)/dk(idir1) | psi^(0) >
365 2880 : cpopt=-1+5*usecprj ; choice=81 ; paw_opt=3 ; signs=2
366 : call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idirc,(/zero/),mpi_enreg,1,nnlout,&
367 2880 : & paw_opt,signs,nonlop_out,tim_nonlop,cwavef,vectout_dum)
368 :
369 2880 : if(compute_conjugate) then
370 : !$OMP PARALLEL DO
371 0 : do ipw=1,npw1*my_nspinor ! Note the multiplication by -i
372 0 : gvnl2_(1,ipw)=gvnl2_(1,ipw)+nonlop_out(2,ipw)
373 0 : gvnl2_(2,ipw)=gvnl2_(2,ipw)-nonlop_out(1,ipw)
374 : end do
375 : else
376 : !$OMP PARALLEL DO
377 274320 : do ipw=1,npw1*my_nspinor ! Note the multiplication by i
378 271440 : gvnl2_(1,ipw)=gvnl2_(1,ipw)-nonlop_out(2,ipw)
379 274320 : gvnl2_(2,ipw)=gvnl2_(2,ipw)+nonlop_out(1,ipw)
380 : end do
381 : end if
382 :
383 2880 : ABI_FREE(nonlop_out)
384 820080 : if (sij_opt==1) gs2c=zero
385 2880 : if (usecprj==0) then
386 2304 : call pawcprj_free(cwaveprj_tmp)
387 6912 : ABI_FREE(cwaveprj_tmp)
388 : end if
389 2880 : nullify(cwaveprj_ptr)
390 :
391 : ! d^2[H_nl]/dtau1dE2 : Non-zero only in PAW
392 : ! -------------------------------------------
393 23040 : else if (pert_phon_elfd.and.gs_hamkq%usepaw==1) then
394 :
395 23040 : iatm = ipert-(natom+11)
396 23040 : if (iatm<1.or.iatm>natom) then
397 0 : ABI_BUG(" iatm must be between 1 and natom")
398 : end if
399 :
400 69120 : ABI_MALLOC(nonlop_out,(2,npw1*my_nspinor))
401 :
402 23040 : if (usecprj==1) then
403 0 : cwaveprj_ptr => cwaveprj
404 : else
405 161280 : ABI_MALLOC(cwaveprj_tmp,(natom,my_nspinor))
406 23040 : call pawcprj_alloc(cwaveprj_tmp,2,gs_hamkq%dimcprj)
407 23040 : cwaveprj_ptr => cwaveprj_tmp
408 : end if
409 :
410 23040 : if (opt_gvnl2==1) then
411 :
412 : ! Compute application of dS/dtau1 to i*d[cwavef]/dk2
413 : ! sum_{i,j} s_ij d(|p_i><p_j|)/dtau(idir1) | i*psi^(k(idir2)) >
414 23040 : cpopt=-1 ; choice=2 ; paw_opt=3 ; signs=2
415 : call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idir1,(/zero/),mpi_enreg,1,nnlout,&
416 23040 : & paw_opt,signs,nonlop_out,tim_nonlop,gvnl2_,vectout_dum,iatom_only=iatm)
417 :
418 : !$OMP PARALLEL DO
419 2194560 : do ipw=1,npw1*my_nspinor
420 6537600 : gvnl2_(:,ipw)=nonlop_out(:,ipw)
421 : end do
422 :
423 : ! Compute part of H^(2) due to derivative of projectors (idir1) and derivative of Dij (idir2)
424 : ! sum_{i,j} chi_ij(idir2) d(|p_i><p_j|)/dtau(idir1) | psi^(0) >
425 23040 : cpopt=4*usecprj ; choice=2 ; paw_opt=1 ; signs=2
426 : call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idir1,(/zero/),mpi_enreg,1,nnlout,&
427 23040 : & paw_opt,signs,svectout_dum,tim_nonlop,cwavef,nonlop_out,enl=enl_ptr,iatom_only=iatm)
428 :
429 : !$OMP PARALLEL DO
430 2194560 : do ipw=1,npw1*my_nspinor
431 6537600 : gvnl2_(:,ipw)=gvnl2_(:,ipw)+nonlop_out(:,ipw)
432 : end do
433 :
434 : else
435 :
436 : !$OMP PARALLEL DO
437 0 : do ipw=1,npw1*my_nspinor
438 0 : gvnl2_(:,ipw)=zero
439 : end do
440 :
441 : end if ! opt_gvnl2==1
442 :
443 : ! Compute derivatives due to projectors |d^2[p_i]/dtau1dk2>,|d[p_i]/dtau1>,|d[p_i]/dk2>
444 : ! i * sum_{i,j} (d(|p_i><dp_j/dk(idir2)|)/dtau(idir1) | psi^(0) >
445 23040 : cpopt=-1+5*usecprj ; choice=54 ; paw_opt=3 ; signs=2
446 : call nonlop(choice,cpopt,cwaveprj_ptr,enlout_dum,gs_hamkq,idirc,(/zero/),mpi_enreg,1,nnlout,&
447 23040 : & paw_opt,signs,nonlop_out,tim_nonlop,cwavef,vectout_dum,iatom_only=iatm)
448 :
449 23040 : if(compute_conjugate) then
450 : !$OMP PARALLEL DO
451 0 : do ipw=1,npw1*my_nspinor ! Note the multiplication by -i
452 0 : gvnl2_(1,ipw)=gvnl2_(1,ipw)+nonlop_out(2,ipw)
453 0 : gvnl2_(2,ipw)=gvnl2_(2,ipw)-nonlop_out(1,ipw)
454 : end do
455 : else
456 : !$OMP PARALLEL DO
457 2194560 : do ipw=1,npw1*my_nspinor ! Note the multiplication by i
458 2171520 : gvnl2_(1,ipw)=gvnl2_(1,ipw)-nonlop_out(2,ipw)
459 2194560 : gvnl2_(2,ipw)=gvnl2_(2,ipw)+nonlop_out(1,ipw)
460 : end do
461 : end if
462 :
463 23040 : ABI_FREE(nonlop_out)
464 23040 : if (sij_opt==1) gs2c=zero
465 23040 : if (usecprj==0) then
466 23040 : call pawcprj_free(cwaveprj_tmp)
467 69120 : ABI_FREE(cwaveprj_tmp)
468 : end if
469 23040 : nullify(cwaveprj_ptr)
470 :
471 : end if
472 :
473 : !No non-local part
474 : !-------------------------------------------
475 : else
476 :
477 0 : if (optnl>=1) then
478 : !$OMP PARALLEL DO
479 0 : do ipw=1,npw1*my_nspinor
480 0 : gvnl2_(:,ipw)=zero
481 : end do
482 : end if
483 0 : if (sij_opt/=0) then
484 : !$OMP PARALLEL DO
485 0 : do ipw=1,npw1*my_nspinor
486 0 : gs2c(:,ipw)=zero
487 : end do
488 : end if
489 :
490 : end if
491 :
492 72096 : if (associated(enl_ptr)) then
493 37716 : nullify(enl_ptr)
494 : end if
495 72096 : if (allocated(enl_temp)) then
496 2880 : ABI_FREE(enl_temp)
497 : end if
498 :
499 : !======================================================================
500 : !== Apply the 2nd-order kinetic operator to the wavefunction
501 : !======================================================================
502 :
503 72096 : if (present(optkin)) then
504 7872 : has_kin=(optkin/=0.and.ipert==natom+10)
505 : else
506 64224 : has_kin=(ipert==natom+10)
507 : end if
508 :
509 : !k-point perturbation
510 : !-------------------------------------------
511 72096 : if (associated(gs_hamkq%kinpw_kp)) then
512 72096 : kinpw1 => gs_hamkq%kinpw_kp
513 0 : else if (optnl>=1.or.has_kin) then
514 0 : msg='need kinpw1 allocated!'
515 0 : ABI_BUG(msg)
516 : end if
517 72096 : if (associated(rf_hamkq%ddkinpw_k)) then
518 46176 : ddkinpw => rf_hamkq%ddkinpw_k
519 25920 : else if (has_kin) then
520 0 : msg='need ddkinpw allocated!'
521 0 : ABI_BUG(msg)
522 : end if
523 :
524 46176 : if (has_kin) then
525 91584 : do ispinor=1,my_nspinor
526 : !$OMP PARALLEL DO PRIVATE(ipw,ipws) SHARED(cwavef,ispinor,gvnl2_,ddkinpw,kinpw1,npw,my_nspinor)
527 6301132 : do ipw=1,npw
528 6209548 : ipws=ipw+npw*(ispinor-1)
529 6255340 : if(kinpw1(ipw)<huge(zero)*1.d-11)then
530 6209548 : gvnl2_(1,ipws)=gvnl2_(1,ipws)+ddkinpw(ipw)*cwavef(1,ipws)
531 6209548 : gvnl2_(2,ipws)=gvnl2_(2,ipws)+ddkinpw(ipw)*cwavef(2,ipws)
532 : else
533 0 : gvnl2_(1,ipws)=zero
534 0 : gvnl2_(2,ipws)=zero
535 : end if
536 : end do
537 : end do
538 : end if
539 :
540 : !======================================================================
541 : !== Sum contributions to get the application of H^(2) to the wf
542 : !======================================================================
543 : !Also filter the wavefunctions for large modified kinetic energy
544 :
545 : !Add non-local+kinetic to local part
546 72096 : if (optnl>=1.or.has_kin) then
547 144192 : do ispinor=1,my_nspinor
548 72096 : ipws=(ispinor-1)*npw1
549 : !$OMP PARALLEL DO PRIVATE(ipw) SHARED(gh2c,gvnl2_,kinpw1,ipws,npw1)
550 8832892 : do ipw=1+ipws,npw1+ipws
551 8760796 : if(kinpw1(ipw-ipws)<huge(zero)*1.d-11)then
552 8688700 : gh2c(1,ipw)=gh2c(1,ipw)+gvnl2_(1,ipw)
553 8688700 : gh2c(2,ipw)=gh2c(2,ipw)+gvnl2_(2,ipw)
554 : else
555 0 : gh2c(1,ipw)=zero
556 0 : gh2c(2,ipw)=zero
557 : end if
558 : end do
559 : end do
560 : end if
561 :
562 72096 : if (usevnl==1) then
563 25920 : nullify(gvnl2_)
564 : else
565 46176 : ABI_FREE(gvnl2_)
566 : end if
567 :
568 : ABI_NVTX_END_RANGE()
569 :
570 : !call timab(196+tim_getgh2c,2,tsec)
571 :
572 : DBG_EXIT("COLL")
573 :
574 216288 : end subroutine getgh2c
575 : !!***
576 :
577 : end module m_getgh2c
578 : !!***
|