TABLE OF CONTENTS
- ABINIT/m_rf2
- m_rf2/rf2_accumulate_bands
- m_rf2/rf2_apply_hamiltonian
- m_rf2/rf2_destroy
- m_rf2/rf2_getidir
- m_rf2/rf2_getidirs
- m_rf2/rf2_t
ABINIT/m_rf2 [ Modules ]
NAME
m_rf2
FUNCTION
This module defines structures and provides procedures used to compute the 2nd order Sternheimer equation.
COPYRIGHT
Copyright (C) 2015-2024 ABINIT group (LB,MT) 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
17 #if defined HAVE_CONFIG_H 18 #include "config.h" 19 #endif 20 21 #include "abi_common.h" 22 23 MODULE m_rf2 24 25 use defs_basis 26 use m_abicore 27 use m_errors 28 use m_hamiltonian 29 use m_cgtools 30 31 use defs_abitypes, only : MPI_type 32 use m_getgh1c, only : getgh1c 33 use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_copy, pawcprj_free, pawcprj_output 34 use m_getghc, only : getghc 35 use m_nonlop, only : nonlop 36 use m_getgh2c, only : getgh2c 37 38 implicit none 39 40 private
m_rf2/rf2_accumulate_bands [ Functions ]
[ Top ] [ m_rf2 ] [ Functions ]
NAME
rf2_init
FUNCTION
Compute the scalar product < vi | v1j > and add it to rf2%lambda_mn If necessary, compute < vi | v2j > and add it to rf2%amn.
INPUTS
rf2 : rf2_t object containing all rf2 data choice : 4 possible values, see "select case (choice)" below gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q mpi_enreg=information about MPI parallelization iband : band index for vi idir1 (used only if debug_mode/=0) : direction of the 1st perturbation idir2 (used only if debug_mode/=0) : direction of the 2nd perturbation ipert1 (used only if debug_mode/=0) : 1st perturbation ipert2 (used only if debug_mode/=0) : 2nd perturbation jband : band index for v1j and v2j debug_mode : if /=0 : all < vi | v1j > and < vi | v2j > are printed in std_out vi,v1j,v2j : input vectors
OUTPUT
NOTES
SOURCE
258 subroutine rf2_accumulate_bands(rf2,choice,gs_hamkq,mpi_enreg,iband,idir1,idir2,ipert1,ipert2,& 259 jband,debug_mode,vi,v1j,v2j,factor_in) 260 261 !Arguments --------------------------------------------- 262 !scalars 263 integer,intent(in) :: choice,iband,idir1,idir2,ipert1,ipert2,jband,debug_mode 264 type(rf2_t),intent(inout) :: rf2 265 type(gs_hamiltonian_type),intent(in) :: gs_hamkq 266 type(MPI_type),intent(in) :: mpi_enreg 267 real(dp), intent(in) :: factor_in 268 269 !arrays 270 real(dp),intent(in) :: vi(2,rf2%size_wf),v1j(2,rf2%size_wf),v2j(2,rf2%size_wf) 271 272 !Local variables --------------------------------------- 273 !scalars 274 integer :: nband_k,size_wf 275 real(dp) :: dotr,dot2r,doti,dot2i 276 character(len=500) :: msg 277 character(len=15) :: bra_i,ket_j,op1,op2 278 character(len=2) :: pert1,pert2 279 280 ! ************************************************************************* 281 282 DBG_ENTER("COLL") 283 284 nband_k = rf2%nband_k 285 size_wf = rf2%size_wf 286 287 call dotprod_g(dotr,doti,gs_hamkq%istwf_k,size_wf,2,vi,v1j,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft) 288 289 if(debug_mode/=0) then 290 if (ipert1 == gs_hamkq%natom+1) then 291 pert1 = "dk" 292 else 293 pert1 = "dE" 294 end if 295 if (ipert2 == gs_hamkq%natom+1) then 296 pert2 = "dk" 297 else 298 pert2 = "dE" 299 end if 300 select case (choice) 301 case(1) ! < u^(pert2) | H^(0) | u^(pert1) > 302 write(bra_i,'(2a,2(i1,a))') ' < du/',pert2,idir2,'(',iband,') | ' 303 write(ket_j,'(2a,2(i1,a))') ' | du/',pert1,idir1,'(',jband,') > ' 304 write(op1,'(a)') ' H^(0) ' 305 write(op2,'(a)') ' S^(0) ' 306 case(2) ! < u^(pert2) | H^(pert1) | u^(0) > 307 write(bra_i,'(2a,2(i1,a))') ' < du/',pert2,idir2,'(',iband,') | ' 308 write(ket_j,'(a,i1,a)') ' | u^(0) (',jband,') > ' 309 write(op1,'(2a,i1,a)') ' dH/',pert1,idir1,' ' 310 write(op2,'(2a,i1,a)') ' dS/',pert1,idir1,' ' 311 case(3) ! < u^(0) | H^(pert1pert2) | u^(0) > 312 write(bra_i,'(a,i1,a)') ' < u^(0) (',iband,') | ' 313 write(ket_j,'(a,i1,a)') ' | u^(0) (',jband,') > ' 314 write(op1,'(2(2a,i1),a)') 'd^2H/(',pert1,idir1,' ',pert2,idir2,')' 315 write(op2,'(2(2a,i1),a)') 'd^2S/(',pert1,idir1,' ',pert2,idir2,')' 316 case(4) ! < u^(0) | H^(pert2) | u^(pert1) > 317 write(bra_i,'(a,i1,a)') ' < u^(0) (',iband,') | ' 318 write(ket_j,'(2a,2(i1,a))') ' | du/',pert1,idir1,'(',jband,') > ' 319 write(op1,'(2a,i1,a)') ' dH/',pert2,idir2,' ' 320 write(op2,'(2a,i1,a)') ' dS/',pert2,idir2,' ' 321 end select 322 dot2r = dotr ; if (abs(dot2r)<tol9) dot2r = zero ! in order to hide the numerical noise 323 dot2i = doti ; if (abs(dot2i)<tol9) dot2i = zero ! in order to hide the numerical noise 324 write(msg,'(3a,2(a,es17.8E3))') bra_i,op1,ket_j,' = ',dot2r,',',dot2i 325 call wrtout(std_out,msg) 326 end if 327 328 rf2%lambda_mn(:,iband+(jband-1)*nband_k) = factor_in*(/dotr,doti/) + rf2%lambda_mn(:,iband+(jband-1)*nband_k) 329 330 if (choice == 1 .or. gs_hamkq%usepaw==1) then 331 call dotprod_g(dotr,doti,gs_hamkq%istwf_k,size_wf,2,vi,v2j,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft) 332 333 if(debug_mode/=0) then 334 dot2r = dotr ; if (abs(dot2r)<tol9) dot2r = zero ! in order to hide the numerical noise 335 dot2i = doti ; if (abs(dot2i)<tol9) dot2i = zero ! in order to hide the numerical noise 336 write(msg,'(3a,2(a,es17.8E3))') bra_i,op2,ket_j,' = ',dot2r,',',dot2i 337 call wrtout(std_out,msg) 338 end if 339 340 rf2%amn(:,iband+(jband-1)*nband_k) = factor_in*(/dotr,doti/) + rf2%amn(:,iband+(jband-1)*nband_k) 341 342 end if ! end choice 343 344 DBG_EXIT("COLL") 345 346 end subroutine rf2_accumulate_bands
m_rf2/rf2_apply_hamiltonian [ Functions ]
[ Top ] [ m_rf2 ] [ Functions ]
NAME
rf2_apply_hamiltonian
FUNCTION
Apply the KS Hamiltonian (or derivative) to an input wave function. If asked, it also does some checks.
INPUTS
rf2 : rf2_t object containing all rf2 data cg_jband (used only if debug_mode/=0) : array containing |u^(0)(jband)> for all bands cprj_jband(natom,nspinor*usecprj)= u^(0) wave functions for all bands projected with non-local projectors: cprj_jband=<p_i|u^(0)(jband)> cwave(2,size_wf) : input wave function |u> cwaveprj(natom,nspinor) : input wave function |u> projected with non-local projectors <p_i|u> eig0 : 0-order eigenvalue for the present wavefunction at k [enl]=optional (if not present, use hamk%ekb); non-local coeffs connecting projectors eig1_k_jband : first-order lagrange multipliers for the band j (Lambda^(1)_ji for all i) [ffnl1]=nonlocal form factors (needed for tests of ipert>=natom+10) [ffnl1_test]=nonlocal form factors used for tests (needed for tests of ipert>=natom+10) jband : band index of the input wavefunction gs_hamkq <type(gs_hamiltonian_type)>=all data for the Hamiltonian at k+q gvnlx1(2,npw1*nspinor)= part of <G|K^(1)+Vnl^(1)|C> not depending on VHxc^(1) (sij_opt/=-1) or part of <G|K^(1)+Vnl^(1)-lambda.S^(1)|C> not depending on VHxc^(1) (sij_opt==-1) idir=direction of the perturbation ipert=type of the perturbation of the Hamiltonian : ipert = 0 : GS calculation, call of getghc ipert = natom+1,2 : 1st order calculation, call of getgh1c ipert = natom+10,11 : 2nd order calculation, call of getgh2c ikpt=number of the k-point isppol=1 index of current spin component mkmem =number of k points trated by this node (GS data). mpi_enreg=information about MPI parallelization nband_k=number of bands at this k point for that spin polarization nsppol=1 for unpolarized, 2 for spin-polarized debug_mode : if /=0 : some tests are done (see NOTES below). Wrong results are printed in std_out prtvol=control print volume and debugging output (for getghc) rf_hamk_idir <type(rf_hamiltonian_type)>=all data for the 1st-order Hamiltonian at k,q (here q=0) size_cprj=size of a cprj array (=gs_hamkq%nspinor) size_wf=size of a wavefunction array (=gs_hamkq%npw_k*gs_hamkq%nspinor)
OUTPUT
h_cwave(2,size_wf) : array containing H^(ipert)|cwave> s_cwave(2,size_wf) : array containing S^(ipert)|cwave>
NOTES
* Tests are done if debug_mode/=0. In that case : cg_jband(:,jband,1) = |u^(0)(jband)> For ipert==natom+2 (electric field) : cg_jband(:,jband,2) = i * |du/dk_idir(jband)> According to ipert, we check that : -- ipert = 0 : < u^(0)(jband)| H^(0) | u^(0)(jband)> = eig0(jband) -- ipert = natom+1 or 2 : < u^(0)(jband)| ( H^(1) - (eig0(jband)+eig0(iband))/2 * S^(1) ) | u^(0)(iband)> = Lambda^(1)(jband,iband) --ipert >= natom+10 : < u^(0) | H^(2) | u^(0) > from getgh2c is equal to nonlop with signs=1 * Use of cprj : The cprj array is computed in dfpt_looppert.F90. In the context of rf2 calculation, it contains <Proj_i^(0)|u^(0)> and <Proj_i^(1)|u^(0)> (dir=1,2 and 3) for all wavefunctions u^(0) or <Proj_i^(0)|u^(1)> and <Proj_i^(1)|u^(1)> (dir=1,2 and 3) for all 1st-order wavefunctions u^(1). Note that <Proj_i^(2)|u^(0)> is always computed on the fly.
SOURCE
415 subroutine rf2_apply_hamiltonian(cg_jband,cprj_jband,cwave,cwaveprj,h_cwave,s_cwave,eig0,eig1_k_jband,& 416 & jband,gs_hamkq,gvnlx1,idir,ipert,ikpt,isppol,mkmem,mpi_enreg,nband_k,nsppol,& 417 & debug_mode,prtvol,rf_hamk_idir,size_cprj,size_wf,& 418 & conj,enl,ffnl1,ffnl1_test) ! optional 419 420 !Arguments --------------------------------------------- 421 !scalars 422 logical,intent(in),optional :: conj 423 integer,intent(in) :: idir,ipert,ikpt,isppol,jband,mkmem,nband_k,nsppol,debug_mode,prtvol,size_wf,size_cprj 424 type(gs_hamiltonian_type),intent(inout) :: gs_hamkq 425 ! type(rf2_t),intent(in) :: rf2 426 type(rf_hamiltonian_type),intent(inout),target :: rf_hamk_idir 427 type(MPI_type),intent(in) :: mpi_enreg 428 429 !arrays 430 real(dp),intent(in),target :: cg_jband(2,size_wf*debug_mode*nband_k,2) 431 real(dp),intent(in),optional,target :: enl(gs_hamkq%dimekb1,gs_hamkq%dimekb2,gs_hamkq%nspinor**2,gs_hamkq%dimekbq) 432 real(dp),intent(in),optional :: ffnl1(:,:,:,:),ffnl1_test(:,:,:,:) 433 real(dp),intent(in) :: eig0(nband_k),eig1_k_jband(2*nband_k) 434 real(dp),intent(inout) :: gvnlx1(2,size_wf) 435 real(dp),intent(inout) :: cwave(2,size_wf),h_cwave(2,size_wf),s_cwave(2,size_wf) 436 type(pawcprj_type),intent(inout),target :: cprj_jband(:,:),cwaveprj(:,:) 437 438 !Local variables --------------------------------------- 439 !scalars 440 integer,parameter :: berryopt=0,tim_getghc=0,tim_getgh1c=0,tim_getgh2c=0,tim_nonlop=0 441 integer,parameter :: alpha(9)=(/1,2,3,2,1,1,3,3,2/),beta(9)=(/1,2,3,3,3,2,2,1,1/) 442 integer :: choice,cpopt,iatom,iband,idirc,idir1,idir2,idir_dum,natom,nnlout,paw_opt,signs,sij_opt 443 integer :: opt_gvnlx1,opt_gvnl2,optlocal,optnl,usevnl 444 logical :: compute_conjugate,has_cprj_jband,has_cwaveprj,pert_phon_elfd 445 real(dp) :: dotr,doti,dotr2,doti2,enlout(18*gs_hamkq%natom),tol_test 446 real(dp), pointer :: enl_ptr(:,:,:,:) 447 real(dp),allocatable,target :: enl_temp(:,:,:,:) 448 character(len=500) :: msg 449 450 !arrays 451 real(dp),target :: cwave_empty(0,0),svectout_dum(0,0) 452 real(dp),allocatable :: gvnlxc(:,:),iddk(:,:) 453 real(dp), ABI_CONTIGUOUS pointer :: cwave_i(:,:),cwave_j(:,:) 454 type(pawcprj_type),target :: cprj_empty(0,0) 455 type(pawcprj_type),pointer :: cprj_j(:,:) 456 ! ********************************************************************* 457 458 DBG_ENTER("COLL") 459 460 compute_conjugate = .false. 461 if(present(conj)) compute_conjugate = conj 462 463 ABI_UNUSED(ikpt) 464 ABI_UNUSED(isppol) 465 ABI_UNUSED(mkmem) 466 ABI_UNUSED(nsppol) 467 468 !Check sizes 469 if (size(cprj_jband)/=0) then 470 if (size(cprj_jband)/=nband_k*gs_hamkq%natom*gs_hamkq%nspinor*gs_hamkq%usecprj) then 471 write(msg,'(2(a,i10))') & 472 'Wrong cprj size! actual size = ',size(cprj_jband),& 473 ' good size = ',nband_k*gs_hamkq%natom*gs_hamkq%nspinor*gs_hamkq%usecprj 474 ABI_BUG(msg) 475 end if 476 end if 477 if (size(cwaveprj)/=0) then 478 if (size(cwaveprj)/=gs_hamkq%natom*gs_hamkq%nspinor*gs_hamkq%usecprj) then 479 write(msg,'(2(a,i10))') & 480 'Wrong cwaveprj size! actual size = ',size(cwaveprj),& 481 ' good size = ',gs_hamkq%natom*gs_hamkq%nspinor*gs_hamkq%usecprj 482 ABI_BUG(msg) 483 end if 484 end if 485 486 natom = gs_hamkq%natom 487 488 pert_phon_elfd = .false. 489 if (ipert>natom+11.and.ipert<=2*natom+11) pert_phon_elfd = .true. 490 usevnl = 0 491 opt_gvnlx1 = 0 492 opt_gvnl2 = 0 493 optnl = 2 494 sij_opt=1;if (gs_hamkq%usepaw==0) sij_opt=0 495 if (ipert==natom+2.or.(ipert==natom+11.and.gs_hamkq%usepaw==1).or.pert_phon_elfd) then 496 usevnl = 1 497 opt_gvnlx1 = 2 498 opt_gvnl2 = 1 499 end if 500 optlocal = 1 501 if (pert_phon_elfd) then 502 optlocal = 0 503 sij_opt = 0 504 optnl = 1 505 end if 506 tol_test=tol8 507 508 ! In the PAW case : manage cprj_jband, cwaveprj 509 has_cprj_jband=(gs_hamkq%usepaw==1.and.gs_hamkq%usecprj==1.and.size(cprj_jband)/=0) 510 has_cwaveprj=(gs_hamkq%usepaw==1.and.gs_hamkq%usecprj==1.and.size(cwaveprj)/=0) 511 cprj_j => cprj_empty 512 513 if (debug_mode/=0) then 514 if (ipert/=0) then 515 write(msg,'(5(a,i4))') 'RF2 TEST rf2_apply_hamiltonian ipert = ',ipert,' idir =',idir,' isppol =',isppol,& 516 & ' ikpt = ',ikpt,' jband = ',jband 517 else 518 write(msg,'(3(a,i4))') 'RF2 TEST rf2_apply_hamiltonian ipert = 0 idir = 0 isppol =',isppol,& 519 & ' ikpt = ',ikpt,' jband = ',jband 520 end if 521 call wrtout(std_out,msg) 522 end if 523 524 ! ******************************************************************************************* 525 ! apply H^(0) 526 ! ******************************************************************************************* 527 if (ipert == 0) then 528 529 ABI_MALLOC(gvnlxc,(2,size_wf)) 530 gvnlxc(:,:) = zero 531 532 ! Test if < u^(0) | H^(0) | u^(0) > = eig0(jband) 533 if(debug_mode/=0) then 534 cwave_j => cg_jband(:,1+(jband-1)*size_wf:jband*size_wf,1) 535 if (has_cprj_jband) cprj_j => cprj_jband(:,1+(jband-1)*size_cprj:jband*size_cprj) 536 cpopt = -1+3*gs_hamkq%usecprj*gs_hamkq%usepaw 537 call getghc(cpopt,cwave_j,cprj_j,h_cwave,s_cwave,gs_hamkq,gvnlxc,zero,mpi_enreg,1,prtvol,& 538 sij_opt,tim_getghc,0,select_k=KPRIME_H_KPRIME) 539 540 call dotprod_g(dotr,doti,gs_hamkq%istwf_k,size_wf,2,cwave_j,h_cwave,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft) 541 dotr = dotr - eig0(jband) 542 dotr = sqrt(dotr**2+doti**2) 543 if (dotr > tol_test) then 544 write(msg,'(a,es17.8E3)') 'RF2 TEST GETGHC : NOT PASSED dotr = ',dotr 545 call wrtout(ab_out,msg) 546 call wrtout(std_out,msg) 547 end if 548 end if ! end tests 549 550 cpopt=-1;if (has_cwaveprj) cpopt=2 551 call getghc(cpopt,cwave,cwaveprj,h_cwave,s_cwave,gs_hamkq,gvnlxc,zero,mpi_enreg,1,prtvol,& 552 sij_opt,tim_getghc,0,select_k=KPRIME_H_KPRIME) 553 ABI_FREE(gvnlxc) 554 555 ! ******************************************************************************************* 556 ! apply H^(1) 557 ! ******************************************************************************************* 558 else if (ipert<=natom+2) then 559 560 ! Test if < u^(0) | ( H^(1) - eps^(0) S^(1) ) | u^(0) > = eig^(1) 561 if(debug_mode/=0) then 562 ABI_MALLOC(iddk,(2,size_wf)) 563 cwave_j => cg_jband(:,1+(jband-1)*size_wf:jband*size_wf,1) 564 if (has_cprj_jband) cprj_j => cprj_jband(:,1+(jband-1)*size_cprj:jband*size_cprj) 565 iddk(:,:) = zero;if (ipert==natom+2) iddk(:,:)=cg_jband(:,1+(jband-1)*size_wf:jband*size_wf,2) 566 call getgh1c(berryopt,cwave_j,cprj_j,h_cwave,cwave_empty,s_cwave,gs_hamkq,iddk,idir,ipert,zero,& 567 mpi_enreg,optlocal,optnl,opt_gvnlx1,rf_hamk_idir,sij_opt,tim_getgh1c,usevnl,conj=compute_conjugate) 568 do iband=1,nband_k 569 cwave_i => cg_jband(:,1+(iband-1)*size_wf:iband*size_wf,1) 570 call dotprod_g(dotr,doti,gs_hamkq%istwf_k,size_wf,2,cwave_i,h_cwave,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft) 571 if (gs_hamkq%usepaw==1.and.ipert/=natom+2) then ! S^(1) is zero for ipert=natom+2 572 call dotprod_g(dotr2,doti2,gs_hamkq%istwf_k,size_wf,2,cwave_i,s_cwave,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft) 573 dotr = dotr - (eig0(iband)+eig0(jband))*dotr2/two 574 doti = doti - (eig0(iband)+eig0(jband))*doti2/two 575 end if 576 dotr = dotr - eig1_k_jband(1+2*(iband-1)) 577 doti = doti - eig1_k_jband(2+2*(iband-1)) 578 dotr = sqrt(dotr**2+doti**2) 579 if (dotr > tol_test) then 580 write(msg,'(4(a,i2),a,es17.8E3)') 'RF2 TEST GETGH1 : ipert=',ipert,' idir=',idir,& 581 ' jband=',jband,' iband=',iband,' NOT PASSED dotr = ',dotr 582 call wrtout(ab_out,msg) 583 call wrtout(std_out,msg) 584 end if 585 end do ! end iband 586 ABI_FREE(iddk) 587 end if ! end tests 588 589 call getgh1c(berryopt,cwave,cwaveprj,h_cwave,cwave_empty,s_cwave,gs_hamkq,gvnlx1,idir,ipert,zero,& 590 mpi_enreg,optlocal,optnl,opt_gvnlx1,rf_hamk_idir,sij_opt,tim_getgh1c,usevnl,conj=compute_conjugate) 591 592 ! ******************************************************************************************* 593 ! apply H^(2) 594 ! ******************************************************************************************* 595 else if (ipert==natom+10.or.ipert==natom+11.or.pert_phon_elfd) then 596 597 ! ******************************************************************************************* 598 ! Test if < u^(0) | H^(2) | u^(0) > from getgh2c is equal to nonlop with signs=1 599 if(debug_mode/=0.and.present(ffnl1).and.present(ffnl1_test)) then 600 601 cwave_j => cg_jband(:,1+(jband-1)*size_wf:jband*size_wf,1) 602 603 ABI_MALLOC(iddk,(2,size_wf)) 604 iddk(:,:) = cwave_j(:,:) 605 606 call getgh2c(cwave_j,cprj_empty,h_cwave,s_cwave,gs_hamkq,iddk,idir,ipert,zero,& 607 mpi_enreg,optlocal,optnl,opt_gvnl2,rf_hamk_idir,sij_opt,tim_getgh2c,usevnl,& 608 conj=compute_conjugate,optkin=0,enl=enl) 609 ABI_FREE(iddk) 610 611 call dotprod_g(dotr,doti,gs_hamkq%istwf_k,size_wf,2,cwave_j,h_cwave,mpi_enreg%me_g0,mpi_enreg%comm_spinorfft) 612 613 idir1=alpha(idir);idir2=beta(idir) 614 idirc=3*(idir1-1)+idir2 615 616 enlout = zero 617 618 ! Change the pointer ffnl_k to ffnl1_test (idir_ffnl=0, for nonlop with signs=1) 619 call gs_hamkq%load_k(ffnl_k=ffnl1_test) 620 621 signs=1 622 dotr2 = 0 623 doti2 = 0 624 625 ! ************************ 626 ! IPERT == NATOM+10 627 ! ************************ 628 if (ipert==natom+10) then 629 630 cpopt=-1; choice=8; paw_opt=1; if (gs_hamkq%usepaw==0) paw_opt=0 ; nnlout = 6 631 632 call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idirc,(/zero/),mpi_enreg,1,nnlout,& 633 & paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum) 634 dotr2 = enlout(idir) 635 636 end if ! IPERT == NATOM+10 637 638 ! ************************ 639 ! IPERT == NATOM+11 640 ! ************************ 641 if (ipert==natom+11) then 642 643 if (present(enl)) then 644 enl_ptr => enl 645 else if (associated(rf_hamk_idir%e1kbfr).and.associated(rf_hamk_idir%e1kbsc).and.optnl==2) then 646 ABI_MALLOC(enl_temp,(gs_hamkq%dimekb1,gs_hamkq%dimekb2,gs_hamkq%nspinor**2,rf_hamk_idir%cplex)) 647 enl_temp(:,:,:,:) = rf_hamk_idir%e1kbfr(:,:,:,:) + rf_hamk_idir%e1kbsc(:,:,:,:) 648 enl_ptr => enl_temp 649 else if (associated(rf_hamk_idir%e1kbfr)) then 650 enl_ptr => rf_hamk_idir%e1kbfr 651 end if 652 653 ! Compute application of dS/dk1 to cwavef 654 ! sum_{i,j} s_ij < psi^(0) | d(|p_i><p_j|)/dk(idir1) | psi^(0) > 655 cpopt=-1 ; choice=5 ; paw_opt=3 ; nnlout=3 656 call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,& 657 & paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum) 658 dotr2 = enlout(idir1) 659 660 ! Compute part of H^(2) due to derivative of projectors (idir1) and derivative of Dij (idir2) 661 ! sum_{i,j} chi_ij(idir2) < psi^(0) | d(|p_i><p_j|)/dk(idir1) | psi^(0) > 662 cpopt=-1 ; choice=5 ; paw_opt=1 ; nnlout=3 663 call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,& 664 & paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum,enl=enl_ptr) 665 dotr2 = dotr2 + enlout(idir1) 666 667 ! Compute derivatives due to projectors |d^2[p_i]/dk1dk2>,|d[p_i]/dk1>,|d[p_i]/dk2> 668 ! i * sum_{i,j} < psi^(0) | (d(|p_i><dp_j/dk(idir2)|)/dk(idir1) | psi^(0) > 669 cpopt=-1 ; choice=81 ; paw_opt=3 ; nnlout=18 670 call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,& 671 & paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum) 672 dotr2 = dotr2 - enlout(2*idirc ) 673 doti2 = doti2 + enlout(2*idirc-1) 674 675 end if ! IPERT == NATOM+11 676 677 ! ************************ 678 ! PERT_PHON_ELFD 679 ! ************************ 680 if (pert_phon_elfd) then 681 682 if (present(enl)) then 683 enl_ptr => enl 684 else if (associated(rf_hamk_idir%e1kbfr).and.associated(rf_hamk_idir%e1kbsc).and.optnl==2) then 685 ABI_MALLOC(enl_temp,(gs_hamkq%dimekb1,gs_hamkq%dimekb2,gs_hamkq%nspinor**2,rf_hamk_idir%cplex)) 686 enl_temp(:,:,:,:) = rf_hamk_idir%e1kbfr(:,:,:,:) + rf_hamk_idir%e1kbsc(:,:,:,:) 687 enl_ptr => enl_temp 688 else if (associated(rf_hamk_idir%e1kbfr)) then 689 enl_ptr => rf_hamk_idir%e1kbfr 690 end if 691 692 iatom = gs_hamkq%atindx(ipert - natom - 11) ! Atoms are type-sorted in enlout() 693 694 ! Compute application of dS/dtau1 to i*d[cwavef]/dk2 695 ! sum_{i,j} s_ij < psi^(0) | d(|p_i><p_j|)/dtau(idir1) | i*psi^(k(idir2)) > 696 cpopt=-1 ; choice=2 ; paw_opt=3 ; nnlout=3*natom 697 call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,& 698 & paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum) 699 dotr2 = enlout(3*(iatom-1)+idir1) 700 701 ! Compute part of H^(2) due to derivative of projectors (idir1) and derivative of Dij (idir2) 702 ! sum_{i,j} chi_ij(idir2) < psi^(0) | d(|p_i><p_j|)/dtau(idir1) | psi^(0) > 703 cpopt=-1 ; choice=2 ; paw_opt=1 ; nnlout=3*natom 704 call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,& 705 & paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum,enl=enl_ptr) 706 dotr2 = dotr2 + enlout(3*(iatom-1)+idir1) 707 708 ! Compute derivatives due to projectors |d^2[p_i]/dtau1dk2>,|d[p_i]/dtau1>,|d[p_i]/dk2> 709 ! i * sum_{i,j} < psi^(0) | (d(|p_i><dp_j/dk(idir2)|)/dtau(idir1) | psi^(0) > 710 cpopt=-1 ; choice=54 ; paw_opt=3 ; nnlout=18*natom 711 call nonlop(choice,cpopt,cprj_empty,enlout,gs_hamkq,idir_dum,(/zero/),mpi_enreg,1,nnlout,& 712 & paw_opt,signs,svectout_dum,tim_nonlop,cwave_j,svectout_dum) 713 dotr2 = dotr2 - enlout(18*(iatom-1)+2*idirc ) 714 doti2 = doti2 + enlout(18*(iatom-1)+2*idirc-1) 715 716 end if ! PERT_PHON_ELFD 717 718 dotr = dotr - dotr2 719 doti = doti - doti2 720 dotr = sqrt(dotr**2+doti**2) 721 if (dotr > 10*tol_test) then 722 write(msg,'(a,es17.8E3)') 'RF2 TEST GETGH2C : NOT PASSED dotr = ',dotr 723 call wrtout(ab_out,msg) 724 call wrtout(std_out,msg) 725 end if 726 727 ! Change the pointer ffnl_k back to ffnl1 (idir_ffnl=4, for nonlop with signs=2) 728 call gs_hamkq%load_k(ffnl_k=ffnl1) 729 730 if (associated(enl_ptr)) then 731 nullify(enl_ptr) 732 end if 733 if (allocated(enl_temp)) then 734 ABI_FREE(enl_temp) 735 end if 736 737 end if ! end tests 738 ! ******************************************************************************************* 739 740 call getgh2c(cwave,cwaveprj,h_cwave,s_cwave,gs_hamkq,gvnlx1,idir,ipert,zero,& 741 mpi_enreg,optlocal,optnl,opt_gvnl2,rf_hamk_idir,sij_opt,tim_getgh2c,usevnl,& 742 conj=compute_conjugate,enl=enl) 743 744 else 745 746 h_cwave = zero 747 ABI_ERROR(" rf2_apply_hamiltonian can be used only for: 0<=ipert<=natom+2 and natom+10<=ipert<=2*natom+11.") 748 return 749 750 end if 751 752 DBG_EXIT("COLL") 753 754 end subroutine rf2_apply_hamiltonian
m_rf2/rf2_destroy [ Functions ]
[ Top ] [ m_rf2 ] [ Functions ]
NAME
rf2_init
FUNCTION
Free all allocated arrays in a rf2_t object
INPUTS
rf2 : the rf2_t object to destroy
OUTPUT
NOTES
SOURCE
775 subroutine rf2_destroy(rf2) 776 777 !Arguments --------------------------------------------- 778 !scalars 779 type(rf2_t),intent(inout) :: rf2 780 !arrays 781 782 !Local variables --------------------------------------- 783 !scalars 784 785 ! ************************************************************************* 786 787 if (associated(rf2%RHS_Stern)) then 788 ABI_FREE(rf2%RHS_Stern) 789 end if 790 if (allocated(rf2%dcwavef)) then 791 ABI_FREE(rf2%dcwavef) 792 end if 793 if (allocated(rf2%amn)) then 794 ABI_FREE(rf2%amn) 795 end if 796 if (allocated(rf2%lambda_mn)) then 797 ABI_FREE(rf2%lambda_mn) 798 end if 799 800 end subroutine rf2_destroy
m_rf2/rf2_getidir [ Functions ]
[ Top ] [ m_rf2 ] [ Functions ]
NAME
rf2_getidir
FUNCTION
Get the direction of the 2nd order perturbation according to inputs idir1 and idir2
INPUTS
idir1 : index of the 1st direction (1<=idir1<=3) idir2 : index of the 2nd direction (1<=idir2<=3)
OUTPUT
idir : integer between 1 and 9
NOTES
SOURCE
148 subroutine rf2_getidir(idir1,idir2,idir) 149 150 !Arguments --------------------------------------------- 151 !scalars 152 integer,intent(in) :: idir1,idir2 153 integer,intent(out) :: idir 154 integer :: dir_from_dirs(9) = (/1,6,5,9,2,4,8,7,3/) 155 156 ! ************************************************************************* 157 158 idir = dir_from_dirs(3*(idir1-1)+idir2) 159 160 end subroutine rf2_getidir
m_rf2/rf2_getidirs [ Functions ]
[ Top ] [ m_rf2 ] [ Functions ]
NAME
rf2_getidirs
FUNCTION
Get directions of the 1st and 2nd perturbations according to the input idir
INPUTS
idir : integer between 1 and 9
OUTPUT
idir1 : index of the 1st direction (1<=idir1<=3) idir2 : index of the 2nd direction (1<=idir2<=3)
NOTES
SOURCE
183 subroutine rf2_getidirs(idir,idir1,idir2) 184 185 !Arguments --------------------------------------------- 186 !scalars 187 integer,intent(in) :: idir 188 integer,intent(out) :: idir1,idir2 189 190 ! ************************************************************************* 191 192 select case(idir) 193 ! Diagonal terms : 194 case(1) 195 idir1 = 1 196 idir2 = 1 197 case(2) 198 idir1 = 2 199 idir2 = 2 200 case(3) 201 idir1 = 3 202 idir2 = 3 203 ! Upper triangular terms : 204 case(4) 205 idir1 = 2 206 idir2 = 3 207 case(5) 208 idir1 = 1 209 idir2 = 3 210 case(6) 211 idir1 = 1 212 idir2 = 2 213 ! Lower triangular terms : 214 case(7) 215 idir1 = 3 216 idir2 = 2 217 case(8) 218 idir1 = 3 219 idir2 = 1 220 case(9) 221 idir1 = 2 222 idir2 = 1 223 end select 224 225 end subroutine rf2_getidirs
m_rf2/rf2_t [ Types ]
NAME
rf2_t
FUNCTION
Datatype gathering all needed data for the computation of the 2nd order Sternheimer equation.
SOURCE
54 type,public :: rf2_t 55 56 !scalars 57 integer :: ndir ! number of directions to consider 58 integer :: nband_k ! number of bands 59 integer :: size_wf ! number of components in a wavefunction 60 integer :: size_cprj ! number of components of a cprj variable (i.e. <p_i|WF>) 61 62 !arrays 63 integer :: iperts(2) ! perturbations to compute 64 ! ipert = natom + 10 : 65 ! iperts(1) = iperts(2) = natom+1 (wavevector k) 66 ! 67 ! ipert = natom + 11 : 68 ! iperts(1) = natom+1 (wavevector k) 69 ! iperts(2) = natom+2 (electric field) 70 71 integer :: idirs(2) ! directions of the perturbations (ndir=1 : idirs(1)=idirs(2) , ndir=2 : idirs(1)/=idirs(2)) 72 73 real(dp), ABI_CONTIGUOUS pointer :: RHS_Stern(:,:) => null() ! need a pointer because is a ptr target 74 ! Right-hand side of the 2nd order Sternheimer equation, for every bands. 75 ! Namely, for a band "n" : 76 ! |(RHS_Stern)_n> = (H^(2)-epsilon_n S^(2)) |u^(0)_n> + 2(H^(1)-epsilon_n S^(1))|u^(1)_n> 77 ! - 2 sum_m ( lambda_mn^(1) ( S^(1) |u^(0)_m> + S^(0) |u^(1)_m> ) 78 ! ( /!\ : in the sum, the index m runs over occupied bands ) 79 ! where : 80 ! - epsilon_n = eigenvalue of the GS Hamiltonian 81 ! - lambda_mn^(1) = <u^(0)_m| (H^(1)-(epsilon_n+epsilon_m)/2 S^(1) |u^(0)_n> (1st order Lagrange multiplier) 82 ! - X^(2) = d^2X/(dk_dir1 dlambda_dir2) 83 ! - 2X^(1)Y^(1) = dX/dk_dir1 dY/dlambda_dir2 + dX/dlambda_dir2 dY/dk_dir1 84 ! lambda_dir2 = k_dir2 (ipert==natom+10) , E_dir2 (ipert==natom+11) 85 ! Note : P_c^* will be apply to |(RHS_Stern)_n> in dfpt_cgwf.F90 86 ! ** 87 ! Computed in "rf2_init" 88 89 real(dp),allocatable :: amn(:,:) 90 ! Scalar needed for the "orhtonormalization condition", see "dcwavef(:,:)" below 91 ! Namely : 92 ! A_mn = <u^(0)_m| S^(2) |u^(0)_n> + 2 <u^(1)_m| S^(0) |u^(1)_n> 93 ! + 2 <u^(1)_m| S^(1) |u^(0)_n> + 2 <u^(0)_m| S^(1) |u^(1)_n> 94 ! ** 95 ! Computed in "rf2_init", stored only for testing purposes 96 97 real(dp),allocatable :: dcwavef(:,:) 98 ! Vector needed to enforce the "orhtonormalization condition" on 2nd order wave functions. 99 ! Namely : 100 ! |dcwavef_n> = -1/2 sum_m A_mn |u^(0)_m> 101 ! ** 102 ! Computed in "rf2_init" 103 104 real(dp),allocatable :: lambda_mn(:,:) 105 ! 2nd order Lagrange multiplier. 106 ! Namely : 107 ! lambda_mn = <u^(0)_m| H^(2) |u^(0)_n> + 2 <u^(1)_m| H^(0) |u^(1)_n> 108 ! + 2 <u^(1)_m| H^(1) |u^(0)_n> + 2 <u^(0)_m| H^(1) |u^(1)_n> 109 ! - A_mn * (epsilon_m + epsilon_n) / 2 110 ! ** 111 ! Computed in "rf2_init" 112 113 end type rf2_t 114 115 public :: rf2_getidir 116 public :: rf2_getidirs 117 public :: rf2_accumulate_bands 118 public :: rf2_apply_hamiltonian 119 public :: rf2_destroy