Branch data Line data Source code
1 : : !!****m* ABINIT/m_gwrdm
2 : : !! NAME
3 : : !! m_gwrdm
4 : : !!
5 : : !! FUNCTION
6 : : !! Compute density matrix correction Galitskii-Migdal Ecorr, G = Go + Go Sigma Go (imaginary freqs. are used in Sigma_c)
7 : : !! and associated quantities (natural orbitals, matrix elements, etc.).
8 : : !!
9 : : !! SOURCE
10 : :
11 : : #if defined HAVE_CONFIG_H
12 : : #include "config.h"
13 : : #endif
14 : :
15 : : #include "abi_common.h"
16 : :
17 : : module m_gwrdm
18 : :
19 : : use defs_basis
20 : : use m_gwdefs
21 : : use m_abicore
22 : : use m_xmpi
23 : : use m_errors
24 : : use m_hide_blas
25 : : use m_time
26 : : use m_wfd
27 : : use m_hdr
28 : : use m_dtset
29 : :
30 : : use m_fstrings, only : sjoin, itoa
31 : : use m_melemts, only : melements_t
32 : : use m_bz_mesh, only : kmesh_t
33 : : use m_ebands, only : ebands_t
34 : : use m_sigma, only : sigma_t
35 : : use m_xctk, only : xcden
36 : : use m_gaussian_quadrature, only: cgqf
37 : :
38 : : implicit none
39 : :
40 : : private :: no2ks,ks2no,printrdm_k,rotate_ks_no
41 : : !!***
42 : :
43 : : public :: quadrature_sigma_cw,calc_Ec_GM_k,calc_rdmx,calc_rdmc,natoccs,update_hdr_bst,print_tot_occ,change_matrix
44 : : public :: print_chkprdm,print_total_energy,print_band_energies,get_chkprdm
45 : : !!***
46 : :
47 : : contains
48 : : !!***
49 : :
50 : : !!****f* ABINIT/quadrature_sigma_cw
51 : : !! NAME
52 : : !! quadrature_sigma_cw
53 : : !!
54 : : !! FUNCTION
55 : : !! Quadrature frequencies used for Sigma_c(iw) integration
56 : : !!
57 : : !! INPUTS
58 : : !! Sigp<sigparams_t>=Parameters governing the self-energy calculation.
59 : : !! Sr=sigma_t (see the definition of this structured datatype)
60 : : !! weights=real quadrature weights.
61 : : !!
62 : : !! OUTPUT
63 : : !! Update Sigp and Sr imaginary frequencies with iw, and weights with the quadrature weights
64 : : !!
65 : : !! SOURCE
66 : :
67 [ - + ]: 5 : subroutine quadrature_sigma_cw(Sigp,Sr,weights)
68 : : !Arguments ------------------------------------
69 : : !scalars
70 : : type(sigparams_t),intent(inout) :: Sigp
71 : : type(sigma_t),intent(inout) :: Sr
72 : : !arrays
73 : : real(dp),intent(inout) :: weights(:)
74 : :
75 : : !Local variables ------------------------------
76 : : !scalars
77 : : integer :: ifreqs,order_int,gaussian_kind,units(2)
78 : : real(dp) :: gwalpha,gwbeta,wmin,wmax
79 : : character(len=500) :: msg
80 : : !arrays
81 : 5 : real(dp),allocatable :: freqs(:)
82 : : !************************************************************************
83 : :
84 [ + + ]: 15 : units = [std_out, ab_out]
85 : :
86 : 5 : order_int=Sigp%nomegasi
87 : 5 : write(msg,'(a45,i9)')' number of imaginary frequencies for Sigma_c ',order_int
88 : 5 : call wrtout(units, msg)
89 : 5 : write(msg,'(a1)')' '
90 : 5 : call wrtout(units, msg)
91 : 5 : order_int=Sigp%nomegasi
92 [ - + + - : 15 : ABI_MALLOC(freqs,(order_int))
+ - + - -
+ - + ]
93 : 5 : gaussian_kind=1
94 : 5 : gwalpha=zero
95 : 5 : gwbeta=zero
96 : 5 : wmin=zero
97 : 5 : wmax=one
98 [ - + - - : 5 : call cgqf(order_int,gaussian_kind,gwalpha,gwbeta,wmin,wmax,freqs,weights)
- - - + -
- ]
99 : : ! From 0 to 1 -> 0 to infinity
100 [ + + ]: 165 : weights(:)=weights(:)/(one-freqs(:))**two
101 [ + + ]: 165 : freqs(:)=freqs(:)/(one-freqs(:))
102 : : ! Form complex frequencies from 0 to iInf and print them in the log file
103 : 5 : write(msg,'(a52)')' Re(iw) Im(iw) Weight '
104 : 5 : call wrtout(std_out,msg)
105 : 5 : write(msg,'(a52)')' -------- -------- -------- '
106 : 5 : call wrtout(std_out,msg)
107 [ + + ]: 165 : do ifreqs=1,order_int
108 : 160 : Sigp%omegasi(ifreqs)=cmplx(zero,freqs(ifreqs))
109 : 160 : Sr%omega_i(ifreqs)=Sigp%omegasi(ifreqs)
110 : 160 : write(msg,'(3f17.5)') Sr%omega_i(ifreqs),weights(ifreqs)
111 : 165 : call wrtout(std_out,msg)
112 : : enddo
113 [ - + ]: 5 : ABI_FREE(freqs)
114 : :
115 : 5 : end subroutine quadrature_sigma_cw
116 : : !!***
117 : :
118 : : !!****f* ABINIT/Calc_Ec_GM_k
119 : : !! NAME
120 : : !! calc_Ec_GM_k
121 : : !!
122 : : !! FUNCTION
123 : : !! Calculate Galitskii-Migdal corr. energy integrated in the Imaginary axis Ec = 1/pi \sum_i \int Gii(iv)*Sigma_c,ii(iv) + cc. dv
124 : : !!
125 : : !! INPUTS
126 : : !! ib1=min band for given k
127 : : !! ib2=max band for given k.
128 : : !! ik_ibz= the label of k-point in the IBZ whose Galitskii-Migdal contribution is accounted.
129 : : !! weights=array containing the weights used in the quadrature.
130 : : !! sigcme_k=array containing Sigma(iw) as Sigma(iw,ib1:ib2,ib1:ib2,nspin)
131 : : !! rdm_k=density matrix, matrix (i,j), where i and j belong to the k-point k (see m_sigma_driver for more details).
132 : : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
133 : : !! eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
134 : : !! occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
135 : : !! Sr=sigma_t (see the definition of this structured datatype)
136 : : !!
137 : : !! OUTPUT
138 : : !! Compute the Galitskii-Migdal corr energy contribution of this k-point:
139 : : !! Ec ^k = 1/(4*pi) * fact_spin * int _{ -Inf }^{ +Inf } dv Sigma_c ^k (iv) * G0(iv)
140 : : !! = 1/(4*pi) * fact_spin * int _{ 0 }^{ +Inf } dv 2 * Re{ Sigma_c ^k (iv) * G0(iv) }
141 : : !!
142 : : !! SOURCE
143 : :
144 [ # # # # ]: 0 : function calc_Ec_GM_k(ib1,ib2,ik_ibz,Sr,weights,sigcme_k,ebands) result(Ec_GM_k)
145 : :
146 : : !Arguments ------------------------------------
147 : : !scalars
148 : : real(dp) :: Ec_GM_k
149 : : integer,intent(in) :: ib1,ib2,ik_ibz
150 : : type(ebands_t),target,intent(in) :: ebands
151 : : type(sigma_t),intent(in) :: Sr
152 : : !arrays
153 : : real(dp),intent(in) :: weights(:)
154 : : complex(dp),intent(in) :: sigcme_k(:,:,:,:)
155 : : !Local variables ------------------------------
156 : : !scalars
157 : : integer :: ibdm!,unitt
158 : : real(dp) :: ec_integrated,spin_fact,fact
159 : : character(len=500) :: msg
160 : : !arrays
161 : : !************************************************************************
162 : :
163 : 0 : ec_integrated=zero
164 : 0 : spin_fact=two
165 : 0 : fact=spin_fact*(one/(two_pi*two))
166 : :
167 [ # # ]: 0 : if (ib1/=1) then
168 : : msg="Unable to compute the Galitskii-Migdal correlation energy because the first band was " // &
169 : 0 : & "not included in bdgw interval. Restart the calculation starting bdgw from 1."
170 : 0 : ABI_WARNING(msg)
171 : : else
172 : : ! WARNING: Sigma_c(iv) produced from a previous integration at the screening stage, is numerically not much stable and introduces bumps.
173 : : ! Unfortunately, the Green's function times Sigma_c(iv) does not decay fast enough with iv to overcome the bumps. These bumps are
174 : : ! not pronouced for the linearized density matrix update, as two Green's functions are multiplied making the decay much faster with iv.
175 : : ! If a better way to produce more stable Sigma_c(iv) values is found, this subroutine can be use to evaluate GM Ecorr in the future. TODO
176 [ # # ]: 0 : do ibdm=1,ib2
177 : : ! Sigma_pp(iv)/[(iv - e_ibdm,k)] + [Sigma_pp(iv)/[(iv - e_ibdm,k)]]^* = 2 Re [Sigma_pp(iv)/(iv - e_ibdm,k)]
178 [ # # ]: 0 : ec_integrated=ec_integrated+two*real( sum(weights(:)*sigcme_k(:,ibdm,ibdm,1)/(Sr%omega_i(:)-ebands%eig(ibdm,ik_ibz,1)) ) )
179 : : end do
180 : : endif
181 : :
182 : 0 : Ec_GM_k=fact*ec_integrated
183 : :
184 : 0 : end function calc_Ec_GM_k
185 : : !!***
186 : :
187 : : !!****f* ABINIT/calc_rdmx
188 : : !! NAME
189 : : !! calc_rdmx
190 : : !!
191 : : !! FUNCTION
192 : : !! Calculate density matrix corrections for G = Go + Go (Sigma_x - alpha*Sigma_x - Vxc) Go
193 : : !!
194 : : !! INPUTS
195 : : !! ib1=min band for given k
196 : : !! ib2=max band for given k.
197 : : !! ik_ibz= the label of k-point in the IBZ.
198 : : !! rdm_k=density matrix, matrix (i,j), where i and j belong to the k-point k (see m_sigma_driver for more details).
199 : : !! pot=Self-energy-Potential difference, matrix size (i,j), where i and j belong to k.
200 : : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
201 : : !! eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
202 : : !! occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
203 : : !!
204 : : !! OUTPUT
205 : : !! Updated rdm_k matrix array with Go (Sigma_x - alpha*Sigma_x - Vxc) Go
206 : : !!
207 : : !! SOURCE
208 : :
209 [ - + - + ]: 27 : subroutine calc_rdmx(ib1,ib2,ik_ibz,pot,rdm_k,ebands)
210 : :
211 : : !Arguments ------------------------------------
212 : : !scalars
213 : : integer,intent(in) :: ib1,ib2,ik_ibz
214 : : type(ebands_t),target,intent(in) :: ebands
215 : : !arrays
216 : : complex(dp),intent(in) :: pot(:,:)
217 : : complex(dp),intent(inout) :: rdm_k(:,:)
218 : :
219 : : !Local variables ------------------------------
220 : : !scalars
221 : : character(len=500) :: msg
222 : : integer :: ib1dm,ib2dm, units(2)
223 : : real(dp) :: spin_fact,tol8
224 : : !************************************************************************
225 : :
226 : 27 : tol8=1.0e-8
227 : 27 : spin_fact=two
228 [ + + ]: 81 : units = [std_out, ab_out]
229 : :
230 : 27 : write(msg,'(a58,3f10.5)')' Computing the 1-RDM correction for Sx-Vxc and k-point: ',ebands%kptns(:,ik_ibz)
231 : 27 : call wrtout(units, msg)
232 : 27 : write(msg,'(a11,i5,a8,i5)')'from band ',ib1,' to band',ib2
233 : 27 : call wrtout(units, msg)
234 : :
235 [ + + + + ]: 1709 : rdm_k(:,:)=czero
236 [ + + ]: 196 : do ib1dm=ib1,ib2-1
237 [ + + ]: 841 : do ib2dm=ib1dm+1,ib2
238 [ + + + + ]: 814 : if ((ebands%occ(ib1dm,ik_ibz,1)>tol8) .and. (ebands%occ(ib2dm,ik_ibz,1)<tol8)) then
239 : : rdm_k(1+(ib1dm-ib1),1+(ib2dm-ib1))=spin_fact&
240 : 236 : &*pot(1+(ib1dm-ib1),1+(ib2dm-ib1))/(ebands%eig(ib1dm,ik_ibz,1)-ebands%eig(ib2dm,ik_ibz,1)+tol8)
241 : : ! Dji = Dij^*
242 : 236 : rdm_k(1+(ib2dm-ib1),1+(ib1dm-ib1))=conjg(rdm_k(1+(ib1dm-ib1),1+(ib2dm-ib1)))
243 : : end if
244 : : end do
245 : : end do
246 : :
247 : 27 : end subroutine calc_rdmx
248 : : !!***
249 : :
250 : : !!****f* ABINIT/calc_rdmc
251 : : !! NAME
252 : : !! calc_rdmc
253 : : !!
254 : : !! FUNCTION
255 : : !! Calculate density matrix corrections for G = Go + int Go(iw) Sigma_c(iw) Go(iw) dw
256 : : !!
257 : : !! INPUTS
258 : : !! ib1=min band for given k
259 : : !! ib2=max band for given k.
260 : : !! ik_ibz= the label of k-point in the IBZ.
261 : : !! omega_i=Frequencies along the imaginary axis.
262 : : !! weights=array containing the weights used in the quadrature.
263 : : !! sigcme_k=array containing Sigma(iw) as Sigma(iw,ib1:ib2,ib1:ib2,nspin)
264 : : !! rdm_k=density matrix, matrix (i,j), where i and j belong to the k-point k (see m_sigma_driver for more details).
265 : : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
266 : : !!
267 : : !! OUTPUT
268 : : !! Updated rdm_k matrix array with int Go(iw) Sigma_c(iw) Go(iw) dw
269 : : !!
270 : : !! SOURCE
271 : :
272 [ - + - + : 21 : subroutine calc_rdmc(ib1,ib2,ik_ibz,omega_i,weights,sigcme_k,ebands,rdm_k)
- + - + ]
273 : :
274 : : !Arguments ------------------------------------
275 : : !scalars
276 : : integer,intent(in) :: ib1,ib2,ik_ibz
277 : : type(ebands_t),target,intent(in) :: ebands
278 : : complex(dp),intent(in) :: omega_i(:)
279 : : !arrays
280 : : real(dp),intent(in) :: weights(:)
281 : : complex(dp),intent(inout) :: rdm_k(:,:)
282 : : complex(dp),intent(in) :: sigcme_k(:,:,:,:)
283 : :
284 : : !Local variables ------------------------------
285 : : !scalars
286 : : real(dp) :: spin_fact,fact
287 : : integer :: ib1dm, ib2dm, units(2)
288 : : character(len=500) :: msg
289 : : !************************************************************************
290 : :
291 : 21 : spin_fact = two
292 : 21 : fact = spin_fact * (one/two_pi)
293 [ + + ]: 63 : units = [std_out, ab_out]
294 : :
295 : 21 : write(msg,'(a58,3f10.5)')' Computing the 1-RDM correction for Sc(iw) and k-point: ',ebands%kptns(1:,ik_ibz)
296 : 21 : call wrtout(units , msg)
297 : 21 : write(msg,'(a11,i5,a8,i5)')'from band ',ib1,' to band',ib2
298 : 21 : call wrtout(units , msg)
299 : :
300 [ + + + + ]: 1271 : rdm_k(:,:)=czero
301 [ + + ]: 169 : do ib1dm=ib1,ib2
302 [ + + ]: 794 : do ib2dm=ib1dm,ib2
303 : : ! Sigma_pq/[(denominator)] + [Sigma_qp/[(denominator)]]^*
304 : : rdm_k(1+(ib1dm-ib1),1+(ib2dm-ib1))=fact*sum(weights(:)*( sigcme_k(:,1+(ib1dm-ib1),1+(ib2dm-ib1),1)/&
305 : : &( (omega_i(:)-ebands%eig(ib1dm,ik_ibz,1))*(omega_i(:)-ebands%eig(ib2dm,ik_ibz,1)) )&
306 : : +conjg( sigcme_k(:,1+(ib2dm-ib1),1+(ib1dm-ib1),1)/&
307 [ + + ]: 19605 : &( (omega_i(:)-ebands%eig(ib1dm,ik_ibz,1))*(omega_i(:)-ebands%eig(ib2dm,ik_ibz,1)) ) ) ) )
308 : : ! Dji = Dij^*
309 : 773 : rdm_k(1+(ib2dm-ib1),1+(ib1dm-ib1))=conjg(rdm_k(1+(ib1dm-ib1),1+(ib2dm-ib1)))
310 : : end do
311 : : end do
312 : :
313 : 21 : end subroutine calc_rdmc
314 : : !!***
315 : :
316 : : !!****f* ABINIT/natoccs
317 : : !! NAME
318 : : !! natoccs
319 : : !!
320 : : !! FUNCTION
321 : : !! Calculate natural orbitals and occ. numbers for a given k-point
322 : : !!
323 : : !! INPUTS
324 : : !! ib1=min band for given k
325 : : !! ib2=max band for given k.
326 : : !! ik_ibz= the label of k-point in the IBZ.
327 : : !! iinfo=use Sigma_x or Sigma_c phaser
328 : : !! weights=array containing the weights used in the quadrature.
329 : : !! nateigv=array containing the natural eigenvectors in columns (nbands,nband,k-point,nspin)
330 : : !! rdm_k=density matrix, matrix (i,j), where i and j belong to the k-point k (see m_sigma_driver for more details).
331 : : !! occs = array containing the occ numbers for a given k-point occs(nband,k-point).
332 : : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
333 : : !! eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
334 : : !! occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
335 : : !! checksij=check the orthonormality of the nat. orbitals
336 : : !!
337 : : !! OUTPUT
338 : : !! Compute the nat. orbitals and occ. numbers from the rdm_k matrix (for exchange and correlations)
339 : : !!
340 : : !! SOURCE
341 : :
342 [ - + - + : 48 : subroutine natoccs(ib1,ib2,rdm_k,nateigv,occs,ebands,ik_ibz,iinfo,checksij)
- + ]
343 : : !Arguments ------------------------------------
344 : : !scalars
345 : : integer,intent(in) :: ib1,ib2,ik_ibz,iinfo
346 : : integer,intent(in),optional :: checksij
347 : : type(ebands_t),target,intent(in) :: ebands
348 : : !arrays
349 : : real(dp),intent(inout) :: occs(:,:)
350 : : complex(dp),intent(inout) :: rdm_k(:,:),nateigv(:,:,:,:)
351 : : !Local variables ------------------------------
352 : : !scalars
353 : : integer:: ndim,ib1dm,ib2dm,ib3dm,lwork,info
354 : : logical:: check_Sijmat
355 : : character(len=500) :: msg
356 : : real(dp) :: toccs_k,tol10
357 : : complex(dp) :: Sib1k_ib2k
358 : : !arrays
359 : : integer :: units(2)
360 : 48 : real(dp),allocatable :: occs_tmp(:),occs_tmp2(:),rwork(:)
361 : 48 : complex(dp),allocatable :: work(:),tmp_mat(:,:),eigenvect(:,:)
362 : : !************************************************************************
363 : :
364 [ - + ]: 48 : check_Sijmat=.false.; if (present(checksij)) check_Sijmat=.true.
365 [ + + ]: 144 : units = [std_out, ab_out]
366 : 48 : tol10=1.0e-10
367 : :
368 : 48 : ndim=ib2-ib1+1
369 : 48 : lwork=2*ndim-1
370 [ - + + - : 144 : ABI_MALLOC(occs_tmp,(ndim))
+ - + - -
+ - + ]
371 [ - + + - : 96 : ABI_MALLOC(occs_tmp2,(ndim))
- + - + ]
372 [ - + + - : 144 : ABI_MALLOC(work,(lwork))
+ - + - -
+ - + ]
373 [ - + + - : 192 : ABI_MALLOC(tmp_mat,(ndim,ndim))
- + + - +
- + - - +
- + ]
374 [ - + + - : 144 : ABI_MALLOC(eigenvect,(ndim,ndim))
- + + - -
+ - + ]
375 [ + - - + : 144 : ABI_MALLOC(rwork,(3*ndim-2))
+ - + - +
- - + -
+ ]
376 : :
377 [ + + + + ]: 2980 : tmp_mat=zero
378 [ + + ]: 392 : do ib2dm=1,ndim
379 [ + + ]: 1858 : do ib1dm=ib2dm,ndim
380 : 1466 : tmp_mat(ib1dm,ib2dm)=rdm_k(ib1dm,ib2dm)
381 : : ! Dji = Dij^*
382 : 1810 : tmp_mat(ib2dm,ib1dm)=conjg(tmp_mat(ib1dm,ib2dm))
383 : : end do
384 : : end do
385 : :
386 [ + + ]: 688 : work=zero
387 [ + + ]: 392 : occs_tmp=zero
388 : 48 : info=0
389 : 48 : call zheev('v','u',ndim,tmp_mat,ndim,occs_tmp,work,lwork,rwork,info)
390 [ - + ]: 48 : ABI_CHECK(info == 0, sjoin("Failed the diagonalization of the updated GW 1-RDM with info:", itoa(info)))
391 : :
392 : : ! Sort in descending order
393 [ + + ]: 392 : do ib1dm=1,ndim
394 : 344 : occs_tmp2(ib1dm)=occs_tmp(ndim-(ib1dm-1))
395 [ + + ]: 2932 : do ib2dm=1,ndim
396 : 2932 : eigenvect(ib2dm,ib1dm)=tmp_mat(ib2dm,(ndim-(ib1dm-1)))
397 : : end do
398 [ + + ]: 392 : if (abs(occs_tmp2(ib1dm))<tol10) then
399 : 106 : occs_tmp2(ib1dm)=zero
400 : : end if
401 : : end do
402 : :
403 : : ! Check orthonormality?
404 [ - + ]: 48 : if (check_Sijmat) then
405 [ # # ]: 0 : do ib1dm=1,ndim
406 [ # # ]: 0 : do ib2dm=1,ib1dm
407 : : Sib1k_ib2k=czero
408 [ # # ]: 0 : do ib3dm=1,ndim
409 : 0 : Sib1k_ib2k=Sib1k_ib2k+conjg(eigenvect(ib3dm,ib1dm))*eigenvect(ib3dm,ib2dm)
410 : : end do
411 [ # # ]: 0 : if (ib1dm==ib2dm) then
412 [ # # ]: 0 : if(abs(Sib1k_ib2k-cmplx(one,zero))>tol10) then
413 : 0 : write(msg,'(a45,i5,a1,i5,f10.5)') 'Large deviation from identity for bands ',ib1dm,' ',ib2dm,real(Sib1k_ib2k)
414 : 0 : call wrtout(std_out,msg)
415 : : endif
416 : : else
417 [ # # ]: 0 : if (abs(Sib1k_ib2k)>tol10) then
418 : 0 : write(msg,'(a45,i5,a1,i5,f10.5)') 'Large deviation from identity for bands ',ib1dm,' ',ib2dm,real(Sib1k_ib2k)
419 : 0 : call wrtout(std_out,msg)
420 : : end if
421 : : end if
422 : : end do
423 : : end do
424 : : end if
425 : :
426 : : ! Print results
427 [ + - ]: 48 : if (info==0) then
428 [ + + ]: 48 : if (iinfo==0) then
429 : 27 : write(msg,'(a51,3f10.5)') 'Occs. after updating with Sx-Vxc corr. at k-point:',ebands%kptns(1:,ik_ibz)
430 : : else
431 : 21 : write(msg,'(a51,3f10.5)') 'Occs. after updating with S_c correct. at k-point:',ebands%kptns(1:,ik_ibz)
432 : : endif
433 : 48 : call wrtout(units, msg)
434 : 48 : ib1dm=ndim-(ndim/10)*10
435 [ + - - - ]: 48 : do ib2dm=1,(ndim/10)*10,10
436 : 0 : write(msg,'(f11.5,9f10.5)') occs_tmp2(ib2dm:ib2dm+9)
437 : 48 : call wrtout(units, msg)
438 : : end do
439 : 48 : ib1dm=(ndim/10)*10+1
440 : 48 : write(msg,'(f11.5,*(f10.5))') occs_tmp2(ib1dm:)
441 : 48 : call wrtout(units, msg)
442 : : else
443 : 0 : write(msg,'(a36,3f10.5)') 'Error computing occs. for k-point: ',ebands%kptns(1:,ik_ibz)
444 : 0 : call wrtout(units, msg)
445 : : end if
446 : :
447 : : ! Store natural orbital eigenvectors matrix and occs. Also compute total number of electrons for this k-point
448 : 48 : toccs_k=zero
449 [ + + ]: 392 : do ib1dm=1,ndim
450 [ + + ]: 2932 : do ib2dm=1,ndim
451 : 2932 : nateigv(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)=eigenvect(ib1dm,ib2dm)
452 : : end do
453 : 344 : occs(ib1+(ib1dm-1),ik_ibz)=occs_tmp2(ib1dm) ! Overwrite the initial KS-DFT occs from ib1 to ib2
454 : 392 : toccs_k=toccs_k+occs_tmp2(ib1dm)
455 : : end do
456 : :
457 : 48 : write(msg,'(a22,i5,a3,i5,a21,f10.5)') ' Total occ. from band ',ib1,' to', ib2,' at current k-point: ',toccs_k
458 : 48 : call wrtout(units, msg)
459 : 48 : write(msg,'(a5)') ' '
460 : 48 : call wrtout(units, msg)
461 : :
462 [ - + ]: 48 : ABI_FREE(rwork)
463 [ - + ]: 48 : ABI_FREE(work)
464 [ - + ]: 48 : ABI_FREE(tmp_mat)
465 [ - + ]: 48 : ABI_FREE(eigenvect)
466 [ - + ]: 48 : ABI_FREE(occs_tmp)
467 [ - + ]: 48 : ABI_FREE(occs_tmp2)
468 : :
469 : 48 : end subroutine natoccs
470 : : !!***
471 : :
472 : : !!****f* ABINIT/update_hdr_bst
473 : : !! NAME
474 : : !! update_hdr_bst
475 : : !!
476 : : !! FUNCTION
477 : : !! Update the Hdr for the WFK and DEN files and the occ. numbers in the ebands file for a given k-point
478 : : !!
479 : : !! INPUTS
480 : : !! Wfd<wfd_t>=Datatype gathering data on QP amplitudes.
481 : : !! ngfft_in(18)=information on the fine FFT grid used for densities and potentials.
482 : : !! b1gw=min band for given k in the interval where we update.
483 : : !! b2gw=max band for given k in the interval where we update.
484 : : !! occs= array containing the occ numbers for a given k-point occs_ks(nband,k-point).
485 : : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
486 : : !! eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
487 : : !! occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
488 : : !!
489 : : !! OUTPUT
490 : : !! Updated Hdr and ebands information
491 : : !!
492 : : !! SOURCE
493 : :
494 [ - + ]: 5 : subroutine update_hdr_bst(Wfd,occs,b1gw,b2gw,ebands,Hdr,ngfft_in)
495 : :
496 : : !Arguments ------------------------------------
497 : : !scalars
498 : : integer,intent(in) :: b1gw,b2gw
499 : : integer,intent(in),dimension(3) :: ngfft_in
500 : : type(ebands_t),target,intent(inout) :: ebands
501 : : type(Hdr_type),intent(inout) :: Hdr
502 : : class(wfd_t),intent(in) :: Wfd
503 : : !arrays
504 : : real(dp),intent(in) :: occs(:,:)
505 : : !Local variables ------------------------------
506 : : !scalars
507 : : integer :: ib1dm,ib2dm,dim_bands,ikpoint
508 : : !arrays
509 : : !************************************************************************
510 : :
511 : : ! ebands occ (QP_ebands ones) are changed and never recoverd
512 [ + + ]: 35 : do ikpoint=1,ebands%nkpt
513 [ + + ]: 269 : ebands%occ(b1gw:b2gw,ikpoint,1) = occs(b1gw:b2gw,ikpoint) ! Spins summed, occ in [0:2]
514 : : enddo
515 : 5 : ABI_COMMENT("QP_ebands: occupancies were updated with nat. orb. ones")
516 [ - + ]: 5 : if ((size(Hdr%occ(:))/ebands%nkpt) < (b2gw-b1gw+1)) then
517 : : !Actually, we should never reach this point because the code should stop during Wfd initialization in m_sigma_driver
518 : 0 : ABI_ERROR("Impossible to use the existing read WFK to build a new one!")
519 : : end if
520 : :
521 : : ! Update occ in Hdr before printing
522 : 5 : ib1dm=1
523 [ + + ]: 35 : do ikpoint=1,ebands%nkpt
524 : 30 : dim_bands=size(ebands%occ(:,ikpoint,1))
525 [ + + ]: 275 : do ib2dm=1,dim_bands
526 : 240 : Hdr%occ(ib1dm)=ebands%occ(ib2dm,ikpoint,1) ! Because Hdr%occ is a 1-D array
527 : 270 : ib1dm=ib1dm+1
528 : : end do
529 : : end do
530 : :
531 [ + + ]: 35 : Hdr%npwarr(:)=Wfd%npwarr(:) ! Use the npw and ngfft = ones used in GW calc
532 [ + + ]: 20 : Hdr%ngfft(1:3)=ngfft_in(1:3)
533 : 5 : ABI_COMMENT("Hdr_sigma: occupancies, npw, and ngfft were updated")
534 : :
535 : 5 : end subroutine update_hdr_bst
536 : : !!***
537 : :
538 : : !!****f* ABINIT/print_tot_occ
539 : : !! NAME
540 : : !! print_tot_occ
541 : : !!
542 : : !! FUNCTION
543 : : !! Compute and print the total (averaged) occ. from all k-points
544 : : !!
545 : : !! INPUTS
546 : : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
547 : : !! eig(Sigp%nbnds,%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
548 : : !! occ(Sigp%nbnds,%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
549 : : !!
550 : : !! OUTPUT
551 : : !! Print the total (averaged) occ. = sum_k weight_k * Nelec_k
552 : : !!
553 : : !! SOURCE
554 : :
555 : 5 : subroutine print_tot_occ(ebands)
556 : :
557 : : !Arguments ------------------------------------
558 : : type(ebands_t),intent(in) :: ebands
559 : :
560 : : !Local variables-------------------------------
561 : : !scalars
562 : : character(len=500) :: msg
563 : : integer :: ik,spin, units(2)
564 : : real(dp) :: wtk,occ_bks,tot_occ
565 : : ! *************************************************************************
566 : :
567 [ + + ]: 15 : units = [std_out, ab_out]
568 : :
569 : 5 : tot_occ=zero
570 : :
571 [ + + ]: 10 : do spin=1,ebands%nsppol
572 [ + + ]: 40 : do ik=1,ebands%nkpt
573 : 30 : wtk = ebands%wtk(ik)
574 [ + + ]: 270 : occ_bks = sum(ebands%occ(:,ik,spin))
575 : : !if (sigma%nsig_ab==1) then ! Only closed-shell restricted is programed
576 : 35 : tot_occ=tot_occ+occ_bks*wtk
577 : : !end if
578 : : end do
579 : : end do
580 : :
581 : 5 : write(msg,'(a1)') ' '
582 : 5 : call wrtout(units, msg)
583 : 5 : write(msg,'(a39,f10.5)') ' Total averaged occ. from all k-points: ',tot_occ
584 : 5 : call wrtout(units, msg)
585 : 5 : write(msg,'(a1)') ' '
586 : 5 : call wrtout(units, msg)
587 : :
588 : 5 : end subroutine print_tot_occ
589 : : !!***
590 : :
591 : : !!****f* ABINIT/get_chkprdm
592 : : !! NAME
593 : : !! get_chkprdm
594 : : !!
595 : : !! FUNCTION
596 : : !! Read all checkpoint files built on previous runs
597 : : !!
598 : : !! INPUTS
599 : : !! Wfd<wfd_t>=Wave function descriptor see file 69_wfd/m_wfd.F90
600 : : !! Kmesh <kmesh_t>=Structure describing the k-point sampling.
601 : : !! Sigp<sigparams_t>=Parameters governing the self-energy calculation.
602 : : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
603 : : !! eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
604 : : !! occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
605 : : !! occs = occ. numbers array occs(Wfd%mband,Wfd%nkibz)
606 : : !! nateigv = natural orbital eigenvectors nateigv(Wfd%mband,Wfd%mband,Wfd%nkibz,Sigp%nsppol))
607 : : !! sigmak_todo = integer array initialized to 1 and its components are set to 0 if the kpoint
608 : : !! is read from the checkpoint sigmak_todo(Wfd%nkibz)
609 : : !! my_rank = rank of the mpi process.
610 : : !!
611 : : !! OUTPUT
612 : : !! occ are updated if they are read from any checkpoint file
613 : : !! nateigv are stored if they are read from any checkpoint file
614 : : !! sigmak_todo components set to 1 if the kpoint is read from any checkpoint file
615 : : !!
616 : : !! SOURCE
617 : :
618 [ - + - + : 1 : subroutine get_chkprdm(Wfd,Kmesh,Sigp,ebands,occs,nateigv,sigmak_todo,my_rank,gw1rdm_fname_in)
- + ]
619 : : !Arguments ------------------------------------
620 : : !scalars
621 : : integer,intent(in) :: my_rank
622 : : class(wfd_t),intent(in) :: Wfd
623 : : type(kmesh_t),intent(in) :: Kmesh
624 : : type(sigparams_t),intent(in) :: Sigp
625 : : type(ebands_t),intent(in) :: ebands
626 : : character(len=fnlen),intent(in) :: gw1rdm_fname_in
627 : : !arrays
628 : : integer,intent(inout) :: sigmak_todo(:)
629 : : real(dp),intent(inout) :: occs(:,:)
630 : : complex(dp),intent(inout) :: nateigv(:,:,:,:)
631 : : !Local variables-------------------------------
632 : : !scalars
633 : : integer,parameter :: master=0,iunit=666314
634 : : integer :: ierr,ib1,ib2,ib3,ikcalc,istat,ik_ibz,ik_ibz_read,iread,iread_eigv
635 : : real(dp) :: auxl_read
636 : : character(len=fnlen) :: gw1rdm_fname
637 : : character(len=500) :: msg
638 : : !arrays
639 : 1 : real(dp),allocatable :: occ_tmp(:),eigvect_tmp(:)
640 : : ! *************************************************************************
641 : :
642 [ + - ]: 1 : if (my_rank==master) then
643 : 1 : iread_eigv=Wfd%mband
644 : 1 : iread_eigv=iread_eigv*(2*iread_eigv)
645 [ - + + - : 3 : ABI_MALLOC(occ_tmp,(Wfd%mband))
+ - + - -
+ - + ]
646 [ - + + - : 3 : ABI_MALLOC(eigvect_tmp,(iread_eigv))
+ - + - -
+ - + ]
647 : :
648 [ + + ]: 7 : do ikcalc=1,Sigp%nkptgw
649 : 6 : ik_ibz=Kmesh%tab(Sigp%kptgw2bz(ikcalc)) ! Irred k-point for GW
650 [ + - ]: 6 : if(ik_ibz<10) then
651 : 6 : write(gw1rdm_fname,"(a,i1)") trim(gw1rdm_fname_in),ik_ibz
652 [ # # ]: 0 : else if(ik_ibz<100 .and. ik_ibz>=10) then
653 : 0 : write(gw1rdm_fname,"(a,i2)") trim(gw1rdm_fname_in),ik_ibz
654 [ # # ]: 0 : else if(ik_ibz<1000 .and. ik_ibz>=100) then
655 : 0 : write(gw1rdm_fname,"(a,i3)") trim(gw1rdm_fname_in),ik_ibz
656 : : else
657 : 0 : ABI_ERROR("The maximum k-point label for the checkpoint file to read is 999.")
658 : : end if
659 : 6 : write(msg,'(a1)')' '
660 : 6 : call wrtout(std_out,msg)
661 : 6 : write(msg,'(a25,a)')' Reading checkpoint file ',trim(gw1rdm_fname)
662 : 6 : call wrtout(std_out,msg)
663 : 6 : write(msg,'(a1)')' '
664 : 6 : call wrtout(std_out,msg)
665 [ + + + + ]: 822 : occ_tmp(:)=zero;eigvect_tmp(:)=zero;
666 : 6 : open(unit=iunit,form='unformatted',file=gw1rdm_fname,iostat=istat,status='old')
667 : 6 : iread=0;ik_ibz_read=0;
668 [ + + ]: 6 : if (istat==0) then
669 : : do
670 [ + + ]: 414 : if (iread<Wfd%mband) then
671 : 27 : iread=iread+1
672 : 27 : read(iunit,iostat=istat) auxl_read
673 [ + + ]: 27 : if (istat==0) then
674 : 24 : occ_tmp(iread)=auxl_read
675 : : end if
676 [ + + ]: 387 : else if (iread<(iread_eigv+Wfd%mband)) then
677 : 384 : iread=iread+1
678 : 384 : read(iunit,iostat=istat) auxl_read
679 [ + - ]: 384 : if (istat==0) then
680 : 384 : eigvect_tmp(iread-Wfd%mband)=auxl_read
681 : : end if
682 : : else
683 : 3 : read(iunit,iostat=istat) ik_ibz_read
684 [ + - + - ]: 3 : if (istat==0 .and. ik_ibz_read/=0) then
685 : 3 : iread=0
686 : 3 : sigmak_todo(ik_ibz_read)=0
687 : 3 : ib3=1
688 [ + + ]: 27 : do ib1=1,Wfd%mband
689 : 24 : occs(ib1,ik_ibz_read)=occ_tmp(ib1)
690 [ + + ]: 219 : do ib2=1,Wfd%mband
691 : 192 : nateigv(ib1,ib2,ik_ibz_read,1)=cmplx(eigvect_tmp(ib3),eigvect_tmp(ib3+1))
692 : 216 : ib3=ib3+2
693 : : end do
694 : : end do
695 : 3 : ik_ibz_read=0
696 [ + + + + ]: 411 : occ_tmp=zero;eigvect_tmp=zero;
697 : : end if
698 : : end if
699 [ + + ]: 414 : if(istat/=0) then
700 : : exit
701 : : end if
702 : : end do
703 : : end if
704 : 7 : close(iunit)
705 : : end do
706 : 1 : write(msg,'(a1)')' '
707 : 1 : call wrtout(std_out,msg)
708 : 1 : write(msg,'(a49)')' List of k-points read from all checkpoint files '
709 : 1 : call wrtout(std_out,msg)
710 [ + + ]: 7 : do ikcalc=1,Sigp%nkptgw
711 : 6 : ik_ibz=Kmesh%tab(Sigp%kptgw2bz(ikcalc)) ! Irred k-point for GW
712 [ + + ]: 7 : if (sigmak_todo(ik_ibz)==0) then
713 : 3 : write(msg,'(3f10.5)') ebands%kptns(1:,ik_ibz)
714 : 3 : call wrtout(std_out,msg)
715 : : end if
716 : : enddo
717 : 1 : write(msg,'(a1)')' '
718 : 1 : call wrtout(std_out,msg)
719 [ - + ]: 1 : ABI_FREE(occ_tmp)
720 [ - + ]: 1 : ABI_FREE(eigvect_tmp)
721 : : end if
722 : :
723 : : ! Broadcast from master the information stored in occs and nateigv to all processes.
724 : 1 : call xmpi_barrier(Wfd%comm)
725 : : ierr=0
726 : 1 : call xmpi_bcast(sigmak_todo(:),master,Wfd%comm,ierr)
727 [ - + ]: 1 : if(ierr/=0) then
728 : 0 : ABI_ERROR("Error distributing the sigmak_todo table.")
729 : : endif
730 : 1 : call xmpi_bcast(occs(:,:),master,Wfd%comm,ierr)
731 [ - + ]: 1 : if(ierr/=0) then
732 : 0 : ABI_ERROR("Error distributing the occs read from checkpoint file(s).")
733 : : endif
734 : 1 : call xmpi_bcast(nateigv(:,:,:,:),master,Wfd%comm,ierr)
735 [ - + ]: 1 : if(ierr/=0) then
736 : 0 : ABI_ERROR("Error distributing the natural orbital eigenvectors read from checkpoint file(s).")
737 : : endif
738 : :
739 : 1 : end subroutine get_chkprdm
740 : : !!***
741 : :
742 : : !!****f* ABINIT/print_chkprdm
743 : : !! NAME
744 : : !! print_chkprdm
745 : : !!
746 : : !! FUNCTION
747 : : !! Write the checkpoint file for a given k-point
748 : : !!
749 : : !! INPUTS
750 : : !! Wfd<wfd_t>=Wave function descriptor see file 69_wfd/m_wfd.F90
751 : : !! occs = occ. numbers array occs(Wfd%mband,Wfd%nkibz)
752 : : !! nateigv = natural orbital eigenvectors nateigv(Wfd%mband,Wfd%mband,Wfd%nkibz,Sigp%nsppol))
753 : : !! my_rank = rank of the mpi process.
754 : : !! gw1rdm_fname_out = name of the gw1rdm checkpoint out without k-point extension
755 : : !!
756 : : !! OUTPUT
757 : : !!
758 : : !! SOURCE
759 : :
760 [ - + - + ]: 6 : subroutine print_chkprdm(Wfd,occs,nateigv,ik_ibz,my_rank,gw1rdm_fname_out)
761 : : !Arguments ------------------------------------
762 : : !scalars
763 : : integer,intent(in) :: ik_ibz,my_rank
764 : : class(wfd_t),intent(in) :: Wfd
765 : : character(len=fnlen),intent(in) :: gw1rdm_fname_out
766 : : !arrays
767 : : real(dp),intent(in) :: occs(:,:)
768 : : complex(dp),intent(in) :: nateigv(:,:,:,:)
769 : : !Local variables-------------------------------
770 : : !scalars
771 : : integer,parameter :: master=0,iunit=666314
772 : : integer :: iwrite,iwrite2
773 : : character(len=fnlen) :: gw1rdm_fname
774 : : character(len=500) :: msg
775 : : !arrays
776 : : ! *************************************************************************
777 : :
778 [ + - ]: 6 : if (my_rank==master) then
779 [ + - ]: 6 : if(ik_ibz<10) then
780 : 6 : write(gw1rdm_fname,"(a,i1)") trim(gw1rdm_fname_out),ik_ibz
781 [ # # ]: 0 : else if(ik_ibz<100 .and. ik_ibz>=10) then
782 : 0 : write(gw1rdm_fname,"(a,i2)") trim(gw1rdm_fname_out),ik_ibz
783 [ # # ]: 0 : else if(ik_ibz<1000 .and. ik_ibz>=100) then
784 : 0 : write(gw1rdm_fname,"(a,i3)") trim(gw1rdm_fname_out),ik_ibz
785 : : else
786 : 0 : ABI_ERROR("The maximum k-point label for the checkpoint file to write is 999.")
787 : : end if
788 : 6 : write(msg,'(a1)')' '
789 : 6 : call wrtout(std_out,msg)
790 : 6 : write(msg,'(a25,a)')' Writing checkpoint file ',trim(gw1rdm_fname)
791 : 6 : call wrtout(std_out,msg)
792 : 6 : write(msg,'(a1)')' '
793 : 6 : call wrtout(std_out,msg)
794 : 6 : open(unit=iunit,form='unformatted',file=gw1rdm_fname)
795 [ + + ]: 54 : do iwrite=1,Wfd%mband
796 : 54 : write(iunit) occs(iwrite,ik_ibz)
797 : : end do
798 [ + + ]: 54 : do iwrite=1,Wfd%mband
799 [ + + ]: 438 : do iwrite2=1,Wfd%mband
800 : 384 : write(iunit) real(nateigv(iwrite,iwrite2,ik_ibz,1))
801 : 432 : write(iunit) aimag(nateigv(iwrite,iwrite2,ik_ibz,1))
802 : : end do
803 : : end do
804 : 6 : write(iunit) ik_ibz
805 : 6 : close(iunit)
806 : : end if
807 : :
808 : 6 : call xmpi_barrier(Wfd%comm)
809 : :
810 : 6 : end subroutine print_chkprdm
811 : : !!***
812 : :
813 : : !!****f* ABINIT/change_matrix
814 : : !! NAME
815 : : !! change_matrix
816 : : !!
817 : : !! FUNCTION
818 : : !! Transform integrals from KS -> NO and NO -> KS orbitals
819 : : !!
820 : : !! Transform <NO_i|K[NO]|NO_j> -> <KS_i|K[NO]|KS_j>,
821 : : !! <KS_i|J[NO]|KS_j> -> <NO_i|J[NO]|NO_j>,
822 : : !! and <KS_i|T|KS_j> -> <NO_i|T|NO_j>
823 : : !!
824 : : !!
825 : : !! INPUTS
826 : : !! Kmesh <kmesh_t>=Structure describing the k-point sampling.
827 : : !! Sigp<sigparams_t>=Parameters governing the self-energy calculation.
828 : : !! nateigv = natural orbital eigenvectors nateigv(Wfd%mband,Wfd%mband,Wfd%nkibz,Sigp%nsppol))
829 : : !!
830 : : !! OUTPUT
831 : : !! Mels
832 : : !! %kinetic=matrix elements of $t$.
833 : : !! %vhartr =matrix elements of $v_H$.
834 : : !! Sr=sigma_t (see the definition of this structured datatype)
835 : : !!
836 : : !! SOURCE
837 : :
838 [ - + ]: 4 : subroutine change_matrix(Sigp,Sr,Mels,Kmesh,nateigv)
839 : :
840 : : !Arguments ------------------------------------
841 : : !scalars
842 : : type(kmesh_t),intent(in) :: Kmesh
843 : : type(sigparams_t),intent(in) :: Sigp
844 : : type(sigma_t),intent(inout) :: Sr
845 : : type(melements_t),intent(inout) :: Mels
846 : : !arrays
847 : : complex(dp),intent(in) :: nateigv(:,:,:,:)
848 : : !Local variables-------------------------------
849 : : !scalars
850 : : integer :: ikcalc,ik_ibz,ib1,ib2,ib1dm,ib2dm
851 : : !arrays
852 : 4 : complex(dp),allocatable :: mat2rot(:,:),Umat(:,:)
853 : : ! *************************************************************************
854 : :
855 [ + + ]: 28 : do ikcalc=1,Sigp%nkptgw
856 : 24 : ik_ibz=Kmesh%tab(Sigp%kptgw2bz(ikcalc)) ! Index of the irreducible k-point for GW
857 [ + + ]: 48 : ib1=MINVAL(Sigp%minbnd(ikcalc,:)) ! min and max band indices for GW corrections (for this k-point)
858 [ + + ]: 48 : ib2=MAXVAL(Sigp%maxbnd(ikcalc,:))
859 [ + - - + : 96 : ABI_MALLOC(mat2rot,(ib2-ib1+1,ib2-ib1+1))
+ - - + +
- + - + -
- + - + -
+ ]
860 [ - + + - : 72 : ABI_MALLOC(Umat,(ib2-ib1+1,ib2-ib1+1))
- + + - -
+ - + -
+ ]
861 : : ! <NO_i|K[NO]|NO_j> -> <KS_i|K[NO]|KS_j>
862 [ + + ]: 216 : do ib1dm=1,ib2-ib1+1
863 [ + + ]: 1752 : do ib2dm=1,ib2-ib1+1
864 : 1536 : Umat(ib1dm,ib2dm)=nateigv(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)
865 : 1728 : mat2rot(ib1dm,ib2dm)=Sr%x_mat(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)
866 : : end do
867 : : end do
868 : 24 : call rotate_ks_no(ib1,ib2,mat2rot,Umat,0)
869 [ + + ]: 216 : do ib1dm=1,ib2-ib1+1
870 [ + + ]: 1752 : do ib2dm=1,ib2-ib1+1
871 : 1728 : Sr%x_mat(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)=mat2rot(ib1dm,ib2dm)
872 : : end do
873 : : end do
874 : : ! <KS_i|J[NO]|KS_j> -> <NO_i|J[NO]|NO_j>
875 [ + + ]: 216 : do ib1dm=1,ib2-ib1+1
876 [ + + ]: 1752 : do ib2dm=1,ib2-ib1+1
877 : 1728 : mat2rot(ib1dm,ib2dm)=Mels%vhartree(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)
878 : : end do
879 : : end do
880 : 24 : call rotate_ks_no(ib1,ib2,mat2rot,Umat,1)
881 [ + + ]: 216 : do ib1dm=1,ib2-ib1+1
882 [ + + ]: 1752 : do ib2dm=1,ib2-ib1+1
883 : 1728 : Mels%vhartree(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)=mat2rot(ib1dm,ib2dm)
884 : : end do
885 : : end do
886 : : ! <KS_i|T|KS_j> -> <NO_i|T|NO_j>
887 [ + + ]: 216 : do ib1dm=1,ib2-ib1+1
888 [ + + ]: 1752 : do ib2dm=1,ib2-ib1+1
889 : 1728 : mat2rot(ib1dm,ib2dm)=Mels%kinetic(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)
890 : : end do
891 : : end do
892 : 24 : call rotate_ks_no(ib1,ib2,mat2rot,Umat,1)
893 [ + + ]: 216 : do ib1dm=1,ib2-ib1+1
894 [ + + ]: 1752 : do ib2dm=1,ib2-ib1+1
895 : 1728 : Mels%kinetic(ib1+(ib1dm-1),ib1+(ib2dm-1),ik_ibz,1)=mat2rot(ib1dm,ib2dm)
896 : : end do
897 : : end do
898 [ - + ]: 24 : ABI_FREE(Umat)
899 [ - + ]: 28 : ABI_FREE(mat2rot)
900 : : end do
901 [ - + - + ]: 4 : end subroutine change_matrix
902 : : !!***
903 : :
904 : : !!****f* ABINIT/print_total_energy
905 : : !! NAME
906 : : !! print_total_energy
907 : : !!
908 : : !! FUNCTION
909 : : !! Print total energy and energy components
910 : : !!
911 : : !! INPUTS
912 : : !! all energy terms are self-explanatory
913 : : !!
914 : : !! OUTPUT
915 : : !!
916 : : !! SOURCE
917 : :
918 : 4 : subroutine print_total_energy(ekin_energy,evext_energy,evextnl_energy,e_corepsp,eh_energy,ex_energy,&
919 : : exc_mbb_energy,e_ewald,etot,etot2,den_int)
920 : : !Arguments ------------------------------------
921 : : !scalars
922 : : real(dp),intent(in) :: ekin_energy,evext_energy,evextnl_energy,e_corepsp,eh_energy,ex_energy
923 : : real(dp),intent(in) :: exc_mbb_energy,e_ewald,etot,etot2,den_int
924 : :
925 : : !Local variables-------------------------------
926 : : character(len=500) :: msg
927 : : integer :: units(2)
928 : :
929 : : !************************************************************************
930 : :
931 [ + + ]: 12 : units = [std_out, ab_out]
932 : :
933 : 4 : write(msg,'(a1)')' '
934 : 4 : call wrtout(units, msg)
935 : : write(msg,'(a98)')'---------------------------------------------------------------&
936 : 4 : &----------------------------------'
937 : 4 : call wrtout(units, msg)
938 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Ekinetic = : ',ekin_energy,' Ha ,',ekin_energy*Ha_eV,' eV'
939 : 4 : call wrtout(units, msg)
940 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Evext_l = : ',evext_energy,' Ha ,',evext_energy*Ha_eV,' eV'
941 : 4 : call wrtout(units, msg)
942 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Evext_nl = : ',evextnl_energy,' Ha ,',evextnl_energy*Ha_eV,' eV'
943 : 4 : call wrtout(units, msg)
944 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Epsp_core = : ',e_corepsp,' Ha ,',e_corepsp*Ha_eV,' eV'
945 : 4 : call wrtout(units, msg)
946 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Ehartree = : ',eh_energy,' Ha ,',eh_energy*Ha_eV,' eV'
947 : 4 : call wrtout(units, msg)
948 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Ex[SD] = : ',ex_energy,' Ha ,',ex_energy*Ha_eV,' eV'
949 : 4 : call wrtout(units, msg)
950 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Exc[MBB] = : ',exc_mbb_energy,' Ha ,',exc_mbb_energy*Ha_eV,' eV'
951 : 4 : call wrtout(units, msg)
952 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Enn = : ',e_ewald,' Ha ,',e_ewald*Ha_eV,' eV'
953 : 4 : call wrtout(units, msg)
954 : : write(msg,'(a98)')'-----------------------------------------------------------------&
955 : 4 : &--------------------------------'
956 : 4 : call wrtout(units, msg)
957 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Etot[SD] = : ',etot,' Ha ,',etot*Ha_eV,' eV'
958 : 4 : call wrtout(units, msg)
959 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Etot[MBB] = : ',etot2,' Ha ,',etot2*Ha_eV,' eV'
960 : 4 : call wrtout(units, msg)
961 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Vee[SD] = : ',(ex_energy+eh_energy),' Ha ,',(ex_energy+eh_energy)*Ha_eV,' eV'
962 : 4 : call wrtout(units, msg)
963 : 4 : write(msg,'(a,f10.5,a,f10.3,a)')' Vee[MBB] = : ',(exc_mbb_energy+eh_energy),' Ha ,',&
964 : 8 : &(exc_mbb_energy+eh_energy)*Ha_eV,' eV'
965 : 4 : call wrtout(units, msg)
966 : 4 : write(msg,'(a,f10.5)') ' Density = : ',den_int
967 : 4 : call wrtout(units, msg)
968 : 4 : write(msg,'(a)')' Vee[SD] (= Ehartree + Ex[SD]) energy obtained using GW 1-RDM:'
969 : 4 : call wrtout(units, msg)
970 : 4 : write(msg,'(a)')' Vee[MBB] (= Ehartree + Exc[MBB]) energy obtained using GW 1-RDM:'
971 : 4 : call wrtout(units, msg)
972 : : write(msg,'(a98)')'-------------------------------------------------------------------&
973 : 4 : &------------------------------'
974 : 4 : call wrtout(units, msg)
975 : :
976 : 4 : end subroutine print_total_energy
977 : : !!***
978 : :
979 : : !!****f* ABINIT/print_band_energies
980 : : !! NAME
981 : : !! print_band_energies
982 : : !!
983 : : !! FUNCTION
984 : : !! Print updated band energies
985 : : !!
986 : : !!
987 : : !! INPUTS
988 : : !! Kmesh <kmesh_t>=Structure describing the k-point sampling.
989 : : !! Sigp<sigparams_t>=Parameters governing the self-energy calculation.
990 : : !! Mels
991 : : !! %kinetic=matrix elements of $t$.
992 : : !! %vhartr =matrix elements of $v_H$.
993 : : !! Sr=sigma_t (see the definition of this structured datatype)
994 : : !! ebands=<ebands_t>=Datatype gathering info on the QP energies (KS if one shot)
995 : : !! eig(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=KS or QP energies for k-points, bands and spin
996 : : !! occ(Sigp%nbnds,Kmesh%nibz,Wfd%nsppol)=occupation numbers, for each k point in IBZ, each band and spin
997 : : !!
998 : : !! OUTPUT
999 : : !!
1000 : : !! SOURCE
1001 : :
1002 [ - + - + ]: 4 : subroutine print_band_energies(b1gw,b2gw,Sr,Sigp,Mels,Kmesh,ebands,new_hartr,old_purex)
1003 : : !Arguments ------------------------------------
1004 : : !scalars
1005 : : type(kmesh_t),intent(in) :: Kmesh
1006 : : type(sigparams_t),intent(in) :: Sigp
1007 : : type(sigma_t),intent(in) :: Sr
1008 : : type(ebands_t),intent(in) :: ebands
1009 : : type(melements_t),intent(in) :: Mels
1010 : : integer,intent(in) :: b1gw,b2gw
1011 : : !arrays
1012 : : complex(dp),intent(in) :: old_purex(:,:),new_hartr(:,:)
1013 : : !Local variables-------------------------------
1014 : : !scalars
1015 : : integer :: ib,ikcalc,ik_ibz, units(2)
1016 : : real(dp) :: eik_new
1017 : : complex(dp) :: delta_band_ibik
1018 : : character(len=500) :: msg
1019 : : !************************************************************************
1020 : :
1021 [ + + ]: 12 : units = [std_out, ab_out]
1022 : :
1023 : 4 : write(msg,'(a1)') ' '
1024 : 4 : call wrtout(units, msg)
1025 : 4 : write(msg,'(a42)') ' Computing band corrections Delta eik (eV)'
1026 : 4 : call wrtout(units, msg)
1027 : 4 : write(msg,'(a42)') ' -----------------------------------------'
1028 : 4 : call wrtout(units, msg)
1029 : 4 : write(msg,'(a1)') ' '
1030 : 4 : call wrtout(units, msg)
1031 : 4 : write(msg,'(a1)') ' '
1032 : 4 : call wrtout(units, msg)
1033 : : write(msg,'(a110)') ' Band corrections Delta eik = <KS_i|K[NO]-a*K[KS]+vH[NO]&
1034 : 4 : &-vH[KS]-Vxc[KS]|KS_i> and eik^new = eik^GS + Delta eik'
1035 : 4 : call wrtout(units, msg)
1036 : 4 : write(msg,'(a1)') ' '
1037 : 4 : call wrtout(units, msg)
1038 [ + + ]: 28 : do ikcalc=1,Sigp%nkptgw
1039 : 24 : ik_ibz=Kmesh%tab(Sigp%kptgw2bz(ikcalc)) ! Index of the irreducible k-point for GW
1040 : : write(msg,'(a127)')'---------------------------------------------------------&
1041 : 24 : &--------------------------------------------------------------------'
1042 : 24 : call wrtout(units, msg)
1043 : : write(msg,'(a)')' k-point band eik^GS eik^new Delta eik &
1044 : 24 : & K[NO] a*K[KS] Vxc[KS] vH[NO] vH[KS]'
1045 : 24 : call wrtout(units, msg)
1046 [ + + ]: 220 : do ib=b1gw,b2gw
1047 : : delta_band_ibik=(new_hartr(ib,ikcalc)-Mels%vhartree(ib,ib,ik_ibz,1))&
1048 : 192 : &+Sr%x_mat(ib,ib,ik_ibz,1)-Mels%vxcval(ib,ib,ik_ibz,1)-old_purex(ib,ikcalc)
1049 : 192 : eik_new=real(ebands%eig(ib,ik_ibz,1))+real(delta_band_ibik)
1050 : : write(msg,'(i5,4x,i5,8(4x,f10.3))') &
1051 : 192 : & ik_ibz,ib,real(ebands%eig(ib,ik_ibz,1))*Ha_eV,eik_new*Ha_eV,real(delta_band_ibik)*Ha_eV,&
1052 : 192 : & real(Sr%x_mat(ib,ib,ik_ibz,1))*Ha_eV,real(old_purex(ib,ikcalc))*Ha_eV,&
1053 : 192 : & real(Mels%vxcval(ib,ib,ik_ibz,1))*Ha_eV,&
1054 : 384 : & real(new_hartr(ib,ikcalc))*Ha_eV,real(Mels%vhartree(ib,ib,ik_ibz,1))*Ha_eV
1055 : 216 : call wrtout(units, msg)
1056 : : enddo
1057 : : enddo
1058 : : write(msg,'(a127)')'---------------------------------------------------------&
1059 : 4 : &--------------------------------------------------------------------'
1060 : 4 : call wrtout(units, msg)
1061 : :
1062 : 4 : end subroutine print_band_energies
1063 : : !!***
1064 : :
1065 : : !!****f* ABINIT/rotate_ks_no
1066 : : !! NAME
1067 : : !! rotate_ks_no
1068 : : !!
1069 : : !! FUNCTION
1070 : : !! Rotate a matrix from KS to NO basis and vicerversa.
1071 : : !!
1072 : : !! INPUTS
1073 : : !! ib1=min band for given k
1074 : : !! ib2=max band for given k.
1075 : : !! Umat=array containing the eigenvectors in Columns (a unitary matrix)
1076 : : !! Mat=initially an array containing the matrix elements in KS or NO basis
1077 : : !! option=0 rotate from NO -> KS | 1 rotate from KS -> NO
1078 : : !!
1079 : : !! OUTPUT
1080 : : !! Rotate a matrix from KS to NO basis and vicerversa and save the new matrix on Mat.
1081 : : !! Mat=at the end an array containing the matrix elements in NO or KS basis
1082 : : !!
1083 : : !! SOURCE
1084 : :
1085 [ - + - + ]: 72 : subroutine rotate_ks_no(ib1,ib2,Mat,Umat,option)
1086 : : !Arguments ------------------------------------
1087 : : !scalars
1088 : : integer,intent(in) :: ib1,ib2,option
1089 : : !arrays
1090 : : complex(dp),intent(in) :: Umat(:,:)
1091 : : complex(dp),intent(inout) :: Mat(:,:)
1092 : : !Local variables ------------------------------
1093 : : !scalars
1094 : : integer:: ndim
1095 : : !arrays
1096 : : !************************************************************************
1097 : :
1098 : 72 : ndim=ib2-ib1+1
1099 [ + + ]: 72 : if (option==0) then
1100 : 24 : call no2ks(ndim,Mat,Umat)
1101 : : else
1102 : 48 : call ks2no(ndim,Mat,Umat)
1103 : : end if
1104 : :
1105 : 72 : end subroutine rotate_ks_no
1106 : : !!***
1107 : :
1108 : : !!****f* ABINIT/ks2no
1109 : : !! NAME
1110 : : !! ks2no
1111 : : !!
1112 : : !! FUNCTION
1113 : : !! Transform the matrix mat from KS to NO basis
1114 : : !!
1115 : : !! INPUTS
1116 : : !! dim=dimension of the matrices
1117 : : !! mat=array in the KS basis
1118 : : !! rot=unitary matrix containg the eigenvectors in NO basis
1119 : : !!
1120 : : !! OUTPUT
1121 : : !! mat=array in the NO basis
1122 : : !!
1123 : : !! SOURCE
1124 : :
1125 [ - + - + ]: 48 : subroutine ks2no(ndim,mat,rot)
1126 : : !Arguments ------------------------------------
1127 : : !scalars
1128 : : integer,intent(in) :: ndim
1129 : : !arrays
1130 : : complex(dp),dimension(:,:),intent(in) :: rot
1131 : : complex(dp),dimension(:,:),intent(inout) :: mat
1132 : : !Local variables ------------------------------
1133 : : !scalars
1134 : : !arrays
1135 : 48 : complex(dp),allocatable :: res(:,:)
1136 : : !************************************************************************
1137 : :
1138 [ - + + - : 192 : ABI_MALLOC(res,(ndim,ndim))
- + + - +
- + - - +
- + ]
1139 [ + + + + ]: 3504 : res=czero
1140 : :
1141 : : ! <NO|Op|NO> = (U^t)* <KS|Op|KS> U
1142 [ + - + - : 31632 : res=matmul(conjg(transpose(rot)),mat)
+ - - + -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + +
+ + + + +
+ + + - -
- - - - ]
1143 [ + - + + : 56208 : mat=matmul(res,rot)
+ + + + +
+ + + + -
+ - ]
1144 : :
1145 [ - + ]: 48 : ABI_FREE(res)
1146 : :
1147 : 48 : end subroutine ks2no
1148 : : !!***
1149 : :
1150 : : !!****f* ABINIT/no2ks
1151 : : !! NAME
1152 : : !! no2ks
1153 : : !!
1154 : : !! FUNCTION
1155 : : !! Transform the matrix mat from NO to KS basis
1156 : : !!
1157 : : !! INPUTS
1158 : : !! dim=dimension of the matrices
1159 : : !! mat=array in the KS basis
1160 : : !! rot=unitary matrix containg the eigenvectors in NO basis
1161 : : !!
1162 : : !! OUTPUT
1163 : : !! mat=array in the KS basis
1164 : : !!
1165 : : !! SOURCE
1166 : :
1167 [ - + - + ]: 24 : subroutine no2ks(ndim,mat,rot)
1168 : : !Arguments ------------------------------------
1169 : : !scalars
1170 : : integer,intent(in) :: ndim
1171 : : !arrays
1172 : : complex(dp),dimension(:,:),intent(in) :: rot
1173 : : complex(dp),dimension(:,:),intent(inout) :: mat
1174 : : !Local variables ------------------------------
1175 : 24 : complex(dp),allocatable :: res(:,:)
1176 : : !************************************************************************
1177 : :
1178 [ - + + - : 96 : ABI_MALLOC(res,(ndim,ndim))
- + + - +
- + - - +
- + ]
1179 [ + + + + ]: 1752 : res=czero
1180 : :
1181 : : ! <KS|Op|KS> = U <NO|Op|NO> (U^t)*
1182 [ + - + - : 15816 : res=matmul(rot,mat)
+ - - + -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - + +
+ + + + +
+ + + ]
1183 [ + - + + : 28104 : mat=matmul(res,conjg(transpose(rot)))
+ + + + +
+ + + + -
+ - - - -
- - - ]
1184 : :
1185 [ - + ]: 24 : ABI_FREE(res)
1186 : :
1187 : 24 : end subroutine no2ks
1188 : : !!***
1189 : :
1190 : : !!****f* ABINIT/printrdm_k
1191 : : !! NAME
1192 : : !! printrdm_k
1193 : : !!
1194 : : !! FUNCTION
1195 : : !! Print the DM1 matrix
1196 : : !!
1197 : : !! INPUTS
1198 : : !! ib1=min band.
1199 : : !! ib2=max band.
1200 : : !! rdm_k=array containing the 1-RDM matrix
1201 : : !!
1202 : : !! OUTPUT
1203 : : !! Print the 1-RDM matrix
1204 : : !! SOURCE
1205 : :
1206 : : subroutine printrdm_k(ib1,ib2,rdm_k) ! Only used for debug on this file, do not use it with large arrays!
1207 : : !Arguments ------------------------------------
1208 : : !scalars
1209 : : integer,intent(in) :: ib1,ib2
1210 : : !arrays
1211 : : complex(dp),intent(in) :: rdm_k(:,:)
1212 : : !Local variables ------------------------------
1213 : : !scalars
1214 : : integer::ib1dm
1215 : : character(len=500) :: msg
1216 : : !arrays
1217 : : !************************************************************************
1218 : :
1219 : : do ib1dm=ib1,ib2
1220 : : write(msg,'(*(f12.5))') real(rdm_k(ib1dm,ib1:ib2))
1221 : : call wrtout(std_out, msg)
1222 : : end do
1223 : :
1224 : : end subroutine printrdm_k
1225 : : !!***
1226 : :
1227 : : end module m_gwrdm
1228 : : !!***
|