Line data Source code
1 : !!****m* ABINIT/m_getchc
2 : !! NAME
3 : !! m_getchc
4 : !!
5 : !! FUNCTION
6 : !! Compute <G|H|C> for input vector |C> expressed in reciprocal space;
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, LSI, MT)
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 : module m_getchc
23 :
24 : use defs_basis
25 : use m_errors
26 : use m_abicore
27 : use m_xmpi
28 :
29 : use defs_abitypes, only : mpi_type
30 : use m_time, only : timab
31 : use m_pawcprj, only : pawcprj_type!, pawcprj_alloc, pawcprj_free, pawcprj_getdim
32 : ! use m_bandfft_kpt, only : bandfft_kpt, bandfft_kpt_get_ikpt
33 : use m_hamiltonian, only : gs_hamiltonian_type, KPRIME_H_K, K_H_KPRIME, K_H_K, KPRIME_H_KPRIME
34 : use m_nonlop, only : nonlop
35 : ! use m_fock, only : fock_common_type, fock_get_getghc_call
36 : ! use m_fock_getghc, only : fock_getghc, fock_ACE_getghc
37 : use m_cgtools, only : dotprod_g
38 :
39 : implicit none
40 :
41 : private
42 : !!***
43 :
44 : public :: getchc
45 : public :: getcsc
46 : !!***
47 :
48 : contains
49 : !!***
50 :
51 : !!****f* ABINIT/getchc
52 : !!
53 : !! NAME
54 : !! getchc
55 : !!
56 : !! FUNCTION
57 : !! Compute <C_left|H|C> for input vectors |C> and |C_left>.
58 : !! Note that |C_left> can be an array of "ndat" wavefunctions if only the non-local part is computed
59 : !!
60 : !! INPUTS
61 : !! cpopt=flag defining the status of cwaveprj%cp(:)=<Proj_i|Cnk> scalars (PAW only)
62 : !! (same meaning as in nonlop.F90 routine)
63 : !! if cpopt=-1, <p_lmn|in> (and derivatives) are computed here (and not saved)
64 : !! if cpopt= 0, <p_lmn|in> are computed here and saved
65 : !! if cpopt= 1, <p_lmn|in> and first derivatives are computed here and saved
66 : !! if cpopt= 2 <p_lmn|in> are already in memory;
67 : !! if cpopt= 3 <p_lmn|in> are already in memory; first derivatives are computed here and saved
68 : !! if cpopt= 4 <p_lmn|in> and first derivatives are already in memory;
69 : !! cwavef(2,npw*my_nspinor)=planewave coefficients of wavefunction.
70 : !! cwavef_left(2,npw*my_nspinor)=planewave coefficients of wavefunction left.
71 : !! cwaveprj(natom,my_nspinor*(1+cpopt))= wave function projected on nl projectors
72 : !! cwaveprj_left(natom,my_nspinor*(1+cpopt))= wave function projected on nl projectors (for left WF)
73 : !! cwavef_r(2,n4,n5,n6,nspinor) = wave function in real space
74 : !! cwavef_left_r(2,n4,n5,n6,nspinor) = wave function in real space (for left WF)
75 : !! gs_ham <type(gs_hamiltonian_type)>=all data for the Hamiltonian to be applied
76 : !! lambda=factor to be used when computing <G|H-lambda.S|C> - only for sij_opt=-1
77 : !! Typically lambda is the eigenvalue (or its guess)
78 : !! mpi_enreg=information about MPI parallelization
79 : !! ndat=number of left wavefunctions
80 : !! sij_opt= -PAW ONLY- if 0, only matrix elements <G|H|C> have to be computed
81 : !! (S=overlap) if 1, matrix elements <G|S|C> have to be computed in gsc in addition to ghc
82 : !! if -1, matrix elements <G|H-lambda.S|C> have to be computed in ghc (gsc not used)
83 : !! type_calc= option governing which part of Hamitonian is to be applied:
84 : ! 0: whole Hamiltonian
85 : !! 1: local part only
86 : !! 2: non-local+Fock+kinetic only (added to the existing Hamiltonian)
87 : !! 3: local + kinetic only (added to the existing Hamiltonian)
88 : !! ===== Optional inputs =====
89 : !! [kg_fft_k(3,:)]=optional, (k+G) vector coordinates to be used for the FFT tranformation
90 : !! instead of the one contained in gs_ham datastructure.
91 : !! Typically used for real WF (in parallel) which are FFT-transformed 2 by 2.
92 : !! [kg_fft_kp(3,:)]=optional, (k^prime+G) vector coordinates to be used for the FFT tranformation
93 : !! [select_k]=optional, option governing the choice of k points to be used.
94 : !! gs_ham datastructure contains quantities needed to apply Hamiltonian
95 : !! in reciprocal space between 2 kpoints, k and k^prime (equal in most cases);
96 : !! if select_k=1, <k^prime|H|k> is applied [default]
97 : !! if select_k=2, <k|H|k^prime> is applied
98 : !! if select_k=3, <k|H|k> is applied
99 : !! if select_k=4, <k^prime|H|k^prime> is applied
100 : !!
101 : !! OUTPUT
102 : !! chc(2*ndat)=matrix elements <C_left|H|C> (if sij_opt>=0)
103 : !! or <C_left|H-lambda.S|C> (if sij_opt=-1)
104 : !! SIDE EFFECTS
105 : !!
106 : !! SOURCE
107 :
108 0 : subroutine getchc(chc,cpopt,cwavef,cwavef_left,cwaveprj,cwaveprj_left,cwavef_r,cwavef_left_r,&
109 : & gs_ham,lambda,mpi_enreg,ndat,&
110 : & sij_opt,type_calc,&
111 0 : & kg_fft_k,kg_fft_kp,select_k) ! optional arguments
112 :
113 : !Arguments ------------------------------------
114 : !scalars
115 : integer,intent(in) :: cpopt,ndat
116 : integer,intent(in) :: sij_opt,type_calc
117 : integer,intent(in),optional :: select_k
118 : real(dp),intent(in) :: lambda
119 : real(dp),intent(inout) :: chc(2*ndat)
120 : type(MPI_type),intent(in) :: mpi_enreg
121 : type(gs_hamiltonian_type),intent(inout),target :: gs_ham
122 : !arrays
123 : integer,intent(in),optional,target :: kg_fft_k(:,:),kg_fft_kp(:,:)
124 : real(dp),intent(inout) :: cwavef(:,:),cwavef_left(:,:),cwavef_r(:,:,:,:,:),cwavef_left_r(:,:,:,:,:)
125 : type(pawcprj_type),intent(inout),target :: cwaveprj(:,:),cwaveprj_left(:,:)
126 :
127 : !Local variables-------------------------------
128 : !scalars
129 : integer,parameter :: re=1,im=2
130 : integer :: choice,cpopt_here,i1,i2,i3,idat,idir
131 : integer :: ig,igspinor,ispinor,ispinor_left,my_nspinor
132 : integer :: nnlout,nffttot,npw,npw_k1,npw_k2,nspinortot,n1,n2,n3
133 : integer :: paw_opt,select_k_,shift1,shift2,signs,tim_nonlop
134 : logical :: k1_eq_k2,has_fock
135 : logical :: nspinor1TreatedByThisProc,nspinor2TreatedByThisProc
136 : character(len=500) :: msg
137 : !arrays
138 0 : integer, pointer :: gbound_k1(:,:),gbound_k2(:,:),kg_k1(:,:),kg_k2(:,:)
139 0 : real(dp) :: enlout(ndat),enlout_im(ndat),lambda_ndat(ndat),tsec(2),z_tmp(2)
140 0 : real(dp),allocatable :: gsc(:,:),gvnlxc(:,:)
141 0 : real(dp), pointer :: kinpw_k1(:),kinpw_k2(:),kpt_k1(:),kpt_k2(:)
142 :
143 : ! *********************************************************************
144 :
145 : DBG_ENTER("COLL")
146 :
147 : !Keep track of total time spent in getchc:
148 0 : call timab(1370,1,tsec)
149 :
150 : !Select k-dependent objects according to select_k input parameter
151 0 : select_k_=1;if (present(select_k)) select_k_=select_k
152 0 : if (select_k_==KPRIME_H_K) then
153 : ! <k^prime|H|k>
154 0 : npw_k1 = gs_ham%npw_fft_k ; npw_k2 = gs_ham%npw_fft_kp
155 0 : kpt_k1 => gs_ham%kpt_k ; kpt_k2 => gs_ham%kpt_kp
156 0 : kg_k1 => gs_ham%kg_k ; kg_k2 => gs_ham%kg_kp
157 0 : gbound_k1 => gs_ham%gbound_k ; gbound_k2 => gs_ham%gbound_kp
158 0 : kinpw_k1 => gs_ham%kinpw_k ; kinpw_k2 => gs_ham%kinpw_kp
159 0 : else if (select_k_==K_H_KPRIME) then
160 : ! <k|H|k^prime>
161 0 : npw_k1 = gs_ham%npw_fft_kp; npw_k2 = gs_ham%npw_fft_k
162 0 : kpt_k1 => gs_ham%kpt_kp ; kpt_k2 => gs_ham%kpt_k
163 0 : kg_k1 => gs_ham%kg_kp ; kg_k2 => gs_ham%kg_k
164 0 : gbound_k1 => gs_ham%gbound_kp ; gbound_k2 => gs_ham%gbound_k
165 0 : kinpw_k1 => gs_ham%kinpw_kp ; kinpw_k2 => gs_ham%kinpw_k
166 0 : else if (select_k_==K_H_K) then
167 : ! <k|H|k>
168 0 : npw_k1 = gs_ham%npw_fft_k ; npw_k2 = gs_ham%npw_fft_k
169 0 : kpt_k1 => gs_ham%kpt_k ; kpt_k2 => gs_ham%kpt_k
170 0 : kg_k1 => gs_ham%kg_k ; kg_k2 => gs_ham%kg_k
171 0 : gbound_k1 => gs_ham%gbound_k ; gbound_k2 => gs_ham%gbound_k
172 0 : kinpw_k1 => gs_ham%kinpw_k ; kinpw_k2 => gs_ham%kinpw_k
173 0 : else if (select_k_==KPRIME_H_KPRIME) then
174 : ! <k^prime|H|k^prime>
175 0 : npw_k1 = gs_ham%npw_fft_kp; npw_k2 = gs_ham%npw_fft_kp
176 0 : kpt_k1 => gs_ham%kpt_kp ; kpt_k2 => gs_ham%kpt_kp
177 0 : kg_k1 => gs_ham%kg_kp ; kg_k2 => gs_ham%kg_kp
178 0 : gbound_k1 => gs_ham%gbound_kp ; gbound_k2 => gs_ham%gbound_kp
179 0 : kinpw_k1 => gs_ham%kinpw_kp ; kinpw_k2 => gs_ham%kinpw_kp
180 : end if
181 0 : k1_eq_k2=(all(abs(kpt_k1(:)-kpt_k2(:))<tol8))
182 0 : if (.not.k1_eq_k2) then
183 0 : ABI_ERROR('getchc is not implemented yet for k1/=k2')
184 : end if
185 :
186 : !Check sizes
187 0 : my_nspinor=max(1,gs_ham%nspinor/mpi_enreg%nproc_spinor)
188 0 : if (size(cwavef)<2*npw_k1*my_nspinor) then
189 0 : msg='wrong size for cwavef!'
190 0 : ABI_BUG(msg)
191 : end if
192 0 : if (gs_ham%usepaw==1.and.cpopt>=0) then
193 0 : if (size(cwaveprj)<gs_ham%natom*my_nspinor) then
194 0 : msg='wrong size for cwaveprj!'
195 0 : ABI_BUG(msg)
196 : end if
197 : end if
198 0 : if (gs_ham%usepaw==1) then
199 0 : if (size(cwaveprj_left)<gs_ham%natom*my_nspinor*ndat) then
200 0 : msg='wrong size for cwaveprj_left!'
201 0 : ABI_BUG(msg)
202 : end if
203 : end if
204 :
205 : !Eventually overwrite plane waves data for FFT
206 0 : if (present(kg_fft_k)) then
207 0 : kg_k1 => kg_fft_k ; kg_k2 => kg_fft_k
208 0 : npw_k1=size(kg_k1,2) ; npw_k2=size(kg_k2,2)
209 : end if
210 0 : if (present(kg_fft_kp)) then
211 0 : kg_k2 => kg_fft_kp ; npw_k2=size(kg_k2,2)
212 : end if
213 :
214 : !paral_kgb constraint
215 0 : if (mpi_enreg%paral_kgb==1.and.(.not.k1_eq_k2)) then
216 0 : msg='paral_kgb=1 not allowed for k/=k_^prime!'
217 0 : ABI_BUG(msg)
218 : end if
219 :
220 : !Do we add Fock exchange term ?
221 0 : has_fock=(associated(gs_ham%fockcommon))
222 0 : if (has_fock) then
223 0 : ABI_BUG('Fock not implemented yet')
224 : end if
225 : ! if (has_fock) fock => gs_ham%fockcommon
226 :
227 : !Parallelization over spinors management
228 : if (mpi_enreg%paral_spinor==0) then
229 : shift1=npw_k1;shift2=npw_k2
230 : nspinor1TreatedByThisProc=.true.
231 : nspinor2TreatedByThisProc=(nspinortot==2)
232 : else
233 0 : shift1=0;shift2=0
234 0 : nspinor1TreatedByThisProc=(mpi_enreg%me_spinor==0)
235 0 : nspinor2TreatedByThisProc=(mpi_enreg%me_spinor==1)
236 : end if
237 :
238 0 : npw=gs_ham%npw_k
239 0 : nspinortot=gs_ham%nspinor
240 :
241 : !============================================================
242 : ! Application of the local potential
243 : !============================================================
244 :
245 0 : if ((type_calc==0).or.(type_calc==1).or.(type_calc==3)) then
246 :
247 0 : call timab(1371,1,tsec)
248 : ! Need a Vlocal
249 0 : if (.not.associated(gs_ham%vlocal)) then
250 0 : ABI_BUG("We need vlocal in gs_ham!")
251 : end if
252 0 : if (ndat>1) then
253 0 : ABI_ERROR("ndat should be 1 for the local part")
254 : end if
255 :
256 0 : n1=gs_ham%ngfft(1)
257 0 : n2=gs_ham%ngfft(2)
258 0 : n3=gs_ham%ngfft(3)
259 0 : nffttot=n1*n2*n3
260 0 : chc = zero
261 : ! Treat scalar local potentials
262 0 : if (gs_ham%nvloc==1) then
263 0 : if (gs_ham%istwf_k==2) then
264 0 : do i3=1,n3
265 0 : do i2=1,n2
266 0 : do i1=1,n1
267 0 : chc(1) = chc(1) + gs_ham%vlocal(i1,i2,i3,1)*cwavef_r(1,i1,i2,i3,1)*cwavef_left_r(1,i1,i2,i3,1)
268 : end do
269 : end do
270 : end do
271 0 : chc(2)=zero
272 : else
273 0 : do ispinor=1,my_nspinor
274 0 : do i3=1,n3
275 0 : do i2=1,n2
276 0 : do i1=1,n1
277 : z_tmp(1) = cwavef_r(1,i1,i2,i3,ispinor)*cwavef_left_r(1,i1,i2,i3,ispinor) &
278 0 : & +cwavef_r(2,i1,i2,i3,ispinor)*cwavef_left_r(2,i1,i2,i3,ispinor)
279 : z_tmp(2) = cwavef_r(2,i1,i2,i3,ispinor)*cwavef_left_r(1,i1,i2,i3,ispinor) &
280 0 : & -cwavef_r(1,i1,i2,i3,ispinor)*cwavef_left_r(2,i1,i2,i3,ispinor)
281 0 : chc(1) = chc(1) + gs_ham%vlocal(i1,i2,i3,1)*z_tmp(1)
282 0 : chc(2) = chc(2) + gs_ham%vlocal(i1,i2,i3,1)*z_tmp(2)
283 : end do
284 : end do
285 : end do
286 : end do
287 : end if
288 : else ! nvloc = 4
289 0 : do ispinor=1,my_nspinor
290 0 : do ispinor_left=1,my_nspinor
291 0 : do i3=1,n3
292 0 : do i2=1,n2
293 0 : do i1=1,n1
294 : z_tmp(1) = cwavef_r(1,i1,i2,i3,ispinor)*cwavef_left_r(1,i1,i2,i3,ispinor_left) &
295 0 : & +cwavef_r(2,i1,i2,i3,ispinor)*cwavef_left_r(2,i1,i2,i3,ispinor_left)
296 : z_tmp(2) = cwavef_r(2,i1,i2,i3,ispinor)*cwavef_left_r(1,i1,i2,i3,ispinor_left) &
297 0 : & -cwavef_r(1,i1,i2,i3,ispinor)*cwavef_left_r(2,i1,i2,i3,ispinor_left)
298 0 : if (ispinor==ispinor_left) then
299 : ! Then vloc is real : vloc_uu = vloc(1) and vloc_dd = vloc(2)
300 0 : chc(1) = chc(1) + gs_ham%vlocal(i1,i2,i3,ispinor)*z_tmp(1)
301 0 : chc(2) = chc(2) + gs_ham%vlocal(i1,i2,i3,ispinor)*z_tmp(2)
302 0 : else if (ispinor==1.and.ispinor_left==2) then ! Psi(left)_d^* Psi_u vloc_ud
303 : ! Otherwise vloc is complex Re(vloc_ud) = vloc(3)
304 : ! Im(vloc_ud) = vloc(4)
305 : ! vloc_du = (vloc_ud)^*
306 0 : chc(1) = chc(1) + gs_ham%vlocal(i1,i2,i3,3)*z_tmp(1) + gs_ham%vlocal(i1,i2,i3,4)*z_tmp(2)
307 0 : chc(2) = chc(2) + gs_ham%vlocal(i1,i2,i3,3)*z_tmp(1) - gs_ham%vlocal(i1,i2,i3,4)*z_tmp(2)
308 0 : else if (ispinor==2.and.ispinor_left==1) then ! Psi(left)_u^* Psi_d vloc_ud
309 0 : chc(1) = chc(1) + gs_ham%vlocal(i1,i2,i3,3)*z_tmp(1) - gs_ham%vlocal(i1,i2,i3,4)*z_tmp(2)
310 0 : chc(2) = chc(2) + gs_ham%vlocal(i1,i2,i3,3)*z_tmp(1) + gs_ham%vlocal(i1,i2,i3,4)*z_tmp(2)
311 : end if
312 : end do
313 : end do
314 : end do
315 : end do
316 : end do
317 : end if
318 0 : chc = chc / dble(nffttot)
319 :
320 0 : call timab(1371,2,tsec)
321 :
322 : end if ! type_calc
323 :
324 0 : if ((type_calc==0).or.(type_calc==2).or.(type_calc==3).or.(type_calc==4)) then
325 :
326 : !============================================================
327 : ! Application of the non-local potential and the Fock potential
328 : !============================================================
329 :
330 : if ((type_calc==0).or.(type_calc==2).or.(type_calc==4)) then
331 :
332 0 : signs=1 ; choice=1 ; nnlout=1 ; idir=0 ; tim_nonlop=15
333 0 : cpopt_here=-1;if (gs_ham%usepaw==1) cpopt_here=cpopt
334 0 : ABI_MALLOC(gvnlxc,(0,0))
335 0 : ABI_MALLOC(gsc,(0,0))
336 : ! if (has_fock) then
337 : ! if (gs_ham%usepaw==1) then
338 : ! cpopt_here=max(cpopt,0)
339 : ! if (cpopt<2) then
340 : ! ABI_DATATYPE_ALLOCATE(cwaveprj_fock,(gs_ham%natom,my_nspinor*ndat))
341 : ! ABI_ALLOCATE(dimcprj,(gs_ham%natom))
342 : ! call pawcprj_getdim(dimcprj,gs_ham%natom,gs_ham%nattyp,gs_ham%ntypat,&
343 : !& gs_ham%typat,fock%pawtab,'O')
344 : ! call pawcprj_alloc(cwaveprj_fock,0,dimcprj)
345 : ! ABI_DEALLOCATE(dimcprj)
346 : ! else
347 : ! cwaveprj_fock=>cwaveprj
348 : ! end if
349 : ! cwaveprj_nonlop=>cwaveprj_fock
350 : ! else
351 : ! cwaveprj_nonlop=>cwaveprj
352 : ! cwaveprj_fock=>cwaveprj
353 : ! end if
354 : ! else
355 : ! end if
356 0 : paw_opt=gs_ham%usepaw ; if (sij_opt/=0) paw_opt=sij_opt+3
357 0 : lambda_ndat = lambda
358 :
359 0 : enlout=zero
360 0 : enlout_im=zero
361 : call nonlop(choice,cpopt_here,cwaveprj,enlout,gs_ham,idir,lambda_ndat,mpi_enreg,1,&
362 : & nnlout,paw_opt,signs,gsc,tim_nonlop,cwavef,gvnlxc,select_k=select_k_,&
363 0 : & cprjin_left=cwaveprj_left,enlout_im=enlout_im,ndat_left=ndat)
364 :
365 0 : do idat=1,ndat
366 0 : chc(2*idat-1) = chc(2*idat-1) + enlout(idat)
367 0 : chc(2*idat ) = chc(2*idat ) + enlout_im(idat)
368 : end do
369 :
370 0 : ABI_FREE(gvnlxc)
371 0 : ABI_FREE(gsc)
372 :
373 : end if ! if(type_calc...
374 :
375 : !============================================================
376 : ! Assemble kinetic, local, nonlocal and Fock contributions
377 : !============================================================
378 :
379 0 : if (type_calc==0.or.type_calc==2.or.type_calc==3) then
380 :
381 0 : if (ndat>1) then
382 0 : ABI_ERROR("ndat should be 1 for the kinetic part")
383 : end if
384 :
385 0 : call timab(1372,1,tsec)
386 : ! Add modified kinetic contributions
387 : ! to <CP|H|C(n,k)>.
388 0 : if (gs_ham%istwf_k==1) then
389 : ! !!$OMP PARALLEL DO PRIVATE(igspinor) COLLAPSE(2)
390 0 : do ispinor=1,my_nspinor
391 0 : do ig=1,npw_k2
392 0 : igspinor=ig+npw_k2*(ispinor-1)
393 0 : if (kinpw_k2(ig)<huge(zero)*1.d-11) then
394 0 : chc(1) = chc(1) + kinpw_k2(ig)*cwavef(re,igspinor)*cwavef_left(re,igspinor)
395 0 : chc(1) = chc(1) + kinpw_k2(ig)*cwavef(im,igspinor)*cwavef_left(im,igspinor)
396 0 : chc(2) = chc(2) + kinpw_k2(ig)*cwavef(im,igspinor)*cwavef_left(re,igspinor)
397 0 : chc(2) = chc(2) - kinpw_k2(ig)*cwavef(re,igspinor)*cwavef_left(im,igspinor)
398 : end if
399 : end do ! ig
400 : end do ! ispinor
401 0 : else if (gs_ham%istwf_k==2.and.mpi_enreg%me_g0==1) then
402 0 : if (kinpw_k2(1)<huge(zero)*1.d-11) then
403 0 : chc(1) = chc(1) + kinpw_k2(1)*cwavef(re,1)*cwavef_left(re,1)
404 : end if
405 0 : do ig=2,npw_k2
406 0 : if (kinpw_k2(ig)<huge(zero)*1.d-11) then
407 0 : chc(1) = chc(1) + 2*kinpw_k2(ig)*cwavef(re,ig)*cwavef_left(re,ig)
408 0 : chc(1) = chc(1) + 2*kinpw_k2(ig)*cwavef(im,ig)*cwavef_left(im,ig)
409 : end if
410 : end do
411 : else
412 0 : do ig=1,npw_k2
413 0 : if (kinpw_k2(ig)<huge(zero)*1.d-11) then
414 0 : chc(1) = chc(1) + 2*kinpw_k2(ig)*cwavef(re,ig)*cwavef_left(re,ig)
415 0 : chc(1) = chc(1) + 2*kinpw_k2(ig)*cwavef(im,ig)*cwavef_left(im,ig)
416 : end if
417 : end do ! ig
418 : end if
419 : ! Special case of PAW + Fock : only return Fock operator contribution in gvnlxc
420 : ! if (gs_ham%usepaw==1 .and. has_fock)then
421 : ! gvnlxc=gvnlxc-gvnlc
422 : ! ABI_DEALLOCATE(gvnlc)
423 : ! endif
424 : !
425 : ! if ((type_calc==0).or.(type_calc==2)) then
426 : ! if (has_fock.and.gs_ham%usepaw==1.and.cpopt<2) then
427 : ! call pawcprj_free(cwaveprj_fock)
428 : ! ABI_DATATYPE_DEALLOCATE(cwaveprj_fock)
429 : ! end if
430 : ! end if
431 0 : call timab(1372,2,tsec)
432 : end if
433 :
434 : end if ! type_calc
435 :
436 0 : call timab(1370,2,tsec)
437 :
438 : DBG_EXIT("COLL")
439 :
440 0 : end subroutine getchc
441 : !!***
442 :
443 : !----------------------------------------------------------------------
444 :
445 : !!****f* ABINIT/getcsc
446 : !! NAME
447 : !! getcsc
448 : !!
449 : !! FUNCTION
450 : !! Compute <C_left|S|C> for input vectors |C> and |C_left>.
451 : !! Note that |C_left> can be an array of "ndat" wavefunctions
452 : !!
453 : !! INPUTS
454 : !! cpopt=flag defining the status of cwaveprj%cp(:)=<Proj_i|Cnk> scalars (PAW only)
455 : !! (same meaning as in nonlop.F90 routine)
456 : !! if cpopt=-1, <p_lmn|in> (and derivatives) are computed here (and not saved)
457 : !! if cpopt= 0, <p_lmn|in> are computed here and saved
458 : !! if cpopt= 1, <p_lmn|in> and first derivatives are computed here and saved
459 : !! if cpopt= 2 <p_lmn|in> are already in memory;
460 : !! if cpopt= 3 <p_lmn|in> are already in memory; first derivatives are computed here and saved
461 : !! if cpopt= 4 <p_lmn|in> and first derivatives are already in memory;
462 : !! cwavef(2,npw*my_nspinor)=planewave coefficients of wavefunction.
463 : !! cwavef_left(2,npw*my_nspinor)=planewave coefficients of wavefunction left.
464 : !! cprj(natom,my_nspinor*(1+cpopt))= wave function projected on nl projectors
465 : !! cprj_left(natom,my_nspinor*(1+cpopt))= wave function projected on nl projectors (for left WF)
466 : !! gs_ham <type(gs_hamiltonian_type)>=all data for the Hamiltonian to be applied
467 : !! lambda=factor to be used when computing <G|H-lambda.S|C> - only for sij_opt=-1
468 : !! Typically lambda is the eigenvalue (or its guess)
469 : !! mpi_enreg=information about MPI parallelization
470 : !! ndat=number of left wavefunctions
471 : !! mpi_enreg=information about MPI parallelization
472 : !!
473 : !! OUTPUT
474 : !! csc(2*ndat)=matrix elements <C_left|S|C>
475 : !!
476 : !! SOURCE
477 :
478 0 : subroutine getcsc(csc,cpopt,cwavef,cwavef_left,cprj,cprj_left,gs_ham,mpi_enreg,ndat,&
479 : & tim_getcsc,&
480 : & select_k) ! optional arguments
481 :
482 : !Arguments ------------------------------------
483 : !scalars
484 : integer,intent(in) :: cpopt,ndat,tim_getcsc
485 : integer,intent(in),optional :: select_k
486 : real(dp),intent(out) :: csc(2*ndat)
487 : type(MPI_type),intent(in) :: mpi_enreg
488 : type(gs_hamiltonian_type),intent(inout) :: gs_ham
489 : !arrays
490 : real(dp),intent(inout) :: cwavef(:,:)
491 : real(dp),intent(inout),target :: cwavef_left(:,:)
492 : type(pawcprj_type),intent(inout) :: cprj(:,:)
493 : type(pawcprj_type),intent(inout),target :: cprj_left(:,:)
494 :
495 : !Local variables-------------------------------
496 : !scalars
497 : integer :: choice,idat,idir,istwf_k
498 : integer :: npw,nspinor,paw_opt,select_k_,signs,tim_nonlop,nnlout
499 : !character(len=500) :: msg
500 : !arrays
501 0 : real(dp) :: tsec(2),real_csc(ndat)
502 0 : real(dp),allocatable :: gsc(:,:),gvnlxc(:,:)
503 0 : real(dp),allocatable :: enlout(:),enlout_im(:)
504 : ! real(dp) :: dum
505 : ! real(dp),pointer :: cwavef_left_idat(:,:)
506 : ! *********************************************************************
507 :
508 : DBG_ENTER("COLL")
509 :
510 0 : call timab(1360+tim_getcsc,1,tsec)
511 :
512 0 : istwf_k = gs_ham%istwf_k
513 0 : npw = gs_ham%npw_k
514 0 : nspinor = gs_ham%nspinor
515 :
516 0 : if (size(cwavef,2)/=npw*nspinor) then
517 0 : ABI_BUG('Wrong size for cwavef')
518 : end if
519 0 : if (size(cwavef_left,2)/=npw*nspinor*ndat) then
520 0 : ABI_BUG('Wrong size for cwavef_left')
521 : end if
522 :
523 0 : call timab(1361,1,tsec)
524 0 : if (istwf_k==1) then
525 0 : call zgemv('C',npw*nspinor,ndat,cone,cwavef_left,npw*nspinor,cwavef,1,czero,csc,1)
526 : else ! nspinor==1 in that case
527 0 : call dgemv('C',2*npw,ndat,one,cwavef_left,2*npw,cwavef,1,zero,real_csc,1)
528 0 : do idat=1,ndat
529 0 : csc(2*idat-1) = two*real_csc(idat)
530 0 : csc(2*idat ) = zero
531 : end do
532 0 : if (istwf_k==2 .and. mpi_enreg%me_g0==1) then ! Gamma k-point and I have G=0
533 0 : do idat=1,ndat
534 0 : csc(2*idat-1) = csc(2*idat-1) - cwavef_left(1,1+npw*(idat-1))*cwavef(1,1)
535 : end do
536 : end if
537 : end if
538 0 : call timab(1361,2,tsec)
539 :
540 :
541 0 : if (gs_ham%usepaw==1) then
542 :
543 0 : if (size(cprj,2)/=nspinor) then
544 0 : ABI_BUG('Wrong size for cprj')
545 : end if
546 0 : if (size(cprj_left,2)/=nspinor*ndat) then
547 0 : ABI_BUG('Wrong size for cprj_left')
548 : end if
549 :
550 0 : select_k_=1;if (present(select_k)) select_k_=select_k
551 0 : choice=1 ; nnlout=1 ; idir=0 ; tim_nonlop=16 ; paw_opt=3
552 0 : ABI_MALLOC(gsc,(0,0))
553 0 : ABI_MALLOC(gvnlxc,(0,0))
554 0 : ABI_MALLOC(enlout ,(ndat))
555 0 : ABI_MALLOC(enlout_im,(ndat))
556 0 : enlout=zero
557 0 : enlout_im=zero
558 0 : signs=1
559 : call nonlop(choice,cpopt,cprj,enlout,gs_ham,idir,(/zero/),mpi_enreg,1,&
560 : & nnlout,paw_opt,signs,gsc,tim_nonlop,cwavef,gvnlxc,select_k=select_k_,&
561 0 : & cprjin_left=cprj_left,enlout_im=enlout_im,ndat_left=ndat)
562 0 : do idat=1,ndat
563 0 : csc(2*idat-1) = csc(2*idat-1) + enlout(idat)
564 0 : csc(2*idat ) = csc(2*idat ) + enlout_im(idat)
565 : end do
566 0 : ABI_FREE(gsc)
567 0 : ABI_FREE(gvnlxc)
568 0 : ABI_FREE(enlout )
569 0 : ABI_FREE(enlout_im)
570 :
571 : end if
572 :
573 0 : call timab(1360+tim_getcsc,2,tsec)
574 :
575 : DBG_EXIT("COLL")
576 :
577 0 : end subroutine getcsc
578 : !!***
579 :
580 : end module m_getchc
581 : !!***
|