Branch data Line data Source code
1 : : !!****m* ABINIT/m_exc_itdiago
2 : : !! NAME
3 : : !! m_exc_itdiago
4 : : !!
5 : : !! FUNCTION
6 : : !! Iterative diagonalization of the BSE Hamiltonian with band-by-band conjugate gradient method
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2008-2026 ABINIT group (MG)
10 : : !! This file is distributed under the terms of the
11 : : !! GNU General Public License, see ~abinit/COPYING
12 : : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : : !!
14 : : !! SOURCE
15 : :
16 : : #if defined HAVE_CONFIG_H
17 : : #include "config.h"
18 : : #endif
19 : :
20 : : #include "abi_common.h"
21 : :
22 : : MODULE m_exc_itdiago
23 : :
24 : : use defs_basis
25 : : use m_bs_defs
26 : : use m_errors
27 : : use m_abicore
28 : : use m_linalg_interfaces
29 : : use m_hdr
30 : : USE_MPI
31 : : use m_xmpi
32 : :
33 : : use m_io_tools, only : open_file
34 : : use m_time, only : cwtime
35 : : use m_numeric_tools, only : stats_t, stats_eval
36 : : use m_hide_lapack, only : xhpev !xheev,
37 : : use m_bse_io, only : exc_read_rcblock
38 : :
39 : : implicit none
40 : :
41 : : private
42 : :
43 : : #ifdef HAVE_MPI1
44 : : include 'mpif.h'
45 : : #endif
46 : :
47 : : public :: exc_iterative_diago ! Calculates eigenvalues and eigenvectors of the Resonant BSE Hamiltonian
48 : : !!***
49 : :
50 : : CONTAINS !===============================================================
51 : : !!***
52 : :
53 : : !!****f* m_exc_itdiago/exc_iterative_diago
54 : : !!
55 : : !! NAME
56 : : !! exc_iterative_diago
57 : : !!
58 : : !! FUNCTION
59 : : !! Calculates eigenvalues and eigenvectors of the Hermitian excitonic Hamiltonian (coupling is neglected).
60 : : !!
61 : : !! INPUTS
62 : : !! Bsp
63 : : !! %nreh=Rank of the resonant block of the Hamiltonian.
64 : : !! %nstates=Number of eigenstates required.
65 : : !! %nline=Max number of line minimizations.
66 : : !! %tolwfr=Tolerance on the residuals.
67 : : !! %nbdbuf
68 : : !! %nstep
69 : : !! BS_files<excfiles>=Datatype storing names and files used in the Bethe-Salpeter code.
70 : : !! %exh=Name of the file storing the excitonin resonant part.
71 : : !! %out_eig_out=Name of the file where final results are store.
72 : : !! %in_eig=Name of the file used to initialize the calculation.
73 : : !! comm=MPI communicator.
74 : : !!
75 : : !! OUTPUT
76 : : !! Eigenvalues and eigenvectors are written on file %out_eig
77 : : !!
78 : : !! NOTES
79 : : !! Concernig the approach followed to parallelize this routine: the most important
80 : : !! bottleneck is represent by the storage of the excitonic Hamiltonian since a
81 : : !! large number of k-points is needed to obtain converged exciton energies.
82 : : !! The number of eigenstates is usually much smaller than the rank of the full matrix,
83 : : !! this is especially true if we are only interested in the binding energy of the
84 : : !! exciton or in the excitonic states close to the single-particle gap.
85 : : !! Therefore good scaling and good performance should be obtained by distributing
86 : : !! the row of the excitonic Hamiltonian among the nodes while the required
87 : : !! eigenvectors are duplicated on each node. The memory needed to stores the eigenvalues
88 : : !! scales like nreh*nstates where nreh is the rank of the Hamiltonian and this might
89 : : !! render the calculation unfeasible when nstates is large.
90 : : !! On the other hand, having the complex set of trial eigenvectors on each node permits to parallelize
91 : : !! tasks such as the application of the Hamiltonian as well as the orthogonalization or the sub-space rotation
92 : : !! the later two algorithms represent the most CPU demanding part in standard KS calculations
93 : : !! as they scale with the third power of the number of atoms.
94 : : !! The conjugate direction and the gradient as well as Hphi are not distributed as the line minimization
95 : : !! requires the evaluation of <cg_dir_|H_exc|cg_dir>.
96 : : !! Note that this routine has been written having in mind an homogeneous network of machines.
97 : : !! A network made of different CPU will lead to unpredictable results as each node has
98 : : !! to check for the converge of the calculation.
99 : : !!
100 : : !! SOURCE
101 : :
102 : 1 : subroutine exc_iterative_diago(BSp,BS_files,Hdr_bse,prtvol,comm)
103 : :
104 : : !Arguments ------------------------------------
105 : : !scalars
106 : : integer,intent(in) :: comm,prtvol
107 : : type(excparam),intent(in) :: BSp
108 : : type(excfiles),intent(in) :: BS_files
109 : : type(Hdr_type),intent(in) :: Hdr_bse
110 : :
111 : : !Local variables ------------------------------
112 : : !scalars
113 : : integer,parameter :: STRICT=2,MEDIUM=1,WORST=0
114 : : integer,parameter :: master=0
115 : : integer(i8b) :: bsize_hmat,bsize_phi_block
116 : : integer :: hexc_size,nstates,nline,nbdbuf,nstep
117 : : integer :: cg_nsteps,my_t1,my_t2,my_nt
118 : : integer :: ii,jj,state,line,max_nline
119 : : integer :: cg_step,nbdbuf_,nsppol,ierr,nproc,my_rank
120 : : real(dp) :: exc_gap,exc_maxene,norm,etrial,etrial_old,deltae,tolwfr
121 : : ! real(dp) :: deold
122 : : real(dp) :: dhd,dhc,den,fac,poly,xx,root,swap,tan2th,diff,tolwfr_
123 : : !complex(dp) :: cg_gamma,dotgg,old_dotgg
124 : : real(dp) :: cg_gamma,dotgg,old_dotgg
125 : : real(dp) :: max_resid,costh,sinth
126 : : complex(dp) :: zz,kprc
127 : : logical,parameter :: DEBUGME=.False.
128 : : logical :: use_mpio,is_resonant,diago_is_real
129 : : character(len=500) :: msg
130 : : character(len=fnlen) :: hexc_fname,ihexc_fname,oeig_fname
131 : : type(stats_t) :: stats
132 : : !arrays
133 : 3 : integer :: nline_for(Bsp%nstates),convergence_of(Bsp%nstates)
134 : 3 : real(dp) :: resid(Bsp%nstates),exc_energy(Bsp%nstates),rbuf2(2)
135 : : ! real(dp),allocatable :: gsc(:,:),cg(:,:)
136 : : !complex,allocatable :: hexc(:,:)
137 : 1 : complex(dp),allocatable :: hexc(:,:),hji(:),vec_tmp(:)
138 : 1 : complex(dp),contiguous, pointer :: my_phi(:)
139 : 1 : real(dp),allocatable :: hexc_diagonal(:)
140 : 1 : complex(dp),target,allocatable :: phi_block(:,:)
141 : 1 : complex(dp),allocatable :: hphi(:) !,buffer_dpc(:)
142 : 1 : complex(dp),allocatable :: cg_dir(:),grad_dir(:),prc_dir(:)
143 : 1 : complex(dp),allocatable :: old_cg_dir(:)
144 : : !************************************************************************
145 : :
146 : : DBG_ENTER("COLL")
147 : :
148 : 1 : if (Bsp%use_coupling>0) then
149 : 0 : ABI_ERROR("CG Method does not support coupling")
150 : : end if
151 : :
152 : 1 : nsppol = Hdr_bse%nsppol
153 [ - + ]: 1 : if (Hdr_bse%nsppol == 2) then
154 : 0 : ABI_WARNING("nsppol==2 with cg method is still under development")
155 : : end if
156 : :
157 : 1 : nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
158 : :
159 : 1 : use_mpio=.FALSE.
160 : : #ifdef HAVE_MPI_IO
161 : : use_mpio = (nproc > 1)
162 : : #endif
163 : : use_mpio=.FALSE.
164 : : !use_mpio = .TRUE.
165 : :
166 [ + + ]: 2 : hexc_size = SUM(Bsp%nreh)
167 : 1 : nstates= Bsp%nstates
168 : 1 : nline = Bsp%nline
169 : 1 : nbdbuf = Bsp%nbdbuf
170 : 1 : nstep = Bsp%niter
171 : 1 : tolwfr = Bsp%cg_tolwfr
172 : :
173 : 1 : write(msg,'(a,i0)')' Iterative diagonalization of the resonant excitonic Hamiltonian, Matrix size= ',hexc_size
174 : 1 : call wrtout(std_out,msg,"COLL")
175 : 1 : call wrtout(ab_out,msg,"COLL")
176 : :
177 [ - + ]: 1 : ABI_CHECK(hexc_size>=nproc,"hexc_size<nproc!")
178 [ - + ]: 1 : ABI_CHECK(nstates <= hexc_size,"nstates cannot be greater that hexc size!")
179 : :
180 : : ! Divide the columns of the Hamiltonian among the nodes.
181 : : call xmpi_split_work(hexc_size,comm,my_t1,my_t2)
182 : :
183 : 1 : my_nt = my_t2-my_t1+1
184 : 1 : write(msg,'(a,i0,a)')" Will handle ",my_nt," columns of the excitonic Hamiltonian. "
185 : 1 : call wrtout(std_out,msg,"PERS")
186 : :
187 : 1 : tolwfr_ = tolwfr
188 [ - + ]: 1 : if (tolwfr < 10**(-30)) then
189 : 0 : tolwfr_ = tol12
190 : 0 : write(msg,'(2(a,es12.4))')" Input tolwfr= ",tolwfr," Using tolwfr= ",tolwfr_
191 : 0 : ABI_WARNING(msg)
192 : : end if
193 : :
194 : 1 : cg_nsteps = nstep
195 [ - + ]: 1 : if (cg_nsteps<=0) then
196 : 0 : cg_nsteps = 30
197 : 0 : write(msg,'(2(a,es12.4))')" Input nstep= ",nstep," Using cg_nsteps= ",cg_nsteps
198 : 0 : ABI_WARNING(msg)
199 : : end if
200 : :
201 : 1 : nbdbuf_ = nbdbuf
202 [ - + ]: 1 : if (nbdbuf<=0) then
203 : 0 : nbdbuf_ = 4
204 : 0 : write(msg,'(2(a,i0))')" Input nbdbuf= ",nbdbuf," Using nbdbuf= ",nbdbuf_
205 : 0 : ABI_WARNING(msg)
206 : : end if
207 : :
208 : : write(msg,"(4(a,i0,a),a,es12.4)")&
209 : 1 : & " cg_nsteps: ",cg_nsteps,ch10,&
210 : 1 : & " nstates: ",nstates,ch10,&
211 : 1 : & " nline: ",nline,ch10,&
212 : 1 : & " nbdbuf: ",nbdbuf_,ch10,&
213 : 2 : & " tolwfr: ",tolwfr_
214 : 1 : call wrtout(std_out,msg,"COLL")
215 : 1 : call wrtout(ab_out,msg,"COLL")
216 : :
217 : 1 : bsize_hmat = 2*dp*hexc_size*my_nt
218 : 1 : write(msg,'(a,f8.1,a)')' Allocating excitonic Hamiltonian. Memory requested: ',bsize_hmat*b2Mb,' Mb.'
219 : 1 : call wrtout(std_out,msg,"COLL")
220 : :
221 [ - + + - : 3 : ABI_MALLOC(hexc_diagonal,(my_t1:my_t2))
+ - + - -
+ - + ]
222 [ - + + - : 4 : ABI_MALLOC_OR_DIE(hexc,(hexc_size,my_t1:my_t2), ierr)
- + + - +
- + - + -
+ - - + +
- - + ]
223 : : !
224 : : ! Read and construct full excitonic Hamiltonian using Hermiticity.
225 [ - + ]: 1 : if (BS_files%in_hreso /= BSE_NOFILE) then
226 : 0 : hexc_fname = BS_files%in_hreso
227 : : else
228 : 1 : hexc_fname = BS_files%out_hreso
229 : : end if
230 : : !
231 : : ! Read the resonant block from file.
232 : 1 : is_resonant=.TRUE.
233 : 1 : diago_is_real=(.not.BSp%have_complex_ene)
234 : 1 : call exc_read_rcblock(hexc_fname,Bsp,is_resonant,diago_is_real,nsppol,Bsp%nreh,hexc_size,my_t1,my_t2,hexc,use_mpio,comm)
235 : : !
236 : : ! Save diagonal part for preconditioning.
237 [ + + ]: 385 : do jj=my_t1,my_t2
238 : 385 : hexc_diagonal(jj) = REAL(hexc(jj,jj),kind=dp)
239 : : end do
240 : : !
241 : : ! === Initialisation of the excitonic wavefunctions ===
242 : : ! Two cases are possible.
243 : : ! 1) Fill trial eigenvectors with random numbers
244 : : ! One needs to initialize wfs in such a way to avoid symmetry traps,
245 : : ! and to avoid linear dependencies between wavefunctions
246 : : ! 2) Read eigenstates generated by a previous calculation.
247 : :
248 : 1 : bsize_phi_block = 2*sp*my_nt*nstates
249 : 1 : write(msg,'(a,f8.1,a)')' Allocating BSE eigenvectors. Memory requested: ',bsize_phi_block*b2Mb,' Mb.'
250 : 1 : call wrtout(std_out,msg,"COLL",do_flush=.True.)
251 : :
252 [ - + + - : 4 : ABI_MALLOC_OR_DIE(phi_block,(my_t1:my_t2,nstates), ierr)
- + + - +
- + - + -
+ - - + +
- - + ]
253 : :
254 : 1 : ihexc_fname = ""
255 [ - + ]: 1 : if (BS_files%in_eig /= BSE_NOFILE) ihexc_fname = BS_files%in_eig
256 : :
257 : 1 : call exc_init_phi_block(ihexc_fname,use_mpio,comm)
258 : : !
259 : : ! =========================
260 : : ! === Orthogonalization ===
261 : : ! =========================
262 : 1 : call exc_cholesky_ortho()
263 : : call exc_check_phi_block("First cholesky ortho")
264 : :
265 : : ! * Sub-space rotation.
266 : 2 : call exc_subspace_rotation()
267 : : call exc_check_phi_block("First subspace_rotation")
268 : : !
269 : : ! ===========================
270 : : ! ==== Conjugate gradient ===
271 : : ! ===========================
272 [ + - + - : 3 : ABI_MALLOC(hphi,(hexc_size))
+ - - + -
+ ]
273 [ - + + - : 2 : ABI_MALLOC(cg_dir,(hexc_size))
- + - + ]
274 [ - + + - : 2 : ABI_MALLOC(old_cg_dir,(hexc_size))
- + - + ]
275 [ - + + - : 2 : ABI_MALLOC(grad_dir,(hexc_size))
- + - + ]
276 [ - + + - : 2 : ABI_MALLOC(prc_dir,(hexc_size))
- + - + ]
277 : :
278 : : max_nline=nline
279 [ + + + + : 31 : resid(:)=HUGE(one); nline_for(1:nstates)=max_nline; convergence_of(1:nstates)=WORST
+ + ]
280 : :
281 [ + + ]: 21 : do cg_step=1,cg_nsteps
282 [ + + ]: 220 : do state=1,nstates
283 : :
284 [ - + ]: 200 : if (prtvol>=10) then ! Tell us what is going on:
285 : 0 : write(msg,'(a,i6,2x,a,i3,a)')' --- exc_iterative_diago is called for state ',state,'for',nline_for(state),' lines'
286 : 0 : call wrtout(std_out,msg,'PERS')
287 : : end if
288 : :
289 : : ! Extraction of the vector that is iteratively updated.
290 : 200 : my_phi => phi_block(my_t1:my_t2,state)
291 : :
292 [ + + ]: 933 : do line=1,nline_for(state)
293 : : ! Compute etrial=<phi|H|phi> and the residual [H-etrial]|phi>.
294 [ + + ]: 283360 : hphi = czero
295 : : #ifdef FC_NVHPC
296 : : !Buggy NVHPC compiler
297 : : do jj=1,my_t2-my_t1+1;do ii=1,hexc_size
298 : : hphi(ii)=hphi(ii)+hexc(ii,jj)*my_phi(jj)
299 : : enddo ; enddo
300 : : #else
301 [ + - - + : 326148832 : hphi = MATMUL(hexc, my_phi)
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- + + + +
+ + + - +
- + - ]
302 : : #endif
303 : 736 : call xmpi_sum(hphi,comm,ierr)
304 : :
305 [ + + ]: 283360 : etrial = DOT_PRODUCT(my_phi, hphi(my_t1:my_t2))
306 : 736 : call xmpi_sum(etrial,comm,ierr)
307 : 736 : exc_energy(state) = etrial
308 : :
309 : : ! Compute residual (squared) norm.
310 [ + + ]: 283360 : grad_dir(my_t1:my_t2) = hphi(my_t1:my_t2) - etrial*my_phi
311 [ + + ]: 283360 : resid(state) = DOT_PRODUCT(grad_dir(my_t1:my_t2), grad_dir(my_t1:my_t2))
312 : 736 : call xmpi_sum(resid(state),comm,ierr)
313 : 1472 : convergence_of(state) = convergence_degree(resid(state))
314 : : !
315 : : ! Check that etrial is decreasing on succeeding lines:
316 [ + + - + ]: 736 : if (line>1 .and. (etrial > etrial_old+tol12)) then
317 : : write(msg,'(a,i8,a,1p,e14.6,a1,3x,a,1p,e14.6,a1)')&
318 : 0 : & 'New trial exc_energy at line ',line,' = ',etrial,ch10,&
319 : 0 : & 'is higher than former:',etrial_old,ch10
320 : 0 : ABI_WARNING(msg)
321 : : end if
322 : 736 : etrial_old = etrial
323 : : !
324 : : ! If residual sufficiently small stop line minimization.
325 [ + + ]: 736 : if (convergence_of(state)==STRICT) then
326 [ - + ]: 23 : if (prtvol>=10) then
327 : : write(msg,'(a,i4,a,i2,a,es12.4)')&
328 : 0 : & ' exc_iterative_diago: state ',state,' converged after ',line,&
329 : 0 : & ' line minimizations : resid =',resid(state)
330 : 0 : call wrtout(std_out,msg,'PERS')
331 : : end if
332 : : EXIT !line
333 : : end if
334 : :
335 : : ! === PROJECT THE STEEPEST DESCENT DIRECTION OVER THE SUBSPACE ORTHOGONAL TO OTHER BANDS ===
336 : : ! The following projection over the subspace orthogonal to occupied bands
337 : : ! is optional. It is a bit more accurate, but doubles the number of N^3 ops.
338 : : ! It is done only if ortalg>=0.
339 : :
340 : : ! Project the steepest descent direction: direc(2,npw)=<G|H|Cnk> - \sum_{(i<=n)} <G|H|Cik> , normalized.
341 : :
342 : : ! Grad_dir is already orthogonal to this band
343 [ - + + - : 2139 : ABI_MALLOC(hji,(nstates))
+ - + - -
+ - + -
+ ]
344 [ + + ]: 7843 : hji=czero
345 : :
346 : : ! MG TODO Don't know why here we sum over i=<=n!!!!!!!!
347 [ + + ]: 7843 : do jj=1,nstates
348 [ + + + + ]: 2471971 : if (jj/=state) hji(jj) = DOT_PRODUCT(phi_block(:,jj), hphi(my_t1:my_t2) )
349 : : end do
350 : 713 : call xmpi_sum(hji,comm,ierr)
351 : :
352 [ + + ]: 7843 : do jj=1,nstates
353 [ + + + + ]: 2471971 : if (jj/=state) grad_dir(my_t1:my_t2) = grad_dir(my_t1:my_t2) - hji(jj)*phi_block(:,jj)
354 : : end do
355 [ - + ]: 713 : ABI_FREE(hji)
356 : : !
357 : : ! === PRECONDITION THE STEEPEST DESCENT DIRECTION ===
358 [ + + ]: 274505 : den = DOT_PRODUCT(grad_dir(my_t1:my_t2), hexc_diagonal(my_t1:my_t2)*grad_dir(my_t1:my_t2) )
359 : 713 : call xmpi_sum(den,comm,ierr)
360 : :
361 [ + + ]: 274505 : do ii=my_t1,my_t2
362 : : ! Teter polynomial ratio, modified according to Kresse, Furthmuller, PRB 54, 11169 (1996) [[cite:Kresse1996]]
363 : 273792 : xx = hexc_diagonal(ii)/den
364 : 273792 : poly=27._dp+xx*(18._dp+xx*(12._dp+xx*8._dp))
365 : 273792 : fac=poly/(poly+16._dp*xx**4)
366 : 273792 : kprc = fac*four/(three*den)
367 : 274505 : prc_dir(ii) = kprc * grad_dir(ii)
368 : : end do
369 : : !
370 : : ! * PROJECT THE PRECOND. STEEPEST DESCENT DIRECTION OVER THE SUBSPACE ORTHOGONAL TO OTHER BANDS.
371 [ - + + - : 2139 : ABI_MALLOC(hji,(nstates))
+ - + - -
+ - + ]
372 [ + + ]: 7843 : hji=czero
373 [ + + ]: 7843 : do jj=1,nstates
374 [ + + ]: 2745763 : hji(jj) = DOT_PRODUCT(phi_block(:,jj), prc_dir(my_t1:my_t2) )
375 : : end do
376 : 713 : call xmpi_sum(hji,comm,ierr)
377 : :
378 [ + + ]: 7843 : do jj=1,nstates
379 [ + + ]: 2745763 : prc_dir(my_t1:my_t2) = prc_dir(my_t1:my_t2) - hji(jj)*phi_block(:,jj)
380 : : end do
381 [ - + ]: 713 : ABI_FREE(hji)
382 : : !
383 : : ! === COMPUTE THE CONJUGATE-GRADIENT ===
384 [ + + ]: 274505 : dotgg = DOT_PRODUCT(prc_dir(my_t1:my_t2),grad_dir(my_t1:my_t2))
385 : 713 : call xmpi_sum(dotgg,comm,ierr)
386 : :
387 [ + + ]: 713 : if (line==1) then ! At first iteration, cg_gamma is set to zero
388 : 179 : cg_gamma=zero
389 : 179 : old_dotgg=dotgg
390 [ - + + + ]: 69094 : cg_dir = prc_dir
391 [ - + + + ]: 69094 : old_cg_dir = cg_dir
392 : : else
393 : 534 : cg_gamma=dotgg/old_dotgg
394 : 534 : old_dotgg=dotgg
395 : : !write(std_out,*)"cg_gamma= ",cg_gamma
396 : : !cg_dir = prc_dir + cg_gamma*cg_dir
397 [ - + + + ]: 206124 : cg_dir = prc_dir + cg_gamma*old_cg_dir !TODO check this, anyhow it is much faster.
398 [ - + + + ]: 206124 : old_cg_dir =cg_dir ! old_cg_dir is used to store the previsou CG direction, cg_dir will be orthonormalized to the band
399 : : end if
400 : : !
401 : : ! === PROJECTION OF THE CONJUGATED GRADIENT ===
402 [ + + ]: 274505 : zz = DOT_PRODUCT(my_phi, cg_dir(my_t1:my_t2))
403 : 713 : call xmpi_sum(zz,comm,ierr)
404 [ + + ]: 274505 : cg_dir(my_t1:my_t2) = cg_dir(my_t1:my_t2) -zz*my_phi(:)
405 : :
406 [ + + ]: 274505 : norm = DOT_PRODUCT(cg_dir(my_t1:my_t2), cg_dir(my_t1:my_t2) )
407 : 713 : call xmpi_sum(norm,comm,ierr)
408 : 713 : norm = SQRT(norm)
409 [ + + ]: 274505 : cg_dir = cg_dir/norm ! Have to normalize it.
410 : :
411 : : ! Line minimization of the Raileigh functional.
412 [ - + + - : 2139 : ABI_MALLOC(vec_tmp,(hexc_size))
+ - + - -
+ - + -
+ ]
413 [ + + ]: 274505 : vec_tmp=czero
414 : : #ifdef FC_NVHPC
415 : : !Buggy NVHPC compiler
416 : : do jj=my_t1,my_t2;do ii=1,hexc_size
417 : : vec_tmp(ii)=vec_tmp(ii)+hexc(ii,jj-my_t1+1)*cg_dir(jj)
418 : : enddo ; enddo
419 : : #else
420 [ + - - + : 210820553 : vec_tmp = MATMUL(hexc, cg_dir(my_t1:my_t2))
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- + + + +
+ + + - +
- ]
421 : : #endif
422 : 713 : call xmpi_sum(vec_tmp,comm,ierr)
423 : :
424 : : !if (my_rank==master) then
425 : : ! write(777,*)"cg_step, state, line",cg_step, state, line
426 : : ! write(777,*)vec_tmp
427 : : !end if
428 : :
429 [ + + ]: 274505 : dhd = DOT_PRODUCT( cg_dir(my_t1:my_t2), vec_tmp(my_t1:my_t2)) ! is this always real?
430 [ + + ]: 274505 : dhc = REAL( DOT_PRODUCT( my_phi, vec_tmp(my_t1:my_t2) ))
431 [ - + ]: 713 : ABI_FREE(vec_tmp)
432 : :
433 [ + + ]: 2139 : rbuf2 = (/dhd,dhc/)
434 : 713 : call xmpi_sum(rbuf2,comm,ierr)
435 : 713 : dhd = rbuf2(1)
436 : 713 : dhc = rbuf2(2)
437 : :
438 : : !write(201*(my_rank+1),*)"cg_step, state, line dotgg dhd dhc",cg_step,state,line,dotgg,dhd,dhc
439 : :
440 : : ! Taken from cgwf
441 : : ! Compute tan(2 theta),sin(theta) and cos(theta)
442 : 713 : tan2th=2.0_dp*dhc/(etrial-dhd)
443 : :
444 [ + + ]: 713 : if (abs(tan2th)<1.d-05) then
445 : 67 : costh=1.0_dp-0.125_dp*tan2th**2
446 : 67 : sinth=0.5_dp*tan2th*(1.0_dp-0.375_dp*tan2th**2)
447 : : ! Check that result is above machine precision
448 : : ! FIXME This part is not safe on clusters made of different machines or different compiation options.
449 [ - + ]: 67 : if (abs(sinth)<epsilon(0._dp)) then
450 : 0 : write(msg, '(a,es16.4)' ) ' exc_iterative_diago: converged with tan2th= ',tan2th
451 : 0 : call wrtout(std_out,msg,'PERS')
452 : 0 : EXIT !Exit from the loop on line
453 : : end if
454 : :
455 : : else
456 : 646 : root =sqrt(1.0_dp+tan2th**2)
457 : 646 : costh=sqrt(0.5_dp+0.5_dp/root)
458 : 646 : sinth=sign(sqrt(0.5_dp-0.5_dp/root),tan2th)
459 : : end if
460 : : !
461 : : ! Check for lower of two possible roots (same sign as curvature at theta where slope is zero)
462 : 713 : diff=(etrial-dhd)
463 [ + + ]: 713 : if (diff>zero) then ! Swap c and d if value of diff is positive
464 : 10 : swap=costh
465 : 10 : costh=-sinth
466 : 10 : sinth=swap
467 [ - + ]: 10 : if (prtvol<0 .or. prtvol>=10) then
468 : 0 : write(msg,'(a,i4,es16.6)')' exc_iterative_diago: swap roots, line,diff= ',line,diff
469 : 0 : call wrtout(std_out,msg,'PERS')
470 : : end if
471 : : end if
472 : : !
473 : : ! === GENERATE NEW |wf>, H|wf> =============
474 [ + + ]: 274505 : my_phi = costh*my_phi + sinth*cg_dir(my_t1:my_t2)
475 : : !write(100*(my_rank+1),*)"cg_step state, line costh sinth etrial",cg_step,state,line,costh,sinth,etrial
476 : : !end taken from cgwf
477 : :
478 : : !norm = SQRT( DOT_PRODUCT(my_phi,my_phi) )
479 : : !my_phi = my_phi /norm
480 : : !write(std_out,*)norm
481 : : !write(std_out,*)DOT_PRODUCT(hphi,my_phi),cos(theta_min)
482 : :
483 : : ! ======================================================================
484 : : ! =========== CHECK CONVERGENCE AGAINST TRIAL ENERGY ===================
485 : : ! ======================================================================
486 : : ! Compute delta(E)
487 : : !deltae=chc*(costh**2-1._dp)+dhd*sinth**2+2._dp*costh*sinth*dhc
488 : 8089 : deltae=etrial*(costh**2-1._dp)+dhd*sinth**2+2._dp*costh*sinth*dhc
489 : :
490 : : ! Check convergence and eventually exit
491 : : ! if (line==1) then
492 : : ! deold=deltae
493 : : ! else if (abs(deltae)<0.005_dp*abs(deold) .and. line/=nline_for(state))then
494 : : ! if (prtvol>=10)then
495 : : ! write(msg, '(a,i4,1x,a,1p,e12.4,a,e12.4,a)' ) &
496 : : !& ' cgwf: line',line,&
497 : : !& ' deltae=',deltae,' < 0.005*',deold,' =>skip lines'
498 : : ! call wrtout(std_out,msg,'PERS')
499 : : ! end if
500 : : ! exc_energy(state) = exc_energy(state) + deltae
501 : : ! EXIT
502 : : ! end if
503 : : end do ! LOOP FOR A GIVEN BAND. Note that there are three "exit" instructions inside
504 : : ! Modify nline_for(state) according to converge degree.
505 : : !if (convergence_of(state) == STRICT) nline_for(state) = MAX(max_nline-2,2)
506 : : !if (convergence_of(state) == MEDIUM) nline_for(state) = MAX(max_nline-1,2)
507 : : !if (convergence_of(state) == WORST ) nline_for(state) = max_nline
508 : : end do !state
509 : :
510 [ - + ]: 20 : if (prtvol>2) then
511 [ # # ]: 0 : do ii=0,(nstates-1)/8
512 : 0 : write(msg,'(a,8es10.2)')' res:',(resid(state),state=1+ii*8,MIN(nstates,8+ii*8))
513 : 0 : call wrtout(std_out,msg,'COLL')
514 : : end do
515 [ # # ]: 0 : do ii=0,(nstates-1)/8
516 : 0 : write(msg,'(a,8es10.2)')' ene:',(exc_energy(state),state=1+ii*8,MIN(nstates,8+ii*8))
517 : 0 : call wrtout(std_out,msg,'COLL')
518 : : end do
519 : : end if
520 : :
521 : 20 : write(msg,'(a,i0)')"After cg_step: ",cg_step
522 : : call exc_check_phi_block(msg)
523 : :
524 : : ! Find largest residual over bands and Print residuals
525 [ - + + - : 160 : max_resid=MAXVAL( resid(:MAX(1,nstates-nbdbuf_)) )
+ + ]
526 : :
527 [ - + ]: 20 : if (max_resid < tolwfr_) then
528 : : write(msg,'(a,i0,2(a,es10.2),a,i0,a)')&
529 : 0 : & " After ",cg_step," iterations, max_resid= ",max_resid," < tolwfr= ",tolwfr_," ( Excluding nbdbuf= ",nbdbuf_,")"
530 : 0 : call wrtout(std_out,msg,'COLL')
531 : 0 : EXIT ! cg_step
532 : : end if
533 : :
534 : : if (cg_step==1.or.MOD(cg_step,1)==0) then
535 : 20 : call wrtout(std_out," Subspace rotation + exc_cholesky_ortho ","COLL")
536 : :
537 : 20 : call exc_subspace_rotation()
538 : 20 : call exc_cholesky_ortho()
539 : :
540 : : !mcg=hexc_size; mgsc=hexc_size; useoverlap=0
541 : : !allocate(cg(2,mcg),gsc(2,mgsc*useoverlap))
542 : : !do ii=1,nstates
543 : : ! cg(1,:) = REAL (phi_block(:,ii))
544 : : ! cg(2,:) = AIMAG(phi_block(:,ii))
545 : : ! call fxphas(cg,gsc,0,0,1,mcg,mgsc,MPI_enreg_seq,1,hexc_size,useoverlap)
546 : : ! phi_block(:,ii)=CMPLX(cg(1,:),cg(2,:))
547 : : !end do
548 : : !deallocate(cg,gsc)
549 : :
550 : : end if
551 : :
552 : : !XG20141126 : At present, keep this fake test. Seems that there is some bug on shiva
553 : : !(compiler ?) so that the result is erroneous without it. Even suppressing the
554 : : !"stop" instruction triggers the bug ...
555 : 1 : if(cg_step==cg_nsteps+1)then
556 : : write(std_out,*)' One should not be here : cg_step==cg_nsteps+1 '
557 : : stop
558 : : endif
559 : :
560 : : end do !cg_step
561 : :
562 : : ! Release some memory before entering RMM-DIIS
563 [ - + ]: 1 : ABI_FREE(hphi)
564 [ - + ]: 1 : ABI_FREE(cg_dir)
565 [ - + ]: 1 : ABI_FREE(old_cg_dir)
566 [ - + ]: 1 : ABI_FREE(grad_dir)
567 [ - + ]: 1 : ABI_FREE(prc_dir)
568 : :
569 [ + + ]: 3 : do ii=0,(nstates-1)/8
570 : 2 : write(msg,'(a,8es10.2)')' res:',(resid(state),state=1+ii*8,min(nstates,8+ii*8))
571 : 3 : call wrtout(std_out,msg,'COLL')
572 : : end do
573 [ + + ]: 3 : do ii=0,(nstates-1)/8
574 : 2 : write(msg,'(a,8es10.2)')' ene:',(exc_energy(state),state=1+ii*8,min(nstates,8+ii*8))
575 : 3 : call wrtout(std_out,msg,'COLL')
576 : : end do
577 : :
578 : 1 : stats = stats_eval(resid)
579 : :
580 : : write(msg,"(4(a,es10.2))")&
581 : 1 : & ". Residuals: min value: ",stats%min,", Max value: ",stats%max,", mean: ",stats%mean,", stdev: ",stats%stdev
582 : 1 : call wrtout(std_out,msg)
583 : 1 : call wrtout(ab_out,msg)
584 : :
585 [ + - ]: 1 : if (max_resid > tolwfr_) then
586 : 1 : write(msg,'(2a,i5,2a,2(a,es10.2),a,i3,a)')ch10,&
587 : 1 : & " WARNING: conjugate-gradient not converged after ",cg_step," iterations.",ch10,&
588 : 2 : & " max_resid= ",max_resid," > tolwfr= ",tolwfr_," ( Excluding nbdbuf= ",nbdbuf_,")"
589 : 1 : call wrtout(ab_out,msg,'COLL')
590 : 1 : call wrtout(std_out,msg,'COLL')
591 : : end if
592 : :
593 [ + - - + : 12 : exc_gap = MINVAL(exc_energy)
- - + + ]
594 [ + - - + : 12 : exc_maxene = MAXVAL(exc_energy)
- - + + ]
595 : :
596 : 1 : write(msg,'(a,2(a,f7.2,2a))')ch10,&
597 : 1 : & " First excitonic eigenvalue= ",exc_gap*Ha_eV, " [eV]. ",ch10,&
598 : 2 : & " Last excitonic eigenvalue= ",exc_maxene*Ha_eV," [eV]. ",ch10
599 : 1 : call wrtout(std_out,msg,"COLL")
600 : 1 : call wrtout(ab_out,msg,"COLL")
601 : :
602 : : call exc_check_phi_block("END OF CONJUGATE-GRADIENT")
603 : :
604 : 0 : ABI_FREE(hexc)
605 [ - + ]: 1 : ABI_FREE(hexc_diagonal)
606 : : !
607 : : ! =====================================
608 : : ! ==== Write final results on file ====
609 : : ! =====================================
610 : 1 : oeig_fname = BS_files%out_eig
611 [ - + ]: 1 : if (oeig_fname== BSE_NOFILE) then
612 : 0 : ABI_WARNING("oeig_fname was set to "//TRIM(BSE_NOFILE))
613 [ # # ]: 0 : oeig_fname = TRIM(BS_files%out_basename)//"_BSEIG"
614 [ # # ]: 0 : ABI_WARNING("using oeig_fname : "//TRIM(oeig_fname))
615 : : end if
616 : :
617 : 1 : call exc_write_phi_block(oeig_fname,use_mpio)
618 : :
619 [ - + ]: 1 : ABI_FREE(phi_block)
620 : :
621 [ - + - + : 3 : call xmpi_barrier(comm)
- + - + -
+ ]
622 : :
623 : : DBG_EXIT("COLL")
624 : :
625 : : CONTAINS !===========================================================
626 : : !!***
627 : :
628 : : !----------------------------------------------------------------------
629 : :
630 : : !!****f* m_exc_itdiago/exc_init_phi_block
631 : : !! NAME
632 : : !! exc_init_phi_block
633 : : !!
634 : : !! FUNCTION
635 : : !! Initialize the eigenstates either from file or fill them with random number
636 : : !! if restart file is not available
637 : : !!
638 : : !! INPUTS
639 : : !! ihexc_fname=
640 : : !! Name of the file from which the eigenvectors will be read.
641 : : !! Empty string to initialize trial eigenvectors with random numbers.
642 : : !!
643 : : !! SIDE EFFECTS
644 : : !! phi_block(my_t1:my_t2,nstates)=Contains the trial eigenstates.
645 : : !!
646 : : !! SOURCE
647 : :
648 : 1 : subroutine exc_init_phi_block(ihexc_fname,use_mpio,comm)
649 : :
650 : : !Arguments ------------------------------------
651 : : !scalars
652 : : integer,intent(in) :: comm
653 : : logical,intent(in) :: use_mpio
654 : : character(len=*),intent(in) :: ihexc_fname
655 : :
656 : : !Local variables ------------------------------
657 : : integer :: eig_unt,hexc_size_restart,ii,state,seed
658 : : integer :: fold1,fold2,foldim,foldre
659 : : real(dp) :: cputime,walltime,gflops
660 : : character(len=500) :: errmsg
661 : : !arrays
662 : 1 : complex(dp),allocatable :: buffer_dpc(:)
663 : : #ifdef HAVE_MPI_IO
664 : : integer:: amode,mpi_fh,mpi_err,old_type,etype,eig_type,my_nel,ierr,my_nrows
665 : : integer(XMPI_OFFSET_KIND) :: ehdr_offset,my_offset,my_offpad,fmarker
666 : 1 : integer(XMPI_OFFSET_KIND),allocatable :: bsize_frecord(:)
667 : : integer :: array_of_sizes(2),array_of_subsizes(2),array_of_starts(2)
668 : : #endif
669 : : !************************************************************************
670 : :
671 [ + - ]: 1 : if (LEN_TRIM(ihexc_fname) == 0) then
672 : 1 : call wrtout(std_out," Initializing eigenvectors with random numbers","COLL")
673 : : !
674 : : ! Use random number generator. For portability, use only integer numbers
675 : : ! The series of couples (fold1,fold2) is periodic with a period of
676 : : ! 3x5x7x11x13x17x19x23x29x31, that is, larger than 2**32, the largest integer*4
677 : : ! fold1 is between 0 and 34, fold2 is between 0 and 114. As sums of five
678 : : ! uniform random variables, their distribution is close to a gaussian
679 : : ! the gaussian distributions are folded, in order to be back to a uniform distribution
680 : : ! foldre is between 0 and 20, foldim is between 0 and 18.
681 : : !
682 [ + + ]: 11 : do state=1,nstates
683 [ + + ]: 3851 : do ii=my_t1,my_t2
684 : 3840 : seed=ii+(state-1)*hexc_size ! Different seed for different transitions and bands
685 : 3840 : fold1 =mod(seed,3)+mod(seed,5)+mod(seed,7)+mod(seed,11)+mod(seed,13)
686 : 3840 : fold2 =mod(seed,17)+mod(seed,19)+mod(seed,23)+mod(seed,29)+mod(seed,31)
687 : 3840 : foldre=mod(fold1+fold2,21)
688 : 3840 : foldim=mod(3*fold1+2*fold2,19)
689 : :
690 : 3850 : phi_block(ii,state) = DCMPLX(foldre,foldim)
691 : : end do
692 : : end do
693 : :
694 : : else
695 : :
696 : 0 : call cwtime(cputime, walltime, gflops, "start")
697 : :
698 [ # # ]: 0 : if (.not.use_mpio) then
699 [ # # ]: 0 : call wrtout(std_out," Initializing eigenvectors from file: "//TRIM(ihexc_fname)//" using Fortran IO.","COLL")
700 : :
701 [ # # ]: 0 : if (open_file(ihexc_fname,msg,newunit=eig_unt,form='unformatted',status="old") /=0 ) then
702 : 0 : ABI_ERROR(msg)
703 : : end if
704 : :
705 [ # # ]: 0 : read(eig_unt, err=10, iomsg=errmsg) hexc_size_restart
706 [ # # ]: 0 : ABI_CHECK(hexc_size_restart==hexc_size,"hexc_size_restart /= hexc_size")
707 [ # # ]: 0 : read(eig_unt, err=10, iomsg=errmsg) !skip DCMPLX(exevl(1:hexc_size))
708 : :
709 [ # # # # : 0 : ABI_MALLOC(buffer_dpc,(hexc_size))
# # # # #
# # # #
# ]
710 [ # # ]: 0 : do ii=1,nstates
711 [ # # ]: 0 : read(eig_unt, err=10, iomsg=errmsg) buffer_dpc
712 [ # # ]: 0 : phi_block(my_t1:my_t2,ii) = buffer_dpc(my_t1:my_t2)
713 : : end do
714 [ # # ]: 0 : ABI_FREE(buffer_dpc)
715 : :
716 [ # # ]: 0 : close(eig_unt, err=10, iomsg=errmsg)
717 : : else
718 [ # # ]: 0 : call wrtout(std_out," Initializing eigenvectors from file: "//TRIM(ihexc_fname)//" using MPI-IO.","COLL")
719 : : #ifdef HAVE_MPI_IO
720 : : !
721 : : ! Open the file with MPI-IO
722 : 0 : amode=MPI_MODE_RDONLY
723 : :
724 : 0 : call MPI_FILE_OPEN(comm, ihexc_fname, amode, MPI_INFO_NULL, mpi_fh, mpi_err)
725 [ # # ]: 0 : msg = " MPI_IO error opening file: "//TRIM(ihexc_fname)
726 : 0 : ABI_CHECK_MPI(mpi_err,msg)
727 : :
728 : : ! Move the file pointer to skip the first two records.
729 : 0 : ehdr_offset=0
730 : 0 : call xmpio_read_frm(mpi_fh,ehdr_offset,xmpio_collective,fmarker,mpi_err)
731 : 0 : write(std_out,*)"fmarker first record ",fmarker
732 : 0 : call xmpio_read_frm(mpi_fh,ehdr_offset,xmpio_collective,fmarker,mpi_err)
733 : 0 : write(std_out,*)"fmarker first record ",fmarker
734 : : !%call hdr_mpio_skip(mpi_fh,fform,ehdr_offset)
735 : : !%ehdr_offset = 4*xmpio_bsize_frm + xmpio_bsize_int + nstates*xmpio_bsize_dpc
736 : :
737 : 0 : etype=MPI_BYTE; old_type=MPI_DOUBLE_COMPLEX
738 : :
739 : 0 : my_nrows=my_t2-my_t1+1; old_type=MPI_DOUBLE_COMPLEX
740 [ # # ]: 0 : array_of_sizes = (/hexc_size,nstates/)
741 [ # # ]: 0 : array_of_subsizes = (/my_nrows,nstates/)
742 [ # # ]: 0 : array_of_starts = (/my_t1,1/)
743 : 0 : call xmpio_create_fsubarray_2D(array_of_sizes,array_of_subsizes,array_of_starts,old_type,eig_type,my_offpad,mpi_err)
744 : 0 : ABI_CHECK_MPI(mpi_err,"fsubarray_2D")
745 : : !
746 : : ! Each node uses a different offset to skip the header and the blocks written by the other CPUs.
747 : 0 : my_offset = ehdr_offset + my_offpad
748 : :
749 : 0 : call MPI_FILE_SET_VIEW(mpi_fh, my_offset, etype, eig_type, 'native', MPI_INFO_NULL, mpi_err)
750 : 0 : ABI_CHECK_MPI(mpi_err,"SET_VIEW")
751 : :
752 : 0 : call MPI_TYPE_FREE(eig_type,mpi_err)
753 : 0 : ABI_CHECK_MPI(mpi_err,"MPI_TYPE_FREE")
754 : :
755 : 0 : my_nel = my_nrows*nstates
756 : 0 : call MPI_FILE_READ_ALL(mpi_fh, phi_block, my_nel, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpi_err)
757 : 0 : ABI_CHECK_MPI(mpi_err,"FILE_READ")
758 : :
759 : : ! It seems that personal calls make the code stuck
760 : : ! check the fortran markers.
761 [ # # # # : 0 : ABI_MALLOC(bsize_frecord,(nstates))
# # # # #
# # # ]
762 [ # # ]: 0 : bsize_frecord = hexc_size * xmpi_bsize_dpc
763 : : ! ehdr_offset points to the end of the header.
764 : 0 : call xmpio_check_frmarkers(mpi_fh,ehdr_offset,xmpio_collective,nstates,bsize_frecord,ierr)
765 [ # # ]: 0 : ABI_CHECK(ierr==0,"Error in Fortran markers")
766 [ # # ]: 0 : ABI_FREE(bsize_frecord)
767 : : !
768 : : ! Close the file.
769 : 0 : call MPI_FILE_CLOSE(mpi_fh, mpi_err)
770 : 0 : ABI_CHECK_MPI(mpi_err,"FILE_CLOSE")
771 : : #else
772 : : ABI_ERROR("You should not be here")
773 : : #endif
774 : : end if
775 : :
776 : 0 : call cwtime(cputime, walltime, gflops, "stop")
777 : 0 : write(msg,'(2(a,f9.1),a)')" IO operation completed. cpu_time: ",cputime,"[s], walltime: ",walltime," [s]"
778 : 0 : call wrtout(std_out, msg, "COLL", do_flush=.True.)
779 : : end if
780 : :
781 : 1 : return
782 : :
783 : : ! Handle IO-error
784 : : 10 continue
785 : 0 : ABI_ERROR(errmsg)
786 : :
787 [ - - + - ]: 1 : end subroutine exc_init_phi_block
788 : : !!***
789 : :
790 : : !----------------------------------------------------------------------
791 : :
792 : : !!****f* m_exc_itdiago/exc_write_phi_block
793 : : !! NAME
794 : : !! exc_write_phi_block
795 : : !!
796 : : !! FUNCTION
797 : : !! Write phi_block on the Fortran file oeig_fname.
798 : : !!
799 : : !! SOURCE
800 : :
801 : 1 : subroutine exc_write_phi_block(oeig_fname,use_mpio)
802 : :
803 : : !Arguments ------------------------------------
804 : : !scalars
805 : : character(len=*),intent(in) :: oeig_fname
806 : : logical,intent(in) :: use_mpio
807 : :
808 : : !Local variables ------------------------------
809 : : integer :: eig_unt,state,mpi_err !,fform
810 : : real(dp) :: cputime,walltime,gflops
811 : : character(len=500) :: msg,errmsg
812 : : ! type(Hdr_type) :: hexc_Hdr
813 : : logical :: do_ep_lifetime
814 : : !!arrays
815 : 1 : complex(dp),allocatable :: buffer_dpc(:)
816 : : #ifdef HAVE_MPI_IO
817 : : integer:: amode,mpi_fh,old_type,etype,eig_type,my_nel,ierr,my_nrows
818 : : integer(XMPI_OFFSET_KIND) :: ehdr_offset,my_offset,my_offpad,fmarker
819 : 1 : integer(XMPI_OFFSET_KIND),allocatable :: bsize_frecord(:)
820 : : integer :: array_of_sizes(2),array_of_subsizes(2),array_of_starts(2)
821 : : #endif
822 : : !************************************************************************
823 : :
824 : 1 : do_ep_lifetime = .FALSE.
825 : :
826 : 1 : call cwtime(cputime, walltime, gflops, "start")
827 : :
828 [ + - ]: 1 : if (.not.use_mpio) then
829 : :
830 : : ! * Master writes the header.
831 [ + - ]: 1 : if (my_rank==master) then
832 [ + - ]: 1 : call wrtout(std_out," Writing eigenstates on file "//TRIM(oeig_fname)//" via Fortran-IO","COLL")
833 [ - + ]: 1 : if (open_file(oeig_fname,msg, newunit=eig_unt, form='unformatted') /= 0) then
834 : 0 : ABI_ERROR(msg)
835 : : end if
836 [ + - ]: 1 : write(eig_unt, err=10, iomsg=errmsg) do_ep_lifetime
837 [ + - ]: 1 : write(eig_unt, err=10, iomsg=errmsg) hexc_size, nstates
838 [ + + + - ]: 11 : write(eig_unt, err=10, iomsg=errmsg) CMPLX(exc_energy(1:nstates),kind=dp)
839 : : end if
840 : :
841 : : ! Wavefunctions are gathered on the master node band-by-band.
842 : : ! TODO bands should be treated in blocks to minimize the number of MPI calls.
843 [ - + + - : 3 : ABI_MALLOC_OR_DIE(buffer_dpc,(hexc_size), ierr)
+ - + - +
- + - - +
+ - - + ]
844 : :
845 [ + + ]: 11 : do state=1,nstates
846 [ + + ]: 3850 : buffer_dpc=czero
847 [ + + ]: 3850 : buffer_dpc(my_t1:my_t2) = phi_block(:,state)
848 : 10 : call xmpi_sum_master(buffer_dpc,master,comm,mpi_err)
849 [ + - + - ]: 11 : if (my_rank==master) write(eig_unt, err=10, iomsg=errmsg) buffer_dpc(1:hexc_size)
850 : : end do
851 [ - + ]: 1 : ABI_FREE(buffer_dpc)
852 : :
853 [ + - + - ]: 1 : if (my_rank==master) close(eig_unt, err=10, iomsg=errmsg)
854 : :
855 : : else
856 : : #ifdef HAVE_MPI_IO
857 [ # # ]: 0 : call wrtout(std_out," Writing eigenstates on file "//TRIM(oeig_fname)//" with MPI-IO","COLL")
858 : :
859 : : ! Write the header.
860 [ # # ]: 0 : if (my_rank==master) then
861 : : ! Write header using Fortran primitives.
862 [ # # ]: 0 : if (open_file(oeig_fname,msg,newunit=eig_unt,form='unformatted') /= 0) then
863 : 0 : ABI_ERROR(msg)
864 : : end if
865 [ # # ]: 0 : write(eig_unt, err=10, iomsg=errmsg) nstates
866 [ # # # # ]: 0 : write(eig_unt, err=10, iomsg=errmsg) CMPLX(exc_energy(1:nstates),kind=dp)
867 : : ! TODO: change setup_bse so that Hdr_bse reflects the parameters of the run.
868 [ # # ]: 0 : close(eig_unt, err=10, iomsg=errmsg)
869 : : end if
870 : :
871 : 0 : call xmpi_barrier(comm)
872 : :
873 : : ! Open the file with MPI-IO
874 : 0 : amode=MPI_MODE_RDWR
875 : :
876 : 0 : call MPI_FILE_OPEN(comm, oeig_fname, amode, MPI_INFO_NULL, mpi_fh, mpi_err)
877 [ # # ]: 0 : msg = " MPI_IO error opening file: "//TRIM(oeig_fname)
878 : 0 : ABI_CHECK_MPI(mpi_err,msg)
879 : :
880 : : ! Move the file pointer to skip the first two records.
881 : 0 : ehdr_offset=0
882 : 0 : call xmpio_read_frm(mpi_fh,ehdr_offset,xmpio_collective,fmarker,mpi_err)
883 : : !write(std_out,*)"fmarker first record ",fmarker
884 : 0 : call xmpio_read_frm(mpi_fh,ehdr_offset,xmpio_collective,fmarker,mpi_err)
885 : : !write(std_out,*)"fmarker first record ",fmarker
886 : : !$call hdr_mpio_skip(mpi_fh,fform,ehdr_offset)
887 : : !$ehdr_offset = 4*xmpio_bsize_frm + xmpio_bsize_int + nstates*xmpio_bsize_dpc
888 : :
889 : 0 : etype=MPI_BYTE; old_type=MPI_DOUBLE_COMPLEX
890 : :
891 : 0 : my_nrows=my_t2-my_t1+1; old_type=MPI_DOUBLE_COMPLEX
892 [ # # ]: 0 : array_of_sizes = (/hexc_size,nstates/)
893 [ # # ]: 0 : array_of_subsizes = (/my_nrows,nstates/)
894 [ # # ]: 0 : array_of_starts = (/my_t1,1/)
895 : 0 : call xmpio_create_fsubarray_2D(array_of_sizes,array_of_subsizes,array_of_starts,old_type,eig_type,my_offpad,mpi_err)
896 : 0 : ABI_CHECK_MPI(mpi_err,"fsubarray_2D")
897 : : !
898 : : ! Each node uses a different offset to skip the header and the blocks written by the other CPUs.
899 : 0 : my_offset = ehdr_offset + my_offpad
900 : :
901 : 0 : call MPI_FILE_SET_VIEW(mpi_fh, my_offset, etype, eig_type, 'native', MPI_INFO_NULL, mpi_err)
902 : 0 : ABI_CHECK_MPI(mpi_err,"SET_VIEW")
903 : :
904 : 0 : call MPI_TYPE_FREE(eig_type,mpi_err)
905 : 0 : ABI_CHECK_MPI(mpi_err,"MPI_TYPE_FREE")
906 : :
907 : 0 : my_nel = my_nrows*nstates
908 : 0 : call MPI_FILE_WRITE_ALL(mpi_fh, phi_block, my_nel, MPI_DOUBLE_COMPLEX, MPI_STATUS_IGNORE, mpi_err)
909 : 0 : ABI_CHECK_MPI(mpi_err,"FILE_WRITE")
910 : :
911 : : ! It seems that personal calls make the code stuck
912 [ # # # # : 0 : ABI_MALLOC(bsize_frecord,(nstates))
# # # # #
# # # ]
913 [ # # ]: 0 : bsize_frecord = hexc_size * xmpi_bsize_dpc
914 : : ! ehdr_offset points to the end of the header.
915 : 0 : call xmpio_write_frmarkers(mpi_fh,ehdr_offset,xmpio_collective,nstates,bsize_frecord,ierr)
916 [ # # ]: 0 : ABI_CHECK(ierr==0,"Error while writing Fortran markers")
917 [ # # ]: 0 : ABI_FREE(bsize_frecord)
918 : : !
919 : : ! Close the file.
920 : 0 : call MPI_FILE_CLOSE(mpi_fh, mpi_err)
921 : 0 : ABI_CHECK_MPI(mpi_err,"FILE_CLOSE")
922 : : #else
923 : : ABI_ERROR("MPI-IO support not enabled")
924 : : #endif
925 : : end if
926 : :
927 : 1 : call cwtime(cputime, walltime, gflops, "stop")
928 : 1 : write(msg,'(2(a,f9.1),a)')" IO operation completed. cpu_time: ",cputime,"[s], walltime: ",walltime," [s]"
929 : 1 : call wrtout(std_out, msg, "COLL", do_flush=.True.)
930 : :
931 : 1 : return
932 : :
933 : : ! Handle IO-error
934 : : 10 continue
935 : 0 : ABI_ERROR(errmsg)
936 : :
937 [ + - - - ]: 1 : end subroutine exc_write_phi_block
938 : : !!***
939 : :
940 : : !----------------------------------------------------------------------
941 : :
942 : : !!****f* m_exc_itdiago/exc_subspace_rotation
943 : : !! NAME
944 : : !! exc_subspace_rotation
945 : : !!
946 : : !! FUNCTION
947 : : !! This routine performs the subspace rotation.
948 : : !!
949 : : !! SIDE EFFECTS
950 : : !! phi_block(my_t1:my_t2,nstates)=Contains the trial eigenstates.
951 : : !!
952 : : !! SOURCE
953 : :
954 : 21 : subroutine exc_subspace_rotation()
955 : :
956 : : !Local variables ------------------------------
957 : : integer :: ii,jj,ipack,ierr
958 : : !arrays
959 : 21 : real(dp),allocatable :: sub_ene(:)
960 : : ! real(dp),allocatable :: evec(:,:)
961 : 21 : complex(dp),allocatable :: sub_ham(:,:),sub_pham(:),hphi_tot(:)
962 : : ! complex(dp),allocatable :: phi_tmp(:,:)
963 : : !************************************************************************
964 : :
965 : : ! * Sub-space rotation. Calculate <phi_i|H|phi_j> in packed form.
966 : : ! TODO: this part can be rewritten using BLAS3 routines.
967 : :
968 [ - + + - : 63 : ABI_MALLOC(hphi_tot,(hexc_size))
+ - + - -
+ - + ]
969 [ + - - + : 63 : ABI_MALLOC(sub_pham,(nstates*(nstates+1)/2))
+ - + - +
- - + -
+ ]
970 [ + + ]: 1176 : sub_pham=czero; ipack=0
971 : :
972 [ + + ]: 231 : do jj=1,nstates
973 [ + + ]: 80850 : hphi_tot = czero
974 [ + + + + : 124024530 : hphi_tot(:) = MATMUL(hexc, phi_block(:,jj))
+ + + - +
- + - +
- ]
975 : 210 : call xmpi_sum(hphi_tot,comm,ierr)
976 : :
977 [ + + ]: 1386 : do ii=1,jj
978 : 1155 : ipack=ipack+1
979 [ + + ]: 444675 : sub_pham(ipack) = DOT_PRODUCT(phi_block(my_t1:my_t2,ii), hphi_tot(my_t1:my_t2) )
980 [ + + ]: 1365 : if (ii==jj) sub_pham(ipack) = REAL(sub_pham(ipack),kind=dp)
981 : : end do
982 : : end do
983 : 21 : call xmpi_sum(sub_pham,comm,ierr)
984 : :
985 [ - + + - : 84 : ABI_MALLOC(sub_ham,(nstates,nstates))
- + + - +
- + - - +
- + ]
986 [ + + + + ]: 2331 : sub_ham=czero
987 [ - + + - : 63 : ABI_MALLOC(sub_ene,(nstates))
+ - + - -
+ - + ]
988 : :
989 : 21 : call xhpev("Vectors","Upper",nstates,sub_pham,sub_ene,sub_ham,nstates) !,comm)
990 : :
991 [ - + ]: 21 : ABI_FREE(hphi_tot)
992 [ - + ]: 21 : ABI_FREE(sub_pham)
993 [ - + ]: 21 : ABI_FREE(sub_ene)
994 : :
995 : : !do ii=1,nstates
996 : : ! norm = DOT_PRODUCT(sub_ham(:,ii),sub_ham(:,ii))
997 : : ! write(std_out,*)"norm subspac",norm
998 : : ! sub_ham(:,ii) = sub_ham(:,ii)/norm
999 : : !end do
1000 : :
1001 : : !allocate(evec(2*nstates,nstates))
1002 : :
1003 : : !do ii=1,nstates
1004 : : ! do jj=1,nstates
1005 : : ! evec(jj, ii) = REAL (sub_ham(jj,ii))
1006 : : ! evec(jj+1,ii) = AIMAG(sub_ham(jj,ii))
1007 : : ! end do
1008 : : !end do
1009 : :
1010 : : !call normev(evec,nstates,nstates)
1011 : :
1012 : : !do ii=1,nstates
1013 : : ! do jj=1,nstates
1014 : : ! sub_ham(jj,ii) = CMPLX( evec(jj,ii),evec(jj+1,ii) )
1015 : : ! end do
1016 : : !end do
1017 : : !deallocate(evec)
1018 : :
1019 : : #if 0
1020 : : ABI_MALLOC(phi_tmp,(my_nt,nstates))
1021 : : phi_tmp = phi_block
1022 : :
1023 : : call ZGEMM('N','N',my_nt,nstates,nstates,cone,phi_tmp,my_nt,sub_ham,nstates,czero,phi_block,my_nt)
1024 : :
1025 : : ABI_FREE(phi_tmp)
1026 : : #else
1027 [ + - + - : 161784 : phi_block = MATMUL(phi_block,sub_ham)
+ + + + -
+ - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - -
- - - - +
- + - - +
- - + + +
+ + - ]
1028 : : #endif
1029 : :
1030 [ - + ]: 21 : ABI_FREE(sub_ham)
1031 : :
1032 : 21 : end subroutine exc_subspace_rotation
1033 : : !!***
1034 : :
1035 : : !----------------------------------------------------------------------
1036 : :
1037 : : !!****f* m_exc_itdiago/exc_cholesky_ortho
1038 : : !! NAME
1039 : : !! exc_cholesky_ortho
1040 : : !!
1041 : : !! FUNCTION
1042 : : !! This routine performs the orthogonalization of the trial eigenstates using the
1043 : : !! Cholesky Algorithm.
1044 : : !!
1045 : : !! SIDE EFFECTS
1046 : : !! phi_block(my_t1:my_t2,nstates)=Contains the trial eigenstates.
1047 : : !!
1048 : : !! SOURCE
1049 : :
1050 : 21 : subroutine exc_cholesky_ortho()
1051 : :
1052 : : !Local variables ------------------------------
1053 : : integer :: my_info,ii,jj,ipack,ierr
1054 : : logical,parameter :: use_unpacked = .False.
1055 : : !arrays
1056 : 21 : complex(dp),allocatable :: overlap(:,:),povlp(:)
1057 : : !************************************************************************
1058 : :
1059 : : ! 1) overlap_ij = <phi_i|phi_j>
1060 [ - + + - : 84 : ABI_MALLOC(overlap, (nstates,nstates))
- + + - +
- + - - +
- + ]
1061 : :
1062 : : if (use_unpacked) then
1063 : : overlap = czero
1064 : :
1065 : : call ZGEMM('C','N',nstates,nstates,my_nt,cone,phi_block,my_nt,phi_block,my_nt,czero,overlap,nstates)
1066 : : call xmpi_sum(overlap,comm,ierr)
1067 : :
1068 : : do ii=1,nstates
1069 : : overlap(ii,ii)=REAL(overlap(ii,ii),kind=dp)
1070 : : end do
1071 : :
1072 : : ! 2) Cholesky factorization: overlap = U^H U with U upper triangle matrix.
1073 : : call ZPOTRF('U',nstates,overlap,nstates,my_info)
1074 : : if (my_info/=0) then
1075 : : write(msg,'(a,i3)')' ZPOTRF returned info= ',my_info
1076 : : ABI_ERROR(msg)
1077 : : end if
1078 : :
1079 : : else
1080 : : ! 1) Calculate overlap_ij = <phi_i|phi_j> in packed form.
1081 [ + - - + : 63 : ABI_MALLOC(povlp,(nstates*(nstates+1)/2))
+ - + - +
- - + -
+ ]
1082 [ + + ]: 1176 : povlp = czero; ipack=0
1083 [ + + ]: 231 : do jj=1,nstates
1084 [ + + ]: 1386 : do ii=1,jj
1085 : 1155 : ipack=ipack+1
1086 [ + + ]: 444675 : povlp(ipack) = DOT_PRODUCT( phi_block(my_t1:my_t2,ii), phi_block(my_t1:my_t2,jj) )
1087 [ + + ]: 1365 : if (ii==jj) povlp(ipack) = REAL(povlp(ipack),kind=dp)
1088 : : end do
1089 : : end do
1090 : 21 : call xmpi_sum(povlp,comm,ierr)
1091 : :
1092 : : ! 2) Cholesky factorization: overlap = U^H U with U upper triangle matrix.
1093 : 21 : call ZPPTRF("U",nstates,povlp,my_info)
1094 [ - + ]: 21 : if (my_info/=0) then
1095 : 0 : write(msg,'(a,i3)')' ZPPTRF returned info= ',my_info
1096 : 0 : ABI_ERROR(msg)
1097 : : end if
1098 : : !call xmpi_sum(povlp,comm,ierr)
1099 : : !povlp=povlp/nproc
1100 : :
1101 : : !unpack povlp to prepare call to ZTRSM.
1102 : 21 : ipack=0
1103 [ + + ]: 231 : do jj=1,nstates
1104 [ + + ]: 1386 : do ii=1,jj
1105 : 1155 : ipack=ipack+1
1106 [ + + ]: 1365 : if (ii/=jj) then
1107 : 945 : overlap(ii,jj)= povlp(ipack)
1108 : 945 : overlap(jj,ii)=CONJG(povlp(ipack))
1109 : : else
1110 : 210 : overlap(ii,ii)=REAL(povlp(ipack),kind=dp)
1111 : : end if
1112 : : end do
1113 : : end do
1114 [ - + ]: 42 : ABI_FREE(povlp)
1115 : : end if
1116 : :
1117 : : ! Check if this can be done with Scalapack. Direct PZTRSM is not provided
1118 : :
1119 : : ! 3) Solve X U = phi_block, on exit the phi_block treated by this node is orthonormalized.
1120 : : !call ZTRSM('R','U','N','N',hexc_size,nstates,cone,overlap,nstates,phi_block,hexc_size)
1121 : 21 : call ZTRSM('Right','Upper','Normal','Normal',my_nt,nstates,cone,overlap,nstates,phi_block,my_nt)
1122 [ - + ]: 21 : ABI_FREE(overlap)
1123 : :
1124 : 21 : end subroutine exc_cholesky_ortho
1125 : : !!***
1126 : :
1127 : : !----------------------------------------------------------------------
1128 : :
1129 : : !!****f* m_exc_itdiago/convergence_degree
1130 : : !! NAME
1131 : : !! convergence_degree
1132 : : !!
1133 : : !! FUNCTION
1134 : : !! Return the degree of convergence from the input residual.
1135 : : !!
1136 : : !! INPUTS
1137 : : !! resid=Residual.
1138 : : !!
1139 : : !! OUTPUT
1140 : : !!
1141 : : !! SOURCE
1142 : :
1143 : 736 : function convergence_degree(resid)
1144 : :
1145 : : !Arguments
1146 : : integer :: convergence_degree
1147 : : real(dp),intent(in) :: resid
1148 : :
1149 : : !************************************************************************
1150 : :
1151 [ + + ]: 736 : if (resid<tolwfr_) then
1152 : : convergence_degree = STRICT
1153 : : else
1154 : 713 : convergence_degree = WORST
1155 [ + + ]: 713 : if (resid<tolwfr_*10**5) convergence_degree = MEDIUM
1156 : : end if
1157 : :
1158 : : end function convergence_degree
1159 : : !!***
1160 : :
1161 : : !----------------------------------------------------------------------
1162 : :
1163 : : !!****f* m_exc_itdiago/exc_check_phi_block
1164 : : !! NAME
1165 : : !! exc_check_phi_block
1166 : : !!
1167 : : !! FUNCTION
1168 : : !! Debugging tools
1169 : : !!
1170 : : !! INPUTS
1171 : : !!
1172 : : !! OUTPUT
1173 : : !!
1174 : : !! SOURCE
1175 : :
1176 : : subroutine exc_check_phi_block(string)
1177 : :
1178 : : !Arguments ------------------------------------
1179 : : !scalars
1180 : : character(len=*),intent(in) :: string
1181 : :
1182 : : !Local variables ------------------------------
1183 : : !scalars
1184 : : integer :: ii,jj,ierr
1185 : : real(dp) :: err,rdum
1186 : : !arrays
1187 [ - + - + ]: 22 : complex(dp),allocatable :: lbuff(:,:)
1188 : : !************************************************************************
1189 : :
1190 : : if (.not. DEBUGME) return
1191 : :
1192 : : #if 0
1193 : : ABI_MALLOC(lbuff,(hexc_size,nstates))
1194 : : err = -one
1195 : : do irank=1,nproc-1
1196 : : call xmpi_exch(phi_block,hexc_size*nstates,irank,lbuff,master,comm,11,ierr)
1197 : : if (my_rank==master) then
1198 : : lbuff = lbuff-phi_block
1199 : : err = MAX(err,MAXVAL(MAXVAL(ABS(lbuff),DIM=1)))
1200 : : end if
1201 : : call xmpi_barrier(comm)
1202 : : end do
1203 : : ABI_FREE(lbuff)
1204 : : #else
1205 : :
1206 : : ABI_MALLOC(lbuff,(nstates,nstates))
1207 : : lbuff=czero
1208 : : do jj=1,nstates
1209 : : do ii=1,jj
1210 : : lbuff(ii,jj) = DOT_PRODUCT( phi_block(my_t1:my_t2,ii), phi_block(my_t1:my_t2,jj) )
1211 : : end do
1212 : : end do
1213 : : call xmpi_sum(lbuff,comm,ierr)
1214 : :
1215 : : err = -one
1216 : : do jj=1,nstates
1217 : : do ii=1,jj
1218 : : if (ii==jj) then
1219 : : rdum = ABS(lbuff(ii,jj)-one)
1220 : : else
1221 : : rdum = ABS(lbuff(ii,jj))
1222 : : end if
1223 : : err = MAX(err,rdum)
1224 : : end do
1225 : : end do
1226 : : ABI_FREE(lbuff)
1227 : : #endif
1228 : :
1229 : : if (my_rank==master) then
1230 : : write(std_out,*)"After ",TRIM(string),", MAX inconsistency error in phi_block= ",err
1231 : : end if
1232 : :
1233 : : !write(std_out,*)"master casts its own data"
1234 : : !call xmpi_bcast(phi_block,master,comm,ierr)
1235 : :
1236 : : end subroutine exc_check_phi_block
1237 : : !!***
1238 : :
1239 : : !----------------------------------------------------------------------
1240 : :
1241 : : end subroutine exc_iterative_diago
1242 : : !!***
1243 : :
1244 : : end module m_exc_itdiago
1245 : : !!***
|