1 2! Tangled code 3module m_pexsi_solver 4 5 use precision, only : dp 6 7 implicit none 8 9 real(dp), save :: prevDmax ! For communication of max diff in DM in scf loop 10 ! used in the heuristics for N_el tolerance 11 public :: prevDmax 12#ifdef SIESTA__PEXSI 13 public :: pexsi_solver 14 15CONTAINS 16 17! This version uses separate distributions for Siesta 18! (setup_H et al) and PEXSI. 19! 20subroutine pexsi_solver(iscf, no_u, no_l, nspin_in, & 21 maxnh, numh, listhptr, listh, H, S, qtot, DM, EDM, & 22 ef, Entropy, temp, delta_Efermi) 23 24 use fdf 25 use parallel, only : SIESTA_worker, BlockSize 26 use parallel, only : SIESTA_Group, SIESTA_Comm 27 use m_mpi_utils, only: globalize_sum, globalize_max 28 use m_mpi_utils, only: broadcast 29 use units, only: Kelvin, eV 30 use m_redist_spmatrix, only: aux_matrix, redistribute_spmatrix 31 use class_Distribution 32 use alloc, only: re_alloc, de_alloc 33 use siesta_options, only: dDtol 34#ifdef MPI 35 use mpi_siesta 36#endif 37use f_ppexsi_interface 38use iso_c_binding 39use m_pexsi, only: plan, pexsi_initialize_scfloop 40 41#ifdef TRACING_SOLVEONLY 42 use extrae_module 43#endif 44 45 implicit none 46 47 integer, intent(in) :: iscf ! scf step number 48 integer, intent(in) :: maxnh, no_u, no_l, nspin_in 49 integer, intent(in), target :: listh(maxnh), numh(no_l), listhptr(no_l) 50 real(dp), intent(in), target :: H(maxnh,nspin_in), S(maxnh) 51 real(dp), intent(in) :: qtot 52 real(dp), intent(out), target:: DM(maxnh,nspin_in), EDM(maxnh,nspin_in) 53 real(dp), intent(out) :: ef ! Fermi energy 54 real(dp), intent(out) :: Entropy ! Entropy/k, dimensionless 55 real(dp), intent(in) :: temp ! Electronic temperature 56 real(dp), intent(in) :: delta_Efermi ! Estimated shift in E_fermi 57integer :: ih, i 58integer :: info 59logical :: write_ok 60!------------ 61external :: timer 62integer :: World_Comm, mpirank, ierr 63! 64real(dp) :: temperature, numElectronExact 65integer :: norbs, scf_step 66real(dp) :: delta_Ef 67! 68integer :: nspin 69integer :: PEXSI_Pole_Group, PEXSI_Spatial_Group, World_Group 70integer, allocatable :: pexsi_pole_ranks_in_world(:) 71integer :: nworkers_SIESTA 72integer, allocatable :: siesta_ranks_in_world(:) 73integer :: PEXSI_Pole_Group_in_World 74integer, allocatable :: PEXSI_Pole_ranks_in_World_Spin(:,:) 75integer :: PEXSI_Pole_Comm, PEXSI_Spatial_Comm, PEXSI_Spin_Comm 76integer :: numNodesTotal 77integer :: npPerPole 78logical :: PEXSI_worker 79! 80type(Distribution) :: dist1 81type(Distribution), allocatable, target :: dist2_spin(:) 82type(Distribution), pointer :: dist2 83integer :: pbs, color, spatial_rank, spin_rank 84type(aux_matrix), allocatable, target :: m1_spin(:) 85type(aux_matrix) :: m2 86type(aux_matrix), pointer :: m1 87integer :: nrows, nnz, nnzLocal, numColLocal 88integer, pointer, dimension(:) :: colptrLocal=> null(), rowindLocal=>null() 89! 90real(dp), pointer, dimension(:) :: & 91 HnzvalLocal=>null(), SnzvalLocal=>null(), & 92 DMnzvalLocal => null() , EDMnzvalLocal => null(), & 93 FDMnzvalLocal => null() 94! 95integer :: ispin, pexsi_spin 96real(dp), save :: PEXSINumElectronToleranceMin, & 97 PEXSINumElectronToleranceMax, & 98 PEXSINumElectronTolerance 99logical, save :: first_call = .true. 100real(dp), save :: muMin0, muMax0, mu 101real(dp) :: on_the_fly_tolerance 102type(f_ppexsi_options) :: options 103! 104integer :: isSIdentity 105integer :: verbosity 106integer :: inertiaMaxIter 107! 108real(dp), save :: energyWidthInertiaTolerance 109real(dp) :: pexsi_temperature, two_kT 110real(dp), allocatable :: numElectronSpin(:), numElectronDrvMuSpin(:) 111integer :: numTotalPEXSIIter 112integer :: numTotalInertiaIter 113real(dp) :: numElectronDrvMuPEXSI, numElectronPEXSI 114real(dp) :: numElectron_out, numElectronDrvMu_out 115real(dp) :: deltaMu 116real(dp) :: bs_energy, eBandH, free_bs_energy 117real(dp) :: buffer1 118real(dp), save :: previous_pexsi_temperature 119! -------- for serial compilation 120#ifndef MPI 121 call die("PEXSI needs MPI") 122#else 123! 124! Our global communicator is a duplicate of the passed communicator 125! 126call MPI_Comm_Dup(true_MPI_Comm_World, World_Comm, ierr) 127call mpi_comm_rank( World_Comm, mpirank, ierr ) 128 129! NOTE: fdf calls will assign values to the whole processor set, 130! but some other variables will have to be re-broadcast (see examples 131! below) 132 133call timer("pexsi", 1) 134 135if (SIESTA_worker) then 136 137 ! rename some intent(in) variables, which are only 138 ! defined for the Siesta subset 139 140 norbs = no_u 141 nspin = nspin_in 142 scf_step = iscf 143 delta_Ef = delta_Efermi 144 numElectronExact = qtot 145 146 ! Note that the energy units for the PEXSI interface are arbitrary, but 147 ! H, the interval limits, and the temperature have to be in the 148 ! same units. Siesta uses Ry units. 149 150 temperature = temp 151 152 if (mpirank==0) write(6,"(a,f10.2)") & 153 "Electronic temperature (K): ", temperature/Kelvin 154endif 155! 156call broadcast(norbs,comm=World_Comm) 157call broadcast(scf_step,comm=World_Comm) 158call broadcast(delta_Ef,comm=World_Comm) 159call broadcast(numElectronExact,World_Comm) 160call broadcast(temperature,World_Comm) 161call broadcast(nspin,World_Comm) 162! Imported from modules, but set only in Siesta side 163call broadcast(prevDmax,comm=World_Comm) 164call broadcast(dDtol,comm=World_Comm) 165call MPI_Comm_Group(World_Comm,World_Group, ierr) 166call MPI_Group_Size(SIESTA_Group, nworkers_SIESTA, ierr) 167allocate(siesta_ranks_in_world(nworkers_SIESTA)) 168call MPI_Group_translate_ranks( SIESTA_Group, nworkers_SIESTA, & 169 (/ (i,i=0,nworkers_SIESTA-1) /), & 170 World_Group, siesta_ranks_in_world, ierr ) 171call newDistribution(dist1,World_Comm,siesta_ranks_in_world, & 172 TYPE_BLOCK_CYCLIC,BlockSize,"bc dist") 173deallocate(siesta_ranks_in_world) 174call MPI_Barrier(World_Comm,ierr) 175 176call mpi_comm_size( World_Comm, numNodesTotal, ierr ) 177 178npPerPole = fdf_get("PEXSI.np-per-pole",4) 179if (nspin*npPerPole > numNodesTotal) & 180 call die("PEXSI.np-per-pole is too big for MPI size") 181 182! "Row" communicator for independent PEXSI operations on each spin 183! The name refers to "spatial" degrees of freedom. 184color = mod(mpirank,nspin) ! {0,1} for nspin = 2, or {0} for nspin = 1 185call MPI_Comm_Split(World_Comm, color, mpirank, PEXSI_Spatial_Comm, ierr) 186 187! "Column" communicator for spin reductions 188color = mpirank/nspin 189call MPI_Comm_Split(World_Comm, color, mpirank, PEXSI_Spin_Comm, ierr) 190 191! Group and Communicator for first-pole team of PEXSI workers 192! 193call MPI_Comm_Group(PEXSI_Spatial_Comm, PEXSI_Spatial_Group, Ierr) 194call MPI_Group_incl(PEXSI_Spatial_Group, npPerPole, & 195 (/ (i,i=0,npPerPole-1) /),& 196 PEXSI_Pole_Group, Ierr) 197call MPI_Comm_create(PEXSI_Spatial_Comm, PEXSI_Pole_Group,& 198 PEXSI_Pole_Comm, Ierr) 199 200 201call mpi_comm_rank( PEXSI_Spatial_Comm, spatial_rank, ierr ) 202call mpi_comm_rank( PEXSI_Spin_Comm, spin_rank, ierr ) 203PEXSI_worker = (spatial_rank < npPerPole) ! Could be spin up or spin down 204 205! PEXSI blocksize 206pbs = norbs/npPerPole 207 208 209allocate(pexsi_pole_ranks_in_world(npPerPole)) 210call MPI_Comm_Group(World_Comm, World_Group, Ierr) 211 212call MPI_Group_translate_ranks( PEXSI_Pole_Group, npPerPole, & 213 (/ (i,i=0,npPerPole-1) /), & 214 World_Group, pexsi_pole_ranks_in_world, ierr ) 215 216! Include the actual world ranks in the distribution object 217 218allocate (PEXSI_Pole_ranks_in_World_Spin(npPerPole,nspin)) 219call MPI_AllGather(pexsi_pole_ranks_in_world,npPerPole,MPI_integer,& 220 PEXSI_Pole_Ranks_in_World_Spin(1,1),npPerPole, & 221 MPI_integer,PEXSI_Spin_Comm,ierr) 222 223! Create distributions known to all nodes 224allocate(dist2_spin(nspin)) 225do ispin = 1, nspin 226 call newDistribution(dist2_spin(ispin), World_Comm, & 227 PEXSI_Pole_Ranks_in_World_Spin(:,ispin), & 228 TYPE_PEXSI, pbs, "px dist") 229enddo 230deallocate(pexsi_pole_ranks_in_world,PEXSI_Pole_Ranks_in_World_Spin) 231call MPI_Barrier(World_Comm,ierr) 232 233pexsi_spin = spin_rank+1 ! {1,2} 234! This is done serially on the Siesta side, each time 235! filling in the structures in one PEXSI set 236 237allocate(m1_spin(nspin)) 238do ispin = 1, nspin 239 240 m1 => m1_spin(ispin) 241 242 if (SIESTA_worker) then 243 m1%norbs = norbs 244 m1%no_l = no_l 245 m1%nnzl = sum(numH(1:no_l)) 246 m1%numcols => numH 247 m1%cols => listH 248 allocate(m1%vals(2)) 249 m1%vals(1)%data => S(:) 250 m1%vals(2)%data => H(:,ispin) 251 252 endif ! SIESTA_worker 253 254 call timer("redist_orbs_fwd", 1) 255 256 ! Note that we cannot simply wrap this in a pexsi_spin test, as 257 ! there are Siesta nodes in both spin sets. 258 ! We must discriminate the PEXSI workers by the distribution info 259 dist2 => dist2_spin(ispin) 260 call redistribute_spmatrix(norbs,m1,dist1,m2,dist2,World_Comm) 261 262 call timer("redist_orbs_fwd", 2) 263 264 if (PEXSI_worker .and. (pexsi_spin == ispin) ) then 265 266 nrows = m2%norbs ! or simply 'norbs' 267 numColLocal = m2%no_l 268 nnzLocal = m2%nnzl 269 call MPI_AllReduce(nnzLocal,nnz,1,MPI_integer,MPI_sum,PEXSI_Pole_Comm,ierr) 270 271 call re_alloc(colptrLocal,1,numColLocal+1,"colptrLocal","pexsi_solver") 272 colptrLocal(1) = 1 273 do ih = 1,numColLocal 274 colptrLocal(ih+1) = colptrLocal(ih) + m2%numcols(ih) 275 enddo 276 277 rowindLocal => m2%cols 278 SnzvalLocal => m2%vals(1)%data 279 HnzvalLocal => m2%vals(2)%data 280 281 call re_alloc(DMnzvalLocal,1,nnzLocal,"DMnzvalLocal","pexsi_solver") 282 call re_alloc(EDMnzvalLocal,1,nnzLocal,"EDMnzvalLocal","pexsi_solver") 283 call re_alloc(FDMnzvalLocal,1,nnzLocal,"FDMnzvalLocal","pexsi_solver") 284 285 call memory_all("after setting up H+S for PEXSI (PEXSI_workers)",PEXSI_Pole_Comm) 286 287 endif ! PEXSI worker 288enddo 289 290! Make these available to all 291! (Note that the values are those on process 0, which is in the spin=1 set 292! In fact, they are only needed for calls to the interface, so the broadcast 293! could be over PEXSI_Spatial_Comm only. 294 295call MPI_Bcast(nrows,1,MPI_integer,0,World_Comm,ierr) 296call MPI_Bcast(nnz,1,MPI_integer,0,World_Comm,ierr) 297 298call memory_all("after setting up H+S for PEXSI",World_comm) 299 300if (first_call) then 301 302! Initial guess of chemical potential and containing interval 303! When using inertia counts, this interval can be wide. 304! Note that mu, muMin0 and muMax0 are saved variables 305 306 muMin0 = fdf_get("PEXSI.mu-min",-1.0_dp,"Ry") 307 muMax0 = fdf_get("PEXSI.mu-max", 0.0_dp,"Ry") 308 mu = fdf_get("PEXSI.mu",-0.60_dp,"Ry") 309 310 PEXSINumElectronToleranceMin = & 311 fdf_get("PEXSI.num-electron-tolerance-lower-bound",0.01_dp) 312 PEXSINumElectronToleranceMax = & 313 fdf_get("PEXSI.num-electron-tolerance-upper-bound",0.5_dp) 314 315 ! start with largest tolerance 316 ! (except if overriden by user) 317 PEXSINumElectronTolerance = fdf_get("PEXSI.num-electron-tolerance",& 318 PEXSINumElectronToleranceMax) 319 first_call = .false. 320else 321! 322! Here we could also check whether we are in the first scf iteration 323! of a multi-geometry run... 324! 325 ! Use a moving tolerance, based on how far DM_out was to DM_in 326 ! in the previous iteration (except if overriden by user) 327 328 call get_on_the_fly_tolerance(prevDmax,on_the_fly_tolerance) 329 330 ! Override if tolerance is explicitly specified in the fdf file 331 PEXSINumElectronTolerance = fdf_get("PEXSI.num-electron-tolerance",& 332 on_the_fly_tolerance) 333endif 334! 335call f_ppexsi_set_default_options( options ) 336 337options%muPEXSISafeGuard = fdf_get("PEXSI.mu-pexsi-safeguard",0.05_dp,"Ry") 338options%maxPEXSIIter = fdf_get("PEXSI.mu-max-iter",10) 339 340isSIdentity = 0 341 342options%numPole = fdf_get("PEXSI.num-poles",40) 343options%gap = fdf_get("PEXSI.gap",0.0_dp,"Ry") 344 345! deltaE is in theory the spectrum width, but in practice can be much smaller 346! than | E_max - mu |. It is found that deltaE that is slightly bigger 347! than | E_min - mu | is usually good enough. 348 349options%deltaE = fdf_get("PEXSI.delta-E",3.0_dp,"Ry") ! Lin: 10 Ry... 350 351! Ordering flag: 352! 1: Use METIS 353! 0: Use PARMETIS/PTSCOTCH 354options%ordering = fdf_get("PEXSI.ordering",1) 355 356! Number of processors for symbolic factorization 357! Only relevant for PARMETIS/PT_SCOTCH 358options%npSymbFact = fdf_get("PEXSI.np-symbfact",1) 359 360verbosity = fdf_get("PEXSI.verbosity",1) 361options%verbosity = verbosity 362 363call get_current_temperature(pexsi_temperature) 364options%temperature = pexsi_temperature 365! 366! Set guard smearing for later use 367! 368two_kT = 2.0_dp * pexsi_temperature 369 370options%numElectronPEXSITolerance = PEXSINumElectronTolerance 371 372! Stop inertia count if mu has not changed much from iteration to iteration. 373 374options%muInertiaTolerance = & 375 fdf_get("PEXSI.inertia-mu-tolerance",0.05_dp,"Ry") 376 377! One-sided expansion of interval if correct mu falls outside it 378options%muInertiaExpansion = & 379 fdf_get("PEXSI.lateral-expansion-inertia",3.0_dp*eV,"Ry") 380 381 382! Other user options 383 384! Maximum number of iterations for computing the inertia 385! in a given scf step (until a proper bracket is obtained) 386inertiaMaxIter = fdf_get("PEXSI.inertia-max-iter",5) 387 388! Energy-width termination tolerance for inertia-counting 389! By default, it is the same as the mu tolerance, to match 390! the criterion in the simple DFT driver 391energyWidthInertiaTolerance = & 392 fdf_get("PEXSI.inertia-energy-width-tolerance", & 393 options%muInertiaTolerance,"Ry") 394if (scf_step == 1) then 395 call pexsi_initialize_scfloop(PEXSI_Spatial_Comm,npPerPole,spatial_rank,info) 396 call check_info(info,"initialize_plan") 397endif 398call f_ppexsi_load_real_symmetric_hs_matrix(& 399 plan,& 400 options,& 401 nrows,& 402 nnz,& 403 nnzLocal,& 404 numColLocal,& 405 colptrLocal,& 406 rowindLocal,& 407 HnzvalLocal,& 408 isSIdentity,& 409 SnzvalLocal,& 410 info) 411 412call check_info(info,"load_real_sym_hs_matrix") 413 414 415if (scf_step == 1) then 416 ! This is only needed for inertia-counting 417 call f_ppexsi_symbolic_factorize_real_symmetric_matrix(& 418 plan, & 419 options,& 420 info) 421 call check_info(info,"symbolic_factorize_real_symmetric_matrix") 422 423 call f_ppexsi_symbolic_factorize_complex_symmetric_matrix(& 424 plan, & 425 options,& 426 info) 427 call check_info(info,"symbolic_factorize_complex_symmetric_matrix") 428endif 429options%isSymbolicFactorize = 0 ! We do not need it anymore 430! 431numTotalInertiaIter = 0 432 433call timer("pexsi-solver", 1) 434 435if (need_inertia_counting()) then 436 call get_bracket_for_inertia_count( ) 437 call do_inertia_count(plan,muMin0,muMax0,mu) 438else 439 ! Maybe there is no need for bracket, just for mu estimation 440 call get_bracket_for_solver() 441endif 442 443numTotalPEXSIIter = 0 444allocate(numElectronSpin(nspin),numElectronDrvMuSpin(nspin)) 445 446solver_loop: do 447 if (numTotalPEXSIIter > options%maxPEXSIIter ) then 448 ! Do not die immediately, and trust further DM normalization 449 ! to fix the number of electrons for unstable cases 450 ! call die("too many PEXSI iterations") 451 if (mpirank == 0) then 452 write(6,"(a)") " ** Maximum number of PEXSI-solver iterations reached without convergence" 453 write(6,"(a)") " .... an attempt will be made to normalize the density-matrix" 454 write(6,"(a)") " This will succeed or not depending on the normalization tolerance (see manual)" 455 endif 456 endif 457 if(mpirank == 0) then 458 write (6,"(a,f9.4,a,f9.5)") 'Computing DM for mu(eV): ', mu/eV, & 459 ' Tol: ', PEXSINumElectronTolerance 460 write (6,"(a,f9.4,f9.5)") 'Monitoring bracket: ', muMin0/eV, muMax0/eV 461 endif 462 463 call f_ppexsi_calculate_fermi_operator_real(& 464 plan,& 465 options,& 466 mu,& 467 numElectronExact,& 468 numElectron_out,& 469 numElectronDrvMu_out,& 470 info) 471 472 call check_info(info,"fermi_operator") 473 474 ! Per spin 475 numElectron_out = numElectron_out / nspin 476 numElectronDrvMu_out = numElectronDrvMu_out / nspin 477 478 ! Gather the results for both spins on all processors 479 480 call MPI_AllGather(numElectron_out,1,MPI_Double_precision,& 481 numElectronSpin,1,MPI_Double_precision,PEXSI_Spin_Comm,ierr) 482 call MPI_AllGather(numElectronDrvMu_out,1,MPI_Double_precision,& 483 numElectronDrvMuSpin,1,MPI_Double_precision,PEXSI_Spin_Comm,ierr) 484 485 numElectronPEXSI = sum(numElectronSpin(1:nspin)) 486 numElectronDrvMuPEXSI = sum(numElectronDrvMuSpin(1:nspin)) 487 488 if (mpirank == 0) then 489 write(6,"(a,f10.4)") "Fermi Operator. mu: ", mu/eV 490 if (nspin == 2) then 491 write(6,"(a,2f10.4,a,f10.4)") "Fermi Operator. numElectron(Up,Down): ", & 492 numElectronSpin(1:nspin), " Total: ", numElectronPEXSI 493 write(6,"(a,2f10.4,a,f10.4)") "Fermi Operator. dN_e/dmu(Up,Down): ", & 494 numElectronDrvMuSpin(1:nspin)*eV, " Total: ", numElectronDrvMuPEXSI*eV 495 else 496 write(6,"(a,f10.4)") "Fermi Operator. numElectron: ", numElectronPEXSI 497 write(6,"(a,f10.4)") "Fermi Operator. dN_e/dmu: ", numElectronDrvMuPEXSI*eV 498 endif 499 endif 500 numTotalPEXSIIter = numTotalPEXSIIter + 1 501 if (abs(numElectronPEXSI-numElectronExact) > PEXSINumElectronTolerance) then 502 503 deltaMu = - (numElectronPEXSI - numElectronExact) / numElectronDrvMuPEXSI 504 ! The simple DFT driver uses the size of the jump to flag problems: 505 ! if (abs(deltaMu) > options%muPEXSISafeGuard) then 506 507 if ( ((mu + deltaMu) < muMin0) .or. ((mu + deltaMu) > muMax0) ) then 508 if (mpirank ==0) then 509 write(6,"(a,f9.3)") "DeltaMu: ", deltaMu, " is too big. Falling back to IC" 510 endif 511 512 ! We choose for now to expand the bracket to include the jumped-to point 513 514 muMin0 = min(muMin0,mu+deltaMu) 515 muMax0 = max(muMax0,mu+deltaMu) 516 517 call do_inertia_count(plan,muMin0,muMax0,mu) 518 519 cycle solver_loop 520 521 endif 522 mu = mu + deltaMu 523 cycle solver_loop 524 else 525 ! Converged 526 if (mpirank == 0) then 527 write(6,"(a,f10.4)") "PEXSI solver converged. mu: ", mu/eV 528 endif 529 exit solver_loop 530 endif 531end do solver_loop 532 533deallocate(numElectronSpin,numElectronDrvMuSpin) 534call timer("pexsi-solver", 2) 535 536 537if( PEXSI_worker ) then 538 call f_ppexsi_retrieve_real_symmetric_dft_matrix(& 539 plan,& 540 DMnzvalLocal,& 541 EDMnzvalLocal,& 542 FDMnzvalLocal,& 543 eBandH,& ! Will not be available 544 bs_energy,& 545 free_bs_energy,& 546 info) 547 call check_info(info,"retrieve_real_symmetric_dft_matrix") 548 549 if (nspin == 2) then 550 ! The matrices have to be divided by two... 551 DMnzvalLocal(:) = 0.5_dp * DMnzvalLocal(:) 552 EDMnzvalLocal(:) = 0.5_dp * EDMnzvalLocal(:) 553 !!! Watch out with this. Internals?? 554 FDMnzvalLocal(:) = 0.5_dp * FDMnzvalLocal(:) 555 endif 556 557endif 558 559if ((mpirank == 0) .and. (verbosity >= 1)) then 560 write(6,"(a,i3)") " #&s Number of solver iterations: ", numTotalPEXSIIter 561 write(6,"(a,i3)") " #&s Number of inertia iterations: ", numTotalInertiaIter 562 write(6,"(a,f12.5,f12.4,2x,a2)") "mu, N_e:", mu/eV, & 563 numElectronPEXSI, "&s" 564endif 565 566if (PEXSI_worker) then 567 568 free_bs_energy = 0.0_dp 569 bs_energy = 0.0_dp 570 eBandH = 0.0_dp 571 do i = 1,nnzLocal 572 free_bs_energy = free_bs_energy + SnzvalLocal(i) * & 573 ( FDMnzvalLocal(i) ) 574 bs_energy = bs_energy + SnzvalLocal(i) * & 575 ( EDMnzvalLocal(i) ) 576 eBandH = eBandH + HnzvalLocal(i) * & 577 ( DMnzvalLocal(i) ) 578 enddo 579 580 ! First, reduce over the Pole_comm 581 582 call globalize_sum( free_bs_energy, buffer1, comm=PEXSI_Pole_Comm ) 583 free_bs_energy = buffer1 584 call globalize_sum( bs_energy, buffer1, comm=PEXSI_Pole_Comm ) 585 bs_energy = buffer1 586 call globalize_sum( eBandH, buffer1, comm=PEXSI_Pole_Comm ) 587 eBandH = buffer1 588 589 ! Now, reduce over both spins 590 591 call globalize_sum( free_bs_energy, buffer1, comm=PEXSI_Spin_Comm ) 592 ! Note that we need an extra term: mu*N for the free energy 593 free_bs_energy = buffer1 + mu*numElectronPEXSI 594 call globalize_sum( bs_energy, buffer1, comm=PEXSI_Spin_Comm ) 595 bs_energy = buffer1 596 call globalize_sum( eBandH, buffer1, comm=PEXSI_Spin_Comm ) 597 eBandH = buffer1 598 599 ! This output block will be executed only if World's root node is 600 ! in one of the leading pole groups. This might not be so 601 602 if ((mpirank == 0) .and. (verbosity >= 2)) then 603 write(6, "(a,f12.4)") "#&s Tr(S*EDM) (eV) = ", bs_energy/eV 604 write(6,"(a,f12.4)") "#&s Tr(H*DM) (eV) = ", eBandH/eV 605 write(6,"(a,f12.4)") "#&s Tr(S*FDM) + mu*N (eV) = ", (free_bs_energy)/eV 606 endif 607 608 ef = mu 609 ! Note that we use the S*EDM version of the band-structure energy 610 ! to estimate the entropy, by comparing it to S*FDM This looks 611 ! consistent, but note that the EDM is not used in Siesta to 612 ! estimate the total energy, only the DM (via the density) (that 613 ! is, the XC and Hartree correction terms to Ebs going into Etot 614 ! are estimated using the DM) 615 616 Entropy = - (free_bs_energy - bs_energy) / temp 617 618 ! ef and Entropy are now known to the leading-pole processes 619endif ! PEXSI_worker 620 621 622do ispin = 1, nspin 623 624 m1 => m1_spin(ispin) 625 626 if (PEXSI_worker .and. (pexsi_spin == ispin)) then 627 ! Prepare m2 to transfer 628 629 call de_alloc(FDMnzvalLocal,"FDMnzvalLocal","pexsi_solver") 630 call de_alloc(colPtrLocal,"colPtrLocal","pexsi_solver") 631 632 call de_alloc(m2%vals(1)%data,"m2%vals(1)%data","pexsi_solver") 633 call de_alloc(m2%vals(2)%data,"m2%vals(2)%data","pexsi_solver") 634 635 m2%vals(1)%data => DMnzvalLocal(1:nnzLocal) 636 m2%vals(2)%data => EDMnzvalLocal(1:nnzLocal) 637 638 endif 639 640 ! Prepare m1 to receive the results 641 if (SIESTA_worker) then 642 nullify(m1%vals(1)%data) ! formerly pointing to S 643 nullify(m1%vals(2)%data) ! formerly pointing to H 644 deallocate(m1%vals) 645 nullify(m1%numcols) ! formerly pointing to numH 646 nullify(m1%cols) ! formerly pointing to listH 647 endif 648 649 call timer("redist_orbs_bck", 1) 650 dist2 => dist2_spin(ispin) 651 call redistribute_spmatrix(norbs,m2,dist2,m1,dist1,World_Comm) 652 call timer("redist_orbs_bck", 2) 653 654 if (PEXSI_worker .and. (pexsi_spin == ispin)) then 655 call de_alloc(DMnzvalLocal, "DMnzvalLocal", "pexsi_solver") 656 call de_alloc(EDMnzvalLocal,"EDMnzvalLocal","pexsi_solver") 657 658 nullify(m2%vals(1)%data) ! formerly pointing to DM 659 nullify(m2%vals(2)%data) ! formerly pointing to EDM 660 deallocate(m2%vals) 661 ! allocated in the direct transfer 662 call de_alloc(m2%numcols,"m2%numcols","pexsi_solver") 663 call de_alloc(m2%cols, "m2%cols", "pexsi_solver") 664 endif 665 666 ! We assume that Siesta's root node also belongs to one of the 667 ! leading-pole PEXSI communicators. 668 ! Note that by wrapping the broadcasts for SIESTA_workers we 669 ! do not make ef and Entropy known to the non-leading PEXSI processes. 670 671 if (SIESTA_worker) then 672 call broadcast(ef,comm=SIESTA_Comm) 673 call broadcast(Entropy,comm=SIESTA_Comm) 674 ! In future, m1%vals(1,2) could be pointing to DM and EDM, 675 ! and the 'redistribute' routine check whether the vals arrays are 676 ! associated, to use them instead of allocating them. 677 DM(:,ispin) = m1%vals(1)%data(:) 678 EDM(:,ispin) = m1%vals(2)%data(:) 679 ! Check no_l 680 if (no_l /= m1%no_l) then 681 call die("Mismatch in no_l") 682 endif 683 ! Check listH 684 if (any(listH(:) /= m1%cols(:))) then 685 call die("Mismatch in listH") 686 endif 687 688 call de_alloc(m1%vals(1)%data,"m1%vals(1)%data","pexsi_solver") 689 call de_alloc(m1%vals(2)%data,"m1%vals(2)%data","pexsi_solver") 690 deallocate(m1%vals) 691 ! allocated in the direct transfer 692 call de_alloc(m1%numcols,"m1%numcols","pexsi_solver") 693 call de_alloc(m1%cols, "m1%cols", "pexsi_solver") 694 695 endif 696enddo 697call timer("pexsi", 2) 698 699 700 701call delete(dist1) 702do ispin = 1, nspin 703 call delete(dist2_spin(ispin)) 704enddo 705deallocate(dist2_spin) 706deallocate(m1_spin) 707 708call MPI_Comm_Free(PEXSI_Spatial_Comm, ierr) 709call MPI_Comm_Free(PEXSI_Spin_Comm, ierr) 710call MPI_Comm_Free(World_Comm, ierr) 711 712! This communicator was created from a subgroup. 713! As such, it is MPI_COMM_NULL for those processes 714! not in the subgroup (non PEXSI_workers). Only 715! defined communicators can be freed 716if (PEXSI_worker) then 717 call MPI_Comm_Free(PEXSI_Pole_Comm, ierr) 718endif 719 720call MPI_Group_Free(PEXSI_Spatial_Group, ierr) 721call MPI_Group_Free(PEXSI_Pole_Group, ierr) 722call MPI_Group_Free(World_Group, ierr) 723#endif 724 725CONTAINS 726 727subroutine do_inertia_count(plan,muMin0,muMax0,muInertia) 728 use iso_c_binding, only : c_intptr_t 729 use m_convergence 730 731 integer(c_intptr_t) :: plan 732 real(dp), intent(inout) :: muMin0, muMax0 733 real(dp), intent(out) :: muInertia 734 735 real(dp) :: muMinInertia, muMaxInertia 736 integer :: nInertiaRounds 737 738 real(dp), parameter :: eps_inertia = 0.1_dp 739 type(converger_t) :: conv_mu 740 logical :: bad_lower_bound, bad_upper_bound 741 logical :: interval_problem, one_more_round 742 real(dp) :: inertia_electron_width 743 real(dp) :: inertia_original_electron_width 744 real(dp) :: inertia_energy_width 745 real(dp) :: muLower, muUpper 746 integer :: numMinICountShifts, numShift 747 integer :: numNodesSpatial 748 749 real(dp), allocatable :: shiftList(:), inertiaList(:) 750 real(dp), allocatable :: inertiaList_out(:) 751 752 integer :: imin, imax 753 754 755 ! Minimum number of sampling points for inertia counts 756 numMinICountShifts = fdf_get("PEXSI.inertia-min-num-shifts", 10) 757 call mpi_comm_size( PEXSI_Spatial_Comm, numNodesSpatial, ierr ) 758 numShift = numNodesSpatial/npPerPole 759 do 760 if (numShift < numMinICountShifts) then 761 numShift = numShift + numNodesSpatial/npPerPole 762 else 763 exit 764 endif 765 enddo 766 767 allocate(shiftList(numShift), inertiaList(numShift)) 768 allocate(inertiaList_out(numShift)) 769 770 771 nInertiaRounds = 0 772 773 refine_interval: do 774 numTotalInertiaIter = numTotalInertiaIter + 1 775 776 options%muMin0 = muMin0 777 options%muMax0 = muMax0 778 779 if (mpirank == 0) then 780 write (6,"(a,2f9.4,a,a,i4)") 'Calling inertiaCount: [', & 781 muMin0/eV, muMax0/eV, "] (eV)", & 782 " Nshifts: ", numShift 783 endif 784 785 call timer("pexsi-inertia-ct", 1) 786 787 do i = 1, numShift 788 shiftList(i) = muMin0 + (i-1) * (muMax0-muMin0)/(numShift-1) 789 enddo 790 791 call f_ppexsi_inertia_count_real_symmetric_matrix(& 792 plan,& 793 options,& 794 numShift,& 795 shiftList,& 796 inertiaList_out,& 797 info) 798 799 call check_info(info,"inertia-count") 800 801 ! All-Reduce to add the (two) spin inertias 802 ! so that all processors have the complete inertiaList(:) 803 call MPI_AllReduce(inertiaList_out, inertiaList, & 804 numShift, MPI_Double_precision, & 805 MPI_Sum, PEXSI_Spin_Comm, ierr) 806 807 ! If nspin=1, each state is doubly occupied 808 ! 809 inertiaList(:) = 2 * inertiaList(:) / nspin 810 811 812 call timer("pexsi-inertia-ct", 2) 813 814 interval_problem = .false. 815 816 if(mpirank == 0) then 817 bad_lower_bound = (inertiaList(1) > (numElectronExact - 0.1)) 818 bad_upper_bound = (inertiaList(numShift) < (numElectronExact + 0.1)) 819 endif 820 821 call broadcast(bad_lower_bound,comm=World_Comm) 822 call broadcast(bad_upper_bound,comm=World_Comm) 823 824 if (bad_lower_bound) then 825 interval_problem = .true. 826 muMin0 = muMin0 - options%muInertiaExpansion ! 0.5 827 if (mpirank==0) then 828 write (6,"(a,2f12.4,a,2f10.4)") 'Wrong inertia-count interval (lower end). Counts: ', & 829 inertiaList(1), inertiaList(numShift), & 830 ' New interval: ', muMin0/eV, muMax0/eV 831 endif 832 endif 833 if (bad_upper_bound) then 834 interval_problem = .true. 835 muMax0 = muMax0 + options%muInertiaExpansion ! 0.5 836 if (mpirank==0) then 837 write (6,"(a,2f12.4,a,2f10.4)") 'Wrong inertia-count interval (upper end). Counts: ', & 838 inertiaList(1), inertiaList(numShift), & 839 ' New interval: ', muMin0/eV, muMax0/eV 840 endif 841 endif 842 843 if (interval_problem) then 844 ! do nothing more, stay in loop 845 cycle refine_interval 846 endif 847 848 nInertiaRounds = nInertiaRounds + 1 849 850 imin = 1; imax = numShift 851 852 do i = 1, numShift 853 if (inertiaList(i) < numElectronExact - eps_inertia) then 854 imin = max(imin,i) 855 endif 856 if (inertiaList(i) > numElectronExact + eps_inertia) then 857 imax = min(imax,i) 858 endif 859 enddo 860 muMaxInertia = shiftList(imax) 861 muMinInertia = shiftList(imin) 862 863 ! Get the band edges by interpolation 864 muLower = interpolate(inertiaList,shiftList,numElectronExact-eps_inertia) 865 muUpper = interpolate(inertiaList,shiftList,numElectronExact+eps_inertia) 866 867 muInertia = 0.5_dp * (muUpper + muLower) 868 869 if (mpirank == 0) then 870 write (6,"(a,i3,f10.4,i3,f10.4)") 'imin, muMinInertia, imax, muMaxInertia: ',& 871 imin, muMinInertia/eV, imax, muMaxInertia/eV 872 write (6,"(a,2f10.4,a,f10.4)") 'muLower, muUpper: ', muLower/eV, muUpper/eV, & 873 ' mu estimated: ', muInertia/eV 874 endif 875 876 if (mpirank==0) then 877 878 inertia_energy_width = (muMaxInertia - muMinInertia) 879 ! Note that this is the width of the starting interval... 880 inertia_original_electron_width = (inertiaList(numShift) - inertiaList(1)) 881 inertia_electron_width = (inertiaList(imax) - inertiaList(imin)) 882 883 write (6,"(a,2f9.4,a,f9.4,3(a,f10.3))") ' -- new bracket (eV): [', & 884 muMinInertia/eV, muMaxInertia/eV, & 885 "] estimated mu: ", muInertia/eV, & 886 " Nel width: ", inertia_electron_width, & 887 " (Base: ", inertia_original_electron_width, & 888 " ) E width: ", inertia_energy_width/eV 889 890 if (nInertiaRounds == 1) then 891 call reset(conv_mu) 892 call set_tolerance(conv_mu,options%muInertiaTolerance) 893 endif 894 call add_value(conv_mu, muInertia) 895 896 897 one_more_round = .true. 898 899 !!$ if (inertia_original_electron_width < inertiaNumElectronTolerance) then 900 !!$ write (6,"(a)") 'Leaving inertia loop: electron tolerance' 901 !!$ one_more_round = .false. 902 !!$ endif 903 !!$ if (inertia_electron_width < inertiaMinNumElectronTolerance) then 904 !!$ write (6,"(a)") 'Leaving inertia loop: minimum workable electron tolerance' 905 !!$ one_more_round = .false. 906 !!$ endif 907 908 ! This is the first clause of Lin's criterion 909 ! in the simple DFT driver. The second clause is the same as the next one 910 ! when the energy-width tolerance is the same as the mu tolerance (my default) 911 ! I am not sure about the basis for this 912 if (abs(muMaxInertia -numElectronExact) < eps_inertia ) then 913 write (6,"(a,f12.6)") "Leaving inertia loop: |muMaxInertia-N_e|: ", & 914 abs(muMaxInertia -numElectronExact) 915 one_more_round = .false. 916 endif 917 if (inertia_energy_width < energyWidthInertiaTolerance) then 918 write (6,"(a,f12.6)") 'Leaving inertia loop: energy width tolerance: ', & 919 energyWidthInertiaTolerance/eV 920 one_more_round = .false. 921 endif 922 if (is_converged(conv_mu)) then 923 write (6,"(a,f12.6)") 'Leaving inertia loop: mu tolerance: ', options%muInertiaTolerance/eV 924 one_more_round = .false. 925 endif 926 if (nInertiaRounds == inertiaMaxIter) then 927 write (6,"(a)") 'Leaving inertia loop: too many rounds' 928 one_more_round = .false. 929 endif 930 endif 931 call broadcast(one_more_round,comm=World_Comm) 932 933 if (one_more_round) then 934 ! stay in loop 935 ! These values should be guarded, in case the refined interval 936 ! is too tight. Use 2*kT 937 ! 938 muMin0 = muMinInertia - two_kT 939 muMax0 = muMaxInertia + two_kT 940 else 941 exit refine_interval 942 endif 943 944 enddo refine_interval 945 946 deallocate(shiftList,inertiaList) 947 948 end subroutine do_inertia_count 949 950! 951! This routine encodes the heuristics to compute the 952! tolerance dynamically. 953! 954subroutine get_on_the_fly_tolerance(dDmax,tolerance) 955real(dp), intent(in) :: dDmax 956real(dp), intent(out) :: tolerance 957 958real(dp) :: tolerance_preconditioner 959real(dp) :: tolerance_target_factor, tolerance_exp 960real(dp), save :: previous_tolerance 961logical :: new_algorithm 962 963new_algorithm = fdf_get("PEXSI.dynamical-tolerance",.false.) 964! 965! 966if (new_algorithm) then 967 968! By default, the tolerance goes to the (minimum) target 969! at a level 5 times dDtol 970 971 tolerance_target_factor = fdf_get("PEXSI.tolerance-target-factor",5.0_dp) 972 973! 974! This can range in a (0.5,2.0) interval, approximately 975 976 tolerance_preconditioner = fdf_get("PEXSI.tolerance-preconditioner",1.0_dp) 977 978 if (scf_step > 1 ) then 979 980 tolerance_exp = log10(dDmax/(tolerance_target_factor*dDtol)) 981 ! 982 ! range = log10(PEXSINumElectronToleranceMax/PEXSINumElectronToleranceMin) 983 tolerance_exp = max(tolerance_exp,0.0_dp)*tolerance_preconditioner 984 tolerance = PEXSINumElectronToleranceMin * 10.0_dp**tolerance_exp 985 tolerance = min(tolerance,PEXSINumElectronToleranceMax) 986 987 if (tolerance > previous_tolerance) then 988 if (mpirank==0) write(6,"(a,f10.2)") & 989 "Will not raise PEXSI solver tolerance to: ", & 990 tolerance 991 tolerance = previous_tolerance 992 endif 993 previous_tolerance = tolerance 994 else 995 ! No heuristics for now for first step 996 ! Note that this should really change in MD or geometry optimization 997 previous_tolerance = huge(1.0_dp) 998 tolerance = PEXSINumElectronToleranceMax 999 1000 endif 1001else 1002 tolerance = Max(PEXSINumElectronToleranceMin, & 1003 Min(dDmax*1.0, PEXSINumElectronToleranceMax)) 1004endif 1005 1006if (mpirank==0) write(6,"(a,f10.2)") & 1007 "Current PEXSI solver tolerance: ", tolerance 1008 1009end subroutine get_on_the_fly_tolerance 1010 1011!------------------------------------------------------------------ 1012! This function will determine whether an initial inertia-counting 1013! stage is needed, based on user input and the level of convergence 1014! 1015! Variables used through host association for now: 1016! 1017! scf_step 1018! prevDmax, safe_dDmax_NoInertia 1019! 1020! Some logging output is done, so this function is not pure. 1021 1022function need_inertia_counting() result(do_inertia_count) 1023logical :: do_inertia_count 1024 1025real(dp) :: safe_dDmax_NoInertia 1026integer :: isInertiaCount, numInertiaCounts 1027 1028! Use inertia counts? 1029! The use of this input variable is deprecated. Warn the user 1030! only if there is a disagreement. 1031 1032isInertiaCount = fdf_get("PEXSI.inertia-count",-1) 1033! For how many scf steps? 1034numInertiaCounts = fdf_get("PEXSI.inertia-counts",3) 1035 1036if ((isInertiaCount == 0) .and. (numInertiaCounts > 0)) then 1037 if (mpirank == 0) write(6,"(a,i4)") & 1038 "Warning: Inertia-counts turned off by legacy parameter" // & 1039 " PEXSI.inertia-count" 1040 numInertiaCounts = 0 1041endif 1042 1043safe_dDmax_NoInertia = fdf_get("PEXSI.safe-dDmax-no-inertia",0.05) 1044 1045do_inertia_count = .false. 1046 1047write_ok = ((mpirank == 0) .and. (verbosity >= 1)) 1048 1049if (numInertiaCounts > 0) then 1050 if (scf_step .le. numInertiaCounts) then 1051 if (write_ok) write(6,"(a,i4)") & 1052 "&o Inertia-count step scf_step<numIC", scf_step 1053 do_inertia_count = .true. 1054 endif 1055else if (numInertiaCounts < 0) then 1056 if (scf_step <= -numInertiaCounts) then 1057 if (write_ok) write(6,"(a,i4)") & 1058 "&o Inertia-count step scf_step<-numIC ", scf_step 1059 do_inertia_count = .true. 1060 else if (prevDmax > safe_dDmax_NoInertia) then 1061 if (write_ok) write(6,"(a,i4)") & 1062 "&o Inertia-count step as prevDmax > safe_Dmax ", scf_step 1063 do_inertia_count = .true. 1064 endif 1065endif 1066 1067end function need_inertia_counting 1068 1069!--------------------------------------------------------------- 1070! Chooses the proper interval for the call to the driver 1071! in case we need a stage of inertia counting 1072! 1073subroutine get_bracket_for_inertia_count() 1074 1075 real(dp) :: safe_width_ic 1076 real(dp) :: safe_dDmax_Ef_inertia 1077 1078 safe_width_ic = fdf_get("PEXSI.safe-width-ic-bracket",4.0_dp*eV,"Ry") 1079 safe_dDmax_Ef_Inertia = fdf_get("PEXSI.safe-dDmax-ef-inertia",0.1) 1080 1081write_ok = ((mpirank == 0) .and. (verbosity >= 1)) 1082 1083 ! Proper bracketing 1084 if (scf_step > 1) then 1085 if (prevDmax < safe_dDmax_Ef_inertia) then 1086 ! Shift brackets using estimate of Ef change from previous iteration 1087 ! 1088 if (write_ok) write(6,"(a)") & 1089 "&o Inertia-count bracket shifted by Delta_Ef" 1090 ! This might be risky, if the final interval of the previous iteration 1091 ! is too narrow. We should broaden it by o(kT) 1092 ! The usefulness of delta_Ef is thus debatable... 1093 1094 muMin0 = muMin0 + delta_Ef - two_kT 1095 muMax0 = muMax0 + delta_Ef + two_kT 1096 else 1097 ! Use a large enough interval around the previous estimation of 1098 ! mu (the gap edges are not available...) 1099 if (write_ok) write(6,"(a)") "&o Inertia-count safe bracket" 1100! muMin0 = min(muLowerEdge - 0.5*safe_width_ic, muMinInertia) 1101 muMin0 = min(mu - 0.5*safe_width_ic, muMin0) 1102! muMax0 = max(muUpperEdge + 0.5*safe_width_ic, muMaxInertia) 1103 muMax0 = max(mu + 0.5*safe_width_ic, muMax0) 1104 endif 1105 else 1106 if (write_ok) write(6,"(a)") & 1107 "&o Inertia-count called with iscf=1 parameters" 1108 endif 1109end subroutine get_bracket_for_inertia_count 1110 1111subroutine get_bracket_for_solver() 1112 1113 real(dp) :: safe_width_solver 1114 real(dp) :: safe_dDmax_Ef_solver 1115 1116safe_width_solver = fdf_get("PEXSI.safe-width-solver-bracket",4.0_dp*eV,"Ry") 1117safe_dDmax_Ef_solver = fdf_get("PEXSI.safe-dDmax-ef-solver",0.05) 1118 1119write_ok = ((mpirank == 0) .and. (verbosity >= 1)) 1120 1121! Do nothing for now 1122! No setting of muMin0 and muMax0 yet, pending clarification of flow 1123 1124 if (scf_step > 1) then 1125 if (prevDmax < safe_dDmax_Ef_solver) then 1126 if (write_ok) write(6,"(a)") "&o Solver mu shifted by delta_Ef" 1127 mu = mu + delta_Ef 1128 endif 1129 ! Always provide a safe bracket around mu, in case we need to fallback 1130 ! to executing a cycle of inertia-counting 1131 if (write_ok) write(6,"(a)") "&o Safe solver bracket around mu" 1132 muMin0 = mu - 0.5*safe_width_solver 1133 muMax0 = mu + 0.5*safe_width_solver 1134 else 1135 if (write_ok) write(6,"(a)") "&o Solver called with iscf=1 parameters" 1136 ! do nothing. Keep mu, muMin0 and muMax0 as they are inherited 1137 endif 1138end subroutine get_bracket_for_solver 1139 1140!------------------------------------------------------ 1141! If using the "annealing" feature, this routine computes 1142! the current temperature to use in the PEXSI solver 1143! 1144subroutine get_current_temperature(pexsi_temperature) 1145 real(dp), intent(out) :: pexsi_temperature 1146 1147 logical :: use_annealing 1148 real(dp) :: annealing_preconditioner, temp_factor 1149 real(dp) :: annealing_target_factor 1150 1151 use_annealing = fdf_get("PEXSI.use-annealing",.false.) 1152 if (use_annealing) then 1153 annealing_preconditioner = fdf_get("PEXSI.annealing-preconditioner",1.0_dp) 1154! By default, the temperature goes to the target at a level 10 times dDtol 1155 annealing_target_factor = fdf_get("PEXSI.annealing-target-factor",10.0_dp) 1156 1157 if (scf_step > 1 ) then 1158 1159 ! Examples for target_factor = 10, dDtol=0.0001: 1160 ! prevDmax=0.1, preconditioner=1, factor=3 1161 ! prevDmax=0.1, preconditioner=2, factor=5 1162 ! prevDmax=0.1, preconditioner=3, factor=7 1163 ! prevDmax<=0.001, factor = 1 1164 ! prevDmax<0.001, factor = 1 1165 1166 temp_factor = (log10(prevDmax/(annealing_target_factor*dDtol))) 1167 temp_factor = 1 + annealing_preconditioner * max(0.0_dp, temp_factor) 1168 1169 pexsi_temperature = temp_factor * temperature 1170 if (pexsi_temperature > previous_pexsi_temperature) then 1171 if (mpirank==0) write(6,"(a,f10.2)") & 1172 "Will not raise PEXSI temperature to: ", & 1173 pexsi_temperature/Kelvin 1174 pexsi_temperature = previous_pexsi_temperature 1175 endif 1176 previous_pexsi_temperature = pexsi_temperature 1177 else 1178 ! No heuristics for now for first step 1179 previous_pexsi_temperature = huge(1.0_dp) 1180 pexsi_temperature = temperature 1181 ! Keep in mind for the future if modifying T at the 1st step 1182 ! previous_pexsi_temperature = pexsi_temperature 1183 endif 1184else 1185 pexsi_temperature = temperature 1186endif 1187if (mpirank==0) write(6,"(a,f10.2)") & 1188 "Current PEXSI temperature (K): ", pexsi_temperature/Kelvin 1189end subroutine get_current_temperature 1190 1191function interpolate(xx,yy,x) result(val) 1192! 1193! Interpolate linearly in the (monotonically increasing!) arrays xx and yy 1194! 1195integer, parameter :: dp = selected_real_kind(10,100) 1196 1197real(dp), intent(in) :: xx(:), yy(:) 1198real(dp), intent(in) :: x 1199real(dp) :: val 1200 1201integer :: i, n 1202 1203n = size(xx) 1204if (size(yy) /= n) call die("Mismatch in array sizes in interpolate") 1205 1206if ( (x < xx(1)) .or. (x > xx(n))) then 1207 call die("Interpolate: x not in range") 1208endif 1209 1210do i = 2, n 1211 if (x <= xx(i)) then 1212 val = yy(i-1) + (x-xx(i-1)) * (yy(i)-yy(i-1))/(xx(i)-xx(i-1)) 1213 exit 1214 endif 1215enddo 1216 1217end function interpolate 1218 1219subroutine check_info(info,str) 1220integer, intent(in) :: info 1221character(len=*), intent(in) :: str 1222 1223 if(mpirank == 0) then 1224 if (info /= 0) then 1225 write(6,*) trim(str) // " info : ", info 1226 call die("Error exit from " // trim(str) // " routine") 1227 endif 1228 call pxfflush(6) 1229 endif 1230end subroutine check_info 1231 1232end subroutine pexsi_solver 1233#endif 1234end module m_pexsi_solver 1235! End of tangled code 1236