Branch data Line data Source code
1 : : !!****m* ABINIT/m_haydock
2 : : !! NAME
3 : : !! m_haydock
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !! COPYRIGHT
8 : : !! Copyright (C) 2008-2026 ABINIT group (M.Giantomassi, Y. Gillet, L.Reining, V.Olevano, F.Sottile, S.Albrecht, G.Onida)
9 : : !! This file is distributed under the terms of the
10 : : !! GNU General Public License, see ~abinit/COPYING
11 : : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : : !!
13 : : !! SOURCE
14 : :
15 : : #if defined HAVE_CONFIG_H
16 : : #include "config.h"
17 : : #endif
18 : :
19 : : #include "abi_common.h"
20 : :
21 : : MODULE m_haydock
22 : :
23 : : use defs_basis
24 : : use m_abicore
25 : : use m_bs_defs
26 : : use m_xmpi
27 : : use m_errors
28 : : use m_haydock_io
29 : : use m_linalg_interfaces
30 : : use netcdf
31 : : use m_nctk
32 : :
33 : : use m_time, only : timab
34 : : use m_fstrings, only : strcat, sjoin, itoa, int2char4
35 : : use m_io_tools, only : file_exists, open_file
36 : : use defs_datatypes, only : pseudopotential_type
37 : : use m_geometry, only : normv
38 : : use m_hide_blas, only : xdotc, xgemv
39 : : use m_hide_lapack, only : matrginv
40 : : use m_numeric_tools, only : print_arr, symmetrize, hermitianize, continued_fract, wrap2_pmhalf, iseven
41 : : use m_kpts, only : listkk
42 : : use m_crystal, only : crystal_t
43 : : use m_ebands, only : ebands_t
44 : : use m_hdr, only : hdr_type
45 : : use m_bz_mesh, only : kmesh_t, findqg0
46 : : use m_double_grid, only : double_grid_t, get_kpt_from_indices_coarse, compute_corresp
47 : : use m_paw_hr, only : pawhur_t
48 : : use m_wfd, only : wfdgw_t
49 : : use m_bse_io, only : exc_write_optme
50 : : use m_pawtab, only : pawtab_type
51 : : use m_vcoul, only : vcoul_t
52 : : use m_hexc, only : hexc_t, hexc_interp_t
53 : : use m_exc_spectra, only : exc_write_data, exc_eps_rpa, exc_write_tensor, mdfs_ncwrite
54 : : use m_eprenorms, only : eprenorms_t, renorm_bst
55 : : use m_wfd_optic, only : calc_optical_mels
56 : :
57 : : implicit none
58 : :
59 : : private
60 : : !!***
61 : :
62 : : public :: exc_haydock_driver ! Driver for the Haydock method (main entry point for client code).
63 : :
64 : : CONTAINS !=======================================================================
65 : : !!***
66 : :
67 : : !!****f* m_haydock/exc_haydock_driver
68 : : !! NAME
69 : : !! exc_haydock_driver
70 : : !!
71 : : !! FUNCTION
72 : : !! Calculate the imaginary part of the macroscopic dielectric function with the Haydock recursive method.
73 : : !!
74 : : !! INPUTS
75 : : !! BSp<type(excparam)=The parameter for the Bethe-Salpeter run.
76 : : !! BS_files<excparam>=Files associated to the bethe_salpeter code.
77 : : !! Cryst<crystal_t>=Info on the crystalline structure.
78 : : !! Kmesh<type(kmesh_t)>=The list of k-points in the BZ, IBZ and symmetry tables.
79 : : !! Cryst<type(crystal_t)>=Info on the crystalline structure.
80 : : !! Hdr_bse
81 : : !! KS_BSt=The KS energies.
82 : : !! QP_BSt=The QP energies.
83 : : !! Wfd<wfdgw_t>=Wavefunction descriptor (input k-mesh)
84 : : !! Psps <type(pseudopotential_type)>=variables related to pseudopotentials.
85 : : !! Pawtab(Cryst%ntypat*usepaw)<pawtab_type>=PAW tabulated starting data.
86 : : !! Hur(Cryst%natom*usepaw)<type(pawhur_t)>=Only for PAW and DFT+U, quantities used to evaluate the commutator [H_u,r].
87 : : !!
88 : : !! OUTPUT
89 : : !! The imaginary part of the macroscopic dielectric function is written on the external file _EXC_MDF
90 : : !!
91 : : !! SOURCE
92 : :
93 : 23 : subroutine exc_haydock_driver(BSp,BS_files,Cryst,Kmesh,Hdr_bse,KS_BSt,QP_Bst,Wfd,Psps,Pawtab,Hur,Epren, &
94 : : Kmesh_dense, KS_BSt_dense, QP_BSt_dense, Wfd_dense, Vcp_dense, grid) ! Optional args
95 : :
96 : : !Arguments ------------------------------------
97 : : !scalars
98 : : type(excparam),intent(in) :: BSp
99 : : type(excfiles),intent(in) :: BS_files
100 : : type(kmesh_t),intent(in) :: Kmesh
101 : : type(crystal_t),intent(in) :: Cryst
102 : : type(Hdr_type),intent(in) :: Hdr_bse
103 : : type(wfdgw_t),intent(inout) :: Wfd
104 : : type(pseudopotential_type),intent(in) :: Psps
105 : : type(ebands_t),intent(in) :: KS_BSt,QP_Bst
106 : : type(double_grid_t),intent(in),optional :: grid
107 : : type(kmesh_t),intent(in),optional :: Kmesh_dense
108 : : type(wfdgw_t),intent(inout),optional :: Wfd_dense
109 : : type(ebands_t),intent(in),optional :: KS_BSt_dense, QP_Bst_dense
110 : : type(vcoul_t),intent(in),optional :: Vcp_dense
111 : : type(eprenorms_t),intent(in) :: Epren
112 : : !arrays
113 : : type(pawtab_type),intent(in) :: Pawtab(Cryst%ntypat*Wfd%usepaw)
114 : : type(pawhur_t),intent(in) :: Hur(Cryst%natom*Wfd%usepaw)
115 : :
116 : : !Local variables ------------------------------
117 : : !scalars
118 : : integer,parameter :: master=0
119 : : integer :: io,my_rank,iq,itt,ierr
120 : : integer :: hsize,comm,my_t1,my_t2,nsppol,nkets,nproc,ncid
121 : : integer :: spin,spad,ik_bz,iv,ic,trans_idx,lomo_min,max_band
122 : : real(dp) :: omegaev,rand_phi !,norm
123 : : complex(dp) :: ks_avg,gw_avg,exc_avg
124 : : logical :: use_mpio,prtdos
125 : : character(len=500) :: msg
126 : 23 : type(hexc_t) :: hexc
127 : 23 : type(hexc_interp_t) :: hexc_i
128 : : !arrays
129 : : real(dp) :: tsec(2)
130 : 23 : real(dp),allocatable :: dos(:),dos_gw(:),dos_ks(:)
131 : 23 : complex(dp),allocatable :: green(:,:)
132 : 23 : complex(dp),allocatable :: opt_cvk(:,:,:,:,:),kets(:,:)
133 : 23 : complex(dp),allocatable :: eps_rpanlf(:,:),eps_gwnlf(:,:)
134 : 23 : complex(dp),allocatable :: tensor_cart(:,:),tensor_cart_rpanlf(:,:),tensor_cart_gwnlf(:,:)
135 : 23 : complex(dp),allocatable :: tensor_red(:,:),tensor_red_rpanlf(:,:),tensor_red_gwnlf(:,:)
136 : :
137 : : !Temperature
138 : : integer :: ep_ik, ik, ireh, isppol, itemp, ntemp
139 : : real(dp) :: dksqmax, en
140 : 23 : integer,allocatable :: bs2eph(:,:)
141 : : integer :: sppoldbl, timrev
142 : : logical :: do_ep_renorm, do_ep_lifetime
143 : : character(len=4) :: ts
144 : : character(len=fnlen) :: prefix, path
145 : 23 : complex(dp),allocatable :: ep_renorms(:)
146 : 23 : type(ebands_t) :: EPBSt, EP_QPBSt
147 : : !************************************************************************
148 : :
149 : 23 : call timab(690,1,tsec) ! exc_haydock_driver
150 : 23 : call timab(691,1,tsec) ! exc_haydock_driver(read)
151 : :
152 [ - + ]: 23 : if (BSp%have_complex_ene) then
153 : 0 : ABI_ERROR("Complex energies are not supported yet")
154 : : end if
155 : :
156 : 23 : my_rank = Wfd%my_rank
157 : 23 : comm = Wfd%comm
158 : 23 : nsppol = Wfd%nsppol
159 : 23 : nproc = Wfd%nproc
160 : :
161 : : use_mpio=.FALSE.
162 : : #ifdef HAVE_MPI_IO
163 : : use_mpio = (nproc > 1)
164 : : !use_mpio = .TRUE.
165 : : #endif
166 : 23 : use_mpio=.FALSE.
167 : : !use_mpio = .TRUE.
168 : :
169 : : ! Hsize refers to the size of the individual blocks (resonant and coupling).
170 : : ! Thanks to the symmetry property of the starting vector, the Haydock method
171 : : ! can be reformulated in terms of matrix-vector multiplication involving the
172 : : ! blocks thus avoiding to allocation of the full matrix ( R C )
173 : : ! -C* -R*)
174 [ + + ]: 46 : hsize=SUM(BSp%nreh)
175 : :
176 : : !YG2014
177 : 23 : call hexc%init(BSp, BS_files, Cryst, Kmesh, Wfd, KS_BSt, QP_BSt, comm)
178 : :
179 : : !YG2014
180 [ + + ]: 23 : if(BSp%use_interp) then
181 : : call hexc_i%init(hexc, BSp%interp_m3_width, BSp%interp_method,&
182 : : Kmesh_dense, Vcp_dense, grid, Wfd_dense, &
183 : 4 : KS_BSt_dense, QP_BSt_dense, Psps, Pawtab)
184 : : end if
185 : :
186 : 23 : call timab(691,2,tsec) ! exc_haydock_driver(read)
187 : 23 : call timab(692,1,tsec) ! exc_haydock_driver(prep)
188 : :
189 : : ! Prepare the starting vectors for the Lanczos chain.
190 : 23 : nkets=Bsp%nq
191 : :
192 : 23 : prtdos=.FALSE. !prtdos=.TRUE.
193 : : if (prtdos) then
194 : : nkets=nkets+1
195 : : if (Bsp%use_coupling>0) then
196 : : ABI_ERROR("DOS with coupling not coded")
197 : : nkets=nkets+1
198 : : end if
199 : : end if
200 : :
201 : : !YG2014
202 [ - + + - : 92 : ABI_MALLOC_OR_DIE(kets,(hexc%hsize,nkets), ierr)
- + + - +
- + - + -
- + - + ]
203 [ + + + + ]: 64289 : kets=czero
204 : : !
205 : : ! Prepare the kets for the macroscopic dielectric function.
206 : 23 : lomo_min=Bsp%lomo_min; max_band=Bsp%nbnds
207 : :
208 : : !YG2014
209 [ - + + - : 161 : ABI_MALLOC_OR_DIE(opt_cvk,(lomo_min:max_band,lomo_min:max_band,hexc%nbz,Wfd%nsppol,BSp%nq), ierr)
- + + - -
+ + - - +
+ - - + +
- + - + -
+ - - + -
+ ]
210 : :
211 [ + + ]: 161 : do iq=1,Bsp%nq
212 : : ! Note KS_BSt is used here to calculate the commutator.
213 : : call calc_optical_mels(hexc%Wfd,hexc%Kmesh,hexc%KS_BSt,Cryst,Psps,Pawtab,Hur, &
214 : 138 : & BSp%inclvkb,BSp%lomo_spin,lomo_min,max_band,hexc%nbz,BSp%q(:,iq),opt_cvk(:,:,:,:,iq))
215 : :
216 : : ! Fill ket0 using the same ordering for the indices as the one used for the excitonic Hamiltonian.
217 : : ! Note that only the resonant part is used here.
218 [ + + ]: 299 : do spin=1,nsppol
219 : :
220 [ + + ]: 138 : if(BSp%use_interp) then
221 : 24 : spad=(spin-1)*BSp%nreh_interp(spin)
222 : : else
223 : 114 : spad=(spin-1)*BSp%nreh(spin)
224 : : end if
225 : :
226 [ + + ]: 7524 : do ik_bz=1,hexc%nbz
227 [ + + ]: 28794 : do iv=BSp%lomo_spin(spin),BSp%homo_spin(spin)
228 [ + + ]: 92784 : do ic=BSp%lumo_spin(spin),BSp%nbnds
229 : :
230 [ + + ]: 64128 : if(BSp%use_interp) then
231 : 18432 : trans_idx = BSp%vcks2t_interp(iv,ic,ik_bz,spin)
232 : : else
233 : 45696 : trans_idx = BSp%vcks2t(iv,ic,ik_bz,spin)
234 : : end if
235 : :
236 [ + - ]: 85536 : if (trans_idx>0) kets(trans_idx+spad,iq)=opt_cvk(ic,iv,ik_bz,spin,iq)
237 : : end do
238 : : end do
239 : : end do
240 : : end do
241 : :
242 : : end do
243 : :
244 : : ! ========================================================
245 : : ! === Write the Optical Matrix Elements to NetCDF file ===
246 : : ! ========================================================
247 : :
248 : : !if (.false.) then
249 : : ! ome_fname='test_OME.nc'
250 : : ! call exc_write_optme(ome_fname,minb,maxb,BSp%nkbz,Wfd%nsppol,BSp%nq,opt_cvk,ierr)
251 : : !end if
252 : :
253 : : ! Free WFD descriptor, we don't need ur and ug anymore !
254 : : ! We make space for interpolated hamiltonian
255 : 23 : call wfd%wave_free("All")
256 [ + + ]: 23 : if(BSp%use_interp) call wfd_dense%wave_free("All")
257 : :
258 : : ! Build interpolated hamiltonian
259 [ + + ]: 23 : if(BSp%use_interp) then
260 [ + + ]: 4 : if (any(BSp%interp_mode == [2,3,4])) call hexc%build_hinterp(hexc_i)
261 : : end if
262 : :
263 : 23 : call timab(692,2,tsec) ! exc_haydock_driver(prep)
264 : 23 : call timab(693,1,tsec) ! exc_haydock_driver(wo lf) - that is, without local field
265 : :
266 : 23 : do_ep_renorm = .FALSE.
267 : 23 : ntemp = 1
268 : 23 : do_ep_lifetime = .FALSE.
269 : :
270 [ + + ]: 23 : if(BSp%do_ep_renorm) then
271 [ - + ]: 1 : if (BSp%nsppol == 2) then
272 : 0 : ABI_ERROR('Elphon renorm with nsppol == 2 not yet coded !')
273 : : end if
274 : 1 : do_ep_renorm = .TRUE.
275 : 1 : ntemp = Epren%ntemp
276 : : if(BSp%do_lifetime) do_ep_lifetime = .TRUE.
277 : :
278 : : ! Force elphon linewidth
279 : 1 : do_ep_lifetime = .TRUE.
280 : :
281 : : ! Map points from BSE to elphon kpoints
282 : 1 : sppoldbl = 1 !; if (any(Cryst%symafm == -1) .and. Epren%nsppol == 1) nsppoldbl=2
283 [ - + + - : 3 : ABI_MALLOC(bs2eph, (Kmesh%nbz*sppoldbl, 6))
+ - + - -
+ - + ]
284 [ - + + - : 3 : ABI_MALLOC(ep_renorms, (hsize))
+ - + - -
+ - + ]
285 : 1 : timrev = 1
286 : : call listkk(dksqmax, Cryst%gmet, bs2eph, Epren%kpts, Kmesh%bz, Epren%nkpt, Kmesh%nbz, Cryst%nsym, &
287 : 1 : sppoldbl, Cryst%symafm, Cryst%symrel, timrev, comm, use_symrec=.False.)
288 : : end if
289 : :
290 : 23 : call timab(693,2,tsec) ! exc_haydock_driver(wo lf - that is, without local field
291 : 23 : call timab(694,1,tsec) ! exc_haydock_driver(apply
292 : :
293 : 23 : prefix = ""
294 [ + + ]: 55 : do itemp = 1, ntemp
295 : :
296 : 32 : call hexc%KS_BSt%copy(EPBSt)
297 : 32 : call hexc%QP_BSt%copy(EP_QPBSt)
298 : :
299 : : ! =================================================
300 : : ! == Calculate elphon vector in transition space ==
301 : : ! =================================================
302 [ + + ]: 32 : if (do_ep_renorm) then
303 : :
304 : : ! Will perform elphon renormalization for itemp
305 : :
306 : 10 : call int2char4(itemp,ts)
307 : 10 : prefix = TRIM("_T") // ts
308 : :
309 : : ! No scissor with KS Bands
310 : 10 : call renorm_bst(Epren, EPBSt, Cryst, itemp, do_lifetime=.TRUE.,do_check=.TRUE.)
311 : 10 : call renorm_bst(Epren, EP_QPBSt, Cryst, itemp, do_lifetime=.TRUE.,do_check=.FALSE.)
312 : :
313 [ + + ]: 20 : do isppol = 1, BSp%nsppol
314 [ + + ]: 980 : do ireh = 1, BSp%nreh(isppol)
315 : 960 : ic = BSp%Trans(ireh,isppol)%c
316 : 960 : iv = BSp%Trans(ireh,isppol)%v
317 : 960 : ik = BSp%Trans(ireh,isppol)%k ! In the full bz
318 : 960 : en = BSp%Trans(ireh,isppol)%en
319 : :
320 : 960 : ep_ik = bs2eph(ik,1)
321 : :
322 : : !TODO support multiple spins !
323 [ - + ]: 960 : if(ABS(en - (Epren%eigens(ic,ep_ik,isppol)-Epren%eigens(iv,ep_ik,isppol)+BSp%mbpt_sciss)) > tol3) then
324 : 0 : ABI_ERROR("Eigen from the transition does not correspond to the EP file !")
325 : : end if
326 : 960 : ep_renorms(ireh) = (Epren%renorms(1,ic,ik,isppol,itemp) - Epren%renorms(1,iv,ik,isppol,itemp))
327 : :
328 : : ! Add linewith
329 : 10 : if(do_ep_lifetime) then
330 : : ep_renorms(ireh) = ep_renorms(ireh) - j_dpc*(Epren%linewidth(1,ic,ik,isppol,itemp) +&
331 : 960 : Epren%linewidth(1,iv,ik,isppol,itemp))
332 : : end if
333 : :
334 : : end do
335 : : end do
336 : : end if
337 : :
338 : : ! =======================================================
339 : : ! === Make EPS RPA and GW without local-field effects ===
340 : : ! =======================================================
341 [ - + + - : 128 : ABI_MALLOC(eps_rpanlf,(BSp%nomega,BSp%nq))
- + + - +
- + - - +
- + ]
342 [ - + + - : 96 : ABI_MALLOC(dos_ks,(BSp%nomega))
+ - + - -
+ - + ]
343 [ - + + - : 96 : ABI_MALLOC(eps_gwnlf ,(BSp%nomega,BSp%nq))
- + + - -
+ - + ]
344 [ - + + - : 64 : ABI_MALLOC(dos_gw,(BSp%nomega))
- + - + ]
345 : :
346 : 32 : call wrtout(std_out," Calculating RPA NLF and QP NLF epsilon")
347 : :
348 : : call exc_eps_rpa(BSp%nbnds,BSp%lomo_spin,BSp%lomo_min,BSp%homo_spin,hexc%Kmesh,EPBSt,BSp%nq,nsppol,&
349 : 32 : opt_cvk,Cryst%ucvol,BSp%broad,BSp%nomega,BSp%omega,eps_rpanlf,dos_ks)
350 : :
351 : : call exc_eps_rpa(BSp%nbnds,BSp%lomo_spin,BSp%lomo_min,BSp%homo_spin,hexc%Kmesh,EP_QPBSt,BSp%nq,nsppol,&
352 : 32 : opt_cvk,Cryst%ucvol,Bsp%broad,BSp%nomega,BSp%omega,eps_gwnlf,dos_gw)
353 : :
354 [ + + ]: 32 : if (my_rank==master) then ! Only master works.
355 : : !
356 : : ! Master node writes final results on file.
357 : 28 : call exc_write_data(BSp,BS_files,"RPA_NLF_MDF",eps_rpanlf,prefix=prefix,dos=dos_ks)
358 : 28 : call exc_write_data(BSp,BS_files,"GW_NLF_MDF",eps_gwnlf,prefix=prefix,dos=dos_gw)
359 : :
360 : : ! Computing and writing tensor in files
361 : :
362 : : ! RPA_NLF
363 [ - + + - : 84 : ABI_MALLOC(tensor_cart_rpanlf,(BSp%nomega,6))
+ - + - -
+ - + ]
364 [ - + + - : 56 : ABI_MALLOC(tensor_red_rpanlf,(BSp%nomega,6))
- + - + ]
365 : :
366 : 28 : call wrtout(std_out," Calculating RPA NLF dielectric tensor")
367 : 28 : call haydock_mdf_to_tensor(BSp,Cryst,eps_rpanlf,tensor_cart_rpanlf, tensor_red_rpanlf, ierr)
368 : :
369 [ + - ]: 28 : if (ierr == 0) then
370 : : ! Writing tensor
371 : 28 : call exc_write_tensor(BSp,BS_files,"RPA_NLF_TSR_CART",tensor_cart_rpanlf)
372 : 28 : call exc_write_tensor(BSp,BS_files,"RPA_NLF_TSR_RED",tensor_red_rpanlf)
373 : : else
374 : : write(msg,'(3a)')&
375 : 0 : 'The RPA_NLF dielectric complex tensor cannot be computed',ch10,&
376 : 0 : 'There must be 6 different q-points in long wavelength limit (see gw_nqlwl)'
377 : 0 : ABI_COMMENT(msg)
378 : : end if
379 : :
380 [ - + ]: 28 : ABI_FREE(tensor_cart_rpanlf)
381 [ - + ]: 28 : ABI_FREE(tensor_red_rpanlf)
382 : :
383 : : ! GW_NLF
384 [ - + + - : 56 : ABI_MALLOC(tensor_cart_gwnlf,(BSp%nomega,6))
- + - + ]
385 [ - + + - : 56 : ABI_MALLOC(tensor_red_gwnlf,(BSp%nomega,6))
- + - + ]
386 : :
387 : 28 : call wrtout(std_out," Calculating GW NLF dielectric tensor")
388 : :
389 : 28 : call haydock_mdf_to_tensor(BSp,Cryst,eps_gwnlf,tensor_cart_gwnlf, tensor_red_gwnlf, ierr)
390 : :
391 [ + - ]: 28 : if(ierr == 0) then
392 : : ! Writing tensor
393 : 28 : call exc_write_tensor(BSp,BS_files,"GW_NLF_TSR_CART",tensor_cart_gwnlf)
394 : 28 : call exc_write_tensor(BSp,BS_files,"GW_NLF_TSR_RED",tensor_red_gwnlf)
395 : : else
396 : : write(msg,'(3a)')&
397 : 0 : 'The GW_NLF dielectric complex tensor cannot be computed',ch10,&
398 : 0 : 'There must be 6 different q-points in long wavelength limit (see gw_nqlwl)'
399 : 0 : ABI_COMMENT(msg)
400 : : end if
401 : :
402 [ - + ]: 28 : ABI_FREE(tensor_cart_gwnlf)
403 [ - + ]: 84 : ABI_FREE(tensor_red_gwnlf)
404 : :
405 : : !call wrtout(std_out," Checking Kramers Kronig on Excitonic Macroscopic Epsilon")
406 : : !call check_kramerskronig(BSp%nomega,REAL(BSp%omega),eps_exc(:,1))
407 : :
408 : : !call wrtout(std_out," Checking Kramers Kronig on RPA NLF Macroscopic Epsilon")
409 : : !call check_kramerskronig(BSp%nomega,REAL(BSp%omega),eps_rpanlf(:,1))
410 : :
411 : : !call wrtout(std_out," Checking Kramers Kronig on GW NLF Macroscopic Epsilon")
412 : : !call check_kramerskronig(BSp%nomega,REAL(BSp%omega),eps_gwnlf(:,1))
413 : :
414 : : !call wrtout(std_out," Checking f-sum rule on Excitonic Macroscopic Epsilon")
415 : :
416 : : !if (BSp%exchange_term>0) then
417 : : ! ABI_COMMENT(' f-sum rule should be checked without LF')
418 : : !end if
419 : : !call check_fsumrule(BSp%nomega,REAL(BSp%omega),AIMAG(eps_exc(:,1)),drude_plsmf)
420 : :
421 : : !call wrtout(std_out," Checking f-sum rule on RPA NLF Macroscopic Epsilon")
422 : : !call check_fsumrule(BSp%nomega,REAL(BSp%omega),AIMAG(eps_rpanlf(:,1)),drude_plsmf)
423 : :
424 : : !call wrtout(std_out," Checking f-sum rule on GW NLF Macroscopic Epsilon")
425 : : !call check_fsumrule(BSp%nomega,REAL(BSp%omega),AIMAG(eps_gwnlf(:,1)),drude_plsmf)
426 : : end if ! my_rank==master
427 : :
428 : : !call xmpi_barrier(comm)
429 : : !
430 : : ! The ket for the approximated DOS.
431 : : if (prtdos) then
432 : : ABI_WARNING("Calculating DOS with Haydock method")
433 : : ABI_CHECK(BSp%use_coupling==0,"DOS with coupling not coded")
434 : : iq = BSp%nq + 1
435 : : if (my_rank==master) then
436 : : !call random_seed()
437 : : do itt=1,SUM(Bsp%nreh)
438 : : call RANDOM_NUMBER(rand_phi)
439 : : rand_phi = two_pi*rand_phi
440 : : kets(itt,iq) = CMPLX( COS(rand_phi), SIN(rand_phi) )
441 : : end do
442 : : ! Normalize the vector.
443 : : !norm = SQRT( DOT_PRODUCT(kets(:,iq), kets(:,iq)) )
444 : : !kets(:,iq) = kets(:,iq)/norm
445 : : end if
446 : : call xmpi_bcast(kets(:,iq),master,comm,ierr)
447 : : end if
448 : :
449 [ - + + - : 128 : ABI_MALLOC(green,(BSp%nomega,nkets))
- + + - +
- + - - +
- + ]
450 : :
451 [ + - ]: 32 : if (BSp%use_coupling==0) then
452 [ + + ]: 32 : if(do_ep_renorm) then
453 : 10 : call haydock_bilanczos(BSp,BS_files,Cryst,Hdr_bse,hexc,hexc_i,hsize,hexc%my_t1,hexc%my_t2,nkets,kets,ep_renorms,green,comm)
454 : : else
455 : : !YG2014
456 : 22 : call haydock_herm(BSp,BS_files,Cryst,Hdr_bse,hexc%my_t1,hexc%my_t2,nkets,kets,green,hexc,hexc_i,comm)
457 : : end if
458 : : else
459 [ # # ]: 0 : if (BSp%use_interp) then
460 : 0 : ABI_ERROR("BSE Interpolation with coupling is not supported")
461 : : else
462 : 0 : call haydock_psherm(BSp,BS_files,Cryst,Hdr_bse,hexc,hexc_i,hsize,my_t1,my_t2,nkets,kets,green,comm)
463 : : end if
464 : : end if
465 : :
466 : : ! Add 1 to have the real part right.
467 [ + + + + ]: 87374 : green = one + green
468 : :
469 [ + + ]: 32 : if (my_rank==master) then ! Master writes the final results.
470 : :
471 : : if (prtdos) then
472 : : ABI_MALLOC(dos,(BSp%nomega))
473 : : dos = -AIMAG(green(:,BSp%nq+1))
474 : : call exc_write_data(BSp,BS_files,"EXC_MDF",green,prefix=prefix,dos=dos)
475 : : ABI_FREE(dos)
476 : : else
477 : 28 : call exc_write_data(BSp,BS_files,"EXC_MDF",green,prefix=prefix)
478 : : end if
479 : :
480 : : ! =========================
481 : : ! === Write out Epsilon ===
482 : : ! =========================
483 : :
484 [ - + + - : 84 : ABI_MALLOC(tensor_cart,(BSp%nomega,6))
+ - + - -
+ - + ]
485 [ - + + - : 56 : ABI_MALLOC(tensor_red,(BSp%nomega,6))
- + - + ]
486 : :
487 : 28 : call wrtout(std_out," Calculating EXC dielectric tensor")
488 : 28 : call haydock_mdf_to_tensor(BSp,Cryst,green,tensor_cart,tensor_red,ierr)
489 : :
490 [ + - ]: 28 : if (ierr == 0) then
491 : : ! Writing tensor
492 : 28 : call exc_write_tensor(BSp,BS_files,"EXC_TSR_CART",tensor_cart)
493 : 28 : call exc_write_tensor(BSp,BS_files,"EXC_TSR_RED",tensor_red)
494 : : else
495 : : write(msg,'(3a)')&
496 : 0 : 'The EXC dielectric complex tensor cannot be computed',ch10,&
497 : 0 : 'There must be 6 different q-points in long wavelength limit (see gw_nqlwl)'
498 : 0 : ABI_COMMENT(msg)
499 : : end if
500 : :
501 [ - + ]: 28 : ABI_FREE(tensor_cart)
502 [ - + ]: 28 : ABI_FREE(tensor_red)
503 : : !
504 : : ! This part will be removed when fldiff will be able to compare two mdf files.
505 : 28 : write(ab_out,*)" "
506 : 28 : write(ab_out,*)"Macroscopic dielectric function:"
507 : 28 : write(ab_out,*)"omega [eV] <KS_RPA_nlf> <GW_RPA_nlf> <BSE> "
508 [ + + ]: 308 : do io=1,MIN(BSp%nomega,10)
509 : 280 : omegaev = REAL(BSp%omega(io))*Ha_eV
510 [ + + ]: 1960 : ks_avg = SUM( eps_rpanlf(io,:)) / Bsp%nq
511 [ + + ]: 1960 : gw_avg = SUM( eps_gwnlf (io,:)) / Bsp%nq
512 [ + + ]: 1960 : exc_avg = SUM( green (io,:)) / BSp%nq
513 : 308 : write(ab_out,'(7f9.4)')omegaev,ks_avg,gw_avg,exc_avg
514 : : end do
515 : 28 : write(ab_out,*)" "
516 : :
517 : : ! Write MDF file with the final results.
518 : : ! FIXME: It won't work if prtdos == True
519 [ + - ]: 28 : path = strcat(BS_files%out_basename,strcat(prefix,"_MDF.nc"))
520 [ - + ]: 28 : NCF_CHECK(nctk_open_create(ncid, path, xmpi_comm_self))
521 [ - + ]: 28 : NCF_CHECK(cryst%ncwrite(ncid))
522 [ - + ]: 28 : NCF_CHECK(QP_bst%ncwrite(ncid))
523 : 28 : call mdfs_ncwrite(ncid, Bsp, green, eps_rpanlf, eps_gwnlf)
524 [ - + ]: 56 : NCF_CHECK(nf90_close(ncid))
525 : : end if
526 : :
527 [ - + ]: 32 : ABI_FREE(green)
528 [ - + ]: 32 : ABI_FREE(eps_rpanlf)
529 [ - + ]: 32 : ABI_FREE(eps_gwnlf)
530 [ - + ]: 32 : ABI_FREE(dos_ks)
531 [ - + ]: 32 : ABI_FREE(dos_gw)
532 : :
533 : 32 : call EPBSt%free()
534 : 55 : call EP_QPBst%free()
535 : : end do ! itemp loop
536 : :
537 [ - + ]: 23 : ABI_FREE(opt_cvk)
538 [ - + ]: 23 : ABI_FREE(kets)
539 : :
540 : 23 : call timab(694,2,tsec) ! exc_haydock_driver(apply
541 : 23 : call timab(695,1,tsec) ! exc_haydock_driver(end)
542 : :
543 : : !YG2014
544 : 23 : call hexc%free()
545 : 23 : call hexc_i%free()
546 : :
547 [ + + ]: 23 : ABI_SFREE(ep_renorms)
548 [ + + ]: 23 : ABI_SFREE(bs2eph)
549 : :
550 : 23 : call timab(695,2,tsec) ! exc_haydock_driver(end)
551 : 23 : call timab(690,2,tsec) ! exc_haydock_driver
552 : :
553 [ - + - + : 23 : end subroutine exc_haydock_driver
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + ]
554 : : !!***
555 : :
556 : : !----------------------------------------------------------------------
557 : :
558 : : !!****f* m_haydock/haydock_herm
559 : : !! NAME
560 : : !! haydock_herm
561 : : !!
562 : : !! FUNCTION
563 : : !! Reads the excitonic Hamiltonian from file and construct the Lanczos set of vectors
564 : : !! by iterative matrix-vector multiplications.
565 : : !!
566 : : !! INPUTS
567 : : !! BSp<excparam>=Parameters for the Bethe-Salpeter calculation.
568 : : !! BS_files<excparam>=Files associated to the bethe_salpeter code.
569 : : !! Cryst<crystal_t>=Info on the crystalline structure.
570 : : !! Pawtab(Cryst%ntypat*usepaw)<pawtab_type>=PAW tabulated starting data.
571 : : !! hize=Size of the excitonic matrix.
572 : : !! my_t1,my_t2=First and last columns treated by this node.
573 : : !! nkets=Number of starting vectors for Haydock method.
574 : : !! kets(hsize,nkets)=The kets in the eh representation.
575 : : !! comm=MPI communicator.
576 : : !!
577 : : !! OUTPUT
578 : : !! green(BSp%nomega,nkets)=
579 : : !!
580 : : !! SOURCE
581 : :
582 : 22 : subroutine haydock_herm(BSp,BS_files,Cryst,Hdr_bse,my_t1,my_t2,nkets,kets,green,hexc,hexc_i,comm)
583 : :
584 : : !Arguments ------------------------------------
585 : : !scalars
586 : : integer,intent(in) :: my_t1,my_t2,nkets,comm
587 : : type(crystal_t),intent(in) :: Cryst
588 : : type(excparam),intent(in) :: BSp
589 : : type(excfiles),intent(in) :: BS_files
590 : : type(Hdr_type),intent(in) :: Hdr_bse
591 : : type(hexc_t),intent(inout) :: hexc
592 : : type(hexc_interp_t),intent(inout) :: hexc_i
593 : : !arrays
594 : : complex(dp),intent(out) :: green(BSp%nomega,nkets)
595 : : complex(dp),intent(in) :: kets(hexc%hsize,nkets)
596 : :
597 : : !Local variables ------------------------------
598 : : !scalars
599 : : integer,parameter :: master=0
600 : : integer :: inn,nproc,my_rank,ierr
601 : : integer :: niter_file,niter_max,niter_done,nsppol,iq,my_nt,term_type,n_all_omegas
602 : : real(dp) :: norm,nfact
603 : : logical :: can_restart,is_converged
604 : : complex(dp) :: factor
605 : : character(len=500) :: msg
606 : : character(len=fnlen), parameter :: tag_file="_HAYDR_SAVE"
607 : : character(len=fnlen) :: restart_file,out_file
608 : 22 : type(haydock_type) :: haydock_file
609 : : !arrays
610 : 22 : real(dp),allocatable :: bb_file(:)
611 : 22 : real(dp),allocatable :: bb(:)
612 : 22 : complex(dp),allocatable :: aa(:),phi_nm1(:),phi_n(:),hphi_n(:),hphi_nm1(:)
613 : 22 : complex(dp),allocatable :: aa_file(:),phi_n_file(:),phi_nm1_file(:)
614 : 22 : complex(dp),allocatable :: ket0(:),all_omegas(:),green_temp(:,:)
615 : : ! complex(dp),allocatable :: diag_dense(:)
616 : : logical :: check(2)
617 : : !************************************************************************
618 : :
619 [ - + ]: 22 : ABI_CHECK(Bsp%nsppol==1,"nsppol > 1 not implemented yet")
620 : :
621 : 22 : nproc = xmpi_comm_size(comm); my_rank= xmpi_comm_rank(comm)
622 : 22 : nsppol = Hdr_bse%nsppol
623 : :
624 [ + + ]: 22 : if (BSp%use_interp) then
625 : 4 : ABI_COMMENT("No parallelization in Interpolation")
626 [ + + ]: 8 : my_nt = SUM(Bsp%nreh_interp)
627 : : else
628 : 18 : my_nt = my_t2-my_t1+1
629 : : end if
630 : :
631 [ - + ]: 22 : ABI_CHECK(my_nt>0,"One of the processors has zero columns")
632 : :
633 : 22 : write(msg,'(a,i0)')' Haydock algorithm with MAX number of iterations: ',BSp%niter
634 : 22 : call wrtout(std_out,msg)
635 : : !
636 : : ! Select the terminator for the continued fraction.
637 [ + + ]: 22 : term_type=0; if (Bsp%hayd_term>0) term_type=1
638 : 22 : call wrtout(std_out,sjoin("Using terminator type: ",itoa(term_type)))
639 : : !
640 : : ! Check for presence of the restart file.
641 : 22 : can_restart=.FALSE.
642 [ - + ]: 22 : if ( BS_files%in_haydock_basename /= BSE_NOFILE) then
643 [ # # ]: 0 : restart_file = TRIM(BS_files%in_haydock_basename)//TRIM(tag_file)
644 [ # # ]: 0 : if (file_exists(restart_file) ) then
645 : 0 : can_restart=.TRUE.
646 : 0 : msg = " Restarting Haydock calculation from file: "//TRIM(restart_file)
647 : 0 : call wrtout(std_out,msg)
648 : 0 : call wrtout(ab_out,msg)
649 : : else
650 : 0 : can_restart=.FALSE.
651 [ # # ]: 0 : call wrtout(ab_out," WARNING: cannot find restart file: "//TRIM(restart_file))
652 : : end if
653 : : end if
654 : 0 : ABI_CHECK(.not.can_restart,"restart not yet implemented")
655 : :
656 : : ! Open the file and write basic dimensions and info.
657 [ + + ]: 22 : if (my_rank==master) then
658 [ + - ]: 18 : out_file = TRIM(BS_files%out_basename)//TRIM(tag_file)
659 : 18 : call haydock_file%open(out_file)
660 : 18 : haydock_file%hsize = hexc%hsize
661 : 18 : haydock_file%use_coupling = Bsp%use_coupling
662 : 18 : haydock_file%op = BSE_HAYD_IMEPS
663 : 18 : haydock_file%nq = nkets
664 : 18 : haydock_file%broad = Bsp%broad
665 : 18 : call haydock_file%write_dim()
666 : : end if
667 : :
668 : : !
669 : : ! Calculate green(w) for the different starting points.
670 [ + + + + ]: 27244 : green=czero
671 [ + + ]: 154 : do iq=1,nkets
672 [ - + + - : 396 : ABI_MALLOC(ket0,(hexc%hsize))
+ - + - -
+ - + ]
673 [ + - - + : 63816 : ket0=kets(:,iq)
- - + + ]
674 : :
675 : 132 : niter_file=0
676 [ - + ]: 132 : if (can_restart) then
677 : : call haydock_restart(BSp,restart_file,BSE_HAYD_IMEPS,iq,hexc%hsize,&
678 [ # # # # : 0 : niter_file,aa_file,bb_file,phi_nm1_file,phi_n_file,comm)
# # # # ]
679 : : end if
680 : : !
681 : : ! For n>1, we have:
682 : : ! 1) a_n = <n|H|n>
683 : : ! 2) b_n = || H|n> - a_n|n> -b_{n-1}|n-1> ||
684 : : ! 3) |n+1> = [H|n> -a_n|n> -b_{n-1}|n-1>]/b_n
685 : : !
686 : : ! The sequences starts with |1> normalized to 1 and b_0 =0, therefore:
687 : : ! a_1 = <1|H|1>
688 : : ! b_1 = || H|1> - a_1|1> ||
689 : : ! |2> = [H|1> - a_1|1>]/b_1
690 : : !
691 [ - + + - : 396 : ABI_MALLOC(hphi_n,(hexc%hsize))
+ - + - -
+ - + -
+ ]
692 [ - + + - : 264 : ABI_MALLOC(hphi_nm1,(hexc%hsize))
- + - + -
+ ]
693 [ - + + - : 396 : ABI_MALLOC(phi_nm1,(my_nt))
+ - + - -
+ - + ]
694 [ - + + - : 264 : ABI_MALLOC(phi_n,(my_nt))
- + - + ]
695 : :
696 : 132 : niter_max = niter_file + Bsp%niter
697 [ - + + - : 396 : ABI_MALLOC(aa,(niter_max))
+ - + - -
+ - + ]
698 [ - + + - : 396 : ABI_MALLOC(bb,(niter_max))
+ - + - -
+ - + ]
699 [ + + + + ]: 34212 : aa=czero; bb=zero
700 : :
701 [ + - ]: 132 : if (niter_file==0) then ! Calculation from scratch.
702 [ + - - + : 54600 : phi_nm1=ket0(my_t1:my_t2) ! Select the slice treated by this node.
- - + + ]
703 : 132 : norm = DZNRM2(hexc%hsize,ket0,1) ! Normalization
704 [ + + ]: 54468 : phi_nm1=phi_nm1/norm
705 : :
706 : 132 : call hexc%matmul_tda(hexc_i,phi_nm1,hphi_n)
707 : :
708 : 132 : aa(1)=xdotc(my_nt,phi_nm1,1,hphi_n(my_t1:),1)
709 : 132 : call xmpi_sum(aa(1:1),comm,ierr)
710 : :
711 [ + - - + : 54600 : phi_n = hphi_n(my_t1:my_t2) - aa(1)*phi_nm1
- - + + ]
712 : :
713 : 132 : bb(1) = xdotc(my_nt,phi_n,1,phi_n,1)
714 : 132 : call xmpi_sum(bb(1:1),comm,ierr)
715 : 132 : bb(1) = SQRT(bb(1))
716 : :
717 [ + + ]: 54468 : phi_n = phi_n/bb(1)
718 : 132 : niter_done=1
719 : :
720 : : else ! Use the previous a and b.
721 : 0 : niter_done=niter_file
722 [ # # ]: 0 : aa(1:niter_done) = aa_file
723 [ # # ]: 0 : bb(1:niter_done) = bb_file
724 [ # # # # : 0 : phi_nm1=phi_nm1_file(my_t1:my_t2) ! Select the slice treated by this node.
# # # # ]
725 [ # # # # : 0 : phi_n =phi_n_file (my_t1:my_t2)
# # # # ]
726 : : end if
727 : :
728 [ - + ]: 132 : if (can_restart) then
729 [ # # ]: 0 : ABI_FREE(aa_file)
730 [ # # ]: 0 : ABI_FREE(bb_file)
731 [ # # ]: 0 : ABI_FREE(phi_nm1_file)
732 [ # # ]: 0 : ABI_FREE(phi_n_file)
733 : : end if
734 : :
735 : : ! Multiplicative factor (k-point sampling and unit cell volume)
736 : : ! TODO be careful with the spin here
737 : : ! TODO four_pi comes from the coulomb term 1/|q| is already included in the
738 : : ! oscillators hence the present approach wont work if a cutoff interaction is used.
739 : 132 : nfact = -four_pi/(Cryst%ucvol*hexc%nbz)
740 [ + - ]: 132 : if (nsppol==1) nfact=two*nfact
741 : :
742 : 132 : factor = nfact*(DZNRM2(hexc%hsize,ket0,1)**2)
743 : :
744 : : ! Which quantity should be checked for convergence?
745 : 132 : check = (/.TRUE.,.TRUE./)
746 [ - + ]: 132 : if (ABS(Bsp%haydock_tol(2)-one)<tol6) check = (/.TRUE. ,.FALSE./)
747 [ - + ]: 132 : if (ABS(Bsp%haydock_tol(2)-two)<tol6) check = (/.FALSE.,.TRUE./)
748 : :
749 : : ! Create new frequencies "mirror" in negative range to add
750 : : ! their contributions. Can be improved by computing only once
751 : : ! zero frequency, but loosing clearness
752 : 132 : n_all_omegas = 2*BSp%nomega
753 : :
754 [ - + + - : 396 : ABI_MALLOC(all_omegas,(n_all_omegas))
+ - + - -
+ - + ]
755 : : ! Put all omegas with frequency > 0 in table
756 [ + + ]: 27222 : all_omegas(BSp%nomega+1:n_all_omegas) = BSp%omega
757 : : ! Put all omegas with frequency < 0
758 : : ! Warning, the broadening must be kept positive
759 [ + + ]: 27222 : all_omegas(1:BSp%nomega) = -DBLE(BSp%omega(BSp%nomega:1:-1)) + j_dpc*AIMAG(BSp%omega(BSp%nomega:1:-1))
760 : :
761 [ - + + - : 528 : ABI_MALLOC(green_temp,(n_all_omegas,nkets))
- + + - +
- + - - +
- + ]
762 : :
763 : : call haydock_herm_algo(niter_done,niter_max,n_all_omegas,all_omegas,BSp%haydock_tol(1),check,&
764 : : my_t1,my_t2,factor,term_type,aa,bb,phi_nm1,phi_n,&
765 : : green_temp(:,iq),inn,is_converged,&
766 : 132 : hexc, hexc_i, comm)
767 : :
768 : : ! Computing result from two ranges of frequencies
769 : : ! The real part is added, the imaginary part is substracted
770 [ + + ]: 27222 : green(:,iq) = green_temp(BSp%nomega+1:n_all_omegas,iq)+CONJG(green_temp(BSp%nomega:1:-1,iq))
771 : :
772 [ - + ]: 132 : ABI_FREE(all_omegas)
773 [ - + ]: 132 : ABI_FREE(green_temp)
774 : : !
775 : : ! Save the a"s and the b"s for possible restarting.
776 : : ! 1) Info on the Q.
777 : : ! 2) Number of iterations performed.
778 : : ! 3) do iter=1,niter_performed
779 : : ! aa(iter),bb(iter)
780 : : ! end do
781 : : ! 4) |n-1>
782 : : ! |n>
783 : : !
784 [ + + ]: 63684 : hphi_nm1 = czero
785 [ + + ]: 54468 : hphi_nm1(my_t1:my_t2) = phi_nm1
786 : 132 : call xmpi_sum_master(hphi_nm1,master,comm,ierr)
787 : :
788 [ + + ]: 63684 : hphi_n = czero
789 [ + + ]: 54468 : hphi_n(my_t1:my_t2) = phi_n
790 : 132 : call xmpi_sum_master(hphi_n,master,comm,ierr)
791 : :
792 [ + + ]: 132 : if (my_rank==master) then
793 : : ! Write data for restarting
794 : 108 : call haydock_file%write(hexc%hsize, Bsp%q(:,iq), aa, bb, hphi_n, hphi_nm1, MIN(inn,niter_max), factor)
795 : : end if
796 : :
797 [ - + ]: 132 : ABI_FREE(hphi_n)
798 [ - + ]: 132 : ABI_FREE(hphi_nm1)
799 [ - + ]: 132 : ABI_FREE(phi_nm1)
800 [ - + ]: 132 : ABI_FREE(phi_n)
801 [ - + ]: 132 : ABI_FREE(aa)
802 [ - + ]: 132 : ABI_FREE(bb)
803 [ - + ]: 154 : ABI_FREE(ket0)
804 : : end do ! iq
805 : :
806 [ + + ]: 22 : if (my_rank==master) call haydock_file%close()
807 : :
808 : 22 : call xmpi_barrier(comm)
809 : :
810 [ - + - + : 22 : end subroutine haydock_herm
- + - + -
+ - + - +
- + ]
811 : : !!***
812 : :
813 : : !----------------------------------------------------------------------
814 : :
815 : : !!****f* m_haydock/haydock_herm_algo
816 : : !! NAME
817 : : !! haydock_herm_algo
818 : : !!
819 : : !! FUNCTION
820 : : !!
821 : : !! INPUTS
822 : : !! niter_done=Number of iterations already performed (0 if the run starts from scratch).
823 : : !! niter_max=Max number of iterations. Always > niter_done
824 : : !! nomega=Number of Frequency points for the evaluation of the matrix element.
825 : : !! omega(nomega)=Frequency set (imaginary part is already included).
826 : : !! tol_iter=Tolerance used to stop the algorithm.
827 : : !! check(2)=Logical flags to specify where both the real and the imaginary part of the
828 : : !! matrix elements of the Green functions have to be checked for convergence.
829 : : !! hsize=Size of the blocks.
830 : : !! my_t1,my_t2=Indices of the first and last column stored treated by this done.
831 : : !! term_type=0 if no terminator is used, 1 otherwise.
832 : : !! hmat(hsize,my_t1:my_t2)=The columns of the block.
833 : : !! factor
834 : : !! ntrans = Number of transitions
835 : : !! corresp = mapping between coarse points and neighbours
836 : : !! overlaps = overlaps of wavefunctions between dense k-point coarse neighbours and bands
837 : : !! comm=MPI communicator.
838 : : !!
839 : : !! OUTPUT
840 : : !! green(nomega)=Output matrix elements.
841 : : !! inn=Last iteration performed.
842 : : !! is_converged=.TRUE. of the algorithm converged.
843 : : !!
844 : : !! SIDE EFFECTS
845 : : !! phi_nm1(my_t2-my_t1+1), phi_n(my_t2-my_t1+1)
846 : : !! input: vectors used to initialize the iteration
847 : : !! output: the vectors obtained in the last iteration
848 : : !! aa(niter_max) and bb(niter_max)
849 : : !! if niter_done>0: aa(1:niter_done), bb(1:niter_done) store the coefficients of the previous run.
850 : : !! when the routine returns aa(1:inn) and bb(1:inn) contain the matrix elements of the tridiagonal form.
851 : : !!
852 : : !! SOURCE
853 : :
854 : 132 : subroutine haydock_herm_algo(niter_done,niter_max,nomega,omega,tol_iter,check,&
855 : 132 : my_t1,my_t2,factor,term_type,aa,bb,phi_nm1,phi_n,&
856 : 132 : green,inn,is_converged, hexc, hexc_i, comm)
857 : :
858 : : !Arguments ------------------------------------
859 : : !scalars
860 : : integer,intent(in) :: niter_max,niter_done,nomega
861 : : integer,intent(in) :: my_t1,my_t2,term_type
862 : : integer,intent(in) :: comm
863 : : integer,intent(out) :: inn
864 : : logical,intent(out) :: is_converged
865 : : real(dp),intent(in) :: tol_iter
866 : : complex(dp),intent(in) :: factor
867 : : type(hexc_t),intent(in) :: hexc
868 : : type(hexc_interp_t),intent(in) :: hexc_i
869 : : !arrays
870 : : real(dp),intent(inout) :: bb(niter_max)
871 : : complex(dp),intent(out) :: green(nomega)
872 : : complex(dp),intent(in) :: omega(nomega)
873 : : complex(dp),intent(inout) :: aa(niter_max)
874 : : complex(dp),intent(inout) :: phi_nm1(my_t2-my_t1+1)
875 : : complex(dp),intent(inout) :: phi_n (my_t2-my_t1+1)
876 : : logical,intent(in) :: check(2)
877 : :
878 : : !Local variables ------------------------------
879 : : !scalars
880 : : integer :: ierr,my_nt,niter_min,nconv
881 : : character(len=500) :: msg
882 : : logical,parameter :: force_real=.TRUE.
883 : : !arrays
884 : : integer :: units(2)
885 : 264 : real(dp) :: abs_err(nomega,2) !,rel_err(nomega,2)
886 : 132 : complex(dp),allocatable :: oldg(:),newg(:), phi_np1(:),hphi_n(:),cfact(:)
887 : : logical :: test(2)
888 : : !************************************************************************
889 : :
890 : : ! The sequences starts with |1> normalized to 1 and b_0 =0, therefore:
891 : : ! a_1 = <1|H|1>
892 : : ! b_1 = || H|1> - a_1|1> ||
893 : : ! |2> = [H|1> - a_1|1>]/b_1
894 : : !
895 : : ! For n>1 we have
896 : : ! 1) a_n = <n|H|n>
897 : : ! 2) b_n = || H|n> - a_n|n> -b_{n-1}|n-1> ||
898 : : ! 3) |n+1> = [H|n> -a_n|n> -b_{n-1}|n-1>]/b_n
899 : : !
900 : 132 : my_nt = my_t2-my_t1+1
901 [ + + ]: 396 : units = [std_out, ab_out]
902 : :
903 [ - + + - : 396 : ABI_MALLOC_OR_DIE(hphi_n,(hexc%hsize), ierr)
+ - + - +
- - + -
+ ]
904 [ - + + - : 396 : ABI_MALLOC(phi_np1,(my_nt))
+ - + - -
+ - + ]
905 [ - + + - : 54576 : ABI_CALLOC(oldg,(nomega))
+ - + - -
+ - + +
+ ]
906 [ - + + - : 54444 : ABI_CALLOC(newg,(nomega))
- + - + +
+ ]
907 [ - + + - : 54444 : ABI_CALLOC(cfact,(nomega))
- + - + +
+ ]
908 : :
909 : 132 : nconv=0
910 [ + - ]: 9661 : do inn=niter_done+1,niter_max
911 : :
912 : : !YG2014
913 : 9661 : call hexc%matmul_tda(hexc_i,phi_n,hphi_n)
914 : :
915 : 9661 : aa(inn) = xdotc(my_nt,phi_n,1,hphi_n(my_t1:),1)
916 : 9661 : call xmpi_sum(aa(inn:inn),comm,ierr)
917 : 9661 : if (force_real) aa(inn) = DBLE(aa(inn)) ! Matrix is Hermitian.
918 : :
919 : : ! |n+1> = H|n> - A(n)|n> - B(n-1)|n-1>
920 [ + - - + : 5417978 : phi_np1 = hphi_n(my_t1:my_t2) - aa(inn)*phi_n - bb(inn-1)*phi_nm1
- - + + ]
921 : :
922 : 9661 : bb(inn) = xdotc(my_nt,phi_np1,1,phi_np1,1)
923 : 9661 : call xmpi_sum(bb(inn),comm,ierr)
924 : 9661 : bb(inn) = SQRT(bb(inn))
925 : :
926 [ + + ]: 5408317 : phi_np1 = phi_np1/bb(inn)
927 [ + + ]: 5408317 : phi_nm1 = phi_n
928 [ + + ]: 5408317 : phi_n = phi_np1
929 : :
930 : 9661 : write(msg,'(a,i0,a,3es12.4)')' Iteration number ',inn,', b_i RE(a_i) IM(a_i) ',bb(inn),REAL(aa(inn)),AIMAG(aa(inn))
931 : 9661 : call wrtout(std_out, msg)
932 : :
933 : 9661 : call continued_fract(inn,term_type,aa,bb,nomega,omega,cfact)
934 [ - + + + ]: 2846830 : newg= factor*cfact
935 : :
936 : : ! Avoid spurious convergence.
937 [ - + ]: 9661 : niter_min=4; if (niter_done>1) niter_min=niter_done+1
938 [ + + ]: 9661 : if (inn>niter_min) then
939 [ + + ]: 27795 : test=.TRUE.
940 [ + + ]: 2674233 : abs_err(:,1) = ABS(DBLE (newg-oldg))
941 [ + + ]: 2674233 : abs_err(:,2) = ABS(AIMAG(newg-oldg))
942 : : !
943 [ + + ]: 9265 : if (tol_iter>zero) then
944 : : ! Test on the L1 norm.
945 [ + - + + : 3938750 : if (check(1)) test(1) = SUM(abs_err(:,1)) < tol_iter*SUM(ABS(DBLE (newg)))
+ + ]
946 [ + - + + : 3938750 : if (check(2)) test(2) = SUM(abs_err(:,2)) < tol_iter*SUM(ABS(AIMAG(newg)))
+ + ]
947 : : else
948 : : ! Stringent test for each point.
949 [ + - + + : 590552 : if (check(1)) test(1) = ALL( abs_err(:,1) < -tol_iter*ABS(DBLE (newg)))
+ + ]
950 [ + - + + : 593729 : if (check(2)) test(2) = ALL( abs_err(:,2) < -tol_iter*ABS(AIMAG(newg)))
+ + ]
951 : : end if
952 : : !
953 [ + + + + : 11028 : if (ALL(test)) then
+ + ]
954 : 371 : nconv = nconv+1
955 : : else
956 : : nconv = 0
957 : : end if
958 [ + + ]: 371 : if (nconv==2) then
959 [ + + ]: 132 : if(inn<100)then
960 : : write(msg,'(a,es10.2,a)')&
961 : 102 : " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after less than 100 iterations."
962 : : else
963 : : write(msg,'(a,es10.2,a,i0,a)')&
964 : 30 : " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after ",inn," iterations."
965 : : endif
966 : 132 : call wrtout(units, msg)
967 : 132 : EXIT
968 : : end if
969 : : end if
970 : :
971 [ - + + + ]: 2802047 : oldg = newg
972 : : end do ! inn
973 : :
974 [ + + ]: 54312 : green = newg
975 [ - + ]: 132 : if (nconv/=2) then
976 : : write(msg,'(a,es10.2,a,i0,a)')&
977 : 0 : " WARNING: Haydock algorithm did not converge within ",tol_iter," after ",niter_max," iterations."
978 : 0 : call wrtout(units, msg)
979 : : end if
980 : :
981 : 132 : is_converged = (nconv==2)
982 : :
983 [ - + ]: 132 : ABI_FREE(oldg)
984 [ - + ]: 132 : ABI_FREE(newg)
985 [ - + ]: 132 : ABI_FREE(cfact)
986 [ - + ]: 132 : ABI_FREE(hphi_n)
987 [ - + ]: 132 : ABI_FREE(phi_np1)
988 : :
989 : 132 : end subroutine haydock_herm_algo
990 : : !!***
991 : :
992 : : !----------------------------------------------------------------------
993 : :
994 : : !!****f* m_haydock/haydock_restart
995 : : !! NAME
996 : : !! haydock_restart
997 : : !!
998 : : !! FUNCTION
999 : : !! Restart the Haydock method from file reading the data produced in a previous run.
1000 : : !!
1001 : : !! INPUTS
1002 : : !! BSp<type(excparam)>=Parameters defining the Bethe-Salpeter calculation.
1003 : : !! omega(BSp%nomega)=Frequency mesh for the macroscopic dielectric function (broadening is already included).
1004 : : !! iq_search=The index of the q-point to be searched.
1005 : : !! hsize
1006 : : !! comm=MPI communicator.
1007 : : !! nsppol
1008 : : !! restart_file
1009 : : !!
1010 : : !! OUTPUT
1011 : : !! niter_file=Number of iterations already performed. 0 to signal that an error occurred during the reading
1012 : : !! bb_file(:)
1013 : : !! aa_file(:)
1014 : : !! phi_n_file(:)
1015 : : !! phi_nm1_file(:)
1016 : : !!
1017 : : !! SOURCE
1018 : :
1019 : 0 : subroutine haydock_restart(BSp,restart_file,ftype,iq_search,hsize,niter_file,aa_file,bb_file,phi_nm1_file,phi_n_file,comm)
1020 : :
1021 : : !Arguments ------------------------------------
1022 : : !scalars
1023 : : integer,intent(in) :: comm,hsize,iq_search,ftype
1024 : : integer,intent(out) :: niter_file
1025 : : character(len=*),intent(in) :: restart_file
1026 : : type(excparam),intent(in) :: BSp
1027 : : !arrays
1028 : : real(dp),allocatable,intent(out) :: bb_file(:)
1029 : : complex(dp),allocatable,intent(out) :: aa_file(:),phi_n_file(:),phi_nm1_file(:)
1030 : :
1031 : : !Local variables ------------------------------
1032 : : !scalars
1033 : : integer,parameter :: master=0
1034 : : integer :: nproc,my_rank,ierr,op_file, units(2)
1035 : : integer :: hsize_file,use_coupling_file
1036 : : complex(dp) :: factor_file
1037 : : character(len=500) :: msg
1038 : 0 : type(haydock_type) :: haydock_file
1039 : : !************************************************************************
1040 : :
1041 : 0 : nproc = xmpi_comm_size(comm); my_rank= xmpi_comm_rank(comm)
1042 [ # # ]: 0 : units = [std_out, ab_out]
1043 : :
1044 [ # # ]: 0 : if (my_rank==master) then
1045 : 0 : call haydock_file%open(restart_file)
1046 : 0 : call haydock_file%read_dim()
1047 : :
1048 [ # # ]: 0 : if (haydock_file%op/=ftype) then
1049 : 0 : write(msg,"(2(a,i0))")" Expecting restart file with filetype: ",ftype," but found ",op_file
1050 : 0 : ABI_ERROR(msg)
1051 : : end if
1052 : :
1053 [ # # ]: 0 : if (haydock_file%hsize/=hsize) then
1054 : : write(msg,"(2(a,i0))")&
1055 : 0 : " Rank of H_exc read from file: ",hsize_file," differs from the one used in this run: ",hsize
1056 : 0 : ABI_ERROR(msg)
1057 : : end if
1058 : :
1059 [ # # ]: 0 : if (haydock_file%use_coupling /= BSp%use_coupling) then
1060 : : write(msg,'(2(a,i0))')&
1061 : 0 : " use_coupling_file: ",use_coupling_file," differs from input file value: ",BSp%use_coupling
1062 : 0 : ABI_ERROR(msg)
1063 : : end if
1064 : :
1065 : : call haydock_file%read(Bsp%q(:,iq_search), aa_file, bb_file, &
1066 [ # # # # : 0 : phi_n_file, phi_nm1_file, niter_file, factor_file)
# # # # ]
1067 : :
1068 [ # # ]: 0 : if (niter_file == 0) then
1069 : : write(msg,"(a,3f8.4,3a)")&
1070 : 0 : " Could not find q-point: ",BSp%q(:,iq_search)," in file ",TRIM(restart_file),&
1071 : 0 : " Cannot restart Haydock iterations for this q-point"
1072 : 0 : ABI_COMMENT(msg)
1073 : : else
1074 : 0 : write(msg,'(a,i0)')" Number of iterations already performed: ",niter_file
1075 : 0 : call wrtout(units, msg)
1076 : :
1077 [ # # ]: 0 : if ( ABS(haydock_file%broad - BSp%broad) > tol6) then
1078 : : write(msg,'(2a,2(a,f8.4),a)')&
1079 : 0 : " Restart file has been produced with a different Lorentzian broadening: ",ch10,&
1080 : 0 : " broad_file: ",haydock_file%broad," input broadening: ",BSp%broad," Continuing anyway. "
1081 : 0 : ABI_WARNING(msg)
1082 : : end if
1083 : :
1084 : 0 : call haydock_file%close()
1085 : : end if
1086 : : end if
1087 : : !
1088 : : ! Master broadcasts the data.
1089 : 0 : call xmpi_bcast(niter_file,master,comm,ierr)
1090 : :
1091 [ # # ]: 0 : if (my_rank/=master) then
1092 [ # # # # : 0 : ABI_MALLOC(aa_file,(niter_file))
# # # # #
# # # #
# ]
1093 [ # # # # : 0 : ABI_MALLOC(bb_file,(niter_file))
# # # # #
# # # #
# ]
1094 [ # # # # : 0 : ABI_MALLOC(phi_nm1_file,(hsize))
# # # # #
# # # #
# ]
1095 [ # # # # : 0 : ABI_MALLOC(phi_n_file,(hsize))
# # # # #
# ]
1096 : : end if
1097 : :
1098 : 0 : call xmpi_bcast(aa_file,master,comm,ierr)
1099 : 0 : call xmpi_bcast(bb_file,master,comm,ierr)
1100 : 0 : call xmpi_bcast(phi_nm1_file,master,comm,ierr)
1101 : 0 : call xmpi_bcast(phi_n_file,master,comm,ierr)
1102 : :
1103 [ # # # # ]: 0 : end subroutine haydock_restart
1104 : : !!***
1105 : :
1106 : : !----------------------------------------------------------------------
1107 : :
1108 : : !!****f* m_haydock/haydock_mdf_to_tensor
1109 : : !! NAME
1110 : : !! haydock_mdf_to_tensor
1111 : : !!
1112 : : !! FUNCTION
1113 : : !! Transform macroscopic dielectric function from green function to each components of the tensor in red and cart coord.
1114 : : !!
1115 : : !! INPUTS
1116 : : !! BSp<type(excparam)>=Parameters defining the Bethe-Salpeter calculation.
1117 : : !! omega(BSp%nomega)=Frequency mesh for the macroscopic dielectric function (broadening is already included).
1118 : : !! Cryst=Parameters of the crystal
1119 : : !! eps(BSp%nomega,BSp%nq) = Macroscopic dielectric function to be written.
1120 : : !!
1121 : : !! OUTPUT
1122 : : !! tensor_cart(BSp%nomega,6) = dielectric tensor for each frequency, order (11,22,33,12,13,23) in cart. coord.
1123 : : !! tensor_red(BSp%nomega, 6) = idem in reduced coordinated
1124 : : !! ierr = 0 if the tensors have been successfully computed
1125 : : !! \= 0 if the system is ill-posed in terms of q-points (not enough or not independent q-points)
1126 : : !!
1127 : : !! SOURCE
1128 : :
1129 : 84 : subroutine haydock_mdf_to_tensor(BSp,Cryst,eps,tensor_cart,tensor_red,ierr)
1130 : :
1131 : : !Arguments ------------------------------------
1132 : : !scalars
1133 : : integer,intent(out) :: ierr
1134 : : type(excparam),intent(in) :: BSp
1135 : : type(crystal_t),intent(in) :: Cryst
1136 : : !arrays
1137 : : complex(dp),intent(in) :: eps(BSp%nomega,BSp%nq)
1138 : : complex(dp),intent(out) :: tensor_cart(BSp%nomega,6), tensor_red(BSp%nomega,6)
1139 : :
1140 : : !Local variables ------------------------------
1141 : : !scalars
1142 : : integer :: iq,info
1143 : : real(dp) :: normqcart, normqred
1144 : : !arrays
1145 : 84 : integer,allocatable :: ipiv(:)
1146 : : real(dp) :: qcart(3), qtmet(3)
1147 : : real(dp) :: qred2cart(3,3),qcart2red(3,3)
1148 : 168 : complex(dp) :: qqcart(BSp%nq,6), qqred(BSp%nq,6)
1149 : 0 : complex(dp) :: b(6,BSP%nomega)
1150 : : !************************************************************************
1151 : :
1152 : : ! Error flag
1153 : 84 : ierr = 0
1154 : :
1155 [ - + ]: 84 : if(BSp%nq /= 6) then
1156 : 0 : ierr = -1
1157 : 0 : return
1158 : : end if
1159 : :
1160 : : ! Transformation matrices from reduced coordinates to cartesian coordinates
1161 [ + + + + ]: 1092 : qred2cart = two_pi*Cryst%gprimd
1162 : 84 : qcart2red = qred2cart
1163 : 84 : call matrginv(qcart2red,3,3)
1164 [ + + ]: 588 : do iq = 1, 6
1165 : :
1166 : : ! Computing cartesian q-vector
1167 [ + + + + : 6552 : qcart = MATMUL(qred2cart, BSp%q(:,iq))
+ - ]
1168 : :
1169 : : ! Computing product 'metric - qred' to form quadratic form
1170 [ + + + + : 8568 : qtmet = (two_pi**2)*MATMUL(Cryst%gmet, BSp%q(:,iq))
+ - + + ]
1171 : :
1172 : : ! squared norms
1173 : 504 : normqcart = qcart(1)**2+qcart(2)**2+qcart(3)**2
1174 : 504 : normqred = (normv(BSp%q(:,iq),Cryst%gmet,"G"))**2
1175 : :
1176 : : ! Compute line 'iq' for matrix in cartesian coord
1177 : 504 : qqcart(iq,1) = (qcart(1))**2
1178 : 504 : qqcart(iq,2) = (qcart(2))**2
1179 : 504 : qqcart(iq,3) = (qcart(3))**2
1180 : 504 : qqcart(iq,4) = 2*(qcart(1)*qcart(2))
1181 : 504 : qqcart(iq,5) = 2*(qcart(1)*qcart(3))
1182 : 504 : qqcart(iq,6) = 2*(qcart(2)*qcart(3))
1183 : :
1184 : : ! Compute line 'iq' for matrix in reduced coord
1185 : 504 : qqred(iq,1) = (qtmet(1))**2
1186 : 504 : qqred(iq,2) = (qtmet(2))**2
1187 : 504 : qqred(iq,3) = (qtmet(3))**2
1188 : 504 : qqred(iq,4) = 2*(qtmet(1)*qtmet(2))
1189 : 504 : qqred(iq,5) = 2*(qtmet(1)*qtmet(3))
1190 : 504 : qqred(iq,6) = 2*(qtmet(2)*qtmet(3))
1191 : :
1192 : : ! Renormalize line
1193 [ + + ]: 3528 : qqcart(iq,:) = qqcart(iq,:)/normqcart
1194 [ + + ]: 3612 : qqred(iq,:) = qqred(iq,:)/normqred
1195 : : end do
1196 : :
1197 [ - + ]: 84 : ABI_MALLOC(ipiv,(6))
1198 : :
1199 : : ! Solving linear system
1200 [ + + + + ]: 279825 : b = TRANSPOSE(eps)
1201 : 84 : call ZGESV(6,BSp%nomega,qqcart,6,ipiv,b,6,info)
1202 [ + + + + ]: 240366 : tensor_cart = TRANSPOSE(b)
1203 : :
1204 [ - + ]: 84 : if(info /= 0) then
1205 : : ! Skipping the rest of the routine
1206 : 0 : ierr = info
1207 [ # # ]: 0 : ABI_FREE(ipiv)
1208 : 0 : return
1209 : : end if
1210 : :
1211 [ + + + + ]: 279825 : b = TRANSPOSE(eps)
1212 : 84 : call ZGESV(6,BSp%nomega,qqred,6,ipiv,b,6,info)
1213 [ + + + + ]: 240366 : tensor_red = TRANSPOSE(b)
1214 : :
1215 [ - + ]: 84 : if(info /= 0) ierr = info
1216 : :
1217 [ - + ]: 84 : ABI_FREE(ipiv)
1218 : :
1219 : : end subroutine haydock_mdf_to_tensor
1220 : : !!***
1221 : :
1222 : : !----------------------------------------------------------------------
1223 : :
1224 : : !!****f* m_haydock/haydock_psherm
1225 : : !! NAME
1226 : : !! haydock_psherm
1227 : : !!
1228 : : !! FUNCTION
1229 : : !! Reads the excitonic Hamiltonian from file and construct the Lanczos set of vectors
1230 : : !! by iterative matrix-vector multiplications.
1231 : : !!
1232 : : !! INPUTS
1233 : : !! BSp<type(excparam)>=Parameters defining the Bethe-Salpeter calculation.
1234 : : !! omega(BSp%nomega)=Frequency mesh for the macroscopic dielectric function (broadening is already included).
1235 : : !! hize
1236 : : !! my_t1,my_t2
1237 : : !! hreso(hsize,my_t1:my_t2)
1238 : : !! hcoup(hsize,my_t1:my_t2)
1239 : : !! nkets
1240 : : !! kets(hsize,nkets)
1241 : : !! comm=MPI communicator.
1242 : : !!
1243 : : !! OUTPUT
1244 : : !! green(BSp%nomega)=The imaginary part of the macroscopic dielectric function.
1245 : : !!
1246 : : !! SOURCE
1247 : :
1248 : 0 : subroutine haydock_psherm(BSp,BS_files,Cryst,Hdr_bse,hexc,hexc_i,hsize,my_t1,my_t2,nkets,kets,green,comm)
1249 : :
1250 : : !Arguments ------------------------------------
1251 : : !scalars
1252 : : integer,intent(in) :: hsize,my_t1,my_t2,nkets,comm
1253 : : type(crystal_t),intent(in) :: Cryst
1254 : : type(excparam),intent(in) :: BSp
1255 : : type(excfiles),intent(in) :: BS_files
1256 : : type(Hdr_type),intent(in) :: Hdr_bse
1257 : : type(hexc_t),intent(in) :: hexc
1258 : : type(hexc_interp_t),intent(in) :: hexc_i
1259 : : !arrays
1260 : : complex(dp),intent(out) :: green(BSp%nomega,BSp%nq)
1261 : : complex(dp),intent(in) :: kets(hsize,nkets)
1262 : :
1263 : : !Local variables ------------------------------
1264 : : !scalars
1265 : : integer,parameter :: master=0
1266 : : integer :: inn,itt,out_unt,nproc,my_rank,ierr
1267 : : integer :: niter_file,niter_max,niter_done,nsppol,iq,my_nt,term_type
1268 : : real(dp) :: ket0_hbar_norm,nfact
1269 : : logical :: can_restart,is_converged
1270 : : complex(dp) :: factor
1271 : : character(len=fnlen),parameter :: tag_file="_HAYDC_SAVE"
1272 : : character(len=500) :: msg
1273 : : character(len=fnlen) :: restart_file,out_file
1274 : : !arrays
1275 : : integer :: units(2)
1276 : 0 : real(dp),allocatable :: bb_file(:), bb(:)
1277 : 0 : complex(dp),allocatable :: aa(:),cc(:),phi_np1(:),phi_n(:),phi_nm1(:),cbuff(:)
1278 : 0 : complex(dp),allocatable :: aa_file(:),phi_n_file(:),phi_np1_file(:),cc_file(:), ket0(:)
1279 : : logical :: check(2)
1280 : : !************************************************************************
1281 : :
1282 : 0 : ABI_WARNING("Haydock + coupling is still under development")
1283 [ # # ]: 0 : units = [std_out, ab_out]
1284 : :
1285 [ # # ]: 0 : if(BSp%use_interp) then
1286 : 0 : ABI_ERROR("Coupling is not yet implemented with interpolation")
1287 : : end if
1288 : :
1289 : 0 : nproc = xmpi_comm_size(comm)
1290 : 0 : my_rank= xmpi_comm_rank(comm)
1291 : 0 : nsppol = Hdr_bse%nsppol
1292 : :
1293 : 0 : my_nt = my_t2-my_t1+1
1294 [ # # ]: 0 : ABI_CHECK(my_nt>0,"One of the processors has zero columns")
1295 : :
1296 : : ! Multiplicative factor (k-point sampling and unit cell volume)
1297 : : ! TODO be careful with the spin here
1298 : : ! TODO four_pi comes from the coulomb term 1/|q| is already included in the
1299 : : ! oscillators hence the present approach wont work if a cutoff interaction is used.
1300 : 0 : nfact = four_pi/(Cryst%ucvol*BSp%nkbz)
1301 [ # # ]: 0 : if (nsppol==1) nfact=two*nfact
1302 : :
1303 : 0 : write(msg,'(a,i0)')' Haydock algorithm with MAX number of iterations: ',BSp%niter
1304 : 0 : call wrtout(std_out,msg)
1305 : : !
1306 : : ! Check for presence of the restart file.
1307 : 0 : can_restart=.FALSE.
1308 : :
1309 [ # # ]: 0 : if ( BS_files%in_haydock_basename /= BSE_NOFILE) then
1310 [ # # ]: 0 : restart_file = strcat(BS_files%in_haydock_basename,tag_file)
1311 [ # # ]: 0 : if (file_exists(restart_file) ) then
1312 : 0 : can_restart=.TRUE.
1313 [ # # ]: 0 : msg = strcat(" Restarting Haydock calculation from file: ",restart_file)
1314 : 0 : call wrtout(units, msg)
1315 : 0 : ABI_ERROR("Restart is not tested")
1316 : : else
1317 : 0 : can_restart=.FALSE.
1318 : 0 : ABI_WARNING(strcat("Cannot find restart file: ",restart_file))
1319 : : end if
1320 : : end if
1321 : : !
1322 : : ! Open the file and writes basic dimensions and info.
1323 [ # # ]: 0 : if (my_rank==master) then
1324 [ # # ]: 0 : out_file = TRIM(BS_files%out_basename)//TRIM(tag_file)
1325 [ # # ]: 0 : if (open_file(out_file,msg,newunit=out_unt,form="unformatted") /= 0) then
1326 : 0 : ABI_ERROR(msg)
1327 : : end if
1328 : : ! write header TODO: standardize this part.
1329 : 0 : write(out_unt)hsize,Bsp%use_coupling,BSE_HAYD_IMEPS,nkets,Bsp%broad
1330 : : end if
1331 : : !
1332 : : ! Select the terminator for the continued fraction.
1333 : 0 : term_type=0 !; if (Bsp%hayd_term>0) term_type=2
1334 : 0 : call wrtout(std_out,sjoin("Using terminator type: ",itoa(term_type)))
1335 : : !
1336 : : ! Calculate green(w) for the different starting kets.
1337 [ # # # # ]: 0 : green=czero
1338 [ # # ]: 0 : do iq=1,nkets
1339 [ # # # # : 0 : ABI_MALLOC(ket0,(my_nt))
# # # # #
# # # ]
1340 [ # # # # : 0 : ket0 = kets(my_t1:my_t2,iq)
# # # # ]
1341 : : !
1342 : 0 : niter_file=0
1343 : :
1344 [ # # ]: 0 : if (can_restart) then
1345 : : call haydock_restart(BSp,restart_file,BSE_HAYD_IMEPS,iq,hsize,&
1346 [ # # # # : 0 : niter_file,aa_file,bb_file,phi_np1_file,phi_n_file,comm)
# # # # ]
1347 : : end if
1348 : :
1349 [ # # # # : 0 : ABI_MALLOC(phi_nm1,(my_nt))
# # # # ]
1350 [ # # # # : 0 : ABI_MALLOC(phi_n,(my_nt))
# # # # ]
1351 [ # # # # : 0 : ABI_MALLOC(phi_np1,(my_nt))
# # # # ]
1352 : : !
1353 : : ! TODO: Note the different convention used for the coefficients
1354 : : ! Should use the same convention in the Hermitian case.
1355 : 0 : niter_max = niter_file + Bsp%niter
1356 [ # # # # : 0 : ABI_MALLOC(aa,(niter_max))
# # # # #
# # # ]
1357 [ # # # # : 0 : ABI_MALLOC(bb,(niter_max+1))
# # # # #
# # # #
# ]
1358 [ # # # # : 0 : ABI_MALLOC(cc,(niter_max+1))
# # # # #
# # # ]
1359 [ # # # # : 0 : aa=czero; bb=czero; cc=czero
# # ]
1360 : :
1361 [ # # ]: 0 : if (niter_file==0) then ! Calculation from scratch.
1362 [ # # # # : 0 : phi_n = ket0
# # # # ]
1363 : 0 : call hexc%matmul_full(hexc_i, phi_n, phi_np1, -1)
1364 : : !phi_np1 = MATMUL(hreso,ket0) - MATMUL(hcoup,CONJG(ket0))
1365 [ # # ]: 0 : ket0_hbar_norm = SQRT(two*DBLE(DOT_PRODUCT(phi_n,phi_np1)))
1366 [ # # ]: 0 : phi_n = phi_n /ket0_hbar_norm
1367 [ # # ]: 0 : phi_np1 = phi_np1/ket0_hbar_norm
1368 : : !ket0 = ket0/ket0_hbar_norm
1369 : 0 : cc(1)=zero ! <P|F|P>
1370 : : !cc(1) = DOT_PRODUCT(ket0,phi_np1)
1371 : : !write(std_out,*)" cc(1), ket0_hbar_norm =",cc(1),ket0_hbar_norm
1372 : :
1373 [ # # ]: 0 : phi_nm1 = czero
1374 : 0 : niter_done=0 ! TODO Be careful here
1375 : :
1376 : : else ! Use the previously calculates a and b.
1377 : 0 : niter_done=niter_file
1378 : 0 : ABI_ERROR("Restart not coded")
1379 : : !aa(1:niter_done) = aa_file
1380 : : !bb(1:niter_done) = bb_file
1381 : : !phi_np1=phi_np1_file(my_t1:my_t2) ! Select the slice treated by this node.
1382 : : !phi_n =phi_n_file (my_t1:my_t2)
1383 : : end if
1384 : :
1385 [ # # ]: 0 : if (can_restart) then
1386 [ # # ]: 0 : ABI_FREE(aa_file)
1387 [ # # ]: 0 : ABI_FREE(bb_file)
1388 : 0 : ABI_FREE(cc_file)
1389 : : ABI_FREE(phi_np1_file)
1390 : : ABI_FREE(phi_n_file)
1391 : : end if
1392 : :
1393 : : ! This factor gives the correct results
1394 : 0 : factor = -nfact*ket0_hbar_norm / SQRT(two)
1395 : :
1396 : : ! Which quantity should be checked for convergence?
1397 : 0 : check = (/.TRUE.,.TRUE./)
1398 [ # # ]: 0 : if (ABS(Bsp%haydock_tol(2)-one)<tol6) check = (/.TRUE. ,.FALSE./)
1399 [ # # ]: 0 : if (ABS(Bsp%haydock_tol(2)-two)<tol6) check = (/.FALSE.,.TRUE./)
1400 : :
1401 : : call haydock_psherm_optalgo(niter_done,niter_max,BSp%nomega,BSp%omega,BSp%haydock_tol(1),check,hexc,hexc_i,&
1402 : : hsize,my_t1,my_t2,factor,term_type,aa,bb,cc,ket0,ket0_hbar_norm,phi_nm1,phi_n,phi_np1,&
1403 : 0 : green(:,iq),inn,is_converged,comm)
1404 : :
1405 : : ! Save the a"s and the b"s for possible restarting.
1406 : : ! 1) Info on the Q.
1407 : : ! 2) Number of iterations performed.
1408 : : ! 3) do iter=1,niter_performed
1409 : : ! aa(iter),bb(iter)
1410 : : ! end do
1411 : : ! 4) |n-1>
1412 : : ! |n>
1413 : : ! |n+1>
1414 : : !
1415 [ # # ]: 0 : if (my_rank==master) then ! Open the file and writes basic dimensions and info.
1416 : 0 : write(out_unt)Bsp%q(:,iq)
1417 : 0 : write(out_unt)MIN(inn,niter_max) ! NB: if the previous loop completed inn=niter_max+1
1418 [ # # ]: 0 : do itt=1,MIN(inn,niter_max) ! if we exited then inn is not incremented by one.
1419 : 0 : write(out_unt)itt,aa(itt),bb(itt)
1420 : : end do
1421 : : end if
1422 : : !
1423 : : ! cbuff is used as workspace to gather |n-1>, |n> and |n+1>.
1424 [ # # # # : 0 : ABI_MALLOC(cbuff,(hsize))
# # # # #
# # # #
# ]
1425 [ # # # # ]: 0 : cbuff=czero; cbuff(my_t1:my_t2) = phi_nm1
1426 : 0 : call xmpi_sum_master(cbuff,master,comm,ierr)
1427 [ # # ]: 0 : if (my_rank==master) write(out_unt) cbuff ! |n-1>
1428 : :
1429 [ # # # # ]: 0 : cbuff=czero; cbuff(my_t1:my_t2) = phi_n
1430 : 0 : call xmpi_sum_master(cbuff,master,comm,ierr)
1431 [ # # ]: 0 : if (my_rank==master) write(out_unt) cbuff ! |n>
1432 : :
1433 [ # # # # ]: 0 : cbuff=czero; cbuff(my_t1:my_t2) = phi_np1
1434 : 0 : call xmpi_sum_master(cbuff,master,comm,ierr)
1435 [ # # ]: 0 : if (my_rank==master) write(out_unt) cbuff ! |n+1>
1436 : :
1437 [ # # ]: 0 : ABI_FREE(phi_nm1)
1438 [ # # ]: 0 : ABI_FREE(phi_n)
1439 [ # # ]: 0 : ABI_FREE(phi_np1)
1440 [ # # ]: 0 : ABI_FREE(cbuff)
1441 [ # # ]: 0 : ABI_FREE(aa)
1442 [ # # ]: 0 : ABI_FREE(bb)
1443 [ # # ]: 0 : ABI_FREE(cc)
1444 [ # # ]: 0 : ABI_FREE(ket0)
1445 : : end do ! iq
1446 : :
1447 [ # # ]: 0 : if (my_rank==master) close(out_unt)
1448 : :
1449 : 0 : call xmpi_barrier(comm)
1450 : :
1451 [ # # # # : 0 : end subroutine haydock_psherm
# # # # #
# ]
1452 : : !!***
1453 : :
1454 : : !----------------------------------------------------------------------
1455 : :
1456 : : !!****f* m_haydock/haydock_psherm_optalgo
1457 : : !! NAME
1458 : : !! haydock_psherm_optalgo
1459 : : !!
1460 : : !! FUNCTION
1461 : : !! Haydock algorithm for pseudo-hermitian matrix
1462 : : !!
1463 : : !! INPUTS
1464 : : !! niter_done=Number of iterations already performed (0 if the run starts from scratch).
1465 : : !! niter_tot=Max number of iterations. Always > niter_done
1466 : : !! nomega=Number of Frequency points for the evaluation of the matrix element.
1467 : : !! omega(nomega)=Frequency set (imaginary part is already included).
1468 : : !! tol_iter=Tollerance used to stop the the algorithm.
1469 : : !! check(2)=Logical flags to specify where both the real and the imaginary part of the
1470 : : !! matrix elements of the Green functions have to be checked for convergence.
1471 : : !! hsize=Size of the blocks.
1472 : : !! my_t1,my_t2=Indeces of the first and last column stored treated by this done.
1473 : : !! term_type=0 if no terminator is used, 1 otherwise.
1474 : : !! hreso(hsize,my_t1:my_t2)=The columns of the resonant block.
1475 : : !! hcoup(hsize,my_t1:my_t2)=The columns of the coupling block.
1476 : : !! factor
1477 : : !! comm=MPI communicator.
1478 : : !!
1479 : : !! OUTPUT
1480 : : !! green(nomega)=Output matrix elements.
1481 : : !! inn=Last iteration performed.
1482 : : !! is_converged=.TRUE. of the algorithm converged.
1483 : : !!
1484 : : !! SIDE EFFECTS
1485 : : !! phi_nm1(my_t2-my_t1+1), phi_n(my_t2-my_t1+1)
1486 : : !! input: vectors used to initialize the iteration
1487 : : !! output: the vectors obtained in the last iteration
1488 : : !! aa(niter_tot) and bb(niter_tot+1)
1489 : : !! if niter_done>0: aa(1:niter_done), bb(1:niter_done) store the coefficients of the previous run.
1490 : : !! when the routine returns aa(1:inn) and bb(1:inn) contain the matrix elements of the tridiagonal form.
1491 : : !! cc(niter_tot+1)
1492 : : !!
1493 : : !! SOURCE
1494 : :
1495 : 0 : subroutine haydock_psherm_optalgo(niter_done,niter_tot,nomega,omega,tol_iter,check,hexc,hexc_i,hsize,my_t1,my_t2,&
1496 : 0 : & factor,term_type,aa,bb,cc,ket0,ket0_hbar_norm,phi_nm1,phi_n,phi_np1,green,inn,is_converged,comm)
1497 : :
1498 : : !Arguments ------------------------------------
1499 : : !scalars
1500 : : integer,intent(in) :: niter_tot,niter_done,nomega,comm,hsize,my_t1,my_t2,term_type
1501 : : integer,intent(out) :: inn
1502 : : logical,intent(out) :: is_converged
1503 : : real(dp),intent(in) :: tol_iter,ket0_hbar_norm
1504 : : complex(dp),intent(in) :: factor
1505 : : type(hexc_t),intent(in) :: hexc
1506 : : type(hexc_interp_t),intent(in) :: hexc_i
1507 : : !arrays
1508 : : real(dp),intent(inout) :: bb(niter_tot+1)
1509 : : complex(dp),intent(out) :: green(nomega)
1510 : : complex(dp),intent(in) :: omega(nomega)
1511 : : complex(dp),intent(inout) :: aa(niter_tot),cc(niter_tot+1)
1512 : : complex(dp),intent(in) :: ket0(my_t2-my_t1+1)
1513 : : complex(dp),intent(inout) :: phi_nm1(my_t2-my_t1+1)
1514 : : complex(dp),intent(inout) :: phi_n (my_t2-my_t1+1)
1515 : : complex(dp),intent(inout) :: phi_np1(my_t2-my_t1+1)
1516 : : logical,intent(in) :: check(2)
1517 : :
1518 : : !Local variables ------------------------------
1519 : : !scalars
1520 : : integer :: my_nt,niter_min,nconv,parity,ii,jj,tdim,ierr
1521 : : integer :: row_max,col_max,nlev
1522 : : character(len=500) :: msg
1523 : : real(dp) :: max_err,mean_err,mean_err2,std_dev,err
1524 : : logical :: keep_vectors=.TRUE.
1525 : : !arrays
1526 : : integer :: units(2)
1527 : 0 : real(dp) :: abs_err(nomega,2) !,ww_err(nomega,2)
1528 : 0 : complex(dp) :: gn0(nomega,niter_tot)
1529 : 0 : complex(dp),allocatable :: oldg(:),newg(:)
1530 : 0 : complex(dp),allocatable :: hphi_n(:),save_phi(:,:)
1531 : 0 : complex(dp),allocatable :: alpha(:,:),beta(:,:),ovlp(:,:)
1532 : 0 : complex(dp),allocatable :: phi_test(:),phi_test2(:),g00(:)
1533 : : logical :: test(2)
1534 : : !************************************************************************
1535 : :
1536 : : ABI_UNUSED(ket0_hbar_norm)
1537 [ # # ]: 0 : units = [std_out, ab_out]
1538 : :
1539 : 0 : my_nt = my_t2-my_t1+1
1540 : :
1541 [ # # # # : 0 : ABI_MALLOC(oldg,(nomega))
# # # # #
# # # ]
1542 [ # # # # : 0 : ABI_MALLOC(newg,(nomega))
# # # # ]
1543 [ # # # # : 0 : ABI_MALLOC(g00,(nomega))
# # # # ]
1544 [ # # # # : 0 : oldg=czero; newg=czero; g00=czero
# # ]
1545 : 0 : nconv=0
1546 : :
1547 [ # # # # ]: 0 : keep_vectors = (keep_vectors.and.xmpi_comm_size(comm)==1)
1548 [ # # ]: 0 : if (keep_vectors) then
1549 [ # # # # : 0 : ABI_MALLOC_OR_DIE(save_phi,(my_t2-my_t1+1,niter_tot), ierr)
# # # # #
# # # # #
# # # # #
# ]
1550 [ # # # # ]: 0 : save_phi=czero
1551 : : end if
1552 : :
1553 [ # # # # : 0 : ABI_MALLOC(hphi_n,(hsize))
# # # # #
# # # ]
1554 : :
1555 [ # # ]: 0 : do inn=niter_done+1,niter_tot
1556 : : !
1557 : : ! a(n) = <Vn+1|F|Vn+1> = <Vn|HFH|Vn>) = 0 by symmetry.
1558 : 0 : aa(inn)=zero
1559 : :
1560 : : ! |n+1> = |n+1> - a(n)|Vn> - a(n)|n-1>
1561 [ # # ]: 0 : phi_np1 = phi_np1 - bb(inn)*phi_nm1
1562 : : !
1563 : : ! |n-1> = |n>
1564 : : ! |n> = |n+1>
1565 [ # # ]: 0 : phi_nm1 = phi_n
1566 [ # # ]: 0 : phi_n = phi_np1
1567 : :
1568 : : !|n+1> = H |n> using all eh components.
1569 : 0 : parity = (-1)**(inn+1)
1570 : 0 : call hexc%matmul_full(hexc_i, phi_n, phi_np1, parity)
1571 : :
1572 : : !phi_np1 = MATMUL(hreso,phi_n) + parity * MATMUL(hcoup,CONJG(phi_n))
1573 : : !call xmpi_sum(hphi_np1,comm,ierr)
1574 : : !
1575 : : ! B(n+1)= <n|F|n+1>^(1/2) = <n|FH|n>^(1/2))= (2*Re(<n|V+1>))^(1/2)
1576 : : ! by symmetry, where the dot_product is done in the resonant eh sub-space.
1577 : : !
1578 [ # # ]: 0 : bb(inn+1)=SQRT(two*DBLE(DOT_PRODUCT(phi_n,phi_np1)))
1579 : : !bb(inn+1)=two*DBLE(DOT_PRODUCT(phi_n,phi_np1))
1580 : : !call xmpi_sum(bb(inn+1),comm,ierr)
1581 : : !bb(inn+1)=SQRT(bb(inn+1)
1582 : : !
1583 : : !|n+1> =|n+1>/B(n+1)
1584 [ # # ]: 0 : phi_n = phi_n /bb(inn+1)
1585 [ # # ]: 0 : phi_np1 = phi_np1/bb(inn+1)
1586 : :
1587 [ # # # # ]: 0 : if (keep_vectors) save_phi(:,inn) = phi_n
1588 : :
1589 : 0 : parity = (-1)**(inn+1)
1590 : : !if (parity==-1) then
1591 : : ! cc(inn+1)=czero
1592 : : !else
1593 [ # # # # ]: 0 : cc(inn+1)=DOT_PRODUCT(ket0,phi_n) + parity * DOT_PRODUCT(phi_n,ket0)
1594 : : !end if
1595 : : !call xmpi_sum(cc(inn+1),comm,ierr)
1596 : :
1597 : 0 : write(msg,'(a,i0,a,3es12.4)')' Iteration number ',inn,', b_i RE(c_i+1) IM(c_i+1) ',bb(inn),REAL(cc(inn+1)),AIMAG(cc(inn+1))
1598 : 0 : call wrtout(std_out,msg)
1599 : :
1600 : 0 : call continued_fract(inn,term_type,aa,bb(2:),nomega,omega,g00)
1601 [ # # ]: 0 : gn0(:,1) = g00
1602 : :
1603 : : if (.FALSE.) then
1604 : : gn0(:,2) = (one - omega(:)*g00(:))/bb(2)
1605 : : do ii=3,inn
1606 : : gn0(:,ii) = -(-bb(ii)*gn0(:,ii-2) -omega(:)*gn0(:,ii-1))/bb(ii+1)
1607 : : end do
1608 : : else
1609 [ # # ]: 0 : do ii=2,inn
1610 : 0 : nlev = inn-ii
1611 : 0 : call continued_fract(nlev,term_type,aa,bb(ii+1:),nomega,omega,g00)
1612 [ # # ]: 0 : gn0(:,ii) = +bb(ii+1) * g00 * gn0(:,ii-1)
1613 : : end do
1614 : : end if
1615 : :
1616 [ # # ]: 0 : newg=czero
1617 [ # # ]: 0 : do ii=1,inn
1618 [ # # ]: 0 : newg(:) = newg + cc(ii)* gn0(:,ii)
1619 : : end do
1620 [ # # ]: 0 : newg = factor*newg
1621 : : !
1622 : : ! Avoid spurious convergence.
1623 [ # # ]: 0 : niter_min=4; if (niter_done>1) niter_min=niter_done+1
1624 [ # # ]: 0 : if (inn>niter_min) then
1625 [ # # ]: 0 : test=.TRUE.
1626 [ # # ]: 0 : abs_err(:,1) = ABS(DBLE (newg-oldg))
1627 [ # # ]: 0 : abs_err(:,2) = ABS(AIMAG(newg-oldg))
1628 : : !
1629 [ # # ]: 0 : if (tol_iter>zero) then
1630 : : ! Test on the L1 norm.
1631 [ # # # # : 0 : if (check(1)) test(1) = SUM(abs_err(:,1)) < tol_iter*SUM(ABS(DBLE (newg)))
# # ]
1632 [ # # # # : 0 : if (check(2)) test(2) = SUM(abs_err(:,2)) < tol_iter*SUM(ABS(AIMAG(newg)))
# # ]
1633 : : else
1634 : : ! Stringent test for each point.
1635 [ # # # # : 0 : if (check(1)) test(1) = ALL( abs_err(:,1) < -tol_iter*ABS(DBLE (newg)))
# # ]
1636 [ # # # # : 0 : if (check(2)) test(2) = ALL( abs_err(:,2) < -tol_iter*ABS(AIMAG(newg)))
# # ]
1637 : : end if
1638 : : !
1639 [ # # # # : 0 : if (ALL(test)) then
# # ]
1640 : 0 : nconv = nconv+1
1641 : : else
1642 : : nconv = 0
1643 : : end if
1644 [ # # ]: 0 : if (nconv==2) then
1645 [ # # ]: 0 : if(inn<100)then
1646 : : write(msg,'(a,es10.2,a)')&
1647 : 0 : " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after less than 100 iterations."
1648 : : else
1649 : : write(msg,'(a,es10.2,a,i0,a)')&
1650 : 0 : " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after ",inn," iterations."
1651 : : endif
1652 : 0 : call wrtout(units, msg)
1653 : 0 : EXIT
1654 : : end if
1655 : : end if
1656 : : !
1657 [ # # # # ]: 0 : oldg = newg
1658 : : end do ! inn
1659 : :
1660 [ # # ]: 0 : green = newg
1661 [ # # ]: 0 : if (nconv/=2) then
1662 : : write(msg,'(a,es10.2,a,i0,a)')&
1663 : 0 : " WARNING: Haydock algorithm did not converge within ",tol_iter," after ",niter_tot," iterations."
1664 : 0 : call wrtout(units, msg)
1665 : : end if
1666 : :
1667 : 0 : is_converged = (nconv==2)
1668 : :
1669 [ # # ]: 0 : ABI_FREE(oldg)
1670 [ # # ]: 0 : ABI_FREE(newg)
1671 [ # # ]: 0 : ABI_FREE(g00)
1672 [ # # ]: 0 : ABI_FREE(hphi_n)
1673 : :
1674 [ # # ]: 0 : if (keep_vectors) then
1675 : 0 : tdim = MIN(inn,niter_tot)
1676 [ # # # # : 0 : ABI_MALLOC(ovlp,(tdim,tdim))
# # # # #
# # # # #
# # ]
1677 : :
1678 [ # # # # : 0 : ABI_MALLOC(phi_test,(hsize))
# # # # ]
1679 [ # # # # : 0 : ABI_MALLOC(phi_test2,(hsize))
# # # # ]
1680 : :
1681 : 0 : max_err=smallest_real; mean_err=zero; mean_err2=zero; row_max=-1
1682 [ # # ]: 0 : do ii=1,tdim
1683 : 0 : parity = (-1)**(ii+1)
1684 [ # # # # : 0 : phi_test = save_phi(:,ii)
# # # # ]
1685 : 0 : call hexc%matmul_full(hexc_i, phi_test, phi_test2, parity)
1686 : : !phi_test2 = MATMUL(hreso,phi_test) + parity * MATMUL(hcoup,CONJG(phi_test))
1687 [ # # # # ]: 0 : ovlp(ii,ii) = DOT_PRODUCT(phi_test,phi_test2) + DOT_PRODUCT(phi_test2,phi_test)
1688 : 0 : err = ABS(ovlp(ii,ii)-cone)
1689 : 0 : mean_err = mean_err + err
1690 : 0 : mean_err2 = mean_err2 + err**2
1691 [ # # ]: 0 : if (err > max_err) then
1692 : 0 : max_err = err
1693 : 0 : row_max = ii
1694 : : end if
1695 : : end do
1696 : 0 : mean_err = mean_err/tdim
1697 : 0 : std_dev = mean_err2/tdim -mean_err**2
1698 : : write(std_out,'(a,i0,1x,3es14.6)') &
1699 : 0 : " Error in normalization (ii, max_err,mean,std_dev): ",row_max,max_err,mean_err,std_dev
1700 : :
1701 [ # # ]: 0 : ABI_FREE(phi_test)
1702 [ # # ]: 0 : ABI_FREE(phi_test2)
1703 : :
1704 [ # # # # : 0 : ABI_MALLOC(alpha,(hsize,tdim))
# # # # #
# # # # #
# # ]
1705 : :
1706 : : ! Less efficient but for sake of simplicity with hexc_matmul
1707 : : ! TODO possibility to call hreso * phi, and hcoup * phi separately
1708 [ # # ]: 0 : do ii=1,tdim
1709 : 0 : parity = (-1)**(ii+1)
1710 : 0 : call hexc%matmul_full(hexc_i, save_phi(:,ii), alpha(:,ii), parity)
1711 : : end do
1712 : :
1713 : : !alpha = MATMUL(hreso,save_phi(:,1:tdim))
1714 : : !
1715 : : !do ii=1,tdim
1716 : : ! parity = (-1)**(ii+1)
1717 : : ! alpha(:,ii) = alpha(:,ii) + parity*MATMUL(hcoup,CONJG(save_phi(:,ii)))
1718 : : !end do
1719 : :
1720 [ # # # # : 0 : ovlp = MATMUL(TRANSPOSE(CONJG(save_phi(:,1:tdim))),alpha)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
1721 : :
1722 [ # # # # : 0 : ABI_MALLOC(beta,(hsize,tdim))
# # # # #
# # # ]
1723 [ # # ]: 0 : do ii=1,tdim
1724 : 0 : parity = (-1)**(ii+1)
1725 [ # # ]: 0 : beta(:,ii) = parity*save_phi(:,ii)
1726 [ # # ]: 0 : alpha(:,ii) = -parity*alpha(:,ii)
1727 : : end do
1728 : :
1729 [ # # # # : 0 : ovlp = ovlp - MATMUL(TRANSPOSE(CONJG(beta)),alpha)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
1730 : :
1731 : 0 : max_err=smallest_real; row_max=-1; col_max=-1
1732 : 0 : mean_err=zero; mean_err2=zero
1733 [ # # ]: 0 : do jj=1,tdim
1734 [ # # ]: 0 : do ii=1,jj
1735 : 0 : err = ABS(ovlp(ii,jj))
1736 [ # # ]: 0 : if (ii==jj) err = ABS(err - one)
1737 : 0 : mean_err = mean_err + err
1738 : 0 : mean_err2 = mean_err2 + err**2
1739 [ # # ]: 0 : if (err > max_err) then
1740 : 0 : max_err = err
1741 : 0 : row_max=ii
1742 : 0 : col_max=jj
1743 : : end if
1744 : : end do
1745 : : end do
1746 : :
1747 : 0 : mean_err = mean_err/(tdim*(tdim+1)/2)
1748 : 0 : std_dev = mean_err2/(tdim*(tdim+1)/2) - mean_err**2
1749 : : write(std_out,'(a,2(i0,1x),3es14.6)')&
1750 : 0 : " Error in Hbar-ortho (i,j), max_err, mean, std_dev ",row_max,col_max,max_err,mean_err,std_dev
1751 : : !call print_arr(ovlp,max_r=185,max_c=10,unit=std_out)
1752 : :
1753 [ # # ]: 0 : ABI_FREE(alpha)
1754 [ # # ]: 0 : ABI_FREE(beta)
1755 [ # # ]: 0 : ABI_FREE(ovlp)
1756 [ # # ]: 0 : ABI_FREE(save_phi)
1757 : : end if
1758 : :
1759 [ # # # # ]: 0 : end subroutine haydock_psherm_optalgo
1760 : : !!***
1761 : :
1762 : : !----------------------------------------------------------------------
1763 : :
1764 : : !!****f* m_haydock/haydock_bilanczos
1765 : : !! NAME
1766 : : !! haydock_bilanczos
1767 : : !!
1768 : : !! FUNCTION
1769 : : !! Reads the excitonic Hamiltonian from file and construct the Lanczos set of vectors
1770 : : !! by iterative matrix-vector multiplications for any general matrix.
1771 : : !!
1772 : : !! INPUTS
1773 : : !! BSp<type(excparam)>=Parameters defining the Bethe-Salpeter calculation.
1774 : : !! omega(BSp%nomega)=Frequency mesh for the macroscopic dielectric function (broadening is already included).
1775 : : !! hize
1776 : : !! my_t1,my_t2
1777 : : !! hreso(hsize,my_t1:my_t2)
1778 : : !! hcoup(hsize,my_t1:my_t2)
1779 : : !! nkets
1780 : : !! kets(hsize,nkets)
1781 : : !! comm=MPI communicator.
1782 : : !!
1783 : : !! OUTPUT
1784 : : !! green(BSp%nomega)=The imaginary part of the macroscopic dielectric function.
1785 : : !!
1786 : : !! SOURCE
1787 : :
1788 : 10 : subroutine haydock_bilanczos(BSp,BS_files,Cryst,Hdr_bse,hexc,hexc_i,hsize,my_t1,my_t2,nkets,kets,ep_renorms,green,comm)
1789 : :
1790 : : !Arguments ------------------------------------
1791 : : !scalars
1792 : : integer,intent(in) :: hsize,my_t1,my_t2,nkets,comm
1793 : : type(crystal_t),intent(in) :: Cryst
1794 : : type(excparam),intent(in) :: BSp
1795 : : type(excfiles),intent(in) :: BS_files
1796 : : type(Hdr_type),intent(in) :: Hdr_bse
1797 : : !arrays
1798 : : complex(dp),intent(out) :: green(BSp%nomega,BSp%nq)
1799 : : complex(dp),intent(in) :: kets(hsize,nkets)
1800 : : complex(dp),intent(in) :: ep_renorms(hsize)
1801 : :
1802 : : !Local variables ------------------------------
1803 : : !scalars
1804 : : integer,parameter :: master=0
1805 : : integer :: inn,itt,out_unt,nproc,my_rank,ierr
1806 : : integer :: niter_file,niter_max,niter_done,nsppol,iq,my_nt,term_type,n_all_omegas
1807 : : real(dp) :: ket0_hbar_norm,nfact,norm
1808 : : logical :: can_restart,is_converged
1809 : : complex(dp) :: factor
1810 : : character(len=fnlen),parameter :: tag_file="_HAYDC_SAVE"
1811 : : character(len=500) :: msg
1812 : : character(len=fnlen) :: restart_file,out_file
1813 : : type(hexc_t),intent(in) :: hexc
1814 : : type(hexc_interp_t),intent(in) :: hexc_i
1815 : : !arrays
1816 : 10 : complex(dp),allocatable :: aa_file(:),bb_file(:),cc_file(:)
1817 : 10 : complex(dp),allocatable :: aa(:),bb(:),cc(:)
1818 : 10 : complex(dp),allocatable :: phi_np1(:),phi_n(:),phi_nm1(:)
1819 : 10 : complex(dp),allocatable :: phit_np1(:),phit_n(:),phit_nm1(:)
1820 : 10 : complex(dp),allocatable :: cbuff(:), phi_n_file(:),phi_np1_file(:)
1821 : 10 : complex(dp),allocatable :: ket0(:), hphi_n(:), hphit_n(:)
1822 : 10 : complex(dp),allocatable :: all_omegas(:),green_temp(:,:)
1823 : : logical :: check(2)
1824 : : !************************************************************************
1825 : :
1826 : 10 : ABI_WARNING("Haydock with Bilanczos is still under development")
1827 : :
1828 [ - + ]: 10 : if(BSp%use_interp) then
1829 : 0 : ABI_ERROR("Bilanczos is not yet implemented with interpolation")
1830 : : end if
1831 : :
1832 : 10 : nproc = xmpi_comm_size(comm)
1833 : 10 : my_rank= xmpi_comm_rank(comm)
1834 : 10 : nsppol = Hdr_bse%nsppol
1835 : :
1836 : 10 : my_nt = my_t2-my_t1+1
1837 [ - + ]: 10 : ABI_CHECK(my_nt>0,"One of the processors has zero columns")
1838 : :
1839 : : ! Multiplicative factor (k-point sampling and unit cell volume)
1840 : : ! TODO be careful with the spin here
1841 : : ! TODO four_pi comes from the coulomb term 1/|q| is already included in the
1842 : : ! oscillators hence the present approach wont work if a cutoff interaction is used.
1843 : 10 : nfact = four_pi/(Cryst%ucvol*BSp%nkbz)
1844 [ + - ]: 10 : if (nsppol==1) nfact=two*nfact
1845 : :
1846 : 10 : write(msg,'(a,i0)')' Bi-Lanczos algorithm with MAX number of iterations: ',BSp%niter
1847 : 10 : call wrtout(std_out,msg)
1848 : : !
1849 : : ! Check for presence of the restart file.
1850 : 10 : can_restart=.FALSE.
1851 : :
1852 [ + - ]: 10 : if (BS_files%in_haydock_basename /= BSE_NOFILE) then
1853 [ # # ]: 0 : restart_file = strcat(BS_files%in_haydock_basename,tag_file)
1854 [ # # ]: 0 : if (file_exists(restart_file) ) then
1855 : 0 : can_restart=.TRUE.
1856 [ # # ]: 0 : msg = strcat(" Restarting Haydock calculation from file: ",restart_file)
1857 : 0 : call wrtout(std_out,msg)
1858 : 0 : call wrtout(ab_out,msg)
1859 : 0 : ABI_ERROR("Restart is not implemented")
1860 : : else
1861 : 0 : can_restart=.FALSE.
1862 : 0 : ABI_WARNING(strcat("Cannot find restart file: ",restart_file))
1863 : : end if
1864 : : end if
1865 : : !
1866 : : ! Open the file and writes basic dimensions and info.
1867 [ + - ]: 10 : if (my_rank==master) then
1868 [ + - ]: 10 : out_file = TRIM(BS_files%out_basename)//TRIM(tag_file)
1869 [ - + ]: 10 : if (open_file(out_file,msg,newunit=out_unt,form="unformatted") /= 0) then
1870 : 0 : ABI_ERROR(msg)
1871 : : end if
1872 : : ! write header TODO: standardize this part.
1873 : 10 : write(out_unt)hsize,Bsp%use_coupling,BSE_HAYD_IMEPS,nkets,Bsp%broad
1874 : : end if
1875 : : !
1876 : : ! Select the terminator for the continued fraction.
1877 : 10 : term_type=0 !; if (Bsp%hayd_term>0) term_type=2
1878 : 10 : call wrtout(std_out,sjoin("Using terminator type: ",itoa(term_type)))
1879 : : !
1880 : : ! Calculate green(w) for the different starting kets.
1881 [ + + + + ]: 60130 : green=czero
1882 [ + + ]: 70 : do iq=1,nkets
1883 [ - + + - : 180 : ABI_MALLOC(ket0,(hexc%hsize))
+ - + - -
+ - + ]
1884 [ + - - + : 5880 : ket0 = kets(:,iq)
- - + + ]
1885 : : !
1886 : 60 : niter_file=0
1887 : :
1888 : : if (can_restart) then
1889 : : ! call haydock_restart(BSp,restart_file,BSE_HAYD_IMEPS,iq,hsize,&
1890 : : !& niter_file,aa_file,bb_file,phi_np1_file,phi_n_file,comm)
1891 : : end if
1892 : : !
1893 [ - + + - : 180 : ABI_MALLOC(phi_nm1,(my_nt))
+ - + - -
+ - + ]
1894 [ - + + - : 120 : ABI_MALLOC(phi_n,(my_nt))
- + - + ]
1895 [ - + + - : 120 : ABI_MALLOC(phi_np1,(my_nt))
- + - + ]
1896 [ - + + - : 120 : ABI_MALLOC(phit_nm1,(my_nt))
- + - + ]
1897 [ - + + - : 120 : ABI_MALLOC(phit_n,(my_nt))
- + - + ]
1898 [ - + + - : 120 : ABI_MALLOC(phit_np1,(my_nt))
- + - + ]
1899 [ - + + - : 120 : ABI_MALLOC(hphi_n,(hexc%hsize))
- + - + ]
1900 [ - + + - : 120 : ABI_MALLOC(hphit_n,(hexc%hsize))
- + - + ]
1901 : : !
1902 : : ! TODO: Note the different convention used for the coefficients
1903 : : ! Should use the same convention in the Hermitian case.
1904 : 60 : niter_max = niter_file + Bsp%niter
1905 [ - + + - : 60180 : ABI_CALLOC(aa,(niter_max))
+ - + - -
+ - + +
+ ]
1906 [ - + + - : 60120 : ABI_CALLOC(bb,(niter_max))
- + - + +
+ ]
1907 [ - + + - : 60120 : ABI_CALLOC(cc,(niter_max))
- + - + +
+ ]
1908 : :
1909 : : if (niter_file==0) then ! Calculation from scratch.
1910 [ + - - + : 5880 : phi_nm1 = ket0(my_t1:my_t2)
- - + + ]
1911 [ + - - + : 5880 : phit_nm1 = ket0(my_t1:my_t2)
- - + + ]
1912 : 60 : norm = DZNRM2(hexc%hsize,ket0,1)
1913 [ + + ]: 5820 : phi_nm1=phi_nm1/norm
1914 [ + + ]: 5820 : phit_nm1=phit_nm1/norm
1915 : :
1916 : 60 : call hexc%matmul_elphon(phi_nm1,hphi_n,'N',ep_renorms)
1917 : 60 : call hexc%matmul_elphon(phit_nm1,hphit_n,'C',ep_renorms)
1918 : :
1919 : 60 : aa(1)=xdotc(my_nt,phit_nm1,1,hphi_n(my_t1:),1)
1920 : 60 : call xmpi_sum(aa(1:1),comm,ierr)
1921 : :
1922 [ + - - + : 5880 : phi_n = hphi_n(my_t1:my_t2) - aa(1)*phi_nm1
- - + + ]
1923 [ + - - + : 5880 : phit_n = hphit_n(my_t1:my_t2) - CONJG(aa(1))*phit_nm1
- - + + ]
1924 : :
1925 : 60 : bb(1)=xdotc(my_nt,phi_n,1,phi_n,1)
1926 : 60 : call xmpi_sum(bb(1:1),comm,ierr)
1927 : 60 : bb(1) = SQRT(bb(1))
1928 : :
1929 : 60 : cc(1)=xdotc(my_nt,phit_n,1,phi_n,1)
1930 : 60 : call xmpi_sum(cc(1:1),comm,ierr)
1931 : 60 : cc(1) = cc(1)/bb(1)
1932 : :
1933 [ + + ]: 5820 : phi_n = phi_n /bb(1)
1934 [ + + ]: 5820 : phit_n = phit_n /CONJG(cc(1))
1935 : 60 : niter_done=1 ! TODO Be careful here
1936 : :
1937 : : else ! Use the previously calculates a and b.
1938 : : niter_done=niter_file
1939 : : ABI_ERROR("Restart not coded")
1940 : : !aa(1:niter_done) = aa_file
1941 : : !bb(1:niter_done) = bb_file
1942 : : !phi_np1=phi_np1_file(my_t1:my_t2) ! Select the slice treated by this node.
1943 : : !phi_n =phi_n_file (my_t1:my_t2)
1944 : : end if
1945 : :
1946 [ - + ]: 60 : if (can_restart) then
1947 : 0 : ABI_FREE(aa_file)
1948 : : ABI_FREE(bb_file)
1949 : : ABI_FREE(cc_file)
1950 : : ABI_FREE(phi_np1_file)
1951 : : ABI_FREE(phi_n_file)
1952 : : end if
1953 : :
1954 : : ! This factor gives the correct results
1955 : 60 : factor = -nfact*(DZNRM2(hexc%hsize,ket0,1)**2)
1956 : :
1957 : : ! Which quantity should be checked for convergence?
1958 : 60 : check = (/.TRUE.,.TRUE./)
1959 [ - + ]: 60 : if (ABS(Bsp%haydock_tol(2)-one)<tol6) check = (/.TRUE. ,.FALSE./)
1960 [ - + ]: 60 : if (ABS(Bsp%haydock_tol(2)-two)<tol6) check = (/.FALSE.,.TRUE./)
1961 : : ! Create new frequencies "mirror" in negative range to add
1962 : : ! their contributions. Can be improved by computing only once
1963 : : ! zero frequency, but loosing clearness
1964 : 60 : n_all_omegas = 2*BSp%nomega
1965 : :
1966 [ - + + - : 180 : ABI_MALLOC(all_omegas,(n_all_omegas))
+ - + - -
+ - + ]
1967 : : ! Put all omegas with frequency > 0 in table
1968 [ + + ]: 60120 : all_omegas(BSp%nomega+1:n_all_omegas) = BSp%omega
1969 : : ! Put all omegas with frequency < 0
1970 : : ! Warning, the broadening must be kept positive
1971 [ + + ]: 60120 : all_omegas(1:BSp%nomega) = -DBLE(BSp%omega(BSp%nomega:1:-1)) + j_dpc*AIMAG(BSp%omega(BSp%nomega:1:-1))
1972 : :
1973 [ - + + - : 240 : ABI_MALLOC(green_temp,(n_all_omegas,nkets))
- + + - +
- + - - +
- + ]
1974 : :
1975 : : call haydock_bilanczos_optalgo(niter_done,niter_max,n_all_omegas,all_omegas,BSp%haydock_tol(1),check,hexc,hexc_i,&
1976 : : hsize,my_t1,my_t2,factor,term_type,ep_renorms,aa,bb,cc,ket0,ket0_hbar_norm,phi_nm1,phi_n,phi_np1,&
1977 : 60 : phit_nm1,phit_n,phit_np1,green_temp(:,iq),inn,is_converged,comm)
1978 : :
1979 : : ! Computing result from two ranges of frequencies
1980 : : ! The real part is added, the imaginary part is substracted
1981 [ + + ]: 60120 : green(:,iq) = green_temp(BSp%nomega+1:n_all_omegas,iq)+CONJG(green_temp(BSp%nomega:1:-1,iq))
1982 : :
1983 [ - + ]: 60 : ABI_FREE(all_omegas)
1984 [ - + ]: 60 : ABI_FREE(green_temp)
1985 : :
1986 : : ! Save the a"s and the b"s for possible restarting.
1987 : : ! 1) Info on the Q.
1988 : : ! 2) Number of iterations performed.
1989 : : ! 3) do iter=1,niter_performed
1990 : : ! aa(iter),bb(iter)
1991 : : ! end do
1992 : : ! 4) |n-1>
1993 : : ! |n>
1994 : : ! |n+1>
1995 : : !
1996 [ + - ]: 60 : if (my_rank==master) then ! Open the file and writes basic dimensions and info.
1997 : 60 : write(out_unt)Bsp%q(:,iq)
1998 : 60 : write(out_unt)MIN(inn,niter_max) ! NB: if the previous loop completed inn=niter_max+1
1999 [ + + ]: 3276 : do itt=1,MIN(inn,niter_max) ! if we exited then inn is not incremented by one.
2000 : 3276 : write(out_unt)itt,aa(itt),bb(itt)
2001 : : end do
2002 : : end if
2003 : : !
2004 : : ! cbuff is used as workspace to gather |n-1>, |n> and |n+1>.
2005 [ - + + - : 180 : ABI_MALLOC(cbuff,(hsize))
+ - + - -
+ - + -
+ ]
2006 [ + + + + ]: 11580 : cbuff=czero; cbuff(my_t1:my_t2) = phi_nm1
2007 : 60 : call xmpi_sum_master(cbuff,master,comm,ierr)
2008 [ + - ]: 60 : if (my_rank==master) write(out_unt) cbuff ! |n-1>
2009 : :
2010 [ + + + + ]: 11580 : cbuff=czero; cbuff(my_t1:my_t2) = phi_n
2011 : 60 : call xmpi_sum_master(cbuff,master,comm,ierr)
2012 [ + - ]: 60 : if (my_rank==master) write(out_unt) cbuff ! |n>
2013 : :
2014 [ + + + + ]: 11580 : cbuff=czero; cbuff(my_t1:my_t2) = phi_np1
2015 : 60 : call xmpi_sum_master(cbuff,master,comm,ierr)
2016 [ + - ]: 60 : if (my_rank==master) write(out_unt) cbuff ! |n+1>
2017 : :
2018 [ - + ]: 60 : ABI_FREE(phi_nm1)
2019 [ - + ]: 60 : ABI_FREE(phi_n)
2020 [ - + ]: 60 : ABI_FREE(phi_np1)
2021 [ - + ]: 60 : ABI_FREE(phit_nm1)
2022 [ - + ]: 60 : ABI_FREE(phit_n)
2023 [ - + ]: 60 : ABI_FREE(phit_np1)
2024 [ - + ]: 60 : ABI_FREE(hphi_n)
2025 [ - + ]: 60 : ABI_FREE(hphit_n)
2026 [ - + ]: 60 : ABI_FREE(cbuff)
2027 : 60 : ABI_FREE(aa)
2028 : 60 : ABI_FREE(bb)
2029 : 60 : ABI_FREE(cc)
2030 [ - + ]: 70 : ABI_FREE(ket0)
2031 : : end do ! iq
2032 : :
2033 [ + - ]: 10 : if (my_rank==master) close(out_unt)
2034 : 10 : call xmpi_barrier(comm)
2035 : :
2036 [ - + ]: 10 : end subroutine haydock_bilanczos
2037 : : !!***
2038 : :
2039 : : !----------------------------------------------------------------------
2040 : :
2041 : : !!****f* m_haydock/haydock_bilanczos_optalgo
2042 : : !! NAME
2043 : : !! haydock_bilanczos_optalgo
2044 : : !!
2045 : : !! FUNCTION
2046 : : !! Haydock algorithm for general matrix
2047 : : !!
2048 : : !! INPUTS
2049 : : !! niter_done=Number of iterations already performed (0 if the run starts from scratch).
2050 : : !! niter_tot=Max number of iterations. Always > niter_done
2051 : : !! nomega=Number of Frequency points for the evaluation of the matrix element.
2052 : : !! omega(nomega)=Frequency set (imaginary part is already included).
2053 : : !! tol_iter=Tollerance used to stop the the algorithm.
2054 : : !! check(2)=Logical flags to specify where both the real and the imaginary part of the
2055 : : !! matrix elements of the Green functions have to be checked for convergence.
2056 : : !! hsize=Size of the blocks.
2057 : : !! my_t1,my_t2=Indeces of the first and last column stored treated by this done.
2058 : : !! term_type=0 if no terminator is used, 1 otherwise.
2059 : : !! hreso(hsize,my_t1:my_t2)=The columns of the resonant block.
2060 : : !! hcoup(hsize,my_t1:my_t2)=The columns of the coupling block.
2061 : : !! factor
2062 : : !! comm=MPI communicator.
2063 : : !!
2064 : : !! OUTPUT
2065 : : !! green(nomega)=Output matrix elements.
2066 : : !! inn=Last iteration performed.
2067 : : !! is_converged=.TRUE. of the algorithm converged.
2068 : : !!
2069 : : !! SIDE EFFECTS
2070 : : !! phi_nm1(my_t2-my_t1+1), phi_n(my_t2-my_t1+1)
2071 : : !! input: vectors used to initialize the iteration
2072 : : !! output: the vectors obtained in the last iteration
2073 : : !! aa(niter_tot) and bb(niter_tot+1)
2074 : : !! if niter_done>0: aa(1:niter_done), bb(1:niter_done) store the coefficients of the previous run.
2075 : : !! when the routine returns aa(1:inn) and bb(1:inn) contain the matrix elements of the tridiagonal form.
2076 : : !! cc(niter_tot+1)
2077 : : !!
2078 : : !! SOURCE
2079 : :
2080 : 60 : subroutine haydock_bilanczos_optalgo(niter_done,niter_tot,nomega,omega,tol_iter,check,hexc,hexc_i,hsize,my_t1,my_t2,&
2081 : 60 : & factor,term_type,ep_renorms,aa,bb,cc,ket0,ket0_hbar_norm,phi_nm1,phi_n,phi_np1,phit_nm1,phit_n,phit_np1,&
2082 : 60 : & green,inn,is_converged,comm)
2083 : :
2084 : : !Arguments ------------------------------------
2085 : : !scalars
2086 : : integer,intent(in) :: niter_tot,niter_done,nomega,comm,hsize,my_t1,my_t2,term_type
2087 : : integer,intent(out) :: inn
2088 : : logical,intent(out) :: is_converged
2089 : : real(dp),intent(in) :: tol_iter,ket0_hbar_norm
2090 : : complex(dp),intent(in) :: factor
2091 : : type(hexc_t),intent(in) :: hexc
2092 : : type(hexc_interp_t),intent(in) :: hexc_i
2093 : : !arrays
2094 : : complex(dp),intent(inout) :: bb(niter_tot+1)
2095 : : complex(dp),intent(out) :: green(nomega)
2096 : : complex(dp),intent(in) :: omega(nomega)
2097 : : complex(dp),intent(inout) :: aa(niter_tot),cc(niter_tot+1)
2098 : : complex(dp),intent(in) :: ket0(my_t2-my_t1+1)
2099 : : complex(dp),intent(in) :: ep_renorms(hsize)
2100 : : complex(dp),intent(inout) :: phi_nm1(my_t2-my_t1+1)
2101 : : complex(dp),intent(inout) :: phi_n (my_t2-my_t1+1)
2102 : : complex(dp),intent(inout) :: phi_np1(my_t2-my_t1+1)
2103 : : complex(dp),intent(inout) :: phit_nm1(my_t2-my_t1+1)
2104 : : complex(dp),intent(inout) :: phit_n (my_t2-my_t1+1)
2105 : : complex(dp),intent(inout) :: phit_np1(my_t2-my_t1+1)
2106 : : logical,intent(in) :: check(2)
2107 : :
2108 : : !Local variables ------------------------------
2109 : : !scalars
2110 : : integer :: my_nt,niter_min,nconv !,ierr
2111 : : character(len=500) :: msg
2112 : : logical :: keep_vectors=.TRUE.
2113 : : !arrays
2114 : : integer :: units(2)
2115 : 120 : real(dp) :: abs_err(nomega,2) !,ww_err(nomega,2)
2116 : 60 : complex(dp),allocatable :: oldg(:),newg(:)
2117 : 60 : complex(dp),allocatable :: hphi_np1(:),hphit_np1(:),save_phi(:,:),save_phit(:,:)
2118 : 60 : complex(dp),allocatable :: g00(:)
2119 : : logical :: test(2)
2120 : : integer :: ierr
2121 : : !************************************************************************
2122 : :
2123 : : ABI_UNUSED(ket0_hbar_norm)
2124 : : ABI_UNUSED(ket0(1))
2125 : : ABI_UNUSED(hexc_i%hsize_dense)
2126 [ + + ]: 180 : units = [std_out, ab_out]
2127 : :
2128 : 60 : my_nt = my_t2-my_t1+1
2129 : :
2130 [ - + + - : 180 : ABI_MALLOC(oldg,(nomega))
+ - + - -
+ - + ]
2131 [ - + + - : 120 : ABI_MALLOC(newg,(nomega))
- + - + ]
2132 [ - + + - : 120 : ABI_MALLOC(g00,(nomega))
- + - + ]
2133 [ + + + + : 360420 : oldg=czero; newg=czero; g00=czero
+ + ]
2134 : 60 : nconv=0
2135 : :
2136 [ + - - + ]: 60 : keep_vectors = (keep_vectors.and.xmpi_comm_size(comm)==1)
2137 [ + - ]: 60 : if (keep_vectors) then
2138 [ + - - + : 300 : ABI_MALLOC(save_phi,(my_t2-my_t1+1,niter_tot))
+ - - + +
- + - + -
- + - + ]
2139 [ - + + - : 180 : ABI_MALLOC_OR_DIE(save_phit,(my_t2-my_t1+1,niter_tot),ierr)
- + + - +
- - + -
+ ]
2140 [ + + + + ]: 5820060 : save_phi=czero
2141 [ + + + + ]: 5820060 : save_phit=czero
2142 : : end if
2143 : :
2144 [ - + + - : 180 : ABI_MALLOC_OR_DIE(hphi_np1,(hexc%hsize),ierr)
+ - + - +
- - + -
+ ]
2145 [ - + + - : 180 : ABI_MALLOC_OR_DIE(hphit_np1,(hexc%hsize),ierr)
+ - + - +
- - + -
+ ]
2146 : :
2147 [ + - ]: 3156 : do inn=niter_done+1,niter_tot
2148 : :
2149 : : !|n+1> = H |n> using all eh components.
2150 : 3156 : call hexc%matmul_elphon(phi_n, hphi_np1, 'N', ep_renorms)
2151 : 3156 : call hexc%matmul_elphon(phit_n, hphit_np1, 'C', ep_renorms)
2152 : :
2153 : : ! a(n) = < phit_n | H | phi_n >
2154 : 3156 : aa(inn)=xdotc(my_nt,phit_n,1,hphi_np1(my_t1:),1)
2155 : 3156 : call xmpi_sum(aa(inn),comm,ierr)
2156 : :
2157 : : ! |n+1> = |n+1> - a(n)|Vn> - c(n)|n-1>
2158 [ + + ]: 306132 : phi_np1 = hphi_np1(my_t1:my_t2) - aa(inn)*phi_n - cc(inn-1)*phi_nm1
2159 [ + + ]: 306132 : phit_np1 = hphit_np1(my_t1:my_t2) - CONJG(aa(inn))*phit_n - CONJG(bb(inn-1))*phit_nm1
2160 : :
2161 : 3156 : bb(inn) = xdotc(my_nt,phi_np1,1,phi_np1,1)
2162 : 3156 : call xmpi_sum(bb(inn),comm,ierr)
2163 : 3156 : bb(inn) = SQRT(bb(inn))
2164 : :
2165 : 3156 : cc(inn) = xdotc(my_nt,phit_np1,1,phi_np1,1)
2166 : 3156 : call xmpi_sum(cc(inn),comm,ierr)
2167 : 3156 : cc(inn) = cc(inn)/bb(inn)
2168 : :
2169 [ + + ]: 306132 : phi_np1 = phi_np1 / bb(inn)
2170 [ + + ]: 306132 : phit_np1 = phit_np1 / CONJG(cc(inn))
2171 : :
2172 : : ! |n-1> = |n>
2173 : : ! |n> = |n+1>
2174 [ + + ]: 306132 : phi_nm1 = phi_n
2175 [ + + ]: 306132 : phi_n = phi_np1
2176 [ + + ]: 306132 : phit_nm1 = phit_n
2177 [ + + ]: 306132 : phit_n = phit_np1
2178 : :
2179 [ + - ]: 3156 : if (keep_vectors) then
2180 [ + + ]: 306132 : save_phi(:,inn) = phi_n
2181 [ + + ]: 306132 : save_phit(:,inn) = phit_n
2182 : : end if
2183 : 3156 : write(msg,'(a,i0,a,3es12.4)')' Iteration number ',inn,', b_i RE(c_i) IM(c_i) ',REAL(bb(inn)),REAL(cc(inn)),AIMAG(cc(inn))
2184 : 3156 : call wrtout(std_out,msg)
2185 : :
2186 : 3156 : call continued_fract_general(inn,term_type,aa,bb,cc,nomega,omega,g00)
2187 [ - + + + ]: 6324624 : newg = factor*g00
2188 : : !
2189 : : ! Avoid spurious convergence.
2190 [ - + ]: 3156 : niter_min=4; if (niter_done>1) niter_min=niter_done+1
2191 [ + + ]: 3156 : if (inn>niter_min) then
2192 [ + + ]: 8928 : test=.TRUE.
2193 [ + + ]: 5960928 : abs_err(:,1) = ABS(DBLE (newg-oldg))
2194 [ + + ]: 5960928 : abs_err(:,2) = ABS(AIMAG(newg-oldg))
2195 : :
2196 [ - + ]: 2976 : if (tol_iter>zero) then
2197 : : ! Test on the L1 norm.
2198 [ # # # # : 0 : if (check(1)) test(1) = SUM(abs_err(:,1)) < tol_iter*SUM(ABS(DBLE (newg)))
# # ]
2199 [ # # # # : 0 : if (check(2)) test(2) = SUM(abs_err(:,2)) < tol_iter*SUM(ABS(AIMAG(newg)))
# # ]
2200 : : else
2201 : : ! Stringent test for each point.
2202 [ + - + + : 4133190 : if (check(1)) test(1) = ALL( abs_err(:,1) < -tol_iter*ABS(DBLE (newg)))
+ + ]
2203 [ + - + + : 4102776 : if (check(2)) test(2) = ALL( abs_err(:,2) < -tol_iter*ABS(AIMAG(newg)))
+ + ]
2204 : : end if
2205 : : !
2206 [ + + + + : 3469 : if (ALL(test)) then
+ + ]
2207 : 186 : nconv = nconv+1
2208 : : else
2209 : : nconv = 0
2210 : : end if
2211 [ + + ]: 186 : if (nconv==2) then
2212 [ + - ]: 60 : if(inn<100)then
2213 : : write(msg,'(a,es10.2,a)')&
2214 : 60 : " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after less than 100 iterations."
2215 : : else
2216 : : write(msg,'(a,es10.2,a,i0,a)')&
2217 : 0 : " >>> Haydock algorithm converged twice within haydock_tol= ",tol_iter," after ",inn," iterations."
2218 : : endif
2219 : 60 : call wrtout(units, msg)
2220 : 60 : EXIT
2221 : : end if
2222 : : end if
2223 : : !
2224 [ - + + + ]: 6213852 : oldg = newg
2225 : : end do ! inn
2226 : :
2227 [ + + ]: 120180 : green = newg
2228 [ - + ]: 60 : if (nconv/=2) then
2229 : : write(msg,'(a,es10.2,a,i0,a)')&
2230 : 0 : " WARNING: Haydock algorithm did not converge within ",tol_iter," after ",niter_tot," iterations."
2231 : 0 : call wrtout(units, msg)
2232 : : end if
2233 : :
2234 : 60 : is_converged = (nconv==2)
2235 : :
2236 [ - + ]: 60 : ABI_FREE(oldg)
2237 [ - + ]: 60 : ABI_FREE(newg)
2238 [ - + ]: 60 : ABI_FREE(g00)
2239 [ - + ]: 60 : ABI_FREE(hphi_np1)
2240 [ - + ]: 60 : ABI_FREE(hphit_np1)
2241 : :
2242 [ + - ]: 60 : ABI_SFREE(save_phi)
2243 [ + - ]: 60 : ABI_SFREE(save_phit)
2244 : :
2245 : : !! if (keep_vectors) then
2246 : : !! tdim = MIN(inn,niter_tot)
2247 : : !! ABI_MALLOC(ovlp,(tdim,tdim))
2248 : :
2249 : : !! ABI_MALLOC(phi_test,(hsize))
2250 : : !! ABI_MALLOC(phi_test2,(hsize))
2251 : :
2252 : : !! max_err=smallest_real; mean_err=zero; mean_err2=zero; row_max=-1
2253 : : !! do ii=1,tdim
2254 : : !! parity = (-1)**(ii+1)
2255 : : !! phi_test = save_phi(:,ii)
2256 : : !! call hexc%matmul_full(hexc_i, phi_test, phi_test2, parity)
2257 : : !! !phi_test2 = MATMUL(hreso,phi_test) + parity * MATMUL(hcoup,CONJG(phi_test))
2258 : : !! ovlp(ii,ii) = DOT_PRODUCT(phi_test,phi_test2) + DOT_PRODUCT(phi_test2,phi_test)
2259 : : !! err = ABS(ovlp(ii,ii)-cone)
2260 : : !! mean_err = mean_err + err
2261 : : !! mean_err2 = mean_err2 + err**2
2262 : : !! if (err > max_err) then
2263 : : !! max_err = err
2264 : : !! row_max = ii
2265 : : !! end if
2266 : : !! end do
2267 : : !! mean_err = mean_err/tdim
2268 : : !! std_dev = mean_err2/tdim -mean_err**2
2269 : : !! write(std_out,'(a,i0,1x,3es14.6)')&
2270 : : !!& " Error in normalization (ii, max_err,mean,std_dev): ",row_max,max_err,mean_err,std_dev
2271 : :
2272 : : !! ABI_FREE(phi_test)
2273 : : !! ABI_FREE(phi_test2)
2274 : : !!
2275 : : !! ABI_MALLOC(alpha,(hsize,tdim))
2276 : :
2277 : : !! ! Less efficient but for sake of simplicity with hexc_matmul
2278 : : !! ! TODO possibility to call hreso * phi, and hcoup * phi separately
2279 : : !! do ii=1,tdim
2280 : : !! parity = (-1)**(ii+1)
2281 : : !! call hexc%matmul_full(hexc_i, save_phi(:,ii), alpha(:,ii), parity)
2282 : : !! end do
2283 : :
2284 : : !! !alpha = MATMUL(hreso,save_phi(:,1:tdim))
2285 : : !! !
2286 : : !! !do ii=1,tdim
2287 : : !! ! parity = (-1)**(ii+1)
2288 : : !! ! alpha(:,ii) = alpha(:,ii) + parity*MATMUL(hcoup,CONJG(save_phi(:,ii)))
2289 : : !! !end do
2290 : :
2291 : : !! ovlp = MATMUL(TRANSPOSE(CONJG(save_phi(:,1:tdim))),alpha)
2292 : :
2293 : : !! ABI_MALLOC(beta,(hsize,tdim))
2294 : : !! do ii=1,tdim
2295 : : !! parity = (-1)**(ii+1)
2296 : : !! beta(:,ii) = parity*save_phi(:,ii)
2297 : : !! alpha(:,ii) = -parity*alpha(:,ii)
2298 : : !! end do
2299 : :
2300 : : !! ovlp = ovlp - MATMUL(TRANSPOSE(CONJG(beta)),alpha)
2301 : :
2302 : : !! max_err=smallest_real; row_max=-1; col_max=-1
2303 : : !! mean_err=zero; mean_err2=zero
2304 : : !! do jj=1,tdim
2305 : : !! do ii=1,jj
2306 : : !! err = ABS(ovlp(ii,jj))
2307 : : !! if (ii==jj) err = ABS(err - one)
2308 : : !! mean_err = mean_err + err
2309 : : !! mean_err2 = mean_err2 + err**2
2310 : : !! if (err > max_err) then
2311 : : !! max_err = err
2312 : : !! row_max=ii
2313 : : !! col_max=jj
2314 : : !! end if
2315 : : !! end do
2316 : : !! end do
2317 : :
2318 : : !! mean_err = mean_err/(tdim*(tdim+1)/2)
2319 : : !! std_dev = mean_err2/(tdim*(tdim+1)/2) - mean_err**2
2320 : : !! write(std_out,'(a,2(i0,1x),3es14.6)')&
2321 : : !! " Error in Hbar-ortho (i,j), max_err, mean, std_dev ",row_max,col_max,max_err,mean_err,std_dev
2322 : : !! !call print_arr(ovlp,max_r=185,max_c=10,unit=std_out)
2323 : :
2324 : : !! ABI_FREE(alpha)
2325 : : !! ABI_FREE(beta)
2326 : : !! ABI_FREE(ovlp)
2327 : : !! ABI_FREE(save_phi)
2328 : : !! end if
2329 : :
2330 : 60 : end subroutine haydock_bilanczos_optalgo
2331 : : !!***
2332 : :
2333 : :
2334 : : !----------------------------------------------------------------------
2335 : :
2336 : : !!****f* m_numeric_tools/continued_fract_general
2337 : : !! NAME
2338 : : !! continued_fract
2339 : : !!
2340 : : !! FUNCTION
2341 : : !! This routine calculates the continued fraction:
2342 : : !!
2343 : : !! 1
2344 : : !! f(z) = _______________________________
2345 : : !! z - a1 - b1^2
2346 : : !! _____________________
2347 : : !! z - a2 - b2^2
2348 : : !! ___________
2349 : : !! z -a3 - ........
2350 : : !!
2351 : : !! INPUTS
2352 : : !! nlev=Number of "levels" in the continued fraction.
2353 : : !! term_type=Type of the terminator.
2354 : : !! 0 --> No terminator.
2355 : : !! -1 --> Assume constant coefficients for a_i and b_i for i>nlev with a_inf = a(nlev) and b_inf = b(nleb)
2356 : : !! 1 --> Same as above but a_inf and b_inf are obtained by averaging over the nlev values.
2357 : : !! aa(nlev)=Set of a_i coefficients.
2358 : : !! bb(nlev)=Set of b_i coefficients.
2359 : : !! nz=Number of points on the z-mesh.
2360 : : !! zpts(nz)=z-mesh.
2361 : : !!
2362 : : !! OUTPUT
2363 : : !! spectrum(nz)=Contains f(z) on the input mesh.
2364 : : !!
2365 : : !! SOURCE
2366 : :
2367 : 3156 : subroutine continued_fract_general(nlev,term_type,aa,bb,cc,nz,zpts,spectrum)
2368 : :
2369 : : !Arguments ------------------------------------
2370 : : !scalars
2371 : : integer,intent(in) :: nlev,term_type,nz
2372 : : !arrays
2373 : : complex(dp),intent(in) :: bb(nlev)
2374 : : complex(dp),intent(in) :: cc(nlev)
2375 : : complex(dp),intent(in) :: aa(nlev)
2376 : : complex(dp),intent(in) :: zpts(nz)
2377 : : complex(dp),intent(out) :: spectrum(nz)
2378 : :
2379 : : !Local variables ------------------------------
2380 : : !scalars
2381 : : integer :: it
2382 : : complex(dp) :: bb_inf,bg,bu,swap, aa_inf
2383 : : character(len=500) :: msg
2384 : : !arrays
2385 : 3156 : complex(dp),allocatable :: div(:),den(:)
2386 : : !************************************************************************
2387 : :
2388 [ - + + - : 9468 : ABI_MALLOC(div,(nz))
+ - + - -
+ - + ]
2389 [ - + + - : 6312 : ABI_MALLOC(den,(nz))
- + - + ]
2390 : :
2391 : 3156 : select case (term_type)
2392 : : case (0) ! No terminator.
2393 [ + + ]: 6321468 : div=czero
2394 : : case (-1,1)
2395 : 0 : ABI_ERROR("Not yet implemented")
2396 [ # # ]: 0 : if (term_type==-1) then
2397 : 0 : bb_inf=bb(nlev)
2398 : 0 : aa_inf=aa(nlev)
2399 : : else
2400 [ # # ]: 0 : bb_inf=SUM(bb)/nlev
2401 [ # # ]: 0 : aa_inf=SUM(aa)/nlev
2402 : : end if
2403 : : ! Be careful with the sign of the SQRT.
2404 [ # # ]: 0 : div(:) = half*(bb(nlev)/(bb_inf))**2 * ( zpts-aa_inf - SQRT((zpts-aa_inf)**2 - four*bb_inf**2) )
2405 : : case (2)
2406 : 0 : ABI_ERROR("Not yet implemented")
2407 [ # # ]: 0 : div = zero
2408 [ # # ]: 0 : if (nlev>4) then
2409 : 0 : bg=zero; bu=zero
2410 [ # # ]: 0 : do it=1,nlev,2
2411 [ # # ]: 0 : if (it+2<nlev) bg = bg + bb(it+2)
2412 [ # # ]: 0 : bu = bu + bb(it)
2413 : : end do
2414 : 0 : bg = bg/(nlev/2+MOD(nlev,2))
2415 : 0 : bu = bg/((nlev+1)/2)
2416 : : !if (iseven(nlev)) then
2417 [ # # ]: 0 : if (.not.iseven(nlev)) then
2418 : 0 : swap = bg
2419 : 0 : bg = bu
2420 : 0 : bu = bg
2421 : : end if
2422 : : !write(std_out,*)nlev,bg,bu
2423 : : !Here be careful with the sign of SQRT
2424 [ # # ]: 0 : do it=1,nz
2425 : : div(it) = half/zpts(it) * (bb(nlev)/bu)**2 * &
2426 : 0 : ( (zpts(it)**2 +bu**2 -bg**2) - SQRT( (zpts(it)**2+bu**2-bg**2)**2 -four*(zpts(it)*bu)**2) )
2427 : : end do
2428 : : end if
2429 : :
2430 : : case default
2431 : 0 : write(msg,'(a,i0)')" Wrong value for term_type: ",term_type
2432 [ + - - - ]: 3156 : ABI_ERROR(msg)
2433 : : end select
2434 : :
2435 [ + + ]: 89458 : do it=nlev,2,-1
2436 [ + + ]: 172862906 : den(:) = zpts(:) - aa(it) - div(:)
2437 [ + + ]: 172866062 : div(:) = (bb(it-1)*cc(it-1) )/ den(:)
2438 : : end do
2439 : :
2440 [ - + + + ]: 6324624 : den = zpts(:) - aa(1) - div(:)
2441 [ - + + + ]: 6324624 : div = one/den(:)
2442 : :
2443 [ + + ]: 6321468 : spectrum = div
2444 [ - + ]: 3156 : ABI_FREE(div)
2445 [ - + ]: 3156 : ABI_FREE(den)
2446 : :
2447 : 3156 : end subroutine continued_fract_general
2448 : : !!***
2449 : :
2450 : : !----------------------------------------------------------------------
2451 : :
2452 [ # # ]: 0 : end module m_haydock
2453 : : !!***
|