Line data Source code
1 : !!****m* ABINIT/m_gwls_lineqsolver
2 : !! NAME
3 : !! m_gwls_lineqsolver
4 : !!
5 : !! FUNCTION
6 : !! .
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 2009-2026 ABINIT group (JLJ, BR, MC)
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 :
23 :
24 : !---------------------------------------------------------------------
25 : ! Module to solve A.x = b efficiently, where A will involve
26 : ! the Hamiltonian.
27 : !---------------------------------------------------------------------
28 :
29 :
30 : module m_gwls_lineqsolver
31 : !----------------------------------------------------------------------------------------------------
32 : ! This module contains routines to solve A x = b interatively to solve the Sternheimer equation
33 : ! in various contexts...
34 : !----------------------------------------------------------------------------------------------------
35 :
36 :
37 : ! local modules
38 : use m_gwls_utility
39 : use m_gwls_wf
40 : use m_gwls_hamiltonian
41 :
42 : ! abinit modules
43 : use defs_basis
44 : use m_abicore
45 : use m_xmpi
46 : use m_bandfft_kpt
47 : use m_cgtools
48 :
49 : use m_time, only : timab
50 : use m_io_tools, only : get_unit
51 :
52 : implicit none
53 : save
54 : private
55 : !!***
56 :
57 : logical :: activate_inf_shift_poles = .false.
58 : real(dp) :: inf_shift_poles = 1.0d-4
59 : !!***
60 :
61 : public :: sqmr, qmr, activate_inf_shift_poles, inf_shift_poles
62 : !!***
63 :
64 : contains
65 :
66 : !!****f* m_hamiltonian/sqmr
67 : !! NAME
68 : !! sqmr
69 : !!
70 : !! FUNCTION
71 : !! .
72 : !!
73 : !! INPUTS
74 : !!
75 : !! OUTPUT
76 : !!
77 : !! SOURCE
78 :
79 1840 : subroutine sqmr(b,x,lambda,project_on_what,omega,omega_imaginary,kill_Pc_x)
80 : !--------------------------------------------------------------------------------
81 : ! This subroutine solves the linear algebra problem
82 : !
83 : ! A x = b
84 : !
85 : ! Where:
86 : ! INPUT
87 : ! -----
88 : ! real(dp) b right-hand-side of the equation to be solved
89 : ! real(dp) omega *OPTIONAL* frequency used in building A
90 : ! logical omega_imaginary *OPTIONAL* is the frequency imaginary?
91 : ! real(dp) lambda value to be subtracted from the Hamiltonian
92 : ! integer project_on_what flag which determines the projection scheme.
93 : !
94 : ! OUTPUT
95 : ! -----
96 : ! real(dp) x solution
97 : !
98 : ! Note that blocksize corresponds to the number of band processors; it is a global
99 : ! variable defined in gwls_hamiltonian. The name is inspired from lobpcgwf.F90.
100 : !
101 : ! with:
102 : ! omega omega_imaginary Operator
103 : ! ------------------------------------------------------
104 : ! absent - A = (H - lambda)
105 : ! present - A = (H - lambda)^2 - omega^2
106 : ! present present, true A = (H - lambda)^2 + omega^2
107 : !
108 : ! project_on_what action
109 : ! ------------------------------------------------------
110 : ! 0 no projection
111 : ! 1 projection on conduction states
112 : ! 2 projection out of subspace degenerate with lambda
113 : ! 3 projection on states beyond all the states explicitly stored
114 : !
115 : ! NOTE: It is the developper's responsibility to apply (H-ev) on the input
116 : ! if the frequency is not zero.
117 : !--------------------------------------------------------------------------------
118 :
119 : !External variables
120 : real(dp), intent(in) :: b(2,npw_g)
121 : real(dp), intent(in) :: lambda
122 : real(dp), intent(out) :: x(2,npw_g)
123 : integer, intent(in) :: project_on_what
124 : real(dp), intent(in), optional :: omega
125 : logical, optional :: omega_imaginary, kill_Pc_x
126 :
127 : !Local variables
128 : real(dp) :: norm, tmp(2), residual
129 1840 : real(dp), allocatable :: g(:), theta(:), rho(:), sigma(:), c(:)
130 1840 : real(dp), allocatable :: t(:,:), delta(:,:), r(:,:), d(:,:), w(:,:), wmb(:,:)
131 : integer :: ii,ipw, k, l
132 : real(dp):: signe
133 : real(dp):: norm_Axb
134 :
135 :
136 : real(dp):: norm_b, tol14
137 :
138 : integer :: min_index
139 : logical :: singular
140 : logical :: precondition_on
141 : logical :: has_omega
142 :
143 : integer :: pow
144 :
145 : logical :: imaginary
146 :
147 : integer,save :: counter = 0
148 : integer :: io_unit
149 : character(128) :: filename
150 : logical :: file_exists
151 : logical :: head_node
152 :
153 : integer :: ierr
154 :
155 : integer :: mpi_communicator, mpi_rank, mpi_group
156 :
157 :
158 :
159 : ! timing
160 : real(dp) :: tsec(2)
161 : integer :: GWLS_TIMAB, OPTION_TIMAB
162 :
163 : ! *************************************************************************
164 :
165 : ! The processors communicate over FFT!
166 1840 : mpi_communicator = mpi_enreg%comm_fft
167 :
168 : ! what is the rank of this processor, within its group?
169 1840 : mpi_rank = mpi_enreg%me_fft
170 :
171 : ! Which group does this processor belong to, given the communicator?
172 1840 : mpi_group = mpi_enreg%me_band
173 :
174 : ! Do we have omega?
175 1840 : has_omega=present(omega)
176 :
177 : ! Test if the input has finite norm
178 1840 : tol14 = 1.0D-14
179 1840 : tmp = cg_zdotc(npw_g,b,b)
180 1840 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
181 1840 : norm_b = tmp(1)
182 :
183 1840 : if (norm_b < tol14) then
184 : ! Because of band parallelism, it is possible that sqmr gets a zero norm argument.
185 : ! A | x> = 0 implies |x > = 0.
186 667248 : x(:,:) = zero
187 : return
188 : end if
189 :
190 736 : GWLS_TIMAB = 1523
191 736 : OPTION_TIMAB = 1
192 736 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
193 :
194 : ! only the head node should write to the log file
195 736 : head_node = ( mpi_rank == 0 )
196 :
197 : !Memory allocation for local variables
198 2208 : ABI_MALLOC(g, (nline))
199 1472 : ABI_MALLOC(theta,(nline))
200 1472 : ABI_MALLOC(rho, (nline))
201 1472 : ABI_MALLOC(sigma,(nline))
202 1472 : ABI_MALLOC(c, (nline))
203 :
204 2208 : ABI_MALLOC(t, (2,npw_g))
205 1472 : ABI_MALLOC(delta,(2,npw_g))
206 1472 : ABI_MALLOC(r, (2,npw_g))
207 1472 : ABI_MALLOC(d, (2,npw_g))
208 1472 : ABI_MALLOC(w, (2,npw_g))
209 1472 : ABI_MALLOC(wmb, (2,npw_g))
210 :
211 :
212 :
213 : !Some vectors won't be filled (first iteration missing) so it's useful to initialise them.
214 74336 : g = zero
215 74336 : theta = zero
216 74336 : rho = zero
217 74336 : sigma = zero
218 74336 : c = zero
219 444832 : x = zero
220 444832 : delta = zero
221 444832 : r = zero
222 444832 : d = zero
223 444832 : w = zero
224 :
225 :
226 : ! Determine if the frequency is imaginary
227 736 : if (has_omega .and. present(omega_imaginary)) then
228 0 : imaginary = omega_imaginary
229 : else
230 : imaginary = .false.
231 : end if
232 :
233 :
234 : ! Define the sign in front of (H-eig(v))**2.
235 : ! If omega_imaginary is not given, we assume that omega is real (and sign=-1).
236 736 : if (has_omega) then
237 0 : if ( imaginary ) then
238 : signe = one
239 : else
240 0 : signe =-one
241 : end if
242 : end if
243 :
244 :
245 : !Check for singularity problems
246 : if (has_omega) then
247 0 : norm = minval(abs((eig(1:nbandv)-lambda)**2 + signe*(omega)**2))
248 0 : min_index = minloc(abs((eig(1:nbandv)-lambda)**2 + signe*(omega)**2),1)
249 : else
250 4416 : norm = minval(abs(eig(1:nbandv)-lambda))
251 3680 : min_index = minloc(abs(eig(1:nbandv)-lambda),1)
252 : end if
253 736 : singular = norm < 1.0d-12
254 :
255 : !--------------------------------------------------------------------------------
256 : ! If the linear operator has a kernel, then the intermediate vectors obtained in
257 : ! SQMR must be projected out of this subspace several time at each iterations,
258 : ! otherwise SQMR is unstable.
259 : !
260 : ! This is true even if the seed vector has been initially projected out of this
261 : ! subspace, since the preconditionning will re-introduce a non-zero component in
262 : ! the subspace of the kernel of the linear operator.
263 : ! ===> Use project_on_what==2 in such cases.
264 : !
265 : ! Here, test if the operator is singular and if we are NOT projecting out of
266 : ! the kernel.
267 : ! ===> If true, stop the code.
268 : !
269 : !--------------------------------------------------------------------------------
270 :
271 : ! Quit if the operator has an uncontrolled kernel, a sign that the routine is being
272 : ! misused by a developper...
273 736 : if (singular .and. ( (project_on_what==1 .and. (min_index > nbandv)) .or. project_on_what==0 )) then
274 0 : write(std_out,*) "ERROR - SQMR: Quasi-singuar problem treated, min. eigenvalue of A is ", norm," < 1d-12."
275 0 : write(std_out,*) " Yet, there is no projection out of the kernel of A. "
276 :
277 0 : if (project_on_what==1 .and. (min_index > nbandv)) then
278 0 : write(std_out,*) " "
279 0 : write(std_out,*) " There is a projection on the conduction states, but A is singular in this "
280 0 : write(std_out,*) " subspace (the kernel contains state i=",min_index," > ",nbandv,"=# of valence states)."
281 : end if
282 :
283 0 : write(std_out,*) " "
284 0 : write(std_out,*) " In this situation, SQMR will be unstable. Use project_on_what==2 as an "
285 0 : write(std_out,*) " input argument of SQMR."
286 0 : write(std_out,*) " "
287 0 : write(std_out,*) " Decision taken to exit..."
288 0 : stop
289 : end if
290 :
291 : !--------------------------------------------------------------------------------
292 : ! Open a log file for the output of SQMR; only write if head of group!
293 : !--------------------------------------------------------------------------------
294 736 : if (head_node) then
295 :
296 576 : io_unit = get_unit()
297 :
298 576 : write(filename,'(A,I0.4,A)') "SQMR_GROUP=",mpi_group,".log"
299 :
300 576 : inquire(file=filename,exist=file_exists)
301 :
302 576 : if (file_exists) then
303 573 : open( io_unit,file=filename,position='append',status=files_status_old)
304 : else
305 3 : open( io_unit,file=filename,status=files_status_new)
306 3 : write(io_unit,10) "#======================================================================================="
307 3 : write(io_unit,10) "# "
308 3 : write(io_unit,10) "# This file contains information regarding the application of the SQMR scheme, "
309 3 : write(io_unit,10) "# for this MPI group. "
310 3 : write(io_unit,10) "#======================================================================================="
311 3 : flush(io_unit)
312 : end if
313 :
314 576 : counter = counter + 1
315 576 : write(io_unit,10) "# "
316 576 : write(io_unit,11) "# Call # ", counter
317 576 : write(io_unit,12) "# lambda = ",lambda," Ha "
318 576 : if (has_omega) then
319 0 : write(io_unit,12) "# omega = ",omega," Ha "
320 0 : if (imaginary) then
321 0 : write(io_unit,10) "# omega is imaginary "
322 : else
323 0 : write(io_unit,10) "# omega is real "
324 : end if
325 : else
326 576 : write(io_unit,10) "# omega is absent "
327 : end if
328 :
329 576 : write(io_unit,13) "# project_on_what = ",project_on_what," "
330 576 : write(io_unit,13) "# "
331 576 : if (has_omega ) then
332 0 : if (imaginary) then
333 0 : write(io_unit,10) "# SOLVE ((H-lambda)^2 + omega^2) x = b"
334 : else
335 0 : write(io_unit,10) "# SOLVE ((H-lambda)^2 - omega^2) x = b"
336 : end if
337 : else
338 576 : write(io_unit,10) "# SOLVE (H-lambda) x = b"
339 : end if
340 :
341 576 : flush(io_unit)
342 : end if ! head_node
343 : !--------------------------------------------------------------------------------
344 : ! Precondition to accelerate convergence
345 : !--------------------------------------------------------------------------------
346 736 : precondition_on = .true.
347 736 : if(imaginary) then
348 0 : if(omega > 10.0_dp) then
349 : precondition_on = .false.
350 : end if
351 : end if
352 :
353 : ! DEBUG
354 736 : pow = project_on_what
355 : !precondition_on = .false.
356 :
357 : !Prepare to precondition
358 : if (precondition_on) then
359 736 : if ( imaginary ) then
360 0 : call set_precondition(lambda,omega)
361 : else
362 736 : call set_precondition()
363 : end if
364 : else
365 0 : call unset_precondition()
366 : end if
367 :
368 : !--------------------------------------------------------------------------------
369 : !Initialisation
370 : !--------------------------------------------------------------------------------
371 :
372 736 : k = 1
373 736 : l = 1
374 :
375 148768 : do ipw=1,npw_g
376 444832 : do ii=1,2
377 444096 : r(ii,ipw) = b(ii,ipw)
378 : end do
379 : end do
380 :
381 736 : if (head_node) then
382 576 : write(io_unit,10) "# "
383 576 : write(io_unit,10) "# iteration approximate residual"
384 576 : write(io_unit,10) "#----------------------------------------"
385 576 : flush(io_unit)
386 : end if
387 :
388 : do ! outer loop
389 736 : call precondition(d,r)
390 :
391 : ! g(k) = norm_k(r)
392 736 : tmp = cg_zdotc(npw_g,r,r)
393 736 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
394 736 : g(k) = dsqrt(tmp(1))
395 :
396 :
397 : !tmp = scprod_k(r,d)
398 736 : tmp = cg_zdotc(npw_g,r,d)
399 736 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
400 736 : rho(k) = tmp(1)
401 :
402 736 : if (head_node) then
403 576 : write(io_unit,16) k, g(k)**2
404 576 : flush(io_unit)
405 : end if
406 :
407 : do ! inner loop
408 16285 : k=k+1
409 16285 : l=l+1
410 :
411 : ! Apply the A operator
412 16285 : if (has_omega) then
413 0 : call Hpsik(w,d,lambda)
414 0 : call Hpsik(w,cte=lambda)
415 0 : do ipw=1,npw_g
416 0 : do ii=1,2
417 0 : w(ii,ipw) = w(ii,ipw) + d(ii,ipw)*signe*omega**2
418 : end do
419 : end do
420 : else
421 16285 : call Hpsik(w,d,lambda)
422 : end if
423 :
424 : ! Apply projections, if requested
425 : !if(dtset%gwcalctyp /= 2) then !This is a test to obtain the time taken by the orthos.
426 16285 : if(pow == 1) call pc_k_valence_kernel(w)
427 : !if(pow == 2) call pc_k(w,eig_e=lambda)
428 : !if(pow == 3) call pc_k(w,n=nband,above=.true.)
429 : !end if
430 :
431 : ! Apply SQMR scheme
432 : !tmp = scprod_k(d,w)
433 16285 : tmp = cg_zdotc(npw_g,d,w)
434 16285 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
435 :
436 16285 : sigma(k-1) = tmp(1)
437 3274274 : do ipw=1,npw_g
438 9790252 : do ii=1,2
439 9773967 : r(ii,ipw) = r(ii,ipw)-(rho(k-1)/sigma(k-1))*w(ii,ipw)
440 : end do
441 : end do
442 :
443 : ! The following two lines must have a bug! We cannot distribute the norm this way!
444 : ! theta(k) = norm_k(r)/g(k-1)
445 : ! call xmpi_sum(theta(k), mpi_communicator,ierr) ! sum on all processors working on FFT!
446 16285 : tmp = cg_zdotc(npw_g,r,r)
447 16285 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
448 16285 : theta(k) = dsqrt(tmp(1))/g(k-1)
449 :
450 16285 : c(k) = one/dsqrt(one+theta(k)**2)
451 16285 : g(k) = g(k-1)*theta(k)*c(k)
452 3274274 : do ipw=1,npw_g
453 9790252 : do ii=1,2
454 6515978 : delta(ii,ipw) = delta(ii,ipw)*(c(k)*theta(k-1))**2+d(ii,ipw)*rho(k-1)/sigma(k-1)*c(k)**2
455 9773967 : x(ii,ipw) = x(ii,ipw)+delta(ii,ipw)
456 : end do
457 : end do
458 :
459 16285 : if (head_node) then
460 12677 : write(io_unit,16) k, g(k)**2
461 12677 : flush(io_unit)
462 : end if
463 :
464 : ! Test exit condition
465 16285 : if(g(k)**2<tolwfr .or. k>= nline) exit
466 : !if(k>=nline) exit
467 :
468 : ! Safety test every 100 iterations, check that estimated residual is of the right order of magnitude.
469 : ! If not, restart SQMR.
470 15549 : if(mod(l,100)==0) then
471 0 : if(has_omega) then
472 0 : call Hpsik(w,x,lambda)
473 0 : call Hpsik(w,cte=lambda)
474 0 : do ipw=1,npw_g
475 0 : do ii=1,2
476 0 : w(ii,ipw) = w(ii,ipw) + x(ii,ipw)*signe*omega**2
477 : end do
478 : end do
479 : else
480 0 : call Hpsik(w,x,lambda)
481 : end if
482 :
483 0 : if(pow == 1) call pc_k_valence_kernel(w)
484 : !if(pow == 2) call pc_k(w,eig_e=lambda)
485 : !if(pow == 3) call pc_k(w,n=nband,above=.true.)
486 :
487 : !if(norm_k(w-b)**2 > 10*g(k)**2) exit
488 0 : do ipw=1,npw_g
489 0 : do ii=1,2
490 0 : wmb(ii,ipw) = w(ii,ipw) - b(ii,ipw)
491 : end do
492 : end do
493 0 : tmp = cg_zdotc(npw_g,wmb,wmb)
494 0 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
495 0 : if(tmp(1) > 10*g(k)**2) exit
496 :
497 : end if
498 :
499 : ! Get ready for next cycle
500 15549 : call precondition(w,r)
501 : !if(dtset%gwcalctyp /= 2) then
502 15549 : if(pow == 1) call pc_k_valence_kernel(w)
503 : !if(pow == 2) call pc_k(w,eig_e=lambda)
504 : !if(pow == 3) call pc_k(w,n=nband,above=.true.)
505 : !end if
506 :
507 : !tmp = scprod_k(r,w)
508 15549 : tmp = cg_zdotc(npw_g,r,w)
509 15549 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
510 15549 : rho(k) = tmp(1)
511 :
512 3126242 : do ipw=1,npw_g
513 9345420 : do ii=1,2
514 9329871 : d(ii,ipw) = w(ii,ipw)+d(ii,ipw)*rho(k)/rho(k-1)
515 : end do
516 : end do
517 :
518 : end do ! end inner loop
519 :
520 : ! Exit condition
521 736 : if(g(k)**2<tolwfr .or. k>=nline) exit
522 : !if(k>=nline) exit
523 :
524 0 : if (head_node) write(io_unit,10) " ---- RESTART of SQMR -----"
525 :
526 : !norm_Axb = norm_k(w-b)**2
527 0 : do ipw=1,npw_g
528 0 : do ii=1,2
529 0 : wmb(ii,ipw) = w(ii,ipw) - b(ii,ipw)
530 : end do
531 : end do
532 0 : tmp = cg_zdotc(npw_g,wmb,wmb)
533 0 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
534 0 : norm_Axb = tmp(1)
535 :
536 0 : if (head_node) then
537 0 : write(io_unit,*) "|Ax-b|^2 :",norm_Axb
538 0 : write(io_unit,*) "g(k)^2 :",g(k)**2
539 0 : flush(io_unit)
540 : end if
541 :
542 0 : k = k+1
543 0 : l = 1
544 :
545 : ! Apply the operator
546 0 : if(has_omega) then
547 0 : call Hpsik(r,x,lambda)
548 0 : call Hpsik(r,cte=lambda)
549 0 : do ipw=1,npw_g
550 0 : do ii=1,2
551 0 : r(ii,ipw) = r(ii,ipw) + x(ii,ipw)*signe*omega**2
552 : end do
553 : end do
554 : else
555 0 : call Hpsik(r,x,lambda)
556 : end if
557 :
558 0 : if(pow == 1) call pc_k_valence_kernel(r)
559 : !if(pow == 2) call pc_k(r,eig_e=lambda)
560 : !if(pow == 3) call pc_k(r,n=nband,above=.true.)
561 :
562 736 : do ipw=1,npw_g
563 0 : do ii=1,2
564 0 : r(ii,ipw) = b(ii,ipw) - r(ii,ipw)
565 : end do
566 : end do
567 :
568 : end do ! outer loop
569 :
570 :
571 736 : ktot = ktot+k
572 736 : if(k >= nline .and. head_node ) then
573 0 : write(io_unit,10) " **** Iterations were not enough to converge! ****"
574 : end if
575 :
576 736 : if( present(kill_Pc_x) ) then
577 0 : if (.not. kill_Pc_x .and. pow == 1) call pc_k_valence_kernel(x)
578 : end if
579 :
580 736 : if( .not. present(kill_Pc_x) .and. pow == 1 ) call pc_k_valence_kernel(x)
581 :
582 :
583 :
584 :
585 : !if(pow == 2) call pc_k(x,eig_e=lambda)
586 : !if(pow == 3) call pc_k(x,n=nband,above=.true.)
587 :
588 736 : if(has_omega) then
589 0 : call Hpsik(w,x,lambda)
590 0 : call Hpsik(w,cte=lambda)
591 0 : do ipw=1,npw_g
592 0 : do ii=1,2
593 0 : w(ii,ipw) = w(ii,ipw) + x(ii,ipw)*signe*omega**2
594 : end do
595 : end do
596 : else
597 736 : call Hpsik(w,x,lambda)
598 : end if
599 736 : if(pow == 1) call pc_k_valence_kernel(w)
600 : !if(pow == 2) call pc_k(w,eig_e=lambda)
601 : !if(pow == 3) call pc_k(w,n=nband,above=.true.)
602 :
603 : !residual = norm_k(w-b)**2
604 148768 : do ipw=1,npw_g
605 444832 : do ii=1,2
606 444096 : wmb(ii,ipw) = w(ii,ipw) - b(ii,ipw)
607 : end do
608 : end do
609 736 : tmp = cg_zdotc(npw_g,wmb,wmb)
610 736 : call xmpi_sum(tmp, mpi_communicator,ierr) ! sum on all processors working on FFT!
611 736 : residual = tmp(1)
612 :
613 736 : if (head_node) then
614 576 : write(io_unit,15) "iterations :", k
615 576 : write(io_unit,14) "tolwfr :", tolwfr
616 576 : write(io_unit,14) "residuals (estimated) :", g(k)**2
617 576 : write(io_unit,14) "residuals : |Ax-b|^2 :", residual
618 576 : close(io_unit)
619 : end if
620 :
621 :
622 :
623 736 : ABI_FREE(g)
624 736 : ABI_FREE(theta)
625 736 : ABI_FREE(rho)
626 736 : ABI_FREE(sigma)
627 736 : ABI_FREE(c)
628 736 : ABI_FREE(t)
629 736 : ABI_FREE(delta)
630 736 : ABI_FREE(r)
631 736 : ABI_FREE(d)
632 736 : ABI_FREE(w)
633 736 : ABI_FREE(wmb)
634 :
635 :
636 736 : OPTION_TIMAB = 2
637 736 : call timab(GWLS_TIMAB,OPTION_TIMAB,tsec)
638 :
639 :
640 :
641 : 10 format(A)
642 : 11 format(A,I8)
643 : 12 format(A,E24.16,A)
644 : 13 format(A,I2,A)
645 : 14 format(20X,A,E24.16)
646 : 15 format(20X,A,I8)
647 : 16 format(5X,I5,15X,E12.3)
648 :
649 : end subroutine sqmr
650 : !!***
651 :
652 : !!****f* m_hamiltonian/qmr
653 : !! NAME
654 : !! qmr
655 : !!
656 : !! FUNCTION
657 : !! .
658 : !!
659 : !! INPUTS
660 : !!
661 : !! OUTPUT
662 : !!
663 : !! SOURCE
664 :
665 320 : subroutine qmr(b,x,lambda) !,project_on_what)
666 : !--------------------------------------------------------------------------------
667 : ! This subroutine solves the linear algebra problem
668 : !
669 : ! A x = b
670 : !
671 : ! where A := (H - lambda) can be non-hermitian.
672 : ! Thus, complex values of lambda are allowed and
673 : ! non-hermitian operators could be handled instead of H.
674 : !
675 : ! Arguments :
676 : ! INPUT
677 : ! -----
678 : ! real(dp) b(2,npw_k) right-hand-side of the equation to be solved
679 : ! real(dp) lambda(2) value to be subtracted from the Hamiltonian (complex).
680 : ! integer project_on_what flag which determines the projection scheme.
681 : !
682 : ! OUTPUT
683 : ! -----
684 : ! real(dp) x(2,npw_k) solution
685 : !
686 : ! project_on_what action
687 : ! ------------------------------------------------------
688 : ! 0 no projection
689 : ! 1 projection on conduction states
690 : ! 2 projection out of subspace degenerate with lambda
691 : ! 3 projection on states beyond all the states explicitly stored
692 : !--------------------------------------------------------------------------------
693 :
694 : !External variables
695 : real(dp), intent(in) :: b(2,npw_k)
696 : real(dp), intent(in) :: lambda(2)
697 : real(dp), intent(out) :: x(2,npw_k)
698 : !integer, intent(in) :: project_on_what !Unused yet, no projections done.
699 :
700 : !Local variables
701 320 : complex(dp), allocatable :: xc(:), r(:), v(:), w(:), z(:), p(:), q(:), y(:), t(:), d(:), s(:)
702 320 : complex(dp), allocatable :: beta(:), eta(:), delta(:), epsilonn(:)
703 : complex(dp) :: lambdac
704 320 : real(dp), allocatable :: rho(:), zeta(:), gama(:), theta(:), resid(:)
705 : integer :: i
706 : integer :: ierr
707 :
708 : integer :: mpi_communicator
709 : !logical :: precondition_on
710 :
711 : ! *************************************************************************
712 :
713 247040 : if(sum(b**2) < tol12) then
714 148224 : x=zero
715 : else
716 :
717 : !Allocation
718 384 : ABI_MALLOC(xc,(npw_k))
719 256 : ABI_MALLOC(r ,(npw_k))
720 256 : ABI_MALLOC(v ,(npw_k))
721 256 : ABI_MALLOC(w ,(npw_k))
722 256 : ABI_MALLOC(z ,(npw_k))
723 256 : ABI_MALLOC(p ,(npw_k))
724 256 : ABI_MALLOC(q ,(npw_k))
725 256 : ABI_MALLOC(y ,(npw_k))
726 256 : ABI_MALLOC(t ,(npw_k))
727 256 : ABI_MALLOC(d ,(npw_k))
728 256 : ABI_MALLOC(s ,(npw_k))
729 :
730 384 : ABI_MALLOC(beta ,(nline))
731 384 : ABI_MALLOC(rho ,(nline+1))
732 256 : ABI_MALLOC(zeta ,(nline+1))
733 256 : ABI_MALLOC(gama ,(nline+1))
734 384 : ABI_MALLOC(eta ,(nline+1))
735 256 : ABI_MALLOC(theta ,(nline+1))
736 256 : ABI_MALLOC(delta ,(nline))
737 256 : ABI_MALLOC(epsilonn,(nline))
738 256 : ABI_MALLOC(resid ,(nline+1))
739 :
740 : !Initialization
741 98816 : x = zero
742 33024 : xc = zero
743 33024 : r = zero
744 33024 : v = zero
745 33024 : w = zero
746 33024 : z = zero
747 33024 : p = zero
748 33024 : q = zero
749 33024 : y = zero
750 33024 : t = zero
751 33024 : d = zero
752 33024 : s = zero
753 :
754 12928 : beta = zero
755 13056 : rho = zero
756 13056 : zeta = zero
757 13056 : gama = zero
758 13056 : eta = zero
759 13056 : theta = zero
760 12928 : delta = zero
761 12928 : epsilonn = zero
762 13056 : resid = zero
763 :
764 128 : call unset_precondition()
765 :
766 :
767 : !mpi_communicator = mpi_enreg%comm_fft
768 128 : mpi_communicator = mpi_enreg%comm_bandfft
769 :
770 128 : lambdac = dcmplx(lambda(1),lambda(2))
771 :
772 128 : i = 1
773 33152 : r = dcmplx(b(1,:),b(2,:))
774 33152 : v = r
775 :
776 128 : rho(i) = norm_kc(v)
777 128 : call xmpi_sum(rho(i),mpi_communicator ,ierr) ! sum on all processors working on FFT!
778 :
779 33152 : w = r
780 128 : call precondition_cplx(z,w)
781 128 : zeta(i) = norm_kc(z)
782 128 : call xmpi_sum(zeta(i),mpi_communicator,ierr) ! sum on all processors working on FFT!
783 :
784 128 : gama(i) = one
785 128 : eta(i) = -one
786 : !theta(i) = zero
787 : !p = zero
788 : !q = zero
789 :
790 3612 : do i=1,nline
791 931896 : v = v/rho(i)
792 931896 : w = w/zeta(i)
793 931896 : z = z/zeta(i)
794 3612 : delta(i) = scprod_kc(z,v)
795 3612 : call xmpi_sum(delta(i),mpi_communicator,ierr) ! sum on all processors working on FFT!
796 :
797 3612 : call precondition_cplx(y,v)
798 3612 : if(i/=1) then
799 902356 : p = y - (zeta(i)*delta(i)/epsilonn(i-1))*p
800 902356 : q = z - ( rho(i)*delta(i)/epsilonn(i-1))*q
801 : else
802 33152 : p = y
803 33152 : q = z
804 : end if
805 3612 : call Hpsikc(t,p,lambdac)
806 3612 : epsilonn(i) = scprod_kc(q,t)
807 3612 : call xmpi_sum(epsilonn(i),mpi_communicator,ierr) ! sum on all processors working on FFT!
808 :
809 3612 : beta(i) = epsilonn(i)/delta(i)
810 935508 : v = t - beta(i)*v
811 3612 : rho(i+1) = norm_kc(v)
812 3612 : call xmpi_sum(rho(i+1),mpi_communicator,ierr) ! sum on all processors working on FFT!
813 :
814 935508 : call Hpsikc(z,q,conjg(lambdac)) ; w = z - beta(i)*w
815 3612 : call precondition_cplx(z,w)
816 3612 : zeta(i+1) = norm_kc(z)
817 3612 : call xmpi_sum(zeta(i+1), mpi_communicator,ierr) ! sum on all processors working on FFT!
818 :
819 3612 : theta(i+1) = rho(i+1)/(gama(i)*abs(beta(i)))
820 3612 : gama(i+1) = 1./sqrt(1+theta(i+1)**2)
821 3612 : eta(i+1) = -eta(i)*rho(i)*gama(i+1)**2/(beta(i)*gama(i)**2)
822 935508 : d = eta(i+1)*p + ((theta(i)*gama(i+1))**2)*d
823 935508 : s = eta(i+1)*t + ((theta(i)*gama(i+1))**2)*s
824 935508 : xc = xc + d
825 935508 : r = r - s
826 3612 : resid(i) = norm_kc(r)**2
827 3612 : call xmpi_sum(resid(i), mpi_communicator,ierr) ! sum on all processors working on FFT!
828 :
829 : !write(std_out,*) "QMR residual**2 = ",resid(i),"; i = ",i-1
830 18060 : if(resid(i) < tolwfr) exit
831 : end do
832 :
833 128 : if(i>=nline) then
834 0 : write(std_out,*) " **** Iterations were not enough to converge! ****"
835 : end if
836 :
837 128 : call Hpsikc(r,xc,lambdac)
838 33152 : v = dcmplx(b(1,:),b(2,:))
839 33024 : resid(nline+1) = norm_kc(r - v)**2
840 128 : call xmpi_sum(resid(nline+1), mpi_communicator,ierr) ! sum on all processors working on FFT!
841 :
842 128 : write(std_out,*) "QMR residual**2 (at end) = ",resid(nline+1),"; # iterations = ",i-1
843 :
844 33024 : x(1,:) = dble(xc)
845 33024 : x(2,:) = dimag(xc)
846 :
847 : !Deallocate
848 128 : ABI_FREE(xc)
849 128 : ABI_FREE(r)
850 128 : ABI_FREE(v)
851 128 : ABI_FREE(w)
852 128 : ABI_FREE(z)
853 128 : ABI_FREE(p)
854 128 : ABI_FREE(q)
855 128 : ABI_FREE(y)
856 128 : ABI_FREE(t)
857 128 : ABI_FREE(d)
858 128 : ABI_FREE(s)
859 :
860 128 : ABI_FREE(beta )
861 128 : ABI_FREE(rho )
862 128 : ABI_FREE(zeta )
863 128 : ABI_FREE(gama )
864 128 : ABI_FREE(eta )
865 128 : ABI_FREE(theta )
866 128 : ABI_FREE(delta )
867 128 : ABI_FREE(epsilonn)
868 512 : ABI_FREE(resid )
869 :
870 : end if
871 :
872 320 : end subroutine qmr
873 : !!***
874 :
875 : end module m_gwls_lineqsolver
876 : !!***
|