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