Line data Source code
1 : !!****m* ABINIT/m_rmm_diis
2 : !! NAME
3 : !! m_rmm_diis
4 : !!
5 : !! FUNCTION
6 : !! This module contains routines for the RMM-DIIS eigenvalue solver.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2020-2026 ABINIT group (MG)
10 : !! This file is distributed under the terms of the
11 : !! GNU General Public License, see ~abinit/COPYING
12 : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : !!
14 : !! SOURCE
15 :
16 : #if defined HAVE_CONFIG_H
17 : #include "config.h"
18 : #endif
19 :
20 : #include "abi_common.h"
21 :
22 : module m_rmm_diis
23 :
24 : use defs_basis
25 : use m_errors
26 : use m_xmpi
27 : use m_abicore
28 : use m_dtset
29 : use m_cgtools
30 : use m_hide_blas
31 : use m_yaml
32 : use m_linalg_interfaces
33 : use m_prep_kgb
34 :
35 : use defs_abitypes, only : mpi_type
36 : use m_fstrings, only : sjoin, itoa, ftoa
37 : use m_time, only : timab, cwtime, cwtime_report
38 : use m_numeric_tools, only : pack_matrix, imin_loc, stats_t, stats_eval
39 : use m_hide_lapack, only : xhegv_cplex, xhesv_cplex
40 : use m_pair_list, only : pair_list
41 : use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_free
42 : use m_fftcore, only : fftcore_set_mixprec
43 : use m_hamiltonian, only : gs_hamiltonian_type
44 : use m_getghc, only : getghc
45 : use m_nonlop, only : nonlop
46 : use m_cgtk, only : cgtk_fixphase
47 : use m_abi_linalg, only : abi_zgemm_2r
48 : !use m_fock, only : fock_set_ieigen, fock_set_getghc_call
49 :
50 : implicit none
51 :
52 : private
53 : !!***
54 :
55 : public :: rmm_diis
56 : public :: subspace_rotation ! rayleigh-ritz procedure from gs_hamk
57 : !!***
58 :
59 : type,private :: rmm_diis_t
60 :
61 : integer :: accuracy_level
62 : ! Defines tolerances, activates/deactivates tricks.
63 :
64 : integer :: usepaw
65 : ! 1 if we are running PAW.
66 :
67 : integer :: istwf_k
68 : ! wavefunction storage mode.
69 :
70 : integer :: cplex
71 : ! 1 if matrices are real (e.g. Gamma-point), 2 for complex
72 :
73 : integer :: bsize
74 : ! (Max) block size for bands
75 :
76 : integer :: max_niter
77 : ! Maximum number of iterations
78 :
79 : integer :: npwsp
80 : ! Total number of planewaves treated by this proc
81 : ! npw * my_nspinor
82 :
83 : integer :: prtvol
84 : ! vervosity level
85 :
86 : integer :: last_iter
87 : ! Last RMM-DIIS iteration performed.
88 :
89 : real(dp) :: tol_occupied
90 : ! Tolerance for partial occupied states
91 :
92 : type(pair_list) :: stats
93 :
94 : real(dp),allocatable :: hist_ene(:,:)
95 : real(dp),allocatable :: hist_resid(:,:)
96 : real(dp),allocatable :: hist_enlx(:,:)
97 : character(len=7),allocatable :: step_type(:,:)
98 : ! (0:max_niter+2, bsize)
99 : ! 0 is the initial step, then DIIS iterations whose number may depend on the block
100 : ! followed by the computation of eigens after ortho.
101 :
102 : real(dp),allocatable :: resmat(:,:,:,:)
103 : ! (2, 0:max_niter, 0:max_niter, bsize))
104 :
105 : real(dp),allocatable :: chain_phi(:,:,:,:)
106 : real(dp),allocatable :: chain_sphi(:,:,:,:)
107 : real(dp),allocatable :: chain_resv(:,:,:,:)
108 : ! (2, npwsp, 0:max_niter, bsize))
109 :
110 : contains
111 : procedure :: free => rmm_diis_free ! Free dynamic memory
112 : procedure :: update_block => rmm_diis_update_block ! DIIS uppdate of wavefuntions and residuals.
113 : procedure :: eval_mats => rmm_diis_eval_mats ! Compute DIIS matrices
114 : procedure :: exit_iter => rmm_diis_exit_iter ! Return True if can exit the DIIS iteration.
115 : procedure :: print_block => rmm_diis_print_block ! Print energies, residuals and diffs for a given block.
116 : ! TODO: Fix problem with last_iter and hist
117 : procedure :: push_iter => rmm_diis_push_iter ! Save results required by the DIIS algorithm
118 :
119 : end type rmm_diis_t
120 :
121 : integer,parameter, private :: level = 432
122 : logical,parameter, private :: timeit = .False.
123 : !logical,parameter, private :: timeit = .True.
124 :
125 : contains
126 : !!***
127 :
128 : !!****f* ABINIT/rmm_diis
129 : !! NAME
130 : !! rmm_diis
131 : !!
132 : !! FUNCTION
133 : !! This routine updates the wave functions at a given (k-point, spin), using the RMM-DIIS method.
134 : !!
135 : !! INPUTS
136 : !! istep,ikpt,isppol=Iteration step, k-point index, spin index (mainly for printing purposes).
137 : !! dtset <type(dataset_type)>=all input variables for this dataset
138 : !! gs_hamk <type(gs_hamiltonian_type)>=all data for the hamiltonian at k
139 : !! kinpw(npw)=(modified) kinetic energy for each plane wave (hartree)
140 : !! mpi_enreg=information about MPI parallelization
141 : !! nband=number of bands at this k point for that spin polarization
142 : !! npw=number of plane waves at this k point
143 : !! my_nspinor=number of spinors treated by this MPI proc
144 : !!
145 : !! OUTPUT
146 : !! eig(nband)=array for holding eigenvalues (hartree)
147 : !! If usepaw==1:
148 : !! gsc(2,*)=<g|s|c> matrix elements (s=overlap)
149 : !! If usepaw==0
150 : !! enlx(nband)=contribution from each band to nonlocal psp + potential Fock ACE part
151 : !! of total energy, at this k-point
152 : !!
153 : !! SIDE EFFECTS
154 : !! cg(2,*)=updated wavefunctions
155 : !! resid(nband)=residuals for each states. In input: previous residuals for this k-point, spin.
156 : !! In output: new residuals.
157 : !! rmm_diis_status(2): Status of the eigensolver.
158 : !! The first entry gives the previous accuracy.
159 : !! The second entry gives the number of iterations already performed with this level.
160 : !!
161 : !! SOURCE
162 :
163 653 : subroutine rmm_diis(istep, ikpt, isppol, cg, dtset, eig, occ, enlx, gs_hamk, kinpw, gsc, &
164 653 : mpi_enreg, nband, npw, my_nspinor, resid, rmm_diis_status)
165 :
166 : !Arguments ------------------------------------
167 : integer,intent(in) :: istep, ikpt, isppol, nband, npw, my_nspinor
168 : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
169 : type(dataset_type),intent(in) :: dtset
170 : type(mpi_type),intent(in) :: mpi_enreg
171 : real(dp),target,intent(inout) :: cg(2,npw*my_nspinor*nband)
172 : real(dp),target,intent(inout) :: gsc(2,npw*my_nspinor*nband*dtset%usepaw)
173 : real(dp),intent(inout) :: enlx(nband), resid(nband)
174 : real(dp),intent(in) :: occ(nband), kinpw(npw)
175 : real(dp),intent(out) :: eig(nband)
176 : integer,intent(inout) :: rmm_diis_status(2)
177 :
178 : !Local variables-------------------------------
179 : integer,parameter :: type_calc0 = 0, option1 = 1, option2 = 2, tim_getghc = 0
180 : integer,parameter :: choice1 = 1, signs1 = 1, signs2 = 2, tim_nonlop = 0, paw_opt0 = 0, paw_opt3 = 3
181 : integer :: ierr, prtvol, bsize, nblocks, iblock, npwsp, ndat, ib_start, ib_stop, idat, paral_kgb !, ortalgo
182 : integer :: cpopt, sij_opt, igs, ige, mcg, mgsc, istwf_k, optekin, usepaw, iter, max_niter, max_niter_block
183 : integer :: me_g0, nb_pocc, jj, kk, accuracy_level, raise_acc, prev_mixprec, after_ortho, me_cell
184 : integer :: comm_bsf, prev_accuracy_level, ncalls_with_prev_accuracy, signs, paw_opt, savemem
185 : logical :: first_call, use_fft_mixprec, has_fock
186 : real(dp),parameter :: rdummy = zero
187 : real(dp) :: accuracy_ene, max_res_pocc, tol_occupied, lock_tolwfr !, max_absimag
188 : real(dp) :: cpu, wall, gflops, cpu_all, wall_all, gflops_all
189 : character(len=500) :: msg
190 : type(yamldoc_t) :: rmm_ydoc
191 653 : type(rmm_diis_t) :: diis
192 : type(stats_t) :: res_stats
193 : !arrays
194 : real(dp) :: tsec(2)
195 : real(dp),target :: fake_gsc_bk(0,0)
196 653 : real(dp),allocatable :: lambda_bk(:), kres_bk(:,:), dots_bk(:,:), residv_bk(:,:)
197 653 : real(dp),allocatable :: umat(:,:,:), gwork(:,:), dots(:, :)
198 653 : real(dp),target,allocatable :: ghc(:,:), gvnlxc(:,:)
199 1306 : real(dp),contiguous, pointer :: gsc_bk(:,:), cg_bk(:,:), ghc_bk(:,:), gvnlxc_bk(:,:)
200 4571 : type(pawcprj_type) :: cprj_dum(1,1)
201 : ! *************************************************************************
202 :
203 : ! Define useful vars.
204 653 : usepaw = dtset%usepaw; istwf_k = gs_hamk%istwf_k; paral_kgb = mpi_enreg%paral_kgb
205 653 : me_g0 = mpi_enreg%me_g0; comm_bsf = mpi_enreg%comm_bandspinorfft
206 653 : npwsp = npw * my_nspinor; mcg = npwsp * nband; mgsc = npwsp * nband * usepaw
207 653 : me_cell = mpi_enreg%me_cell; prtvol = dtset%prtvol !; prtvol = -level
208 653 : has_fock = associated(gs_hamk%fockcommon)
209 :
210 : if (timeit) then
211 : call cwtime(cpu_all, wall_all, gflops_all, "start")
212 : call cwtime(cpu, wall, gflops, "start")
213 : end if
214 :
215 : ! =================
216 : ! Prepare DIIS loop
217 : ! =================
218 : ! accuracy_level is computed from the maxval of the previous residuals received in input.
219 : ! The different levels are:
220 : !
221 : ! 1: Used at the beginning of the SCF cycle. Use loosy convergence criteria in order
222 : ! to reduce the number of H|psi> applications as much as possible so that
223 : ! we can start to mix densities/potentials.
224 : ! Allow for incosistent data in output rediduals and Vnl matrix elements.
225 : ! Move to the next level after Max 15 iterations.
226 : !
227 : ! 2: Intermediate step. Decrease convergence criteria in order to perform more wavefuction iterations.
228 : ! Allow for incosistent data in output rediduals and Vnl matrix elements.
229 : ! Move to the next level after Max 25 iterations.
230 : !
231 : ! 3: Approaching convergence. Use stricter convergence criteria.
232 : ! Move to the next level after Max 25 iterations.
233 : !
234 : ! 4: Ultimate precision. Try to reach the same accuracy as the other eigenvalue solvers.
235 : ! This implies: using similar convergence criteria as in the other solvers.
236 :
237 : ! Note:
238 : !
239 : ! * Accuracy_level is not allowed to increase during the SCF cycle.
240 : !
241 : ! * Since we operate on blocks of bands, all the states in the block will receive the same treatment.
242 : ! This means that one can observe different convergence behaviour depending on bsize.
243 : !
244 917 : if (all(rmm_diis_status == 0)) then
245 : ! This is the first time we call rmm_diis for this (k-point, spin)
246 : prev_accuracy_level = 1; ncalls_with_prev_accuracy = 0
247 : first_call = .True.
248 : else
249 521 : prev_accuracy_level = rmm_diis_status(1); ncalls_with_prev_accuracy = rmm_diis_status(2)
250 521 : first_call = .False.
251 : end if
252 :
253 : ! Decide whether we should move to the next level.
254 653 : raise_acc = 0
255 653 : if (prev_accuracy_level == 1 .and. ncalls_with_prev_accuracy >= 15) raise_acc = 2
256 653 : if (prev_accuracy_level == 2 .and. ncalls_with_prev_accuracy >= 25) raise_acc = 3
257 653 : if (prev_accuracy_level == 3 .and. ncalls_with_prev_accuracy >= 25) raise_acc = 4
258 653 : if (raise_acc > 0) then
259 0 : ABI_COMMENT("Accuracy_level is automatically increased as we reached the max number of NSCF iterations.")
260 : end if
261 653 : raise_acc = max(raise_acc, prev_accuracy_level)
262 :
263 : ! Define tolerance for occupied states on the basis of prev_accuracy_level
264 : ! and compute max of residuals for these bands.
265 653 : tol_occupied = zero
266 653 : if (dtset%iscf > 0) then
267 588 : tol_occupied = tol3; if (any(prev_accuracy_level == [1])) tol_occupied = tol2
268 : end if
269 13141 : nb_pocc = count(occ >= tol_occupied)
270 10498 : max_res_pocc = maxval(resid(1:nb_pocc))
271 :
272 : ! Define accuracy_level for this run.
273 653 : accuracy_level = 1
274 653 : if (max_res_pocc < tol8) accuracy_level = 2
275 522 : if (max_res_pocc < tol12) accuracy_level = 3
276 195 : if (max_res_pocc < tol16) accuracy_level = 4
277 : !if (max_res_pocc < tol18) accuracy_level = 4
278 653 : accuracy_level = max(prev_accuracy_level, accuracy_level, raise_acc)
279 653 : if (istep == 1) accuracy_level = 2 ! FIXME: Differenciate between restart or rmm_diis - 3.
280 653 : if (first_call .and. max_res_pocc == zero) accuracy_level = 1
281 : !print *, "rmm_diis_status:", rmm_diis_status
282 : !print *, "rmm_prev_acc:", prev_accuracy_level, "rmm_raise_acc:", raise_acc
283 : !print *, "accuracy_level:", accuracy_level, "rmm_raise_acc:", raise_acc
284 :
285 : ! Update rmm_diis_status. Reset number of calls if we've just moved to a new accuracy_level.
286 653 : rmm_diis_status(1) = accuracy_level
287 653 : if (accuracy_level /= prev_accuracy_level) rmm_diis_status(2) = 0
288 653 : rmm_diis_status(2) = rmm_diis_status(2) + 1
289 :
290 : ! Will perform max_niter DIIS steps. Usually 3 as nline by default is 4.
291 : ! Note that, unlike in Vasp's recipe, here we don't end with a trial step after DIIS.
292 653 : max_niter = max(dtset%nline - 1, 1)
293 653 : if (accuracy_level >= 4) max_niter = dtset%nline
294 653 : if (dtset%iscf < 0) max_niter = dtset%nline + 1
295 :
296 : ! Define accuracy_ene for SCF.
297 653 : accuracy_ene = zero
298 653 : if (dtset%iscf > 0) then
299 588 : if (dtset%toldfe /= zero) then
300 200 : accuracy_ene = dtset%toldfe * ten**(-accuracy_level + 2) / nb_pocc
301 : else
302 : ! We are not using toldfe to stop the SCF cycle
303 : ! so we are forced to hardcode a tolerance for the absolute diff in the KS eigenvalue.
304 388 : accuracy_ene = tol8 * ten**(-accuracy_level + 2) / nb_pocc
305 : end if
306 : end if
307 :
308 : ! Tolerance on residuals used for band locking after subdiago.
309 653 : if (dtset%tolwfr > zero) then
310 117 : lock_tolwfr = tol2 * dtset%tolwfr
311 : else
312 536 : lock_tolwfr = tol14
313 536 : if (accuracy_level >= 2) lock_tolwfr = tol16
314 536 : if (accuracy_level >= 3) lock_tolwfr = tol18
315 536 : if (accuracy_level >= 4) lock_tolwfr = tol20 * tol2
316 : end if
317 :
318 : ! Use mixed precisions if requested by the user but only for low accuracy_level
319 653 : use_fft_mixprec = dtset%mixprec == 1 .and. accuracy_level < 2
320 0 : if (use_fft_mixprec) prev_mixprec = fftcore_set_mixprec(1)
321 :
322 : ! Select preconditioning.
323 : optekin = 0; if (dtset%wfoptalg >= 10) optekin = 1
324 653 : optekin = 1 ! optekin = 0
325 :
326 : ! Will treat states in groups of bsize bands even when paral_kgb = 0
327 653 : bsize = 8; if (paral_kgb == 1) bsize = mpi_enreg%nproc_band * mpi_enreg%bandpp
328 653 : nblocks = nband / bsize; if (mod(nband, bsize) /= 0) nblocks = nblocks + 1
329 :
330 : ! Build DIIS object.
331 653 : diis = rmm_diis_new(accuracy_level, usepaw, istwf_k, npwsp, max_niter, bsize, prtvol)
332 653 : diis%tol_occupied = tol_occupied
333 : !call wrtout(std_out, sjoin(" Using Max", itoa(max_niter), "RMM-DIIS iterations"))
334 : !call wrtout(std_out, sjoin( &
335 : ! " Max_input_resid_pocc", ftoa(max_res_pocc), "accuracy_level:", itoa(accuracy_level), &
336 : ! ", accuracy_ene: ", ftoa(accuracy_ene)))
337 653 : call timab(1634, 1, tsec) ! "rmm_diis:band_opt"
338 :
339 653 : rmm_ydoc = yamldoc_open("RMM-DIIS", with_iter_state=.False.)
340 3265 : call rmm_ydoc%add_ints("ikpt, isppol, istep, accuracy_level", [ikpt, isppol, istep, accuracy_level])
341 653 : call rmm_ydoc%open_tabular("RESIDS_POCC") !, tag, indent, newline, comment)
342 653 : write(msg, "(1x, a12, 4(a10))")"level", "mean", "min", "max", "stdev"
343 653 : call rmm_ydoc%add_tabular_line(msg, indent=0)
344 653 : call rmm_ydoc%add_tabular_line(resids2str("input"), indent=0)
345 :
346 : ! =========================
347 : ! === Subspace rotation ===
348 : ! =========================
349 : ! Allocate big (scalable) array with <G|H|C> for all nband so that we can recompute the residuals after the rotation.
350 : ! This approach requires more memory but we avoid one extra call to H|Psi> per band.
351 : ! Alternatively, one can compute ghc and the residuals by applying H|psi>
352 : ! inside the loop over blocks (less memory but slower).
353 653 : savemem = dtset%rmm_diis_savemem
354 : !savemem = 1
355 : !if (savemem == 0) then
356 : ! ABI_MALLOC_OR_DIE(ghc, (2, npwsp*nband), ierr)
357 : ! ABI_MALLOC_OR_DIE(gvnlxc, (2, npwsp*nband), ierr)
358 : !end if
359 :
360 : call subspace_rotation(gs_hamk, dtset%prtvol, mpi_enreg, nband, npw, my_nspinor, savemem, &
361 653 : enlx, eig, cg, gsc, ghc, gvnlxc)
362 :
363 653 : gsc_bk => fake_gsc_bk
364 653 : cpopt = -1; sij_opt = 0
365 653 : if (usepaw == 1) then
366 160 : sij_opt = 1 ! matrix elements <G|S|C> have to be computed in gsc in addition to ghc
367 : cpopt = -1 ! <p_lmn|in> (and derivatives) are computed here (and not saved)
368 : end if
369 :
370 1959 : ABI_MALLOC(lambda_bk, (bsize))
371 1959 : ABI_MALLOC(dots_bk, (2, bsize))
372 1959 : ABI_MALLOC(residv_bk, (2, npwsp*bsize))
373 1306 : ABI_MALLOC(kres_bk, (2, npwsp*bsize))
374 :
375 653 : if (savemem == 1) then
376 96 : ABI_MALLOC(ghc_bk, (2, npwsp*bsize))
377 96 : ABI_MALLOC(gvnlxc_bk, (2, npwsp*bsize))
378 : end if
379 : !write(msg, "(a,f8.1,a)")" Memory required: ", 2 * natom3**2 * (my_q2 - my_q1 + 1) * dp * b2Mb, " [Mb] <<< MEM"
380 : !call wrtout(std_out, msg)
381 :
382 : ! We loop over nblocks, each block contains ndat states.
383 : !
384 : ! - Convergence behaviour may depend on bsize as branches are taken according to
385 : ! the status of all bands in the block.
386 : ! TODO: Transpose only once per block and then work with already_transposed = .True.
387 : if (timeit) call cwtime(cpu, wall, gflops, "start")
388 :
389 1546 : do iblock=1,nblocks
390 893 : igs = 1 + (iblock - 1) * npwsp * bsize; ige = min(iblock * npwsp * bsize, npwsp * nband)
391 893 : ndat = (ige - igs + 1) / npwsp
392 893 : ib_start = 1 + (iblock - 1) * bsize; ib_stop = min(iblock * bsize, nband)
393 :
394 : ! Reduce number of niter iterations if block contains "empty" states.
395 : ! This should happen only if npband is small wrt nband and nband >> nbocc.
396 : ! TODO: Don't reduce niter if MD
397 893 : max_niter_block = max_niter
398 893 : if (dtset%iscf > 0) then
399 1884 : if (all(occ(ib_start:ib_stop) < diis%tol_occupied)) max_niter_block = max(1 + max_niter / 2, 2)
400 : end if
401 :
402 : ! Compute H |phi_0> with cg block after subdiago.
403 893 : cg_bk => cg(:,igs:ige); if (usepaw == 1) gsc_bk => gsc(1:2,igs:ige)
404 :
405 : ! Compute residual vectors after subspace_rotation.
406 893 : if (savemem == 0) then
407 845 : ghc_bk => ghc(:,igs:ige); gvnlxc_bk => gvnlxc(:,igs:ige)
408 845 : call cg_get_residvecs(usepaw, npwsp, ndat, eig(ib_start), cg_bk, ghc_bk, gsc_bk, residv_bk)
409 845 : call cg_norm2g(istwf_k, npwsp, ndat, residv_bk, resid(ib_start), me_g0, comm_bsf)
410 : else
411 : call getghc_eigresid(gs_hamk, npw, my_nspinor, ndat, cg_bk, ghc_bk, gsc_bk, mpi_enreg, prtvol, &
412 48 : eig(ib_start), resid(ib_start), enlx(ib_start), residv_bk, gvnlxc_bk, normalize=.False.)
413 : end if
414 :
415 : ! Band locking.
416 1073 : if (all(resid(ib_start:ib_stop) < lock_tolwfr)) then
417 0 : call diis%stats%increment("locked", ndat)
418 0 : cycle ! iblock
419 : end if
420 :
421 : ! Save <R0|R0> and <phi_0|S|phi_0>, |phi_0>, |S phi_0>. Assume input cg_bk is already S-normalized.
422 893 : call diis%push_iter(0, ndat, eig(ib_start), resid(ib_start), enlx(ib_start), cg_bk, residv_bk, gsc_bk, "SDIAG")
423 :
424 : ! Line minimization with preconditioned steepest descent:
425 : !
426 : ! |phi_1> = |phi_0> + lambda |K R_0>
427 : !
428 : ! where lambda minimizes the residual (we don't try to find the stationary
429 : ! point of the Rayleigh quotient as in Kresse's paper).
430 : !
431 : ! lambda = - Re{<R_0|(H - e_0 S)} |K R_0>} / |(H - e_0 S) |K R_0>|**2
432 : !
433 : ! more expensive than finding the stationary point of the Rayleigh quotient as it requires
434 : ! an extra H application but it should be more stable and more consistent with the RMM approach.
435 : !
436 : ! Precondition |R_0>, output in kres_bk = |K R_0>
437 893 : call cg_zcopy(npwsp * ndat, residv_bk, kres_bk)
438 893 : call cg_precon_many(istwf_k, npw, my_nspinor, ndat, cg_bk, optekin, kinpw, kres_bk, me_g0, comm_bsf)
439 :
440 : ! Compute H |K R_0>
441 893 : if (paral_kgb == 0) then
442 : call getghc(cpopt, kres_bk, cprj_dum, ghc_bk, gsc_bk, gs_hamk, gvnlxc_bk, &
443 393 : rdummy, mpi_enreg, ndat, prtvol, sij_opt, tim_getghc, type_calc0)
444 : else
445 : call prep_getghc(kres_bk, gs_hamk, gvnlxc_bk, ghc_bk, gsc_bk, rdummy, ndat, &
446 500 : mpi_enreg, prtvol, sij_opt, cpopt, cprj_dum, already_transposed=.False.)
447 : end if
448 :
449 : ! Compute (H - e_0 S) |K R_0>
450 893 : call cg_get_residvecs(usepaw, npwsp, ndat, eig(ib_start), kres_bk, ghc_bk, gsc_bk, residv_bk)
451 893 : call cg_norm2g(istwf_k, npwsp, ndat, residv_bk, lambda_bk, me_g0, comm_bsf)
452 :
453 : ! Compute lambda
454 38645 : dots_bk = zero
455 : !$OMP PARALLEL DO PRIVATE(jj, kk)
456 13381 : do idat=1,ndat
457 12488 : jj = 1 + (idat - 1) * npwsp; kk = idat * npwsp
458 : call dotprod_g(dots_bk(1,idat), dots_bk(2,idat), istwf_k, npwsp, option1, &
459 13381 : diis%chain_resv(:,:,0,idat), residv_bk(:,jj), me_g0, xmpi_comm_self)
460 : end do
461 :
462 893 : call xmpi_sum(dots_bk, comm_bsf, ierr)
463 :
464 : ! Build |Psi_1> = |Phi_0> + lambda |K R_0>
465 : !$OMP PARALLEL DO PRIVATE(jj, kk)
466 13381 : do idat=1,ndat
467 12488 : lambda_bk(idat) = -dots_bk(1,idat) / lambda_bk(idat)
468 12488 : jj = 1 + (idat - 1) * npwsp; kk = idat * npwsp
469 41321029 : cg_bk(:,jj:kk) = diis%chain_phi(:,:,0,idat) + lambda_bk(idat) * kres_bk(:,jj:kk)
470 : end do
471 :
472 : ! ===============
473 : ! DIIS iterations
474 : ! ===============
475 3215 : iter_loop: do iter=1,max_niter_block
476 :
477 2454 : if (iter > 1) then
478 : ! Solve DIIS equations and update cg_bk and residv_bk for iter > 1
479 1561 : call diis%update_block(iter, npwsp, ndat, cg_bk, residv_bk, comm_bsf)
480 :
481 : ! Precondition residual, output in kres_bk.
482 1561 : call cg_zcopy(npwsp * ndat, residv_bk, kres_bk)
483 1561 : call cg_precon_many(istwf_k, npw, my_nspinor, ndat, cg_bk, optekin, kinpw, kres_bk, me_g0, comm_bsf)
484 :
485 : ! Compute cg_bk with the same lambda(ndat) obtained at iteration #0
486 1561 : call cg_zaxpy_many_areal(npwsp, ndat, lambda_bk, kres_bk, cg_bk)
487 : end if
488 :
489 : ! Compute H |phi_now> and evaluate new enlx for NC.
490 : call getghc_eigresid(gs_hamk, npw, my_nspinor, ndat, cg_bk, ghc_bk, gsc_bk, mpi_enreg, prtvol, &
491 2454 : eig(ib_start), resid(ib_start), enlx(ib_start), residv_bk, gvnlxc_bk, normalize=.True.)
492 :
493 : ! Store new wavevefunctions and residuals.
494 2454 : call diis%push_iter(iter, ndat, eig(ib_start), resid(ib_start), enlx(ib_start), cg_bk, residv_bk, gsc_bk, "DIIS")
495 :
496 : ! CHECK FOR CONVERGENCE
497 2454 : if (diis%exit_iter(iter, ndat, max_niter_block, occ(ib_start), accuracy_ene, dtset, comm_bsf)) exit iter_loop
498 :
499 : ! Compute <R_i|R_j> and <i|S|j> for j=iter
500 3083 : if (iter /= max_niter_block) call diis%eval_mats(iter, ndat, me_g0, comm_bsf)
501 : end do iter_loop
502 :
503 2439 : if (prtvol == -level) call diis%print_block(ib_start, ndat, istep, ikpt, isppol)
504 : end do ! iblock
505 :
506 653 : call timab(1634, 2, tsec) !"rmm_diis:band_opt"
507 : if (timeit) call cwtime_report(" rmm_diis:band_opt", cpu, wall, gflops)
508 653 : call rmm_ydoc%add_tabular_line(resids2str("rmm-diis"), indent=0)
509 :
510 : ! ===============================
511 : ! Orthogonalize states after DIIS
512 : ! ===============================
513 653 : call timab(583,1,tsec) ! "vtowfk(pw_orthon)"
514 :
515 : !ortalgo = 3 !; ortalgo = mpi_enreg%paral_kgb
516 : !call pw_orthon(0, 0, istwf_k, mcg, mgsc, npwsp, nband, ortalgo, gsc, usepaw, cg, me_g0, comm_bsf)
517 :
518 : ! TODO: Merge the two routines.
519 653 : if (usepaw == 1) then
520 : !call cgtk_fixphase(cg, gsc, 0, 0, istwf_k, mcg, mgsc, mpi_enreg, nband, npwsp, usepaw)
521 : !call cgpaw_normalize(npwsp, nband, cg, gsc, istwf_k, me_g0, comm_bsf)
522 :
523 160 : call cgpaw_cholesky(npwsp, nband, cg, gsc, istwf_k, me_g0, comm_bsf, umat=umat)
524 :
525 : !call cgtk_fixphase(cg, gsc, 0, 0, istwf_k, mcg, mgsc, mpi_enreg, nband, npwsp, usepaw)
526 : !call cgpaw_normalize(npwsp, nband, cg, gsc, istwf_k, me_g0, comm_bsf)
527 : else
528 493 : call cgnc_cholesky(npwsp, nband, cg, istwf_k, me_g0, comm_bsf, use_gemm=.False., umat=umat)
529 : end if
530 :
531 653 : call timab(583,2,tsec)
532 : if (timeit) call cwtime_report(" pw_orthon ", cpu, wall, gflops)
533 :
534 : ! Recompute eigenvalues, residuals, and enlx after orthogonalization.
535 : ! This step is important to improve the convergence of the NC total energy
536 : ! and it guarantees that eigenvalues and residuals are consistent with the output wavefunctions.
537 : ! but we try to avoid it at the beginning of the SCF cycle.
538 : ! NB: In principle, one can rotate Vnl(b,b') using U^-1 from the Cholesky decomposition
539 : ! but the full Vnl matrix should be computed before the ortho step.
540 :
541 : ! Select value of after_ortho:
542 : !
543 : ! 0: return with inconsistent eigenvalues, residuals and enlx_bk to avoid final H |Psi>.
544 : ! 1: recompute enlx_bx after ortho. Return inconsistent eigens and residuals (last DIIS iteration).
545 : ! 2: fully consistent mode: execute final H|Psi> after ortho step to update enlx_bx, eigens, residuals
546 : !
547 : ! Total number of H |Psi> applications:
548 : !
549 : ! 1 for subdiago.
550 : ! 1 for preconditioned steepest descent.
551 : ! (nline - 1) for DIIS or nline if ultimate accuracy is reached.
552 : ! 1 if after_ortho > 0
553 : !
554 653 : after_ortho = 0
555 653 : if (accuracy_level >= 2) after_ortho = 1
556 653 : if (accuracy_level >= 4) after_ortho = 2
557 653 : if (after_ortho >= 1 .and. savemem == 0) after_ortho = 1
558 : ! It seems that PAW is more sensitive to after_ortho. Perhaps I can avoid the final H|phi> if accuracy_level == 1
559 : !if (usepaw == 1) after_ortho = 1
560 : !if (usepaw == 1) after_ortho = 0
561 653 : if (usepaw == 1) after_ortho = 2 ! FIXME ??
562 :
563 653 : if (after_ortho == 0) then
564 90 : call wrtout(std_out, " VERY-FAST: Won't recompute data after orthogonalization.")
565 :
566 : !else if (after_ortho == 1 .and. savemem == 0) then
567 563 : else if (after_ortho == 1 .and. savemem == 0 .and. usepaw == 0) then
568 : !if (prtvol == -level)
569 363 : call wrtout(std_out, " FAST: Recomputing data by rotating matrix elements.")
570 :
571 : if (usepaw == 0 .or. has_fock) then
572 : ! Rotate gvnlxc by solving X_new U = Y_old for X with U upper triangle.
573 : ! Compute enlx with rotated cg and gvnlxc.
574 363 : if (istwf_k == 1) then
575 267 : call ZTRSM('R', 'U', 'N', 'N', npwsp, nband, cone, umat, nband, gvnlxc, npwsp)
576 : else
577 96 : call DTRSM('R', 'U', 'N', 'N', 2*npwsp, nband, one, umat, nband, gvnlxc, 2*npwsp)
578 : end if
579 1089 : ABI_MALLOC(dots, (2, nband))
580 363 : call cg_zdotg_zip(istwf_k, npwsp, nband, option1, cg, gvnlxc, dots, me_g0, comm_bsf)
581 8387 : enlx = dots(1,:)
582 363 : ABI_FREE(dots)
583 : end if
584 :
585 : if (.False.) then
586 : !if (usepaw == 1) then
587 : ! Compute new eigenvalues, residual vectors and norms.
588 : ! Rotate ghc by solving X_new U = Y_old for X with U upper triangle.
589 : if (istwf_k == 1) then
590 : call ZTRSM('R', 'U', 'N', 'N', npwsp, nband, cone, umat, nband, ghc, npwsp)
591 : else
592 : call DTRSM('R', 'U', 'N', 'N', 2*npwsp, nband, one, umat, nband, ghc, 2*npwsp)
593 : end if
594 : ABI_MALLOC_OR_DIE(gwork, (2, npwsp*nband), ierr)
595 : call cg_get_eigens(usepaw, istwf_k, npwsp, nband, cg, ghc, gsc, eig, me_g0, comm_bsf)
596 : call cg_get_residvecs(usepaw, npwsp, nband, eig, cg, ghc, gsc, gwork)
597 : call cg_norm2g(istwf_k, npwsp, nband, gwork, resid, me_g0, comm_bsf)
598 : call rmm_ydoc%add_tabular_line(resids2str("ortho_rot"), indent=0)
599 : ABI_FREE(gwork)
600 : end if
601 :
602 : else
603 200 : if (after_ortho == 1) call wrtout(std_out, " SLOW: Recomputing enlx gvnlx by calling nonlop.")
604 200 : if (after_ortho == 2) call wrtout(std_out, " VERY-SLOW: Recomputing eigens and residues by calling getghc.")
605 :
606 496 : do iblock=1,nblocks
607 296 : igs = 1 + (iblock - 1) * npwsp * bsize; ige = min(iblock * npwsp * bsize, npwsp * nband)
608 296 : ndat = (ige - igs + 1) / npwsp
609 296 : ib_start = 1 + (iblock - 1) * bsize; ib_stop = min(iblock * bsize, nband)
610 296 : cg_bk => cg(:,igs:ige); if (usepaw == 1) gsc_bk => gsc(1:2,igs:ige)
611 296 : if (savemem == 0) then
612 256 : ghc_bk => ghc(:,igs:ige); gvnlxc_bk => gvnlxc(:,igs:ige)
613 : end if
614 :
615 200 : select case (after_ortho)
616 : case (1)
617 : ! recompute NC enlx_bx after ortho.
618 : ! eigens and residuals are inconsistent as they have been computed before pw_orthon.
619 40 : signs = 1; paw_opt = 0
620 40 : if (usepaw == 1) then
621 0 : signs = 2; paw_opt = 3
622 : end if
623 40 : if (paral_kgb == 0) then
624 : call nonlop(choice1, cpopt, cprj_dum, enlx(ib_start:), gs_hamk, 0, eig(ib_start), &
625 40 : mpi_enreg, ndat, 1, paw_opt, signs, gsc_bk, tim_nonlop, cg_bk, gvnlxc_bk)
626 : else
627 : call prep_nonlop(choice1, cpopt, cprj_dum, enlx(ib_start), gs_hamk, 0, eig(ib_start), &
628 : ndat, mpi_enreg, 1, paw_opt, signs, gsc_bk, tim_nonlop, &
629 0 : cg_bk, gvnlxc_bk, already_transposed=.False.)
630 : end if
631 :
632 : case (2)
633 : ! Consistent mode: update enlx_bx, eigens, residuals after orthogonalizalization.
634 : call getghc_eigresid(gs_hamk, npw, my_nspinor, ndat, cg_bk, ghc_bk, gsc_bk, mpi_enreg, prtvol, &
635 : eig(ib_start), resid(ib_start), enlx(ib_start), residv_bk, gvnlxc_bk, &
636 256 : normalize=usepaw == 1)
637 : case default
638 296 : ABI_BUG(sjoin("Wrong after_ortho:", itoa(after_ortho)))
639 : end select
640 : end do ! iblock
641 :
642 200 : call rmm_ydoc%add_tabular_line(resids2str("after_ortho"), indent=0)
643 : end if ! after_ortho > 0
644 :
645 : !if (usepaw == 1) then
646 : ! !call cgtk_fixphase(cg, gsc, 0, 0, istwf_k, mcg, mgsc, mpi_enreg, nband, npwsp, usepaw)
647 : ! call cg_set_imag0_to_zero(istwf_k, me_g0, npwsp, nband, cg, max_absimag)
648 : ! call cg_set_imag0_to_zero(istwf_k, me_g0, npwsp, nband, gsc, max_absimag)
649 : ! call cgpaw_normalize(npwsp, nband, cg, gsc, istwf_k, me_g0, comm_bsf)
650 : !end if
651 :
652 : if (timeit) call cwtime_report(" after_ortho ", cpu, wall, gflops)
653 :
654 : ! Revert mixprec to previous status before returning.
655 653 : if (use_fft_mixprec) prev_mixprec = fftcore_set_mixprec(prev_mixprec)
656 :
657 : !if (dtset%prtvol > 0) then
658 653 : if (diis%stats%length() > 0) call rmm_ydoc%add_dict("skip_stats", diis%stats)
659 653 : call rmm_ydoc%write_and_free(std_out)
660 :
661 : if (timeit) call cwtime_report(" rmm_diis total: ", cpu_all, wall_all, gflops_all)
662 :
663 : ! Final cleanup.
664 653 : ABI_FREE(lambda_bk)
665 653 : ABI_FREE(dots_bk)
666 653 : ABI_FREE(residv_bk)
667 653 : ABI_FREE(kres_bk)
668 653 : ABI_FREE(umat)
669 653 : if (savemem == 0) then
670 605 : ABI_FREE(ghc)
671 605 : ABI_FREE(gvnlxc)
672 : else
673 48 : ABI_FREE(ghc_bk)
674 48 : ABI_FREE(gvnlxc_bk)
675 : end if
676 1959 : call diis%free()
677 :
678 : contains
679 :
680 1506 : function resids2str(level) result(str)
681 : character(len=*),intent(in) :: level
682 : character(len=500) :: str
683 1506 : res_stats = stats_eval(resid(1:nb_pocc))
684 : !res_stats = stats_eval(resid(1:nband))
685 1506 : write(str, "(1x, a12, 4(es10.3))") trim(level), res_stats%mean, res_stats%min, res_stats%max, res_stats%stdev
686 1506 : end function resids2str
687 :
688 : end subroutine rmm_diis
689 : !!***
690 :
691 : !!****f* m_rmm_diis/rmm_diis_push_iter
692 : !! NAME
693 : !! rmm_diis_push_iter
694 : !!
695 : !! FUNCTION
696 : !! Save one iteration of the DIIS algorithm.
697 : !!
698 : !! INPUTS
699 : !!
700 : !! OUTPUT
701 : !!
702 : !! SOURCE
703 :
704 3347 : subroutine rmm_diis_push_iter(diis, iter, ndat, eig_bk, resid_bk, enlx_bk, cg_bk, residv_bk, gsc_bk, tag)
705 :
706 : class(rmm_diis_t),intent(inout) :: diis
707 : integer,intent(in) :: iter, ndat
708 : real(dp),intent(in) :: eig_bk(ndat), resid_bk(ndat), enlx_bk(ndat)
709 : real(dp),intent(in) :: cg_bk(2, diis%npwsp*ndat), residv_bk(2, diis%npwsp*ndat), gsc_bk(2, diis%npwsp*ndat*diis%usepaw)
710 : character(len=*),intent(in) :: tag
711 :
712 : !Local variables-------------------------------
713 : integer :: idat, ibk
714 : ! *************************************************************************
715 :
716 3347 : diis%last_iter = iter
717 51531 : diis%hist_ene(iter, 1:ndat) = eig_bk
718 51531 : diis%hist_resid(iter, 1:ndat) = resid_bk
719 51531 : diis%hist_enlx(iter, 1:ndat) = enlx_bk
720 51531 : diis%step_type(iter, 1:ndat) = tag
721 :
722 51531 : do idat=1,ndat
723 48184 : if (iter == 0) then
724 12488 : if (diis%cplex == 2) then
725 27804 : diis%resmat(:, 0, 0, idat) = [resid_bk(idat), zero]
726 : else
727 6440 : diis%resmat(:, 0, 0, idat) = resid_bk(idat)
728 : end if
729 : end if
730 : !write(std_out, *)"res0", diis%resmat(:, 0, 0, idat)
731 48184 : diis%step_type(iter, idat) = tag
732 48184 : ibk = 1 + (idat - 1) * diis%npwsp
733 48184 : call cg_zcopy(diis%npwsp, cg_bk(:,ibk), diis%chain_phi(:,:,iter,idat))
734 48184 : call cg_zcopy(diis%npwsp, residv_bk(:,ibk), diis%chain_resv(:,:,iter,idat))
735 51531 : if (diis%usepaw == 1) call cg_zcopy(diis%npwsp, gsc_bk(:,ibk), diis%chain_sphi(:,:,iter,idat))
736 : end do
737 :
738 3347 : end subroutine rmm_diis_push_iter
739 : !!***
740 :
741 : !!****f* m_rmm_diis/rmm_diis_exit_iter
742 : !! NAME
743 : !! rmm_diis_exit_iter
744 : !!
745 : !! FUNCTION
746 : !! Return true if we can exit the DIIS iteration
747 : !!
748 : !! INPUTS
749 : !!
750 : !! OUTPUT
751 : !!
752 : !! SOURCE
753 :
754 2454 : logical function rmm_diis_exit_iter(diis, iter, ndat, niter_block, occ_bk, accuracy_ene, dtset, comm) result(ans)
755 :
756 : class(rmm_diis_t),intent(inout) :: diis
757 : integer,intent(in) :: iter, ndat, niter_block, comm
758 : real(dp),intent(in) :: occ_bk(ndat)
759 : real(dp),intent(in) :: accuracy_ene
760 : type(dataset_type),intent(in) :: dtset
761 :
762 : !Local variables-------------------------------
763 : integer,parameter :: master = 0
764 4908 : integer :: idat, ierr, nok, checks(ndat) !nbocc,
765 : real(dp) :: resid, deltae, deold , fact
766 4908 : character(len=50) :: msg_list(ndat)
767 : ! *************************************************************************
768 :
769 2454 : diis%last_iter = iter !; ans = .False.; return
770 2454 : if (xmpi_comm_rank(comm) /= master) goto 10
771 :
772 : ! Tolerances depend on accuracy_level and occupation of the state.
773 16409 : checks = 0
774 :
775 16409 : do idat=1,ndat
776 15016 : resid = diis%hist_resid(iter, idat)
777 15016 : deold = diis%hist_ene(1, idat) - diis%hist_ene(0, idat)
778 15016 : deltae = diis%hist_ene(iter, idat) - diis%hist_ene(iter-1, idat)
779 :
780 : ! Relative criterion on eigenvalue differerence.
781 : ! Abinit default in the CG part is 0.005 that is really low (0.3 in V).
782 : ! Here we increase it depending whether the state is occupied or empty
783 15016 : fact = one !; if (dtset%iscf > 0 .and. abs(occ_bk(idat)) < diis%tol_occupied) fact = three
784 15016 : if (diis%accuracy_level == 1) fact = fact * 18
785 15016 : if (diis%accuracy_level == 2) fact = fact * 12
786 15016 : if (diis%accuracy_level == 3) fact = fact * 6
787 15016 : if (abs(deltae) < fact * dtset%tolrde * abs(deold)) then
788 1528 : checks(idat) = 1; msg_list(idat) = "deltae < fact * tolrde * deold"; cycle
789 : end if
790 :
791 14881 : if (dtset%iscf < 0) then
792 : ! This is the only condition available for NSCF run.
793 869 : if (resid < dtset%tolwfr) then
794 419 : checks(idat) = 1; msg_list(idat) = 'resid < tolwfr'; cycle
795 : end if
796 :
797 : else
798 : ! Conditions available for SCF run.
799 12619 : if (resid < dtset%tolwfr) then
800 102 : checks(idat) = 1; msg_list(idat) = 'resid < tolwfr'; cycle
801 : end if
802 :
803 : ! Absolute criterion on eigenvalue difference. Assuming error on Etot ~ band_energy.
804 12517 : fact = one; if (dtset%iscf > 0 .and. abs(occ_bk(idat)) < diis%tol_occupied) fact = ten
805 12517 : if (sqrt(abs(resid)) < fact * accuracy_ene) then
806 0 : checks(idat) = 1; msg_list(idat) = 'resid < accuracy_ene'; cycle
807 : end if
808 : end if
809 : end do ! idat
810 :
811 : ! Depending on the accuracy_level either full block or a fraction of it must pass the test in order to exit.
812 16409 : nok = count(checks /= 0)
813 1393 : if (diis%accuracy_level == 1) ans = nok >= 0.65_dp * ndat
814 1393 : if (diis%accuracy_level == 2) ans = nok >= 0.75_dp * ndat
815 1393 : if (diis%accuracy_level == 3) ans = nok >= 0.90_dp * ndat
816 1393 : if (diis%accuracy_level == 4) ans = nok == ndat
817 :
818 1393 : if (ans) then
819 : ! Log exit only if this is not the last iteration.
820 108 : if (iter /= niter_block) then
821 646 : do idat=1,ndat
822 646 : if (checks(idat) /= 0) call diis%stats%increment(msg_list(idat), 1)
823 : end do
824 : end if
825 : end if
826 :
827 : ! Broadcast final decision to all ranks.
828 2454 : 10 call xmpi_bcast(ans, master, comm, ierr)
829 :
830 2454 : end function rmm_diis_exit_iter
831 : !!***
832 :
833 : !!****f* m_rmm_diis/rmm_diis_print_block
834 : !! NAME
835 : !! rmm_diis_print_block
836 : !!
837 : !! FUNCTION
838 : !! Print energies, residuals for a block of states.
839 : !!
840 : !! INPUTS
841 : !!
842 : !! OUTPUT
843 : !!
844 : !! SOURCE
845 :
846 0 : subroutine rmm_diis_print_block(diis, ib_start, ndat, istep, ikpt, isppol)
847 :
848 : class(rmm_diis_t),intent(in) :: diis
849 : integer,intent(in) :: ib_start, ndat, istep, ikpt, isppol
850 :
851 : !Local variables-------------------------------
852 : integer :: iter, idat, iband
853 : real(dp) :: deltae, deold, dedold, absdiff
854 : character(len=500) :: msg
855 : ! *************************************************************************
856 :
857 : call wrtout(std_out, &
858 : sjoin("<BEGIN RMM-DIIS-BLOCK, istep:", itoa(istep), ", ikpt:", itoa(ikpt), ", spin: ", itoa(isppol), ">"), &
859 0 : pre_newlines=1)
860 :
861 0 : do idat=1,ndat
862 : write(msg,'(1a, 2(a5), 4(a14), 1x, a6)') &
863 0 : "#", 'iter', "band", "eigen_eV", "eigde_meV", "de/dold", "resid", "type"; call wrtout(std_out, msg)
864 :
865 0 : iband = ib_start + idat - 1
866 0 : deold = diis%hist_ene(1, idat) - diis%hist_ene(0, idat)
867 0 : do iter=0,diis%last_iter
868 0 : dedold = zero; absdiff = zero
869 0 : if (iter > 0) then
870 0 : deltae = diis%hist_ene(iter, idat) - diis%hist_ene(iter-1, idat)
871 0 : dedold = deltae / deold
872 0 : absdiff = (diis%hist_ene(iter, idat) - diis%hist_ene(iter-1, idat))
873 : end if
874 :
875 : write(msg,"(1x, 2(i5), 4(es14.6), 1x, a6)") &
876 0 : iter, iband, diis%hist_ene(iter, idat) * Ha_eV, absdiff * Ha_meV, dedold, &
877 0 : diis%hist_resid(iter, idat), diis%step_type(iter, idat); call wrtout(std_out, msg)
878 : end do
879 : end do
880 :
881 0 : call wrtout(std_out, "<END RMM-DIIS-BLOCK>", newlines=1)
882 :
883 0 : end subroutine rmm_diis_print_block
884 : !!***
885 :
886 : !!****f* m_rmm_diis/getghc_eigresid
887 : !! NAME
888 : !! getghc_eigresid
889 : !!
890 : !! FUNCTION
891 : !! Compute new eigenvalues, residuals, H |psi> and enlx from cg and gsc.
892 : !!
893 : !! INPUTS
894 : !!
895 : !! OUTPUT
896 : !!
897 : !! SOURCE
898 :
899 2758 : subroutine getghc_eigresid(gs_hamk, npw, my_nspinor, ndat, cg, ghc, gsc, mpi_enreg, prtvol, &
900 2758 : eig, resid, enlx, residvecs, gvnlxc, normalize)
901 :
902 : !Arguments ------------------------------------
903 : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
904 : integer,intent(in) :: npw, my_nspinor, ndat, prtvol
905 : real(dp),intent(inout) :: cg(2, npw*my_nspinor*ndat)
906 : real(dp),intent(out) :: ghc(2,npw*my_nspinor*ndat), gsc(2,npw*my_nspinor*ndat*gs_hamk%usepaw)
907 : type(mpi_type),intent(in) :: mpi_enreg
908 : real(dp),intent(out) :: eig(ndat), resid(ndat), enlx(ndat)
909 : real(dp),intent(out) :: residvecs(2, npw*my_nspinor*ndat), gvnlxc(2, npw*my_nspinor*ndat)
910 : logical,optional,intent(in) :: normalize
911 :
912 : !Local variables-------------------------------
913 : integer,parameter :: type_calc0 = 0, option1 = 1, option2 = 2, tim_getghc = 0
914 : integer :: istwf_k, usepaw, cpopt, sij_opt, npwsp, me_g0, comm_bsf
915 : real(dp),parameter :: rdummy = zero
916 : !real(dp) :: cpu, wall, gflops
917 : logical :: normalize_, has_fock
918 : !arrays
919 2758 : real(dp) :: dots(2, ndat)
920 22064 : type(pawcprj_type) :: cprj_dum(1,1)
921 : ! *************************************************************************
922 :
923 : !if (timeit) call cwtime(cpu, wall, gflops, "start")
924 2758 : normalize_ = .True.; if (present(normalize)) normalize_ = normalize
925 2758 : npwsp = npw * my_nspinor
926 2758 : usepaw = gs_hamk%usepaw; istwf_k = gs_hamk%istwf_k; me_g0 = mpi_enreg%me_g0
927 2758 : comm_bsf = mpi_enreg%comm_spinorfft; if (mpi_enreg%paral_kgb == 1) comm_bsf = mpi_enreg%comm_bandspinorfft
928 2758 : has_fock = associated(gs_hamk%fockcommon)
929 :
930 2758 : cpopt = -1; sij_opt = 0
931 2758 : if (usepaw == 1) then
932 991 : sij_opt = 1 ! matrix elements <G|S|C> have to be computed in gsc in addition to ghc
933 : cpopt = -1 ! <p_lmn|in> (and derivatives) are computed here (and not saved)
934 : end if
935 :
936 : ! NC normalization.
937 2758 : if (usepaw == 0 .and. normalize_) call cgnc_normalize(npwsp, ndat, cg, istwf_k, me_g0, comm_bsf)
938 :
939 : ! Compute H |cg>
940 : !call fock_set_ieigen(gs_hamk%fockcommon, iband)
941 2758 : if (mpi_enreg%paral_kgb == 0) then
942 : call getghc(cpopt, cg, cprj_dum, ghc, gsc, gs_hamk, gvnlxc, &
943 1210 : rdummy, mpi_enreg, ndat, prtvol, sij_opt, tim_getghc, type_calc0)
944 : else
945 : call prep_getghc(cg, gs_hamk, gvnlxc, ghc, gsc, rdummy, ndat, &
946 1548 : mpi_enreg, prtvol, sij_opt, cpopt, cprj_dum, already_transposed=.False.)
947 : end if
948 :
949 : ! PAW normalization must be done here once gsc is known.
950 2758 : if (usepaw == 1 .and. normalize_) call cgpaw_normalize(npwsp, ndat, cg, gsc, istwf_k, me_g0, comm_bsf)
951 :
952 : ! Compute new eigenvalues, residual vectors and norms.
953 2758 : call cg_get_eigens(usepaw, istwf_k, npwsp, ndat, cg, ghc, gsc, eig, me_g0, comm_bsf)
954 2758 : call cg_get_residvecs(usepaw, npwsp, ndat, eig, cg, ghc, gsc, residvecs)
955 2758 : call cg_norm2g(istwf_k, npwsp, ndat, residvecs, resid, me_g0, comm_bsf)
956 :
957 2758 : if (usepaw == 0 .or. has_fock) then
958 : ! Evaluate new enlx from gvnlxc.
959 1767 : call cg_zdotg_zip(istwf_k, npwsp, ndat, option1, cg, gvnlxc, dots, me_g0, comm_bsf)
960 33150 : enlx = dots(1,:)
961 : end if
962 :
963 : !if (timeit) call cwtime_report(" getghc_eigresid", cpu, wall, gflops)
964 :
965 8274 : end subroutine getghc_eigresid
966 : !!***
967 :
968 : !!****f* m_rmm_diis/rmm_diis_new
969 : !! NAME
970 : !! rmm_diis_new
971 : !!
972 : !! FUNCTION
973 : !! Build new rmm_diis_t instance.
974 : !!
975 : !! INPUTS
976 : !!
977 : !! OUTPUT
978 : !!
979 : !! SOURCE
980 :
981 653 : type(rmm_diis_t) function rmm_diis_new(accuracy_level, usepaw, istwf_k, npwsp, max_niter, bsize, prtvol) result(diis)
982 :
983 : !Arguments ------------------------------------
984 : integer,intent(in) :: accuracy_level, usepaw, istwf_k, npwsp, max_niter, bsize, prtvol
985 : ! *************************************************************************
986 :
987 653 : diis%accuracy_level = accuracy_level
988 653 : diis%usepaw = usepaw
989 653 : diis%istwf_k = istwf_k
990 126 : diis%cplex = 2; if (istwf_k == 2) diis%cplex = 1
991 653 : diis%npwsp = npwsp
992 653 : diis%max_niter = max_niter
993 653 : diis%bsize = bsize
994 653 : diis%prtvol = prtvol
995 :
996 2612 : ABI_MALLOC(diis%hist_ene, (0:max_niter+2, bsize))
997 1959 : ABI_MALLOC(diis%hist_resid, (0:max_niter+2, bsize))
998 78620 : ABI_CALLOC(diis%hist_enlx, (0:max_niter+2, bsize))
999 2612 : ABI_MALLOC(diis%step_type, (0:max_niter+2, bsize))
1000 3265 : ABI_MALLOC(diis%chain_phi, (2, npwsp, 0:max_niter, bsize))
1001 3265 : ABI_MALLOC(diis%chain_sphi, (2, npwsp*usepaw, 0:max_niter, bsize))
1002 2612 : ABI_MALLOC(diis%chain_resv, (2, npwsp, 0:max_niter, bsize))
1003 560566 : ABI_CALLOC(diis%resmat, (diis%cplex, 0:max_niter, 0:max_niter, bsize)) ! <R_i|R_j>
1004 :
1005 653 : end function rmm_diis_new
1006 : !!***
1007 :
1008 : !!****f* m_rmm_diis/rmm_diis_free
1009 : !! NAME
1010 : !! rmm_diis_free
1011 : !!
1012 : !! FUNCTION
1013 : !! Free dynamic memory.
1014 : !!
1015 : !! INPUTS
1016 : !!
1017 : !! OUTPUT
1018 : !!
1019 : !! SOURCE
1020 :
1021 653 : subroutine rmm_diis_free(diis)
1022 :
1023 : !Arguments ------------------------------------
1024 : class(rmm_diis_t),intent(inout) :: diis
1025 : ! *************************************************************************
1026 :
1027 653 : ABI_SFREE(diis%hist_ene)
1028 653 : ABI_SFREE(diis%hist_resid)
1029 653 : ABI_SFREE(diis%hist_enlx)
1030 653 : ABI_SFREE(diis%step_type)
1031 653 : ABI_SFREE(diis%chain_phi)
1032 653 : ABI_SFREE(diis%chain_sphi)
1033 653 : ABI_SFREE(diis%chain_resv)
1034 653 : ABI_SFREE(diis%resmat)
1035 :
1036 653 : call diis%stats%free()
1037 :
1038 653 : end subroutine rmm_diis_free
1039 : !!***
1040 :
1041 : !!****f* m_rmm_diis/rmm_diis_update_block
1042 : !! NAME
1043 : !! rmm_diis_update_block
1044 : !!
1045 : !! FUNCTION
1046 : !! Compute new trial wavefunctions and residuals from the DIIS chain.
1047 : !!
1048 : !! INPUTS
1049 : !!
1050 : !! OUTPUT
1051 : !!
1052 : !! SOURCE
1053 :
1054 1561 : subroutine rmm_diis_update_block(diis, iter, npwsp, ndat, cg_bk, residv_bk, comm)
1055 :
1056 : !Arguments ------------------------------------
1057 : class(rmm_diis_t),intent(in) :: diis
1058 : integer,intent(in) :: iter, npwsp, comm, ndat
1059 : real(dp),intent(inout) :: cg_bk(2, npwsp, ndat), residv_bk(2, npwsp, ndat)
1060 :
1061 : !local variables
1062 : integer,parameter :: master = 0
1063 : integer :: cplex, ierr, nprocs, my_rank, idat
1064 : real(dp) :: noise !, cpu, wall, gflops
1065 1561 : real(dp),allocatable :: wmat1(:,:,:), wvec(:,:,:), alphas(:,:)
1066 : character(len=500) :: msg
1067 : ! *************************************************************************
1068 :
1069 : !if (timeit) call cwtime(cpu, wall, gflops, "start")
1070 1561 : my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
1071 1561 : cplex = diis%cplex
1072 :
1073 : ! Solve system of linear equations.
1074 : ! Only master works so that we are sure we have the same solution.
1075 252929 : ABI_CALLOC(wvec, (cplex, 0:iter, ndat))
1076 :
1077 1561 : if (my_rank == master) then
1078 4355 : ABI_MALLOC(wmat1, (cplex, 0:iter, 0:iter))
1079 :
1080 10447 : do idat=1,ndat
1081 : !if (mod(idat, nprocs) /= my_rank) cycle ! MPI parallelism
1082 9576 : wvec(1, iter, idat) = -one
1083 382676 : wmat1 = zero
1084 43224 : wmat1(1,:,iter) = -one
1085 43224 : wmat1(1,iter,:) = -one
1086 9576 : wmat1(1,iter,iter) = zero
1087 211976 : wmat1(:,0:iter-1, 0:iter-1) = diis%resmat(:, 0:iter-1, 0:iter-1, idat)
1088 :
1089 9576 : call xhesv_cplex("U", cplex, iter+1, 1, wmat1, wvec(:,:,idat), msg, ierr)
1090 9576 : ABI_CHECK(ierr == 0, msg)
1091 :
1092 : !if (diis%prtvol == -level) then
1093 : ! write(std_out,*)"wvec:", wvec(:,:,idat)
1094 : ! write(std_out,*)"sum(wvec):", sum(wvec(:, 0:iter-1, idat), dim=2)
1095 : !end if
1096 10447 : if (cplex == 2) then
1097 : ! coefficients should sum up to 1 but sometimes we get a small imaginary part. here we remove it
1098 26628 : noise = sum(wvec(2, 0:iter-1, idat))
1099 26628 : wvec(2, 0:iter-1, idat) = wvec(2, 0:iter-1, idat) - noise * iter
1100 : end if
1101 :
1102 : end do
1103 871 : ABI_FREE(wmat1)
1104 : end if
1105 :
1106 : ! Master broadcasts data.
1107 1561 : if (nprocs > 1) call xmpi_bcast(wvec, master, comm, ierr)
1108 : !if (nprocs > 1) call xmpi_sum(wvec, comm, ierr)
1109 :
1110 : ! Take linear combination of chain_phi and chain_resv.
1111 : !$omp parallel private(idat, alphas)
1112 1561 : if (cplex /= 2) then
1113 894 : ABI_MALLOC(alphas, (1, 0:iter))
1114 : end if
1115 :
1116 : !$omp do
1117 24769 : do idat=1,ndat
1118 24769 : if (cplex == 2) then
1119 16932 : call cg_zgemv("N", npwsp, iter, diis%chain_phi(:,:,:,idat), wvec(:,:,idat), cg_bk(:,:,idat))
1120 16932 : call cg_zgemv("N", npwsp, iter, diis%chain_resv(:,:,:,idat), wvec(:,:,idat), residv_bk(:,:,idat))
1121 : else
1122 : ! coefficients are real --> use DGEMV.
1123 28368 : alphas(1,:) = wvec(1,:,idat)
1124 6276 : call dgemv("N", 2*npwsp, iter, one, diis%chain_phi(:,:,:,idat), 2*npwsp, alphas, 1, zero, cg_bk(:,:,idat), 1)
1125 6276 : call dgemv("N", 2*npwsp, iter, one, diis%chain_resv(:,:,:,idat), 2*npwsp, alphas, 1, zero, residv_bk(:,:,idat), 1)
1126 : end if
1127 : end do ! idat
1128 : !$omp end do
1129 :
1130 1561 : if (cplex /= 2) then
1131 298 : ABI_FREE(alphas)
1132 : end if
1133 : !$omp end parallel
1134 :
1135 1561 : ABI_FREE(wvec)
1136 : !if (timeit) call cwtime_report(" update_block", cpu, wall, gflops)
1137 :
1138 1561 : end subroutine rmm_diis_update_block
1139 : !!***
1140 :
1141 : !!****f* m_rmm_diis/rmm_diis_eval_mats
1142 : !! NAME
1143 : !! rmm_diis_eval_mats
1144 : !!
1145 : !! FUNCTION
1146 : !! Compute matrix elements required by the RMM-DIIS method.
1147 : !!
1148 : !! INPUTS
1149 : !!
1150 : !! OUTPUT
1151 : !!
1152 : !! SOURCE
1153 :
1154 1561 : subroutine rmm_diis_eval_mats(diis, iter, ndat, me_g0, comm)
1155 :
1156 : !Arguments ------------------------------------
1157 : class(rmm_diis_t),intent(inout) :: diis
1158 : integer,intent(in) :: iter, ndat, me_g0, comm
1159 :
1160 : !local variables
1161 : integer :: ii, ierr, idat, nprocs, option
1162 : real(dp) :: dotr, doti !, cpu, wall, gflops
1163 : !integer :: requests(ndat)
1164 : ! *************************************************************************
1165 :
1166 : !if (timeit) call cwtime(cpu, wall, gflops, "start")
1167 1561 : nprocs = xmpi_comm_size(comm)
1168 1561 : option = 2; if (diis%cplex == 1) option = 1
1169 :
1170 24769 : do idat=1,ndat
1171 :
1172 82897 : do ii=0,iter
1173 : ! <R_i|R_j>
1174 : call dotprod_g(dotr, doti, diis%istwf_k, diis%npwsp, option, &
1175 58128 : diis%chain_resv(:,:,ii,idat), diis%chain_resv(:,:,iter,idat), me_g0, xmpi_comm_self)
1176 58128 : if (ii == iter) doti = zero
1177 81336 : if (diis%cplex == 2) then
1178 126936 : diis%resmat(:, ii, iter, idat) = [dotr, doti]
1179 : else
1180 15816 : diis%resmat(1, ii, iter, idat) = dotr
1181 : end if
1182 : end do ! ii
1183 :
1184 : !if (nprocs > 1) then
1185 : ! call xmpi_sum(diis%resmat(:,0:iter,iter,idat), comm, ierr)
1186 : ! !call xmpi_isum_ip(diis%resmat(:,0:iter,iter,idat), comm, requests(idat), ierr)
1187 : !endif
1188 : !if (diis%prtvol == -level) write(std_out,*)"iter, idat, resmat:", iter, idat, diis%resmat(:,0:iter,iter,idat)
1189 : end do ! idat
1190 :
1191 1561 : if (nprocs > 1) call xmpi_sum(diis%resmat(:,0:iter,iter,1:ndat), comm, ierr)
1192 : !if (nprocs > 1) call xmpi_waitall(requests, ierr)
1193 : !if (timeit) call cwtime_report(" eval_mats", cpu, wall, gflops)
1194 :
1195 1561 : end subroutine rmm_diis_eval_mats
1196 : !!***
1197 :
1198 : !!****f* m_numeric_tools/my_pack_matrix
1199 : !! NAME
1200 : !! my_pack_matrix
1201 : !!
1202 : !! FUNCTION
1203 : !! Packs a matrix into hermitian format
1204 : !!
1205 : !! INPUTS
1206 : !! N: size of matrix
1207 : !! cplx: 2 if matrix is complex, 1 for real matrix.
1208 : !! mat_in(cplx, N*N)= matrix to be packed
1209 : !!
1210 : !! OUTPUT
1211 : !! mat_out(cplx*N*N+1/2)= packed matrix (upper triangle)
1212 : !!
1213 : !! SOURCE
1214 :
1215 160 : subroutine my_pack_matrix(n, mat_in, mat_out)
1216 :
1217 : !Arguments ------------------------------------
1218 : integer, intent(in) :: N
1219 : real(dp), intent(in) :: mat_in(N, N)
1220 : real(dp), intent(out) :: mat_out(2, N*(N+1)/2)
1221 :
1222 : !local variables
1223 : integer :: isubh, i, j
1224 : ! *************************************************************************
1225 :
1226 160 : isubh = 1
1227 4348 : do j=1,N
1228 65134 : do i=1,j
1229 60786 : mat_out(1,isubh) = mat_in(i, j)
1230 60786 : mat_out(2,isubh) = zero
1231 64974 : isubh = isubh + 1
1232 : end do
1233 : end do
1234 :
1235 160 : end subroutine my_pack_matrix
1236 : !!***
1237 :
1238 : !!****f* ABINIT/subspace_rotation
1239 : !! NAME
1240 : !! subspace_rotation
1241 : !!
1242 : !! FUNCTION
1243 : !! This routine computes the <i|H|j> matrix elements and then performs the subspace rotation
1244 : !! of the orbitals (Rayleigh-Ritz procedure)
1245 : !! The main difference with respect to other similar routines is that this implementation does not require
1246 : !! the <i|H|j> matrix elements as input so it can be used before starting the wavefunction optimation
1247 : !! as required e.g. by the RMM-DIIS method.
1248 : !! Moreover, the routine computes the new residuals after the subspace rotation by rotating the
1249 : !! matrix elements of the Hamiltonian in the new basis (requires more memory but client code
1250 : !! can avoid calling getghc after subspace_rotation.
1251 : !!
1252 : !! INPUTS
1253 : !! gs_hamk <type(gs_hamiltonian_type)>=all data for the hamiltonian at k
1254 : !! ptrvol
1255 : !! mpi_enreg=information about MPI parallelization
1256 : !! nband=number of bands at this k point and spin
1257 : !! npw=number of plane waves at this k point
1258 : !! my_nspinor=number of spinor components treated by this MPI proc.
1259 : !!
1260 : !! OUTPUT
1261 : !! eig(nband): New eigvalues from subspace rotation.
1262 : !! If usepaw==1:
1263 : !! gsc(2,*)=<g|S|c> matrix elements (S=overlap)
1264 : !! enlx(nband)=contribution from each band to nonlocal psp + potential Fock ACE part of total energy, at this k-point
1265 : !! ghc
1266 : !!
1267 : !! SIDE EFFECTS
1268 : !! cg(2,*)=updated wavefunctions
1269 : !! gsc(2,*)=update <G|S|C>
1270 : !!
1271 : !! SOURCE
1272 :
1273 657 : subroutine subspace_rotation(gs_hamk, prtvol, mpi_enreg, nband, npw, my_nspinor, savemem, enlx, eig, cg, gsc, ghc, gvnlxc)
1274 :
1275 : !Arguments ------------------------------------
1276 : type(gs_hamiltonian_type),intent(inout) :: gs_hamk
1277 : integer,intent(in) :: prtvol, nband, npw, my_nspinor, savemem
1278 : type(mpi_type),intent(in) :: mpi_enreg
1279 : real(dp),target,intent(inout) :: cg(2,npw*my_nspinor*nband)
1280 : real(dp),target,intent(inout) :: gsc(2,npw*my_nspinor*nband*gs_hamk%usepaw)
1281 : !real(dp),target,intent(out) :: ghc(2,npw*my_nspinor*nband), gvnlxc(2,npw*my_nspinor*nband)
1282 : real(dp),target,allocatable,intent(out) :: ghc(:,:), gvnlxc(:,:)
1283 : real(dp),intent(out) :: eig(nband), enlx(nband)
1284 :
1285 : !Local variables-------------------------------
1286 : integer,parameter :: type_calc0 = 0, tim_getghc = 0, use_subovl0 = 0, option1 = 1
1287 : integer :: ig, ig0, ib, ierr, bsize, nblocks, iblock, npwsp, ndat, ib_start, ib_stop, paral_kgb
1288 : integer :: iband, cpopt, sij_opt, igs, ige, mcg, mgsc, istwf_k, usepaw, me_g0, cplex, comm_bsf
1289 : logical :: has_fock
1290 : real(dp),parameter :: rdummy = zero
1291 : real(dp) :: cpu, wall, gflops
1292 : !arrays
1293 : real(dp),target :: fake_gsc_bk(0,0)
1294 657 : real(dp) :: subovl(use_subovl0), dots(2, nband)
1295 657 : real(dp),allocatable :: subham(:), h_ij(:,:,:), evec(:,:,:), evec_re(:,:), gwork(:,:)
1296 657 : real(dp),contiguous, pointer :: ghc_bk(:,:), gvnlxc_bk(:,:), gsc_bk(:,:)
1297 4599 : type(pawcprj_type) :: cprj_dum(1,1)
1298 : ! *************************************************************************
1299 :
1300 : if (timeit) call cwtime(cpu, wall, gflops, "start")
1301 :
1302 657 : usepaw = gs_hamk%usepaw; istwf_k = gs_hamk%istwf_k
1303 657 : paral_kgb = mpi_enreg%paral_kgb; me_g0 = mpi_enreg%me_g0
1304 428 : comm_bsf = mpi_enreg%comm_spinorfft; if (mpi_enreg%paral_kgb == 1) comm_bsf = mpi_enreg%comm_bandspinorfft
1305 657 : npwsp = npw * my_nspinor
1306 657 : has_fock = associated(gs_hamk%fockcommon)
1307 :
1308 : ! =======================================
1309 : ! Apply H to input cg to compute <i|H|j>
1310 : ! =======================================
1311 657 : gsc_bk => fake_gsc_bk
1312 657 : cpopt = -1; sij_opt = 0
1313 657 : if (usepaw == 1) then
1314 160 : sij_opt = 1 ! matrix elements <G|S|C> have to be computed in gsc in addition to ghc
1315 : cpopt = -1 ! <p_lmn|in> (and derivatives) are computed here (and not saved)
1316 : end if
1317 :
1318 : ! Treat states in groups of bsize bands even when paral_kgb = 0
1319 657 : bsize = 8; if (paral_kgb == 1) bsize = mpi_enreg%nproc_band * mpi_enreg%bandpp
1320 657 : nblocks = nband / bsize; if (mod(nband, bsize) /= 0) nblocks = nblocks + 1
1321 :
1322 657 : cplex = 2; if (istwf_k /= 1) cplex = 1
1323 : !cplex = 2; if (istwf_k == 2) cplex = 1
1324 :
1325 840085 : ABI_CALLOC(h_ij, (cplex, nband, nband))
1326 :
1327 : ! Allocate full ghc and gvnlxc to be able to rotate residuals and Vnlx matrix elements
1328 : ! after subdiago. More memory but we can save a call to H|psi>.
1329 657 : if (savemem == 0) then
1330 1815 : ABI_MALLOC_OR_DIE(ghc, (2, npwsp*nband), ierr)
1331 1210 : ABI_MALLOC_OR_DIE(gvnlxc, (2, npwsp*nband), ierr)
1332 52 : else if (savemem == 1) then
1333 156 : ABI_MALLOC(ghc_bk, (2, npwsp*bsize))
1334 104 : ABI_MALLOC(gvnlxc_bk, (2, npwsp*bsize))
1335 : else
1336 0 : ABI_ERROR(sjoin("Invalid savemem:", itoa(savemem)))
1337 : end if
1338 :
1339 1566 : do iblock=1,nblocks
1340 909 : igs = 1 + (iblock - 1) * npwsp * bsize; ige = min(iblock * npwsp * bsize, npwsp * nband)
1341 909 : ndat = (ige - igs + 1) / npwsp
1342 909 : ib_start = 1 + (iblock - 1) * bsize; ib_stop = min(iblock * bsize, nband)
1343 :
1344 909 : if (usepaw == 1) gsc_bk => gsc(1:2,igs:ige)
1345 909 : if (savemem == 0) then
1346 845 : ghc_bk => ghc(:, igs:ige); gvnlxc_bk => gvnlxc(:, igs:ige)
1347 : end if
1348 :
1349 909 : if (paral_kgb == 0) then
1350 : call getghc(cpopt, cg(:,igs:ige), cprj_dum, ghc_bk, gsc_bk, gs_hamk, gvnlxc_bk, &
1351 409 : rdummy, mpi_enreg, ndat, prtvol, sij_opt, tim_getghc, type_calc0)
1352 : else
1353 : call prep_getghc(cg(:,igs:ige), gs_hamk, gvnlxc_bk, ghc_bk, gsc_bk, rdummy, ndat, &
1354 500 : mpi_enreg, prtvol, sij_opt, cpopt, cprj_dum, already_transposed=.False.)
1355 : end if
1356 :
1357 : ! Compute <i|H|j> for i=1,nband and all j in block
1358 909 : if (cplex == 2) then
1359 629 : call cg_zgemm("C", "N", npwsp, nband, ndat, cg, ghc_bk, h_ij(:,:,ib_start))
1360 : else
1361 280 : call dgemm("T", "N", nband, ndat, 2*npwsp, one, cg, 2*npwsp, ghc_bk, 2*npwsp, zero, h_ij(:,:,ib_start), nband)
1362 : end if
1363 :
1364 1566 : if (istwf_k /= 1) then
1365 4468 : do iband=ib_start, ib_stop
1366 238956 : h_ij(:,:,iband) = two * h_ij(:,:,iband)
1367 :
1368 4188 : if (istwf_k == 2 .and. me_g0 == 1) then
1369 : ! Gamma k-point and I have G=0. Remove double counting term.
1370 1084 : ig = 1 + (iband - ib_start) * npwsp
1371 31188 : do ib=1,nband
1372 30104 : ig0 = 1 + npwsp * (ib - 1)
1373 : #if defined FC_NVHPC
1374 : if (ig<0) write(100,*) ig,ig0,h_ij(1,ib,iband),cg(1,ig0),ghc_bk(1,ig)
1375 : #endif
1376 31188 : h_ij(1,ib,iband) = h_ij(1,ib,iband) - cg(1,ig0) * ghc_bk(1,ig)
1377 : end do
1378 : end if
1379 :
1380 : ! Force real matrix.
1381 4468 : if (cplex == 2) h_ij(2,:,iband) = zero
1382 : end do
1383 : end if
1384 :
1385 : end do ! iblock
1386 :
1387 : ! Pack <i|H|j> to prepare call to subdiago.
1388 1971 : ABI_MALLOC(subham, (nband*(nband+1)))
1389 657 : if (cplex == 2) then
1390 8925 : do iband=1,nband
1391 8925 : h_ij(2,iband,iband) = zero ! Force diagonal elements to be real
1392 : end do
1393 : end if
1394 :
1395 : if (cplex == 2) then
1396 497 : call pack_matrix(h_ij, subham, nband, 2)
1397 : else
1398 160 : call my_pack_matrix(nband, h_ij, subham)
1399 : end if
1400 :
1401 657 : ABI_FREE(h_ij)
1402 657 : call xmpi_sum(subham, comm_bsf, ierr)
1403 : if (timeit) call cwtime_report(" subspace build Hij", cpu, wall, gflops)
1404 :
1405 : ! ========================
1406 : ! Subspace diagonalization
1407 : ! =======================
1408 : ! Rotate cg, gsc and compute new eigenvalues.
1409 2628 : ABI_MALLOC(evec, (2, nband, nband))
1410 657 : mcg = npwsp * nband; mgsc = npwsp * nband * usepaw
1411 : call subdiago(cg, eig, evec, gsc, 0, 0, istwf_k, mcg, mgsc, nband, npw, my_nspinor, paral_kgb, &
1412 657 : subham, subovl, use_subovl0, usepaw, me_g0)
1413 :
1414 657 : ABI_FREE(subham)
1415 : if (timeit) call cwtime_report(" subspace subdiago", cpu, wall, gflops)
1416 :
1417 657 : if (savemem == 0) then
1418 : ! Rotate ghc matrix in the new subspace:
1419 : !
1420 : ! new_{g,b} = old_{g,i} evec_{i,b}
1421 : !
1422 : ! cg and PAW gsc have been already rotated in subdiago
1423 : !
1424 605 : if (cplex == 1) then
1425 : ! Eigenvectors are real.
1426 624 : ABI_MALLOC(evec_re, (nband, nband))
1427 117660 : evec_re = evec(1,:,:)
1428 : end if
1429 :
1430 1815 : ABI_MALLOC_OR_DIE(gwork, (2, npwsp*nband), ierr)
1431 605 : if (cplex == 1) then
1432 156 : call DGEMM("N", "N", 2*npwsp, nband, nband, one, ghc, 2*npwsp, evec_re, nband, zero, gwork, 2*npwsp)
1433 : else
1434 449 : call abi_zgemm_2r("N", "N", npwsp, nband, nband, cone, ghc, npwsp, evec, nband, czero, gwork, npwsp)
1435 : end if
1436 605 : call cg_zcopy(npwsp * nband, gwork, ghc)
1437 :
1438 : ! Rotate <G|Vnlx|Psi_n> and evaluate new enlx for NC.
1439 605 : if (usepaw == 0 .or. has_fock) then
1440 445 : if (cplex == 1) then
1441 124 : call DGEMM("N", "N", 2*npwsp, nband, nband, one, gvnlxc, 2*npwsp, evec_re, nband, zero, gwork, 2*npwsp)
1442 : else
1443 321 : call abi_zgemm_2r("N", "N", npwsp, nband, nband, cone, gvnlxc, npwsp, evec, nband, czero, gwork, npwsp)
1444 : end if
1445 : !call abi_xgemm('N','N', vectsize, nband, nband, cone, gvnlxc, vectsize, evec, nband, czero, gwork, vectsize, x_cplx=cplx)
1446 445 : call cg_zcopy(npwsp * nband, gwork, gvnlxc)
1447 445 : call cg_zdotg_zip(istwf_k, npwsp, nband, option1, cg, gvnlxc, dots, me_g0, comm_bsf)
1448 10757 : enlx = dots(1,:)
1449 : end if
1450 605 : ABI_FREE(gwork)
1451 605 : ABI_SFREE(evec_re)
1452 : end if
1453 :
1454 657 : ABI_FREE(evec)
1455 657 : if (savemem == 1) then
1456 52 : ABI_FREE(ghc_bk)
1457 52 : ABI_FREE(gvnlxc_bk)
1458 : end if
1459 :
1460 : if (timeit) call cwtime_report(" subspace final rotation", cpu, wall, gflops)
1461 :
1462 1314 : end subroutine subspace_rotation
1463 : !!***
1464 :
1465 0 : end module m_rmm_diis
1466 : !!***
|