Branch data Line data Source code
1 : : !!****m* ABINIT/m_exc_build
2 : : !! NAME
3 : : !! m_exc_build
4 : : !!
5 : : !! FUNCTION
6 : : !! Build the BSE Hamiltonian in the e-h representation with MPI
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 1992-2009 EXC group (L.Reining, V.Olevano, F.Sottile, S.Albrecht, G.Onida)
10 : : !! Copyright (C) 2009-2026 ABINIT group (L.Reining, V.Olevano, F.Sottile, S.Albrecht, G.Onida, M.Giantomassi)
11 : : !! This file is distributed under the terms of the
12 : : !! GNU General Public License, see ~abinit/COPYING
13 : : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : : !!
15 : : !! SOURCE
16 : :
17 : : #if defined HAVE_CONFIG_H
18 : : #include "config.h"
19 : : #endif
20 : :
21 : : #include "abi_common.h"
22 : :
23 : : module m_exc_build
24 : :
25 : : use defs_basis
26 : : use m_abicore
27 : : use m_bs_defs
28 : : use m_bse_io
29 : : USE_MPI
30 : : use m_xmpi
31 : : use m_errors
32 : : use m_screen
33 : : use m_hdr
34 : :
35 : : use m_wfd, only : wfdgw_t, wave_t, WFD_STORED
36 : : use defs_datatypes, only : pseudopotential_type
37 : : use m_gwdefs, only : czero_gw, cone_gw, GW_TOLQ0
38 : : use m_time, only : cwtime, timab
39 : : use m_io_tools, only : get_unit, open_file
40 : : use m_hide_blas, only : xdotc, xgemv
41 : : use m_geometry, only : normv
42 : : use m_crystal, only : crystal_t
43 : : use m_gsphere, only : gsphere_t
44 : : use m_vcoul, only : vcoul_t
45 : : use m_bz_mesh, only : kmesh_t, findqg0
46 : : use m_pawpwij, only : pawpwff_t, pawpwij_t, pawpwij_init, pawpwij_free, paw_rho_tw_g
47 : : use m_pawang, only : pawang_type
48 : : use m_pawtab, only : pawtab_type
49 : : use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_free
50 : : use m_paw_sym, only : paw_symcprj_op
51 : : use m_oscillators, only : rho_tw_g, sym_rhotwgq0
52 : :
53 : : implicit none
54 : :
55 : : #if defined HAVE_MPI1
56 : : include 'mpif.h'
57 : : #endif
58 : :
59 : : private
60 : : !!***
61 : :
62 : : public :: exc_build_ham ! Calculate and write the excitonic Hamiltonian to file.
63 : : !!***
64 : :
65 : : contains
66 : : !!***
67 : :
68 : : !!****f* m_exc_build/exc_build_block
69 : : !! NAME
70 : : !! exc_build_block
71 : : !!
72 : : !! FUNCTION
73 : : !! Calculate and write the excitonic Hamiltonian on an external binary file (Fortran file open
74 : : !! in random mode) for subsequent treatment in the Bethe-Salpeter code.
75 : : !!
76 : : !! INPUTS
77 : : !! BSp<excparam>=The parameters for the Bethe-Salpeter calculation.
78 : : !! Cryst<crystal_t>=Info on the crystalline structure.
79 : : !! Kmesh<kmesh_t>=The list of k-points in the BZ, IBZ and symmetry tables.
80 : : !! Qmesh<kmesh_t>=The list of q-points for epsilon^{-1} and related symmetry tables.
81 : : !! ktabr(nfftot_osc,BSp%nkbz)=The FFT index of $(R^{-1}(r-\tau))$ where R is symmetry needed to obtains
82 : : !! the k-points from the irreducible image. Used to symmetrize u_Sk where S = \transpose R^{-1}
83 : : !! Gsph_x<gsphere_t>=Info on the G-sphere used to describe wavefunctions and W (the largest one is actually stored).
84 : : !! Gsph_c<gsphere_t>=Info on the G-sphere used to describe the correlation part.
85 : : !! Vcp<vcoul_t>=The Coulomb interaction in reciprocal space. A cutoff can be used
86 : : !! screen<screen_t>=Data type gathering info and data for W.
87 : : !! nfftot_osc=Total Number of FFT points used for the oscillator matrix elements.
88 : : !! ngfft_osc(18)=Info on the FFT algorithm used to calculate the oscillator matrix elements.
89 : : !! Psps<Pseudopotential_type>=Variables related to pseudopotentials
90 : : !! Pawtab(Psps%ntypat)<pawtab_type>=PAW tabulated starting data.
91 : : !! Pawang<pawang_type>=PAW angular mesh and related data.
92 : : !! Paw_pwff(Cryst%ntypat*Wfd%usepaw)<pawpwff_t>=Form factor used to calculate the onsite matrix
93 : : !! elements of a plane wave.
94 : : !! Wfd<wfdgw_t>=Handler for the wavefunctions.
95 : : !! prtvol=Verbosity level.
96 : : !! rhxtwg_q0
97 : : !! is_resonant
98 : : !! fname
99 : : !! comm=MPI communicator.
100 : : !!
101 : : !! OUTPUT
102 : : !! The excitonic Hamiltonian is saved on an external binary file (see below).
103 : : !!
104 : : !! NOTES
105 : : !! *) Version for K_V = K_C (q=0), thus KP_V = KP_C
106 : : !! *) No exchange limit: use DFT energies in case.
107 : : !! *) Symmetry of H(-k-k') = H*(k k') not used.
108 : : !! *) Coulomb term can be approximated as diagonal in G.
109 : : !! *) Valence bands treated from lomo on.
110 : : !! *) Symmetries of the sub-blocks are used to reduce the number of elements to calculate.
111 : : !!
112 : : !! ____________
113 : : !! |_(cv)__(vc)_|
114 : : !! H_exc = | R C |
115 : : !! | -C* -R* |
116 : : !!
117 : : !! where C is symmetric and R is Hermitian provided that the QP energies are real.
118 : : !!
119 : : !! For nsppol=1 ==> R = diag-W+2v; C = -W+2v
120 : : !! since the Hamiltonian can be diagonalized in the spin-singlet basis set thanks to
121 : : !! the fact that spin triplet does not contribute to the optical limit of epsilon.
122 : : !!
123 : : !! For nsppol=2 ==> R = diag-W+v; C = -W+v
124 : : !! Now the matrix elements depend on the spin of the transitions but only those
125 : : !! transitions in which the spin of the electron and of the hole are equal contribute
126 : : !! to the macroscopic dielectric function. Moreover only the exchange term can connect transitions of different spin.
127 : : !! When nsppol==2 the transitions are ordered using | (cv up) | (cv dwn) | (vc up) | (vc down) |
128 : : !!
129 : : !! The resonant block is given by:
130 : : !!
131 : : !! | (v'c' up) | (v'c' dwn) |
132 : : !! ----------------------------------- where v_{-+} = v_{+-}^H when the momentum of the photon is neglected.
133 : : !! | [diag-W+v]++ | v+- | (vc up) Note that v_{+-} is not Hermitian due to the presence of different spins.
134 : : !! R = ----------------------------------- Actually it reduces to a Hermitian matrix when the system is not spin polarized.
135 : : !! | v-+ | [diag-W+v]-- | (vc dwn) but in this case one should use nsppol=1.
136 : : !! ----------------------------------- As a consequence the entire matrix is calculated and stored on file.
137 : : !!
138 : : !! The coupling block is given by:
139 : : !!
140 : : !! | (c'v' up) | (c'v dwn) |
141 : : !! ----------------------------------- where v_{-+} = v_{+-}^t when the momentum of the photon is neglected.
142 : : !! | [-W+v]++ | v+- | (vc up) Also in this case the entire matrix v_{+-} has to be calculated
143 : : !! C = ----------------------------------- and stored on file.
144 : : !! | v-+ | [-W+v]-- | (vc dwn)
145 : : !! -----------------------------------
146 : : !!
147 : : !! SOURCE
148 : :
149 : 23 : subroutine exc_build_block(BSp,Cryst,Kmesh,Qmesh,ktabr,Gsph_x,Gsph_c,Vcp,Wfd,screen,Hdr_bse,&
150 : 23 : nfftot_osc,ngfft_osc,Psps,Pawtab,Pawang,Paw_pwff,rhxtwg_q0,is_resonant,fname)
151 : :
152 : : !Arguments ------------------------------------
153 : : !scalars
154 : : integer,intent(in) :: nfftot_osc
155 : : character(len=*),intent(in) :: fname
156 : : logical,intent(in) :: is_resonant
157 : : type(excparam),intent(in) :: BSp
158 : : type(screen_t),intent(inout) :: screen
159 : : type(kmesh_t),intent(in) :: Kmesh,Qmesh
160 : : type(crystal_t),intent(in) :: Cryst
161 : : type(vcoul_t),intent(in) :: Vcp
162 : : type(gsphere_t),intent(in) :: Gsph_x,Gsph_c
163 : : type(Pseudopotential_type),intent(in) :: Psps
164 : : type(Hdr_type),intent(inout) :: Hdr_bse
165 : : type(pawang_type),intent(in) :: Pawang
166 : : type(wfdgw_t),target,intent(inout) :: Wfd
167 : : !arrays
168 : : integer,intent(in) :: ngfft_osc(18)
169 : : integer,intent(in) :: ktabr(nfftot_osc,Kmesh%nbz)
170 : : complex(gwp),intent(in) :: rhxtwg_q0(BSp%npweps,BSp%lomo_min:BSp%humo_max,BSp%lomo_min:BSp%humo_max,Wfd%nkibz,Wfd%nsppol)
171 : : type(Pawtab_type),intent(in) :: Pawtab(Psps%ntypat*Wfd%usepaw)
172 : : type(pawpwff_t),intent(in) :: Paw_pwff(Psps%ntypat*Wfd%usepaw)
173 : :
174 : : !Local variables ------------------------------
175 : : !scalars
176 : : integer,parameter :: map2sphere=1,ndat1=1,master=0
177 : : integer(i8b) :: bsize_my_block
178 : : integer :: nspinor,nsppol,ISg,mpi_err,tmp_size,ngx
179 : : integer :: ik_bz,ikp_bz,col_glob,itpk_min,itpk_max
180 : : integer :: dim_rtwg,bsh_unt,ncol,dump_unt,npweps
181 : : #ifdef HAVE_MPI_IO
182 : : integer :: amode,mpi_fh,hmat_type,offset_err,old_type
183 : : integer(XMPI_OFFSET_KIND) :: ehdr_offset,my_offset
184 : : logical,parameter :: is_fortran_file=.TRUE.
185 : : #endif
186 : : integer :: neh1,neh2,ig,nblocks
187 : : integer :: ik_ibz,itim_k,ikp_ibz,itim_kp,isym_k,isym_kp
188 : : integer :: iq_bz,iq_ibz,isym_q,itim_q,iqbz0,rank
189 : : integer :: iv,ivp,ic,icp,jj,nrows,sender,my_ncols
190 : : integer :: use_padfft,prev_nrows,spin1,spin2,block
191 : : integer :: ierr,nproc,my_rank,mgfft_osc,fftalga_osc,comm
192 : : integer(i8b) :: tot_nels,prev_nels,prev_ncols,nels,ir,it,itp,ist,iend,my_hsize
193 : : real(dp) :: faq,kx_fact,cputime,walltime,gflops
194 : : complex(sp) :: http,ctemp
195 : : complex(dp) :: ph_mkpt,ph_mkt,ene_t,ene_tp
196 : : logical,parameter :: with_umklp=.FALSE.
197 : : logical :: use_mpiio,do_coulomb_term,do_exchange_term,w_is_diagonal,isirred
198 : : logical :: is_qeq0
199 : : character(len=500) :: msg
200 : : type(wave_t),pointer :: wave_ck, wave_ckp, wave_vk, wave_vkp
201 : : !arrays
202 : : integer :: bidx(2,4),g0(3),spin_ids(2,3)
203 : : integer(i8b) :: nels_block(3)
204 : : integer :: my_cols(2),my_rows(2),proc_end(2),proc_start(2)
205 : : integer :: my_extrema(2,2),sender_extrema(2,2),my_starts(2),my_ends(2)
206 : 23 : integer,allocatable :: igfftg0(:),ktabr_k(:),ktabr_kp(:),id_tab(:)
207 : 23 : integer,allocatable :: ncols_of(:)
208 : 23 : integer(i8b),allocatable :: t_start(:),t_stop(:),hsize_of(:)
209 : 23 : integer,allocatable :: col_start(:),col_stop(:)
210 : 23 : integer,allocatable :: gbound(:,:)
211 : : real(dp) :: kbz(3),kpbz(3),qbz(3),spinrot_k(4),spinrot_kp(4),kmkp(3),tsec(2)
212 : 23 : complex(dp),allocatable :: my_bsham(:),buffer(:),buffer_2d(:,:),my_kxssp(:,:),prev_col(:)
213 : : !DBYG
214 : 23 : complex(dp),allocatable :: acoeffs(:),bcoeffs(:),ccoeffs(:) ! Coeff of W = a/q^2 + b/q + c
215 : : integer :: a_unt, b_unt, c_unt
216 : : complex(dp) :: aatmp, bbtmp, cctmp
217 : 23 : complex(gwp),allocatable :: aa_vpv(:),aa_cpc(:),aa_ctccp(:)
218 : 23 : complex(gwp),allocatable :: bb_vpv1(:),bb_cpc1(:),bb_ctccp1(:)
219 : 23 : complex(gwp),allocatable :: bb_vpv2(:),bb_cpc2(:),bb_ctccp2(:)
220 : 23 : complex(gwp),allocatable :: cc_vpv(:),cc_cpc(:),cc_ctccp(:)
221 : 23 : complex(dp),allocatable :: abuffer(:),aprev_col(:)
222 : 23 : complex(dp),allocatable :: bbuffer(:),bprev_col(:)
223 : 23 : complex(dp),allocatable :: cbuffer(:),cprev_col(:)
224 : : character(len=fnlen) :: tmpfname
225 : : integer :: ii
226 : : !END DBYG
227 : 23 : complex(gwp),allocatable :: vc_sqrt_qbz(:), rhotwg1(:),rhotwg2(:),rhxtwg_vpv(:),rhxtwg_cpc(:),ctccp(:)
228 : 23 : complex(gwp),target,allocatable :: ur_ckp(:),ur_vkp(:),ur_vk(:),ur_ck(:)
229 : 23 : complex(gwp),contiguous, pointer :: ptur_ckp(:),ptur_vkp(:),ptur_vk(:),ptur_ck(:)
230 : 23 : type(pawcprj_type),target,allocatable :: Cp_tmp1(:,:),Cp_tmp2(:,:)
231 : 23 : type(pawcprj_type),target,allocatable :: Cp_tmp3(:,:),Cp_tmp4(:,:)
232 : 23 : type(pawcprj_type),allocatable :: Cp_ckp(:,:),Cp_vkp(:,:)
233 : 23 : type(pawcprj_type),allocatable :: Cp_vk(:,:),Cp_ck(:,:)
234 : 23 : type(pawcprj_type),pointer :: ptcp_ckp(:,:),ptcp_vkp(:,:),ptcp_vk(:,:),ptcp_ck(:,:)
235 : 23 : type(pawpwij_t),allocatable :: Pwij_q(:)
236 : : #ifdef HAVE_MPI_IO
237 : : integer(XMPI_OFFSET_KIND) :: tmp_off,my_offpad
238 : 23 : integer(XMPI_OFFSET_KIND),allocatable :: bsize_frecord(:),offset_of_block(:)
239 : : #endif
240 : : #ifdef DEV_MG_DEBUG_MODE
241 : : integer,allocatable :: ttp_check(:,:)
242 : : #endif
243 : : !************************************************************************
244 : :
245 : 23 : call timab(680,1,tsec)
246 : 23 : call timab(681,1,tsec)
247 : :
248 : : DBG_ENTER("COLL")
249 : :
250 [ - + ]: 23 : ABI_CHECK(Wfd%nspinor==1,"nspinor==2 not coded")
251 [ + + - + ]: 92 : ABI_CHECK(nfftot_osc==PRODUCT(ngfft_osc(1:3)),"mismatch in FFT size")
252 : :
253 [ + + ]: 23 : if (Wfd%nsppol==2) then
254 : 1 : ABI_WARNING("nsppol==2 is still under testing")
255 : : end if
256 : : ! MPI variables.
257 : 23 : comm = Wfd%comm
258 : 23 : nproc = Wfd%nproc
259 : 23 : my_rank = Wfd%my_rank
260 : :
261 : : ! Basic constants.
262 : 23 : nspinor = Wfd%nspinor
263 : 23 : nsppol = Wfd%nsppol
264 : 23 : dim_rtwg=1; faq = one/(Cryst%ucvol*Kmesh%nbz)
265 : 23 : npweps = Bsp%npweps
266 : :
267 : : ! Prepare the FFT tables to have u(r) on the ngfft_osc mesh.
268 [ + + ]: 92 : mgfft_osc = MAXVAL(ngfft_osc(1:3))
269 : 23 : fftalga_osc = ngfft_osc(7)/100
270 [ + + + - : 92 : if ( ANY(ngfft_osc(1:3) /= Wfd%ngfft(1:3)) ) call wfd%change_ngfft(Cryst,Psps,ngfft_osc)
- + ]
271 : :
272 [ - + + - : 69 : ABI_MALLOC(igfftg0,(npweps))
+ - + - -
+ - + ]
273 [ - + + - : 69 : ABI_MALLOC(ktabr_k,(nfftot_osc))
+ - + - -
+ - + ]
274 [ - + + - : 46 : ABI_MALLOC(ktabr_kp,(nfftot_osc))
- + - + ]
275 [ - + + - : 46 : ABI_MALLOC(id_tab,(nfftot_osc))
- + - + ]
276 [ - + + + : 482671 : id_tab = (/(ic, ic=1,nfftot_osc)/)
+ - + + +
- - + - -
+ + ]
277 : :
278 : : ! Workspace arrays for wavefunctions and oscillator matrix elements.
279 [ - + + - : 69 : ABI_MALLOC(rhxtwg_vpv,(npweps))
+ - + - -
+ - + ]
280 [ - + + - : 46 : ABI_MALLOC(rhxtwg_cpc,(npweps))
- + - + ]
281 : :
282 [ + + ]: 23 : if (BSp%prep_interp) then
283 : 1 : call wrtout(std_out,"Preparing BSE interpolation")
284 [ - + + - : 2 : ABI_MALLOC(aa_vpv,(npweps))
- + - + ]
285 [ - + + - : 2 : ABI_MALLOC(bb_vpv1,(npweps))
- + - + ]
286 [ - + + - : 2 : ABI_MALLOC(bb_vpv2,(npweps))
- + - + ]
287 [ - + + - : 2 : ABI_MALLOC(cc_vpv,(npweps))
- + - + ]
288 [ - + + - : 2 : ABI_MALLOC(aa_cpc,(npweps))
- + - + ]
289 [ - + + - : 2 : ABI_MALLOC(bb_cpc1,(npweps))
- + - + ]
290 [ - + + - : 2 : ABI_MALLOC(bb_cpc2,(npweps))
- + - + ]
291 [ - + + - : 2 : ABI_MALLOC(cc_cpc,(npweps))
- + - + ]
292 : : end if
293 : :
294 [ - + + - : 69 : ABI_MALLOC(ur_ckp,(nspinor*nfftot_osc))
+ - + - -
+ - + ]
295 [ - + + - : 46 : ABI_MALLOC(ur_vkp,(nspinor*nfftot_osc))
- + - + ]
296 [ - + + - : 46 : ABI_MALLOC(ur_ck ,(nspinor*nfftot_osc))
- + - + ]
297 [ - + + - : 46 : ABI_MALLOC(ur_vk ,(nspinor*nfftot_osc))
- + - + ]
298 : :
299 [ + + ]: 23 : if (Wfd%usepaw==1) then
300 [ - + + - : 14 : ABI_MALLOC(Cp_vk,(Wfd%natom,nspinor))
- + + - +
- + - - +
- + + + +
+ ]
301 : 2 : call pawcprj_alloc(Cp_vk,0,Wfd%nlmn_atm)
302 [ - + + - : 14 : ABI_MALLOC(Cp_ck,(Wfd%natom,nspinor))
- + + - +
- + - - +
- + + + +
+ ]
303 : 2 : call pawcprj_alloc(Cp_ck,0,Wfd%nlmn_atm)
304 [ - + + - : 14 : ABI_MALLOC(Cp_ckp,(Wfd%natom,nspinor))
- + + - +
- + - - +
- + + + +
+ ]
305 : 2 : call pawcprj_alloc(Cp_ckp,0,Wfd%nlmn_atm)
306 [ - + + - : 14 : ABI_MALLOC(Cp_vkp,(Wfd%natom,nspinor))
- + + - +
- + - - +
- + + + +
+ ]
307 : 2 : call pawcprj_alloc(Cp_vkp,0,Wfd%nlmn_atm)
308 : :
309 [ - + + - : 14 : ABI_MALLOC(Cp_tmp1,(Wfd%natom,nspinor))
- + + - +
- + - - +
- + + + +
+ ]
310 : 2 : call pawcprj_alloc(Cp_tmp1,0,Wfd%nlmn_atm)
311 [ - + + - : 14 : ABI_MALLOC(Cp_tmp2,(Wfd%natom,nspinor))
- + + - +
- + - - +
- + + + +
+ ]
312 : 2 : call pawcprj_alloc(Cp_tmp2,0,Wfd%nlmn_atm)
313 [ - + + - : 14 : ABI_MALLOC(Cp_tmp3,(Wfd%natom,nspinor))
- + + - +
- + - - +
- + + + +
+ ]
314 : 2 : call pawcprj_alloc(Cp_tmp3,0,Wfd%nlmn_atm)
315 [ - + + - : 14 : ABI_MALLOC(Cp_tmp4,(Wfd%natom,nspinor))
- + + - +
- + - - +
- + + + +
+ ]
316 : 2 : call pawcprj_alloc(Cp_tmp4,0,Wfd%nlmn_atm)
317 : : end if
318 : : !
319 : : ! Identify the index of q==0
320 : 23 : iqbz0=0
321 [ + + ]: 1079 : do iq_bz=1,Qmesh%nbz
322 [ + + + + : 1446 : if (ALL(ABS(Qmesh%bz(:,iq_bz))<tol3)) iqbz0 = iq_bz
+ + ]
323 : : end do
324 [ - + ]: 23 : ABI_CHECK(iqbz0/=0,"q=0 not found")
325 : : !
326 : : ! Treat the spin polarization.
327 [ + + ]: 69 : spin_ids(:,1) = (/1,1/)
328 [ + + ]: 69 : spin_ids(:,2) = (/2,2/)
329 [ + + ]: 69 : spin_ids(:,3) = (/1,2/)
330 : :
331 : 23 : nblocks=1
332 : 23 : kx_fact=two
333 : 23 : nels_block(:)=0
334 : 23 : nels_block(1)=BSp%nreh(1)*(BSp%nreh(1)+1_i8b)/2
335 : 23 : tot_nels=nels_block(1)
336 : :
337 [ + + ]: 23 : if (nsppol==2) then
338 : 1 : nblocks=3
339 : 1 : kx_fact=one
340 : : nels_block(1) = BSp%nreh(1)*(BSp%nreh(1)+1_i8b)/2 ! Only the upper triangle for block 1 and 2
341 : 1 : nels_block(2) = BSp%nreh(2)*(BSp%nreh(2)+1_i8b)/2
342 : 1 : nels_block(3) = BSp%nreh(1)*BSp%nreh(2)*1_i8b ! Note: Block 3 does not have symmetries.
343 [ + + ]: 4 : tot_nels= SUM(nels_block)
344 : : end if
345 : : !
346 : : ! Distribute the calculation of the matrix elements among the nodes.
347 : : ! * tstart and t_stop give the initial and final transition index treated by each node.
348 : : ! * my_hsize is the number of transitions treated by this processor
349 : : ! * my_cols(1:2) gives the initial and final column treated by this node.
350 : : !
351 : : use_mpiio=.FALSE.
352 : : #ifdef HAVE_MPI_IO
353 : : use_mpiio = (nproc>1)
354 : : #endif
355 : 23 : use_mpiio=.FALSE.
356 : : !use_mpiio=.TRUE.
357 : :
358 [ + + ]: 23 : if (is_resonant) then
359 : : if (use_mpiio) then
360 : : write(msg,'(2a,f6.2,a)')&
361 : : ". Writing resonant excitonic Hamiltonian on file "//TRIM(fname)," via MPI-IO; file size= ",two*tot_nels*dp*b2Gb," [Gb]."
362 : : else
363 : : write(msg,'(2a,f6.2,a)')&
364 : 22 : ". Writing resonant excitonic Hamiltonian on file "//TRIM(fname),"; file size= ",two*dp*tot_nels*b2Gb," [Gb]."
365 : : end if
366 : : else
367 : : if (use_mpiio) then
368 : : write(msg,'(2a,f6.2,a)')&
369 : : ". Writing coupling excitonic Hamiltonian on file "//TRIM(fname)," via MPI-IO; file size= ",tot_nels*2*dp*b2Gb," [Gb]."
370 : : else
371 : : write(msg,'(2a,f6.2,a)')&
372 : 1 : ". Writing coupling excitonic Hamiltonian on file "//TRIM(fname),"; file size= ",two*dp*tot_nels*b2Gb," [Gb]."
373 : : end if
374 : : end if
375 [ + + ]: 69 : call wrtout([std_out, ab_out], msg, do_flush=.True.)
376 : :
377 : : ! Master writes the BSE header with Fortran IO.
378 [ + + ]: 23 : if (my_rank==master) then
379 [ - + ]: 19 : if (open_file(fname,msg,newunit=bsh_unt,form="unformatted",action="write") /= 0) then
380 : 0 : ABI_ERROR(msg)
381 : : end if
382 : 19 : call exc_write_bshdr(bsh_unt,Bsp,Hdr_bse)
383 : : ! To force the writing (needed for MPI-IO).
384 : 19 : close(bsh_unt)
385 : :
386 : 19 : if (.not.use_mpiio) then ! Reopen the file and skip the header.
387 [ - + ]: 19 : if (open_file(fname,msg,newunit=bsh_unt,form="unformatted",action="readwrite") /= 0) then
388 : 0 : ABI_ERROR(msg)
389 : : end if
390 : 19 : call exc_skip_bshdr(bsh_unt,ierr)
391 : : end if
392 : :
393 [ + + ]: 19 : if (BSp%prep_interp) then
394 [ - + ]: 1 : tmpfname = fname
395 : 1 : ii = LEN_TRIM(fname)
396 : 1 : tmpfname(ii-2:ii+1) = 'ABSR'
397 [ - + ]: 1 : if (open_file(tmpfname,msg,newunit=a_unt,form='unformatted',action="write") /= 0) then
398 : 0 : ABI_ERROR(msg)
399 : : end if
400 : 1 : tmpfname(ii-2:ii+1) = 'BBSR'
401 [ - + ]: 1 : if (open_file(tmpfname,msg,newunit=b_unt,form='unformatted',action="write") /= 0) then
402 : 0 : ABI_ERROR(msg)
403 : : end if
404 : 1 : tmpfname(ii-2:ii+1) = 'CBSR'
405 [ - + ]: 1 : if (open_file(tmpfname,msg,newunit=c_unt,form='unformatted',action="write") /= 0) then
406 : 0 : ABI_ERROR(msg)
407 : : end if
408 : 1 : call exc_write_bshdr(a_unt,Bsp,Hdr_bse)
409 : 1 : call exc_write_bshdr(b_unt,Bsp,Hdr_bse)
410 : 1 : call exc_write_bshdr(c_unt,Bsp,Hdr_bse)
411 : 1 : close(a_unt)
412 : 1 : close(b_unt)
413 : 1 : close(c_unt)
414 : 3 : if (.not.use_mpiio) then ! Reopen the file and skip the header.
415 : 1 : tmpfname(ii-2:ii+1) = 'ABSR'
416 [ - + ]: 1 : if (open_file(tmpfname,msg,newunit=a_unt,form='unformatted',action="readwrite") /= 0) then
417 : 0 : ABI_ERROR(msg)
418 : : end if
419 : 1 : call exc_skip_bshdr(a_unt,ierr)
420 : 1 : tmpfname(ii-2:ii+1) = 'BBSR'
421 [ - + ]: 1 : if (open_file(tmpfname,msg,newunit=b_unt,form='unformatted',action="readwrite") /= 0) then
422 : 0 : ABI_ERROR(msg)
423 : : end if
424 : 1 : call exc_skip_bshdr(b_unt,ierr)
425 : 1 : tmpfname(ii-2:ii+1) = 'CBSR'
426 [ - + ]: 1 : if (open_file(tmpfname,msg,newunit=c_unt,form='unformatted',action="readwrite") /= 0) then
427 : 0 : ABI_ERROR(msg)
428 : : end if
429 : 1 : call exc_skip_bshdr(c_unt,ierr)
430 : : end if
431 : : end if
432 : : end if
433 : :
434 : 23 : call xmpi_barrier(comm)
435 : :
436 : : if (use_mpiio) then
437 : : #ifdef HAVE_MPI_IO
438 : : ! Open the file with MPI-IO
439 : : amode = MPI_MODE_RDWR
440 : : !amode = MPI_MODE_CREATE + MPI_MODE_RDWR,
441 : :
442 : : call MPI_FILE_OPEN(comm, fname, amode, MPI_INFO_NULL, mpi_fh, mpi_err)
443 : : ABI_CHECK_MPI(mpi_err,"opening: "//TRIM(fname))
444 : :
445 : : ! Skip the header.
446 : : call exc_skip_bshdr_mpio(mpi_fh,xmpio_collective,ehdr_offset)
447 : :
448 : : ! Precompute the offset of the each block including the Fortran markers.
449 : : ABI_MALLOC(offset_of_block,(nblocks))
450 : : offset_of_block(1) = ehdr_offset
451 : : do block=2,nblocks
452 : : tmp_off = offset_of_block(block-1) + nels_block(block-1)*xmpi_bsize_dpc
453 : : tmp_off = tmp_off + Bsp%nreh(block-1)*2*xmpio_bsize_frm ! markers.
454 : : offset_of_block(block) = tmp_off
455 : : end do
456 : : #endif
457 : : end if
458 : :
459 : 23 : call timab(681,2,tsec)
460 : :
461 [ + + ]: 47 : do block=1,nsppol
462 : : !
463 : : ! Indices used to loop over bands.
464 : : ! bidx contains the starting and final indices used to loop over bands.
465 : : !
466 : : ! (b3,b4)
467 : : ! |... ...|
468 : : ! (b1,b2) |... ...|
469 : : !
470 : : ! Resonant matrix is given by
471 : : ! (v',c')
472 : : ! |... ...|
473 : : ! (v,c) |... ...|
474 : : !
475 : : ! Coupling matrix is given by
476 : : ! (c',v')
477 : : ! |... ...|
478 : : ! (v,c) |... ...|
479 : :
480 [ + + ]: 24 : if (is_resonant) then
481 [ + + ]: 69 : bidx(:,1) = [BSp%lomo_spin(block),BSp%homo_spin(block)] ! range for b1
482 [ + + ]: 69 : bidx(:,2) = [BSp%lumo_spin(block),BSp%humo_spin(block)] ! range for b2
483 [ + + ]: 69 : bidx(:,3) = [BSp%lomo_spin(block),BSp%homo_spin(block)] ! range for b3
484 [ + + ]: 69 : bidx(:,4) = [BSp%lumo_spin(block),BSp%humo_spin(block)] ! range for b4
485 : : else
486 [ + + ]: 3 : bidx(:,1) = [BSp%lomo_spin(block),BSp%homo_spin(block)] ! range for b1
487 [ + + ]: 3 : bidx(:,2) = [BSp%lumo_spin(block),BSp%humo_spin(block)] ! range for b2
488 [ + + ]: 3 : bidx(:,3) = [BSp%lumo_spin(block),BSp%humo_spin(block)] ! range for b3
489 [ + + ]: 3 : bidx(:,4) = [BSp%lomo_spin(block),BSp%homo_spin(block)] ! range for b4
490 : : end if
491 : :
492 : 24 : spin1 = spin_ids(1,block)
493 : 24 : spin2 = spin_ids(2,block)
494 : :
495 [ + - - + ]: 24 : do_coulomb_term = (Bsp%use_coulomb_term .and. (spin1==spin2))
496 : 24 : do_exchange_term = (Bsp%exchange_term>0)
497 : 24 : w_is_diagonal = BSp%use_diagonal_Wgg
498 : : !
499 : : ! Distribution of the matrix elements among the nodes.
500 : : ! Note that rank0 will get the first transitions.
501 : 24 : nels=nels_block(block)
502 [ - + + - : 72 : ABI_MALLOC(t_start,(0:nproc-1))
+ - + - -
+ - + ]
503 [ - + + - : 48 : ABI_MALLOC(t_stop,(0:nproc-1))
- + - + ]
504 : 24 : call xmpi_split_work2_i8b(nels,nproc,t_start,t_stop)
505 : :
506 [ - + + - : 48 : ABI_MALLOC(hsize_of,(0:nproc-1))
- + - + ]
507 [ + + ]: 62 : hsize_of=0
508 [ + + ]: 62 : do rank=0,nproc-1
509 [ + - ]: 62 : if (t_stop(rank)>=t_start(rank)) hsize_of(rank) = t_stop(rank)-t_start(rank)+1
510 : : !write(std_out,*)"nels",nels,hsize_of(rank)
511 : : end do
512 : :
513 : 24 : my_hsize = hsize_of(my_rank)
514 [ - + ]: 24 : if (my_hsize<=0) then
515 : 0 : write(msg,'(a,i0)')"Wrong number of transitions: my_hsize= ",my_hsize
516 : 0 : ABI_ERROR(msg)
517 : : end if
518 [ - + ]: 24 : if (my_hsize /= INT(my_hsize,KIND=i4b)) then
519 : 0 : write(msg,'(a,i0)')"Size of local block too large for a default integer, Increase the number of CPUs: my_hsize= ",my_hsize
520 : 0 : ABI_ERROR(msg)
521 : : end if
522 : :
523 : 24 : my_cols=0
524 [ + + ]: 9272 : do itp=1,Bsp%nreh(block)
525 [ + + ]: 2182216 : do it=1,itp
526 : 2172944 : ir = it + itp*(itp-1_i8b)/2
527 [ + + ]: 2172944 : if (ir==t_start(my_rank)) then
528 : 24 : my_rows(1) = it
529 : 24 : my_cols(1) = itp
530 : : end if
531 [ + + ]: 2182192 : if (ir==t_stop(my_rank)) then
532 : 24 : my_rows(2) = it
533 : 24 : my_cols(2) = itp
534 : : end if
535 : : end do
536 : : end do
537 : :
538 [ + + ]: 72 : my_starts = [my_rows(1),my_cols(1)]
539 : 24 : my_ends = [my_rows(2),my_cols(2)]
540 : : !
541 : : ! Announce the treatment of submatrix treated by each node.
542 : 24 : bsize_my_block = 2*dp*my_hsize
543 : 24 : write(msg,'(4(a,i0))')' Treating ',my_hsize,'/',nels,' matrix elements, from column ',my_cols(1),' up to column ',my_cols(2)
544 : 24 : call wrtout(std_out, msg)
545 : :
546 [ + + ]: 24 : if (is_resonant) then
547 : 23 : write(msg,'(a,f8.1,a)')' Calculating resonant blocks. Memory required: ',bsize_my_block*b2Mb,' [Mb] <<< MEM'
548 : : else
549 : 1 : write(msg,'(a,f8.1,a)')' Calculating coupling blocks. Memory required: ',bsize_my_block*b2Mb,' [Mb] <<< MEM'
550 : : end if
551 : 24 : call wrtout(std_out, msg)
552 : :
553 : : ! Allocate big (scalable) buffer to store the BS matrix on this node.
554 [ - + + - : 72 : ABI_MALLOC_OR_DIE(my_bsham,(t_start(my_rank):t_stop(my_rank)), ierr)
+ - + - +
- + - - +
+ - - + ]
555 : :
556 [ + + ]: 24 : if (BSp%prep_interp) then
557 : : ! Allocate big (scalable) buffers to store a,b,c coefficients
558 [ - + + - : 2 : ABI_MALLOC_OR_DIE(acoeffs,(t_start (my_rank):t_stop(my_rank)), ierr)
+ - + - -
+ + - -
+ ]
559 [ - + + - : 2 : ABI_MALLOC_OR_DIE(bcoeffs,(t_start(my_rank):t_stop(my_rank)), ierr)
+ - + - -
+ + - -
+ ]
560 [ - + + - : 2 : ABI_MALLOC_OR_DIE(ccoeffs,(t_start(my_rank):t_stop(my_rank)), ierr)
+ - + - -
+ + - -
+ ]
561 : : end if
562 : :
563 [ + - ]: 24 : if (do_coulomb_term) then ! Construct Coulomb term.
564 : :
565 : 24 : call timab(682,1,tsec) ! exc_build_ham(Coulomb)
566 : :
567 : 24 : write(msg,'(a,2i2,a)')" Calculating direct Coulomb term for (spin1,spin2) ",spin1,spin2," using full W_{GG'} ..."
568 [ + + ]: 24 : if (w_is_diagonal) then
569 : : write(msg,'(a,2i2,a)')&
570 : 2 : " Calculating direct Coulomb term for (spin1, spin2) ",spin1,spin2," using diagonal approximation for W_{GG'} ..."
571 : : end if
572 : 24 : call wrtout(std_out, msg)
573 : :
574 [ - + + - : 72 : ABI_MALLOC(ctccp,(npweps))
+ - + - -
+ - + ]
575 : :
576 [ + + ]: 24 : if (BSp%prep_interp) then
577 [ - + + - : 2 : ABI_MALLOC(aa_ctccp,(npweps))
- + - + -
+ ]
578 [ - + + - : 2 : ABI_MALLOC(bb_ctccp1,(npweps))
- + - + -
+ ]
579 [ - + + - : 2 : ABI_MALLOC(bb_ctccp2,(npweps))
- + - + -
+ ]
580 [ - + + - : 2 : ABI_MALLOC(cc_ctccp,(npweps))
- + - + -
+ ]
581 : : end if
582 : :
583 [ - + + - : 48 : ABI_MALLOC(vc_sqrt_qbz,(npweps))
- + - + ]
584 : :
585 : : #ifdef DEV_MG_DEBUG_MODE
586 : : ABI_MALLOC(ttp_check,(BSp%nreh(block),BSp%nreh(block)))
587 : : ttp_check=0
588 : : #endif
589 : :
590 [ + + ]: 1112 : do ikp_bz=1,BSp%nkbz ! Loop over kp
591 : : ! NOTE: this way of looping is good for bulk but it's not optimal in the
592 : : ! case of systems sampled only at Gamma e.g. isolated systems in which
593 : : ! one should take advantage of Hermiticity by looping over c-v !!!!
594 : :
595 : : ! Check whether (vp,cp,ikp_bz,spin2) belongs to the set of columns treated by me for some vp,cp
596 : : ! Be careful since vcks2t contains zeros corresponding to transitions that should be skipped.
597 [ + + + + : 13456 : itpk_min = MINVAL(Bsp%vcks2t(:,:,ikp_bz,spin2), MASK=(Bsp%vcks2t(:,:,ikp_bz,spin2)>0) )
+ - ]
598 [ + + + + ]: 13456 : itpk_max = MAXVAL(Bsp%vcks2t(:,:,ikp_bz,spin2))
599 [ + + + + ]: 1088 : if (my_cols(2)<itpk_min .or. my_cols(1)>itpk_max) CYCLE
600 : :
601 : 836 : write(msg,'(3(a,i0))')" status: ",ikp_bz,"/",BSp%nkbz," done by node ",my_rank
602 : 836 : call wrtout(std_out, msg, do_flush=.True.)
603 : :
604 : : ! * Get ikp_ibz, non-symmorphic phase, ph_mkpt, and symmetries from ikp_bz.
605 : 836 : call kmesh%get_BZ_item(ikp_bz,kpbz,ikp_ibz,isym_kp,itim_kp,ph_mkpt,isirred=isirred)
606 : : !ABI_CHECK(isirred,"not irred!")
607 : : !ABI_CHECK(ph_mkpt == cone, "Wrong phase!")
608 : :
609 [ + + ]: 6059836 : ktabr_kp(:) = ktabr(:,ikp_bz)
610 [ + + ]: 4180 : spinrot_kp(:)=Cryst%spinrot(:,isym_kp)
611 : : !ABI_CHECK(ALL(ktabr_kp == id_tab), "wrong tab")
612 : :
613 [ + + ]: 23600 : do ik_bz=1,ikp_bz ! Loop over k
614 : : !
615 : : ! * Get ik_ibz, non-symmorphic phase, ph_mkt, and symmetries from ik_bz
616 : 22740 : call kmesh%get_BZ_item(ik_bz,kbz,ik_ibz,isym_k,itim_k,ph_mkt,isirred=isirred)
617 : : !ABI_CHECK(isirred,"not irred!")
618 : : !ABI_CHECK(ph_mkt == cone, "Wrong phase!")
619 : :
620 [ + + ]: 172008240 : ktabr_k(:) = ktabr(:,ik_bz)
621 [ + + ]: 113700 : spinrot_k(:)=Cryst%spinrot(:,isym_k)
622 : : !ABI_CHECK(ALL(ktabr_k == id_tab), "wrong tab")
623 : : !if(itim_k==2) CYCLE ! time-reversal or not
624 : : !
625 : : ! * Find q = K-KP-G0 in the full BZ.
626 [ + + ]: 90960 : kmkp = Kmesh%bz(:,ik_bz) - Kmesh%bz(:,ikp_bz)
627 : 22740 : call findqg0(iq_bz,g0,kmkp,Qmesh%nbz,Qmesh%bz,BSp%mG0)
628 : :
629 : : ! Evaluate the tables needed for the padded FFT performed in rhotwg. Note that we have
630 : : ! to pass G-G0 to sphereboundary instead of G as we need FFT results on the shifted G-sphere,
631 : : ! If Gamma is not inside G-G0 one has to disable FFT padding as sphereboundary will give wrong tables.
632 : : ! * Get the G-G0 shift for the FFT of the oscillators.
633 : : !
634 [ + - - + : 90960 : ABI_MALLOC(gbound,(2*mgfft_osc+8,2))
+ - + - +
- + - - +
- + - + ]
635 : 22740 : call Gsph_c%fft_tabs(g0,mgfft_osc,ngfft_osc,use_padfft,gbound,igfftg0)
636 [ - + ]: 22740 : if ( ANY(fftalga_osc == (/2,4/)) ) use_padfft=0 ! Pad-FFT is not coded in rho_tw_g
637 [ + + ]: 22740 : if (use_padfft==0) then
638 [ - + ]: 28 : ABI_FREE(gbound)
639 [ - + + - : 56 : ABI_MALLOC(gbound,(2*mgfft_osc+8,2*use_padfft))
- + - + ]
640 : : end if
641 : : !
642 : : ! Get iq_ibz, and symmetries from iq_bz
643 : 22740 : call qmesh%get_BZ_item(iq_bz,qbz,iq_ibz,isym_q,itim_q)
644 : 22740 : is_qeq0 = (normv(qbz,Cryst%gmet,'G')<GW_TOLQ0)
645 : :
646 : : ! Symmetrize em1(omega=0)
647 : 22740 : call screen%rotate_iqbz(iq_bz, Cryst, Gsph_c, Qmesh, Vcp)
648 : :
649 : : ! Set up table of |q_BZ+G|
650 [ + + ]: 22740 : if (iq_ibz==1) then
651 [ + + ]: 40208 : do ig=1,npweps
652 : 39372 : isg = Gsph_c%rottb(ig,itim_q,isym_q)
653 : 40208 : vc_sqrt_qbz(isg)=Vcp%vcqlwl_sqrt(ig,1)
654 : : end do
655 : : else
656 [ + + ]: 1014192 : do ig=1,npweps
657 : 992288 : isg = Gsph_c%rottb(ig,itim_q,isym_q)
658 : 1014192 : vc_sqrt_qbz(isg) = Vcp%vc_sqrt(ig,iq_ibz)
659 : : end do
660 : : end if
661 : :
662 : : ! === Evaluate oscillator matrix elements ===
663 : : ! * $ <phj/r|e^{-i(q+G)}|phi/r> - <tphj/r|e^{-i(q+G)}|tphi/r> $ in packed form.
664 [ + + + + ]: 22740 : if (Wfd%usepaw==1.and.ik_bz/=ikp_bz) then
665 [ - + + - : 4108 : ABI_MALLOC(Pwij_q,(Cryst%ntypat))
+ - + - -
+ - + - +
+ + ]
666 : 1020 : call pawpwij_init(Pwij_q,npweps,Qmesh%bz(:,iq_bz),Gsph_c%gvec,Cryst%rprimd,Psps,Pawtab,Paw_pwff)
667 : : end if
668 : :
669 : : ! =======================================
670 : : ! === Loop over the four band indices ===
671 : : ! =======================================
672 [ + + ]: 90388 : do ic=bidx(1,2),bidx(2,2) !do ic=BSp%lumo,BSp%nbnds
673 : :
674 [ - + ]: 67648 : ABI_CHECK(wfd%get_wave_ptr(ic, ik_ibz, spin1, wave_ck, msg) == 0, msg)
675 [ + + ]: 67648 : if (wave_ck%has_ur == WFD_STORED) then
676 : 67420 : ptur_ck => wave_ck%ur
677 : : else
678 : 228 : call wfd%get_ur(ic,ik_ibz,spin1,ur_ck)
679 : 228 : ptur_ck => ur_ck
680 : : end if
681 : : !
682 : : ! Get cprj for this (c,kbz,s1) in the BZ.
683 : : ! phase due to the umklapp G0 in k-q is already included.
684 [ + + ]: 67648 : if (Wfd%usepaw==1) then
685 [ + - ]: 4296 : if (wave_ck%has_cprj == WFD_STORED) then
686 : 4296 : ptcp_ck => wave_ck%cprj
687 : : else
688 : 0 : call wfd%get_cprj(ic,ik_ibz,spin1,Cryst,Cp_tmp1,sorted=.FALSE.)
689 : 0 : ptcp_ck => Cp_tmp1
690 : : end if
691 [ - + ]: 4296 : call paw_symcprj_op(ik_bz,nspinor,1,Cryst,Kmesh,Pawtab,Pawang,ptcp_ck,Cp_ck)
692 : : end if
693 : :
694 [ + + ]: 306004 : do icp=bidx(1,4),bidx(2,4) !do icp=BSp%lumo,BSp%nbnds
695 : : ! Calculate matrix-elements rhxtwg_cpc
696 : : !
697 [ + + ]: 215616 : if (ik_bz==ikp_bz) then ! Already in memory.
698 : 8688 : rhxtwg_cpc(:) = sym_rhotwgq0(itim_k,isym_k,dim_rtwg,npweps,rhxtwg_q0(:,icp,ic,ik_ibz,spin1),Gsph_c)
699 : :
700 : : else
701 : : ! Calculate matrix element from wfr.
702 : : ! TODO: change the order of the loops.
703 : :
704 [ - + ]: 206928 : ABI_CHECK(wfd%get_wave_ptr(icp, ikp_ibz, spin2, wave_ckp, msg) == 0, msg)
705 [ + + ]: 206928 : if (wave_ckp%has_ur == WFD_STORED) then
706 : 206724 : ptur_ckp => wave_ckp%ur
707 : : else
708 : 204 : call wfd%get_ur(icp,ikp_ibz,spin2,ur_ckp)
709 : 204 : ptur_ckp => ur_ckp
710 : : end if
711 : :
712 : : ! Load cprj for this (c,k,s2) in the BZ.
713 : : ! Do not care about umklapp G0 in k-q as the phase is already included.
714 [ + + ]: 206928 : if (Wfd%usepaw==1) then
715 [ + - ]: 15984 : if (wave_ckp%has_cprj == WFD_STORED) then
716 : 15984 : ptcp_ckp => wave_ckp%cprj
717 : : else
718 : 0 : call wfd%get_cprj(icp,ikp_ibz,spin2,Cryst,Cp_tmp2,sorted=.FALSE.)
719 : 0 : ptcp_ckp => Cp_tmp2
720 : : end if
721 [ - + ]: 15984 : call paw_symcprj_op(ikp_bz,nspinor,1,Cryst,Kmesh,Pawtab,Pawang,ptcp_ckp,Cp_ckp)
722 : : end if
723 : :
724 : : call rho_tw_g(nspinor,npweps,nfftot_osc,ndat1,ngfft_osc,map2sphere,use_padfft,igfftg0,gbound,&
725 : : ptur_ckp,itim_kp,ktabr_kp,ph_mkpt,spinrot_kp,&
726 : : ptur_ck ,itim_k ,ktabr_k ,ph_mkt ,spinrot_k ,&
727 : 206928 : dim_rtwg,rhxtwg_cpc)
728 : :
729 [ + + ]: 206928 : if (Wfd%usepaw==1) then ! Add PAW onsite contribution.
730 : 15984 : call paw_rho_tw_g(cryst,Pwij_q,npweps,dim_rtwg,nspinor,Gsph_c%gvec, Cp_ckp,Cp_ck,rhxtwg_cpc)
731 : : end if
732 : : end if
733 : :
734 [ + + ]: 215616 : if (BSp%prep_interp) then
735 [ + - - + : 30528 : aa_cpc = rhxtwg_cpc
- - + + ]
736 [ + + ]: 29376 : aa_cpc(2:) = czero
737 [ + - - + : 30528 : bb_cpc1 = vc_sqrt_qbz*rhxtwg_cpc
- - + + ]
738 : 576 : bb_cpc1(1) = czero
739 [ + - - + : 30528 : bb_cpc2 = rhxtwg_cpc
- - + + ]
740 [ + + ]: 29376 : bb_cpc2(2:) = czero
741 : :
742 [ + + ]: 576 : if(ik_bz == ikp_bz) then
743 : : ! Enforce orthogonality of the wavefunctions.
744 [ + + ]: 128 : if(icp == ic) then
745 : 32 : aa_cpc(1) = cone
746 : 32 : bb_cpc2(1) = cone
747 : : else
748 : 96 : aa_cpc(1) = czero
749 : 96 : bb_cpc2(1) = czero
750 : : end if
751 : : end if
752 : :
753 : : ! MG TODO: a does not require a call to w0gemv
754 : 576 : call screen%w0gemv("C",npweps,nspinor,w_is_diagonal,cone_gw,czero_gw,aa_cpc,aa_ctccp)
755 : 576 : call screen%w0gemv("C",npweps,nspinor,w_is_diagonal,cone_gw,czero_gw,bb_cpc1,bb_ctccp1)
756 : 576 : call screen%w0gemv("C",npweps,nspinor,w_is_diagonal,cone_gw,czero_gw,bb_cpc2,bb_ctccp2)
757 : :
758 [ + - - + : 30528 : cc_cpc = vc_sqrt_qbz*rhxtwg_cpc
- - + + ]
759 : 576 : cc_cpc(1) = czero
760 : :
761 : 576 : call screen%w0gemv("C",npweps,nspinor,w_is_diagonal,cone_gw,czero_gw,cc_cpc,cc_ctccp)
762 : : end if
763 : :
764 : : ! Prepare sum_GG' rho_c'c*(G) W_qbz(G,G') rho_v'v(G')
765 : : ! First sum on G: sum_G rho_c'c(G) W_qbz*(G,G') (W_qbz conjugated)
766 [ - + + + ]: 9953856 : rhxtwg_cpc = rhxtwg_cpc * vc_sqrt_qbz
767 : 215616 : call screen%w0gemv("C",npweps,nspinor,w_is_diagonal,cone_gw,czero_gw,rhxtwg_cpc,ctccp)
768 : :
769 [ + + ]: 921936 : do iv=bidx(1,1),bidx(2,1) !do iv=BSp%lomo,BSp%homo
770 [ + - ]: 638672 : it = BSp%vcks2t(iv,ic,ik_bz,spin1); if (it==0) CYCLE ! ir-uv-cutoff
771 : 638672 : ene_t = BSp%Trans(it,spin1)%en
772 : :
773 : : ! TODO: use this but change the order of the loops.
774 [ - + ]: 638672 : ABI_CHECK(wfd%get_wave_ptr(iv, ik_ibz, spin1, wave_vk, msg) == 0, msg)
775 : :
776 [ + + ]: 638672 : if (wave_vk%has_ur == WFD_STORED) then
777 : 638453 : ptur_vk => wave_vk%ur
778 : : else
779 : 219 : call wfd%get_ur(iv,ik_ibz,spin1,ur_vk)
780 : 219 : ptur_vk => ur_vk
781 : : end if
782 : : !
783 : : ! Load cprj for this (v,k,s1) in the BZ.
784 : : ! Do not care about umklapp G0 in k-q as the phase is already included.
785 [ + + ]: 638672 : if (Wfd%usepaw==1) then
786 [ + - ]: 51264 : if (wave_vk%has_cprj == WFD_STORED) then
787 : 51264 : ptcp_vk => wave_vk%cprj
788 : : else
789 : 0 : call wfd%get_cprj(iv,ik_ibz,spin1,Cryst,Cp_tmp3,sorted=.FALSE.)
790 : 0 : ptcp_vk => Cp_tmp3
791 : : end if
792 [ - + ]: 51264 : call paw_symcprj_op(ik_bz,nspinor,1,Cryst,Kmesh,Pawtab,Pawang,ptcp_vk,Cp_vk)
793 : : end if
794 : :
795 [ + + ]: 2773248 : do ivp=bidx(1,3),bidx(2,3) !do ivp=BSp%lomo,BSp%homo
796 : :
797 [ + + ]: 1918960 : if (is_resonant) then
798 : 1842928 : itp = BSp%vcks2t(ivp,icp,ikp_bz,spin2)
799 : : else ! have to exchange band indices
800 : 76032 : itp = BSp%vcks2t(icp,ivp,ikp_bz,spin2)
801 : : end if
802 : :
803 [ - + ]: 1918960 : if (itp==0) CYCLE ! ir-uv-cutoff
804 : :
805 : : ! FIXME Temporary work around, when ikp_bz == ik it might happen that itp<it
806 : : ! should rewrite the loops using contracted k-dependent indices for bands
807 [ + + ]: 1918960 : if (itp<it) CYCLE
808 : :
809 : 1883684 : ir = it + itp*(itp-1)/2
810 [ + + + + ]: 1883684 : if (ir<t_start(my_rank).or.ir>t_stop(my_rank)) CYCLE
811 : :
812 : 1877264 : ene_tp = BSp%Trans(itp,spin2)%en
813 : :
814 : : ! ============================================
815 : : ! === Calculate matrix elements rhxtwg_vpv ===
816 : : ! ============================================
817 [ + + ]: 1877264 : if (ik_bz==ikp_bz) then
818 : : ! Already in memory.
819 : 42928 : rhxtwg_vpv(:) = sym_rhotwgq0(itim_k,isym_k,dim_rtwg,npweps,rhxtwg_q0(:,ivp,iv,ik_ibz,spin1),Gsph_c)
820 : :
821 : : else
822 : :
823 [ - + ]: 1834336 : ABI_CHECK(wfd%get_wave_ptr(ivp, ikp_ibz, spin2, wave_vkp, msg) == 0, msg)
824 : :
825 : : ! Calculate matrix element from wfr.
826 [ + + ]: 1834336 : if (wave_vkp%has_ur == WFD_STORED) then
827 : 1834123 : ptur_vkp => wave_vkp%ur
828 : : else
829 : 213 : call wfd%get_ur(ivp,ikp_ibz,spin2,ur_vkp)
830 : 213 : ptur_vkp => ur_vkp
831 : : end if
832 : : !
833 : : ! Load cprj for this (vp,kp,s2) in the BZ.
834 : : ! Do not care about umklapp G0 in k-q as the phase is already included.
835 [ + + ]: 1834336 : if (Wfd%usepaw==1) then
836 [ + - ]: 144640 : if (wave_vkp%has_cprj == WFD_STORED) then
837 : 144640 : ptcp_vkp => wave_vkp%cprj
838 : : else
839 : 0 : call wfd%get_cprj(ivp,ikp_ibz,spin2,Cryst,Cp_tmp4,sorted=.FALSE.)
840 : 0 : ptcp_vkp => Cp_tmp4
841 : : end if
842 [ - + ]: 144640 : call paw_symcprj_op(ikp_bz,nspinor,1,Cryst,Kmesh,Pawtab,Pawang,ptcp_vkp,Cp_vkp)
843 : : end if
844 : :
845 : : call rho_tw_g(nspinor,npweps,nfftot_osc,ndat1,ngfft_osc,map2sphere,use_padfft,igfftg0,gbound,&
846 : : ptur_vkp,itim_kp,ktabr_kp,ph_mkpt,spinrot_kp,&
847 : : ptur_vk ,itim_k ,ktabr_k ,ph_mkt ,spinrot_k ,&
848 : 1834336 : dim_rtwg,rhxtwg_vpv)
849 : :
850 [ + + ]: 1834336 : if (Wfd%usepaw==1) then ! Add PAW onsite contribution.
851 : 144640 : call paw_rho_tw_g(cryst,Pwij_q,npweps,dim_rtwg,nspinor,Gsph_c%gvec,Cp_vkp,Cp_vk,rhxtwg_vpv)
852 : : end if
853 : : end if
854 : :
855 : : ! Index in the global Hamiltonian matrix.
856 : : ir = it + itp*(itp-1_i8b)/2
857 : :
858 [ + - - + ]: 1877264 : if (ir<t_start(my_rank).or.ir>t_stop(my_rank)) then
859 : 0 : write(msg,'(a,3(1x,i0))')" Gonna SIGFAULT, ir, t_start, t_stop ",ir,t_start(my_rank),t_stop(my_rank)
860 : 0 : ABI_ERROR(msg)
861 : : end if
862 : : !ABI_CHECK(itp >= it,"itp < it")
863 : :
864 [ + + ]: 1877264 : if (BSp%prep_interp) then
865 : : ! Save a,b, c coefficients.
866 [ + - - + : 246768 : aa_vpv = rhxtwg_vpv
- - + + ]
867 [ + + ]: 237456 : aa_vpv(2:) = czero
868 [ + - - + : 246768 : bb_vpv1 = rhxtwg_vpv
- - + + ]
869 [ + + ]: 237456 : bb_vpv1(2:) = czero
870 [ + - - + : 246768 : bb_vpv2 = vc_sqrt_qbz*rhxtwg_vpv
- - + + ]
871 : 4656 : bb_vpv2(1) = czero
872 : :
873 [ + + ]: 4656 : if (ik_bz == ikp_bz) then
874 : : ! Enforce orthogonality of the wavefunctions.
875 [ + + ]: 624 : if (ivp == iv) then
876 : 240 : aa_vpv(1) = cone
877 : 240 : bb_vpv1(1) = cone
878 : : else
879 : 384 : aa_vpv(1) = czero
880 : 384 : bb_vpv1(1) = czero
881 : : end if
882 : : end if
883 : :
884 [ + - - + : 246768 : cc_vpv = vc_sqrt_qbz*rhxtwg_vpv
- - + + ]
885 : 4656 : cc_vpv(1) = czero
886 : :
887 : 4656 : aatmp = -faq * xdotc(npweps,aa_ctccp,1,aa_vpv,1)
888 : 4656 : bbtmp = -faq * xdotc(npweps,bb_ctccp1,1,bb_vpv1,1)-faq*xdotc(npweps,bb_ctccp2,1,bb_vpv2,1)
889 : 4656 : cctmp = -faq * xdotc(npweps,cc_ctccp,1,cc_vpv,1)
890 : :
891 : 4656 : acoeffs(ir) = aatmp
892 : 4656 : bcoeffs(ir) = bbtmp
893 : 4656 : ccoeffs(ir) = cctmp
894 : : end if
895 : :
896 : : ! sum_G2 rho_c'c(G) W_qbz(G,G') rho_v'v(G')
897 [ + - - + : 87272848 : rhxtwg_vpv = vc_sqrt_qbz * rhxtwg_vpv
- - + + ]
898 : 1877264 : http = - faq * xdotc(npweps,ctccp,1,rhxtwg_vpv,1)
899 : :
900 : : ! Save result taking into account the symmetry of the matrix.
901 : : ! Note that the diagonal of the resonant block is not forced to be real
902 : 2557632 : my_bsham(ir) = http
903 : :
904 : : #ifdef DEV_MG_DEBUG_MODE
905 : : ttp_check(it,itp) = ttp_check(it,itp)+1
906 : : #endif
907 : : end do !ivp
908 : : end do !iv
909 : : end do !icp
910 : : end do !ic
911 : :
912 [ - + ]: 22740 : ABI_FREE(gbound)
913 : :
914 [ + + + + ]: 23828 : if (Wfd%usepaw==1.and.ik_bz/=ikp_bz) then ! Free the onsite contribution for this q.
915 : 1020 : call pawpwij_free(Pwij_q)
916 [ + - + + : 2068 : ABI_FREE(Pwij_q)
- + - + ]
917 : : end if
918 : :
919 : : end do ! ik_bz
920 : : end do ! Fat loop over ikp_bz
921 : :
922 : : #ifdef DEV_MG_DEBUG_MODE
923 : : do itp=1,BSp%nreh(block)
924 : : do it=1,BSp%nreh(block)
925 : : ir = it + itp*(itp-1_i8b)/2
926 : : if (itp>=it .and. ttp_check(it,itp) /= 1) then
927 : : if (ir>=t_start(my_rank).and.ir<=t_stop(my_rank)) then
928 : : write(std_out,*)"WARN: upper triangle is not 1 ",it,itp,ttp_check(it,itp)
929 : : write(std_out,*)TRIM(repr_trans(Bsp%Trans(it ,spin1)))
930 : : write(std_out,*)TRIM(repr_trans(Bsp%Trans(itp,spin2)))
931 : : end if
932 : : end if
933 : : if (itp< it .and. ttp_check(it,itp) /= 0) then
934 : : write(std_out,*)"WARN: then lower triangle is not 0 ",it,itp,ttp_check(it,itp)
935 : : write(std_out,*)TRIM(repr_trans(Bsp%Trans(it ,spin1)))
936 : : write(std_out,*)TRIM(repr_trans(Bsp%Trans(itp,spin2)))
937 : : end if
938 : : end do
939 : : end do
940 : : ierr = SUM(SUM(ttp_check,DIM=2),DIM=1)
941 : : if (ierr/=my_hsize) then
942 : : write(msg,'(a,2i0)')"ierr/=my_hsize",ierr,my_hsize
943 : : ABI_ERROR(msg)
944 : : end if
945 : : ABI_FREE(ttp_check)
946 : : #endif
947 : :
948 [ - + ]: 24 : ABI_FREE(ctccp)
949 [ + + ]: 24 : if(Bsp%prep_interp) then
950 [ - + ]: 1 : ABI_FREE(aa_ctccp)
951 [ - + ]: 1 : ABI_FREE(bb_ctccp1)
952 [ - + ]: 1 : ABI_FREE(bb_ctccp2)
953 [ - + ]: 1 : ABI_FREE(cc_ctccp)
954 : : end if
955 : :
956 [ - + ]: 24 : ABI_FREE(vc_sqrt_qbz)
957 : 24 : call wrtout(std_out,' Coulomb term completed')
958 : :
959 : 24 : call timab(682,2,tsec) ! exc_build_ham(Coulomb)
960 : : end if ! do_coulomb_term
961 : : !
962 : : ! =====================
963 : : ! === Exchange term ===
964 : : ! =====================
965 : : ! TODO might add treatment of <psi|q+G|psi> for q+G -> 0
966 : : ! TODO might used enlarged G-sphere for better convergence.
967 [ + - ]: 24 : if (do_exchange_term) then
968 : :
969 : : !call exc_build_v(spin1,spin2,nsppol,npweps,Bsp,Cryst,Kmesh,Qmesh,Gsph_x,Gsph_c,Vcp,&
970 : : ! & is_resonant,rhxtwg_q0,nproc,my_rank,t_start,t_stop,my_bsham,comm)
971 : :
972 : 24 : call timab(683,1,tsec) ! exc_build_ham(exchange)
973 : :
974 : 24 : write(msg,'(a,2i2,a)')" Calculating exchange term for (spin1,spin2) ",spin1,spin2," ..."
975 : 24 : call wrtout(std_out, msg)
976 : :
977 [ - + + - : 72 : ABI_MALLOC(rhotwg1,(npweps))
+ - + - -
+ - + ]
978 [ - + + - : 48 : ABI_MALLOC(rhotwg2,(npweps))
- + - + ]
979 : :
980 : 24 : ngx = Gsph_x%ng
981 [ - + + - : 72 : ABI_MALLOC(vc_sqrt_qbz,(ngx))
+ - + - -
+ - + ]
982 : :
983 : : ! * Get iq_ibz, and symmetries from iq_bz.
984 : 24 : iq_bz = iqbz0 ! q = 0 -> iqbz0
985 : 24 : call qmesh%get_BZ_item(iq_bz,qbz,iq_ibz,isym_q,itim_q)
986 : :
987 : : ! * Set up table of |q(BZ)+G|
988 [ + - ]: 24 : if (iq_ibz==1) then
989 [ + + ]: 7078 : do ig=1,ngx
990 : 7054 : ISg = Gsph_x%rottb(ig,itim_q,isym_q)
991 : 7078 : vc_sqrt_qbz(ISg)=Vcp%vcqlwl_sqrt(ig,1)
992 : : end do
993 : : else
994 : 0 : ABI_ERROR("iq_ibz should be 1")
995 : : end if
996 : :
997 [ + + ]: 9272 : do itp=1,BSp%nreh(block) ! Loop over transition tp = (kp,vp,cp,spin2)
998 : :
999 [ + + + + ]: 9248 : if (itp<my_cols(1) .or. itp>my_cols(2)) CYCLE ! I dont have this column.
1000 : 7716 : ene_tp = Bsp%Trans(itp,spin2)%en
1001 : 7716 : ikp_bz = Bsp%Trans(itp,spin2)%k
1002 : 7716 : ivp = Bsp%Trans(itp,spin2)%v
1003 : 7716 : icp = Bsp%Trans(itp,spin2)%c
1004 : :
1005 : 7716 : ikp_ibz = Kmesh%tab (ikp_bz)
1006 : 7716 : isym_kp = Kmesh%tabo(ikp_bz)
1007 : 7716 : itim_kp = (3-Kmesh%tabi(ikp_bz))/2
1008 : :
1009 [ + + ]: 7716 : if (is_resonant) then
1010 : 7332 : rhotwg2(:) = sym_rhotwgq0(itim_kp,isym_kp,dim_rtwg,npweps,rhxtwg_q0(:,ivp,icp,ikp_ibz,spin2),Gsph_c)
1011 : : else ! Code for coupling block.
1012 : 384 : rhotwg2(:) = sym_rhotwgq0(itim_kp,isym_kp,dim_rtwg,npweps,rhxtwg_q0(:,icp,ivp,ikp_ibz,spin2),Gsph_c)
1013 : : end if
1014 : : !
1015 : : ! Multiply by the Coulomb term.
1016 [ + + ]: 365516 : do ig=2,npweps
1017 : 365516 : rhotwg2(ig) = rhotwg2(ig) * vc_sqrt_qbz(ig) * vc_sqrt_qbz(ig)
1018 : : end do
1019 : :
1020 [ + + ]: 1886073 : do it=1,itp ! Loop over transition t = (k,v,c,spin1)
1021 : 1878333 : ir = it + itp*(itp-1_i8b)/2
1022 [ + + + + ]: 1878333 : if (ir<t_start(my_rank) .or. ir>t_stop(my_rank)) CYCLE
1023 : :
1024 : 1877264 : ene_t = Bsp%Trans(it,spin1)%en
1025 : 1877264 : ik_bz = Bsp%Trans(it,spin1)%k
1026 : 1877264 : iv = Bsp%Trans(it,spin1)%v
1027 : 1877264 : ic = Bsp%Trans(it,spin1)%c
1028 : :
1029 : 1877264 : ik_ibz = Kmesh%tab(ik_bz)
1030 : 1877264 : isym_k = Kmesh%tabo(ik_bz)
1031 : 1877264 : itim_k = (3-Kmesh%tabi(ik_bz))/2
1032 : : !if (itim_k==2) CYCLE ! time-reversal or not
1033 : :
1034 : 1877264 : rhotwg1(:) = sym_rhotwgq0(itim_k,isym_k,dim_rtwg,npweps,rhxtwg_q0(:,iv,ic,ik_ibz,spin1),Gsph_c)
1035 : : !
1036 : : ! sum over G/=0
1037 : 1877264 : ctemp = xdotc(npweps-1,rhotwg1(2:),1,rhotwg2(2:),1)
1038 : 1877264 : ctemp = faq * kx_fact * ctemp
1039 : :
1040 : : ! exchange term is non divergent !
1041 [ + + ]: 1877264 : if (BSp%prep_interp) then
1042 : 4656 : ccoeffs(ir) = ccoeffs(ir) + ctemp
1043 : : end if
1044 : :
1045 : 1887581 : my_bsham(ir) = my_bsham(ir) + ctemp
1046 : : end do !it
1047 : : end do !itp
1048 : :
1049 [ - + ]: 24 : ABI_FREE(rhotwg1)
1050 [ - + ]: 24 : ABI_FREE(rhotwg2)
1051 [ - + ]: 24 : ABI_FREE(vc_sqrt_qbz)
1052 : :
1053 : 24 : call timab(683,2,tsec) ! exc_build_ham(exchange)
1054 : : end if ! do_exchange_term
1055 : : !
1056 : : ! =====================
1057 : : ! === Diagonal term ===
1058 : : ! =====================
1059 [ + + + - ]: 24 : if (is_resonant .and. spin1==spin2) then
1060 : 23 : write(msg,'(a,2i2,a)')" Adding diagonal term for (spin1,spin2) ",spin1,spin2," ..."
1061 : 23 : call wrtout(std_out, msg)
1062 [ + + ]: 8887 : do it=1,BSp%nreh(block)
1063 : 8864 : ir = it + it*(it-1_i8b)/2
1064 [ + + + + ]: 8887 : if (ir>=t_start(my_rank) .and. ir<=t_stop(my_rank)) my_bsham(ir) = my_bsham(ir) + Bsp%Trans(it,spin1)%en
1065 : : end do
1066 : : end if
1067 : :
1068 : : if (.FALSE.) then
1069 : : dump_unt = get_unit()
1070 : : msg=' Coupling Hamiltonian matrix elements: '
1071 : : if (is_resonant) msg=' Reasonant Hamiltonian matrix elements: '
1072 : : call wrtout(dump_unt, msg)
1073 : : call wrtout(dump_unt,' k v c s k" v" c" s" H')
1074 : : do itp=1,BSp%nreh(block)
1075 : : ikp_bz = Bsp%Trans(itp,spin2)%k
1076 : : ivp = Bsp%Trans(itp,spin2)%v
1077 : : icp = Bsp%Trans(itp,spin2)%c
1078 : : do it=1,itp
1079 : : ik_bz = Bsp%Trans(it,spin1)%k
1080 : : iv = Bsp%Trans(it,spin1)%v
1081 : : ic = Bsp%Trans(it,spin1)%c
1082 : : ir = it + itp*(itp-1_i8b)/2
1083 : : if (ir>=t_start(my_rank).and.ir<=t_stop(my_rank)) then
1084 : : http = my_bsham(ir)
1085 : : !if (ABS(http) > tol3) then
1086 : : write(msg,'(2(i0,1x),2(i5,3i3,3x),2f7.3)')it,itp, ik_bz,iv,ic,spin1, ikp_bz,ivp,icp,spin2, http
1087 : : call wrtout(dump_unt, msg)
1088 : : !end if
1089 : : end if
1090 : : end do
1091 : : end do
1092 : : end if
1093 : :
1094 : : !DBYG
1095 : : if (.False.) then
1096 : : dump_unt = get_unit()
1097 : : dump_unt = 999
1098 : : msg=' Coupling Hamiltonian matrix elements: '
1099 : : if (is_resonant) msg=' Resonant Hamiltonian matrix elements: '
1100 : : call wrtout(dump_unt, msg)
1101 : : call wrtout(dump_unt,' k v c s k" v" c" s" H')
1102 : : do itp=1,BSp%nreh(block)
1103 : : ikp_bz = Bsp%Trans(itp,spin2)%k
1104 : : ivp = Bsp%Trans(itp,spin2)%v
1105 : : icp = Bsp%Trans(itp,spin2)%c
1106 : : do it=1,BSp%nreh(block)
1107 : : ik_bz = Bsp%Trans(it,spin1)%k
1108 : : iv = Bsp%Trans(it,spin1)%v
1109 : : ic = Bsp%Trans(it,spin1)%c
1110 : : if(it > itp) then
1111 : : ir = itp+it*(it-1_i8b)/2
1112 : : else
1113 : : ir = it + itp*(itp-1_i8b)/2
1114 : : end if
1115 : : if (ir>=t_start(my_rank).and.ir<=t_stop(my_rank)) then
1116 : : if(it > itp) then
1117 : : http = CONJG(my_bsham(ir))
1118 : : if (BSp%prep_interp) then
1119 : : aatmp = CONJG(acoeffs(ir))
1120 : : bbtmp = CONJG(bcoeffs(ir))
1121 : : cctmp = CONJG(ccoeffs(ir))
1122 : : end if
1123 : : else
1124 : : http = my_bsham(ir)
1125 : : if (BSp%prep_interp) then
1126 : : aatmp = acoeffs(ir)
1127 : : bbtmp = bcoeffs(ir)
1128 : : cctmp = ccoeffs(ir)
1129 : : end if
1130 : : end if
1131 : : if (it == itp) http = http - Bsp%Trans(it,spin1)%en
1132 : : !if (ABS(http) > tol3) then
1133 : : if (BSp%prep_interp) then
1134 : : write(msg,'(2(i0,1x),2(i5,3i3,3x),2f24.20,2f24.20,2f24.20,2f24.20)')it,itp, ik_bz,iv,ic,spin1, ikp_bz,ivp,icp,&
1135 : : & spin2, http, aatmp, bbtmp, cctmp
1136 : : else
1137 : : write(msg,'(2(i0,1x),2(i5,3i3,3x),2f24.20)')it,itp, ik_bz,iv,ic,spin1, ikp_bz,ivp,icp,spin2, http
1138 : : end if
1139 : : call wrtout(dump_unt, msg)
1140 : : !end if
1141 : : end if
1142 : : end do
1143 : : end do
1144 : : end if
1145 : :
1146 : 24 : call timab(684,1,tsec) ! exc_build_ham(synchro)
1147 : 24 : call xmpi_barrier(comm)
1148 : 24 : call timab(684,2,tsec) ! exc_build_ham(synchro)
1149 : : !
1150 : : ! =================================
1151 : : ! === Write Hamiltonian on disk ===
1152 : : ! =================================
1153 : 24 : call timab(685,1,tsec) ! exc_build_ham(write_ham)
1154 : 48 : if (use_mpiio) then
1155 : : #ifdef HAVE_MPI_IO
1156 : : ! Write the Hamiltonian with collective MPI-IO.
1157 : : if (BSp%prep_interp) then
1158 : : ABI_ERROR("Preparation of interpolation technique not yet coded with MPI-IO")
1159 : : end if
1160 : : ABI_CHECK(nsppol==1,"nsppol==2 not coded, offset is wrong")
1161 : : !
1162 : : old_type = MPI_DOUBLE_COMPLEX
1163 : : call xmpio_create_fherm_packed(my_starts,my_ends,is_fortran_file,my_offset,old_type,hmat_type,offset_err)
1164 : :
1165 : : if (offset_err/=0) then
1166 : : write(msg,"(3a)")&
1167 : : "Global position index cannot be stored in a standard Fortran integer. ",ch10,&
1168 : : "BSE matrix cannot be written with a single MPI-IO call. "
1169 : : ABI_ERROR(msg)
1170 : : end if
1171 : : !
1172 : : ! Each node uses a different offset to skip the header and the blocks written by the other CPUs.
1173 : : my_offset = offset_of_block(block) + my_offset
1174 : :
1175 : : call MPI_FILE_SET_VIEW(mpi_fh, my_offset, MPI_BYTE, hmat_type, 'native', MPI_INFO_NULL, mpi_err)
1176 : : ABI_CHECK_MPI(mpi_err,"SET_VIEW")
1177 : :
1178 : : call MPI_TYPE_FREE(hmat_type,mpi_err)
1179 : : ABI_CHECK_MPI(mpi_err,"MPI_TYPE_FREE")
1180 : :
1181 : : if (hsize_of(my_rank) /= INT(hsize_of(my_rank),kind=i4b) ) then
1182 : : ABI_ERROR("Wraparound error")
1183 : : end if
1184 : :
1185 : : tmp_size = INT(hsize_of(my_rank))
1186 : : call MPI_FILE_WRITE_ALL(mpi_fh, my_bsham, tmp_size, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpi_err)
1187 : : ABI_CHECK_MPI(mpi_err,"FILE_WRITE")
1188 : :
1189 : : ! It seems that personal calls in make the code stuck
1190 : : !if (is_fortran_file .and. my_rank==master) then ! Master writes the Fortran record markers.
1191 : : ! Write the Fortran record markers.
1192 : : neh2=BSp%nreh(block)
1193 : : ABI_MALLOC(bsize_frecord,(neh2))
1194 : : bsize_frecord = (/(col_glob * xmpi_bsize_dpc, col_glob=1,neh2)/)
1195 : : ! ehdr_offset points to the end of the header.
1196 : : !call xmpio_write_frmarkers(mpi_fh,ehdr_offset,xmpio_collective,neh2,bsize_frecord,mpi_err)
1197 : : my_offset = offset_of_block(block)
1198 : : call xmpio_write_frmarkers(mpi_fh,my_offset,xmpio_collective,neh2,bsize_frecord,ierr)
1199 : : ABI_CHECK(ierr==0,"Error while writing Fortran markers")
1200 : : ABI_FREE(bsize_frecord)
1201 : : #else
1202 : : ABI_BUG("You should not be here!")
1203 : : #endif
1204 : : else
1205 : : ! Use FORTRAN IO with sequential access mode.
1206 : : ! * Each node sends its data to master node.
1207 : : ! * Blocks are distributed according to the rank of the node.
1208 : : ! * Matrix is written by columns hence make sure that the last column is completely written.
1209 : 24 : call cwtime(cputime,walltime,gflops,"start")
1210 : :
1211 [ + + ]: 24 : if (my_rank==master) then
1212 [ + + ]: 20 : prev_nrows=0; if (my_cols(2) /= my_rows(2)) prev_nrows = my_rows(2)
1213 : 20 : ncol = my_cols(2)-my_cols(1)+1
1214 : 20 : ist=1
1215 [ + + ]: 7428 : do jj=1,ncol
1216 : 7408 : col_glob = my_starts(2) + jj - 1
1217 [ + + ]: 7408 : nrows = col_glob; if (jj==ncol) nrows=my_rows(2)
1218 : 7408 : iend = ist + nrows -1
1219 : 7408 : write(bsh_unt) my_bsham(ist:iend)
1220 [ + + ]: 7408 : if (BSp%prep_interp) then
1221 : 96 : write(a_unt) acoeffs(ist:iend)
1222 : 96 : write(b_unt) bcoeffs(ist:iend)
1223 : 96 : write(c_unt) ccoeffs(ist:iend)
1224 : : end if
1225 : 7428 : ist=iend+1
1226 : : end do
1227 : 20 : write(msg,'(2(a,i0))')" Wraparound error: iend=",iend," my_hsize=",hsize_of(my_rank)
1228 [ - + ]: 20 : ABI_CHECK(iend == hsize_of(my_rank),msg)
1229 [ - + ]: 20 : ABI_FREE(my_bsham)
1230 [ + + ]: 20 : if (BSp%prep_interp) then
1231 [ - + ]: 1 : ABI_FREE(acoeffs)
1232 [ - + ]: 1 : ABI_FREE(bcoeffs)
1233 [ - + ]: 1 : ABI_FREE(ccoeffs)
1234 : : end if
1235 : : end if
1236 : :
1237 : 24 : call xmpi_barrier(comm)
1238 : : !
1239 : : ! Collect data from the other nodes.
1240 [ + + ]: 38 : do sender=1,nproc-1
1241 : : ! If I'm not involved, jump to the end of the loop and wait there (sequential IO? Of course!)
1242 [ + + ]: 14 : if (all(my_rank /= [sender, master])) goto 100
1243 : :
1244 [ + + ]: 8 : if (my_rank==master) then
1245 [ - + + - : 12 : ABI_MALLOC(buffer,(hsize_of(sender)))
+ - + - -
+ - + -
+ ]
1246 [ - + ]: 4 : if (BSp%prep_interp) then
1247 [ # # # # : 0 : ABI_MALLOC(abuffer,(hsize_of(sender)))
# # # # #
# ]
1248 [ # # # # : 0 : ABI_MALLOC(bbuffer,(hsize_of(sender)))
# # # # #
# ]
1249 [ # # # # : 0 : ABI_MALLOC(cbuffer,(hsize_of(sender)))
# # # # #
# ]
1250 : : end if
1251 : : end if
1252 : 8 : tmp_size = INT(hsize_of(sender),kind=i4b)
1253 : 8 : call xmpi_exch(my_bsham,tmp_size,sender,buffer,master,comm,10*block+1,mpi_err)
1254 [ - + ]: 8 : if (BSp%prep_interp) then
1255 : 0 : call xmpi_exch(acoeffs,tmp_size,sender,abuffer,master,comm,10*block+2,mpi_err)
1256 : 0 : call xmpi_exch(bcoeffs,tmp_size,sender,bbuffer,master,comm,10*block+3,mpi_err)
1257 : 0 : call xmpi_exch(ccoeffs,tmp_size,sender,cbuffer,master,comm,10*block+4,mpi_err)
1258 : : end if
1259 : :
1260 : : ! TODO Be careful with the MPI TAG here, add optional Arguments in xmpi_exch so that the TAG can be specified!
1261 [ + + ]: 24 : proc_start = (/my_rows(1),my_cols(1)/)
1262 [ + + ]: 24 : proc_end = (/my_rows(2),my_cols(2)/)
1263 [ + + ]: 24 : my_extrema(:,1) = proc_start
1264 [ + + ]: 24 : my_extrema(:,2) = proc_end
1265 : :
1266 : 8 : sender_extrema = my_extrema ! just to avoid NAN on sender. xechh_mpi is not well designed
1267 : 8 : call xmpi_exch(my_extrema,4,sender,sender_extrema,master,comm,10*block+5,mpi_err)
1268 : :
1269 [ + + ]: 8 : if (my_rank==master) then
1270 [ + + ]: 12 : proc_start = sender_extrema(:,1)
1271 [ + + ]: 12 : proc_end = sender_extrema(:,2)
1272 : : !write(std_out,*)"proc_start, proc_end",proc_start,proc_end
1273 : :
1274 [ + - ]: 4 : if (prev_nrows>0) then ! backspace the file if the last record written was not complete.
1275 : : !write(std_out,*)" master node had to call backspace"
1276 : 4 : backspace(bsh_unt)
1277 [ - + + - : 12 : ABI_MALLOC(prev_col,(prev_nrows))
+ - - + -
+ - + ]
1278 : 4 : read(bsh_unt) prev_col
1279 : 4 : backspace(bsh_unt)
1280 : :
1281 [ - + ]: 4 : if (BSp%prep_interp) then
1282 : 0 : backspace(a_unt)
1283 [ # # # # : 0 : ABI_MALLOC(aprev_col,(prev_nrows))
# # # # #
# ]
1284 : 0 : read(a_unt) aprev_col
1285 : 0 : backspace(a_unt)
1286 : :
1287 : 0 : backspace(b_unt)
1288 [ # # # # : 0 : ABI_MALLOC(bprev_col,(prev_nrows))
# # # # #
# ]
1289 : 0 : read(b_unt) bprev_col
1290 : 0 : backspace(b_unt)
1291 : :
1292 : 0 : backspace(c_unt)
1293 [ # # # # : 0 : ABI_MALLOC(cprev_col,(prev_nrows))
# # # # #
# ]
1294 : 0 : read(c_unt) cprev_col
1295 : 0 : backspace(c_unt)
1296 : : end if
1297 : : end if
1298 : : !
1299 : : ! Write the columns owned by sender.
1300 : 4 : ncol = proc_end(2)-proc_start(2)+1
1301 : 4 : ist=1
1302 [ + + ]: 312 : do jj=1,ncol
1303 : 308 : col_glob = proc_start(2) + jj-1
1304 : 308 : nrows = col_glob
1305 [ + + ]: 308 : if (jj==1 ) nrows=col_glob - proc_start(1) + 1
1306 [ + + ]: 308 : if (jj==ncol) then
1307 : 4 : nrows=proc_end(1)
1308 [ - + ]: 4 : if (ncol==1) nrows=proc_end(1) - proc_start(1) + 1
1309 : : end if
1310 : 308 : iend = ist + nrows -1
1311 : : !write(std_out,*)"Using nrows, ist, iend=",nrows,ist,iend
1312 [ + + ]: 308 : if (jj==1 .and. prev_nrows>0) then ! join prev_col and this subcolumn.
1313 [ + + + + ]: 1073 : write(bsh_unt) CMPLX(prev_col,kind=dp),CMPLX(buffer(ist:iend),kind=dp)
1314 [ - + ]: 4 : if (BSp%prep_interp) then
1315 [ # # # # ]: 0 : write(a_unt) CMPLX(aprev_col,kind=dp),CMPLX(abuffer(ist:iend),kind=dp)
1316 [ # # # # ]: 0 : write(b_unt) CMPLX(bprev_col,kind=dp),CMPLX(bbuffer(ist:iend),kind=dp)
1317 [ # # # # ]: 0 : write(c_unt) CMPLX(cprev_col,kind=dp),CMPLX(cbuffer(ist:iend),kind=dp)
1318 : : end if
1319 : 4 : prev_nrows = prev_nrows + iend-ist+1
1320 : : else
1321 [ + + ]: 92149 : write(bsh_unt) CMPLX(buffer(ist:iend),kind=dp)
1322 [ - + ]: 304 : if (BSp%prep_interp) then
1323 [ # # ]: 0 : write(a_unt) CMPLX(abuffer(ist:iend),kind=dp)
1324 [ # # ]: 0 : write(b_unt) CMPLX(bbuffer(ist:iend),kind=dp)
1325 [ # # ]: 0 : write(c_unt) CMPLX(cbuffer(ist:iend),kind=dp)
1326 : : end if
1327 : : prev_nrows=0
1328 : : end if
1329 : 312 : ist=iend+1
1330 : : end do
1331 [ + - ]: 4 : if (ncol>1) then ! Reset prev_nrows if a new column has begun.
1332 : 4 : prev_nrows = proc_end(1)
1333 [ + + ]: 4 : if (proc_end(1) == proc_end(2)) prev_nrows = 0
1334 : : end if
1335 [ - + ]: 4 : if (iend/=hsize_of(sender)) then
1336 : 0 : write(msg,'(2(a,i0))')" Wraparound error: iend=",iend," my_hsize=",hsize_of(sender)
1337 : 0 : ABI_ERROR(msg)
1338 : : end if
1339 [ + - ]: 4 : ABI_SFREE(prev_col)
1340 [ - + ]: 4 : if (BSp%prep_interp) then
1341 [ # # ]: 0 : ABI_SFREE(aprev_col)
1342 [ # # ]: 0 : ABI_SFREE(bprev_col)
1343 [ # # ]: 0 : ABI_SFREE(cprev_col)
1344 : : end if
1345 [ - + ]: 4 : ABI_FREE(buffer)
1346 [ - + ]: 4 : if (BSp%prep_interp) then
1347 [ # # ]: 0 : ABI_FREE(abuffer)
1348 [ # # ]: 0 : ABI_FREE(bbuffer)
1349 [ # # ]: 0 : ABI_FREE(cbuffer)
1350 : : end if
1351 : : end if ! master
1352 : : !
1353 : 38 : 100 call xmpi_barrier(comm)
1354 : : end do ! sender
1355 : :
1356 : 24 : call cwtime(cputime,walltime,gflops,"stop")
1357 : 24 : write(msg,'(2(a,f9.1),a)')" Fortran-IO completed. cpu_time: ",cputime,"[s], walltime: ",walltime," [s]"
1358 : 24 : call wrtout(std_out, msg, do_flush=.True.)
1359 : : end if ! use_mpiio
1360 : 24 : call timab(685,2,tsec) ! exc_build_ham(write_ham)
1361 : : !
1362 [ + + ]: 24 : ABI_SFREE(my_bsham)
1363 [ + + ]: 24 : if (BSp%prep_interp) then
1364 [ - + ]: 1 : ABI_SFREE(acoeffs)
1365 [ - + ]: 1 : ABI_SFREE(bcoeffs)
1366 [ - + ]: 1 : ABI_SFREE(ccoeffs)
1367 : : end if
1368 : 24 : ABI_FREE(t_start)
1369 : 24 : ABI_FREE(t_stop)
1370 : 47 : ABI_FREE(hsize_of)
1371 : : end do ! block
1372 : : !
1373 : : ! ===========================================
1374 : : ! === Exchange term for spin_up spin_down ===
1375 : : ! ===========================================
1376 : :
1377 [ + + ]: 23 : if (nsppol==2) then
1378 : 1 : call timab(686,2,tsec) ! exc_build_ham(exch.spin)
1379 : 1 : block=3
1380 : 1 : neh1=BSp%nreh(1)
1381 : 1 : neh2=BSp%nreh(2)
1382 : : !
1383 : : ! The oscillators at q=0 are available on each node for both spin.
1384 : : ! Here the calculation of the block is parallelized over columns.
1385 [ - + + - : 3 : ABI_MALLOC(col_start,(0:nproc-1))
+ - + - -
+ - + ]
1386 [ - + + - : 2 : ABI_MALLOC(col_stop,(0:nproc-1))
- + - + ]
1387 : 1 : call xmpi_split_work2_i4b(neh2,nproc,col_start,col_stop)
1388 : :
1389 : 1 : my_cols(1) = col_start(my_rank)
1390 : 1 : my_cols(2) = col_stop (my_rank)
1391 [ - + ]: 1 : if (my_cols(2)-my_cols(1)<=0) then
1392 : 0 : ABI_ERROR("One of the processors has zero columns!")
1393 : : end if
1394 : :
1395 [ - + + - : 2 : ABI_MALLOC(ncols_of,(0:nproc-1))
- + - + ]
1396 [ + + ]: 2 : ncols_of=0
1397 [ + + ]: 2 : do rank=0,nproc-1
1398 [ + - ]: 2 : if (col_stop(rank)>=col_start(rank)) ncols_of(rank) = col_stop(rank)-col_start(rank)+1
1399 : : end do
1400 : :
1401 : 1 : ABI_FREE(col_start)
1402 : 1 : ABI_FREE(col_stop)
1403 : : !
1404 : : ! TODO might add treatment of <psi|q+G|psi> for q+G -> 0
1405 : : ! TODO might used enlarged G-sphere for better convergence.
1406 : : ! Note that my_kxssp is always written on file when nsppol=2, even when
1407 : : ! non-local field effects are neglected.
1408 [ - + + - : 4 : ABI_MALLOC(my_kxssp,(neh1,my_cols(1):my_cols(2)))
- + + - +
- + - - +
- + - + ]
1409 [ + + + + ]: 147841 : my_kxssp=czero
1410 : :
1411 [ + - ]: 1 : if (do_exchange_term) then
1412 : 1 : spin1=1; spin2=2
1413 : 1 : write(msg,'(a,2i2,a)')" Calculating exchange term for (spin1,spin2) ",spin1,spin2," ..."
1414 : 1 : call wrtout(std_out, msg)
1415 : :
1416 [ - + + - : 3 : ABI_MALLOC(rhotwg1,(npweps))
+ - + - -
+ - + ]
1417 [ - + + - : 2 : ABI_MALLOC(rhotwg2,(npweps))
- + - + ]
1418 : :
1419 : 1 : ngx = Gsph_x%ng
1420 [ - + + - : 3 : ABI_MALLOC(vc_sqrt_qbz,(ngx))
+ - + - -
+ - + ]
1421 : : !
1422 : : ! * Get iq_ibz, and symmetries from iq_bz.
1423 : 1 : iq_bz = iqbz0 ! q = 0 -> iqbz0
1424 : 1 : call qmesh%get_BZ_item(iq_bz,qbz,iq_ibz,isym_q,itim_q)
1425 : : !
1426 : : ! * Set up table of |q(BZ)+G|
1427 [ + - ]: 1 : if (iq_ibz==1) then
1428 [ + + ]: 170 : do ig=1,ngx
1429 : 169 : ISg = Gsph_x%rottb(ig,itim_q,isym_q)
1430 : 170 : vc_sqrt_qbz(ISg)=Vcp%vcqlwl_sqrt(ig,1)
1431 : : end do
1432 : : else
1433 : 0 : ABI_ERROR("iq_ibz should be 1")
1434 : : end if
1435 : :
1436 [ + + ]: 385 : do itp=1,neh2 ! Loop over transition tp = (kp,vp,cp,spin2)
1437 : :
1438 [ + - - + ]: 384 : if (itp<my_cols(1) .or. itp>my_cols(2)) CYCLE ! I dont have this column.
1439 : 384 : ene_tp = Bsp%Trans(itp,spin2)%en
1440 : 384 : ikp_bz = Bsp%Trans(itp,spin2)%k
1441 : 384 : ivp = Bsp%Trans(itp,spin2)%v
1442 : 384 : icp = Bsp%Trans(itp,spin2)%c
1443 : :
1444 : 384 : ikp_ibz = Kmesh%tab (ikp_bz)
1445 : 384 : isym_kp = Kmesh%tabo(ikp_bz)
1446 : 384 : itim_kp = (3-Kmesh%tabi(ikp_bz))/2
1447 : :
1448 [ + - ]: 384 : if (is_resonant) then
1449 : 384 : rhotwg2(:) = sym_rhotwgq0(itim_kp,isym_kp,dim_rtwg,npweps,rhxtwg_q0(:,ivp,icp,ikp_ibz,spin2),Gsph_c)
1450 : : else ! Code for coupling block.
1451 : 0 : rhotwg2(:) = sym_rhotwgq0(itim_kp,isym_kp,dim_rtwg,npweps,rhxtwg_q0(:,icp,ivp,ikp_ibz,spin2),Gsph_c)
1452 : : end if
1453 : : !
1454 : : ! Multiply by the Coulomb term.
1455 [ + + ]: 19584 : do ig=2,npweps
1456 : 19584 : rhotwg2(ig) = rhotwg2(ig) * vc_sqrt_qbz(ig) * vc_sqrt_qbz(ig)
1457 : : end do
1458 : :
1459 [ + + ]: 147841 : do it=1,neh1 ! Loop over transition t = (k,v,c,spin1) FULL matrix.
1460 : :
1461 : 147456 : ene_t = Bsp%Trans(it,spin1)%en
1462 : 147456 : ik_bz = Bsp%Trans(it,spin1)%k
1463 : 147456 : iv = Bsp%Trans(it,spin1)%v
1464 : 147456 : ic = Bsp%Trans(it,spin1)%c
1465 : :
1466 : 147456 : ik_ibz = Kmesh%tab(ik_bz)
1467 : 147456 : isym_k = Kmesh%tabo(ik_bz)
1468 : 147456 : itim_k = (3-Kmesh%tabi(ik_bz))/2
1469 : : !if (itim_k==2) CYCLE ! time-reversal or not
1470 : :
1471 : 147456 : rhotwg1(:) = sym_rhotwgq0(itim_k,isym_k,dim_rtwg,npweps,rhxtwg_q0(:,iv,ic,ik_ibz,spin1),Gsph_c)
1472 : : !
1473 : : ! sum over G/=0
1474 : 147456 : ctemp = XDOTC(npweps-1,rhotwg1(2:),1,rhotwg2(2:),1)
1475 : 147456 : ctemp = faq * kx_fact * ctemp
1476 : :
1477 : 147840 : my_kxssp(it,itp) = ctemp
1478 : : end do !it
1479 : : end do !itp
1480 : :
1481 [ - + ]: 1 : ABI_FREE(rhotwg1)
1482 [ - + ]: 1 : ABI_FREE(rhotwg2)
1483 [ - + ]: 1 : ABI_FREE(vc_sqrt_qbz)
1484 : : end if ! do_exchange_term
1485 : 1 : call timab(686,2,tsec) ! exc_build_ham(exch.spin)
1486 : : !
1487 : : ! =====================================
1488 : : ! === Write the Hamiltonian on disk ===
1489 : : ! =====================================
1490 : 1 : call timab(685,1,tsec) ! exc_build_ham(write_ham)
1491 : :
1492 : : if (use_mpiio) then
1493 : : #ifdef HAVE_MPI_IO
1494 : : my_ncols=ncols_of(my_rank); old_type=MPI_DOUBLE_COMPLEX
1495 : : call xmpio_create_fsubarray_2D((/neh1,my_ncols/),(/neh1,my_ncols/),(/1,1/),old_type,hmat_type,my_offpad,mpi_err)
1496 : : ABI_CHECK_MPI(mpi_err,"fsubarray_2D")
1497 : : !
1498 : : ! Each node uses a different offset to skip the header and the blocks written by the other CPUs.
1499 : : prev_nels=0
1500 : : prev_ncols=0
1501 : : if (my_rank>0) then
1502 : : prev_ncols = SUM(ncols_of(0:my_rank-1))
1503 : : prev_nels = neh1*prev_ncols
1504 : : end if
1505 : : tmp_off = prev_nels*xmpi_bsize_dpc + prev_ncols*2*xmpio_bsize_frm
1506 : :
1507 : : my_offset = offset_of_block(block) + tmp_off + my_offpad
1508 : :
1509 : : call MPI_FILE_SET_VIEW(mpi_fh, my_offset, MPI_BYTE, hmat_type, 'native', MPI_INFO_NULL, mpi_err)
1510 : : ABI_CHECK_MPI(mpi_err,"SET_VIEW")
1511 : :
1512 : : call MPI_TYPE_FREE(hmat_type,mpi_err)
1513 : : ABI_CHECK_MPI(mpi_err,"MPI_TYPE_FREE")
1514 : :
1515 : : tmp_size = INT(neh1*my_ncols)
1516 : : call MPI_FILE_WRITE_ALL(mpi_fh, my_kxssp,tmp_size, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpi_err)
1517 : : ABI_CHECK_MPI(mpi_err,"FILE_WRITE")
1518 : :
1519 : : ! It seems that personal calls in make the code stuck
1520 : : ! Master writes the Fortran record markers.
1521 : : ABI_MALLOC(bsize_frecord,(neh2))
1522 : : bsize_frecord = neh1 * xmpi_bsize_dpc
1523 : : ! ehdr_offset points to the end of the header.
1524 : : !call xmpio_write_frmarkers(mpi_fh,ehdr_offset,xmpio_collective,neh2,bsize_frecord,mpi_err)
1525 : : my_offset = offset_of_block(block)
1526 : : call xmpio_write_frmarkers(mpi_fh,my_offset,xmpio_collective,neh2,bsize_frecord,ierr)
1527 : : ABI_CHECK(ierr==0,"Error while writing Fortran markers")
1528 : : ABI_FREE(bsize_frecord)
1529 : : #else
1530 : : ABI_BUG("You should not be here")
1531 : : #endif
1532 : : else
1533 : : ! Use FORTRAN IO with sequential access mode.
1534 : : ! * Each node sends its data to master node.
1535 : : ! * Columns are distributed according to the rank of the node.
1536 [ + - ]: 1 : if (my_rank==master) then
1537 [ + + ]: 385 : do jj=my_cols(1),my_cols(2)
1538 : 385 : write(bsh_unt) my_kxssp(:,jj)
1539 : : end do
1540 [ - + ]: 1 : ABI_FREE(my_kxssp)
1541 : : end if
1542 : :
1543 : 1 : call xmpi_barrier(comm)
1544 : : !
1545 : : ! Collect data from the other nodes.
1546 [ - + ]: 1 : do sender=1,nproc-1
1547 : : ! If I'm not involved, jump to the end of the loop and wait there (sequential IO? Of course!)
1548 [ # # # # ]: 0 : if (all(my_rank /= [sender, master])) goto 200
1549 : :
1550 [ # # ]: 0 : if (my_rank==master) then
1551 [ # # # # : 0 : ABI_MALLOC(buffer_2d,(neh1,ncols_of(sender)))
# # # # #
# # # # #
# # # # ]
1552 : : end if
1553 : 0 : call xmpi_exch(my_kxssp,neh1*ncols_of(sender),sender,buffer_2d,master,comm,5,mpi_err)
1554 : : !
1555 [ # # ]: 0 : if (my_rank==master) then ! Write the columns owned by sender.
1556 [ # # ]: 0 : do jj=1,ncols_of(sender)
1557 : 0 : write(bsh_unt) buffer_2d(:,jj)
1558 : : end do
1559 [ # # ]: 0 : ABI_FREE(buffer_2d)
1560 : : end if ! master
1561 : : !
1562 : 1 : 200 call xmpi_barrier(comm)
1563 : : end do ! sender
1564 : : end if
1565 : 1 : call timab(685,2,tsec) ! exc_build_ham(write_ham)
1566 : :
1567 [ - + ]: 1 : ABI_FREE(ncols_of)
1568 [ - + ]: 1 : ABI_SFREE(my_kxssp)
1569 : : end if
1570 : :
1571 : : ! Close the file.
1572 : : if (use_mpiio) then
1573 : : #ifdef HAVE_MPI_IO
1574 : : call MPI_FILE_CLOSE(mpi_fh, mpi_err)
1575 : : ABI_CHECK_MPI(mpi_err,"FILE_CLOSE")
1576 : : ABI_FREE(offset_of_block)
1577 : : #endif
1578 : : end if
1579 : :
1580 : : ! master closes the Fortran files.
1581 [ + + ]: 23 : if (my_rank==master) then
1582 : 19 : close(bsh_unt)
1583 [ + + ]: 19 : if (BSp%prep_interp) then
1584 : 1 : close(a_unt)
1585 : 1 : close(b_unt)
1586 : 1 : close(c_unt)
1587 : : end if
1588 : : end if
1589 : :
1590 : : ! Free memory.
1591 [ - + ]: 23 : ABI_FREE(igfftg0)
1592 [ - + ]: 23 : ABI_FREE(ktabr_k)
1593 [ - + ]: 23 : ABI_FREE(id_tab)
1594 [ - + ]: 23 : ABI_FREE(ktabr_kp)
1595 [ - + ]: 23 : ABI_FREE(rhxtwg_vpv)
1596 [ - + ]: 23 : ABI_FREE(rhxtwg_cpc)
1597 [ + + ]: 23 : if (BSp%prep_interp) then
1598 [ - + ]: 1 : ABI_FREE(aa_vpv)
1599 [ - + ]: 1 : ABI_FREE(bb_vpv1)
1600 [ - + ]: 1 : ABI_FREE(bb_vpv2)
1601 [ - + ]: 1 : ABI_FREE(cc_vpv)
1602 [ - + ]: 1 : ABI_FREE(aa_cpc)
1603 [ - + ]: 1 : ABI_FREE(bb_cpc1)
1604 [ - + ]: 1 : ABI_FREE(bb_cpc2)
1605 [ - + ]: 1 : ABI_FREE(cc_cpc)
1606 : : end if
1607 [ - + ]: 23 : ABI_FREE(ur_ckp)
1608 [ - + ]: 23 : ABI_FREE(ur_vkp)
1609 [ - + ]: 23 : ABI_FREE(ur_vk)
1610 [ - + ]: 23 : ABI_FREE(ur_ck)
1611 : :
1612 : : ! Deallocation for PAW.
1613 [ + + ]: 23 : if (Wfd%usepaw==1) then
1614 : 2 : call pawcprj_free(Cp_vk)
1615 [ + - + + : 6 : ABI_FREE(Cp_vk)
- + - + -
+ ]
1616 : 2 : call pawcprj_free(Cp_ck)
1617 [ + - + + : 6 : ABI_FREE(Cp_ck)
- + - + -
+ ]
1618 : 2 : call pawcprj_free(Cp_ckp)
1619 [ + - + + : 6 : ABI_FREE(Cp_ckp)
- + - + -
+ ]
1620 : 2 : call pawcprj_free(Cp_vkp)
1621 [ + - + + : 6 : ABI_FREE(Cp_vkp)
- + - + -
+ ]
1622 : 2 : call pawcprj_free(Cp_tmp1)
1623 [ + - + + : 6 : ABI_FREE(Cp_tmp1)
- + - + -
+ ]
1624 : 2 : call pawcprj_free(Cp_tmp2)
1625 [ + - + + : 6 : ABI_FREE(Cp_tmp2)
- + - + -
+ ]
1626 : 2 : call pawcprj_free(Cp_tmp3)
1627 [ + - + + : 6 : ABI_FREE(Cp_tmp3)
- + - + -
+ ]
1628 : 2 : call pawcprj_free(Cp_tmp4)
1629 [ + - + + : 6 : ABI_FREE(Cp_tmp4)
- + - + -
+ ]
1630 : : end if
1631 : :
1632 : 23 : call xmpi_barrier(comm)
1633 : :
1634 : : DBG_EXIT("COLL")
1635 : :
1636 : 23 : call timab(680,2,tsec)
1637 : :
1638 [ - + - - : 46 : end subroutine exc_build_block
- - - + -
+ - + - +
- + - + -
- - - - -
- + - - -
- - - - +
- - - - -
- - + - -
- - - - -
+ - - - -
- - - + -
- - - - -
- + - - -
- - - - +
- - - - -
- - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + -
+ ]
1639 : : !!***
1640 : :
1641 : : !!****f* m_exc_build/exc_build_v
1642 : : !! NAME
1643 : : !! exc_build_v
1644 : : !!
1645 : : !! FUNCTION
1646 : : !! Calculate and write the excitonic Hamiltonian on an external binary file (Fortran file open
1647 : : !! in random mode) for subsequent treatment in the Bethe-Salpeter code.
1648 : : !!
1649 : : !! INPUTS
1650 : : !! BSp<excparam>=The parameters for the Bethe-Salpeter calculation.
1651 : : !! Cryst<crystal_t>=Info on the crystalline structure.
1652 : : !! Kmesh<kmesh_t>=The list of k-points in the BZ, IBZ and symmetry tables.
1653 : : !! Qmesh<kmesh_t>=The list of q-points for epsilon^{-1} and related symmetry tables.
1654 : : !! Gsph_x<gsphere_t>=Info on the G-sphere used to describe wavefunctions and W (the largest one is actually stored).
1655 : : !! Gsph_c<gsphere_t>=Info on the G-sphere used to describe the correlation part.
1656 : : !! Vcp<vcoul_t>=The Coulomb interaction in reciprocal space. A cutoff can be used
1657 : : !! rhxtwg_q0
1658 : : !! is_resonant
1659 : : !! comm=MPI communicator.
1660 : : !!
1661 : : !! OUTPUT
1662 : : !!
1663 : : !! NOTES
1664 : : !! *) Version for K_V = K_C (q=0), thus KP_V = KP_C
1665 : : !! *) No exchange limit: use DFT energies in case.
1666 : : !! *) Symmetry of H(-k-k') = H*(k k') not used.
1667 : : !! *) Coulomb term can be approximated as diagonal in G.
1668 : : !! *) Valence bands treated from lomo on.
1669 : : !! *) Symmetries of the sub-blocks are used to reduce the number of elements to calculate.
1670 : : !!
1671 : : !! ____________
1672 : : !! |_(cv)__(vc)_|
1673 : : !! H_exc = | R C |
1674 : : !! | -C* -R* |
1675 : : !!
1676 : : !! where C is symmetric and R is Hermitian provided that the QP energies are real.
1677 : : !!
1678 : : !! For nsppol=1 ==> R = diag-W+2v; C = -W+2v
1679 : : !! since the Hamiltonian can be diagonalized in the spin-singlet basis set thanks to
1680 : : !! the fact that spin triplet does not contribute to the optical limit of epsilon.
1681 : : !!
1682 : : !! For nsppol=2 ==> R = diag-W+v; C = -W+v
1683 : : !! Now the matrix elements depend on the spin of the transitions but only those
1684 : : !! transitions in which the spin of the electron and of the hole are equal contribute
1685 : : !! to the macroscopic dielectric function. Moreover only the exchange term can connect transitions of different spin.
1686 : : !! When nsppol==2 the transitions are ordered using | (cv up) | (cv dwn) | (vc up) | (vc down) |
1687 : : !!
1688 : : !! The resonant block is given by:
1689 : : !!
1690 : : !! | (v'c' up) | (v'c' dwn) |
1691 : : !! ----------------------------------- where v_{-+} = v_{+-}^H when the momentum of the photon is neglected.
1692 : : !! | [diag-W+v]++ | v+- | (vc up) Note that v_{+-} is not Hermitian due to the presence of different spins.
1693 : : !! R = ----------------------------------- Actually it reduces to a Hermitian matrix when the system is not spin polarized.
1694 : : !! | v-+ | [diag-W+v]-- | (vc dwn) but in this case one should use nsppol=1.
1695 : : !! ----------------------------------- As a consequence the entire matrix is calculated and stored on file.
1696 : : !!
1697 : : !! The coupling block is given by:
1698 : : !!
1699 : : !! | (c'v' up) | (c'v dwn) |
1700 : : !! ----------------------------------- where v_{-+} = v_{+-}^t when the momentum of the photon is neglected.
1701 : : !! | [-W+v]++ | v+- | (vc up) Also in this case the entire matrix v_{+-} has to be calculated
1702 : : !! C = ----------------------------------- and stored on file.
1703 : : !! | v-+ | [-W+v]-- | (vc dwn)
1704 : : !! -----------------------------------
1705 : : !!
1706 : : !! SOURCE
1707 : :
1708 : : subroutine exc_build_v(spin1,spin2,nsppol,npweps,Bsp,Cryst,Kmesh,Qmesh,Gsph_x,Gsph_c,Vcp,&
1709 : : & is_resonant,rhxtwg_q0,nproc,my_rank,t_start,t_stop,my_bsham)
1710 : :
1711 : : !Arguments ------------------------------------
1712 : : !scalars
1713 : : integer,intent(in) :: spin1,spin2,nsppol,npweps,nproc,my_rank
1714 : : logical,intent(in) :: is_resonant
1715 : : type(excparam),intent(in) :: BSp
1716 : : type(kmesh_t),intent(in) :: Kmesh,Qmesh
1717 : : type(crystal_t),intent(in) :: Cryst
1718 : : type(vcoul_t),intent(in) :: Vcp
1719 : : type(gsphere_t),intent(in) :: Gsph_x,Gsph_c
1720 : : !arrays
1721 : : integer(i8b),intent(in) :: t_start(0:nproc-1),t_stop(0:nproc-1)
1722 : : complex(gwp),intent(in) :: rhxtwg_q0(npweps,BSp%lomo_min:BSp%humo_max,BSp%lomo_min:BSp%humo_max,Kmesh%nibz,nsppol)
1723 : : complex(dp),intent(inout) :: my_bsham(t_start(my_rank):t_stop(my_rank))
1724 : :
1725 : : !Local variables ------------------------------
1726 : : !scalars
1727 : : integer :: ISg,ngx,ik_bz,ikp_bz,dim_rtwg
1728 : : integer :: neh1,neh2,ig,nblocks
1729 : : integer :: ik_ibz,itim_k,ikp_ibz,itim_kp,isym_k,isym_kp
1730 : : integer :: iq_bz,iq_ibz,isym_q,itim_q,iqbz0,rank
1731 : : integer :: iv,ivp,ic,icp
1732 : : integer :: block
1733 : : integer(i8b) :: tot_nels,ir,it,itp
1734 : : real(dp) :: faq,kx_fact
1735 : : complex(sp) :: ctemp
1736 : : character(len=500) :: msg
1737 : : !arrays
1738 : : integer :: bidx(2,4),spin_ids(2,3), my_cols(2),my_rows(2) !,proc_end(2),proc_start(2)
1739 : : integer(i8b) :: nels_block(3)
1740 : : integer,allocatable :: ncols_of(:), col_start(:),col_stop(:)
1741 : : real(dp) :: qbz(3),tsec(2) !kbz(3),kpbz(3),
1742 : : complex(dp),allocatable :: my_kxssp(:,:)
1743 : : complex(gwp),allocatable :: vc_sqrt_qbz(:),rhotwg1(:),rhotwg2(:)
1744 : : !************************************************************************
1745 : :
1746 : : DBG_ENTER("COLL")
1747 : :
1748 : : write(msg,'(a,2i2,a)')" Calculating exchange term for (spin1,spin2) ",spin1,spin2," ..."
1749 : : call wrtout(std_out, msg)
1750 : :
1751 : : ! Basic constants.
1752 : : dim_rtwg=1; faq = one/(Cryst%ucvol*Kmesh%nbz)
1753 : :
1754 : : ! Identify the index of q==0
1755 : : iqbz0=0
1756 : : do iq_bz=1,Qmesh%nbz
1757 : : if (ALL(ABS(Qmesh%bz(:,iq_bz))<tol3)) iqbz0 = iq_bz
1758 : : end do
1759 : : ABI_CHECK(iqbz0/=0,"q=0 not found")
1760 : : !
1761 : : ! Treat the spin polarization.
1762 : : spin_ids(:,1) = (/1,1/)
1763 : : spin_ids(:,2) = (/2,2/)
1764 : : spin_ids(:,3) = (/1,2/)
1765 : :
1766 : : nblocks=1
1767 : : kx_fact=two
1768 : : nels_block(:)=0
1769 : : nels_block(1)=BSp%nreh(1)*(BSp%nreh(1)+1_i8b)/2
1770 : : tot_nels=nels_block(1)
1771 : :
1772 : : if (nsppol==2) then
1773 : : nblocks=3
1774 : : kx_fact=one
1775 : : nels_block(1) = BSp%nreh(1)*(BSp%nreh(1)+1_i8b)/2 ! Only the upper triangle for block 1 and 2
1776 : : nels_block(2) = BSp%nreh(2)*(BSp%nreh(2)+1_i8b)/2
1777 : : nels_block(3) = BSp%nreh(1)*BSp%nreh(2)*1_i8b ! Note: Block 3 does not have symmetries.
1778 : : tot_nels= SUM(nels_block)
1779 : : end if
1780 : : !
1781 : : ! Distribute the calculation of the matrix elements among the nodes.
1782 : : ! * tstart and t_stop give the initial and final transition index treated by each node.
1783 : : ! * my_hsize is the number of transitions treated by this processor
1784 : : ! * my_cols(1:2) gives the initial and final column treated by this node.
1785 : : !
1786 : : do block=1,nsppol
1787 : : !
1788 : : ! Indices used to loop over bands.
1789 : : ! bidx contains the starting and final indices used to loop over bands.
1790 : : !
1791 : : ! (b3,b4)
1792 : : ! |... ...|
1793 : : ! (b1,b2) |... ...|
1794 : : !
1795 : : ! Resonant matrix is given by
1796 : : ! (v',c')
1797 : : ! |... ...|
1798 : : ! (v,c) |... ...|
1799 : : !
1800 : : ! Coupling matrix is given by
1801 : : ! (c',v')
1802 : : ! |... ...|
1803 : : ! (v,c) |... ...|
1804 : :
1805 : : if (is_resonant) then
1806 : : bidx(:,1) = [BSp%lomo_spin(block),BSp%homo_spin(block)] ! range for b1
1807 : : bidx(:,2) = [BSp%lumo_spin(block),BSp%humo_spin(block)] ! range for b2
1808 : : bidx(:,3) = [BSp%lomo_spin(block),BSp%homo_spin(block)] ! range for b3
1809 : : bidx(:,4) = [BSp%lumo_spin(block),BSp%humo_spin(block)] ! range for b4
1810 : : else
1811 : : bidx(:,1) = [BSp%lomo_spin(block),BSp%homo_spin(block)] ! range for b1
1812 : : bidx(:,2) = [BSp%lumo_spin(block),BSp%humo_spin(block)] ! range for b2
1813 : : bidx(:,3) = [BSp%lumo_spin(block),BSp%humo_spin(block)] ! range for b3
1814 : : bidx(:,4) = [BSp%lomo_spin(block),BSp%homo_spin(block)] ! range for b4
1815 : : end if
1816 : :
1817 : : !spin1 = spin_ids(1,block)
1818 : : !spin2 = spin_ids(2,block)
1819 : :
1820 : : my_cols=0
1821 : : do itp=1,Bsp%nreh(block)
1822 : : do it=1,itp
1823 : : ir = it + itp*(itp-1_i8b)/2
1824 : : if (ir==t_start(my_rank)) then
1825 : : my_rows(1) = it
1826 : : my_cols(1) = itp
1827 : : end if
1828 : : if (ir==t_stop(my_rank)) then
1829 : : my_rows(2) = it
1830 : : my_cols(2) = itp
1831 : : end if
1832 : : end do
1833 : : end do
1834 : :
1835 : : ! Allocate big (scalable) buffer to store the BS matrix on this node.
1836 : : !ABI_MALLOC(my_bsham,(t_start(my_rank):t_stop(my_rank)))
1837 : : !
1838 : : ! =====================
1839 : : ! === Exchange term ===
1840 : : ! =====================
1841 : : ! TODO might add treatment of <psi|q+G|psi> for q+G -> 0
1842 : : ! TODO might used enlarged G-sphere for better convergence.
1843 : : !if (do_exchange_term) then
1844 : : call timab(683,1,tsec) ! exc_build_ham(exchange)
1845 : :
1846 : : ABI_MALLOC(rhotwg1,(npweps))
1847 : : ABI_MALLOC(rhotwg2,(npweps))
1848 : :
1849 : : ngx = Gsph_x%ng
1850 : : ABI_MALLOC(vc_sqrt_qbz,(ngx))
1851 : :
1852 : : ! * Get iq_ibz, and symmetries from iq_bz.
1853 : : iq_bz = iqbz0 ! q = 0 -> iqbz0
1854 : : call qmesh%get_BZ_item(iq_bz,qbz,iq_ibz,isym_q,itim_q)
1855 : :
1856 : : ! * Set up table of |q(BZ)+G|
1857 : : if (iq_ibz==1) then
1858 : : do ig=1,ngx
1859 : : ISg = Gsph_x%rottb(ig,itim_q,isym_q)
1860 : : vc_sqrt_qbz(ISg)=Vcp%vcqlwl_sqrt(ig,1)
1861 : : end do
1862 : : else
1863 : : ABI_ERROR("iq_ibz should be 1")
1864 : : end if
1865 : :
1866 : : do itp=1,BSp%nreh(block) ! Loop over transition tp = (kp,vp,cp,spin2)
1867 : :
1868 : : if (itp<my_cols(1) .or. itp>my_cols(2)) CYCLE ! I dont have this column.
1869 : : ikp_bz = Bsp%Trans(itp,spin2)%k
1870 : : ivp = Bsp%Trans(itp,spin2)%v
1871 : : icp = Bsp%Trans(itp,spin2)%c
1872 : :
1873 : : ikp_ibz = Kmesh%tab (ikp_bz)
1874 : : isym_kp = Kmesh%tabo(ikp_bz)
1875 : : itim_kp = (3-Kmesh%tabi(ikp_bz))/2
1876 : :
1877 : : if (is_resonant) then
1878 : : rhotwg2(:) = sym_rhotwgq0(itim_kp,isym_kp,dim_rtwg,npweps,rhxtwg_q0(:,ivp,icp,ikp_ibz,spin2),Gsph_c)
1879 : : else ! Code for coupling block.
1880 : : rhotwg2(:) = sym_rhotwgq0(itim_kp,isym_kp,dim_rtwg,npweps,rhxtwg_q0(:,icp,ivp,ikp_ibz,spin2),Gsph_c)
1881 : : end if
1882 : : !
1883 : : ! Multiply by the Coulomb term.
1884 : : do ig=2,npweps
1885 : : rhotwg2(ig) = rhotwg2(ig) * vc_sqrt_qbz(ig) * vc_sqrt_qbz(ig)
1886 : : end do
1887 : :
1888 : : do it=1,itp ! Loop over transition t = (k,v,c,spin1)
1889 : : ir = it + itp*(itp-1_i8b)/2
1890 : : if (ir<t_start(my_rank) .or. ir>t_stop(my_rank)) CYCLE
1891 : :
1892 : : ik_bz = Bsp%Trans(it,spin1)%k
1893 : : iv = Bsp%Trans(it,spin1)%v
1894 : : ic = Bsp%Trans(it,spin1)%c
1895 : :
1896 : : ik_ibz = Kmesh%tab(ik_bz)
1897 : : isym_k = Kmesh%tabo(ik_bz)
1898 : : itim_k = (3-Kmesh%tabi(ik_bz))/2
1899 : : !if (itim_k==2) CYCLE ! time-reversal or not
1900 : :
1901 : : rhotwg1(:) = sym_rhotwgq0(itim_k,isym_k,dim_rtwg,npweps,rhxtwg_q0(:,iv,ic,ik_ibz,spin1),Gsph_c)
1902 : : !
1903 : : ! sum over G/=0
1904 : : ctemp = xdotc(npweps-1,rhotwg1(2:),1,rhotwg2(2:),1)
1905 : : ctemp = faq * kx_fact * ctemp
1906 : :
1907 : : ! exchange term is non divergent !
1908 : : !if (BSp%prep_interp) then
1909 : : ! ccoeffs(ir) = ccoeffs(ir) + ctemp
1910 : : !end if
1911 : :
1912 : : my_bsham(ir) = my_bsham(ir) + ctemp
1913 : : end do !it
1914 : : end do !itp
1915 : :
1916 : : ABI_FREE(rhotwg1)
1917 : : ABI_FREE(rhotwg2)
1918 : : ABI_FREE(vc_sqrt_qbz)
1919 : :
1920 : : call timab(683,2,tsec) ! exc_build_ham(exchange)
1921 : : !end if ! do_exchange_term
1922 : : end do ! block
1923 : :
1924 : : !
1925 : : ! ===========================================
1926 : : ! === Exchange term for spin_up spin_down ===
1927 : : ! ===========================================
1928 : :
1929 : : if (nsppol==2) then
1930 : : call timab(686,2,tsec) ! exc_build_ham(exch.spin)
1931 : : block=3
1932 : : neh1=BSp%nreh(1)
1933 : : neh2=BSp%nreh(2)
1934 : : !
1935 : : ! The oscillators at q=0 are available on each node for both spin.
1936 : : ! Here the calculation of the block is parallelized over columns.
1937 : : ABI_MALLOC(col_start,(0:nproc-1))
1938 : : ABI_MALLOC(col_stop,(0:nproc-1))
1939 : : call xmpi_split_work2_i4b(neh2,nproc,col_start,col_stop) !check this but it should be OK.
1940 : :
1941 : : my_cols(1) = col_start(my_rank)
1942 : : my_cols(2) = col_stop (my_rank)
1943 : : if (my_cols(2)-my_cols(1)<=0) then
1944 : : ABI_ERROR("One of the processors has zero columns!")
1945 : : end if
1946 : :
1947 : : ABI_MALLOC(ncols_of,(0:nproc-1))
1948 : : ncols_of=0
1949 : : do rank=0,nproc-1
1950 : : if (col_stop(rank)>=col_start(rank)) ncols_of(rank) = col_stop(rank)-col_start(rank)+1
1951 : : end do
1952 : :
1953 : : ABI_FREE(col_start)
1954 : : ABI_FREE(col_stop)
1955 : : !
1956 : : ! TODO might add treatment of <psi|q+G|psi> for q+G -> 0
1957 : : ! TODO might used enlarged G-sphere for better convergence.
1958 : : ! Note that my_kxssp is always written on file when nsppol=2, even when
1959 : : ! non-local field effects are neglected.
1960 : : ABI_MALLOC(my_kxssp,(neh1,my_cols(1):my_cols(2)))
1961 : : my_kxssp=czero
1962 : :
1963 : : !if (do_exchange_term) then
1964 : : !spin1=1; spin2=2
1965 : : ABI_MALLOC(rhotwg1,(npweps))
1966 : : ABI_MALLOC(rhotwg2,(npweps))
1967 : :
1968 : : ngx = Gsph_x%ng
1969 : : ABI_MALLOC(vc_sqrt_qbz,(ngx))
1970 : : !
1971 : : ! * Get iq_ibz, and symmetries from iq_bz.
1972 : : iq_bz = iqbz0 ! q = 0 -> iqbz0
1973 : : call qmesh%get_BZ_item(iq_bz,qbz,iq_ibz,isym_q,itim_q)
1974 : : !
1975 : : ! * Set up table of |q(BZ)+G|
1976 : : if (iq_ibz==1) then
1977 : : do ig=1,ngx
1978 : : ISg = Gsph_x%rottb(ig,itim_q,isym_q)
1979 : : vc_sqrt_qbz(ISg)=Vcp%vcqlwl_sqrt(ig,1)
1980 : : end do
1981 : : else
1982 : : ABI_ERROR("iq_ibz should be 1")
1983 : : end if
1984 : :
1985 : : do itp=1,neh2 ! Loop over transition tp = (kp,vp,cp,spin2)
1986 : :
1987 : : if (itp<my_cols(1) .or. itp>my_cols(2)) CYCLE ! I dont have this column.
1988 : : ikp_bz = Bsp%Trans(itp,spin2)%k
1989 : : ivp = Bsp%Trans(itp,spin2)%v
1990 : : icp = Bsp%Trans(itp,spin2)%c
1991 : :
1992 : : ikp_ibz = Kmesh%tab (ikp_bz)
1993 : : isym_kp = Kmesh%tabo(ikp_bz)
1994 : : itim_kp = (3-Kmesh%tabi(ikp_bz))/2
1995 : :
1996 : : if (is_resonant) then
1997 : : rhotwg2(:) = sym_rhotwgq0(itim_kp,isym_kp,dim_rtwg,npweps,rhxtwg_q0(:,ivp,icp,ikp_ibz,spin2),Gsph_c)
1998 : : else ! Code for coupling block.
1999 : : rhotwg2(:) = sym_rhotwgq0(itim_kp,isym_kp,dim_rtwg,npweps,rhxtwg_q0(:,icp,ivp,ikp_ibz,spin2),Gsph_c)
2000 : : end if
2001 : : !
2002 : : ! Multiply by the Coulomb term.
2003 : : do ig=2,npweps
2004 : : rhotwg2(ig) = rhotwg2(ig) * vc_sqrt_qbz(ig) * vc_sqrt_qbz(ig)
2005 : : end do
2006 : :
2007 : : do it=1,neh1 ! Loop over transition t = (k,v,c,spin1) FULL matrix.
2008 : : ik_bz = Bsp%Trans(it,spin1)%k
2009 : : iv = Bsp%Trans(it,spin1)%v
2010 : : ic = Bsp%Trans(it,spin1)%c
2011 : :
2012 : : ik_ibz = Kmesh%tab(ik_bz)
2013 : : isym_k = Kmesh%tabo(ik_bz)
2014 : : itim_k = (3-Kmesh%tabi(ik_bz))/2
2015 : : !if (itim_k==2) CYCLE ! time-reversal or not
2016 : :
2017 : : rhotwg1(:) = sym_rhotwgq0(itim_k,isym_k,dim_rtwg,npweps,rhxtwg_q0(:,iv,ic,ik_ibz,spin1),Gsph_c)
2018 : : !
2019 : : ! sum over G/=0
2020 : : ctemp = XDOTC(npweps-1,rhotwg1(2:),1,rhotwg2(2:),1)
2021 : : ctemp = faq * kx_fact * ctemp
2022 : :
2023 : : my_kxssp(it,itp) = ctemp
2024 : : end do !it
2025 : : end do !itp
2026 : :
2027 : : ABI_FREE(rhotwg1)
2028 : : ABI_FREE(rhotwg2)
2029 : : ABI_FREE(vc_sqrt_qbz)
2030 : : !end if ! do_exchange_term
2031 : : call timab(686,2,tsec) ! exc_build_ham(exch.spin)
2032 : :
2033 : : ABI_FREE(ncols_of)
2034 : : ABI_SFREE(my_kxssp)
2035 : : end if
2036 : :
2037 : : DBG_EXIT("COLL")
2038 : :
2039 : : end subroutine exc_build_v
2040 : : !!***
2041 : :
2042 : : !!****f* m_exc_build/exc_build_ham
2043 : : !! NAME
2044 : : !! exc_build_ham
2045 : : !!
2046 : : !! FUNCTION
2047 : : !! Calculate and write the excitonic Hamiltonian on an external binary file (Fortran binary file)
2048 : : !! for subsequent treatment in the Bethe-Salpeter code.
2049 : : !!
2050 : : !! INPUTS
2051 : : !! BSp<excparam>=The parameters for the Bethe-Salpeter calculation.
2052 : : !! BS_files<excfiles>=File names internally used in the BS code.
2053 : : !! Cryst<crystal_t>=Info on the crystalline structure.
2054 : : !! Kmesh<kmesh_t>=The list of k-points in the BZ, IBZ and symmetry tables.
2055 : : !! Qmesh<kmesh_t>=The list of q-points for epsilon^{-1} and related symmetry tables.
2056 : : !! ktabr(nfftot_osc,BSp%nkbz)=The FFT index of $(R^{-1}(r-\tau))$ where R is symmetry needed to obtains
2057 : : !! the k-points from the irreducible image. Used to symmetrize u_Sk where S = \transpose R^{-1}
2058 : : !! Gsph_x<gsphere_t>=Info on the G-sphere used to describe wavefunctions and W (the largest one is actually stored).
2059 : : !! Gsph_c<gsphere_t>=Info on the G-sphere used to describe the correlation part.
2060 : : !! Vcp<vcoul_t>=The Coulomb interaction in reciprocal space. A cutoff can be used
2061 : : !! screen<screen_t>=Data type gathering info and data for W.
2062 : : !! nfftot_osc=Total Number of FFT points used for the oscillator matrix elements.
2063 : : !! ngfft_osc(18)=Info on the FFT algorithm used to calculate the oscillator matrix elements.
2064 : : !! Psps<Pseudopotential_type>=Variables related to pseudopotentials
2065 : : !! Pawtab(Psps%ntypat)<pawtab_type>=PAW tabulated starting data.
2066 : : !! Pawang<pawang_type>=PAW angular mesh and related data.
2067 : : !! Paw_pwff(Cryst%ntypat*Wfd%usepaw)<pawpwff_t>=Form factor used to calculate the onsite mat. elements of a plane wave.
2068 : : !! Wfd<wfdgw_t>=Handler for the wavefunctions.
2069 : : !!
2070 : : !! OUTPUT
2071 : : !! The excitonic Hamiltonian is saved on an external binary file (see below).
2072 : : !!
2073 : : !! SOURCE
2074 : :
2075 : 29 : subroutine exc_build_ham(BSp,BS_files,Cryst,Kmesh,Qmesh,ktabr,Gsph_x,Gsph_c,Vcp,&
2076 : 29 : Wfd,screen,Hdr_bse,nfftot_osc,ngfft_osc,Psps,Pawtab,Pawang,Paw_pwff)
2077 : :
2078 : : !Arguments ------------------------------------
2079 : : !scalars
2080 : : integer,intent(in) :: nfftot_osc
2081 : : type(excparam),intent(in) :: BSp
2082 : : type(excfiles),intent(in) :: BS_files
2083 : : type(screen_t),intent(inout) :: screen
2084 : : type(kmesh_t),intent(in) :: Kmesh,Qmesh
2085 : : type(crystal_t),intent(in) :: Cryst
2086 : : type(vcoul_t),intent(in) :: Vcp
2087 : : type(gsphere_t),intent(in) :: Gsph_x,Gsph_c
2088 : : type(Pseudopotential_type),intent(in) :: Psps
2089 : : type(Hdr_type),intent(inout) :: Hdr_bse
2090 : : type(pawang_type),intent(in) :: Pawang
2091 : : type(wfdgw_t),target,intent(inout) :: Wfd
2092 : : !arrays
2093 : : integer,intent(in) :: ngfft_osc(18)
2094 : : integer,intent(in) :: ktabr(nfftot_osc,Kmesh%nbz)
2095 : : type(Pawtab_type),intent(in) :: Pawtab(Psps%ntypat*Wfd%usepaw)
2096 : : type(pawpwff_t),intent(in) :: Paw_pwff(Psps%ntypat*Wfd%usepaw)
2097 : :
2098 : : !Local variables ------------------------------
2099 : : !scalars
2100 : : logical :: do_resonant,do_coupling
2101 : : !character(len=500) :: msg
2102 : : !arrays
2103 : : real(dp) :: tsec(2)
2104 : 29 : complex(gwp),allocatable :: all_mgq0(:,:,:,:,:)
2105 : : !************************************************************************
2106 : :
2107 : 29 : call timab(670,1,tsec)
2108 : :
2109 [ - + ]: 29 : ABI_CHECK(Wfd%nspinor==1,"nspinor==2 not coded")
2110 [ + + - + ]: 116 : ABI_CHECK(nfftot_osc==PRODUCT(ngfft_osc(1:3)),"mismatch in FFT size")
2111 : :
2112 [ - + ]: 29 : if (BSp%have_complex_ene) then
2113 : 0 : ABI_ERROR("Complex energies are not supported yet")
2114 : : end if
2115 : :
2116 : : ! Do we have to compute some block?
2117 : 29 : do_resonant = (BS_files%in_hreso == BSE_NOFILE)
2118 : 29 : do_coupling = (BS_files%in_hcoup == BSE_NOFILE)
2119 : :
2120 [ + + ]: 29 : if (BSp%use_coupling == 0) then
2121 [ + + ]: 28 : if (.not.do_resonant) then
2122 : 6 : call wrtout(std_out,"Will skip the calculation of resonant block (will use BSR file)")
2123 : 6 : goto 100
2124 : : end if
2125 : : else
2126 [ - + ]: 1 : if (.not. do_resonant .and. .not. do_coupling) then
2127 : 0 : call wrtout(std_out,"Will skip the calculation of both resonant and coupling block (will use BSR and BSC files)")
2128 : 0 : goto 100
2129 : : end if
2130 : : end if
2131 : :
2132 : : ! Compute M_{k,q=0}^{b,b}(G) for all k-points in the IBZ and each pair b, b'
2133 : : ! used for the exchange part and part of the Coulomb term.
2134 : 23 : call wrtout(std_out," Calculating all matrix elements for q=0 to save CPU time")
2135 : :
2136 : : call wfd_all_mgq0(Wfd,Cryst,Qmesh,Gsph_x,Vcp,Psps,Pawtab,Paw_pwff,&
2137 : 23 : Bsp%lomo_spin,Bsp%homo_spin,Bsp%humo_spin,nfftot_osc,ngfft_osc,Bsp%npweps,all_mgq0)
2138 : :
2139 : : ! ========================
2140 : : ! ==== Resonant Block ====
2141 : : ! ========================
2142 [ + + ]: 23 : if (do_resonant) then
2143 : 22 : call timab(672,1,tsec)
2144 : : call exc_build_block(BSp,Cryst,Kmesh,Qmesh,ktabr,Gsph_x,Gsph_c,Vcp,&
2145 : 22 : Wfd,screen,Hdr_bse,nfftot_osc,ngfft_osc,Psps,Pawtab,Pawang,Paw_pwff,all_mgq0,.TRUE.,BS_files%out_hreso)
2146 : 22 : call timab(672,2,tsec)
2147 : : end if
2148 : :
2149 : : ! ========================
2150 : : ! ==== Coupling Block ====
2151 : : ! ========================
2152 [ + - + + ]: 23 : if (do_coupling .and. BSp%use_coupling > 0) then
2153 : 1 : call timab(673,1,tsec)
2154 : : call exc_build_block(BSp,Cryst,Kmesh,Qmesh,ktabr,Gsph_x,Gsph_c,Vcp,&
2155 : 1 : Wfd,screen,Hdr_bse,nfftot_osc,ngfft_osc,Psps,Pawtab,Pawang,Paw_pwff,all_mgq0,.FALSE.,BS_files%out_hcoup)
2156 : 1 : call timab(673,2,tsec)
2157 : : end if
2158 : :
2159 : : ! Free memory.
2160 [ - + ]: 23 : ABI_FREE(all_mgq0)
2161 : :
2162 : 29 : 100 call timab(670,2,tsec)
2163 : :
2164 [ - + ]: 29 : end subroutine exc_build_ham
2165 : : !!***
2166 : :
2167 : : !!****f* m_exc_build/wfd_all_mgq0
2168 : : !! NAME
2169 : : !! wfd_all_mgq0
2170 : : !!
2171 : : !! FUNCTION
2172 : : !!
2173 : : !! INPUTS
2174 : : !! Wfd<wfdgw_t>=Handler for the wavefunctions.
2175 : : !! Cryst<crystal_t>=Info on the crystalline structure.
2176 : : !! Qmesh<kmesh_t>=The list of q-points for epsilon^{-1} and related symmetry tables.
2177 : : !! Gsph_x<gsphere_t>=G-sphere with the G-vectors in mgq0.
2178 : : !! Vcp<vcoul_t>=The Coulomb interaction in reciprocal space. A cutoff can be used
2179 : : !! Psps<Pseudopotential_type>=Variables related to pseudopotentials
2180 : : !! Pawtab(Psps%ntypat)<pawtab_type>=PAW tabulated starting data.
2181 : : !! Paw_pwff(Cryst%ntypat*Wfd%usepaw)<pawpwff_t>=Form factor used to calculate the onsite mat. elements of a plane wave.
2182 : : !! lomo_spin(Wfd%nsppol)=Lowest occupied band for each spin
2183 : : !! homo_spin(Wfd%nsppol)=Highest occupied band for each spin
2184 : : !! humo_spin(Wfd%nsppol)=Highest unoccupied band for each spin
2185 : : !! nfftot_osc=Total Number of FFT points used for the oscillator matrix elements.
2186 : : !! ngfft_osc(18)=Info on the FFT algorithm used to calculate the oscillator matrix elements.
2187 : : !! npweps=Number of G-vectors in mgq0.
2188 : : !!
2189 : : !! OUTPUT
2190 : : !! mgq0(npweps,lomo_min:humo_max,lomo_min:humo_max,Wfd%nkibz,Wfd%nsppol)
2191 : : !! Allocated here and filled with the matrix elements on each node.
2192 : : !!
2193 : : !! SOURCE
2194 : :
2195 : 23 : subroutine wfd_all_mgq0(Wfd,Cryst,Qmesh,Gsph_x,Vcp,&
2196 : 23 : & Psps,Pawtab,Paw_pwff,lomo_spin,homo_spin,humo_spin,nfftot_osc,ngfft_osc,npweps,mgq0)
2197 : :
2198 : : !Arguments ------------------------------------
2199 : : !scalars
2200 : : integer,intent(in) :: nfftot_osc,npweps
2201 : : type(kmesh_t),intent(in) :: Qmesh
2202 : : type(crystal_t),intent(in) :: Cryst
2203 : : type(vcoul_t),intent(in) :: Vcp
2204 : : type(gsphere_t),intent(in) :: Gsph_x
2205 : : type(Pseudopotential_type),intent(in) :: Psps
2206 : : type(wfdgw_t),target,intent(inout) :: Wfd
2207 : : !arrays
2208 : : integer,intent(in) :: lomo_spin(Wfd%nsppol),homo_spin(Wfd%nsppol),humo_spin(Wfd%nsppol)
2209 : : integer,intent(in) :: ngfft_osc(18)
2210 : : complex(gwp),allocatable,intent(out) :: mgq0(:,:,:,:,:)
2211 : : type(Pawtab_type),intent(in) :: Pawtab(Psps%ntypat)
2212 : : type(pawpwff_t),intent(in) :: Paw_pwff(Psps%ntypat*Wfd%usepaw)
2213 : :
2214 : : !Local variables ------------------------------
2215 : : !scalars
2216 : : integer,parameter :: map2sphere1=1,dim_rtwg1=1,ndat1=1
2217 : : integer :: use_padfft,mgfft_osc,fftalga_osc,ii
2218 : : integer :: ik_ibz,itim_k,isym_k,iq_bz,iq_ibz,isym_q,itim_q,iqbz0
2219 : : integer :: ierr,iv,ic,spin,lomo_min,humo_max !,inv_ipw,ipw
2220 : : real(dp) :: cpu,wall,gflops !q0vol,fcc_const
2221 : : complex(dp) :: ph_mkt
2222 : : character(len=500) :: msg
2223 : : type(wave_t),pointer :: wave_v, wave_c
2224 : : !arrays
2225 : 23 : integer,allocatable :: igfftg0(:),task_distrib(:,:,:,:)
2226 : 23 : integer,allocatable :: gbound(:,:),id_tab(:)
2227 : : real(dp) :: qbz(3),spinrot_k(4),tsec(2)
2228 : 23 : complex(gwp),allocatable :: rhotwg1(:)
2229 : 23 : complex(gwp),target,allocatable :: ur1(:),ur2(:)
2230 : 23 : complex(gwp),contiguous, pointer :: ptr_ur1(:),ptr_ur2(:)
2231 : 23 : type(pawcprj_type),allocatable :: Cp1(:,:),Cp2(:,:)
2232 : 23 : type(pawpwij_t),allocatable :: Pwij_q0(:)
2233 : : !************************************************************************
2234 : :
2235 : 23 : call timab(671,1,tsec)
2236 : :
2237 [ - + ]: 23 : ABI_CHECK(Wfd%nspinor==1,"nspinor==2 not coded")
2238 [ + + - + ]: 92 : ABI_CHECK(nfftot_osc==PRODUCT(ngfft_osc(1:3)),"mismatch in FFT size")
2239 : :
2240 [ + + + + ]: 71 : lomo_min = MINVAL(lomo_spin); humo_max = MAXVAL(humo_spin)
2241 : :
2242 [ + + + + : 50 : if ( ANY(ngfft_osc(1:3) /= Wfd%ngfft(1:3)) ) call wfd%change_ngfft(Cryst,Psps,ngfft_osc)
+ + ]
2243 : :
2244 [ + + ]: 92 : mgfft_osc = MAXVAL(ngfft_osc(1:3))
2245 : 23 : fftalga_osc = ngfft_osc(7)/100 !; fftalgc_osc=MOD(ngfft_osc(7),10)
2246 : :
2247 : : ! (temporary) Table used for the wavefunction in the IBZ.
2248 [ - + + - : 69 : ABI_MALLOC(id_tab, (Wfd%nfft))
+ - + - -
+ - + ]
2249 [ - + + + : 482671 : id_tab = (/(ii, ii=1,Wfd%nfft)/)
+ - + + +
- - + - -
+ + ]
2250 : :
2251 : : ! Analytic integration of 4pi/q^2 over the volume element:
2252 : : ! $4pi/V \int_V d^3q 1/q^2 =4pi bz_geometric_factor V^(-2/3)$
2253 : : ! i_sz=4*pi*bz_geometry_factor*q0_vol**(-two_thirds) where q0_vol= V_BZ/N_k
2254 : : ! bz_geometry_factor: sphere=7.79, fcc=7.44, sc=6.188, bcc=6.946, wz=5.255
2255 : : ! (see gwa.pdf, appendix A.4)
2256 : :
2257 : : ! If q=0 and C=V then set up rho-twiddle(G=0) to reflect an
2258 : : ! analytic integration of q**-2 over the volume element:
2259 : : ! <q**-2> = 7.44 V**(-2/3) (for fcc cell)
2260 : :
2261 : : ! q0vol = (8.0*pi**3) / (Cryst%ucvol*Kmesh%nbz)
2262 : : ! fcc_const = SQRT(7.44*q0vol**(-2.0/3.0))
2263 : : ! rtw = (6.0*pi**2/(Cryst%ucvol*Kmesh%nkbz))**(1./3.)
2264 : : ! Average of (q+q')**-2 integration for head of Coulomb matrix
2265 : : ! INTRTW(QL) = (2*pi*rtw + pi*(rtw**2/QL-QL)*LOG((QL+rtw)/(QL-rtw)))
2266 : : ! & * (Cryst%ucvol*Kmesh%nbz)/(2*pi)**3. * QL*QL
2267 : :
2268 [ + + ]: 23 : if (Wfd%usepaw==1) then
2269 [ - + + - : 14 : ABI_MALLOC(Cp1,(Wfd%natom,Wfd%nspinor))
- + + - +
- + - - +
- + + + +
+ ]
2270 : 2 : call pawcprj_alloc(Cp1,0,Wfd%nlmn_atm)
2271 [ - + + - : 14 : ABI_MALLOC(Cp2,(Wfd%natom,Wfd%nspinor))
- + + - +
- + - - +
- + + + +
+ ]
2272 : 2 : call pawcprj_alloc(Cp2,0,Wfd%nlmn_atm)
2273 : : end if
2274 : :
2275 [ - + + - : 69 : ABI_MALLOC(ur1,(nfftot_osc*Wfd%nspinor))
+ - + - -
+ - + ]
2276 [ - + + - : 46 : ABI_MALLOC(ur2,(nfftot_osc*Wfd%nspinor))
- + - + ]
2277 : :
2278 : : ! Identify q==0
2279 : 23 : iqbz0=0
2280 [ + + ]: 1079 : do iq_bz=1,Qmesh%nbz
2281 [ + + + + : 1446 : if (ALL(ABS(Qmesh%bz(:,iq_bz))<tol3)) iqbz0 = iq_bz
+ + ]
2282 : : end do
2283 [ - + ]: 23 : ABI_CHECK(iqbz0/=0,"q=0 not found in q-point list!")
2284 : :
2285 : : ! * Get iq_ibz, and symmetries from iqbz0.
2286 : 23 : call qmesh%get_BZ_item(iqbz0,qbz,iq_ibz,isym_q,itim_q)
2287 : :
2288 [ + + ]: 23 : if (Wfd%usepaw==1) then ! Prepare onsite contributions at q==0
2289 [ - + + - : 9 : ABI_MALLOC(Pwij_q0,(Cryst%ntypat))
+ - + - -
+ - + +
+ ]
2290 : 2 : call pawpwij_init(Pwij_q0,npweps,Qmesh%bz(:,iqbz0),Gsph_x%gvec,Cryst%rprimd,Psps,Pawtab,Paw_pwff)
2291 : : end if
2292 : : !
2293 : : ! Tables for the FFT of the oscillators.
2294 : : ! a) FFT index of the G sphere (only vertical transitions, unlike cchi0, no need to shift the sphere).
2295 : : ! b) gbound table for the zero-padded FFT performed in rhotwg.
2296 [ - + + - : 69 : ABI_MALLOC(igfftg0,(Gsph_x%ng))
+ - + - -
+ - + ]
2297 [ + - - + : 92 : ABI_MALLOC(gbound,(2*mgfft_osc+8,2))
+ - + - +
- + - - +
- + ]
2298 : 23 : call Gsph_x%fft_tabs((/0,0,0/),mgfft_osc,ngfft_osc,use_padfft,gbound,igfftg0)
2299 [ - + ]: 23 : if ( ANY(fftalga_osc == (/2,4/)) ) use_padfft=0 ! Pad-FFT is not coded in rho_tw_g
2300 [ - + ]: 23 : if (use_padfft==0) then
2301 [ # # ]: 0 : ABI_FREE(gbound)
2302 [ # # # # : 0 : ABI_MALLOC(gbound,(2*mgfft_osc+8,2*use_padfft))
# # # # ]
2303 : : end if
2304 : :
2305 [ - + + - : 69 : ABI_MALLOC(rhotwg1,(npweps))
+ - + - -
+ - + ]
2306 : :
2307 [ - + + - : 161 : ABI_MALLOC_OR_DIE(mgq0, (npweps,lomo_min:humo_max,lomo_min:humo_max,Wfd%nkibz,Wfd%nsppol), ierr)
- + + - -
+ + - - +
+ - - + +
- + - + -
+ - + - -
+ + - -
+ ]
2308 [ + + + + : 1317080 : mgq0 = czero
+ + + + +
+ ]
2309 : :
2310 : 23 : call cwtime(cpu,wall,gflops,"start")
2311 : :
2312 [ + + ]: 47 : do spin=1,Wfd%nsppol
2313 : : ! Distribute the calculation of the matrix elements.
2314 : : ! processors have the entire set of wavefunctions hence we divide the workload
2315 : : ! without checking if the pair of states is available. Last dimension is fake.
2316 [ - + + - : 120 : ABI_MALLOC(task_distrib,(lomo_spin(spin):humo_spin(spin),lomo_spin(spin):humo_spin(spin),Wfd%nkibz,1))
- + + - -
+ + - + -
+ - - + -
+ - + ]
2317 : 24 : call xmpi_distab(Wfd%nproc,task_distrib)
2318 : :
2319 : : ! loop over the k-points in IBZ
2320 [ + + ]: 887 : do ik_ibz=1,Wfd%nkibz
2321 [ + + + + : 8543 : if ( ALL(task_distrib(:,:,ik_ibz,1)/= Wfd%my_rank) ) CYCLE
+ + + + ]
2322 : :
2323 : : ! Don't need to symmetrize the wavefunctions.
2324 [ + + ]: 3035 : itim_k=1; isym_k=1; ph_mkt=cone; spinrot_k=Cryst%spinrot(:,isym_k)
2325 : :
2326 [ + + ]: 4109 : do iv=lomo_spin(spin),humo_spin(spin) ! Loop over band V
2327 [ + - - + : 3478 : if ( ALL(task_distrib(:,iv,ik_ibz,1)/=Wfd%my_rank) ) CYCLE
+ - ]
2328 : :
2329 [ - + ]: 3478 : ABI_CHECK(wfd%get_wave_ptr(iv, ik_ibz, spin, wave_v, msg) == 0, msg)
2330 : :
2331 [ + + ]: 3478 : if (wave_v%has_ur == WFD_STORED) then
2332 : 2989 : ptr_ur1 => wave_v%ur
2333 : : else
2334 : 489 : call wfd%get_ur(iv,ik_ibz,spin,ur1)
2335 : 489 : ptr_ur1 => ur1
2336 : : end if
2337 : :
2338 [ + + ]: 3478 : if (Wfd%usepaw==1) call wfd%get_cprj(iv,ik_ibz,spin,Cryst,Cp1,sorted=.FALSE.)
2339 : :
2340 : : ! Loop over band C
2341 [ + + ]: 24829 : do ic=lomo_spin(spin),humo_spin(spin)
2342 [ + - ]: 20488 : if ( task_distrib(ic,iv,ik_ibz,1)/=Wfd%my_rank ) CYCLE
2343 : :
2344 [ - + ]: 20488 : ABI_CHECK(wfd%get_wave_ptr(ic, ik_ibz, spin, wave_c, msg) == 0, msg)
2345 : :
2346 [ + + ]: 20488 : if (wave_c%has_ur == WFD_STORED) then
2347 : 17853 : ptr_ur2 => wave_c%ur
2348 : : else
2349 : 2635 : call wfd%get_ur(ic,ik_ibz,spin,ur2)
2350 : 2635 : ptr_ur2 => ur2
2351 : : end if
2352 : :
2353 [ + + ]: 20488 : if (Wfd%usepaw==1) call wfd%get_cprj(ic,ik_ibz,spin,Cryst,Cp2,sorted=.FALSE.)
2354 : :
2355 : : call rho_tw_g(Wfd%nspinor,npweps,nfftot_osc,ndat1,ngfft_osc,map2sphere1,use_padfft,igfftg0,gbound,&
2356 : : ptr_ur1,1,id_tab,ph_mkt,spinrot_k,&
2357 : : ptr_ur2,1,id_tab,ph_mkt,spinrot_k,&
2358 : 20488 : dim_rtwg1,rhotwg1)
2359 : :
2360 [ + + ]: 20488 : if (Wfd%usepaw==1) then
2361 : : ! Add PAW onsite contribution.
2362 : 304 : call paw_rho_tw_g(cryst,Pwij_q0,npweps,dim_rtwg1,Wfd%nspinor,Gsph_x%gvec,Cp1,Cp2,rhotwg1)
2363 : : end if
2364 : :
2365 : : ! If q=0 treat Exchange and Coulomb-term independently
2366 [ + + + + : 20488 : if (iv <= homo_spin(spin) .and. ic <= homo_spin(spin) .or. &
+ + + + ]
2367 : : iv > homo_spin(spin) .and. ic > homo_spin(spin)) then
2368 : :
2369 [ + + ]: 10424 : if (iv/=ic) then !COULOMB term: C/=V: ignore them
2370 : 6946 : rhotwg1(1) = czero_gw
2371 : : else
2372 : : ! If q=0 and C=V then set up rho-twiddle(G=0) to reflect an
2373 : : ! analytic integration of q**-2 over the volume element:
2374 : : ! <q**-2> = 7.44 V**(-2/3) (for fcc cell)
2375 : : !rhotwg1(1) = fcc_const * qpg(1,iqbz0)
2376 : 3478 : rhotwg1(1) = SQRT(GWPC_CMPLX(Vcp%i_sz,zero)) / Vcp%vcqlwl_sqrt(1,1)
2377 : : !if (vcut) rhotwg1(1) = 1.0
2378 : : end if
2379 : :
2380 : : else
2381 : : ! At present this term is set to zero
2382 : : ! EXCHANGE term: limit value.
2383 : : ! Set up rho-twiddle(G=0) using small vector q instead of zero and k.p perturbation theory (see notes)
2384 : 10064 : rhotwg1(1) = czero_gw
2385 : : end if
2386 : :
2387 [ + + ]: 930890 : mgq0(:,iv,ic,ik_ibz,spin) = rhotwg1(:)
2388 : : end do !ic
2389 : : end do !iv
2390 : : end do !ik_ibz
2391 : :
2392 [ - + ]: 47 : ABI_FREE(task_distrib)
2393 : : end do !spin
2394 : :
2395 : : ! TODO: One can speedup the calculation by computing the upper triangle of the
2396 : : ! matrix in (b,b') space and then take advantage of the symmetry property:
2397 : : !
2398 : : ! M_{k,0}{{bb'}(G)^* = M{k,0}{b'b'}(-G)
2399 : :
2400 : : #if 0
2401 : : !!!! $OMP PARALLEL DO COLLAPSE(3) PRIVATE(inv_ipw)
2402 : : do spin=1,Wfd%nsppol
2403 : : do ik_ibz=1,Wfd%nkibz
2404 : : do iv=lomo_spin(spin),humo_spin(spin)
2405 : : do ic=1,iv-1
2406 : : do ipw=1,npweps
2407 : : inv_ipw = gsph_x%g2mg(ipw)
2408 : : mgq0(inv_ipw,ic,iv,ik_ibz,spin) = mgq0(ipw,iv,ic,ik_ibz,spin)
2409 : : end do
2410 : : end do
2411 : : end do
2412 : : end do
2413 : : end do
2414 : : #endif
2415 : : !
2416 : : ! Gather matrix elements on each node.
2417 : 23 : call xmpi_sum(mgq0,Wfd%comm,ierr)
2418 : :
2419 : 23 : call cwtime(cpu,wall,gflops,"stop")
2420 : 23 : write(msg,'(2(a,f9.6))')"cpu_time = ",cpu,", wall_time = ",wall
2421 : 23 : call wrtout(std_out, msg)
2422 : :
2423 [ - + ]: 23 : ABI_FREE(rhotwg1)
2424 [ - + ]: 23 : ABI_FREE(igfftg0)
2425 [ - + ]: 23 : ABI_FREE(gbound)
2426 [ - + ]: 23 : ABI_FREE(ur1)
2427 [ - + ]: 23 : ABI_FREE(ur2)
2428 [ - + ]: 23 : ABI_FREE(id_tab)
2429 : :
2430 [ + + ]: 23 : if (Wfd%usepaw==1) then
2431 : : ! Deallocation for PAW.
2432 : 2 : call pawpwij_free(Pwij_q0)
2433 [ + - + + : 5 : ABI_FREE(Pwij_q0)
- + - + ]
2434 : 2 : call pawcprj_free(Cp1)
2435 [ + - + + : 6 : ABI_FREE(Cp1)
- + - + -
+ ]
2436 : 2 : call pawcprj_free(Cp2)
2437 [ + - + + : 6 : ABI_FREE(Cp2)
- + - + -
+ ]
2438 : : end if
2439 : :
2440 : 23 : call timab(671,2,tsec)
2441 : :
2442 [ - + - + : 92 : end subroutine wfd_all_mgq0
- - - - -
+ - - - -
- - - + -
- - - -
- ]
2443 : : !!***
2444 : :
2445 : : end module m_exc_build
2446 : : !!***
|