TABLE OF CONTENTS
- ABINIT/m_gwls_LanczosResolvents
- m_hamiltonian/build_preconditioned_Hamiltonian_Lanczos_basis
- m_hamiltonian/cleanup_LanczosResolvents
- m_hamiltonian/compute_resolvent_column_shift_lanczos
- m_hamiltonian/compute_resolvent_column_shift_lanczos_right_vectors
- m_hamiltonian/invert_general_matrix
- m_hamiltonian/matrix_function_preconditioned_Hamiltonian
- m_hamiltonian/setup_LanczosResolvents
ABINIT/m_gwls_LanczosResolvents [ Modules ]
NAME
m_gwls_LanczosResolvents
FUNCTION
.
COPYRIGHT
Copyright (C) 2009-2024 ABINIT group (JLJ, BR, MC) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
SOURCE
16 #if defined HAVE_CONFIG_H 17 #include "config.h" 18 #endif 19 20 #include "abi_common.h" 21 22 23 module m_gwls_LanczosResolvents 24 !---------------------------------------------------------------------------------------------------- 25 ! This module contains routines to compute the matrix elements of the resolent, namely 26 ! 27 ! < phi_l | 1/ (H-z) | psi_l' > 28 ! 29 ! where H is the Hamiltonian, and z should be such that we are far from its poles. 30 ! 31 !---------------------------------------------------------------------------------------------------- 32 ! local modules 33 34 use m_gwls_utility 35 use m_gwls_wf 36 use m_gwls_TimingLog 37 use m_gwls_hamiltonian 38 use m_gwls_lineqsolver 39 use m_gwls_GWlanczos 40 41 use defs_basis 42 use m_abicore 43 use m_xmpi 44 use m_io_tools, only : get_unit 45 46 implicit none 47 save 48 private
m_hamiltonian/build_preconditioned_Hamiltonian_Lanczos_basis [ Functions ]
[ Top ] [ m_hamiltonian ] [ Functions ]
NAME
build_preconditioned_Hamiltonian_Lanczos_basis
FUNCTION
.
INPUTS
OUTPUT
SOURCE
243 subroutine build_preconditioned_Hamiltonian_Lanczos_basis(seed_vector) 244 !---------------------------------------------------------------------------------------------------- 245 ! This function Computes the Lanczos basis of the preconditioned Hamiltonian. 246 !---------------------------------------------------------------------------------------------------- 247 implicit none 248 complex(dpc), intent(in) :: seed_vector(npw_g) 249 250 integer :: l 251 integer :: ierr 252 integer :: mpi_communicator 253 254 ! ************************************************************************* 255 256 257 258 mpi_communicator = mpi_enreg%comm_fft 259 260 ! Compute the Lanczos basis as well as the eigenvalues of the T matrix 261 ! Seed must also be preconditioned! 262 LR_seeds(:,1) = precondition_one_on_C(:)*seed_vector(:) 263 264 call block_lanczos_algorithm(mpi_communicator, matrix_function_preconditioned_Hamiltonian, LR_kmax, LR_nseeds, npw_g, LR_seeds, & 265 & LR_alpha, LR_beta, Hamiltonian_Qk) 266 267 268 call diagonalize_lanczos_banded(LR_kmax,LR_nseeds,npw_g, LR_alpha,LR_beta, & 269 Hamiltonian_Qk, LR_Hamiltonian_eigenvalues,.false.) 270 271 272 273 ! Update the Lanczos vectors with the preconditioning matrix 274 do l = 1, LR_kmax 275 Hamiltonian_Qk(:,l) = precondition_C(:)*Hamiltonian_Qk(:,l) 276 end do 277 278 ! compute the M matrix 279 280 ! Compute Q^dagger . Q 281 call ZGEMM('C','N',LR_kmax,LR_kmax,npw_g,cmplx_1,Hamiltonian_Qk,npw_g,Hamiltonian_Qk,npw_g,cmplx_0,LR_M_matrix,LR_kmax) 282 call xmpi_sum(LR_M_matrix,mpi_communicator,ierr) ! sum on all processors working on FFT! 283 284 do l = 1, LR_kmax 285 LR_M_matrix(l,:) = LR_M_matrix(l,:)*LR_Hamiltonian_eigenvalues(l) 286 end do 287 288 end subroutine build_preconditioned_Hamiltonian_Lanczos_basis
m_hamiltonian/cleanup_LanczosResolvents [ Functions ]
[ Top ] [ m_hamiltonian ] [ Functions ]
NAME
cleanup_LanczosResolvents
FUNCTION
.
INPUTS
OUTPUT
SOURCE
156 subroutine cleanup_LanczosResolvents 157 !---------------------------------------------------------------------------------------------------- 158 ! 159 ! This subroutine cleans up global arrays. 160 ! 161 ! 162 !---------------------------------------------------------------------------------------------------- 163 implicit none 164 165 ! ************************************************************************* 166 167 ABI_FREE(precondition_C) 168 ABI_FREE(precondition_one_on_C) 169 ABI_FREE(LR_alpha) 170 ABI_FREE(LR_beta ) 171 ABI_FREE(LR_seeds) 172 ABI_FREE(Hamiltonian_Qk) 173 ABI_FREE(LR_Hamiltonian_eigenvalues) 174 ABI_FREE(LR_M_matrix) 175 176 end subroutine cleanup_LanczosResolvents
m_hamiltonian/compute_resolvent_column_shift_lanczos [ Functions ]
[ Top ] [ m_hamiltonian ] [ Functions ]
NAME
compute_resolvent_column_shift_lanczos
FUNCTION
.
INPUTS
OUTPUT
SOURCE
305 subroutine compute_resolvent_column_shift_lanczos(nz, list_z, nvec, list_left_vectors, seed_vector, matrix_elements_resolvent) 306 !---------------------------------------------------------------------------------------------------- 307 ! This function Computes one column of the resolvent using the shift lanczos algorithm, 308 ! namely 309 ! 310 ! 311 ! I_l(z) = < left_vector_l | xi(z) > 312 ! 313 ! where |xi(z) > is obtained from the shift lanczos scheme. 314 !---------------------------------------------------------------------------------------------------- 315 implicit none 316 317 integer , intent(in) :: nz 318 complex(dpc), intent(in) :: list_z(nz) 319 320 integer , intent(in) :: nvec 321 complex(dpc), intent(in) :: list_left_vectors(npw_g,nvec) 322 323 complex(dpc), intent(in) :: seed_vector(npw_g) 324 325 complex(dpc), intent(out) :: matrix_elements_resolvent(nz,nvec) 326 327 ! local variables 328 integer :: iz, l 329 complex(dpc) :: z 330 integer :: ierr 331 integer :: mpi_communicator 332 333 complex(dpc) :: right_vec(LR_kmax) 334 complex(dpc) :: left_vecs(LR_kmax,nvec) 335 complex(dpc) :: work_vec(LR_kmax) 336 complex(dpc) :: shift_lanczos_matrix(LR_kmax,LR_kmax) 337 338 complex(dpc) :: work_array(npw_g) 339 340 ! ************************************************************************* 341 342 343 ! processes will communicate along FFT rows 344 mpi_communicator = mpi_enreg%comm_fft 345 346 !---------------------------------------------------------------------------------------------------- 347 ! First, build the Lanczos basis for the preconditioned Hamiltonian 348 !---------------------------------------------------------------------------------------------------- 349 call build_preconditioned_Hamiltonian_Lanczos_basis(seed_vector) 350 351 352 !---------------------------------------------------------------------------------------------------- 353 ! Next, generate arrays which do not depend on z, the external shift. 354 !---------------------------------------------------------------------------------------------------- 355 356 ! Q^dagger . C^{-2} | seed > 357 work_array(:) = precondition_one_on_C(:)**2*seed_vector 358 359 call ZGEMV('C',npw_g,LR_kmax,cmplx_1,Hamiltonian_Qk,npw_g,work_array,1,cmplx_0,right_vec,1) 360 call xmpi_sum(right_vec,mpi_communicator,ierr) ! sum on all processors working on FFT! 361 362 ! Q^dagger | left_vectors > 363 call ZGEMM('C','N',LR_kmax,nvec,npw_g,cmplx_1,Hamiltonian_Qk,npw_g,list_left_vectors,npw_g,cmplx_0,left_vecs,LR_kmax) 364 call xmpi_sum(left_vecs,mpi_communicator,ierr) ! sum on all processors working on FFT! 365 366 !---------------------------------------------------------------------------------------------------- 367 ! Use shift Lanczos to compute all matrix elements! 368 !---------------------------------------------------------------------------------------------------- 369 370 do iz = 1, nz 371 372 z = list_z(iz) 373 374 ! Generate the matrix to be inverted 375 shift_lanczos_matrix(:,:) = LR_M_matrix(:,:) 376 377 do l = 1, LR_kmax 378 shift_lanczos_matrix(l,l) = shift_lanczos_matrix(l,l)-z 379 end do 380 381 ! since z could be complex, the matrix is not necessarily hermitian. Invert using general Lapack scheme 382 call invert_general_matrix(LR_kmax,shift_lanczos_matrix) 383 ! the matrix now contains the inverse! 384 385 386 ! | work_vec > = M^{-1} . | right_vec > 387 call ZGEMV('N',LR_kmax,LR_kmax,cmplx_1,shift_lanczos_matrix,LR_kmax,right_vec,1,cmplx_0,work_vec,1) 388 389 390 ! matrix_elements = < right_vecs | work_vec > 391 call ZGEMV('C',LR_kmax,nvec,cmplx_1,left_vecs,LR_kmax,work_vec,1,cmplx_0,matrix_elements_resolvent(iz,:),1) 392 393 end do 394 395 396 end subroutine compute_resolvent_column_shift_lanczos
m_hamiltonian/compute_resolvent_column_shift_lanczos_right_vectors [ Functions ]
[ Top ] [ m_hamiltonian ] [ Functions ]
NAME
compute_resolvent_column_shift_lanczos_right_vectors
FUNCTION
.
INPUTS
OUTPUT
SOURCE
413 subroutine compute_resolvent_column_shift_lanczos_right_vectors(seed_vector, right_vec) 414 !---------------------------------------------------------------------------------------------------- 415 ! The goal of this routine is to participate in the computation of a column of the resolvent 416 ! using the shift lanczos algorithm. This routine should be called FIRST. 417 ! 418 ! This routine: 419 ! 420 ! 1) builds the preconditioned Hamiltonian Lanczos basis, using the seed_vector, and 421 ! stores result in the Module variables. 422 ! 423 ! 2) prepares and returns the Lanczos basis-projected right vectors, ready for further processing. 424 ! 425 ! 426 !---------------------------------------------------------------------------------------------------- 427 implicit none 428 429 complex(dpc), intent(in) :: seed_vector(npw_g) 430 complex(dpc), intent(out):: right_vec(LR_kmax) 431 432 ! local variables 433 integer :: mpi_communicator 434 integer :: ierr 435 436 complex(dpc) :: work_array(npw_g) 437 438 ! ************************************************************************* 439 440 441 ! processes will communicate along FFT rows 442 mpi_communicator = mpi_enreg%comm_fft 443 444 !---------------------------------------------------------------------------------------------------- 445 ! First, build the Lanczos basis for the preconditioned Hamiltonian 446 !---------------------------------------------------------------------------------------------------- 447 call build_preconditioned_Hamiltonian_Lanczos_basis(seed_vector) 448 449 !---------------------------------------------------------------------------------------------------- 450 ! Next, generate arrays which do not depend on z, the external shift. 451 !---------------------------------------------------------------------------------------------------- 452 453 ! Q^dagger . C^{-2} | seed > 454 work_array(:) = precondition_one_on_C(:)**2*seed_vector(:) 455 456 call ZGEMV('C', npw_g, LR_kmax, cmplx_1, Hamiltonian_Qk, npw_g, work_array, 1, cmplx_0, right_vec, 1) 457 call xmpi_sum(right_vec,mpi_communicator,ierr) ! sum on all processors working on FFT! 458 459 460 end subroutine compute_resolvent_column_shift_lanczos_right_vectors
m_hamiltonian/invert_general_matrix [ Functions ]
[ Top ] [ m_hamiltonian ] [ Functions ]
NAME
invert_general_matrix
FUNCTION
.
INPUTS
OUTPUT
SOURCE
478 subroutine invert_general_matrix(n,matrix) 479 !---------------------------------------------------------------------------------------------------- 480 ! Simple wrapper around lapack routines to invert a general matrix 481 !---------------------------------------------------------------------------------------------------- 482 implicit none 483 484 integer, intent(in) :: n 485 complex(dpc), intent(inout) :: matrix(n,n) 486 487 integer :: info 488 integer :: ipiv(n) 489 490 integer :: debug_unit 491 character(50) :: debug_filename 492 493 494 495 496 complex(dpc) :: work(n) 497 498 ! ************************************************************************* 499 500 call ZGETRF( n, n, matrix, n, ipiv, info ) 501 if ( info /= 0) then 502 debug_unit = get_unit() 503 write(debug_filename,'(A,I4.4,A)') 'LAPACK_DEBUG_PROC=',mpi_enreg%me,'.log' 504 505 open(debug_unit,file=trim(debug_filename),status='unknown') 506 507 write(debug_unit,'(A)') '*********************************************************************************************' 508 write(debug_unit,'(A,I4,A)') '* ERROR: info = ',info,' in ZGETRF(1), gwls_LanczosResolvents' 509 write(debug_unit,'(A)') '*********************************************************************************************' 510 511 close(debug_unit) 512 513 end if 514 515 516 call ZGETRI( n, matrix, n, ipiv, work, n, info ) 517 518 if ( info /= 0) then 519 debug_unit = get_unit() 520 write(debug_filename,'(A,I4.4,A)') 'LAPACK_DEBUG_PROC=',mpi_enreg%me,'.log' 521 522 open(debug_unit,file=trim(debug_filename),status='unknown') 523 524 write(debug_unit,'(A)') '*********************************************************************************************' 525 write(debug_unit,'(A,I4,A)') '* ERROR: info = ',info,' in ZGETRI(1), gwls_LanczosResolvents' 526 write(debug_unit,'(A)') '*********************************************************************************************' 527 528 close(debug_unit) 529 530 end if 531 532 533 end subroutine invert_general_matrix
m_hamiltonian/matrix_function_preconditioned_Hamiltonian [ Functions ]
[ Top ] [ m_hamiltonian ] [ Functions ]
NAME
matrix_function_preconditioned_Hamiltonian
FUNCTION
.
INPUTS
OUTPUT
SOURCE
192 subroutine matrix_function_preconditioned_Hamiltonian(vector_out,vector_in,Hsize) 193 !---------------------------------------------------------------------------------------------------- 194 ! This subroutine is a simple wrapper around the preconditioned Hamiltonian operator which acts as 195 ! 196 ! C^{-1} . H . C^{-1} 197 ! 198 ! where C^{-2} ~ 1 / T, where T is the kinetic energy. 199 ! 200 !---------------------------------------------------------------------------------------------------- 201 implicit none 202 integer, intent(in) :: Hsize 203 complex(dpc), intent(out) :: vector_out(Hsize) 204 complex(dpc), intent(in) :: vector_in(Hsize) 205 206 ! local variables 207 real(dp) :: psikg(2,npw_g) 208 209 complex(dpc) :: tmp_vector(Hsize) 210 211 ! ************************************************************************* 212 213 ! convert from one format to the other 214 215 tmp_vector(:) = precondition_one_on_C(:)*vector_in(:) 216 217 psikg(1,:) = dble (tmp_vector(:)) 218 psikg(2,:) = dimag(tmp_vector(:)) 219 220 call Hpsik(psikg) 221 222 tmp_vector(:) = cmplx_1*psikg(1,:)+cmplx_i*psikg(2,:) 223 224 vector_out(:) = precondition_one_on_C(:)*tmp_vector(:) 225 226 227 end subroutine matrix_function_preconditioned_Hamiltonian
m_hamiltonian/setup_LanczosResolvents [ Functions ]
[ Top ] [ m_hamiltonian ] [ Functions ]
NAME
setup_LanczosResolvents
FUNCTION
.
INPUTS
OUTPUT
SOURCE
92 subroutine setup_LanczosResolvents(kmax, prec) 93 !---------------------------------------------------------------------------------------------------- 94 ! 95 ! This subroutine prepares global work arrays in order to use the Lanczos scheme to 96 ! compute matrix elements of inverse operators. 97 ! 98 ! 99 !---------------------------------------------------------------------------------------------------- 100 implicit none 101 102 !------------------------------ 103 ! input/output variables 104 !------------------------------ 105 106 integer, intent(in) :: kmax ! number of Lanczos steps 107 logical, intent(in) :: prec ! should there be preconditioning? 108 109 ! ************************************************************************* 110 111 112 LR_kmax = kmax 113 LR_nseeds = 1 ! only one seed 114 115 ! Prepare the algorithm 116 117 ABI_MALLOC(precondition_C, (npw_g)) 118 ABI_MALLOC(precondition_one_on_C, (npw_g)) 119 120 121 if ( prec ) then 122 call set_precondition() 123 124 precondition_one_on_C(:) = sqrt(pcon(:)) 125 !precondition_one_on_C(:) = pcon(:) ! yields very bad results! 126 precondition_C(:) = cmplx_1/precondition_one_on_C(:) 127 128 else 129 precondition_C(:) = cmplx_1 130 precondition_one_on_C(:) = cmplx_1 131 end if 132 133 ABI_MALLOC(LR_alpha, (LR_nseeds,LR_nseeds,LR_kmax)) 134 ABI_MALLOC(LR_beta , (LR_nseeds,LR_nseeds,LR_kmax)) 135 ABI_MALLOC(LR_seeds, (npw_g,LR_nseeds)) 136 ABI_MALLOC(Hamiltonian_Qk, (npw_g,LR_kmax)) 137 ABI_MALLOC(LR_Hamiltonian_eigenvalues, (LR_kmax)) 138 ABI_MALLOC(LR_M_matrix, (LR_kmax,LR_kmax)) 139 140 end subroutine setup_LanczosResolvents