LCOV - code coverage report
Current view: top level - src/78_eph - m_varpeq.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 84.8 % 1716 1456
Test Date: 2026-09-19 17:42:43 Functions: 87.0 % 69 60

            Line data    Source code
       1              : !! NAME
       2              : !!  m_varpeq
       3              : !!
       4              : !! FUNCTION
       5              : !!  Description
       6              : !!
       7              : !! COPYRIGHT
       8              : !!  Copyright (C) 2023-2026 ABINIT group (VV, MG)
       9              : !!  This file is distributed under the terms of the
      10              : !!  GNU General Public License, see ~abinit/COPYING
      11              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      12              : !!
      13              : !! SOURCE
      14              : 
      15              : #if defined HAVE_CONFIG_H
      16              : #include "config.h"
      17              : #endif
      18              : 
      19              : #include "abi_common.h"
      20              : 
      21              : module m_varpeq
      22              : 
      23              :  use, intrinsic :: iso_c_binding
      24              :  use defs_basis
      25              :  use m_abicore
      26              :  use m_dtset
      27              :  use m_dtfil
      28              :  use m_crystal
      29              :  use m_ebands
      30              :  use m_errors
      31              :  use m_krank
      32              :  use netcdf
      33              :  use m_nctk
      34              :  use m_xmpi
      35              :  use m_ifc
      36              :  use m_wfd
      37              :  use m_sigtk
      38              : 
      39              :  use defs_datatypes,    only : pseudopotential_type
      40              :  use m_numeric_tools,   only : interpolate_ur
      41              :  use m_fstrings,        only : sjoin, ktoa, ftoa, strcat, ltoa, itoa, yesno
      42              :  use m_time,            only : cwtime_report, cwtime
      43              :  use m_io_tools,        only : file_exists, iomode_from_fname, open_file
      44              :  use m_pptools,         only : write_xsf
      45              :  use m_geometry,        only : xcart2xred, phdispl_cart2red_nmodes
      46              :  use m_kpts,            only : kpts_map, kpts_timrev_from_kptopt, bzlint_t, kptrlatt_from_ngkpt
      47              :  use m_fft_mesh,        only : calc_ceikr
      48              :  use m_pawtab,          only : pawtab_type
      49              :  use m_gstore,          only : gstore_t, gqk_t
      50              :  use m_supercell,       only : supercell_type
      51              :  use m_paw_sphharm,     only : ylm_angular_mesh
      52              :  use m_fftcore,         only : ngfft_seq
      53              :  use m_ephtk,           only : ephtk_get_mpw_gmax, EPHTK_WTOL
      54              :  use m_dynmat,          only : phdispl_from_eigvec
      55              :  use m_phonons,         only : pheigvec_rotate
      56              :  use m_splines,         only : spline_complex, splint_complex
      57              :  use m_occ,             only : occ_be, occ_fd
      58              : 
      59              : 
      60              :  implicit none
      61              : 
      62              :  private
      63              : !!***
      64              : 
      65              : !----------------------------------------------------------------------
      66              : 
      67              : !!****t* m_varpeq/polstate_t
      68              : !! NAME
      69              : !!  polstate_t
      70              : !!
      71              : !! FUNCTION
      72              : !!  Datatype defining MPI-distributed parameters of polaronic states for a
      73              : !!  given spin index (if collinear magnetism i.e. nsppol 2). Local variables and
      74              : !!  arrays start with `my_`, global have `*glob*` in their names. The MPI grid is
      75              : !!  inherited from a gstore%gqk object at initialization.
      76              : !!
      77              : !! SOURCE
      78              : 
      79              :  type, public :: polstate_t
      80              : 
      81              :   character(len=abi_slen) :: aseed = " "
      82              :    ! Specifies the type of initial seed for charge localization A_nk
      83              :    ! Possible values: "gau_energy", "gau_length", "random", "even", "localize"
      84              : 
      85              :   logical :: translate = .false.
      86              :    ! Flag controlling treatment of polaronic solution invariant by primitive
      87              :    ! translations inside supercell
      88              :    ! if .true. and np > 1, the next solution is found to be orthogonal to all
      89              :    ! previous states + their translated replicas
      90              : 
      91              :   integer :: spin = -1
      92              :    ! Spin index
      93              : 
      94              :   integer :: ip = -1
      95              :    ! Current polaronic state
      96              : 
      97              :   integer :: np = -1
      98              :    ! Number of polaronic states
      99              : 
     100              :   integer :: nkbz = -1
     101              :    ! Number of k-points in full BZ
     102              : 
     103              :   integer :: nqbz = -1
     104              :    ! Number of q-points in full BZ
     105              : 
     106              :   integer :: psign = 1
     107              :    ! Sign of the charge carrier
     108              :    ! +1 -- electron addition (electron polaron)
     109              :    ! -1 -- electron removal (hole polaron)
     110              : 
     111              :   real(dp) :: e_frohl
     112              :    ! Long-range divergence correction of polaron binding energy due to g(0) avg
     113              : 
     114              :   real(dp) :: efilter
     115              :    ! Energy filter
     116              : 
     117              :   integer :: ngkpt(3)
     118              :    ! Number of points in the uniform k-grid defining the electronic subspace
     119              : 
     120              :   real(dp) :: gpr_energy(2)
     121              :   ! Gaussian parameters for energy-based initialization
     122              : 
     123              :   real(dp) :: gpr_length(3)
     124              :   ! Gaussian parameters for localization length-based initialization
     125              : 
     126              :   logical, allocatable :: has_prev_grad(:)
     127              :    ! (np)
     128              :    ! Flag indicating if an electronic gradient has been computed at previous step
     129              : 
     130              :   real(dp), allocatable :: gradres(:)
     131              :    ! (np)
     132              :    ! L^2-norm of the electronic gradient for each state
     133              : 
     134              :   real(dp), allocatable :: enterms(:,:)
     135              :    ! (4, np)
     136              :    ! Polaronic energy terms for each state
     137              :    ! 1 -> electronic term
     138              :    ! 2 -> vibrational term
     139              :    ! 3 -> electron-phonon term
     140              :    ! 4 -> polaron energy level
     141              : 
     142              :   real(dp), allocatable :: eig(:,:)
     143              :    ! (gqk%nb_k, gstore%ebands%nkpt)
     144              :    ! Electronic eigenstates participating in the polaron formation
     145              :    ! Correspond either to valence or conduction manifold, not both
     146              :    ! Band edge is set to 0; valence states are also inverted
     147              : 
     148              :   real(dp), allocatable :: my_g0(:)
     149              :    ! (gqk%my_npert)
     150              :    ! Long-range correction for electron-phonon matrix elements at q=\Gamma
     151              : 
     152              :   real(dp), allocatable :: my_qpts(:,:)
     153              :    ! (3, gqk%my_nq)
     154              :    ! q-points treated by this MPI proc
     155              : 
     156              :   real(dp), allocatable :: displ(:,:,:)
     157              :   ! (3, self%scell%natom, np)
     158              :   ! Atomic displacements \Delta \tau_{\alpha \kappa*p} for each state
     159              : 
     160              :   real(dp), pointer :: my_kpts(:,:) => null()
     161              :    ! (3, gqk%my_nk)
     162              :    ! k-points treated by this MPI proc, points to gqk%my_kpts(:,:)
     163              : 
     164              :   complex(dp), allocatable :: my_a(:,:,:)
     165              :    ! (gqk%nb_k, gqk%my_nk, np)
     166              :    ! Electronic coefficients A_nk for each state treated by this MPI proc
     167              : 
     168              :   complex(dp), allocatable :: a_glob(:,:,:)
     169              :    ! (gqk%nb_k, gqk%glob_nk, np)
     170              :    ! Global array of electronic coefficients A_nk at each state
     171              : 
     172              :   complex(dp), allocatable :: my_b(:,:,:)
     173              :    ! (gqk%my_npert, gqk%my_nq, np)
     174              :    ! Vibrational coefficients B_q\nu for each state treated by this MPI proc
     175              : 
     176              :   complex(dp), allocatable :: my_prev_b(:,:)
     177              :    ! (gqk%my_npert, gqk%my_nq)
     178              :    ! Previous vibrational coefficients B_q\nu for each state treated by this MPI proc
     179              : 
     180              :   complex(dp), allocatable :: my_prev_b_hop(:,:,:)
     181              :    ! (gqk%my_npert, gqk%my_nq)
     182              :    ! Previous vibrational coefficients B_q\nu for each state (hopping optimization)
     183              : 
     184              :   complex(dp), allocatable :: my_pc(:,:)
     185              :    ! (gqk%nb_k, gqk%my_nk)
     186              :    ! Preconditioner at current state treated by this MPI proc
     187              : 
     188              :   complex(dp), allocatable :: my_grad(:,:)
     189              :    ! (gqk%nb_k, gqk%my_nk)
     190              :    ! Electronic gradient D_nk at current state treated by this MPI proc
     191              :    ! orthogonal to states
     192              : 
     193              :   complex(dp), allocatable :: my_prev_grad(:,:)
     194              :    ! (gqk%nb_k, gqk%my_nk)
     195              :    ! Previous electronic gradient D_nk at current state, orthogonal to states
     196              : 
     197              :   complex(dp), allocatable :: my_pcgrad(:,:)
     198              :    ! (gqk%nb_k, gqk%my_nk)
     199              :    ! Preconditioned gradient at current state, orthogonal to states
     200              : 
     201              :   complex(dp), allocatable :: my_prev_pcgrad(:,:)
     202              :    ! (gqk%nb_k, gqk%my_nk)
     203              :    ! Previous preconditioned gradient at current state, orthogonal to states
     204              : 
     205              :   complex(dp), allocatable :: my_pcjgrad(:,:)
     206              :    ! (gqk%nb_k, gqk%my_nk)
     207              :    ! Preconditioned conjugate gradient at current state treated by this MPI proc
     208              :    ! orthogonal to current state & normalized
     209              : 
     210              :   complex(dp), allocatable :: my_prev_pcjgrad(:,:)
     211              :    ! (gqk%nb_k, gqk%my_nk)
     212              :    ! Previous preconditioned conjugate gradient at current state
     213              : 
     214              :   complex(dp), allocatable :: pcjgrad_glob(:,:)
     215              :    ! (gqk%nb_k, gqk%glob_nk)
     216              :    ! Global preconditioned conjugate gradient at current state
     217              :    ! orthogonal to current state & normalized
     218              : 
     219              :   complex(dp), allocatable :: my_phgrad(:,:,:)
     220              :    ! (gqk%my_npert, gqk%my_nq, np)
     221              :    ! Phonon gradient \nabla E_{B_q\nu} for each state treated by this MPI proc
     222              : 
     223              :   complex(dp), allocatable :: my_eff_phforce(:,:,:)
     224              :    ! (gqk%my_npert, gqk%my_nq, np)
     225              :    ! Effective phonon force F_q\nu at current state treated by this MPI proc
     226              : 
     227              :   real(dp), allocatable :: hop_ts(:)
     228              :    ! (np)
     229              :    ! Line minimization timestep for hopping optimization for each state
     230              : 
     231              :   class(gqk_t), pointer :: gqk => null()
     232              :    ! Datastructure storing e-ph matrix elements treated by this MPI proc
     233              : 
     234              :   type(krank_t) :: krank_kpts
     235              :    ! Object used to find k-points in BZ
     236              : 
     237              :   type(krank_t) :: krank_qpts
     238              :    ! Object used to find q-points in BZ
     239              : 
     240              :   type(crystal_t) :: cryst
     241              :   ! Object storing information on crystal structure & symmetries
     242              : 
     243              :   contains
     244              : 
     245              :     procedure :: setup => polstate_setup
     246              :     ! Set up optimization process by specifying initial electronic vector A_nk
     247              : 
     248              :     procedure :: localize => polstate_localize
     249              :     ! Localize polaron at current state. From A_nk calculate:
     250              :     ! vibrational coefficients B_q\nu, energy terms, polaron level
     251              : 
     252              :     procedure :: get_enel => polstate_get_enel
     253              :     ! Calculate and return electronic energy term
     254              : 
     255              :     procedure :: get_enph => polstate_get_enph
     256              :     ! Calculate and return vibrational energy term
     257              : 
     258              :     procedure :: get_enelph => polstate_get_enelph
     259              :     ! Calculate and return electron-phonon energy term
     260              : 
     261              :     procedure :: get_lm_theta => polstate_get_lm_theta
     262              :     ! Calculate and return line minimization parameter \theta
     263              : 
     264              :     procedure :: calc_grad => polstate_calc_grad
     265              :     ! Calculate steepest descent vector (electronic gradient)
     266              : 
     267              :     procedure :: calc_pcjgrad => polstate_calc_pcjgrad
     268              :     ! Calculate preconditioned conjugate gradient direction
     269              : 
     270              :     procedure :: update_pc => polstate_update_pc
     271              :     ! Update preconditioner
     272              : 
     273              :     procedure :: update_a => polstate_update_a
     274              :     ! Update array of electronic coefficients
     275              : 
     276              :     procedure :: ort_to_states => polstate_ort_to_states
     277              :     ! Orthogonalize a given vector to a set of polaronic states
     278              : 
     279              :     procedure :: calc_b_from_a => polstate_calc_b_from_a
     280              :     ! Calculate vibrational coefficients B_q\nu from a known set of electronic
     281              :     ! coefficients A_nk
     282              : 
     283              :     procedure :: calc_b_from_displ => polstate_calc_b_from_displ
     284              :     ! Calculate vibrational coefficients B_q\nu from a known set of displacements
     285              :     ! \Delta \tau_{\alpha \kappa p}
     286              : 
     287              :     procedure :: calc_displ_from_b => polstate_calc_displ_from_b
     288              :     ! Calculate polaron-induced displacements \Delta \tau_{\alpha \kappa p} from
     289              :     ! a known set of vibrational coefficients B_q\nu
     290              : 
     291              :     procedure :: calc_clb_displ => polstate_calc_clb_displ
     292              :     ! Calculate displacements induced by the Coulomb forces for a unit charge
     293              :     ! localized on a supercell atom
     294              : 
     295              :     procedure :: calc_phgrad => polstate_calc_phgrad
     296              :     ! Calculate steepest descent vector (phonon gradient)
     297              : 
     298              :     procedure :: calc_hpol => polstate_calc_hpol
     299              :     ! Construct and calculate the polaron Hamiltonian, <A_bra|H(B)|A_ket>
     300              : 
     301              :     procedure :: seed_a => polstate_seed_a
     302              :     ! Seed an initial vector of electronic coefficients A_nk
     303              : 
     304              :     procedure :: load_a => polstate_load_a
     305              :     ! Initialize A_nk from an existing vector of electronic coefficients
     306              : 
     307              :     procedure :: load_b => polstate_load_b
     308              :     ! Initialize B_q\nu from an existing vector of electronic coefficients
     309              : 
     310              :     procedure :: linterp_b => polstate_linterp_b
     311              :     ! Linear interpolation of B_\qnu coefficients between initial and final state
     312              : 
     313              :     procedure :: redistr_b => polstate_redistr_b
     314              :     ! Redistribute B_\qnu coefficients with spline interpolation
     315              : 
     316              :     procedure :: calc_eff_phforce => polstate_calc_eff_phforce
     317              :     ! Calculate effective phonon force for hopping optimization
     318              : 
     319              :     procedure :: calc_hop_timestep => polstate_calc_hop_timestep
     320              :     ! Calculate timestep from effective phonon force for this state
     321              : 
     322              :     procedure :: get_sqnorm => polstate_get_sqnorm
     323              :     ! Helper function to compute squared L^2-norm of MPI-distributed array
     324              : 
     325              :     procedure :: gather => polstate_gather
     326              :     ! Helper function to gather MPI-distributed array into a global one
     327              : 
     328              :     procedure :: filter => polstate_filter
     329              :     ! Helper function to filter MPI-distributed array
     330              : 
     331              :     procedure :: get_krank_glob => polstate_get_krank_glob
     332              :     ! Helper function to calculate global krank objects
     333              : 
     334              :     procedure :: free => polstate_free
     335              :     ! Free memory
     336              : 
     337              :  end type polstate_t
     338              : !!***
     339              : 
     340              : !----------------------------------------------------------------------
     341              : 
     342              : !!****t* m_varpeq/varpeq_t
     343              : !! NAME
     344              : !!  varpeq_t
     345              : !!
     346              : !! FUNCTION
     347              : !!  Variational Polaron Equations datatype. Stores variational optimization
     348              : !!  parameters, polaronic states and provides higher-level procedures required
     349              : !!  for variational optimization and related input and output.
     350              : !!
     351              : !! SOURCE
     352              : 
     353              :  type, public :: varpeq_t
     354              : 
     355              :    character(len=abi_slen) :: mode = " "
     356              :    ! Specifies the calculation mode
     357              :    ! Possible values: "polaron", "hopping"
     358              : 
     359              :    character(len=abi_slen) :: pkind = " "
     360              :    ! Specifies the kind of polaron
     361              :    ! Possible values: "hole", "electron"
     362              : 
     363              :    character(len=abi_slen) :: aseed = " "
     364              :    ! Specifies the type of initial seed for charge localization A_nk
     365              :    ! Possible values: "gau_energy", "gau_length", "random", "even", "localize"
     366              : 
     367              :    logical :: fix_displ = .false.
     368              :    ! Flag indicating if vibrational coefficients need to be fixed between steps.
     369              :    ! True for hopping calculations.
     370              : 
     371              :    logical  :: use_filter = .false.
     372              :    ! Flag indicating if the energy filtering for electronic states was used
     373              : 
     374              :    logical :: is_complete = .false.
     375              :    ! Flag indicating if the datatype is completely or partially initialized
     376              :    ! Required to distinguish between newly created and loaded-from-disk datatype
     377              : 
     378              :    logical :: restart = .false.
     379              :    ! Flag to check if a restart from a *VPQ.nc file is needed
     380              : 
     381              :    logical :: interp = .false.
     382              :    ! Flag to check if an interpolation from a *VPQ.nc file is needed
     383              : 
     384              :    logical :: ld_flag = .false.
     385              :    ! Flag indicating if internal variables have been loaded from source
     386              : 
     387              :    logical :: g0_flag = .true.
     388              :    ! Flag indicating if the average of el-ph matrix elements at Gamma is computed
     389              : 
     390              :    logical :: translate = .false.
     391              :    ! Flag controlling the translational invariance of polaronic solutions
     392              : 
     393              :    integer :: ncid = nctk_noid
     394              :    ! Netcdf file handle used to save results
     395              : 
     396              :    integer :: atloc = -1
     397              :    ! At which atom the polaron is localized
     398              :    ! from 1 to cryst%natom if aseed = "localize"
     399              : 
     400              :    integer :: hop_nstep = -1
     401              :    ! Maximum number of iterations for hopping transport optimization
     402              : 
     403              :    integer :: nstep = -1
     404              :    ! Maximum number of iterations for optimization of a single polaronic state
     405              : 
     406              :    integer :: nstep_ort = -1
     407              :    ! Maximum number of iterations for which orthogonalization to all previous
     408              :    ! states is performed
     409              : 
     410              :    integer :: nsppol = -1
     411              :    ! Number of independent spin polarizations
     412              : 
     413              :    integer :: nstates = -1
     414              :    ! Number of polaronic states to be optimized for each spin polarization
     415              : 
     416              :    integer :: natom3 = -1
     417              :    ! 3*gstore%cryst%natom
     418              :    ! Number of atomic perturbations, mainly used to dimensionalize arrays
     419              : 
     420              :    integer :: max_nk = -1
     421              :    ! Maximum number of k-points among between independent spin polarizations
     422              : 
     423              :    integer :: max_nq = -1
     424              :    ! Maximum number of q-points among between independent spin polarizations
     425              : 
     426              :    integer :: max_nb = -1
     427              :    ! Maximum number of bands among between independent spin polarizations
     428              : 
     429              :    integer :: frohl_ntheta = -1
     430              :    ! Number of angular mesh division for spherical integration of long-range
     431              :    ! divergence of electron-phonon matrix elements
     432              : 
     433              :    real(dp) :: e_frohl
     434              :    ! Long-range divergence correction of polaron binding energy
     435              : 
     436              :    real(dp) :: mixing_factor
     437              :    ! Mixing factor to be used in the solver for vibrational coefficients
     438              : 
     439              :    real(dp) :: tolgrs
     440              :    ! L^2 gradient norm tolerance
     441              : 
     442              :    real(dp) :: hop_tolgrs
     443              :    ! L^2 force norm tolerance for hopping optimization
     444              : 
     445              :    real(dp) :: hop_ts
     446              :    ! Timestep for hopping
     447              : 
     448              :    integer :: ngkpt(3)
     449              :    ! Number of points in the uniform k-grid defining the electronic subspace
     450              : 
     451              :    integer, allocatable :: nk_spin(:)
     452              :    ! (nsppol)
     453              :    ! Number of k-points for each spin polarization
     454              : 
     455              :    integer, allocatable :: nq_spin(:)
     456              :    ! (nsppol)
     457              :    ! Number of q-points for each spin polarization
     458              : 
     459              :    integer, allocatable :: nb_spin(:)
     460              :    ! (nsppol)
     461              :    ! Number of bands for each spin polarization
     462              : 
     463              :    integer, allocatable :: brange_spin(:,:)
     464              :    ! (2, nsppol)
     465              :    ! Number of bands for each spin polarization
     466              : 
     467              :    integer, allocatable :: cvflag_spin(:,:,:)
     468              :    ! (nstates, hop_nstep, nsppol)
     469              :    ! Convergence flags at each state for each spin:
     470              :    ! 0 --> calculation is not converged
     471              :    ! 1 --> calculation is converged
     472              : 
     473              :    integer, allocatable :: hop_nstep2cv_spin(:)
     474              :    ! (nsppol)
     475              :    ! number of steps to convergence the hopping optimization for each spin
     476              : 
     477              :    integer, allocatable :: nstep2cv_spin(:,:,:)
     478              :    ! (nstates, hop_nstep, nsppol)
     479              :    ! number of steps to convergence at each state for each spin
     480              : 
     481              :    real(dp), allocatable :: erange_spin(:)
     482              :    ! (nsppol)
     483              :    ! energy window wrt to vbm/cbm for hole/electron polaron for each spin
     484              : 
     485              :    integer, allocatable :: k2ibz_spin(:,:)
     486              :    ! (max_nk, nsppol)
     487              :    ! bz->ibz index table for kpoints (related to sell%gstore%kibz)
     488              : 
     489              :    integer, allocatable :: q2ibz_spin(:,:)
     490              :    ! (max_nq, nsppol)
     491              :    ! bz->ibz index table for qpoints (related to sell%gstore%qibz)
     492              : 
     493              :    real(dp), allocatable :: chrgat(:)
     494              :    ! (natom)
     495              :    ! charge of the cations
     496              : 
     497              :    real(dp), allocatable :: hop_hist_spin(:,:,:,:)
     498              :    ! (5, nstates, hop_nstep, nsppol)
     499              :    ! hopping optimization history at each state (image) for each spin
     500              :    ! 1 - bare phonon force norms, i.e. |dE_pol/dB| at each image
     501              :    ! 2 - string forces, i.e. |B^n - B^(n-1)|/timestep for step n
     502              :    ! 3 - diabatic energy curve for initial state: <A_in|B_i|A_in>
     503              :    ! 4 - diabatic energy curve for final state: <A_end|B_i|A_end>
     504              :    ! 5 - overlap integral <A_in|B_i|A_end>
     505              : 
     506              :    real(dp), allocatable :: scf_hist_spin(:,:,:,:,:)
     507              :    ! (6, nstep, nstates, hop_nstep, nsppol)
     508              :    ! scf optimization history at each state for each spin
     509              :    ! 1 - binding energy, 2 - electronic energy, 3 - phonon energy
     510              :    ! 4 - electron-phonon energy, 5 - localization energy
     511              :    ! 6 - gradient norm
     512              : 
     513              :    real(dp), allocatable :: kpts_spin(:,:,:)
     514              :    ! (3, max_nk, nsppol)
     515              :    ! k-points for each spin
     516              : 
     517              :    real(dp), allocatable :: qpts_spin(:,:,:)
     518              :    ! (3, max_nq, nsppol)
     519              :    ! q-points for each spin
     520              : 
     521              :    complex(dp), allocatable :: a_spin(:,:,:,:)
     522              :    ! (max_nb, max_nk, nstates, nsppol)
     523              :    ! optimized electronic coefficients a_nk at each state for each spin
     524              : 
     525              :    complex(dp), allocatable :: b_spin(:,:,:,:)
     526              :    ! (natom3, max_nq, nstates, nsppol)
     527              :    ! optimized vibrational coefficients b_q\nu at each state for each spin
     528              : 
     529              :    class(gstore_t), pointer :: gstore => null()
     530              :    ! object storing el-ph matrix elements and other related quantities
     531              : 
     532              :    type(crystal_t) :: cryst
     533              :    ! Object storing information on crystal structure & symmetries
     534              : 
     535              :    type(gaps_t) :: gaps
     536              :    ! Object used to get information on bandgap
     537              : 
     538              :    type(supercell_type) :: scell
     539              :    ! Object used to get information on supercell
     540              : 
     541              :    type(polstate_t), allocatable :: polstate(:)
     542              :    ! (nsppol)
     543              :    ! Datatype providing data and lower-level methods for polaronic states
     544              :    ! at each spin polarization
     545              : 
     546              :  contains
     547              : 
     548              :     procedure :: init => varpeq_init
     549              :     ! Initialize object
     550              : 
     551              :     procedure :: load => varpeq_load
     552              :     ! Load the initial electronic vector from a *VPQ.nc netcdf file
     553              : 
     554              :     procedure :: solve => varpeq_solve
     555              :     ! Solve variational polaron equations at each polaronic state for each spin
     556              : 
     557              :     procedure :: record => varpeq_record
     558              :     ! Record the current SCF optimization data
     559              : 
     560              :     procedure :: collect => varpeq_collect
     561              :     ! Collect SCF optimization results from each spin
     562              : 
     563              :     procedure :: print_scf_results => varpeq_print_scf_results
     564              :     ! Output SCF optimization final results
     565              : 
     566              :     procedure :: print_hop_results => varpeq_print_hop_results
     567              :     ! Output hopping optimization final results
     568              : 
     569              :     procedure :: print_metadata => varpeq_print_metadata
     570              :     ! Output parameters defining varpeq calculation
     571              : 
     572              :     procedure :: ncwrite => varpeq_ncwrite
     573              :     ! Save results to a *VPQ.nc netcdf file
     574              : 
     575              :     procedure :: ncread => varpeq_ncread
     576              :     ! Initialize an incomplete object from a *VPQ.nc netcdf file
     577              : 
     578              :     procedure :: compare => varpeq_compare
     579              :     ! Compare basic dimensions with another instance of varpeq_t datatype
     580              : 
     581              :     procedure :: calc_fravg => varpeq_calc_fravg
     582              :     ! Calculate average Fr\"ohlich (long-range) contribution to the polaron
     583              :     ! binding energy & average of electron-phonon matrix elements at q=\Gamma
     584              : 
     585              :     procedure :: hop_setup => varpeq_hop_setup
     586              :     ! Set up the data structure for hopping transport calculations
     587              : 
     588              :     procedure :: hop => varpeq_hop
     589              :     ! Polaron hopping optimization for self%nstates images
     590              : 
     591              :     procedure :: free => varpeq_free
     592              :     ! Free memory
     593              : 
     594              :  end type varpeq_t
     595              : !!***
     596              : 
     597              :  public :: varpeq_run
     598              :    ! Main entry point
     599              : 
     600              :  public :: varpeq_plot
     601              :   ! Compute polaron wavefunctions and atomic displacements in the supercell and write results to XSF files
     602              : 
     603              : contains !=====================================================================
     604              : 
     605              : 
     606              : !!****f* m_varpeq/varpeq_run
     607              : !! NAME
     608              : !!  varpeq_run
     609              : !!
     610              : !! FUNCTION
     611              : !!  Higher-level subroutine that solves variational polaron equations, produces
     612              : !!  necessary output and writes results to a *VPQ.nc file.
     613              : !!
     614              : !! INPUTS
     615              : !!  gstore<gstore_t>=Electron-phonon matrix elements and related quantities.
     616              : !!  dtset<dataset_type>=All input variables for this dataset.
     617              : !!  dtfil<datafiles_types>=Variables related to files.
     618              : !!
     619              : !! OUTPUT
     620              : !!
     621              : !! SOURCE
     622              : 
     623            9 : subroutine varpeq_run(gstore, dtset, dtfil)
     624              : 
     625              : !Arguments ------------------------------------
     626              :  class(gstore_t), intent(in) :: gstore
     627              :  type(dataset_type), intent(in) :: dtset
     628              :  type(datafiles_type), intent(in) :: dtfil
     629              : !arrays
     630              :  integer :: units(2)
     631              : 
     632              : !Local variables-------------------------------
     633          468 :  type(varpeq_t) :: vpq
     634              : !----------------------------------------------------------------------
     635              : 
     636           27 :  units = [std_out, ab_out]
     637            9 :  call wrtout(units, sjoin(ch10, " === Variational Polaron Equations ==="))
     638              : 
     639            9 :  call vpq%init(gstore, dtset)
     640            9 :  if (vpq%frohl_ntheta > 0) call vpq%calc_fravg(avg_g0=vpq%g0_flag)
     641            9 :  if (vpq%interp .or. vpq%restart) call vpq%load(dtfil, dtset%vpq_select)
     642              : 
     643            9 :  call vpq%print_metadata()
     644              : 
     645            8 :  select case(vpq%mode)
     646              :  case ("polaron")
     647            8 :    call vpq%solve(verbose=.true.)
     648              : 
     649              :  case ("hopping")
     650            1 :    ABI_CHECK(vpq%nstates > 1, "varpeq_run: vpq_nstates must be > 1 for hopping")
     651            1 :    call vpq%hop_setup(dtset)
     652            1 :    call vpq%hop()
     653              : 
     654              :  case default
     655            9 :    ABI_ERROR(sjoin("varpeq_run, unsupported varpeq mode: ", vpq%mode))
     656              :  end select
     657              : 
     658            9 :  call vpq%collect()
     659              : 
     660            8 :  select case(vpq%mode)
     661              :  case ("polaron")
     662            8 :    call vpq%print_scf_results(ihop=1)
     663              :  case ("hopping")
     664            9 :    call vpq%print_hop_results()
     665              :  end select
     666              : 
     667            9 :  call vpq%ncwrite(dtset, dtfil)
     668            9 :  call vpq%free()
     669              : 
     670            9 : end subroutine varpeq_run
     671              : !!***
     672              : 
     673              : !----------------------------------------------------------------------
     674              : 
     675              : !!****f* m_varpeq/varpeq_free
     676              : !! NAME
     677              : !!  varpeq_free
     678              : !!
     679              : !! FUNCTION
     680              : !!  Free dynamic memory
     681              : !!
     682              : !! SOURCE
     683              : 
     684           13 : subroutine varpeq_free(self)
     685              : 
     686              : !Arguments ------------------------------------
     687              :  class(varpeq_t), target, intent(inout) :: self
     688              : 
     689              : !Local variables-------------------------------
     690              :  integer :: my_is
     691              : !----------------------------------------------------------------------
     692              : 
     693              :  ! Free allocatable arrays
     694              :  ! integer
     695           13 :  ABI_SFREE(self%nk_spin)
     696           13 :  ABI_SFREE(self%nq_spin)
     697           13 :  ABI_SFREE(self%nb_spin)
     698           13 :  ABI_SFREE(self%brange_spin)
     699           13 :  ABI_SFREE(self%cvflag_spin)
     700           13 :  ABI_SFREE(self%hop_nstep2cv_spin)
     701           13 :  ABI_SFREE(self%nstep2cv_spin)
     702              :  ! real
     703           13 :  ABI_SFREE(self%chrgat)
     704           13 :  ABI_SFREE(self%erange_spin)
     705           13 :  ABI_SFREE(self%hop_hist_spin)
     706           13 :  ABI_SFREE(self%scf_hist_spin)
     707           13 :  ABI_SFREE(self%k2ibz_spin)
     708           13 :  ABI_SFREE(self%q2ibz_spin)
     709           13 :  ABI_SFREE(self%kpts_spin)
     710           13 :  ABI_SFREE(self%qpts_spin)
     711              : 
     712              :  ! complex
     713           13 :  ABI_SFREE(self%a_spin)
     714           13 :  ABI_SFREE(self%b_spin)
     715              : 
     716              :  ! Free local datatypes
     717           13 :  call self%cryst%free()
     718              : 
     719              :  ! Close netcdf file
     720           13 :  if (self%ncid /= nctk_noid) then
     721            9 :    NCF_CHECK(nf90_close(self%ncid))
     722            9 :    self%ncid = nctk_noid
     723              :  end if
     724              : 
     725              :  ! If entry is completely initialized (e.g. from self%init call), free remaining
     726              :  ! datatypes and nullify pointers
     727           13 :  if (self%is_complete) then
     728            9 :    call self%gaps%free()
     729           18 :    do my_is=1,self%gstore%my_nspins
     730           18 :      call self%polstate(my_is)%free()
     731              :    enddo
     732            9 :    call self%scell%free()
     733           18 :    ABI_SFREE(self%polstate)
     734            9 :    self%gstore => null()
     735              :  endif
     736              : 
     737           13 : end subroutine varpeq_free
     738              : !!***
     739              : 
     740              : !----------------------------------------------------------------------
     741              : 
     742              : !!****f* m_varpeq/varpeq_compare
     743              : !! NAME
     744              : !!  varpeq_compare
     745              : !!
     746              : !! FUNCTION
     747              : !!  Compares the current instance of varpeq datatype with another one (possibly
     748              : !!  incomplete).
     749              : !!
     750              : !! INPUTS
     751              : !!  other<varpeq_t>=Varpeq datatype to compare with.
     752              : !!  bz_mismatch [optional]=if .true. mismatch between BZ sampling is allowed
     753              : !!    (required for comparison prior to an interpolation)
     754              : !!
     755              : !! OUTPUT
     756              : !!
     757              : !! SOURCE
     758              : 
     759            4 : subroutine varpeq_compare(self, other, bz_mismatch)
     760              : 
     761              : !Arguments ------------------------------------
     762              :  class(varpeq_t), target, intent(in) :: self, other
     763              :  logical, optional, intent(in) :: bz_mismatch
     764              : 
     765              : !Local variables-------------------------------
     766              :  integer :: ierr
     767              :  real(dp) :: cpu, wall, gflops
     768              : !----------------------------------------------------------------------
     769              : 
     770              :  ! TODO: provide more flexibility for nstates
     771              : 
     772            2 :  call cwtime(cpu, wall, gflops, "start")
     773              : 
     774            2 :  ierr = 0
     775              : 
     776              :  ! Compare basic dimensions
     777            2 :  call check_(self%pkind == other%pkind, "Difference found in pkind.")
     778            2 :  call check_(self%nsppol == other%nsppol, "Difference found in nsppol.")
     779              :  !call check_(self%nstates == other%nstates, "Difference found in nstates.")
     780              :  call check_(self%cryst%compare(other%cryst) == 0, &
     781            2 :    "Difference found in cryst.")
     782              :  call check_(all(self%brange_spin == other%brange_spin), &
     783            8 :    "Difference found in brange_spin.")
     784              : 
     785              :  ! If bz_mismatch is not allowed, also compare k/q-grids
     786            2 :  if (present(bz_mismatch)) then
     787            2 :    if (.not. bz_mismatch) then
     788              :      call check_(all(abs(self%kpts_spin - other%kpts_spin) < tol6), &
     789         1004 :        "Difference found in kpts_spin.")
     790              :      call check_(all(abs(self%qpts_spin - other%qpts_spin) < tol6), &
     791         1004 :      "Difference found in nq_spin.")
     792              :    end if
     793              :  endif
     794              : 
     795            2 :  ABI_CHECK(ierr == 0, "Error in varpeq_compare, see previous messages!")
     796              : 
     797            2 :  call cwtime_report(" varpeq_compare", cpu, wall, gflops)
     798              : 
     799              :  contains
     800           12 :  subroutine check_(cond, msg)
     801              :    logical, intent(in) :: cond
     802              :    character(len=*), intent(in) :: msg
     803           12 :    ABI_CHECK_NOSTOP(cond, msg, ierr)
     804           12 :  end subroutine check_
     805              : 
     806              : end subroutine varpeq_compare
     807              : !!***
     808              : 
     809              : !----------------------------------------------------------------------
     810              : 
     811              : !!****f* m_varpeq/varpeq_ncread
     812              : !! NAME
     813              : !!  varpeq_ncread
     814              : !!
     815              : !! FUNCTION
     816              : !!  Reads basic dimensions of varpeq_t datatype from a *VPQ.nc netcdf file.
     817              : !!
     818              : !! INPUTS
     819              : !!  path=Path a *VPQ.nc file to be read.
     820              : !!  comm=MPI communicator.
     821              : !!  keep_open [optional]=if .true. keep the nc file handle open for further
     822              : !!    reading. Default: .false.
     823              : !!
     824              : !! OUTPUT
     825              : !!
     826              : !! SOURCE
     827              : 
     828            4 : subroutine varpeq_ncread(self, path, comm, keep_open)
     829              : 
     830              : !Arguments ------------------------------------
     831              :  class(varpeq_t), target, intent(inout) :: self
     832              :  character(len=fnlen), intent(in) :: path
     833              :  integer, intent(in) :: comm
     834              :  logical, optional, intent(in) :: keep_open
     835              : 
     836              : !Local variables-------------------------------
     837              :  integer :: ncid, nsppol, natom3, nstates
     838              :  real(dp) :: cpu, wall, gflops
     839            4 :  real(dp), contiguous, pointer :: rpt_d5(:,:,:,:,:)
     840              : !----------------------------------------------------------------------
     841              : 
     842            4 :  call cwtime(cpu, wall, gflops, "start")
     843              : 
     844            4 :  ABI_CHECK(file_exists(path), sjoin(" varpeq_ncread: cannot find *VPQ.nc file", path))
     845              : 
     846            4 :  NCF_CHECK(nctk_open_read(ncid, path, comm))
     847              : 
     848              :  ! Read crystal structure
     849            4 :  call self%cryst%ncread(ncid)
     850              : 
     851              :  ! Read varpeq dimensions
     852            4 :  NCF_CHECK(nctk_get_dim(ncid, "nsppol", self%nsppol))
     853            4 :  NCF_CHECK(nctk_get_dim(ncid, "nstates", self%nstates))
     854            4 :  NCF_CHECK(nctk_get_dim(ncid, "natom3", self%natom3))
     855            4 :  NCF_CHECK(nctk_get_dim(ncid, "max_nk", self%max_nk))
     856            4 :  NCF_CHECK(nctk_get_dim(ncid, "max_nq", self%max_nq))
     857            4 :  NCF_CHECK(nctk_get_dim(ncid, "max_nb", self%max_nb))
     858            4 :  nsppol = self%nsppol
     859            4 :  nstates = self%nstates
     860            4 :  natom3 = self%natom3
     861              : 
     862              :  ! Read data
     863              :  ! Static arrays
     864            4 :  NCF_CHECK(nf90_get_var(ncid, vid("vpq_pkind"), self%pkind))
     865            4 :  NCF_CHECK(nf90_get_var(ncid, vid("ngkpt"), self%ngkpt))
     866              : 
     867              :  ! Allocatable arrays
     868           12 :  ABI_MALLOC(self%nk_spin, (nsppol))
     869            8 :  ABI_MALLOC(self%nq_spin, (nsppol))
     870            8 :  ABI_MALLOC(self%nb_spin, (nsppol))
     871           12 :  ABI_MALLOC(self%brange_spin, (2, nsppol))
     872           16 :  ABI_MALLOC(self%kpts_spin, (3, self%max_nk, nsppol))
     873           16 :  ABI_MALLOC(self%qpts_spin, (3, self%max_nq, nsppol))
     874           24 :  ABI_MALLOC(self%a_spin, (self%max_nb, self%max_nk, nstates, nsppol))
     875           24 :  ABI_MALLOC(self%b_spin, (natom3, self%max_nq, nstates, nsppol))
     876              : 
     877              :  ! integer
     878            4 :  NCF_CHECK(nf90_get_var(ncid, vid("nk_spin"), self%nk_spin))
     879            4 :  NCF_CHECK(nf90_get_var(ncid, vid("nq_spin"), self%nq_spin))
     880            4 :  NCF_CHECK(nf90_get_var(ncid, vid("nb_spin"), self%nb_spin))
     881            4 :  NCF_CHECK(nf90_get_var(ncid, vid("brange_spin"), self%brange_spin))
     882              :  ! real
     883            4 :  NCF_CHECK(nf90_get_var(ncid, vid("kpts_spin"), self%kpts_spin))
     884            4 :  NCF_CHECK(nf90_get_var(ncid, vid("qpts_spin"), self%qpts_spin))
     885              :  ! complex
     886              :  ! TODO: is it possible to encapsulate this trick as some abstraction?
     887              :  call c_f_pointer(c_loc(self%a_spin), rpt_d5, &
     888           24 :    [2, self%max_nb, self%max_nk, nstates, nsppol])
     889            4 :  NCF_CHECK(nf90_get_var(ncid, vid("a_spin"), rpt_d5))
     890              : 
     891              :  call c_f_pointer(c_loc(self%b_spin), rpt_d5, &
     892           24 :    [2, natom3, self%max_nq, nstates, nsppol])
     893            4 :  NCF_CHECK(nf90_get_var(ncid, vid("b_spin"), rpt_d5))
     894              : 
     895            4 :  if (present(keep_open)) then
     896            2 :    if (keep_open) self%ncid = ncid
     897              :  else
     898            2 :    NCF_CHECK(nf90_close(ncid))
     899            2 :    self%ncid = nctk_noid
     900              :  end if
     901              : 
     902            4 :  self%is_complete = .false.
     903              : 
     904            8 :  call cwtime_report(" varpeq_ncread", cpu, wall, gflops)
     905              : 
     906              : !----------------------------------------------------------------------
     907              : 
     908              :  contains
     909           40 :   integer function vid(var_name)
     910              :     character(len=*),intent(in) :: var_name
     911           40 :     vid = nctk_idname(ncid, var_name)
     912              :   end function vid
     913              : 
     914              : end subroutine varpeq_ncread
     915              : !!***
     916              : 
     917              : !----------------------------------------------------------------------
     918              : 
     919              : !!****f* m_varpeq/varpeq_ncwrite
     920              : !! NAME
     921              : !!  varpeq_ncwrite
     922              : !!
     923              : !! FUNCTION
     924              : !!  Dump varpeq variables in a newly created *VPQ.nc netcdf file.
     925              : !!
     926              : !! INPUTS
     927              : !!  dtset<dataset_type>=All input variables for this dataset.
     928              : !!  dtfil<datafiles_types>=Variables related to files.
     929              : !!
     930              : !! OUTPUT
     931              : !!
     932              : !! SOURCE
     933              : 
     934           27 : subroutine varpeq_ncwrite(self, dtset, dtfil)
     935              : 
     936              : !Arguments ------------------------------------
     937              :  class(varpeq_t), target, intent(inout) :: self
     938              :  type(dataset_type), intent(in) :: dtset
     939              :  type(datafiles_type),intent(in) :: dtfil
     940              : 
     941              : !Local variables-------------------------------
     942              :  character(len=fnlen) :: path
     943              :  integer, parameter :: master = 0
     944              :  integer :: my_rank, ncid, ncerr
     945              :  real(dp) :: cpu, wall, gflops
     946            9 :  real(dp), contiguous, pointer :: rpt_d5(:,:,:,:,:)
     947              :  integer :: units(2)
     948              : !----------------------------------------------------------------------
     949              : 
     950           27 :  units = [std_out, ab_out]
     951              : 
     952            9 :  call cwtime(cpu, wall, gflops, "start")
     953              : 
     954            9 :  my_rank = xmpi_comm_rank(self%gstore%comm)
     955              : 
     956              :  ! Create netcdf file (only master works, HDF5 + MPI-IO can be handled after
     957              :  ! by reopening the file inside ncwrite_comm)
     958            9 :  path = strcat(dtfil%filnam_ds(4), "_VPQ.nc")
     959            9 :  if (my_rank == master) then
     960              : 
     961            9 :    call wrtout(units, sjoin(ch10, sjoin("Saving results to:", path)))
     962              : 
     963              :    ! Master creates the netcdf file used to store the data.
     964            9 :    NCF_CHECK(nctk_open_create(self%ncid, path, xmpi_comm_self))
     965            9 :    ncid = self%ncid
     966              : 
     967              :    ! Write the crystal (TR & invsersion symmetry only) & ebands dataset_type
     968            9 :    NCF_CHECK(self%cryst%ncwrite(ncid))
     969            9 :    NCF_CHECK(self%gstore%ebands%ncwrite(ncid))
     970              : 
     971              :    ! Add varpeq dimensions.
     972              :    ncerr = nctk_def_dims(ncid, [ &
     973              :      nctkdim_t("hop_nstep", self%hop_nstep), &
     974              :      nctkdim_t("nstep", self%nstep), nctkdim_t("nsppol", self%nsppol), &
     975              :      nctkdim_t("nstates", self%nstates), nctkdim_t("natom3", self%natom3), &
     976              :      nctkdim_t("max_nk", self%max_nk), nctkdim_t("max_nq", self%max_nq), &
     977              :      nctkdim_t("max_nb", self%max_nb), nctkdim_t("nkibz", self%gstore%nkibz), &
     978              :      nctkdim_t("nqibz", self%gstore%nqibz)], &
     979           99 :      defmode=.true.)
     980            9 :    NCF_CHECK(ncerr)
     981              : 
     982              :    ! Define scalars
     983              :    ! integers
     984              :    ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: &
     985              :      "eph_task", "nkbz", "nqbz", "frohl_ntheta", "vpq_avg_g", "vpq_translate", &
     986              :      "vpq_interp", "vpq_nstates", "vpq_nstep_ort", "vpq_select", "vpq_mesh_fact", &
     987          117 :      "vpq_hop_nstep"])
     988            9 :    NCF_CHECK(ncerr)
     989              :    ! real
     990              :    ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: &
     991           36 :      "vpq_tolgrs", "e_frohl", "vpq_mix_fact"])
     992            9 :    NCF_CHECK(ncerr)
     993              : 
     994              :    ! Define arrays with results
     995              :    ncerr = nctk_def_arrays(ncid, [ &
     996              :      nctkarr_t("vpq_mode", "c", "character_string_length"), &
     997              :      nctkarr_t("vpq_pkind", "c", "character_string_length"), &
     998              :      nctkarr_t("vpq_aseed", "c", "character_string_length"), &
     999              :      nctkarr_t("ngkpt", "int", "three"), &
    1000              :      nctkarr_t("gstore_ngqpt", "int", "three"), &
    1001              :      nctkarr_t("nk_spin", "int", "nsppol"), &
    1002              :      nctkarr_t("nq_spin", "int", "nsppol"), &
    1003              :      nctkarr_t("nb_spin", "int", "nsppol"), &
    1004              :      nctkarr_t("brange_spin", "int", "two, nsppol"), &
    1005              :      nctkarr_t("cvflag_spin", "int", "nstates, hop_nstep, nsppol"), &
    1006              :      nctkarr_t("hop_nstep2cv_spin", "int", "nsppol"), &
    1007              :      nctkarr_t("nstep2cv_spin", "int", "nstates, hop_nstep, nsppol"), &
    1008              :      nctkarr_t("vpq_trvec", "int", "three"), &
    1009              :      nctkarr_t("k2ibz_spin", "int", "max_nk, nsppol"), &
    1010              :      nctkarr_t("q2ibz_spin", "int", "max_nq, nsppol"), &
    1011              :      nctkarr_t("erange_spin", "dp", "nsppol"), &
    1012              :      nctkarr_t("hop_hist_spin", "dp", "five, nstates, hop_nstep, nsppol"), &
    1013              :      nctkarr_t("scf_hist_spin", "dp", "six, nstep, nstates, hop_nstep, nsppol"), &
    1014              :      nctkarr_t("kibz", "dp", "three, nkibz"), &
    1015              :      nctkarr_t("qibz", "dp", "three, nqibz"), &
    1016              :      nctkarr_t("kpts_spin", "dp", "three, max_nk, nsppol"), &
    1017              :      nctkarr_t("qpts_spin", "dp", "three, max_nq, nsppol"), &
    1018              :      nctkarr_t("cb_min_spin", "dp", "nsppol"), &
    1019              :      nctkarr_t("vb_max_spin", "dp", "nsppol"), &
    1020              :      nctkarr_t("vpq_gpr_energy", "dp", "two"), &
    1021              :      nctkarr_t("vpq_gpr_length", "dp", "three"), &
    1022              :      nctkarr_t("a_spin", "dp", "two, max_nb, max_nk, nstates, nsppol"), &
    1023              :      nctkarr_t("b_spin", "dp", "two, natom3, max_nq, nstates, nsppol") &
    1024          261 :    ])
    1025            9 :    NCF_CHECK(ncerr)
    1026              : 
    1027              :    ! Write data
    1028            9 :    NCF_CHECK(nctk_set_datamode(ncid))
    1029              :    ! Scalars
    1030              :    ! integer
    1031              :    ncerr = nctk_write_iscalars(ncid, [character(len=nctk_slen) :: &
    1032              :      "eph_task", "nkbz", "nqbz", "frohl_ntheta", "vpq_avg_g", "vpq_translate", &
    1033              :      "vpq_interp", "vpq_nstates", "vpq_nstep_ort", "vpq_select", "vpq_mesh_fact", &
    1034              :      "vpq_hop_nstep"], &
    1035              :      [dtset%eph_task, self%gstore%nkbz, self%gstore%nqbz, self%frohl_ntheta, &
    1036              :       dtset%vpq_avg_g, dtset%vpq_translate, dtset%vpq_interp, dtset%vpq_nstates, &
    1037          225 :       dtset%vpq_nstep_ort, dtset%vpq_select, dtset%vpq_mesh_fact, dtset%vpq_hop_nstep])
    1038            9 :    NCF_CHECK(ncerr)
    1039              :    ! real
    1040              :    ncerr = nctk_write_dpscalars(ncid, [character(len=nctk_slen) :: &
    1041              :      "vpq_tolgrs", "e_frohl", "vpq_mix_fact"], &
    1042           63 :      [self%tolgrs, self%e_frohl, dtset%vpq_mix_fact])
    1043            9 :    NCF_CHECK(ncerr)
    1044              : 
    1045              :    ! Arrays
    1046              :    ! character
    1047            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vpq_mode"), self%mode))
    1048            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vpq_pkind"), self%pkind))
    1049            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vpq_aseed"), self%aseed))
    1050              :    ! integer
    1051            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ngkpt"), self%ngkpt))
    1052            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "gstore_ngqpt"), self%gstore%ngqpt))
    1053            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "nk_spin"), self%nk_spin))
    1054            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "nq_spin"), self%nq_spin))
    1055            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "nb_spin"), self%nb_spin))
    1056            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "brange_spin"), self%brange_spin))
    1057            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "cvflag_spin"), self%cvflag_spin))
    1058            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "hop_nstep2cv_spin"), self%hop_nstep2cv_spin))
    1059            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "nstep2cv_spin"), self%nstep2cv_spin))
    1060            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vpq_trvec"), dtset%vpq_trvec))
    1061            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "k2ibz_spin"), self%k2ibz_spin))
    1062            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "q2ibz_spin"), self%q2ibz_spin))
    1063              :    ! real
    1064            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "hop_hist_spin"), self%hop_hist_spin))
    1065            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "scf_hist_spin"), self%scf_hist_spin))
    1066            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kibz"), self%gstore%kibz))
    1067            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "qibz"), self%gstore%qibz))
    1068            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kpts_spin"), self%kpts_spin))
    1069            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "qpts_spin"), self%qpts_spin))
    1070            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "cb_min_spin"), self%gaps%cb_min))
    1071            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vb_max_spin"), self%gaps%vb_max))
    1072            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vpq_gpr_energy"), dtset%vpq_gpr_energy))
    1073            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vpq_gpr_length"), dtset%vpq_gpr_length))
    1074            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "erange_spin"), self%erange_spin))
    1075              :    ! complex
    1076              :    call c_f_pointer(c_loc(self%a_spin), rpt_d5, &
    1077           54 :      [2, self%max_nb, self%max_nk, self%nstates, self%nsppol])
    1078            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "a_spin"), rpt_d5))
    1079              : 
    1080              :    call c_f_pointer(c_loc(self%b_spin), rpt_d5, &
    1081           54 :      [2, self%natom3, self%max_nq, self%nstates, self%nsppol])
    1082            9 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "b_spin"), rpt_d5))
    1083              :  end if ! master
    1084              : 
    1085            9 :  call xmpi_barrier(self%gstore%comm)
    1086            9 :  call cwtime_report(" varpeq: ncwrite", cpu, wall, gflops)
    1087              : 
    1088            9 : end subroutine varpeq_ncwrite
    1089              : !!***
    1090              : 
    1091              : !!----------------------------------------------------------------------
    1092              : 
    1093              : !!****f* m_varpeq/varpeq_print_metadata
    1094              : !! NAME
    1095              : !!  varpeq_print_metadata
    1096              : !!
    1097              : !! FUNCTION
    1098              : !!  Output parameters defining varpeq calculation
    1099              : !!
    1100              : !! INPUTS
    1101              : !!
    1102              : !! OUTPUT
    1103              : !!
    1104              : !! SOURCE
    1105              : 
    1106              : !subroutine varpeq_print_metadata(self, dtset)
    1107            9 :  subroutine varpeq_print_metadata(self)
    1108              : 
    1109              : !Arguments ------------------------------------
    1110              :  class(varpeq_t), target, intent(inout) :: self
    1111              : !type(dataset_type), intent(in) :: dtset
    1112              : 
    1113              : !Local variables-------------------------------
    1114              : !scalars
    1115              :  character(len=abi_slen) :: msg
    1116              : !character(len=abi_slen) :: use_frohl = "no"
    1117              :  integer :: spin, my_rank
    1118              :  integer, parameter :: master = 0
    1119              : !arrays
    1120              :  integer :: units(2)
    1121              : 
    1122              : !----------------------------------------------------------------------
    1123              : 
    1124            9 :  my_rank = xmpi_comm_rank(self%gstore%comm)
    1125              : 
    1126           27 :  units = [std_out, ab_out]
    1127            9 :  if (my_rank == master) then
    1128              : 
    1129            9 :    call title_("Polaron:")
    1130              : 
    1131            9 :    call entry_("Polaron kind", self%pkind)
    1132            9 :    write(msg, '(i0,a,i0,a,i0)') self%ngkpt(1), "x", self%ngkpt(2), "x", self%ngkpt(3)
    1133            9 :    call entry_("BvK supercell", msg)
    1134            9 :    call entry_("Number of independent spin polarizations", itoa(self%nsppol))
    1135            9 :    call entry_("Number of polaronic states", itoa(self%nstates))
    1136            9 :    call entry_("Filtering of electronic states", yesno(self%use_filter))
    1137            9 :    if (self%use_filter) then
    1138            2 :      do spin=1,self%nsppol
    1139            1 :        write(msg, '(a,i0,a,i0)') "Energy filter wrt band edge for spin ", &
    1140            2 :          spin, "/", self%nsppol
    1141            2 :        call entry_(msg, sjoin(ftoa(self%erange_spin(spin)*Ha_eV, "es8.2"), "eV"))
    1142              :      enddo
    1143              :    endif
    1144              : 
    1145            9 :    call title_("Long-range corrections:")
    1146            9 :    call entry_("Frohlich correction", yesno(self%frohl_ntheta > 0))
    1147            9 :    if (self%frohl_ntheta > 0) then
    1148            9 :      call entry_("Frohlich correction value", sjoin(ftoa(self%e_frohl*Ha_eV), "eV"))
    1149            9 :      call entry_("Frohlich correction included in matrix elements", yesno(self%g0_flag))
    1150              :    endif
    1151              : 
    1152            9 :    call title_("Optimization parameters:")
    1153              : 
    1154              :    ! TODO change this once a support for starting from B is added
    1155            9 :    call entry_("Initial seed", "charge localization A_nk")
    1156            9 :    call entry_("Initial seed type", strseed())
    1157              : 
    1158            9 :    call entry_("Tolerance on the gradient norm", ftoa(self%tolgrs, "es8.2"))
    1159            9 :    call entry_("Maximum number of iterations per state", itoa(self%nstep))
    1160            9 :    if (self%nstates > 1) then
    1161            2 :      call wrtout(units, " (for pstate > 1)")
    1162            2 :      call entry_("Number of orthogonaliztion steps", itoa(self%nstep_ort))
    1163            2 :      call entry_("Translational invariance", yesno(self%translate))
    1164              :    endif
    1165              : 
    1166              :  endif
    1167              : 
    1168              :  contains
    1169           27 :  subroutine title_(str)
    1170              :    character(len=*), intent(in) :: str
    1171           27 :    call wrtout(units, sjoin(ch10, str))
    1172           27 :  end subroutine title_
    1173              : 
    1174          113 :  subroutine entry_(name, val)
    1175              :    character(len=*), intent(in) :: name
    1176              :    character(len=*), intent(in) :: val
    1177              :    character(len=abi_slen) :: output
    1178          113 :    write(output, '(a5,a,a2,a)') "* ", trim(name), ": ", trim(val)
    1179          113 :    call wrtout(units, output)
    1180          113 :  end subroutine entry_
    1181              : 
    1182            9 :  character(len=abi_slen) function strseed()
    1183           18 :    select case(self%aseed)
    1184              :    case ("gau_energy")
    1185            9 :      write(strseed, *) "Gaussian, based on the electroic energies"
    1186              :    case ("gau_length")
    1187            0 :      write(strseed, *) "Gaussian, based on the localizaiton length"
    1188              :    case ("random")
    1189            0 :      write(strseed, *) "random"
    1190              :    case ("even")
    1191            0 :      write(strseed, *) "even"
    1192              :    case ("localize")
    1193            0 :      write(strseed, *) "manual loclization"
    1194              :    case default
    1195            9 :      write(strseed, *) "undefined"
    1196              :    end select
    1197              : 
    1198            9 :    if (self%interp .or. self%restart) then
    1199            0 :      write(strseed, *) "loaded from file"
    1200              :    endif
    1201              : 
    1202            9 :    strseed = adjustl(strseed)
    1203            9 :  end function strseed
    1204              : 
    1205              : end subroutine varpeq_print_metadata
    1206              : !!***
    1207              : 
    1208              : !!----------------------------------------------------------------------
    1209              : 
    1210              : !!****f* m_varpeq/varpeq_print_scf_results
    1211              : !! NAME
    1212              : !!  varpeq_print_scf_results
    1213              : !!
    1214              : !! FUNCTION
    1215              : !!  Output SCF optimization results
    1216              : !!
    1217              : !! INPUTS
    1218              : !!  ineb [optional]=Hopping iteration. Relevant only if self%vpq_mode="hopping".
    1219              : !!
    1220              : !! OUTPUT
    1221              : !!
    1222              : !! SOURCE
    1223              : 
    1224            8 : subroutine varpeq_print_scf_results(self, ihop)
    1225              : 
    1226              : !Arguments ------------------------------------
    1227              :  class(varpeq_t), target, intent(inout) :: self
    1228              :  integer, optional, intent(in) :: ihop
    1229              : 
    1230              : !Local variables-------------------------------
    1231              : !scalars
    1232              :  character(len=5000) :: msg
    1233              :  integer, parameter :: master = 0
    1234              :  integer :: my_rank, spin, ip, ii, ihop_
    1235              : !arrays
    1236              :  integer :: units(2)
    1237              : !----------------------------------------------------------------------
    1238              : 
    1239            8 :  my_rank = xmpi_comm_rank(self%gstore%comm)
    1240              : 
    1241            8 :  ihop_ = 1
    1242            8 :  if (present(ihop)) ihop_ = ihop
    1243              : 
    1244           24 :  units = [std_out, ab_out]
    1245            8 :  if (my_rank == master) then
    1246           16 :    do spin=1,self%gstore%nsppol
    1247           26 :      do ip=1,self%nstates
    1248           10 :        call header_(spin, ip)
    1249              : 
    1250          334 :        do ii=1,self%nstep2cv_spin(ip, ihop_, spin)
    1251          326 :          call report_(spin, ip, ii, ihop_, self%nstep2cv_spin(ip, ihop_, spin))
    1252              : 
    1253              :        enddo
    1254              :      enddo
    1255              :    enddo
    1256              :  endif
    1257              : 
    1258              :  contains
    1259           10 :  subroutine header_(spin, state)
    1260              :    integer, intent(in) :: spin, state
    1261              :    character(len=5000) :: sep
    1262              : 
    1263           10 :    call wrtout(units, "")
    1264           10 :    if (state == 1) then
    1265            8 :      call wrtout(units, " Printing the optimization logs")
    1266              :    endif
    1267              : 
    1268           10 :    write(sep, "(a3,a)") "", repeat('-', 86)
    1269              :    write(msg, '(a5,a,i0,a,i0,a,i0,a,i0)') &
    1270           10 :      "* ", "spin ", spin, "/", self%nsppol, ", pstate ", state, "/", self%nstates
    1271              : 
    1272           10 :    call wrtout(units, sep)
    1273           10 :    call wrtout(units, msg)
    1274           10 :    write(msg, '(a3,a)') "", "* values in the optimization log are in (a.u.)"
    1275           10 :    call wrtout(units, msg)
    1276              : 
    1277           10 :    if ((state > 1) .and. (self%nstep_ort > 1)) then
    1278            2 :      write(msg, "(a3,a,i0)") "", "(o) - orthogonal all pstates < ", state
    1279            2 :      call wrtout(units, msg)
    1280              :    endif
    1281              : 
    1282           10 :    call wrtout(units, sep)
    1283              :    !write(msg, '(a3,a4,7a13,a5)') "", "Step", "E_pol", "E_el", "E_ph", "E_elph", "E2_elph", &
    1284              :    !  "epsilon", "||grad||", ""
    1285           10 :    write(msg, '(a3,a4,6a13,a5)') "", "Step", "E_pol", "E_el", "E_ph", "E_elph", &
    1286           20 :      "epsilon", "||grad||", ""
    1287           10 :    call wrtout(units, msg)
    1288           10 :  end subroutine header_
    1289              : 
    1290          316 :  subroutine report_(spin, state, step, hop_step, step2conv)
    1291              :    integer, intent(in) :: spin, state, step, hop_step, step2conv
    1292              :    character(len=5000) :: sep
    1293              :    character(len=abi_slen) :: ort_flag
    1294              :    logical :: is_conv
    1295              :    real(dp) :: enpol, enel, enph, enelph, eps, grs
    1296              : 
    1297          316 :    enpol = self%scf_hist_spin(1, step, state, hop_step, spin)
    1298          316 :    enel = self%scf_hist_spin(2, step, state, hop_step, spin)
    1299          316 :    enph = self%scf_hist_spin(3, step, state, hop_step, spin)
    1300          316 :    enelph = self%scf_hist_spin(4, step, state, hop_step, spin)
    1301          316 :    eps = self%scf_hist_spin(5, step, state, hop_step, spin)
    1302          316 :    grs = self%scf_hist_spin(6, step, state, hop_step, spin)
    1303              : 
    1304          316 :    write(sep, "(a3,a)") "", repeat('-', 86)
    1305              : 
    1306              :    ! for states > 1 add flag if orthogonalization is used
    1307          316 :    write(ort_flag, '(a)') ""
    1308          316 :    if ((ip > 1) .and. (step <= self%nstep_ort)) then
    1309           60 :      write(ort_flag, '(a)') "(o)"
    1310              :    endif
    1311              : 
    1312              :    write(msg,'(a3,i4,6es13.4,a5)') &
    1313          316 :      "", step, enpol, enel, enph, enelph, eps, grs, trim(ort_flag)
    1314          316 :    call wrtout(units, msg)
    1315              : 
    1316          316 :    if (step == step2conv) then
    1317              : 
    1318           10 :      is_conv = (self%cvflag_spin(state, hop_step, spin) == 1)
    1319           10 :      if (is_conv) then
    1320            9 :        write(msg, '(a3,a,es11.4,a,es11.4)') "", "Converged: ||grad||=", grs, &
    1321           18 :          " < vpq_tolgrs=", self%tolgrs
    1322              :      else
    1323            1 :        write(msg, '(a3,a,es11.4,a,es11.4)') "", "Unconverged: ||grad||=", grs, &
    1324            2 :          " > vpq_tolgrs=", self%tolgrs
    1325              :      endif
    1326              : 
    1327           10 :      call wrtout(units, sep)
    1328           10 :      call wrtout(units, msg)
    1329              : 
    1330           10 :      write(msg, '(a3,a,es17.8)') "", "E_pol (eV):", enpol*Ha_eV
    1331           10 :      call wrtout(units, msg)
    1332           10 :      write(msg, '(a3,a,es17.8)') "", "  eps (eV):", eps*Ha_eV
    1333           10 :      call wrtout(units, msg)
    1334              : 
    1335           10 :      call wrtout(units, sep)
    1336              : 
    1337              :    endif
    1338          316 :  end subroutine report_
    1339              : 
    1340              : end subroutine varpeq_print_scf_results
    1341              : !!***
    1342              : 
    1343              : !!----------------------------------------------------------------------
    1344              : 
    1345              : !!****f* m_varpeq/varpeq_print_hop_results
    1346              : !! NAME
    1347              : !!  varpeq_print_hop_results
    1348              : !!
    1349              : !! FUNCTION
    1350              : !!  Output hopping optimization results
    1351              : !!
    1352              : !! INPUTS
    1353              : !!
    1354              : !! OUTPUT
    1355              : !!
    1356              : !! SOURCE
    1357              : 
    1358            1 : subroutine varpeq_print_hop_results(self)
    1359              : 
    1360              : !Arguments ------------------------------------
    1361              :  class(varpeq_t), target, intent(inout) :: self
    1362              : 
    1363              : !Local variables-------------------------------
    1364              : !scalars
    1365              :  character(len=5000) :: msg
    1366              :  integer, parameter :: master = 0
    1367              :  integer :: my_rank, spin, ip, ihop
    1368              :  integer :: hop_nstep2cv, scf_nstep2cv
    1369              : !arrays
    1370              :  integer :: units(2)
    1371              : 
    1372              : !----------------------------------------------------------------------
    1373              : 
    1374            1 :  my_rank = xmpi_comm_rank(self%gstore%comm)
    1375              : 
    1376              : 
    1377            3 :  units = [std_out, ab_out]
    1378              : 
    1379            1 :  if (my_rank == master) then
    1380            2 :    do spin=1,self%gstore%nsppol
    1381            1 :      hop_nstep2cv = self%hop_nstep2cv_spin(spin)
    1382              : 
    1383            1 :      call hop_header_(spin)
    1384           16 :      do ihop=1,self%hop_nstep2cv_spin(spin)
    1385           16 :        call hop_report_(spin, ihop)
    1386              :      enddo
    1387              : 
    1388            1 :      call header_(spin)
    1389           11 :      do ip=1,self%nstates
    1390            9 :        scf_nstep2cv = self%nstep2cv_spin(ip, hop_nstep2cv, spin)
    1391           10 :        call report_(spin, ip, scf_nstep2cv, hop_nstep2cv)
    1392              :      enddo
    1393              : 
    1394              :    enddo
    1395              :  endif
    1396              : 
    1397              :  contains
    1398            1 :  subroutine header_(spin)
    1399              :    integer, intent(in) :: spin
    1400              :    character(len=5000) :: sep
    1401              : 
    1402            1 :    call wrtout(units, "")
    1403            1 :    call wrtout(units, " Printing the minimal energy path")
    1404              : 
    1405            1 :    write(sep, "(a3,a)") "", repeat('-', 86)
    1406              :    write(msg, '(a5,a,i0,a,i0)') &
    1407            1 :      "* ", "spin ", spin, "/", self%nsppol
    1408              : 
    1409            1 :    call wrtout(units, sep)
    1410            1 :    call wrtout(units, msg)
    1411            1 :    write(msg, '(a3,a)') "", "* values are in (a.u.)"
    1412            1 :    call wrtout(units, msg)
    1413              : 
    1414            1 :    call wrtout(units, sep)
    1415            1 :    write(msg, '(a3,a4,6a13)') "", "Image", "E_pol", "E_el", "E_ph", "E_elph", &
    1416            2 :      "epsilon", "||el_grad||"
    1417            1 :    call wrtout(units, msg)
    1418            1 :  end subroutine header_
    1419              : 
    1420            1 :  subroutine hop_header_(spin)
    1421              :    integer, intent(in) :: spin
    1422              :    character(len=5000) :: sep
    1423              : 
    1424            1 :    call wrtout(units, "")
    1425            1 :    call wrtout(units, " Printing the hopping optimization log")
    1426              : 
    1427            1 :    write(sep, "(a3,a)") "", repeat('-', 43)
    1428              :    write(msg, '(a5,a,i0,a,i0)') &
    1429            1 :      "* ", "spin ", spin, "/", self%nsppol
    1430              : 
    1431            1 :    call wrtout(units, sep)
    1432            1 :    call wrtout(units, msg)
    1433            1 :    write(msg, '(a3,a)') "", "* values are in (a.u.)"
    1434            1 :    call wrtout(units, msg)
    1435              : 
    1436            1 :    call wrtout(units, sep)
    1437            1 :    write(msg, '(a3,a4,a17,a18)') "", "Step", &
    1438            2 :      "max||ph_grad||", "max||hop_grad||"
    1439            1 :    call wrtout(units, msg)
    1440            1 :  end subroutine hop_header_
    1441              : 
    1442            9 :  subroutine report_(spin, state, step, hop_step)
    1443              :    integer, intent(in) :: spin, state, step, hop_step
    1444              :    character(len=5000) :: sep
    1445              :    real(dp) :: enpol, enel, enph, enelph, eps, grs
    1446              :    !real(dp) :: min_epol, max_epol, ehop
    1447              : 
    1448            9 :    enpol = self%scf_hist_spin(1, step, state, hop_step, spin)
    1449            9 :    enel = self%scf_hist_spin(2, step, state, hop_step, spin)
    1450            9 :    enph = self%scf_hist_spin(3, step, state, hop_step, spin)
    1451            9 :    enelph = self%scf_hist_spin(4, step, state, hop_step, spin)
    1452            9 :    eps = self%scf_hist_spin(5, step, state, hop_step, spin)
    1453            9 :    grs = self%scf_hist_spin(6, step, state, hop_step, spin)
    1454              : 
    1455            9 :    write(sep, "(a3,a)") "", repeat('-', 86)
    1456              : 
    1457              :    write(msg,'(a3,i4,6es13.4)') &
    1458            9 :      "", state, enpol, enel, enph, enelph, eps, grs
    1459            9 :    call wrtout(units, msg)
    1460              : 
    1461            9 :    if (state == self%nstates) then
    1462            1 :      call wrtout(units, sep)
    1463              :    endif
    1464              : 
    1465            9 :  end subroutine report_
    1466              : 
    1467           15 :  subroutine hop_report_(spin, hop_step)
    1468              :    integer, intent(in) :: spin, hop_step
    1469              :    character(len=5000) :: sep
    1470              :    real(dp) :: ph_max_grs, hop_max_grs
    1471              : 
    1472          165 :    ph_max_grs = maxval(self%hop_hist_spin(1, :, hop_step, spin))
    1473          165 :    hop_max_grs = maxval(self%hop_hist_spin(2, :, hop_step, spin))
    1474              : 
    1475           15 :    write(sep, "(a3,a)") "", repeat('-', 43)
    1476              : 
    1477              :    write(msg,'(a3,i4,es17.4,es18.4)') &
    1478           15 :      "", hop_step, ph_max_grs, hop_max_grs
    1479           15 :    call wrtout(units, msg)
    1480              : 
    1481           15 :    if (hop_step == self%hop_nstep2cv_spin(spin)) then
    1482            1 :      call wrtout(units, sep)
    1483              :    endif
    1484              : 
    1485           15 :  end subroutine hop_report_
    1486              : 
    1487              : end subroutine varpeq_print_hop_results
    1488              : !!***
    1489              : 
    1490              : !!----------------------------------------------------------------------
    1491              : 
    1492              : !!****f* m_varpeq/varpeq_collect
    1493              : !! NAME
    1494              : !!  varpeq_collect
    1495              : !!
    1496              : !! FUNCTION
    1497              : !!  Collect SCF optimization results for each spin
    1498              : !!
    1499              : !! INPUTS
    1500              : !!
    1501              : !! OUTPUT
    1502              : !!
    1503              : !! SOURCE
    1504              : 
    1505          198 : subroutine varpeq_collect(self)
    1506              : 
    1507              : !Arguments ------------------------------------
    1508              :  class(varpeq_t), target, intent(inout) :: self
    1509              : 
    1510              : !Local variables-------------------------------
    1511              :  class(gqk_t), pointer :: gqk
    1512              :  class(polstate_t), pointer :: polstate
    1513              :  integer :: ierr
    1514              :  integer :: my_is, spin, my_ik, ik_glob, ik_ibz, ip
    1515              :  integer :: my_iq, iq_glob, iq_ibz, my_pert, pert_glob
    1516              :  integer :: oc_scf, oc_a, oc_b, oc_k, oc_q
    1517              : !----------------------------------------------------------------------
    1518              : 
    1519              :  ! Gather the SCF process evolution data
    1520           18 :  call xmpi_sum(self%cvflag_spin, self%gstore%comm, ierr)
    1521           18 :  call xmpi_sum(self%scf_hist_spin, self%gstore%comm, ierr)
    1522           18 :  call xmpi_sum(self%nstep2cv_spin, self%gstore%comm, ierr)
    1523              : 
    1524           18 :  call xmpi_sum(self%hop_hist_spin, self%gstore%comm, ierr)
    1525           18 :  call xmpi_sum(self%hop_nstep2cv_spin, self%gstore%comm, ierr)
    1526              : 
    1527              :  ! Gather electron/phonon vectors and k/q points
    1528        13534 :  self%a_spin(:,:,:,:) = zero
    1529        31364 :  self%b_spin(:,:,:,:) = zero
    1530         1382 :  self%k2ibz_spin(:,:) = zero
    1531         2398 :  self%q2ibz_spin(:,:) = zero
    1532         9484 :  self%qpts_spin(:,:,:) = zero
    1533         5420 :  self%kpts_spin(:,:,:) = zero
    1534           36 :  do my_is=1,self%gstore%my_nspins
    1535           18 :    spin = self%gstore%my_spins(my_is)
    1536           18 :    gqk => self%gstore%gqk(my_is)
    1537           18 :    polstate => self%polstate(spin)
    1538              : 
    1539           56 :    do ip=1,self%nstates
    1540              : 
    1541              :      ! electronic vector
    1542         3492 :      do my_ik=1,gqk%my_nk
    1543         3454 :        ik_glob = gqk%my_kstart + my_ik - 1
    1544        13498 :        self%a_spin(:, ik_glob, ip, spin) = polstate%my_a(:, my_ik, ip)
    1545              :      enddo
    1546              : 
    1547              :      ! phonon vector
    1548         4526 :      do my_iq=1,gqk%my_nq
    1549         4470 :        iq_glob = gqk%my_qstart + my_iq - 1
    1550        31328 :        do my_pert=1,gqk%my_npert
    1551        26820 :          pert_glob = gqk%my_pert_start + my_pert - 1
    1552       168054 :          self%b_spin(pert_glob, iq_glob, :, spin) = polstate%my_b(my_pert, my_iq, :)
    1553              :        enddo
    1554              :      enddo
    1555              : 
    1556              :    enddo
    1557              : 
    1558              :    ! k-points
    1559         1364 :    do my_ik=1,gqk%my_nk
    1560         1346 :      ik_ibz = gqk%my_k2ibz(1, my_ik)
    1561         1346 :      ik_glob = gqk%my_kstart + my_ik - 1
    1562         5384 :      self%kpts_spin(:, ik_glob, spin) = polstate%my_kpts(:, my_ik)
    1563         1364 :      self%k2ibz_spin(ik_glob, spin) = ik_ibz
    1564              :    enddo
    1565              : 
    1566              :    ! q-points
    1567         2398 :    do my_iq=1,gqk%my_nq
    1568         2362 :      iq_ibz = gqk%my_q2ibz(1, my_iq)
    1569         2362 :      iq_glob = gqk%my_qstart + my_iq - 1
    1570         9448 :      self%qpts_spin(:, iq_glob, spin) = polstate%my_qpts(:, my_iq)
    1571         2380 :      self%q2ibz_spin(iq_glob, spin) = iq_ibz
    1572              :    enddo
    1573              : 
    1574              :  enddo
    1575              : 
    1576           18 :  call xmpi_sum(self%a_spin, self%gstore%comm, ierr)
    1577           18 :  call xmpi_sum(self%b_spin, self%gstore%comm, ierr)
    1578           18 :  call xmpi_sum(self%k2ibz_spin, self%gstore%comm, ierr)
    1579           18 :  call xmpi_sum(self%q2ibz_spin, self%gstore%comm, ierr)
    1580           18 :  call xmpi_sum(self%kpts_spin, self%gstore%comm, ierr)
    1581           18 :  call xmpi_sum(self%qpts_spin, self%gstore%comm, ierr)
    1582              : 
    1583              :  ! Hack to mimic the summation over a non-existing spin communicator
    1584              :  ! Divide by the number of times we overcount, as we use the global communicator
    1585           36 :  do my_is=1,self%gstore%my_nspins
    1586           18 :    spin = self%gstore%my_spins(my_is)
    1587           18 :    gqk => self%gstore%gqk(my_is)
    1588           18 :    polstate => self%polstate(spin)
    1589              : 
    1590           18 :    oc_scf = gqk%comm%nproc
    1591           18 :    oc_a = gqk%qpt_pert_comm%nproc
    1592           18 :    oc_b = gqk%kpt_comm%nproc
    1593           18 :    oc_k = oc_a
    1594           18 :    oc_q = oc_b * gqk%pert_comm%nproc
    1595              : 
    1596          354 :    self%cvflag_spin(:,:,spin) = self%cvflag_spin(:,:,spin) / oc_scf
    1597       197264 :    self%scf_hist_spin(:,:,:,:,spin) = self%scf_hist_spin(:,:,:,:,spin) / oc_scf
    1598          354 :    self%nstep2cv_spin(:,:,spin) = self%nstep2cv_spin(:,:,spin) / oc_scf
    1599         1804 :    self%hop_hist_spin(:,:,:,spin) = self%hop_hist_spin(:,:,:,spin) / oc_scf
    1600           18 :    self%hop_nstep2cv_spin(spin) = self%hop_nstep2cv_spin(spin) / oc_scf
    1601              : 
    1602        13516 :    self%a_spin(:,:,:,spin) = self%a_spin(:,:,:,spin) / oc_a
    1603        31346 :    self%b_spin(:,:,:,spin) = self%b_spin(:,:,:,spin) / oc_b
    1604         1364 :    self%k2ibz_spin(:,spin) = self%k2ibz_spin(:,spin) / oc_k
    1605         2380 :    self%q2ibz_spin(:,spin) = self%q2ibz_spin(:,spin) / oc_q
    1606         5402 :    self%kpts_spin(:,:,spin) = self%kpts_spin(:,:,spin) / oc_k
    1607         9484 :    self%qpts_spin(:,:,spin) = self%qpts_spin(:,:,spin) / oc_q
    1608              :  enddo
    1609              : 
    1610           18 : end subroutine varpeq_collect
    1611              : !!***
    1612              : 
    1613              : !----------------------------------------------------------------------
    1614              : 
    1615              : !!****f* m_varpeq/varpeq_load
    1616              : !! NAME
    1617              : !!  varpeq_load
    1618              : !!
    1619              : !! FUNCTION
    1620              : !!  Load and (optionally) interpolate the initial electronic vector A_nk from
    1621              : !!  a *VPQ.nc netcdf file. Store result in the self%a_spin variable.
    1622              : !!
    1623              : !! INPUTS
    1624              : !!  dtfil<datafiles_types>=Variables related to files.
    1625              : !!  pselect=Which state to select for reload/interpolation. Non-positive value
    1626              : !!    selects all states.
    1627              : !!
    1628              : !! OUTPUT
    1629              : !!
    1630              : !! SOURCE
    1631              : 
    1632            0 : subroutine varpeq_load(self, dtfil, pselect)
    1633              : 
    1634              : !Arguments ------------------------------------
    1635              :  class(varpeq_t), target, intent(inout) :: self
    1636              :  type(datafiles_type), intent(in) :: dtfil
    1637              :  integer,intent(in) :: pselect
    1638              : 
    1639              : !Local variables-------------------------------
    1640              : !scalars
    1641            0 :  type(varpeq_t) :: vpq_ld
    1642            0 :  type(bzlint_t) :: bzlint
    1643              :  logical :: single_state
    1644              :  integer, parameter :: master = 0
    1645              :  integer :: my_rank, comm, ierr
    1646              :  integer :: spin, ip, nk, nb, ik, ib
    1647              :  real(dp) :: cpu, wall, gflops
    1648              : !arrays
    1649              :  integer :: units(2)
    1650              :  real(dp) :: kpt(3)
    1651            0 :  real(dp), allocatable :: ak(:), kpts_ld(:,:)
    1652            0 :  real(dp), contiguous, pointer :: rpt_d2(:,:)
    1653            0 :  complex(dp), allocatable, target :: a_ld(:,:)
    1654              : !----------------------------------------------------------------------
    1655              : 
    1656            0 :  call cwtime(cpu, wall, gflops, "start")
    1657              : 
    1658            0 :  units = [std_out, ab_out]
    1659            0 :  comm = self%gstore%comm; my_rank = xmpi_comm_rank(comm)
    1660              : 
    1661              :  ! Read A_nk from file. Only the master processor reads, then broadcasts the data
    1662            0 :  if (my_rank == master) then
    1663            0 :    call vpq_ld%ncread(dtfil%filvpqin, xmpi_comm_self, keep_open=.false.)
    1664              : 
    1665              :    ! Consitency check
    1666            0 :    call self%compare(vpq_ld, bz_mismatch=self%interp)
    1667            0 :    if (pselect > 0) then
    1668            0 :      ABI_CHECK(self%nstates == 1, "vpq_pstates must be 1 if vpq_select > 0.")
    1669            0 :      ABI_CHECK(pselect <= vpq_ld%nstates, "vpq_select must be <= loaded nstates.")
    1670              :      single_state = .true.
    1671              :    else
    1672            0 :      ABI_CHECK(self%nstates == vpq_ld%nstates, "Diefference found in nstates.")
    1673              :      single_state = .false.
    1674              :    endif
    1675              : 
    1676            0 :    self%a_spin(:,:,:,:) = zero
    1677              : 
    1678            0 :    if (self%interp) then ! Interpolation
    1679            0 :      call wrtout(units, " - interpolating previous A_nk")
    1680            0 :      do spin=1,self%nsppol
    1681              :        ! Setting basic dimensions & arrays
    1682            0 :        nk = vpq_ld%nk_spin(spin); nb = vpq_ld%nb_spin(spin)
    1683            0 :        ABI_MALLOC(kpts_ld, (3, nk))
    1684            0 :        ABI_MALLOC(a_ld, (nb, nk))
    1685            0 :        ABI_MALLOC(ak, (2*nb))
    1686            0 :        kpts_ld(:,:) = vpq_ld%kpts_spin(:, 1:nk, spin)
    1687              : 
    1688              :        ! Here, interpolation is performed
    1689            0 :        do ip=1,self%nstates
    1690              : 
    1691            0 :          if (single_state) then
    1692            0 :            a_ld(:,:) = vpq_ld%a_spin(:, 1:nk, pselect, spin)
    1693              :          else
    1694            0 :            a_ld(:,:) = vpq_ld%a_spin(:, 1:nk, ip, spin)
    1695              :          endif
    1696              : 
    1697            0 :          call c_f_pointer(c_loc(a_ld), rpt_d2, [2*nb, nk])
    1698              : 
    1699            0 :          call bzlint%init(vpq_ld%ngkpt, 2*nb, nk, kpts_ld, rpt_d2)
    1700              : 
    1701            0 :          do ik=1,self%nk_spin(spin)
    1702            0 :            kpt(:) = self%kpts_spin(:, ik, spin)
    1703            0 :            call bzlint%interp(kpt, ak)
    1704              : 
    1705            0 :            do ib=1,nb
    1706            0 :              self%a_spin(ib, ik, ip, spin) = ak(2*ib-1) + j_dpc*ak(2*ib)
    1707              :            enddo
    1708              :          enddo
    1709            0 :          call bzlint%free()
    1710              : 
    1711              :        enddo
    1712            0 :        ABI_FREE(kpts_ld)
    1713            0 :        ABI_FREE(a_ld)
    1714            0 :        ABI_FREE(ak)
    1715              :      enddo
    1716              : 
    1717              :    else ! Restart
    1718            0 :      call wrtout(units, " - restarting from previous A_nk")
    1719            0 :      if (single_state) then
    1720            0 :        self%a_spin(:,:,:,:) = vpq_ld%a_spin(:,:,pselect:pselect,:)
    1721              :      else
    1722            0 :        self%a_spin(:,:,:,:) = vpq_ld%a_spin(:,:,:,:)
    1723              :      endif
    1724              :    endif
    1725              : 
    1726            0 :    call vpq_ld%free()
    1727              :  endif
    1728              : 
    1729            0 :  call xmpi_bcast(self%a_spin, master, comm, ierr)
    1730            0 :  self%ld_flag = .true.
    1731              : 
    1732            0 :  call cwtime_report(" varpeq: load", cpu, wall, gflops)
    1733              : 
    1734            0 : end subroutine varpeq_load
    1735              : !!***
    1736              : 
    1737              : !----------------------------------------------------------------------
    1738              : 
    1739              : !!****f* m_varpeq/varpeq_hop
    1740              : !! NAME
    1741              : !!  varpeq_hop
    1742              : !!
    1743              : !! FUNCTION
    1744              : !!  Solve the Variational Polaron Equations for polaronic hopping between
    1745              : !!  initial and final state.
    1746              : !!  self%nstates act as number of polarnoc images, including the initial
    1747              : !!  and final one.
    1748              : !!  Optimization is performed via string method:
    1749              : !!  [Weinan, J. Chem. Phys. 126, 164103 (2007)]
    1750              : !!
    1751              : !! INPUTS
    1752              : !!
    1753              : !! OUTPUT
    1754              : !!
    1755              : !! SOURCE
    1756              : 
    1757            1 : subroutine varpeq_hop(self)
    1758              : 
    1759              : !Arguments ------------------------------------
    1760              :  class(varpeq_t), target, intent(inout) :: self
    1761              : 
    1762              : !Local variables-------------------------------
    1763              : !scalars
    1764              :  class(polstate_t), pointer :: polstate
    1765              :  character(len=5000) :: msg
    1766              :  integer :: ierr
    1767              :  integer :: my_is, spin, ip, ihop
    1768              :  real(dp) :: cpu, wall, gflops
    1769              :  real(dp) :: ts, dist2
    1770              :  real(dp) :: phforce_grs, phforce_hop_grs
    1771              : !arrays
    1772            2 :  logical :: is_conv_spin(self%nsppol)
    1773              :  integer :: units(2)
    1774            2 :  real(dp) :: b_mesh(self%nstates)
    1775            2 :  real(dp) :: even_mesh(self%nstates)
    1776              : 
    1777              : !----------------------------------------------------------------------
    1778              : 
    1779            3 :  units = [std_out, ab_out]
    1780              : 
    1781              :  call wrtout(units, &
    1782            1 :    sjoin(ch10, "Solving for the polaron hopping..."))
    1783              : 
    1784            1 :  call cwtime(cpu, wall, gflops, "start")
    1785              : 
    1786           10 :  do ip=1,self%nstates
    1787           10 :    even_mesh(ip) = (ip - one) / (self%nstates - one)
    1788              :  enddo
    1789              : 
    1790            2 :  is_conv_spin(:) = .false.
    1791           16 :  do ihop=1,self%hop_nstep
    1792           15 :    write(msg, '(a5,a,i0,a,i0)')  "* ", "Hopping: step ", ihop, "/", self%hop_nstep
    1793           15 :    call wrtout(units, msg)
    1794              : 
    1795              :    ! Solve the variational polaron equations
    1796           15 :    call self%solve(verbose=.false., ihop=ihop)
    1797              : 
    1798           30 :    do my_is=1,self%gstore%my_nspins
    1799           15 :      spin = self%gstore%my_spins(my_is)
    1800           15 :      polstate => self%polstate(my_is)
    1801              : 
    1802         7899 :      if (ihop == 1) polstate%my_prev_b_hop(:,:,:) = zero
    1803           15 :      self%hop_nstep2cv_spin(spin) = ihop
    1804              : 
    1805              :      ! Calculate the forces
    1806          150 :      do ip=1,self%nstates
    1807          135 :        call polstate%calc_eff_phforce("fw_euler", ip)
    1808              : 
    1809              :        ! Record the bare phonon force norm
    1810          135 :        phforce_grs = sqrt(polstate%get_sqnorm("phgrad", ip))
    1811          150 :        self%hop_hist_spin(1, ip, ihop, spin) = phforce_grs
    1812              : 
    1813              :      enddo
    1814              : 
    1815              :      ! Calculate optimal timestep
    1816           15 :      if (ihop == 1) then
    1817            8 :        do ip=2,self%nstates-1
    1818            8 :          call polstate%calc_hop_timestep(ip)
    1819              :        enddo
    1820            9 :        ts = minval(abs(polstate%hop_ts(2:self%nstates-1)))
    1821              : 
    1822            1 :        if (self%hop_ts > zero) ts = self%hop_ts
    1823              : 
    1824            1 :        write(msg, '(a5,a,es8.2)')  "", "line minimiation step t = ", ts
    1825            1 :        call wrtout(units, msg)
    1826              :      endif
    1827              : 
    1828              :      ! Evolve B_\qnu coefficients
    1829              :      polstate%my_b(:,:,:) = &
    1830       118275 :        polstate%my_b(:,:,:) + ts * polstate%my_eff_phforce(:,:,:)
    1831              : 
    1832              :      ! Reparametrize the string:
    1833              :      ! Get current parametrization
    1834           15 :      b_mesh(1) = zero
    1835          135 :      do ip=2,self%nstates
    1836       105120 :        dist2 = sum(abs(polstate%my_b(:,:,ip) - polstate%my_b(:,:,ip-1))**2)
    1837          120 :        call xmpi_sum(dist2, polstate%gqk%qpt_pert_comm%value, ierr)
    1838          135 :        b_mesh(ip) = b_mesh(ip-1) + sqrt(dist2)
    1839              :      enddo
    1840          150 :      b_mesh(:) = b_mesh(:) / b_mesh(self%nstates)
    1841              : 
    1842              :      ! Redistribute B_q\nu
    1843           15 :      call polstate%redistr_b(b_mesh, even_mesh, self%nstates)
    1844              : 
    1845              :      ! Record phonon force norm, computed from optimization
    1846              :      ! F_q\nu = 1/ts * |B_q\nu^(n) - B_q\nu^(n-1)|
    1847          150 :      do ip=1,self%nstates
    1848              :        phforce_hop_grs = &
    1849       118260 :          sum(abs(polstate%my_b(:,:,ip) - polstate%my_prev_b_hop(:,:,ip))**2)
    1850          135 :        call xmpi_sum(phforce_hop_grs, polstate%gqk%qpt_pert_comm%value, ierr)
    1851              : 
    1852          150 :        self%hop_hist_spin(2, ip, ihop, spin) = sqrt(phforce_hop_grs) / ts
    1853              :      enddo
    1854              : 
    1855          165 :      if (maxval(self%hop_hist_spin(2, :, ihop, spin)) < self%hop_tolgrs) then
    1856            0 :        is_conv_spin(spin) = .true.
    1857              :      endif
    1858              : 
    1859       118290 :      polstate%my_prev_b_hop(:,:,:) = polstate%my_b(:,:,:)
    1860              :    enddo
    1861              : 
    1862           15 :    if (all(is_conv_spin) .or. (ihop == self%hop_nstep)) then
    1863           10 :      do ip=1,self%nstates
    1864              :        ! Compute the overlaps
    1865              :        ! <A_in|B_i|A_in>
    1866              :        self%hop_hist_spin(3, ip, ihop, spin) = &
    1867              :          polstate%calc_hpol(polstate%my_a(:,:,1), polstate%a_glob(:,:,1), &
    1868            9 :                             polstate%my_a(:,:,1), polstate%my_b(:,:,ip))
    1869              :        ! <A_end|B_i|A_end>
    1870              :        self%hop_hist_spin(4, ip, ihop, spin) = &
    1871              :          polstate%calc_hpol(polstate%my_a(:,:,self%nstates), polstate%a_glob(:,:,self%nstates), &
    1872            9 :                             polstate%my_a(:,:,self%nstates), polstate%my_b(:,:,ip))
    1873              :        ! <A_in|B_i|A_end>
    1874              :        self%hop_hist_spin(5, ip, ihop, spin) = &
    1875              :          polstate%calc_hpol(polstate%my_a(:,:,1), polstate%a_glob(:,:,1), &
    1876           24 :                             polstate%my_a(:,:,self%nstates), polstate%my_b(:,:,ip))
    1877              :      enddo
    1878              :    endif
    1879              : 
    1880           16 :    if (all(is_conv_spin)) exit
    1881              : 
    1882              :  enddo
    1883              : 
    1884            1 :  call cwtime_report(" varpeq: hop", cpu, wall, gflops)
    1885              : 
    1886            1 : end subroutine varpeq_hop
    1887              : !!***
    1888              : 
    1889              : !----------------------------------------------------------------------
    1890              : 
    1891              : !!****f* m_varpeq/varpeq_solve
    1892              : !! NAME
    1893              : !!  varpeq_solve
    1894              : !!
    1895              : !! FUNCTION
    1896              : !!  Solve the Variational Polaron Equations for each spin for self%nstates
    1897              : !!  polaronic states.
    1898              : !!
    1899              : !! INPUTS
    1900              : !!  ineb [optional]=Hopping iteration. Relevant only if self%vpq_mode="hopping".
    1901              : !!
    1902              : !! OUTPUT
    1903              : !!
    1904              : !! SOURCE
    1905              : 
    1906           69 : subroutine varpeq_solve(self, verbose, ihop)
    1907              : 
    1908              : !Arguments ------------------------------------
    1909              :  class(varpeq_t), target, intent(inout) :: self
    1910              :  logical, intent(in) :: verbose
    1911              :  integer, optional, intent(in) :: ihop
    1912              : 
    1913              : !Local variables-------------------------------
    1914              :  class(polstate_t), pointer :: polstate
    1915              :  character(len=5000) :: msg
    1916              :  integer :: my_is, spin, ip, ii, ihop_
    1917              :  real(dp) :: grad_sqnorm
    1918              :  real(dp) :: cpu, wall, gflops
    1919              :  integer :: units(2)
    1920              : !----------------------------------------------------------------------
    1921              : 
    1922           69 :  units = [std_out, ab_out]
    1923              : 
    1924           23 :  ihop_ = 1
    1925           23 :  if (present(ihop)) ihop_ = ihop
    1926              : 
    1927           23 :  if (verbose) then
    1928              :    call wrtout(units, &
    1929            8 :      sjoin(ch10, "Solving the variational polaron equations for each state..."))
    1930              :  endif
    1931              : 
    1932           23 :  call cwtime(cpu, wall, gflops, "start")
    1933              : 
    1934           46 :  do my_is=1,self%gstore%my_nspins
    1935           23 :    spin = self%gstore%my_spins(my_is)
    1936           23 :    polstate => self%polstate(my_is)
    1937              : 
    1938          191 :    do ip=1,self%nstates
    1939              : 
    1940          145 :      if (verbose) then
    1941           10 :        write(msg, '(a5,a,i0,a,i0,a,i0,a,i0,a)')  "* ", "spin ", spin, "/", &
    1942           20 :          self%nsppol, ", pstate ", ip, "/", self%nstates, "..."
    1943           10 :        call wrtout(units, msg)
    1944              :      endif
    1945              : 
    1946              :      ! initialize A_nk at this state, orthogonalize to the previous ones
    1947              :      ! and normalize
    1948          145 :      if (ihop_ == 1) then
    1949              :        call polstate%setup(ip, a_src=self%a_spin(:,:,ip,spin), load=self%ld_flag, &
    1950              :          atloc=self%atloc, chrgat=self%chrgat, scell=self%scell, cryst=self%cryst, &
    1951           19 :          nstep_loc=self%nstep)
    1952              :      endif
    1953              : 
    1954         2286 :      do ii=1,self%nstep
    1955              :        ! gather A, get B_qnu, get energies
    1956         2285 :        call polstate%localize(ip, self%mixing_factor, fix_displ=self%fix_displ)
    1957              : 
    1958              :        ! get bare gradient
    1959         2285 :        call polstate%calc_grad(ip)
    1960              : 
    1961              :        ! calculate and save the L^2 gradient norm
    1962         2285 :        grad_sqnorm = polstate%get_sqnorm("grad", ip)
    1963         2285 :        polstate%gradres(ip) = sqrt(grad_sqnorm)
    1964              : 
    1965              :        ! record the energies & gradient norm to varepq datatype
    1966         2285 :        call self%record(ii, ip, ihop_, my_is)
    1967              : 
    1968              :        ! check if gradient norm is lower than convergence threshold
    1969         2285 :        if (polstate%gradres(ip) < self%tolgrs) then
    1970          144 :          self%cvflag_spin(ip, ihop_, spin) = 1
    1971          144 :          exit
    1972              :        endif
    1973              : 
    1974              :        ! calculate the preconditioner
    1975         2141 :        call polstate%update_pc(ip)
    1976              : 
    1977              :        ! get preconditioned conjugate gradient direction
    1978         2141 :        call polstate%calc_pcjgrad(ip, ii, self%nstep_ort)
    1979              : 
    1980              :        ! update a based on line minimization and pcj direction
    1981         2142 :        call polstate%update_a(ip)
    1982              : 
    1983              :      enddo
    1984              : 
    1985          168 :      if (verbose) then
    1986           10 :        call wrtout(units, "   Done")
    1987              :      endif
    1988              : 
    1989              :    enddo
    1990              :  enddo
    1991              : 
    1992           23 :  call cwtime_report(" varpeq: solve", cpu, wall, gflops)
    1993              : 
    1994           23 : end subroutine varpeq_solve
    1995              : !!***
    1996              : 
    1997              : !----------------------------------------------------------------------
    1998              : 
    1999              : !!****f* m_varpeq/varpeq_record
    2000              : !! NAME
    2001              : !!  varpeq_record
    2002              : !!
    2003              : !! FUNCTION
    2004              : !!  Record variational polaron equations results for current iteration.
    2005              : !!  Used to propagate the SCF cycle history from self%polstate to the
    2006              : !!  varpeq datatype itself.
    2007              : !!
    2008              : !! INPUTS
    2009              : !!  iter=Current iteration.
    2010              : !!  ihop=Current iteration (hopping).
    2011              : !!  ip=Index of a polaronic state.
    2012              : !!  my_is=Spin polarization treated by this MPI proc.
    2013              : !!
    2014              : !! OUTPUT
    2015              : !!
    2016              : !! SOURCE
    2017              : 
    2018         2285 : subroutine varpeq_record(self, iter, ip, ihop, my_is)
    2019              : 
    2020              : !Arguments ------------------------------------
    2021              :  class(varpeq_t), target, intent(inout) :: self
    2022              :  integer, intent(in) :: iter, ip, ihop, my_is
    2023              : 
    2024              : !Local variables-------------------------------
    2025              :  class(polstate_t), pointer :: polstate
    2026              :  integer :: spin, psign
    2027              :  real(dp) :: enel, enph, enelph, eps
    2028              : !----------------------------------------------------------------------
    2029              : 
    2030         2285 :  spin = self%gstore%my_spins(my_is)
    2031         2285 :  polstate => self%polstate(my_is)
    2032              : 
    2033         2285 :  psign = 1
    2034         2285 :  if (self%pkind == "hole") psign = -1
    2035              : 
    2036         2285 :  enel = polstate%enterms(1, ip); enph = polstate%enterms(2, ip)
    2037         2285 :  enelph = polstate%enterms(3, ip); eps = polstate%enterms(4, ip)
    2038              : 
    2039         2285 :  self%scf_hist_spin(1, iter, ip, ihop, spin) = (enel + enph + enelph)
    2040         2285 :  self%scf_hist_spin(2, iter, ip, ihop, spin) = enel
    2041         2285 :  self%scf_hist_spin(3, iter, ip, ihop, spin) = enph
    2042         2285 :  self%scf_hist_spin(4, iter, ip, ihop, spin) = enelph
    2043         2285 :  self%scf_hist_spin(5, iter, ip, ihop, spin) = psign*eps
    2044         2285 :  self%scf_hist_spin(6, iter, ip, ihop, spin) = polstate%gradres(ip)
    2045         2285 :  self%nstep2cv_spin(ip, ihop, spin) = iter
    2046              : 
    2047         2285 : end subroutine varpeq_record
    2048              : !!***
    2049              : 
    2050              : !----------------------------------------------------------------------
    2051              : 
    2052              : !!****f* m_varpeq/varpeq_hop_setup
    2053              : !! NAME
    2054              : !!  varpeq_hop_setup
    2055              : !!
    2056              : !! FUNCTION
    2057              : !!  Setup the hopping optimization.
    2058              : !!  This routine specfifies the set of B_q\nu images via linear
    2059              : !!  interpolation between an initial and final images.
    2060              : !!
    2061              : !! INPUTS
    2062              : !!  dtset<dataset_type>=All input variables for this dataset.
    2063              : !!
    2064              : !! OUTPUT
    2065              : !!
    2066              : !! SOURCE
    2067              : 
    2068            1 : subroutine varpeq_hop_setup(self, dtset)
    2069              : 
    2070              : !Arguments ------------------------------------
    2071              :  class(varpeq_t), target, intent(inout) :: self
    2072              :  type(dataset_type), intent(in) :: dtset
    2073              : 
    2074              : !Local variables-------------------------------
    2075              : !scalars
    2076          103 :  type(varpeq_t) :: vpq_from, vpq_to
    2077              :  class(polstate_t), pointer :: polstate
    2078              :  class(gqk_t), pointer :: gqk
    2079              :  integer, parameter :: master = 0
    2080              :  integer :: my_rank, comm, ierr
    2081              :  integer :: my_is, spin
    2082              :  real(dp) :: cpu, wall, gflops
    2083              : !arrays
    2084              :  integer :: center(3)
    2085            2 :  complex(dp) :: b_spin_from(self%natom3, self%max_nq, self%nsppol)
    2086            1 :  complex(dp) :: b_spin_to(self%natom3, self%max_nq, self%nsppol)
    2087              : 
    2088              : !----------------------------------------------------------------------
    2089              : 
    2090            1 :  call cwtime(cpu, wall, gflops, "start")
    2091              : 
    2092            1 :  comm = self%gstore%comm; my_rank = xmpi_comm_rank(comm)
    2093              : 
    2094            1 :  if (my_rank == master) then
    2095            1 :    call vpq_from%ncread(dtset%vpq_hop_from_filepath, xmpi_comm_self)
    2096              : 
    2097            1 :    if (dtset%vpq_hop_to_filepath /= ABI_NOFILE) then
    2098            1 :       call vpq_to%ncread(dtset%vpq_hop_to_filepath, xmpi_comm_self)
    2099              :    else
    2100            0 :       call vpq_to%ncread(dtset%vpq_hop_from_filepath, xmpi_comm_self)
    2101              :    endif
    2102              : 
    2103              : 
    2104              :    ! TODO: allow BZ mismatch by adding a BZ interpolation step?
    2105            1 :    call self%compare(vpq_from, bz_mismatch=.false.)
    2106            1 :    call self%compare(vpq_to, bz_mismatch=.false.)
    2107              : 
    2108          877 :    b_spin_from(:,:,:) = vpq_from%b_spin(:,:, dtset%vpq_hop_from_ip, :)
    2109          877 :    b_spin_to(:,:,:) = vpq_to%b_spin(:,:, dtset%vpq_hop_to_ip, :)
    2110              : 
    2111            1 :    call vpq_from%free()
    2112            1 :    call vpq_to%free()
    2113              :  endif
    2114              : 
    2115            1 :  call xmpi_bcast(b_spin_from, master, comm, ierr)
    2116            1 :  call xmpi_bcast(b_spin_to, master, comm, ierr)
    2117              : 
    2118            4 :  center(:) = self%ngkpt(:) / 2
    2119              : 
    2120            2 :  do my_is=1,self%gstore%my_nspins
    2121            1 :    spin = self%gstore%my_spins(my_is)
    2122            1 :    gqk => self%gstore%gqk(my_is)
    2123            1 :    polstate => self%polstate(spin)
    2124              : 
    2125              :    call polstate%load_b(b_spin_from(:,:,spin), ip=1, &
    2126            4 :      trvec=(center(:) - dtset%vpq_hop_from_site(:)))
    2127              : 
    2128            1 :    if (dtset%vpq_hop_to_filepath /= ABI_NOFILE) then
    2129              :      call polstate%load_b(b_spin_to(:,:,spin), ip=self%nstates, &
    2130            4 :        trvec=(center(:) - dtset%vpq_hop_to_site(:) + dtset%vpq_hop_vec(:)))
    2131              :    else
    2132              :      call polstate%load_b(b_spin_to(:,:,spin), ip=self%nstates, &
    2133            0 :        trvec=(center(:) - dtset%vpq_hop_from_site(:) + dtset%vpq_hop_vec(:)))
    2134              :    endif
    2135              : 
    2136            2 :    call polstate%linterp_b()
    2137              :  enddo
    2138              : 
    2139            1 :  self%fix_displ = .true.
    2140              : 
    2141            1 :  call cwtime_report(" varpeq: hop_setup", cpu, wall, gflops)
    2142              : 
    2143            1 : end subroutine varpeq_hop_setup
    2144              : !!***
    2145              : 
    2146              : !----------------------------------------------------------------------
    2147              : 
    2148              : !!****f* m_varpeq/varpeq_init
    2149              : !! NAME
    2150              : !!  varpeq_init
    2151              : !!
    2152              : !! FUNCTION
    2153              : !!  Initialize the oboject by setting basic variables, allocate dynamic arrays.
    2154              : !!
    2155              : !! INPUTS
    2156              : !!  gstore<gstore_t>=Electron-phonon matrix elements and related quantities.
    2157              : !!  dtset<dataset_type>=All input variables for this dataset.
    2158              : !!
    2159              : !! OUTPUT
    2160              : !!
    2161              : !! SOURCE
    2162              : 
    2163            9 : subroutine varpeq_init(self, gstore, dtset)
    2164              : 
    2165              : !Arguments ------------------------------------
    2166              :  class(varpeq_t), target, intent(inout) :: self
    2167              :  type(gstore_t), target, intent(in) :: gstore
    2168              :  type(dataset_type), intent(in) :: dtset
    2169              : 
    2170              : !Local variables-------------------------------
    2171              : !scalars
    2172              :  character(len=5000) :: msg
    2173              :  class(gqk_t), pointer :: gqk
    2174              :  class(crystal_t), pointer :: cryst
    2175              :  class(polstate_t), pointer :: polstate
    2176              :  integer :: ierr, my_is, spin, bstart, bend, my_iq
    2177              :  real(dp) :: wtq, cpu, wall, gflops
    2178              : !----------------------------------------------------------------------
    2179              : 
    2180            9 :  call cwtime(cpu, wall, gflops, "start")
    2181              : 
    2182              :  ! Consistency check
    2183            9 :  ierr = 0
    2184            9 :  if (gstore%check_cplex_qkzone_gmode(2, "bz", "bz", "phonon") /= 0) then
    2185            0 :    ABI_ERROR_NOSTOP("The gstore object is inconsistent with varpeq. See messages above.", ierr)
    2186              :  end if
    2187            9 :  if (gstore%has_used_lgk /= 0) then
    2188            0 :    ABI_ERROR_NOSTOP("The varpeq formalism does not support use_lgk /=0 .", ierr)
    2189              :  end if
    2190            9 :  if (gstore%has_used_lgq /= 0) then
    2191            0 :    ABI_ERROR_NOSTOP("The varpeq formalism does not support use_lgq /=0 .", ierr)
    2192              :  end if
    2193            9 :  if (ierr > 1) then
    2194              :    write(msg,'(a,i0,5a)')&
    2195            0 :      'Checking consistency of input data against itself gave ',ierr,' inconsistencies.',ch10,&
    2196            0 :      'The details of the problems can be FOUND ABOVE (or in output or log file), in an earlier WARNING.',ch10,&
    2197            0 :      'In parallel, the details might not even be printed there. Then, try running in sequential to see the details.'
    2198            0 :    ABI_ERROR(msg)
    2199              :  end if
    2200              : 
    2201            9 :  cryst => gstore%cryst
    2202              : 
    2203              :  ! Scalars
    2204              :  ! character
    2205            9 :  self%mode = dtset%vpq_mode
    2206            9 :  self%pkind = dtset%vpq_pkind
    2207            9 :  self%aseed = dtset%vpq_aseed
    2208              :  ! logical
    2209            9 :  self%restart = (dtset%eph_restart /= 0)
    2210            9 :  self%interp = (dtset%vpq_interp /= 0)
    2211            9 :  self%g0_flag = (dtset%vpq_avg_g /= 0)
    2212            9 :  self%translate = (dtset%vpq_translate /= 0)
    2213              :  ! integer
    2214            9 :  self%atloc = dtset%vpq_atloc
    2215            9 :  self%hop_nstep = dtset%vpq_hop_nstep
    2216            9 :  self%nstep = dtset%vpq_nstep
    2217            9 :  self%nstep_ort = dtset%vpq_nstep_ort
    2218            9 :  self%nsppol = gstore%nsppol
    2219            9 :  self%nstates = dtset%vpq_nstates
    2220            9 :  self%natom3 = cryst%natom*3
    2221           18 :  self%max_nk = maxval(gstore%glob_nk_spin)
    2222           18 :  self%max_nq = maxval(gstore%glob_nq_spin)
    2223           18 :  self%max_nb = maxval(gstore%brange_k_spin(2,:) - gstore%brange_k_spin(1,:)) + 1
    2224            9 :  self%frohl_ntheta = dtset%eph_frohl_ntheta
    2225              :  ! real
    2226            9 :  self%hop_tolgrs = dtset%vpq_hop_tolgrs
    2227            9 :  self%hop_ts = dtset%vpq_hop_ts
    2228            9 :  self%tolgrs = dtset%vpq_tolgrs
    2229            9 :  self%mixing_factor = dtset%vpq_mix_fact
    2230              : 
    2231              :  ! Static arrays
    2232              :  ! integer
    2233           36 :  self%ngkpt(:) = dtset%ngkpt(:)
    2234              : 
    2235              :  ! Dynamic arrays
    2236              :  ! integer
    2237           27 :  ABI_MALLOC(self%nk_spin, (gstore%nsppol))
    2238           27 :  ABI_MALLOC(self%nq_spin, (gstore%nsppol))
    2239           27 :  ABI_MALLOC(self%nb_spin, (gstore%nsppol))
    2240           27 :  ABI_MALLOC(self%brange_spin, (2, gstore%nsppol))
    2241           18 :  self%nk_spin(:) = gstore%glob_nk_spin(:)
    2242           18 :  self%nq_spin(:) = gstore%glob_nq_spin(:)
    2243           18 :  self%nb_spin(:) = gstore%brange_k_spin(2,:) - gstore%brange_k_spin(1,:) + 1
    2244           36 :  self%brange_spin(:,:) = gstore%brange_k_spin(:,:)
    2245              : 
    2246           45 :  ABI_MALLOC(self%cvflag_spin, (self%nstates, self%hop_nstep, gstore%nsppol))
    2247           45 :  ABI_MALLOC(self%nstep2cv_spin, (self%nstates, self%hop_nstep, gstore%nsppol))
    2248           27 :  ABI_MALLOC(self%hop_nstep2cv_spin, (gstore%nsppol))
    2249          186 :  self%cvflag_spin(:,:,:) = zero
    2250          186 :  self%nstep2cv_spin(:,:,:) = zero
    2251           18 :  self%hop_nstep2cv_spin(:) = zero
    2252              : 
    2253           36 :  ABI_MALLOC(self%k2ibz_spin, (self%max_nk, gstore%nsppol))
    2254           36 :  ABI_MALLOC(self%q2ibz_spin, (self%max_nq, gstore%nsppol))
    2255              : 
    2256              :  ! real
    2257           27 :  ABI_MALLOC(self%chrgat, (cryst%natom))
    2258           45 :  ABI_MALLOC(self%hop_hist_spin, (5, self%nstates, self%hop_nstep, gstore%nsppol))
    2259           54 :  ABI_MALLOC(self%scf_hist_spin, (6, self%nstep, self%nstates, self%hop_nstep, gstore%nsppol))
    2260           27 :  self%chrgat(:) = dtset%chrgat(:)
    2261          911 :  self%hop_hist_spin(:,:,:,:) = zero
    2262        98641 :  self%scf_hist_spin(:,:,:,:,:) = zero
    2263              : 
    2264           36 :  ABI_MALLOC(self%kpts_spin, (3, self%max_nk, gstore%nsppol))
    2265           36 :  ABI_MALLOC(self%qpts_spin, (3, self%max_nq, gstore%nsppol))
    2266           27 :  ABI_MALLOC(self%erange_spin, (gstore%nsppol))
    2267           18 :  self%erange_spin(:) = zero
    2268            9 :  if (gstore%kfilter == "erange") then
    2269            1 :    self%use_filter = .true.
    2270            1 :    if (dtset%vpq_pkind == "hole") then
    2271            0 :      self%erange_spin(:) = gstore%erange_spin(1,:)
    2272              :    else
    2273            2 :      self%erange_spin(:) = gstore%erange_spin(2,:)
    2274              :    endif
    2275              :  endif
    2276              : 
    2277              :  ! complex
    2278           54 :  ABI_MALLOC(self%a_spin, (self%max_nb, self%max_nk, self%nstates, gstore%nsppol))
    2279           54 :  ABI_MALLOC(self%b_spin, (self%natom3, self%max_nq, self%nstates, gstore%nsppol))
    2280              : 
    2281              :  ! Datatypes and pointers
    2282            9 :  self%gstore => gstore
    2283            9 :  call cryst%copy(self%cryst)
    2284            9 :  self%gaps = gstore%ebands%get_gaps(ierr)
    2285              : 
    2286              :  call self%scell%init(cryst%natom, gstore%ebands%kptrlatt, cryst%rprimd, &
    2287            9 :    cryst%typat, cryst%xcart, cryst%znucl, xyz_order="xyz")
    2288            9 :  ABI_CHECK(gstore%same_nbands(msg), sjoin("VarPEq requires nb_k == nb_kq.", msg))
    2289              : 
    2290              :  ! Initialize polaronic states for each spin
    2291          495 :  ABI_MALLOC(self%polstate, (gstore%my_nspins))
    2292           18 :  do my_is=1,gstore%my_nspins
    2293            9 :    spin = gstore%my_spins(my_is)
    2294            9 :    gqk => gstore%gqk(my_is)
    2295            9 :    polstate => self%polstate(my_is)
    2296              : 
    2297              :    ! Scalars
    2298              :    ! character
    2299            9 :    polstate%aseed = dtset%vpq_aseed
    2300              :    ! logical
    2301            9 :    polstate%translate = (dtset%vpq_translate /= 0)
    2302              :    ! integers
    2303            9 :    polstate%np = dtset%vpq_nstates
    2304            9 :    polstate%nkbz = gstore%nkbz
    2305            9 :    polstate%nqbz = gstore%nqbz
    2306              :    ! real
    2307            9 :    polstate%e_frohl = zero
    2308            9 :    polstate%efilter = dtset%vpq_efilter
    2309              : 
    2310              :    ! Static arrays
    2311              :    ! integer
    2312           36 :    polstate%ngkpt(:) = dtset%ngkpt(:)
    2313              :    ! real
    2314           27 :    polstate%gpr_energy(:) = dtset%vpq_gpr_energy(:)
    2315           36 :    polstate%gpr_length(:) = dtset%vpq_gpr_length(:)
    2316              : 
    2317              :    ! Dynamic arrays
    2318              :    ! logical
    2319           27 :    ABI_MALLOC(polstate%has_prev_grad, (dtset%vpq_nstates))
    2320           28 :    polstate%has_prev_grad(:) = .false.
    2321              :    ! real
    2322           27 :    ABI_MALLOC(polstate%gradres, (dtset%vpq_nstates))
    2323           27 :    ABI_MALLOC(polstate%enterms, (4, dtset%vpq_nstates))
    2324              : 
    2325           36 :    ABI_MALLOC(polstate%eig, (gqk%nb_k, gstore%ebands%nkpt))
    2326              :    msg = sjoin(self%gaps%errmsg_spin(spin), &
    2327            9 :      "VarPEq is incompatible with metals and requires band gap.")
    2328            9 :    ABI_CHECK(self%gaps%ierr(spin) == 0, msg)
    2329              : 
    2330            9 :    bstart = gstore%brange_k_spin(1, spin)
    2331            9 :    bend = bstart + gqk%nb_k - 1
    2332            1 :    select case(dtset%vpq_pkind)
    2333              :    case ("electron")
    2334              :      polstate%eig = &
    2335          170 :        gstore%ebands%eig(bstart:bend, :, spin) - self%gaps%cb_min(spin)
    2336            1 :      polstate%psign = 1
    2337              :    case ("hole")
    2338              :      polstate%eig = &
    2339          248 :        -(gstore%ebands%eig(bstart:bend, :, spin) - self%gaps%vb_max(spin))
    2340           17 :      polstate%psign = -1
    2341              :    end select
    2342              : 
    2343           27 :    ABI_MALLOC(polstate%my_g0, (gqk%my_npert))
    2344           63 :    polstate%my_g0(:) = zero
    2345              : 
    2346           27 :    ABI_MALLOC(polstate%my_qpts, (3, gqk%my_nq))
    2347         1190 :    do my_iq=1,gqk%my_nq
    2348         1190 :      call gqk%myqpt(my_iq, gstore, wtq, polstate%my_qpts(:, my_iq))
    2349              :    enddo
    2350              : 
    2351           36 :    ABI_MALLOC(polstate%displ, (3, self%scell%natom, dtset%vpq_nstates))
    2352              : 
    2353              :    ! complex
    2354           45 :    ABI_MALLOC(polstate%my_a, (gqk%nb_k, gqk%my_nk, dtset%vpq_nstates))
    2355           45 :    ABI_MALLOC(polstate%a_glob, (gqk%nb_k, gqk%glob_nk, dtset%vpq_nstates))
    2356           45 :    ABI_MALLOC(polstate%my_b, (gqk%my_npert, gqk%my_nq, dtset%vpq_nstates))
    2357           36 :    ABI_MALLOC(polstate%my_prev_b, (gqk%my_npert, gqk%my_nq))
    2358           45 :    ABI_MALLOC(polstate%my_prev_b_hop, (gqk%my_npert, gqk%my_nq, dtset%vpq_nstates))
    2359           36 :    ABI_MALLOC(polstate%my_pc, (gqk%nb_k, gqk%my_nk))
    2360           36 :    ABI_MALLOC(polstate%my_grad, (gqk%nb_k, gqk%my_nk))
    2361           36 :    ABI_MALLOC(polstate%my_prev_grad, (gqk%nb_k, gqk%my_nk))
    2362           36 :    ABI_MALLOC(polstate%my_pcgrad, (gqk%nb_k, gqk%my_nk))
    2363           36 :    ABI_MALLOC(polstate%my_prev_pcgrad, (gqk%nb_k, gqk%my_nk))
    2364           36 :    ABI_MALLOC(polstate%my_pcjgrad, (gqk%nb_k, gqk%my_nk))
    2365           36 :    ABI_MALLOC(polstate%my_prev_pcjgrad, (gqk%nb_k, gqk%my_nk))
    2366           36 :    ABI_MALLOC(polstate%pcjgrad_glob, (gqk%nb_k, gqk%glob_nk))
    2367           45 :    ABI_MALLOC(polstate%my_phgrad, (gqk%my_npert, gqk%my_nq, dtset%vpq_nstates))
    2368           45 :    ABI_MALLOC(polstate%my_eff_phforce, (gqk%my_npert, gqk%my_nq, dtset%vpq_nstates))
    2369           27 :    ABI_MALLOC(polstate%hop_ts, (dtset%vpq_nstates))
    2370              : 
    2371              :    ! Datatypes ans pointers
    2372            9 :    polstate%gqk => gqk
    2373            9 :    polstate%my_kpts => gqk%my_kpts(:,:)
    2374            9 :    polstate%krank_kpts = polstate%get_krank_glob("k", gstore%ebands%kptrlatt)
    2375            9 :    polstate%krank_qpts = polstate%get_krank_glob("q", gstore%ebands%kptrlatt)
    2376              : 
    2377           18 :    call cryst%copy(polstate%cryst)
    2378              : 
    2379              :  enddo
    2380              : 
    2381              :  ! This is needed to fill kpts_spin/qpts_spin before the calculation, as they may
    2382              :  ! be required by the varpeq_load subroutine
    2383            9 :  call xmpi_barrier(gstore%comm)
    2384            9 :  call self%collect()
    2385              : 
    2386            9 :  self%is_complete = .true.
    2387              : 
    2388            9 :  call cwtime_report(" varpeq: init", cpu, wall, gflops)
    2389              : 
    2390           18 : end subroutine varpeq_init
    2391              : !!***
    2392              : 
    2393              : !----------------------------------------------------------------------
    2394              : 
    2395              : !!****f* m_varpeq/varpeq_calc_fravg
    2396              : !! NAME
    2397              : !!  varpeq_calc_fravg
    2398              : !!
    2399              : !! FUNCTION
    2400              : !!  Calculate the average Fr\"ohlich long-range contribution to the polaron
    2401              : !!  binding energy at Gamma using spherical integration in the spherical region
    2402              : !!  arond Gamma-point.
    2403              : !!
    2404              : !! INPUTS
    2405              : !!  avg_g0 [optional]=If .true., average electron-phonon matrix elements at
    2406              : !!    Gamma-point. Default: .true.
    2407              : !!
    2408              : !! OUTPUT
    2409              : !!
    2410              : !! SOURCE
    2411              : 
    2412            9 : subroutine varpeq_calc_fravg(self, avg_g0)
    2413              : 
    2414              : !Arguments ------------------------------------
    2415              :  class(varpeq_t), target, intent(inout) :: self
    2416              :  logical, optional, intent(in) :: avg_g0
    2417              : 
    2418              : !Local variables-------------------------------
    2419              : !scalars
    2420              :  type(ifc_type), pointer :: ifc
    2421              :  class(polstate_t), pointer :: polstate
    2422              :  class(gqk_t), pointer :: gqk
    2423              :  integer :: comm, my_rank, nproc, ierr
    2424              :  integer :: ntheta, nphi, angl_size
    2425              :  integer :: iang, iatom
    2426              :  integer :: nu, my_is, my_pert, pert_glob
    2427              :  real(dp) :: inv_qepsq, wqnu, prefactor
    2428              :  real(dp) :: cpu, wall, gflops
    2429              :  complex(dp) :: cnum
    2430              : !arrays
    2431              :  real(dp) :: qpt_cart(3)
    2432            9 :  real(dp), allocatable :: phfreq(:), displ_cart(:, :, :, :)
    2433            9 :  real(dp), allocatable :: qvers_cart(:, :)
    2434            9 :  real(dp), allocatable :: angweight(:)
    2435              :  real(dp), allocatable :: e_frohl_mode(:)
    2436              :  complex(dp) :: cp3(3)
    2437              : !----------------------------------------------------------------------
    2438              : 
    2439            9 :  call cwtime(cpu, wall, gflops, "start")
    2440              : 
    2441            9 :  comm = self%gstore%comm
    2442            9 :  nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    2443              : 
    2444              :  ! Integrate electron-phonon energy in the spherical region around Gamma
    2445           27 :  ABI_MALLOC(phfreq, (self%natom3))
    2446           18 :  ABI_MALLOC(e_frohl_mode, (self%natom3))
    2447           36 :  ABI_MALLOC(displ_cart, (2, 3, self%cryst%natom, self%natom3))
    2448              : 
    2449            9 :  ifc => self%gstore%ifc
    2450              : 
    2451              :  ! Create the mesh for spherical integrtion
    2452            9 :  ntheta = self%frohl_ntheta
    2453            9 :  nphi = 2*ntheta
    2454            9 :  call ylm_angular_mesh(ntheta, nphi, angl_size, qvers_cart, angweight)
    2455              : 
    2456              :  ! Integrate the contribution from each phonon mode
    2457              :  ! This is similar to what is done in the src/78_eph/m_sigmaph.f90 module
    2458           63 :  e_frohl_mode(:) = zero
    2459        18441 :  do iang=1,angl_size
    2460        18432 :    if (mod(iang, nproc) /= my_rank) cycle
    2461              : 
    2462        73728 :    qpt_cart = qvers_cart(:, iang)
    2463       294912 :    inv_qepsq = one / dot_product(qpt_cart, matmul(ifc%dielt, qpt_cart))
    2464        18432 :    call ifc%fourq(self%cryst, qpt_cart, phfreq, displ_cart, nanaqdir="cart")
    2465              : 
    2466        73737 :    do nu=4,self%natom3
    2467        55296 :      wqnu = phfreq(nu)
    2468              : 
    2469        55296 :      cp3(:) = zero
    2470       165888 :      do iatom=1,self%cryst%natom
    2471       331776 :        cp3(:) = cp3(:) + matmul(ifc%zeff(:, :, iatom), &
    2472      4036608 :          cmplx(displ_cart(1,:,iatom,nu), displ_cart(2,:,iatom,nu), kind=dp))
    2473              :      enddo
    2474       221184 :      cnum = dot_product(qpt_cart, cp3)
    2475        55296 :      if (abs(cnum) < tol12) cycle
    2476              : 
    2477              :      e_frohl_mode(nu) = e_frohl_mode(nu) + &
    2478        73728 :        angweight(iang)*(abs(cnum)*inv_qepsq/wqnu)**2
    2479              :    enddo
    2480              :  enddo
    2481            9 :  call xmpi_sum(e_frohl_mode, comm, ierr)
    2482              : 
    2483              :  prefactor = (eight * pi / self%cryst%ucvol) * &
    2484            9 :    (three / (four_pi * self%cryst%ucvol * self%gstore%nqbz))**third
    2485              : 
    2486           63 :  e_frohl_mode(:) = prefactor*e_frohl_mode(:)
    2487           63 :  self%e_frohl = sum(e_frohl_mode)
    2488              :  ! For an electron polaron, the correction has to be negative
    2489            9 :  if (self%pkind == "electron") self%e_frohl = -self%e_frohl
    2490              : 
    2491              :  ! If corresponding flag is provided, average the matrix elements at Gamma
    2492            9 :  if (present(avg_g0) .and. avg_g0) then
    2493           12 :    do my_is=1,self%gstore%my_nspins
    2494            6 :      polstate => self%polstate(my_is)
    2495            6 :      gqk => polstate%gqk
    2496              : 
    2497            6 :      polstate%e_frohl = self%e_frohl
    2498           48 :      do my_pert=1,gqk%my_npert
    2499           36 :        pert_glob = gqk%my_pert_start + my_pert - 1
    2500           36 :        wqnu = phfreq(pert_glob)
    2501              :        polstate%my_g0(my_pert) = &
    2502           42 :          sqrt(polstate%nqbz * wqnu * e_frohl_mode(pert_glob) / two)
    2503              : 
    2504              :      enddo
    2505              :    enddo
    2506              :  endif
    2507              : 
    2508            9 :  ABI_FREE(phfreq)
    2509            9 :  ABI_FREE(e_frohl_mode)
    2510            9 :  ABI_FREE(displ_cart)
    2511            9 :  ABI_FREE(qvers_cart)
    2512            9 :  ABI_FREE(angweight)
    2513              : 
    2514            9 :  call cwtime_report(" varpeq: calc_fravg", cpu, wall, gflops)
    2515              : 
    2516           27 : end subroutine varpeq_calc_fravg
    2517              : !!***
    2518              : 
    2519              : !----------------------------------------------------------------------
    2520              : 
    2521              : !!****f* m_varpeq/polstate_free
    2522              : !! NAME
    2523              : !!  polstate_free
    2524              : !!
    2525              : !! FUNCTION
    2526              : !!  Free dynamic memory
    2527              : !!
    2528              : !! OUTPUT
    2529              : !!
    2530              : !! SOURCE
    2531              : 
    2532            9 : subroutine polstate_free(self)
    2533              : 
    2534              : !Arguments ------------------------------------
    2535              :  class(polstate_t), intent(inout) :: self
    2536              : !----------------------------------------------------------------------
    2537              : 
    2538              :  ! Free allocatable arrays
    2539              : 
    2540              :  ! logical
    2541            9 :  ABI_SFREE(self%has_prev_grad)
    2542              :  ! real
    2543            9 :  ABI_SFREE(self%gradres)
    2544            9 :  ABI_SFREE(self%enterms)
    2545            9 :  ABI_SFREE(self%eig)
    2546            9 :  ABI_SFREE(self%my_g0)
    2547            9 :  ABI_SFREE(self%my_qpts)
    2548            9 :  ABI_SFREE(self%displ)
    2549              : 
    2550              :  ! complex
    2551            9 :  ABI_SFREE(self%my_a)
    2552            9 :  ABI_SFREE(self%a_glob)
    2553            9 :  ABI_SFREE(self%my_b)
    2554            9 :  ABI_SFREE(self%my_prev_b)
    2555            9 :  ABI_SFREE(self%my_prev_b_hop)
    2556            9 :  ABI_SFREE(self%my_pc)
    2557            9 :  ABI_SFREE(self%my_grad)
    2558            9 :  ABI_SFREE(self%my_pcgrad)
    2559            9 :  ABI_SFREE(self%my_prev_pcgrad)
    2560            9 :  ABI_SFREE(self%my_prev_grad)
    2561            9 :  ABI_SFREE(self%my_pcjgrad)
    2562            9 :  ABI_SFREE(self%my_prev_pcjgrad)
    2563            9 :  ABI_SFREE(self%pcjgrad_glob)
    2564            9 :  ABI_SFREE(self%my_phgrad)
    2565            9 :  ABI_SFREE(self%my_eff_phforce)
    2566            9 :  ABI_SFREE(self%hop_ts)
    2567              : 
    2568              :  ! Free local datatypes & nullify pointers
    2569            9 :  self%my_kpts => null()
    2570            9 :  self%gqk => null()
    2571              : 
    2572            9 :  call self%krank_kpts%free()
    2573            9 :  call self%krank_qpts%free()
    2574              : 
    2575            9 :  call self%cryst%free()
    2576              : 
    2577            9 : end subroutine polstate_free
    2578              : !!***
    2579              : 
    2580              : !----------------------------------------------------------------------
    2581              : 
    2582              : !!****f* m_varpeq/polstate_setup
    2583              : !! NAME
    2584              : !!  polstate_setup
    2585              : !!
    2586              : !! FUNCTION
    2587              : !!  Setup optimization process at a given polaronic state.
    2588              : !!  This routine specfifies an initial electronic vector A_nk, either by
    2589              : !!  initializaing it by a pre-determined algorithm or loading from a
    2590              : !!  *VPQ.nc netcdf file.
    2591              : !!
    2592              : !! INPUTS
    2593              : !!  ip=Index of the polaronic state.
    2594              : !!  a_src(self%gqk%nb_k, self%gqk%glob_nk) [optional]=Global A_nk coefficients at
    2595              : !!    this state, which have to be provided if load_src=.true.
    2596              : !!  load_src [optional]=.true. if A_nk is initialized from an external source,
    2597              : !!    e.g. loaded from file. Default: .false.
    2598              : !!   atloc [optional]=Index of an atom where charge is localized.
    2599              : !!   chrgat(natom) [optional]=Charge of the atoms.
    2600              : !!   scell<supercell_type> [optional]=Supercell data structure.
    2601              : !!   cryst<crystal_t> [optional]=Crystal data structure.
    2602              : !!   nstep_loc [optional]=Number of iterations for charge localization.
    2603              : !!
    2604              : !! OUTPUT
    2605              : !!
    2606              : !! SOURCE
    2607              : 
    2608           19 : subroutine polstate_setup(self, ip, a_src, load, atloc, chrgat, scell, cryst, nstep_loc)
    2609              : 
    2610              : !Arguments ------------------------------------
    2611              :  class(polstate_t), target, intent(inout) :: self
    2612              :  integer, intent(in) :: ip
    2613              :  logical, optional, intent(in) :: load
    2614              :  complex(dp), optional, intent(in) :: a_src(self%gqk%nb_k, self%gqk%glob_nk)
    2615              :  integer, optional, intent(in) :: atloc
    2616              :  class(supercell_type), optional, intent(in) :: scell
    2617              :  class(crystal_t), optional, intent(in) :: cryst
    2618              :  real(dp), optional, intent(in) :: chrgat(:)
    2619              :  integer, optional, intent(in) :: nstep_loc
    2620              : 
    2621              : !Local variables-------------------------------
    2622              :  real(dp) :: a_sqnorm
    2623              :  class(gqk_t), pointer :: gqk
    2624              : !----------------------------------------------------------------------
    2625              : 
    2626           19 :  gqk => self%gqk
    2627              : 
    2628           19 :  if (present(load) .and. load) then
    2629            0 :    ABI_CHECK(present(a_src), "polstate_setup: A_nk is expected but not provided")
    2630              :    !print *, "load"
    2631            0 :    call self%load_a(a_src, ip)
    2632              :  else
    2633           19 :    call self%seed_a(self%aseed, ip, atloc, chrgat, scell, cryst, nstep_loc)
    2634              :  endif
    2635              : 
    2636           19 :  if (self%efilter > zero) call self%filter("a", ip)
    2637              : 
    2638              :  ! Orthogonalize current states to the previous ones
    2639           19 :  call self%ort_to_states(self%my_a(:,:,ip), 1, ip-1, ip, tr_flag=self%translate)
    2640              : 
    2641              :  ! Normalize A_nk at current polaronic state
    2642           19 :  a_sqnorm = self%get_sqnorm("a", ip)
    2643           19 :  if (a_sqnorm > tol12) then
    2644         6749 :    self%my_a(:,:,ip) = sqrt(self%nkbz/a_sqnorm) * self%my_a(:,:,ip)
    2645              :  endif
    2646              : 
    2647           19 : end subroutine polstate_setup
    2648              : !!***
    2649              : 
    2650              : !----------------------------------------------------------------------
    2651              : 
    2652              : !!****f* m_varpeq/polstate_update_a
    2653              : !! NAME
    2654              : !!  polstate_update_a
    2655              : !!
    2656              : !! FUNCTION
    2657              : !!  Update the vector of electronic coefficients A_nk by line minimization in
    2658              : !!  the pcj direction for current polaronic state.
    2659              : !!
    2660              : !! INPUTS
    2661              : !!  ip=Index of a polaronic state.
    2662              : !!
    2663              : !! OUTPUT
    2664              : !!
    2665              : !! SOURCE
    2666              : 
    2667         2141 : subroutine polstate_update_a(self, ip)
    2668              : 
    2669              : !Arguments ------------------------------------
    2670              :  class(polstate_t), intent(inout) :: self
    2671              :  integer, intent(in) :: ip
    2672              : 
    2673              : !Local variables-------------------------------
    2674              :  real(dp) :: theta
    2675              : !----------------------------------------------------------------------
    2676              : 
    2677         2141 :  theta = self%get_lm_theta(ip)
    2678              :  self%my_a(:,:,ip) = &
    2679       979741 :    cos(theta)*self%my_a(:,:,ip) + sin(theta)*self%my_pcjgrad(:,:)
    2680              : 
    2681         2141 : end subroutine polstate_update_a
    2682              : !!***
    2683              : 
    2684              : !----------------------------------------------------------------------
    2685              : 
    2686              : !!****f* m_varpeq/polstate_update_pc
    2687              : !! NAME
    2688              : !!  polstate_update_pc
    2689              : !!
    2690              : !! FUNCTION
    2691              : !!  Update the preconditioner for the present configuration. Changing this
    2692              : !!  procedure may significantly improve (or worsen) the optimization process.
    2693              : !!
    2694              : !! INPUTS
    2695              : !!  ip=Index of a polaronic state.
    2696              : !!
    2697              : !! OUTPUT
    2698              : !!
    2699              : !! SOURCE
    2700              : 
    2701         2141 : subroutine polstate_update_pc(self, ip)
    2702              : 
    2703              : !Arguments ------------------------------------
    2704              :  class(polstate_t), intent(inout) :: self
    2705              :  integer, intent(in) :: ip
    2706              : 
    2707              : !Local variables-------------------------------
    2708              :  class(gqk_t), pointer :: gqk
    2709              :  integer :: my_ik, ik_ibz, ib
    2710              :  real(dp) :: eps
    2711              : !----------------------------------------------------------------------
    2712              : 
    2713         2141 :  gqk => self%gqk
    2714              : 
    2715         2141 :  eps = self%enterms(4, ip)
    2716       247787 :  do my_ik=1,gqk%my_nk
    2717       245646 :    ik_ibz = gqk%my_k2ibz(1, my_ik)
    2718       979741 :    do ib=1,gqk%nb_k
    2719              :      self%my_pc(ib, my_ik) = &
    2720       977600 :        one/abs(self%eig(ib, ik_ibz) - two*abs(self%e_frohl) + abs(eps))
    2721              :      !self%my_pc(ib, my_ik) = one
    2722              :    enddo
    2723              :  enddo
    2724              : 
    2725         2141 : end subroutine polstate_update_pc
    2726              : !!***
    2727              : 
    2728              : !----------------------------------------------------------------------
    2729              : 
    2730              : !!****f* m_varpeq/polstate_ort_to_states
    2731              : !! NAME
    2732              : !!  polstate_ort_to_states
    2733              : !!
    2734              : !! FUNCTION
    2735              : !!  Orthognongalize a vector wrt polaronic states using the Gram-Schmidt process.
    2736              : !!  The orthogonalization is performed for a range of states, specified by arguments.
    2737              : !!
    2738              : !! INPUTS
    2739              : !!  my_v(:,:)=Vetor to be orthogonalized
    2740              : !!  istart=Index of starting polaronic state
    2741              : !!  iend=Index of final polaronic state
    2742              : !!  this_ip=Index of current polaronic state
    2743              : !!  tr_flag=.true. if orthogonalization must include all states invariant by
    2744              : !!    translations inside a supercell
    2745              : !!
    2746              : !! OUTPUT
    2747              : !!
    2748              : !! SOURCE
    2749              : 
    2750         6257 : subroutine polstate_ort_to_states(self, my_v, istart, iend, this_ip, tr_flag)
    2751              : 
    2752              : !Arguments ------------------------------------
    2753              :  class(polstate_t), intent(inout) :: self
    2754              :  logical, intent(in) :: tr_flag
    2755              :  integer, intent(in) :: istart, iend, this_ip
    2756              :  complex(dp), intent(inout) :: my_v(self%gqk%nb_k, self%gqk%my_nk)
    2757              : 
    2758              : !Local variables-------------------------------
    2759              :  class(gqk_t), pointer :: gqk
    2760              :  integer :: ip, my_ik, vx, vy, vz
    2761              :  complex(dp) :: phase, proj
    2762              :  integer :: tr_vec(3), ngkpt_tr(3)
    2763              :  real(dp) :: kpt(3)
    2764        12514 :  complex(dp) :: a_tr(self%gqk%nb_k, self%gqk%my_nk)
    2765              : !----------------------------------------------------------------------
    2766              : 
    2767         6257 :  gqk => self%gqk
    2768              : 
    2769              :  !! TODO: optimize
    2770              :  !ngkpt_tr(:) = 1
    2771              :  !if (tr_flag) ngkpt_tr(:) = self%ngkpt(:)
    2772              : 
    2773        28472 :  do ip=istart,iend
    2774              : 
    2775        22215 :    if ((tr_flag) .and. ip /= this_ip) then
    2776          732 :      ngkpt_tr(:) = self%ngkpt(:)
    2777              :    else
    2778        88128 :      ngkpt_tr(:) = 1
    2779              :    endif
    2780              : 
    2781        51053 :    do vx=1,ngkpt_tr(1)
    2782        22581 :      tr_vec(1) = vx - 1
    2783        68475 :      do vy=1,ngkpt_tr(2)
    2784        23679 :        tr_vec(2) = vy - 1
    2785        73233 :        do vz=1,ngkpt_tr(3)
    2786        26973 :          tr_vec(3) = vz - 1
    2787              : 
    2788      2870422 :          do my_ik=1,gqk%my_nk
    2789     11373796 :            kpt(:) = self%my_kpts(:, my_ik)
    2790     11373796 :            phase = exp(j_dpc*sum(kpt(:)*tr_vec(:))*two_pi)
    2791     11390801 :            a_tr(:, my_ik) = phase*self%my_a(:, my_ik, ip)
    2792              :          enddo
    2793              : 
    2794        26973 :          proj = get_proj_(a_tr)
    2795     11414480 :          my_v(:,:) = my_v(:,:) - proj * a_tr(:,:)
    2796              : 
    2797              :        enddo
    2798              :      enddo
    2799              :    enddo
    2800              : 
    2801              :  enddo
    2802              : 
    2803              :  !----------------------------------------------------------------------
    2804              :  contains
    2805              : 
    2806        26973 :  complex(dp) function get_proj_(my_u) result(proj)
    2807              : 
    2808              :   complex(dp), intent(in) :: my_u(gqk%nb_k, gqk%my_nk)
    2809              :   integer :: ierr
    2810              :   real(dp) :: u_sqnorm
    2811              :  !----------------------------------------------------------------------
    2812     11390801 :   u_sqnorm = sum(abs(my_u(:,:))**2)
    2813        26973 :   call xmpi_sum(u_sqnorm, gqk%kpt_comm%value, ierr)
    2814              : 
    2815        26973 :   proj = zero
    2816        26973 :   if (u_sqnorm > tol12) then
    2817     11390801 :     proj = sum(conjg(my_u(:,:))*my_v(:,:))
    2818        26973 :     call xmpi_sum(proj, gqk%kpt_comm%value, ierr)
    2819        26973 :     proj = proj/u_sqnorm
    2820              :   endif
    2821        26973 :  end function get_proj_
    2822              : 
    2823              : end subroutine polstate_ort_to_states
    2824              : !!***
    2825              : 
    2826              : !----------------------------------------------------------------------
    2827              : 
    2828              : !!****f* m_varpeq/polstate_get_lm_theta
    2829              : !! NAME
    2830              : !!  polstate_get_lm_theta
    2831              : !!
    2832              : !! FUNCTION
    2833              : !!  Calculate line minimization parameter theta that minimizes polaron binding
    2834              : !!  energy at the next electronic configuration:
    2835              : !!  A^n = A^(n-1)*cos(theta) + D^(n-1)*sin(theta), where
    2836              : !!  A^(n-1) and D^(n-1) are current electronic configuration and gradient.
    2837              : !!
    2838              : !! INPUTS
    2839              : !!  ip=Index of a polaronic state.
    2840              : !!
    2841              : !! OUTPUT
    2842              : !!  theta=Line minimization parameter.
    2843              : !!
    2844              : !! SOURCE
    2845              : 
    2846         2141 : real(dp) function polstate_get_lm_theta(self, ip) result(theta)
    2847              : 
    2848              : !Arguments ------------------------------------
    2849              :  class(polstate_t), intent(inout) :: self
    2850              :  integer, intent(in) :: ip
    2851              : 
    2852              : !Local variables-------------------------------
    2853              : !scalars
    2854              :  class(gqk_t), pointer :: gqk
    2855              :  real(dp) :: sqnorm, e1, e2, eps
    2856              : 
    2857              : !----------------------------------------------------------------------
    2858              : 
    2859         2141 :  gqk => self%gqk
    2860              : 
    2861              :  ! Orthogonalize pcj direction to the current state and normalize
    2862         2141 :  call self%ort_to_states(self%my_pcjgrad, ip, ip, ip, tr_flag=.false.)
    2863              : 
    2864         2141 :  sqnorm = self%get_sqnorm('pcjgrad', ip)
    2865       979741 :  self%my_pcjgrad(:,:) = sqrt(self%nkbz/sqnorm)*self%my_pcjgrad(:,:)
    2866              : 
    2867              :  ! Calculation of theta requires globally available pcj direction
    2868         2141 :  call self%gather("pcjgrad", ip)
    2869              : 
    2870              : 
    2871              :  ! Line-minimization theta
    2872              :  ! E_pol(theta) = E_pol[A,B] - e1/2 + e1/2*cos(2*theta) + e2/2*sin(theta)
    2873         2141 :  eps = self%enterms(4, ip)
    2874              :  e1 = eps - self%calc_hpol(self%my_pcjgrad, self%pcjgrad_glob, &
    2875         2141 :                            self%my_pcjgrad, self%my_b(:,:,ip))
    2876              :  e2 = &
    2877              :    self%calc_hpol(self%my_a(:,:,ip), self%a_glob(:,:,ip), self%my_pcjgrad, self%my_b(:,:,ip)) + &
    2878         2141 :    self%calc_hpol(self%my_pcjgrad, self%pcjgrad_glob, self%my_a(:,:,ip), self%my_b(:,:,ip))
    2879              : 
    2880         2141 :  theta = half*atan2(-e2, -e1)
    2881              :  !if (theta < zero) then
    2882              :  !    theta = theta + pi
    2883              :  !end if
    2884              :  !theta = half*theta
    2885              : 
    2886         2141 : end function polstate_get_lm_theta
    2887              : !!***
    2888              : 
    2889              : !----------------------------------------------------------------------
    2890              : 
    2891              : !!****f* m_varpeq/polstate_calc_pcjgrad
    2892              : !! NAME
    2893              : !!  polstate_calc_pcjgrad
    2894              : !!
    2895              : !! FUNCTION
    2896              : !!  Calculate preconditioned conjugate gradient direction, orthogonal to all
    2897              : !!  already optimized polaronic states. The procedure is similar to the one
    2898              : !!  described in [Payne et al, Rev. Mod. Phys, 64, 4, 1045-1097 (1992)].
    2899              : !!
    2900              : !! INPUTS
    2901              : !!   ip=Index of a polaronic state.
    2902              : !!   ii=Iteration number.
    2903              : !!   nstep_ort=Iteration number, after which the orthogonality constraint
    2904              : !!     on all PREVIOUS states is lifted.
    2905              : !!
    2906              : !! OUTPUT
    2907              : !!
    2908              : !! SOURCE
    2909              : 
    2910         2141 : subroutine polstate_calc_pcjgrad(self, ip, ii, nstep_ort)
    2911              : 
    2912              : !Arguments ------------------------------------
    2913              :  class(polstate_t), intent(inout) :: self
    2914              :  integer, intent(in) :: ip, ii, nstep_ort
    2915              : 
    2916              : !Local variables-------------------------------
    2917              :  class(gqk_t), pointer :: gqk
    2918              :  integer :: ierr
    2919              :  !real(dp) :: eps
    2920              :  complex(dp) :: beta, beta_num, beta_den
    2921              : !----------------------------------------------------------------------
    2922              : 
    2923         2141 :  gqk => self%gqk
    2924              : 
    2925         2141 :  if (self%efilter > zero) call self%filter("grad", ip)
    2926              : 
    2927              :  ! Orthogonalize current gradient to all previous bands
    2928         2141 :  if (ii <= nstep_ort) then
    2929         1956 :    call self%ort_to_states(self%my_grad, 1, ip-1, ip, tr_flag=self%translate)
    2930              :  endif
    2931              : 
    2932              :  ! Precondtion vector
    2933       979741 :  self%my_pcgrad(:,:) = self%my_pc(:,:)*self%my_grad(:,:)
    2934              :  ! Orthogonalize to all bands
    2935         2141 :  if (ii <= nstep_ort) then
    2936         1956 :    call self%ort_to_states(self%my_pcgrad, 1, ip, ip, tr_flag=self%translate)
    2937              :  else
    2938          185 :    call self%ort_to_states(self%my_pcgrad, ip, ip, ip, tr_flag=.false.)
    2939              :  endif
    2940              : 
    2941              :  ! Conjugate gradient direction
    2942         2141 :  if (self%has_prev_grad(ip)) then
    2943              :    ! Polak-Ribiere coefficient
    2944              :    beta_num = &
    2945       972992 :      sum(conjg(self%my_pcgrad(:,:))*(self%my_grad(:,:) - self%my_prev_grad(:,:)))
    2946       972992 :    beta_den = sum(conjg(self%my_prev_pcgrad(:,:))*self%my_prev_grad(:,:))
    2947         2122 :    call xmpi_sum(beta_num, gqk%kpt_comm%value, ierr)
    2948         2122 :    call xmpi_sum(beta_den, gqk%kpt_comm%value, ierr)
    2949         2122 :    beta = beta_num / beta_den
    2950              :    !if (abs(aimag(beta)) < tol12) beta = real(beta, dp)
    2951              : 
    2952              : 
    2953       972992 :    self%my_pcjgrad(:,:) = self%my_pcgrad(:,:) + beta*self%my_prev_pcjgrad(:,:)
    2954              :  else
    2955         6749 :    self%my_pcjgrad(:,:) = self%my_pcgrad(:,:)
    2956              :  endif
    2957              : 
    2958              :  ! Save previous gradients
    2959       979741 :  self%my_prev_grad(:,:) = self%my_grad(:,:)
    2960       979741 :  self%my_prev_pcgrad(:,:) = self%my_pcgrad(:,:)
    2961       979741 :  self%my_prev_pcjgrad(:,:) = self%my_pcjgrad(:,:)
    2962         2141 :  self%has_prev_grad(ip) = .true.
    2963              : 
    2964         2141 : end subroutine polstate_calc_pcjgrad
    2965              : !!***
    2966              : 
    2967              : !----------------------------------------------------------------------
    2968              : 
    2969              : !!****f* m_varpeq/polstate_calc_grad
    2970              : !! NAME
    2971              : !!  polstate_calc_grad
    2972              : !!
    2973              : !! FUNCTION
    2974              : !!  Calculate the electronic gradient D_nk at the current configuration.
    2975              : !!
    2976              : !! INPUTS
    2977              : !!   ip=Index of a polaronic state.
    2978              : !!
    2979              : !! OUTPUT
    2980              : !!
    2981              : !! SOURCE
    2982              : 
    2983         2285 : subroutine polstate_calc_grad(self, ip)
    2984              : 
    2985              : !Arguments ------------------------------------
    2986              :  class(polstate_t), intent(inout) :: self
    2987              :  integer, intent(in) :: ip
    2988              : 
    2989              : !Local variables-------------------------------
    2990              : !scalars
    2991              :  class(gqk_t), pointer :: gqk
    2992              :  logical :: q_gamma
    2993              :  integer :: ierr
    2994              :  integer :: my_iq, my_pert
    2995              :  integer :: my_ik, ik_ibz, ik_forw, ik_back, ib, jb
    2996              :  real(dp) :: eps, fact
    2997              :  complex(dp) :: a_forw, a_back
    2998              :  complex(dp) :: g_forw, g_back
    2999              :  complex(dp) :: b, g0
    3000              : !arrays
    3001              :  real(dp) :: kpt(3), qpt(3), kpq(3), kmq(3)
    3002         4570 :  complex(dp) :: ak(self%gqk%nb_k), akq(self%gqk%nb_kq), akmq(self%gqk%nb_kq), bq(self%gqk%my_npert)
    3003         2285 :  complex(dp), allocatable :: gq_gathered(:,:,:,:)
    3004              : !----------------------------------------------------------------------
    3005              : 
    3006         2285 :  gqk => self%gqk
    3007              : 
    3008              :  !ABI_MALLOC(gq_gathered, (gqk%my_npert, gqk%nb_k, gqk%nb_k, gqk%glob_nk))
    3009              : 
    3010              :  ! Scattering-dependent part
    3011      1049507 :  self%my_grad(:, :) = zero
    3012              : 
    3013         2285 :  fact = two * self%psign / real(self%nqbz, dp)
    3014              : 
    3015       280113 :  do my_iq=1,gqk%my_nq
    3016      1111312 :    qpt(:) = self%my_qpts(:, my_iq)
    3017      1944796 :    bq(:) = self%my_b(:, my_iq, ip)
    3018              : 
    3019              :    ! Check if q=\Gamma
    3020       346465 :    q_gamma = .false.
    3021       346465 :    if (all(abs(qpt) < tol6)) q_gamma = .true.
    3022              : 
    3023              :    ! For this q, gather all the k-distributed matrix elements
    3024       277828 :    call gqk%gather("q", my_iq, gq_gathered)
    3025              : 
    3026     33678830 :    do my_ik=1,gqk%my_nk
    3027    130522294 :      ak(:) = self%my_a(:,my_ik,ip)
    3028    133604008 :      kpt(:) = self%my_kpts(:, my_ik)
    3029              : 
    3030              :      ! Forward scattering
    3031              :      ! Find k+q-->k' index in krank_kpts
    3032    133604008 :      kpq(:) = kpt(:) + qpt(:)
    3033     33401002 :      ik_forw = self%krank_kpts%get_index(kpq)
    3034              : 
    3035              :      ! If erange filter was used in gstore, some transitions are not valid
    3036     33401002 :      if (ik_forw /= -1) then
    3037    127899998 :        akq(:) = self%a_glob(:, ik_forw, ip)
    3038              : 
    3039    127899998 :        do ib=1,gqk%nb_k
    3040              : 
    3041    414871012 :          do jb=1,gqk%nb_kq
    3042    286971014 :            a_forw = akq(jb)
    3043              : 
    3044   2104607242 :            do my_pert=1,gqk%my_npert
    3045   1721826084 :              b = bq(my_pert)
    3046              : 
    3047   1721826084 :              g_forw = gqk%my_g(my_pert, jb, my_iq, ib, my_ik)
    3048              :              ! Add long-range correction to matrix elements at Gamma
    3049   1721826084 :              g0 = self%my_g0(my_pert)
    3050   1721826084 :              if (q_gamma .and. (ib == jb)) then
    3051      4704756 :                g_forw = g_forw + g0
    3052              :              endif
    3053              : 
    3054              :              self%my_grad(ib, my_ik) = &
    3055   2008797098 :                self%my_grad(ib, my_ik) + a_forw*b*conjg(g_forw)
    3056              : 
    3057              :            enddo
    3058              :          enddo
    3059              :        enddo
    3060              :      endif ! Forward scattering
    3061              : 
    3062              :      ! Backward scattering
    3063              :      ! Find k-q-->k' index in krank_kpts
    3064    133604008 :      kmq(:) = kpt(:) - qpt(:)
    3065     33401002 :      ik_back = self%krank_kpts%get_index(kmq)
    3066              : 
    3067              :      ! If erange filter was used in gstore, some transitions are not valid
    3068     33678830 :      if (ik_back /= -1) then
    3069    127899998 :        akmq(:) = self%a_glob(:, ik_back, ip)
    3070              : 
    3071    127899998 :        do ib=1,gqk%nb_k
    3072              : 
    3073    414871012 :          do jb=1,gqk%nb_kq
    3074    286971014 :            a_back = akmq(jb)
    3075              : 
    3076   2104607242 :            do my_pert=1,gqk%my_npert
    3077   1721826084 :              b = bq(my_pert)
    3078              : 
    3079   1721826084 :              g_back = gq_gathered(my_pert, ib, jb, ik_back)
    3080              :              ! Add long-range correction to matrix elements at Gamma
    3081   1721826084 :              g0 = self%my_g0(my_pert)
    3082   1721826084 :              if (q_gamma .and. (ib == jb)) then
    3083      4704756 :                g_back = g_back + g0
    3084              :              endif
    3085              : 
    3086              :              self%my_grad(ib, my_ik) = &
    3087   2008797098 :                self%my_grad(ib, my_ik) + a_back*conjg(b)*g_back
    3088              : 
    3089              :            enddo
    3090              :          enddo
    3091              :        enddo
    3092              :      endif ! Backward scattering
    3093              : 
    3094              :    enddo
    3095              : 
    3096       280113 :    ABI_FREE(gq_gathered)
    3097              :  enddo
    3098         2285 :  call xmpi_sum(self%my_grad, gqk%qpt_pert_comm%value, ierr)
    3099              :  self%my_grad(:, :) = &
    3100      1049507 :    -two/(real(self%nkbz, dp)*real(self%nqbz, dp)) * self%my_grad(:, :)
    3101              : 
    3102              :  ! Scattering-independent part
    3103         2285 :  eps = self%enterms(4, ip)
    3104       265381 :  do my_ik=1,gqk%my_nk
    3105       263096 :    ik_ibz = gqk%my_k2ibz(1, my_ik)
    3106      1047222 :    ak(:) = self%my_a(:, my_ik, ip)
    3107              : 
    3108      1049507 :    do ib=1,gqk%nb_k
    3109              :      self%my_grad(ib, my_ik) = self%my_grad(ib, my_ik) + &
    3110      1047222 :        two/self%nkbz * (self%eig(ib, ik_ibz) - eps) * self%my_a(ib, my_ik, ip)
    3111              : 
    3112              :    enddo
    3113              :  enddo
    3114              : 
    3115              :  ! Here we're actually changing the gradient to the steepest descent direction
    3116              :  ! A bit messy but i dont want to make another array called "forces" or something
    3117              :  !self%my_grad(:,:) = -self%my_grad(:,:)
    3118              : 
    3119              :  !ABI_FREE(gq_gathered)
    3120              : 
    3121         2285 :  if (self%efilter > zero) call self%filter("grad", ip)
    3122              : 
    3123         2285 : end subroutine polstate_calc_grad
    3124              : !!***
    3125              : 
    3126              : !----------------------------------------------------------------------
    3127              : 
    3128              : !!****f* m_varpeq/polstate_localize
    3129              : !! NAME
    3130              : !!  polstate_localize
    3131              : !!
    3132              : !! FUNCTION
    3133              : !!  Calculate vibrational coefficients, polaron energy terms and polaron energy
    3134              : !!  level at a current state.
    3135              : !!
    3136              : !! INPUTS
    3137              : !!  ip=Index of a polaronic state.
    3138              : !!  alpha=Mixing factor.
    3139              : !!  fix_displ [optional]=if .true., DO NOT update the phonon vector B_\qnu.
    3140              : !!    Relevant for hopping calculations. Defaults to. False.
    3141              : !!
    3142              : !! OUTPUT
    3143              : !!
    3144              : !! SOURCE
    3145              : 
    3146         2285 : subroutine polstate_localize(self, ip, alpha, fix_displ)
    3147              : 
    3148              : !Arguments ------------------------------------
    3149              :  class(polstate_t), intent(inout) :: self
    3150              :  integer, intent(in) :: ip
    3151              :  real(dp), intent(in) :: alpha
    3152              :  logical, optional, intent(in) :: fix_displ
    3153              : !----------------------------------------------------------------------
    3154              : 
    3155              :  ! Calculation of B_qnu requires globally available A_nk
    3156         2285 :  call self%gather("a", ip)
    3157              : 
    3158              :  ! We skip B calculation ONLY if the fix_displ is present and .true.
    3159         2285 :  if (.not. (present(fix_displ) .and. fix_displ)) then
    3160          316 :    call self%calc_b_from_a(ip)
    3161              :  end if
    3162              : 
    3163              :  ! Mixing the previous & current vectors of vibrational coefficients
    3164         2285 :  if (self%has_prev_grad(ip)) then
    3165      1931417 :    self%my_b(:,:, ip) = (one - alpha)*self%my_b(:,:, ip) + alpha*self%my_prev_b(:,:)
    3166              :  end if
    3167      1947081 :  self%my_prev_b(:,:) = self%my_b(:,:, ip)
    3168              : 
    3169              :  ! Electronic term
    3170         2285 :  self%enterms(1, ip) = self%get_enel(ip)
    3171              :  ! Vibrational term
    3172         2285 :  self%enterms(2, ip) = self%get_enph(ip)
    3173              :  ! Electron-phonon term
    3174         2285 :  self%enterms(3, ip) = self%get_enelph(ip)
    3175              :  ! Polaron energy level
    3176         2285 :  self%enterms(4, ip) = self%enterms(1, ip) + self%enterms(3, ip)
    3177              : 
    3178         2285 : end subroutine polstate_localize
    3179              : !!***
    3180              : 
    3181              : !----------------------------------------------------------------------
    3182              : 
    3183              : !!****f* m_varpeq/polstate_get_enelph
    3184              : !! NAME
    3185              : !!  polstate_get_enelph
    3186              : !!
    3187              : !! FUNCTION
    3188              : !!  Returns the electron-phonon term of the polaron bidning energy at a specified
    3189              : !!  polaronic state.
    3190              : !!
    3191              : !! INPUTS
    3192              : !!  ip=Index of a polaronic state.
    3193              : !!
    3194              : !! OUTPUT
    3195              : !!  enelph=Electron-phonon term of the polaron binding energy.
    3196              : !!
    3197              : !! SOURCE
    3198              : 
    3199         2285 : real(dp) function polstate_get_enelph(self, ip) result(enelph)
    3200              : 
    3201              : !Arguments ------------------------------------
    3202              :  class(polstate_t), intent(inout) :: self
    3203              :  integer, intent(in) :: ip
    3204              : 
    3205              : !Local variables-------------------------------
    3206              : !scalars
    3207              :  class(gqk_t), pointer :: gqk
    3208              :  logical :: q_gamma
    3209              :  integer :: ierr, my_iq, my_pert, my_ik, ik_forw, ib, jb
    3210              :  complex(dp) :: a_from, a_forw, g_forw, g0, b
    3211              : !arrays
    3212              :  real(dp) :: kpt(3), qpt(3), kpq(3)
    3213         4570 :  complex(dp) :: ak(self%gqk%nb_k), akq(self%gqk%nb_kq), bq(self%gqk%my_npert)
    3214              : !----------------------------------------------------------------------
    3215              : 
    3216         2285 :  gqk => self%gqk
    3217              : 
    3218         2285 :  enelph = zero
    3219       265381 :  do my_ik=1,gqk%my_nk
    3220      1052384 :    kpt(:) = self%my_kpts(:, my_ik)
    3221      1047222 :    ak(:) = self%my_a(:, my_ik, ip)
    3222              : 
    3223     33666383 :    do my_iq=1,gqk%my_nq
    3224    133604008 :      qpt(:) = self%my_qpts(:, my_iq)
    3225              : 
    3226              :      ! Find k+q-->k' index in krank_kpts
    3227    133604008 :      kpq(:) = kpt(:) + qpt(:)
    3228     33401002 :      ik_forw = self%krank_kpts%get_index(kpq)
    3229              :      ! If erange filter was used in gstore, some transitions are not valid
    3230     33401002 :      if (ik_forw == -1) cycle
    3231              : 
    3232              :      ! Check if q=\Gamma
    3233     40097230 :      q_gamma = .false.
    3234     40097230 :      if (all(abs(qpt) < tol6)) q_gamma = .true.
    3235              : 
    3236    127899998 :      akq(:) = self%a_glob(:, ik_forw, ip)
    3237    224628978 :      bq(:) = self%my_b(:, my_iq, ip)
    3238              : 
    3239    128163094 :      do ib=1,gqk%nb_k
    3240     95810144 :        a_from = ak(ib)
    3241              : 
    3242    416182160 :        do jb=1,gqk%nb_kq
    3243    286971014 :          a_forw = akq(jb)
    3244              : 
    3245   2104607242 :          do my_pert=1,gqk%my_npert
    3246   1721826084 :            b = bq(my_pert)
    3247              : 
    3248   1721826084 :            g_forw = gqk%my_g(my_pert, jb, my_iq, ib, my_ik)
    3249              :            ! Add long-range correction to matrix elements at Gamma
    3250   1721826084 :            g0 = self%my_g0(my_pert)
    3251   1721826084 :            if (q_gamma .and. (ib == jb)) then
    3252      4704756 :              g_forw = g_forw + g0
    3253              :            endif
    3254              : 
    3255   2008797098 :            enelph = enelph + real(a_from*conjg(b)*g_forw*conjg(a_forw), dp)
    3256              :          enddo
    3257              :        enddo
    3258              :      enddo
    3259              : 
    3260              :    enddo
    3261              :  enddo
    3262         2285 :  call xmpi_sum(enelph, gqk%comm%value, ierr)
    3263         2285 :  enelph = -two*enelph/(one*self%nkbz*self%nqbz)
    3264              : 
    3265         2285 :  end function polstate_get_enelph
    3266              : !!***
    3267              : 
    3268              : !----------------------------------------------------------------------
    3269              : 
    3270              : !!****f* m_varpeq/polstate_get_enph
    3271              : !! NAME
    3272              : !!  polstate_get_enph
    3273              : !!
    3274              : !! FUNCTION
    3275              : !!  Returns the vibrational term of the polaron bidning energy at a specified
    3276              : !!  polaronic state.
    3277              : !!
    3278              : !! INPUTS
    3279              : !!  ip=Index of a polaronic state.
    3280              : !!
    3281              : !! OUTPUT
    3282              : !!  enph=Vibrational term of the polaron binding energy.
    3283              : !!
    3284              : !! SOURCE
    3285              : 
    3286         4570 : real(dp) function polstate_get_enph(self, ip) result(enph)
    3287              : 
    3288              : !Arguments ------------------------------------
    3289              :  class(polstate_t), intent(inout) :: self
    3290              :  integer, intent(in) :: ip
    3291              : 
    3292              : !Local variables-------------------------------
    3293              :  class(gqk_t), pointer :: gqk
    3294              :  integer :: ierr, my_iq, my_pert
    3295              : !----------------------------------------------------------------------
    3296              : 
    3297         2285 :  gqk => self%gqk
    3298              : 
    3299         2285 :  enph = zero
    3300       280113 :  do my_iq=1,gqk%my_nq
    3301      1947081 :    do my_pert=1,gqk%my_npert
    3302              :      enph = enph + &
    3303      1944796 :        gqk%my_wnuq(my_pert, my_iq)*abs(self%my_b(my_pert, my_iq, ip))**2
    3304              :    enddo
    3305              :  enddo
    3306         2285 :  call xmpi_sum(enph, gqk%qpt_pert_comm%value, ierr)
    3307         2285 :  enph = enph/real(self%nqbz, dp)
    3308              : 
    3309         2285 : end function polstate_get_enph
    3310              : !!***
    3311              : 
    3312              : !----------------------------------------------------------------------
    3313              : 
    3314              : !!****f* m_varpeq/polstate_get_enel
    3315              : !! NAME
    3316              : !!  polstate_get_enel
    3317              : !!
    3318              : !! FUNCTION
    3319              : !!  Returns the electronic term of the polaron bidning energy at a specified
    3320              : !!  polaronic state.
    3321              : !!
    3322              : !! INPUTS
    3323              : !!  ip=Index of a polaronic state.
    3324              : !!
    3325              : !! OUTPUT
    3326              : !!  enel=Electronic term of the polaron binding energy.
    3327              : !!
    3328              : !! SOURCE
    3329              : 
    3330         4570 : real(dp) function polstate_get_enel(self, ip) result(enel)
    3331              : 
    3332              : !Arguments ------------------------------------
    3333              :  class(polstate_t), intent(inout) :: self
    3334              :  integer, intent(in) :: ip
    3335              : 
    3336              : !Local variables-------------------------------
    3337              :  class(gqk_t), pointer :: gqk
    3338              :  integer :: ierr, my_ik, ik_ibz, ib
    3339              : 
    3340              : !----------------------------------------------------------------------
    3341              : 
    3342         2285 :  gqk => self%gqk
    3343              : 
    3344         2285 :  enel = zero
    3345       265381 :  do my_ik=1,gqk%my_nk
    3346       263096 :    ik_ibz = gqk%my_k2ibz(1, my_ik)
    3347      1049507 :    do ib=1,gqk%nb_k
    3348      1047222 :      enel = enel + self%eig(ib, ik_ibz)*abs(self%my_a(ib, my_ik, ip))**2
    3349              :    enddo
    3350              :  enddo
    3351         2285 :  call xmpi_sum(enel, gqk%kpt_comm%value, ierr)
    3352         2285 :  enel = enel/self%nkbz
    3353              : 
    3354         2285 : end function polstate_get_enel
    3355              : !!***
    3356              : 
    3357              : !----------------------------------------------------------------------
    3358              : 
    3359              : !!****f* m_varpeq/polstate_calc_b_from_a
    3360              : !! NAME
    3361              : !!  polstate_calc_b_from_a
    3362              : !!
    3363              : !! FUNCTION
    3364              : !!  Calculate vibrational coefficients B_q\nu at the current configuration,
    3365              : !!  so the energy gradient wrt B_q\nu is 0.
    3366              : !!
    3367              : !! INPUTS
    3368              : !!   ip=Index of a polaronic state.
    3369              : !!
    3370              : !! OUTPUT
    3371              : !!
    3372              : !! SOURCE
    3373              : 
    3374          316 : subroutine polstate_calc_b_from_a(self, ip)
    3375              : 
    3376              : !Arguments ------------------------------------
    3377              :  class(polstate_t), intent(inout) :: self
    3378              :  integer, intent(in) :: ip
    3379              : 
    3380              : !Local variables-------------------------------
    3381              : !scalars
    3382              :  class(gqk_t), pointer :: gqk
    3383              :  logical :: q_gamma
    3384              :  integer :: ierr, my_iq, my_pert, my_ik, ik_forw, ib, jb, ik_ibz, pert_glob
    3385              :  real(dp) :: wqnu
    3386              :  complex(dp) :: a_from, a_forw, g_forw, g0, b_tmp
    3387              : !arrays
    3388              :  real(dp) :: qpt(3), kpq(3)
    3389          632 :  complex(dp) :: ak(self%gqk%nb_k), akq(self%gqk%nb_kq)
    3390              : !----------------------------------------------------------------------
    3391              : 
    3392          316 :  gqk => self%gqk
    3393              : 
    3394        32019 :  do my_iq=1,gqk%my_nq
    3395       126812 :    qpt(:) = self%my_qpts(:, my_iq)
    3396              :    ! Check if q=\Gamma
    3397        39301 :    q_gamma = .false.
    3398        39301 :    if (all(abs(qpt) < tol6)) q_gamma = .true.
    3399              : 
    3400       222237 :    do my_pert=1,gqk%my_npert
    3401       190218 :      pert_glob = gqk%my_pert_start + my_pert - 1
    3402              : 
    3403       190218 :      wqnu = gqk%my_wnuq(my_pert, my_iq)
    3404              : 
    3405              :      ! Skip acoustic modes at Gamma
    3406       190218 :      if (wqnu < EPHTK_WTOL) then
    3407          948 :        self%my_b(my_pert, my_iq, ip) = zero
    3408          948 :        cycle
    3409              :      endif
    3410       189270 :      g0 = self%my_g0(my_pert)
    3411              : 
    3412              :      ! For this q and perturbation, calculate linear B_q\nu sum
    3413       189270 :      b_tmp = zero
    3414     15950619 :      do my_ik=1,self%gqk%my_nk
    3415              :        ! Find k+q-->k' index in krank_kpts
    3416     63045396 :        kpq(:) = qpt(:) + self%my_kpts(:, my_ik)
    3417     15761349 :        ik_forw = self%krank_kpts%get_index(kpq)
    3418              :        ! If erange filter was used in gstore, some transitions are not valid
    3419     15761349 :        if (ik_forw == -1) cycle
    3420              : 
    3421      7894461 :        ik_ibz = gqk%my_k2ibz(1, my_ik)
    3422              : 
    3423     28836822 :        ak(:) = self%my_a(:, my_ik, ip)
    3424     28836822 :        akq(:) = self%a_glob(:, ik_forw, ip)
    3425              : 
    3426     29026092 :        do ib=1,gqk%nb_k
    3427     20942361 :          a_from = ak(ib)
    3428              : 
    3429     96789771 :          do jb=1,gqk%nb_kq
    3430     60086061 :            a_forw = akq(jb)
    3431              : 
    3432     60086061 :            g_forw = gqk%my_g(my_pert, jb, my_iq, ib, my_ik)
    3433              :            ! Add long-range correction to matrix elements at Gamma
    3434     60086061 :            if (q_gamma .and. (ib == jb)) then
    3435       137253 :              g_forw = g_forw + g0
    3436              :            endif
    3437              : 
    3438     81028422 :            b_tmp = b_tmp + a_from*g_forw*conjg(a_forw)
    3439              : 
    3440              :          enddo
    3441              :        enddo
    3442              :      enddo
    3443       189270 :      call xmpi_sum(b_tmp, gqk%kpt_comm%value, ierr)
    3444              : 
    3445       189270 :      b_tmp = b_tmp / (real(self%nkbz, dp) * wqnu)
    3446              : 
    3447       220973 :      self%my_b(my_pert, my_iq, ip) = b_tmp
    3448              :    enddo
    3449              :  enddo
    3450              : 
    3451          316 : end subroutine polstate_calc_b_from_a
    3452              : !!***
    3453              : 
    3454              : !----------------------------------------------------------------------
    3455              : 
    3456              : !!****f* m_varpeq/polstate_calc_b_from_displ
    3457              : !! NAME
    3458              : !!  polstate_calc_b_from_displ
    3459              : !!
    3460              : !! FUNCTION
    3461              : !!  Calculate vibrational coefficients B_q\nu from a set of atomic
    3462              : !!  displacements.
    3463              : !!
    3464              : !! INPUTS
    3465              : !!   ip=Index of a polaronic state.
    3466              : !!   scell<supercell_type>=Supercell data structure.
    3467              : !!   cryst<crystal_type>=Crystal data structure.
    3468              : !!
    3469              : !! OUTPUT
    3470              : !!
    3471              : !! SOURCE
    3472              : 
    3473            0 : subroutine polstate_calc_b_from_displ(self, ip, scell, cryst)
    3474              : 
    3475              : !Arguments ------------------------------------
    3476              :  class(polstate_t), intent(inout) :: self
    3477              :  integer, intent(in) :: ip
    3478              :  class(supercell_type), intent(in) :: scell
    3479              :  class(crystal_t), intent(in) :: cryst
    3480              : 
    3481              : !Local variables-------------------------------
    3482              : !scalars
    3483              :  class(gqk_t), pointer :: gqk
    3484              :  integer :: iatom_sc, iatom_uc, typat, idir
    3485              :  integer :: my_iq, my_pert
    3486              :  real(dp) :: wqnu, phdispl_re, phdispl_im, amass, dtau
    3487              :  complex(dp) :: bqnu_tmp, my_phdispl, cphase
    3488              : !arrays
    3489              :  integer :: cell_vec(3)
    3490              :  real(dp) :: qpt(3)
    3491              : 
    3492              : !----------------------------------------------------------------------
    3493              : 
    3494            0 :  gqk => self%gqk
    3495              : 
    3496              :  ! loop over q-vectors and perturbations
    3497            0 :  do my_iq=1,gqk%my_nq
    3498            0 :    qpt(:) = self%my_qpts(:, my_iq)
    3499              : 
    3500            0 :    do my_pert=1,gqk%my_npert
    3501            0 :      wqnu = gqk%my_wnuq(my_pert, my_iq)
    3502              : 
    3503            0 :      bqnu_tmp = zero
    3504              :      ! loop over ALL atoms in the supercell & cartesian directions
    3505            0 :      do iatom_sc=1,scell%natom
    3506            0 :        iatom_uc = scell%atom_indexing(iatom_sc)
    3507            0 :        typat = scell%typat(iatom_sc)
    3508            0 :        cell_vec(:) = scell%uc_indexing(:, iatom_sc)
    3509              : 
    3510            0 :        cphase = exp(j_dpc * two_pi * dot_product(qpt, cell_vec))
    3511            0 :        amass = cryst%amu(typat) * amu_emass
    3512              : 
    3513            0 :        do idir=1,3
    3514            0 :          phdispl_re = gqk%my_displ_cart(1, idir, iatom_uc, my_pert, my_iq)
    3515            0 :          phdispl_im = gqk%my_displ_cart(2, idir, iatom_uc, my_pert, my_iq)
    3516            0 :          my_phdispl = phdispl_re + j_dpc * phdispl_im
    3517              : 
    3518            0 :          dtau = self%displ(idir, iatom_sc, ip)
    3519              : 
    3520            0 :          bqnu_tmp = bqnu_tmp + amass * my_phdispl * cphase * dtau
    3521              : 
    3522              :        enddo
    3523              :      enddo
    3524            0 :      bqnu_tmp = -bqnu_tmp * sqrt(wqnu) * sqrthalf
    3525              : 
    3526            0 :      self%my_b(my_pert, my_iq, ip) = bqnu_tmp
    3527              : 
    3528              :    enddo
    3529              :  enddo
    3530              : 
    3531            0 : end subroutine polstate_calc_b_from_displ
    3532              : !!***
    3533              : 
    3534              : !----------------------------------------------------------------------
    3535              : 
    3536              : !!****f* m_varpeq/polstate_calc_displ_from_b
    3537              : !! NAME
    3538              : !!  polstate_calc_displ_from_b
    3539              : !!
    3540              : !! FUNCTION
    3541              : !!  Calculate atomic displacements from a set of vibrational
    3542              : !!  coefficients B_q\nu.
    3543              : !!
    3544              : !! INPUTS
    3545              : !!   ip=Index of a polaronic state.
    3546              : !!   scell<supercell_type>=Supercell data structure.
    3547              : !!
    3548              : !! OUTPUT
    3549              : !!
    3550              : !! SOURCE
    3551              : 
    3552            0 : subroutine polstate_calc_displ_from_b(self, ip, scell)
    3553              : 
    3554              : !Arguments ------------------------------------
    3555              :  class(polstate_t), intent(inout) :: self
    3556              :  integer, intent(in) :: ip
    3557              :  class(supercell_type), intent(in) :: scell
    3558              : 
    3559              : !Local variables-------------------------------
    3560              : !scalars
    3561              :  class(gqk_t), pointer :: gqk
    3562              :  integer :: ierr
    3563              :  integer :: iatom_sc, iatom_uc, idir
    3564              :  integer :: my_iq, my_pert
    3565              :  real(dp) :: wqnu, phdispl_re, phdispl_im
    3566              :  complex(dp) :: bqnu, my_phdispl, cphase
    3567              : !arrays
    3568              :  integer :: cell_vec(3)
    3569              :  real(dp) :: qpt(3)
    3570              : 
    3571              : !----------------------------------------------------------------------
    3572              : 
    3573            0 :  gqk => self%gqk
    3574              : 
    3575            0 :  self%displ(:,:,ip) = zero
    3576              : 
    3577              :  ! loop over q-vectors and perturbations
    3578            0 :  do my_iq=1,gqk%my_nq
    3579            0 :    qpt(:) = self%my_qpts(:, my_iq)
    3580              : 
    3581            0 :    do my_pert=1,gqk%my_npert
    3582            0 :      wqnu = gqk%my_wnuq(my_pert, my_iq)
    3583              : 
    3584              :      ! Skip acoustic modes at Gamma
    3585            0 :      if (abs(wqnu) < tol12) cycle
    3586              : 
    3587            0 :      bqnu = self%my_b(my_pert, my_iq, ip)
    3588              : 
    3589              :      ! loop over ALL atoms in the supercell & cartesian directions
    3590            0 :      do iatom_sc=1,scell%natom
    3591            0 :        iatom_uc = scell%atom_indexing(iatom_sc)
    3592            0 :        cell_vec(:) = scell%uc_indexing(:, iatom_sc)
    3593              : 
    3594            0 :        cphase = exp(j_dpc * two_pi * dot_product(qpt, cell_vec))
    3595              : 
    3596            0 :        do idir=1,3
    3597            0 :          phdispl_re = gqk%my_displ_cart(1, idir, iatom_uc, my_pert, my_iq)
    3598            0 :          phdispl_im = gqk%my_displ_cart(2, idir, iatom_uc, my_pert, my_iq)
    3599            0 :          my_phdispl = phdispl_re + j_dpc * phdispl_im
    3600              : 
    3601              :          self%displ(idir, iatom_sc, ip) = self%displ(idir, iatom_sc, ip) + &
    3602            0 :            conjg(bqnu) * my_phdispl * cphase / sqrt(wqnu)
    3603              : 
    3604              :        enddo
    3605              :      enddo
    3606              :    enddo
    3607              :  enddo
    3608              : 
    3609            0 :  call xmpi_sum(self%displ(:,:,ip), gqk%qpt_pert_comm%value, ierr)
    3610            0 :  self%displ(:,:,ip) = -sqrt2 / self%nqbz * self%displ(:,:,ip)
    3611              : 
    3612            0 : end subroutine polstate_calc_displ_from_b
    3613              : !!***
    3614              : 
    3615              : !----------------------------------------------------------------------
    3616              : 
    3617              : !!****f* m_varpeq/calc_clb_displ
    3618              : !! NAME
    3619              : !!  calc_clb_displ
    3620              : !!
    3621              : !! FUNCTION
    3622              : !!  Calculate Coulomb displacements introduced by a unit charge localized
    3623              : !!  on a supercell atom
    3624              : !!  Note that internally it is assumed that the localized charge is negative,
    3625              : !!  regargdless of the polaron type. However, for hole polaron, the displacements
    3626              : !!  are filpped at post-processing and hence physically correct.
    3627              : !!
    3628              : !! INPUTS
    3629              : !!   atloc=Index of an atom where charge is localized.
    3630              : !!   chrgat(natom)=Charge of the atoms.
    3631              : !!   scell<supercell_type>=Supercell data structure.
    3632              : !!   cryst<crystal_t>=Crystal data structure.
    3633              : !!
    3634              : !! OUTPUT
    3635              : !!
    3636              : !! SOURCE
    3637              : 
    3638            0 : subroutine polstate_calc_clb_displ(self, atloc, chrgat, scell, cryst)
    3639              : 
    3640              : !Arguments ------------------------------------
    3641              :  class(polstate_t), intent(inout) :: self
    3642              :  integer, intent(in) :: atloc
    3643              :  class(supercell_type), intent(in) :: scell
    3644              :  class(crystal_t), intent(in) :: cryst
    3645              :  real(dp), intent(in) :: chrgat(scell%natom_primcell)
    3646              : 
    3647              : !Local variables-------------------------------
    3648              : !scalars
    3649              :  integer :: ip, ii, ix, iy, iz, iatom_sc, iatom_uc
    3650              : !arrays
    3651              :  integer :: sc_ind(3)
    3652              :  integer :: box_dim(3), center_sc(3), vec(3)
    3653              :  real(dp) :: rdist(3), center_atom(3)
    3654            0 :  integer, allocatable :: scell_flag(:,:,:)
    3655            0 :  real(dp), allocatable :: scell_displ(:,:,:,:,:)
    3656              : 
    3657              : !----------------------------------------------------------------------
    3658              : 
    3659              :  ! supercell center
    3660            0 :  center_sc(:) = (self%ngkpt(:) + 1) / 2
    3661              :  ! select atom in the unit cell
    3662            0 :  center_atom(:) = cryst%xcart(:, atloc)
    3663              : 
    3664              :  ! displacement box dimensions
    3665            0 :  do ii=1,3
    3666            0 :    box_dim(ii) = min(3, self%ngkpt(ii))
    3667              :  enddo
    3668              : 
    3669            0 :  ABI_MALLOC(scell_displ, (3, cryst%natom, self%ngkpt(1), self%ngkpt(2), self%ngkpt(3)))
    3670            0 :  ABI_MALLOC(scell_flag, (self%ngkpt(1), self%ngkpt(2), self%ngkpt(3)))
    3671            0 :  scell_flag(:,:,:) = zero
    3672            0 :  scell_displ(:,:,:,:,:) = zero
    3673              : 
    3674            0 :  do iz=1,box_dim(3)
    3675            0 :    do iy=1,box_dim(2)
    3676            0 :      do ix=1,box_dim(1)
    3677              :         ! get all displacement vectors wrt centeral supercell
    3678              :         vec(:) = [shift_(ix-1, box_dim(1)), &
    3679            0 :           shift_(iy-1, box_dim(2)), shift_(iz-1, box_dim(3))]
    3680              : 
    3681              :         ! get indices of related supercells
    3682            0 :         do ii=1,3
    3683              :           ! add 1 becasue of fortran indexing
    3684            0 :           sc_ind(ii) = mod(center_sc(ii) + vec(ii) - 1, self%ngkpt(ii))
    3685            0 :           sc_ind(ii) = sc_ind(ii) + 1
    3686              :         enddo
    3687            0 :         scell_flag(sc_ind(1), sc_ind(2), sc_ind(3)) = one
    3688              : 
    3689              :         ! calculate displacements in these supercells
    3690            0 :         do iatom_uc=1,cryst%natom
    3691              :           rdist(:) = matmul(cryst%rprimd(:,:), vec(:)) + &
    3692            0 :             cryst%xcart(:,iatom_uc) - center_atom(:)
    3693            0 :           if (norm2(rdist) > tol8) then
    3694              :             scell_displ(:,iatom_uc,sc_ind(1),sc_ind(2),sc_ind(3)) = &
    3695            0 :               -chrgat(iatom_uc) * rdist(:) / norm2(rdist)**3
    3696              :           endif
    3697              : 
    3698              :         enddo
    3699              : 
    3700              :      enddo
    3701              :    enddo
    3702              :  enddo
    3703              : 
    3704            0 :  self%displ(:,:,:) = zero
    3705              :  ! insert displacements
    3706            0 :  ip = 1
    3707            0 :  do iatom_sc=1,scell%natom
    3708            0 :    iatom_uc = scell%atom_indexing(iatom_sc)
    3709              :    ! add 1 becasue of fortran indexing
    3710            0 :    vec(:) = scell%uc_indexing(:, iatom_sc) + 1
    3711            0 :    if (scell_flag(vec(1), vec(2), vec(3)) /= 0) then
    3712            0 :      self%displ(:,iatom_sc,ip) = scell_displ(:,iatom_uc, vec(1), vec(2), vec(3))
    3713              :    endif
    3714              :  enddo
    3715            0 :  do ip=2,self%np
    3716            0 :    self%displ(:,iatom_sc,ip) = self%displ(:,iatom_sc,ip-1)
    3717              :  enddo
    3718              : 
    3719            0 :  ABI_FREE(scell_flag)
    3720            0 :  ABI_FREE(scell_displ)
    3721              : 
    3722              : !----------------------------------------------------------------------
    3723              : 
    3724              :  contains
    3725            0 :  integer function shift_(x, n) result(x_shift)
    3726              :   integer, intent(in) :: x, n
    3727            0 :   x_shift = x
    3728            0 :   if (x > n/2) x_shift = -n + x
    3729              :  end function shift_
    3730              : 
    3731              : end subroutine polstate_calc_clb_displ
    3732              : !!***
    3733              : 
    3734              : !----------------------------------------------------------------------
    3735              : 
    3736              : !!****f* m_varpeq/polstate_calc_phgrad
    3737              : !! NAME
    3738              : !!  polstate_calc_phgrad
    3739              : !!
    3740              : !! FUNCTION
    3741              : !!  Calculate the gradient of the polaronic energy wrt phonon
    3742              : !!  coefficients B_q\nu.
    3743              : !!
    3744              : !! INPUTS
    3745              : !!   ip=Index of a polaronic state.
    3746              : !!
    3747              : !! OUTPUT
    3748              : !!
    3749              : !! SOURCE
    3750              : 
    3751          135 : subroutine polstate_calc_phgrad(self, ip)
    3752              : 
    3753              : !Arguments ------------------------------------
    3754              :  class(polstate_t), intent(inout) :: self
    3755              :  integer, intent(in) :: ip
    3756              : 
    3757              : !Local variables-------------------------------
    3758              : !scalars
    3759              :  class(gqk_t), pointer :: gqk
    3760              :  logical :: q_gamma
    3761              :  integer :: ierr
    3762              :  integer :: my_iq, my_pert
    3763              :  integer:: my_ik, ik_forw, ib, jb
    3764              :  real(dp) :: wqnu
    3765              :  complex(dp) :: a_from, a_forw, g_forw, phgrad_tmp
    3766              :  complex(dp) :: g0, b
    3767              : !arrays
    3768              :  real(dp) :: qpt(3), kpq(3)
    3769          270 :  complex(dp) :: ak(self%gqk%nb_k), akq(self%gqk%nb_kq)
    3770              : 
    3771              : !----------------------------------------------------------------------
    3772              : 
    3773          135 :  gqk => self%gqk
    3774              : 
    3775        17010 :  do my_iq=1,gqk%my_nq
    3776        67500 :    qpt(:) = self%my_qpts(:, my_iq)
    3777              :    ! Check if q=\Gamma
    3778        21060 :    q_gamma = .false.
    3779        21060 :    if (all(abs(qpt) < tol6)) q_gamma = .true.
    3780              : 
    3781       118260 :    do my_pert=1,gqk%my_npert
    3782       101250 :      b = self%my_b(my_pert, my_iq, ip)
    3783       101250 :      wqnu = gqk%my_wnuq(my_pert, my_iq)
    3784       101250 :      g0 = self%my_g0(my_pert)
    3785              : 
    3786              :     ! For this q and perturbation, calculate B_q\nu sum
    3787       101250 :      phgrad_tmp = zero
    3788              : 
    3789     12757500 :      do my_ik=1,self%gqk%my_nk
    3790              :        ! Find k+q-->k' index in krank_kpts
    3791     50625000 :        kpq(:) = qpt(:) + self%my_kpts(:, my_ik)
    3792     12656250 :        ik_forw = self%krank_kpts%get_index(kpq)
    3793              : 
    3794              :        ! If erange filter was used in gstore, some transitions are not valid
    3795     12656250 :        if (ik_forw == -1) cycle
    3796              : 
    3797     50625000 :        ak(:) = self%my_a(:, my_ik, ip)
    3798     50625000 :        akq(:) = self%a_glob(:, ik_forw, ip)
    3799              : 
    3800     50726250 :        do ib=1,gqk%nb_k
    3801     37968750 :          a_from = ak(ib)
    3802              : 
    3803    164531250 :          do jb=1,gqk%nb_kq
    3804    113906250 :            a_forw = akq(jb)
    3805              : 
    3806    113906250 :            g_forw = gqk%my_g(my_pert, jb, my_iq, ib, my_ik)
    3807              :            ! Add long-range correction to matrix elements at Gamma
    3808    113906250 :            if (q_gamma .and. (ib == jb)) then
    3809       303750 :              g_forw = g_forw + g0
    3810              :            endif
    3811              : 
    3812    151875000 :            phgrad_tmp = phgrad_tmp + a_from*g_forw*conjg(a_forw)
    3813              :          enddo
    3814              :        enddo
    3815              :      enddo
    3816       101250 :      call xmpi_sum(phgrad_tmp, gqk%kpt_comm%value, ierr)
    3817              : 
    3818              :      self%my_phgrad(my_pert, my_iq, ip) = &
    3819       118125 :        two/self%nqbz * (b*wqnu - phgrad_tmp / self%nkbz)
    3820              : 
    3821              :    enddo
    3822              :  enddo
    3823              : 
    3824          135 : end subroutine polstate_calc_phgrad
    3825              : !!***
    3826              : 
    3827              : !----------------------------------------------------------------------
    3828              : 
    3829              : !!****f* m_varpeq/polstate_calc_hpol
    3830              : !! NAME
    3831              : !!  polstate_calc_hpol
    3832              : !!
    3833              : !! FUNCTION
    3834              : !!  Construct and calculate the polaron Hamiltonian, <A_bra|H_pol(B)|A_ket>
    3835              : !!
    3836              : !! INPUTS
    3837              : !!   my_a_bra(gqk%nb_kq,gqk%my_nk)=Electronic coefficients for the bra vector
    3838              : !!   a_bra_lglob(gqk%nb_kq,gqk%glob_nk)=Electronic coefficients for the bra vectors
    3839              : !!     (global array)
    3840              : !!   my_a_ket(gqk%nb_k,gqk%my_nk)=Electronic coefficients for the ket vector
    3841              : !!   my_b(gqk%my_npert,gqk%my_nq)=Phonon coeffcients used to construct H_pol(B)
    3842              : !!   Note that these arrays are MPI-distributed as in the polstate datatype
    3843              : !!
    3844              : !! OUTPUT
    3845              : !!
    3846              : !! SOURCE
    3847              : 
    3848         6450 : real(dp) function polstate_calc_hpol(self, my_a_bra, a_bra_glob, my_a_ket, my_b) &
    3849              :     result(hpol)
    3850              : 
    3851              : !Arguments ------------------------------------
    3852              :  class(polstate_t), intent(inout) :: self
    3853              :  complex(dp), intent(in) :: my_a_bra(self%gqk%nb_kq, self%gqk%my_nk)
    3854              :  complex(dp), intent(in) :: a_bra_glob(self%gqk%nb_kq, self%gqk%glob_nk)
    3855              :  complex(dp), intent(in) :: my_a_ket(self%gqk%nb_k, self%gqk%my_nk)
    3856              :  complex(dp), intent(in) :: my_b(self%gqk%my_npert, self%gqk%my_nq)
    3857              : 
    3858              : !Local variables-------------------------------
    3859              : !scalars
    3860              :  class(gqk_t), pointer :: gqk
    3861              :  logical :: q_gamma
    3862              :  integer :: ierr, my_ik, ik_ibz, ib
    3863              :  integer :: my_iq, my_pert, ik_forw, jb
    3864              :  complex(dp) :: a_from, a_forw, g_forw, g0, b
    3865              :  real(dp) :: h_el, h_elph
    3866              : !arrays
    3867              :  real(dp) :: kpt(3), qpt(3), kpq(3)
    3868        12900 :  complex(dp) :: a_ket(self%gqk%nb_k), a_bra(self%gqk%nb_kq), bq(self%gqk%my_npert)
    3869              : 
    3870              : !----------------------------------------------------------------------
    3871              : 
    3872         6450 :  gqk => self%gqk
    3873              : 
    3874              :  ! <A_1|H_p(B)|A_2> = <A_1|H_el(B)|A_2> + <A_1|H_el-ph(B)|A_2>
    3875              : 
    3876              :  ! 1st term
    3877         6450 :   h_el = zero
    3878       746763 :   do my_ik=1,gqk%my_nk
    3879       740313 :     ik_ibz = gqk%my_k2ibz(1, my_ik)
    3880      2952750 :     do ib=1,gqk%nb_k
    3881              :       h_el = h_el + &
    3882      2946300 :         conjg(my_a_bra(ib, my_ik))*self%eig(ib, ik_ibz)*my_a_ket(ib, my_ik)
    3883              :     enddo
    3884              :   enddo
    3885         6450 :   call xmpi_sum(h_el, gqk%kpt_comm%value, ierr)
    3886         6450 :   h_el = h_el/self%nkbz
    3887              : 
    3888              :   ! 2nd term
    3889         6450 :   h_elph = zero
    3890       746763 :   do my_ik=1,gqk%my_nk
    3891      2961252 :     kpt(:) = self%my_kpts(:, my_ik)
    3892      2946300 :     a_ket(:) = my_a_ket(:, my_ik)
    3893              : 
    3894     94757046 :     do my_iq=1,gqk%my_nq
    3895    376041132 :       qpt(:) = self%my_qpts(:, my_iq)
    3896              : 
    3897              :       ! Find k+q-->k' index in krank_kpts
    3898    376041132 :       kpq(:) = kpt(:) + qpt(:)
    3899     94010283 :       ik_forw = self%krank_kpts%get_index(kpq)
    3900              :       ! If erange filter was used in gstore, some transitions are not valid
    3901     94010283 :       if (ik_forw == -1) cycle
    3902              : 
    3903              :       ! Check if q=\Gamma
    3904    112728480 :       q_gamma = .false.
    3905    112728480 :       if (all(abs(qpt) < tol6)) q_gamma = .true.
    3906              : 
    3907    359519172 :       a_bra(:) = a_bra_glob(:, ik_forw)
    3908    631487325 :       bq(:) = my_b(:, my_iq)
    3909              : 
    3910    360259485 :       do ib=1,gqk%nb_k
    3911    269306697 :         a_from = a_ket(ib)
    3912              : 
    3913   1169906343 :         do jb=1,gqk%nb_kq
    3914    806589363 :           a_forw = a_bra(jb)
    3915              : 
    3916   5915432238 :           do my_pert=1,gqk%my_npert
    3917   4839536178 :             b = bq(my_pert)
    3918              : 
    3919   4839536178 :             g_forw = gqk%my_g(my_pert, jb, my_iq, ib, my_ik)
    3920              :             ! Add long-range correction to matrix elements at Gamma
    3921   4839536178 :             g0 = self%my_g0(my_pert)
    3922   4839536178 :             if (q_gamma .and. (ib == jb)) then
    3923     13235922 :               g_forw = g_forw + g0
    3924              :             endif
    3925              : 
    3926   5646125541 :             h_elph = h_elph + real(a_from*conjg(b)*g_forw*conjg(a_forw), dp)
    3927              :           enddo
    3928              :         enddo
    3929              :       enddo
    3930              : 
    3931              :     enddo
    3932              :   enddo
    3933         6450 :   call xmpi_sum(h_elph, gqk%comm%value, ierr)
    3934         6450 :   h_elph = -two*h_elph/(one*self%nkbz*self%nqbz)
    3935              : 
    3936         6450 :   hpol = h_el + h_elph
    3937              : 
    3938         6450 : end function polstate_calc_hpol
    3939              : !!***
    3940              : 
    3941              : !----------------------------------------------------------------------
    3942              : 
    3943              : !!****f* m_varpeq/polstate_load_a
    3944              : !! NAME
    3945              : !!  polstate_load_a
    3946              : !!
    3947              : !! FUNCTION
    3948              : !!  Load the initial vector of electronic coefficients A_nk from source.
    3949              : !!
    3950              : !! INPUTS
    3951              : !!  a_src(self%gqk%nb_k, self%gqk%glob_nk)=Global A_nk array to be loaded.
    3952              : !!
    3953              : !! OUTPUT
    3954              : !!
    3955              : !! SOURCE
    3956              : 
    3957            0 : subroutine polstate_load_a(self, a_src, ip)
    3958              : 
    3959              : !Arguments ------------------------------------
    3960              : !scalars
    3961              :  class(polstate_t), intent(inout) :: self
    3962              :  integer, intent(in) :: ip
    3963              : !arrays
    3964              :  complex(dp), intent(in) :: a_src(self%gqk%nb_k, self%gqk%glob_nk)
    3965              : 
    3966              : !Local variables-------------------------------
    3967              :  class(gqk_t), pointer :: gqk
    3968              :  integer :: my_ik, ik_glob, ib
    3969              : !----------------------------------------------------------------------
    3970              : 
    3971            0 :  gqk => self%gqk
    3972              : 
    3973            0 :  do my_ik=1,gqk%my_nk
    3974            0 :    ik_glob = gqk%my_kstart + my_ik - 1
    3975            0 :    do ib=1,gqk%nb_k
    3976            0 :      self%my_a(ib, my_ik, ip) = a_src(ib, ik_glob)
    3977              :    enddo
    3978              :  enddo
    3979              : 
    3980            0 : end subroutine polstate_load_a
    3981              : !!***
    3982              : 
    3983              : !----------------------------------------------------------------------
    3984              : 
    3985              : !!****f* m_varpeq/polstate_load_b
    3986              : !! NAME
    3987              : !!  polstate_load_b
    3988              : !!
    3989              : !! FUNCTION
    3990              : !!  Load the initial vector of phonon coefficients B_q\nu from source.
    3991              : !!
    3992              : !! INPUTS
    3993              : !!  b_src(self%gqk%natom3, self%gqk%glob_nq)=Global B_q\nu array to be loaded.
    3994              : !!  ip=Index of a polaronic state.
    3995              : !!  trvec(3) [optional]=Translational vector.
    3996              : !!
    3997              : !! OUTPUT
    3998              : !!
    3999              : !! SOURCE
    4000              : 
    4001            2 : subroutine polstate_load_b(self, b_src, ip, trvec)
    4002              : 
    4003              : !Arguments ------------------------------------
    4004              : !scalars
    4005              :  class(polstate_t), intent(inout) :: self
    4006              :  integer, intent(in) :: ip
    4007              : !arrays
    4008              :  complex(dp), intent(in) :: b_src(self%gqk%natom3, self%gqk%glob_nq)
    4009              :  integer, optional, intent(in) :: trvec(3)
    4010              : 
    4011              : !Local variables-------------------------------
    4012              : !scalars
    4013              :  class(gqk_t), pointer :: gqk
    4014              :  integer :: my_iq, my_pert, pert_glob, iq_glob
    4015              :  complex(dp) :: cphase
    4016              : !arrays
    4017              :  integer trvec_(3)
    4018              :  real(dp) :: qpt(3)
    4019              : 
    4020              : !----------------------------------------------------------------------
    4021              : 
    4022            2 :  gqk => self%gqk
    4023              : 
    4024            2 :  trvec_ (:) = 0
    4025            2 :  if (present(trvec)) trvec_(:) = trvec(:)
    4026              : 
    4027          252 :  do my_iq=1,gqk%my_nq
    4028          250 :    iq_glob = gqk%my_qstart + my_iq - 1
    4029         1000 :    qpt(:) = self%my_qpts(:, my_iq)
    4030              : 
    4031         1000 :    cphase = exp(+j_dpc * two_pi * dot_product(qpt, trvec_))
    4032              : 
    4033         1752 :    do my_pert=1,gqk%my_npert
    4034         1500 :      pert_glob = gqk%my_pert_start + my_pert - 1
    4035         1750 :      self%my_b(my_pert, my_iq, ip) = b_src(pert_glob, iq_glob) * cphase
    4036              :    enddo
    4037              :  enddo
    4038              : 
    4039            2 : end subroutine polstate_load_b
    4040              : !!***
    4041              : 
    4042              : !----------------------------------------------------------------------
    4043              : 
    4044              : !!****f* m_varpeq/polstate_linterp_b
    4045              : !! NAME
    4046              : !!  polstate_linterp_b
    4047              : !!
    4048              : !! FUNCTION
    4049              : !!  Interpolate the phonon coefficients on uniform mesh between initial
    4050              : !!  and final state.
    4051              : !!
    4052              : !! INPUTS
    4053              : !!
    4054              : !! OUTPUT
    4055              : !!
    4056              : !! SOURCE
    4057              : 
    4058            1 : subroutine polstate_linterp_b(self)
    4059              : 
    4060              : !Arguments ------------------------------------
    4061              :  class(polstate_t), intent(inout) :: self
    4062              : 
    4063              : !Local variables-------------------------------
    4064              : !scalars
    4065              :  class(gqk_t), pointer :: gqk
    4066              :  integer :: ip, from_ip, to_ip
    4067              : !arrays
    4068            2 :  complex(dp) :: my_b_step(self%gqk%my_npert, self%gqk%my_nq)
    4069              : 
    4070              : !----------------------------------------------------------------------
    4071              : 
    4072            1 :  gqk => self%gqk
    4073              : 
    4074            1 :  from_ip = 1; to_ip = self%np
    4075              : 
    4076          876 :  my_b_step(:,:) = (self%my_b(:,:,to_ip) - self%my_b(:,:,from_ip)) / (self%np - one)
    4077              : 
    4078            8 :  do ip=2,self%np-1
    4079         6133 :    self%my_b(:,:,ip) = self%my_b(:,:,ip-1) + my_b_step(:,:)
    4080              :  enddo
    4081              : 
    4082            1 : end subroutine polstate_linterp_b
    4083              : !!***
    4084              : 
    4085              : !----------------------------------------------------------------------
    4086              : 
    4087              : !!****f* m_varpeq/polstate_redistr_b
    4088              : !! NAME
    4089              : !!  polstate_redistr_b
    4090              : !!
    4091              : !! FUNCTION
    4092              : !!  Redistribute the phonon coefficients B_\qnu with spline interpolation.
    4093              : !!  Assumes parametrization [0,1] -> B_\qnu.
    4094              : !!
    4095              : !! INPUTS
    4096              : !!
    4097              : !! OUTPUT
    4098              : !!
    4099              : !! SOURCE
    4100              : 
    4101           15 : subroutine polstate_redistr_b(self, mesh_in, mesh_out, nimag)
    4102              : 
    4103              : !Arguments ------------------------------------
    4104              :  class(polstate_t), intent(inout) :: self
    4105              :  integer, intent(in) :: nimag
    4106              :  real(dp), intent(in) :: mesh_in(nimag)
    4107              :  real(dp), intent(in) :: mesh_out(nimag)
    4108              : 
    4109              : !Local variables-------------------------------
    4110              : !scalars
    4111              :  class(gqk_t), pointer :: gqk
    4112              :  integer :: from_ip, to_ip
    4113              :  integer :: my_iq, my_pert
    4114              :  complex(dp) :: phgrad_qnu_from, phgrad_qnu_to
    4115              : !arrays
    4116           30 :  complex(dp) :: my_b_mesh_in(nimag)
    4117           30 :  complex(dp) :: my_2der_mesh_out(nimag)
    4118           30 :  complex(dp) :: my_b_mesh_out(nimag)
    4119              : 
    4120              : !----------------------------------------------------------------------
    4121              : 
    4122           15 :  gqk => self%gqk
    4123              : 
    4124           15 :  from_ip = 1; to_ip = self%np
    4125              : 
    4126              :  !call self%calc_phgrad(from_ip)
    4127              :  !call self%calc_phgrad(to_ip)
    4128              : 
    4129         1890 :  do my_iq=1,gqk%my_nq
    4130        13140 :    do my_pert=1,gqk%my_npert
    4131              : 
    4132              :      ! derivatives of the binding energy at endpoints
    4133        11250 :      phgrad_qnu_from = self%my_phgrad(my_pert, my_iq, from_ip)
    4134        11250 :      phgrad_qnu_to = self%my_phgrad(my_pert, my_iq, to_ip)
    4135              : 
    4136       112500 :      my_b_mesh_in(:) = self%my_b(my_pert, my_iq, :)
    4137              : 
    4138              :      ! spline interpolation
    4139              :      call spline_complex(mesh_in, my_b_mesh_in, nimag, phgrad_qnu_from, &
    4140        11250 :        phgrad_qnu_to, my_2der_mesh_out)
    4141              :      call splint_complex(nimag, mesh_in, my_b_mesh_in, my_2der_mesh_out, nimag, &
    4142        11250 :        mesh_out, my_b_mesh_out)
    4143              : 
    4144       114375 :      self%my_b(my_pert, my_iq, :) = my_b_mesh_out(:)
    4145              : 
    4146              :    enddo
    4147              :  enddo
    4148              : 
    4149           15 : end subroutine polstate_redistr_b
    4150              : !!***
    4151              : 
    4152              : !----------------------------------------------------------------------
    4153              : 
    4154              : !!****f* m_varpeq/polstate_calc_eff_phforce
    4155              : !! NAME
    4156              : !!  polstate_calc_eff_phforce
    4157              : !!
    4158              : !! FUNCTION
    4159              : !!  Calculate the effective phonon force for the hopping optimization.
    4160              : !!
    4161              : !! INPUTS
    4162              : !!  mode=Select the method for effective force calculation:
    4163              : !!    "fw_euler" ---> Forward Euler method;
    4164              : !!    "rk" ---> 4th order Runge-Kutta method.
    4165              : !!  ip=Index of a polaronic state.
    4166              : !!
    4167              : !! OUTPUT
    4168              : !!
    4169              : !! SOURCE
    4170              : 
    4171          135 : subroutine polstate_calc_eff_phforce(self, mode, ip)
    4172              : 
    4173              : !Arguments ------------------------------------
    4174              :  class(polstate_t), intent(inout) :: self
    4175              :  character(len=*), intent(in) :: mode
    4176              :  integer, intent(in) :: ip
    4177              : 
    4178              : !Local variables-------------------------------
    4179              : !scalars
    4180              :  class(gqk_t), pointer :: gqk
    4181              :  integer :: ii
    4182              : !arrays
    4183              :  real(dp) :: rk_shifts(3) = [half, half, one]
    4184          270 :  complex(dp) :: my_b_copy(self%gqk%my_npert, self%gqk%my_nq)
    4185          270 :  complex(dp) :: rk_coeff(self%gqk%my_npert, self%gqk%my_nq, 4)
    4186              : 
    4187              : !----------------------------------------------------------------------
    4188              : 
    4189          135 :  gqk => self%gqk
    4190              : 
    4191          135 :  call self%calc_phgrad(ip)
    4192              : 
    4193          135 :  select case(mode)
    4194              :  case ("fw_euler")
    4195       118260 :    self%my_eff_phforce(:,:,ip) = -self%my_phgrad(:,:,ip)
    4196              : 
    4197              :  case ("rk")
    4198              :    ! Make a copy of current B_\qnu
    4199            0 :    my_b_copy(:,:) = self%my_b(:,:,ip)
    4200              : 
    4201              :    ! Calculate Runge-Kutta coefficients
    4202            0 :    rk_coeff(:,:,1) = self%my_phgrad(:,:,ip)
    4203              : 
    4204            0 :    do ii=1,3
    4205            0 :      self%my_b(:,:,ip) = my_b_copy(:,:) + rk_shifts(ii) * rk_coeff(:,:,ii)
    4206            0 :      call self%calc_phgrad(ip)
    4207            0 :      rk_coeff(:,:,ii+1) = self%my_phgrad(:,:,ip)
    4208              :    enddo
    4209              : 
    4210              :    self%my_eff_phforce(:,:,ip) = -sixth*(rk_coeff(:,:,1) + two*rk_coeff(:,:,2) + &
    4211            0 :      two*rk_coeff(:,:,3) + rk_coeff(:,:,4))
    4212              : 
    4213              :    ! Restore the gradient value
    4214            0 :    self%my_phgrad(:,:,ip) = rk_coeff(:,:,1)
    4215              : 
    4216              :  case default
    4217          135 :    ABI_ERROR(sjoin("polstate_calc_eff_phforce, unsupported mode: ", mode))
    4218              :  end select
    4219              : 
    4220          135 : end subroutine polstate_calc_eff_phforce
    4221              : !!***
    4222              : 
    4223              : !----------------------------------------------------------------------
    4224              : 
    4225              : !!****f* m_varpeq/polstate_calc_hop_timestep
    4226              : !! NAME
    4227              : !!  polstate_calc_hop_timestep
    4228              : !!
    4229              : !! FUNCTION
    4230              : !!  Calculate the optimal timestep for hopping optimization at this state.
    4231              : !!
    4232              : !! INPUTS
    4233              : !!  ip=Index of a polaronic state.
    4234              : !!
    4235              : !! OUTPUT
    4236              : !!
    4237              : !! SOURCE
    4238              : 
    4239            7 : subroutine polstate_calc_hop_timestep(self, ip)
    4240              : 
    4241              : !Arguments ------------------------------------
    4242              :  class(polstate_t), intent(inout) :: self
    4243              :  integer, intent(in) :: ip
    4244              : 
    4245              : !Local variables-------------------------------
    4246              : !scalars
    4247              :  class(gqk_t), pointer :: gqk
    4248              :  logical :: q_gamma
    4249              :  integer :: ierr
    4250              :  integer :: my_iq, my_pert
    4251              :  integer :: my_ik, ik_forw, ib, jb
    4252              :  real(dp) :: wqnu
    4253              :  real(dp) :: ts_denom, ts_num_ph, ts_num_elph
    4254              :  complex(dp) :: a_from, a_forw
    4255              :  complex(dp) :: g_forw, g0,  phforce, b
    4256              : !arrays
    4257              :  real(dp) :: kpt(3), qpt(3), kpq(3)
    4258           14 :  complex(dp) :: ak(self%gqk%nb_k), akq(self%gqk%nb_kq)
    4259           14 :  complex(dp) :: phforce_q(self%gqk%my_npert)
    4260              : 
    4261              : !----------------------------------------------------------------------
    4262              : 
    4263            7 :  gqk => self%gqk
    4264              : 
    4265            7 :  ts_denom = zero
    4266            7 :  ts_num_ph = zero ! Phonon-dependent component of the numerator
    4267              : 
    4268              :  ! Phonon-dependent components
    4269          882 :  do my_iq=1,gqk%my_nq
    4270         6132 :    do my_pert=1,gqk%my_npert
    4271         5250 :      wqnu = gqk%my_wnuq(my_pert, my_iq)
    4272         5250 :      phforce = self%my_eff_phforce(my_pert, my_iq, ip)
    4273         5250 :      b = self%my_b(my_pert, my_iq, ip)
    4274              : 
    4275         5250 :      ts_denom = ts_denom + wqnu*abs(phforce)**2
    4276         6125 :      ts_num_ph = ts_num_ph + wqnu*real(b*phforce, dp)
    4277              :    enddo
    4278              :  enddo
    4279            7 :  call xmpi_sum(ts_denom, gqk%qpt_pert_comm%value, ierr)
    4280            7 :  call xmpi_sum(ts_num_ph, gqk%qpt_pert_comm%value, ierr)
    4281              : 
    4282            7 :  ts_num_elph = zero
    4283              :  ! Scattering-dependent component of the numerator
    4284          882 :  do my_iq=1,gqk%my_nq
    4285         3500 :    qpt(:) = self%my_qpts(:, my_iq)
    4286         6125 :    phforce_q(:) = self%my_eff_phforce(:, my_iq, ip)
    4287              : 
    4288              :    ! Check if q=\Gamma
    4289         1092 :    q_gamma = .false.
    4290         1092 :    if (all(abs(qpt) < tol6)) q_gamma = .true.
    4291              : 
    4292       110257 :    do my_ik=1,gqk%my_nk
    4293       437500 :      kpt(:) = self%my_kpts(:, my_ik)
    4294              : 
    4295              :      ! Find k+q-->k' index in krank_kpts
    4296       437500 :      kpq(:) = kpt(:) + qpt(:)
    4297       109375 :      ik_forw = self%krank_kpts%get_index(kpq)
    4298              :      ! If erange filter was used in gstore, some transitions are not valid
    4299       109375 :      if (ik_forw == -1) cycle
    4300              : 
    4301       437500 :      ak(:) = self%my_a(:, my_ik, ip)
    4302       437500 :      akq(:) = self%a_glob(:, ik_forw, ip)
    4303              : 
    4304       438375 :      do ib=1,gqk%nb_k
    4305       328125 :        a_from = ak(ib)
    4306              : 
    4307      1421875 :        do jb=1,gqk%nb_kq
    4308       984375 :          a_forw = akq(jb)
    4309              : 
    4310      7218750 :          do my_pert=1,gqk%my_npert
    4311      5906250 :            phforce = phforce_q(my_pert)
    4312      5906250 :            g_forw = gqk%my_g(my_pert, jb, my_iq, ib, my_ik)
    4313              : 
    4314              :            ! Add long-range correction to matrix elements at Gamma
    4315      5906250 :            g0 = self%my_g0(my_pert)
    4316      5906250 :            if (q_gamma .and. (ib == jb)) then
    4317        15750 :              g_forw = g_forw + g0
    4318              :            endif
    4319              : 
    4320              :            ts_num_elph = &
    4321      6890625 :              ts_num_elph + real(a_from*g_forw*conjg(phforce)*conjg(a_forw), dp)
    4322              : 
    4323              :          enddo
    4324              :        enddo
    4325              :      enddo
    4326              :    enddo
    4327              :  enddo
    4328            7 :  call xmpi_sum(ts_num_elph, gqk%comm%value, ierr)
    4329            7 :  ts_num_elph = ts_num_elph / self%nkbz
    4330              : 
    4331            7 :  self%hop_ts(ip) = (ts_num_elph - ts_num_ph) / ts_denom
    4332              : 
    4333            7 : end subroutine polstate_calc_hop_timestep
    4334              : !!***
    4335              : 
    4336              : !----------------------------------------------------------------------
    4337              : 
    4338              : !!****f* m_varpeq/polstate_seed_a
    4339              : !! NAME
    4340              : !!  polstate_seed_a
    4341              : !!
    4342              : !! FUNCTION
    4343              : !!  Specify initial vector of electronic coefficients A_nk at runtime.
    4344              : !!
    4345              : !! INPUTS
    4346              : !!  mode=Select the initialization type. Possible options:
    4347              : !!    "gau_energy" ---> Gaussian shape based on the energy of electronic states;
    4348              : !!    "gau_length" ---> Gaussian shape based on the polaron localization length;
    4349              : !!    "even" ---> equal contribution from each electronic state;
    4350              : !!    "random" ---> random initalization.
    4351              : !!  ip=Index of a polaronic state.
    4352              : !!   atloc [optional]=Index of an atom where charge is localized.
    4353              : !!   chrgat(natom) [optional]=Charge of the atoms.
    4354              : !!   scell<supercell_type> [optional]=Supercell data structure.
    4355              : !!   cryst<crystal_t> [optional]=Crystal data structure.
    4356              : !!   nstep_loc [optional]=Number of iterations for charge localization.
    4357              : !!
    4358              : !! OUTPUT
    4359              : !!
    4360              : !! SOURCE
    4361              : 
    4362           19 : subroutine polstate_seed_a(self, mode, ip, atloc, chrgat, scell, cryst, nstep_loc)
    4363              : 
    4364              : !Arguments ------------------------------------
    4365              :  class(polstate_t), intent(inout) :: self
    4366              :  character(len=*), intent(in) :: mode
    4367              :  integer, intent(in) :: ip
    4368              :  integer, optional, intent(in) :: atloc
    4369              :  class(supercell_type), optional, intent(in) :: scell
    4370              :  class(crystal_t), optional, intent(in) :: cryst
    4371              :  real(dp), optional, intent(in) :: chrgat(:)
    4372              :  integer, optional, intent(in) :: nstep_loc
    4373              : 
    4374              : !Local variables-------------------------------
    4375              :  class(gqk_t), pointer :: gqk
    4376              :  logical :: flag
    4377              :  integer :: ii, ierr
    4378              :  real(dp) :: a_sqnorm, grad_sqnorm
    4379              : !----------------------------------------------------------------------
    4380              : 
    4381           19 :  gqk => self%gqk
    4382              : 
    4383           38 :  select case(mode)
    4384              :  case ("gau_energy")
    4385           19 :    call gau_energy_()
    4386              :  case ("gau_length")
    4387            0 :    call gau_length_()
    4388              :  case ("random")
    4389            0 :    call random_()
    4390              :  case ("localize")
    4391              :     flag = (present(atloc) .and. present(chrgat) .and. present(scell) &
    4392            0 :       .and. present(cryst) .and. present(nstep_loc))
    4393            0 :     ABI_CHECK(flag, "polstate_seed_a: atloc, chrgat and scell are needed to localize")
    4394              : 
    4395              :     ! enforce Coulomb displacements
    4396            0 :     if (ip == 1) call self%calc_clb_displ(atloc, chrgat, scell, cryst)
    4397              : 
    4398              :     ! calcualte associated deformation field
    4399            0 :     call self%calc_b_from_displ(ip, scell, cryst)
    4400              : 
    4401              :     ! start with random charge distribution
    4402            0 :     self%my_a(:,:,ip) = one + j_dpc*one
    4403              : 
    4404            0 :     if (self%efilter > zero) call self%filter("a", ip)
    4405              : 
    4406              :     ! then we do miniminzation with fixed displacements to localize charge distribution
    4407            0 :     a_sqnorm = self%get_sqnorm("a", ip)
    4408            0 :     if (a_sqnorm > tol12) then
    4409            0 :       self%my_a(:,:,ip) = sqrt(self%nkbz/a_sqnorm) * self%my_a(:,:,ip)
    4410              :     endif
    4411              : 
    4412            0 :     do ii=1,nstep_loc
    4413            0 :       call self%localize(ip, alpha=zero, fix_displ=.true.)
    4414            0 :       call self%calc_grad(ip)
    4415            0 :       grad_sqnorm = self%get_sqnorm("grad", ip)
    4416            0 :       if (sqrt(grad_sqnorm) < tol6) then
    4417              :         exit
    4418              :       endif
    4419            0 :       call self%update_pc(ip)
    4420            0 :       call self%calc_pcjgrad(ip,ii,nstep_ort=0)
    4421            0 :       call self%update_a(ip)
    4422              :     enddo
    4423              : 
    4424              :  case ("even")
    4425            0 :    self%my_a(:,:,ip) = one + j_dpc*one
    4426              :  case default
    4427           19 :    ABI_ERROR(sjoin("polstate_seed_a, unsupported mode: ", mode))
    4428              :  end select
    4429              : 
    4430              : !----------------------------------------------------------------------
    4431              : 
    4432              :  contains
    4433           19 :  subroutine gau_energy_()
    4434              :   real(dp) :: mu, sigma
    4435              :   integer :: my_ik, ik_ibz, ib
    4436              :   real(dp) :: eig
    4437           19 :   mu = self%gpr_energy(1); sigma = self%gpr_energy(2)
    4438           19 :   ABI_CHECK(sigma /= 0, "gpr_energy: standard deviation must be non-zero")
    4439         1746 :   do my_ik=1,gqk%my_nk
    4440         1727 :     ik_ibz = gqk%my_k2ibz(1, my_ik)
    4441         6749 :     do ib=1,gqk%nb_k
    4442         5003 :       eig = self%eig(ib, ik_ibz)
    4443         6730 :       self%my_a(ib, my_ik, ip) = exp(-half*(eig - mu)**2/sigma**2)
    4444              :     enddo
    4445              :   enddo
    4446           19 :  end subroutine gau_energy_
    4447              : 
    4448            0 :  subroutine gau_length_()
    4449              :   integer :: my_ik, ib
    4450              :   real(dp) :: kpt(3)
    4451            0 :   do my_ik=1,gqk%my_nk
    4452            0 :     kpt(:) = self%my_kpts(:, my_ik)
    4453            0 :     do ib=1,gqk%nb_k
    4454            0 :       self%my_a(ib, my_ik, ip) = exp(-sum((kpt(:)*self%gpr_length(:))**2))
    4455              :     enddo
    4456              :   enddo
    4457            0 :  end subroutine gau_length_
    4458              : 
    4459            0 :  subroutine random_()
    4460            0 :    real(dp), allocatable :: re_rand(:,:), im_rand(:,:)
    4461            0 :    ABI_MALLOC(re_rand, (gqk%nb_k, gqk%my_nk))
    4462            0 :    ABI_MALLOC(im_rand, (gqk%nb_k, gqk%my_nk))
    4463            0 :    call random_number(re_rand)
    4464            0 :    call random_number(im_rand)
    4465            0 :    self%my_a(:,:,ip) = re_rand(:,:) + j_dpc*im_rand(:,:)
    4466            0 :    call xmpi_sum(self%my_a(:,:,ip), gqk%qpt_pert_comm%value, ierr)
    4467            0 :    ABI_FREE(re_rand)
    4468            0 :    ABI_FREE(im_rand)
    4469            0 :  end subroutine random_
    4470              : 
    4471              : end subroutine polstate_seed_a
    4472              : !!***
    4473              : 
    4474              : !----------------------------------------------------------------------
    4475              : 
    4476              : !!****f* m_varpeq/polstate_get_sqnorm
    4477              : !! NAME
    4478              : !!  polstate_get_sqnorm
    4479              : !!
    4480              : !! FUNCTION
    4481              : !!  Helper function that calculates squared L^2-norm of an MPI-distributed
    4482              : !!  array at current state.
    4483              : !!
    4484              : !! INPUTS
    4485              : !!  mode=Select which array to gather. Possible options:
    4486              : !!    "a" ---> A_nk coefficients for this state;
    4487              : !!    "b" ---> B_q\nu coefficients for this state;
    4488              : !!    "grad" ---> current gradient;
    4489              : !!    "pcjgrad" ---> current preconditioned conjugate gradient direction.
    4490              : !!  ip=Index of a polaronic state.
    4491              : !!
    4492              : !! OUTPUT
    4493              : !!   Squared L^2-norm of the specified array.
    4494              : !!
    4495              : !! SOURCE
    4496              : 
    4497         4580 : real(dp) function polstate_get_sqnorm(self, mode, ip) result(sqnorm)
    4498              : 
    4499              : !Arguments ------------------------------------
    4500              :  class(polstate_t), target, intent(inout) :: self
    4501              :  character(len=*), intent(in) :: mode
    4502              :  integer, intent(in) :: ip
    4503              : 
    4504              : !Local variables-------------------------------
    4505              :  class(gqk_t), pointer :: gqk
    4506              : !----------------------------------------------------------------------
    4507              : 
    4508         4580 :  gqk => self%gqk
    4509         4599 :  select case(mode)
    4510              :  case ("a")
    4511           19 :    sqnorm = get_sqnorm_(self%my_a(:,:,ip), gqk%kpt_comm%value)
    4512              :  case ("b")
    4513            0 :    sqnorm = get_sqnorm_(self%my_b(:,:,ip), gqk%qpt_pert_comm%value)
    4514              :  case ("grad")
    4515         2285 :    sqnorm = get_sqnorm_(self%my_grad, gqk%kpt_comm%value)
    4516              :  case ("pcjgrad")
    4517         2141 :    sqnorm = get_sqnorm_(self%my_pcjgrad, gqk%kpt_comm%value)
    4518              :  case ("phgrad")
    4519          135 :    sqnorm = get_sqnorm_(self%my_phgrad(:,:,ip), gqk%qpt_pert_comm%value)
    4520              :  case ("eff_phforce")
    4521            0 :    sqnorm = get_sqnorm_(self%my_eff_phforce(:,:,ip), gqk%qpt_pert_comm%value)
    4522              :  case default
    4523         4580 :    ABI_ERROR(sjoin("polstate_get_sqnorm, unsupported mode: ", mode))
    4524              :  end select
    4525              : 
    4526              : !----------------------------------------------------------------------
    4527              : 
    4528              :  contains
    4529         4580 :  real(dp) function get_sqnorm_(my_arr, comm) result(sqnorm)
    4530              :   integer, intent(in) :: comm
    4531              :   complex(dp), intent(in) :: my_arr(:, :)
    4532              :   integer :: ierr
    4533      2154257 :   sqnorm = sum(abs(my_arr(:,:))**2)
    4534         4580 :   call xmpi_sum(sqnorm, comm, ierr)
    4535         4580 :  end function get_sqnorm_
    4536              : 
    4537              : end function polstate_get_sqnorm
    4538              : !!***
    4539              : 
    4540              : !----------------------------------------------------------------------
    4541              : 
    4542              : !!****f* m_varpeq/polstate_gather
    4543              : !! NAME
    4544              : !!  polstate_gather
    4545              : !!
    4546              : !! FUNCTION
    4547              : !!  Helper function that gathers a MPI-distributed array from the datatype
    4548              : !!  into a global one.
    4549              : !!
    4550              : !! INPUTS
    4551              : !!  mode=Select which array to gather. Possible options:
    4552              : !!    "a" ---> my_a(:,:,ip) -- array of A_nk coefficients for this state;
    4553              : !!    "pcjgrad" ---> my_pcjgrad(:,:) -- gradient.
    4554              : !!  ip=Index of a polaronic state.
    4555              : !!
    4556              : !! OUTPUT
    4557              : !!
    4558              : !! SOURCE
    4559              : 
    4560         4426 : subroutine polstate_gather(self, mode, ip)
    4561              : 
    4562              : !Arguments ------------------------------------
    4563              :  class(polstate_t), target, intent(inout) :: self
    4564              :  character(len=*),intent(in) :: mode
    4565              :  integer, intent(in) :: ip
    4566              : 
    4567              : !Local variables-------------------------------
    4568              :  class(gqk_t), pointer :: gqk
    4569              : !----------------------------------------------------------------------
    4570              : 
    4571         4426 :  gqk => self%gqk
    4572         6711 :  select case(mode)
    4573              :  case ("a")
    4574              :    call gather_(self%my_a(:,:,ip), gqk%my_nk, gqk%my_kstart, self%a_glob(:,:,ip), &
    4575         2285 :      gqk%kpt_comm%value)
    4576              :  case ("pcjgrad")
    4577              :    call gather_(self%my_pcjgrad, gqk%my_nk, gqk%my_kstart, self%pcjgrad_glob, &
    4578         2141 :      gqk%kpt_comm%value)
    4579              :  case default
    4580         4426 :    ABI_ERROR(sjoin("polstate_gather, unsupported mode: ", mode))
    4581              :  end select
    4582              : 
    4583              : !----------------------------------------------------------------------
    4584              : 
    4585              :  contains
    4586         4426 :  subroutine gather_(my_arr, my_nk, my_kstart, glob_arr, comm)
    4587              : 
    4588              :   integer, intent(in) :: comm, my_nk, my_kstart
    4589              :   complex(dp), intent(in) :: my_arr(:, :)
    4590              :   complex(dp), intent(out) :: glob_arr(:, :)
    4591              : 
    4592              :   integer :: ierr, my_ik, ik_glob
    4593              :  !----------------------------------------------------------------------
    4594              : 
    4595      2029248 :   glob_arr(:, :) = zero
    4596       513168 :   do my_ik=1,my_nk
    4597       508742 :     ik_glob = my_ik + my_kstart - 1
    4598      2029248 :     glob_arr(:, ik_glob) = my_arr(:, my_ik)
    4599              :   enddo
    4600         4426 :   call xmpi_sum(glob_arr, comm, ierr)
    4601              : 
    4602         4426 :  end subroutine gather_
    4603              : 
    4604              : end subroutine polstate_gather
    4605              : !!***
    4606              : 
    4607              : !----------------------------------------------------------------------
    4608              : 
    4609              : !!****f* m_varpeq/polstate_filter
    4610              : !! NAME
    4611              : !!  polstate_filter
    4612              : !!
    4613              : !! FUNCTION
    4614              : !!  Helper function that filters a MPI-distributed array from the datatype
    4615              : !!
    4616              : !! INPUTS
    4617              : !!  mode=Select which array to filter. Possible options:
    4618              : !!    "a" ---> my_a(:,:,ip) -- array of A_nk coefficients for this state;
    4619              : !!    "pcjgrad" ---> my_pcjgrad(:,:) -- gradient.
    4620              : !!  ip=Index of a polaronic state.
    4621              : !!
    4622              : !! OUTPUT
    4623              : !!
    4624              : !! SOURCE
    4625              : 
    4626            0 : subroutine polstate_filter(self, mode, ip)
    4627              : 
    4628              : !Arguments ------------------------------------
    4629              :  class(polstate_t), target, intent(inout) :: self
    4630              :  character(len=*),intent(in) :: mode
    4631              :  integer, intent(in) :: ip
    4632              : 
    4633              : !Local variables-------------------------------
    4634              :  class(gqk_t), pointer :: gqk
    4635              : !----------------------------------------------------------------------
    4636              : 
    4637            0 :  gqk => self%gqk
    4638            0 :  select case(mode)
    4639              :  case ("a")
    4640            0 :    call filter_(self%my_a(:,:,ip))
    4641              :  case ("grad")
    4642            0 :    call filter_(self%my_grad(:,:))
    4643              :  case ("pcjgrad")
    4644            0 :    call filter_(self%my_pcjgrad(:,:))
    4645              :  case default
    4646            0 :    ABI_ERROR(sjoin("polstate_filter, unsupported mode: ", mode))
    4647              :  end select
    4648              : 
    4649              : !----------------------------------------------------------------------
    4650              : 
    4651              :  contains
    4652            0 :  subroutine filter_(my_arr)
    4653              : 
    4654              :   complex(dp), intent(inout) :: my_arr(:, :)
    4655              : 
    4656              :   integer :: my_ik, ik_ibz, ib
    4657              :  !----------------------------------------------------------------------
    4658              : 
    4659            0 :   do my_ik=1,gqk%my_nk
    4660            0 :     ik_ibz = gqk%my_k2ibz(1, my_ik)
    4661            0 :     do ib=1,gqk%nb_k
    4662            0 :       if (self%eig(ib, ik_ibz) > self%efilter .or. self%eig(ib, ik_ibz) < -tol6) then
    4663            0 :         my_arr(ib, my_ik) = zero
    4664              :       endif
    4665              :     enddo
    4666              :   enddo
    4667              : 
    4668            0 :  end subroutine filter_
    4669              : 
    4670              : end subroutine polstate_filter
    4671              : !!***
    4672              : 
    4673              : !----------------------------------------------------------------------
    4674              : 
    4675              : !!****f* m_varpeq/polstate_get_krank_glob
    4676              : !! NAME
    4677              : !!  polstate_get_krank_glob
    4678              : !!
    4679              : !! FUNCTION
    4680              : !!  Helper function that computes krank objects for the full BZ q/k-meshes.
    4681              : !!
    4682              : !! INPUTS
    4683              : !!  mode=Select reciprocal space for which krank is computed. Possible options:
    4684              : !!    "k" ---> k-space;
    4685              : !!    "q" ---> q-space.
    4686              : !!  kptrlatt(3,3)=Lattice specifiyng the grid.
    4687              : !!
    4688              : !! OUTPUT
    4689              : !!  krank<krank_t>=Object proiding mapping between reciprocal space points and
    4690              : !!    their indices.
    4691              : !!
    4692              : !! SOURCE
    4693              : 
    4694           18 : type(krank_t) function polstate_get_krank_glob(self, mode, kptrlatt) result(krank_kpts)
    4695              : 
    4696              : !Arguments ------------------------------------
    4697              : !scalars
    4698              :  class(polstate_t), target, intent(in) :: self
    4699              :  character(len=*), intent(in) :: mode
    4700              : !arrays
    4701              :  integer, intent(in) :: kptrlatt(3, 3)
    4702              : 
    4703              : !Local variables-------------------------------
    4704              : !scalars
    4705              :  class(gqk_t), pointer :: gqk
    4706              : !----------------------------------------------------------------------
    4707              : 
    4708           18 :  gqk => self%gqk
    4709              : 
    4710           45 :  select case(mode)
    4711              :  case ("k")
    4712              :    krank_kpts = get_krank_glob_(self%my_kpts, gqk%my_nk, gqk%my_kstart, &
    4713            9 :      gqk%glob_nk, gqk%kpt_comm%value)
    4714              :  case ("q")
    4715              :    krank_kpts = get_krank_glob_(self%my_qpts, gqk%my_nq, gqk%my_qstart, &
    4716            9 :      gqk%glob_nq, gqk%qpt_comm%value)
    4717              :  case default
    4718           18 :    ABI_ERROR(sjoin("polstate_get_krank_glob, unsupported mode: ", mode))
    4719              :  end select
    4720              : 
    4721              : !----------------------------------------------------------------------
    4722              : 
    4723              :  contains
    4724           18 :  type(krank_t) function get_krank_glob_(my_kpts, my_nk, my_kstart, glob_nk, &
    4725              :      comm) result(krank_kpts)
    4726              : 
    4727              :   integer, intent(in) :: comm, my_nk, my_kstart, glob_nk
    4728              :   real(dp), intent(in) :: my_kpts(3, my_nk)
    4729              : 
    4730           18 :   type(krank_t) :: krank_tmp
    4731              :   integer :: ierr, my_ik, ik_glob
    4732           36 :   real(dp) :: kpts(3, glob_nk)
    4733              : 
    4734              :  !----------------------------------------------------------------------
    4735              : 
    4736         7434 :   kpts(:, :) = zero
    4737         1872 :   do my_ik=1,my_nk
    4738         1854 :     ik_glob = my_ik + my_kstart - 1
    4739         7434 :     kpts(:, ik_glob) = my_kpts(:, my_ik)
    4740              :   enddo
    4741           18 :   call xmpi_sum(kpts, comm, ierr)
    4742              : 
    4743           18 :   call krank_tmp%from_kptrlatt(glob_nk, kpts, kptrlatt, compute_invrank=.true.)
    4744           18 :   krank_kpts = krank_tmp%copy()
    4745           18 :   call krank_tmp%free()
    4746              : 
    4747           36 :  end function get_krank_glob_
    4748              : 
    4749              : end function polstate_get_krank_glob
    4750              : !!***
    4751              : 
    4752              : !!****f* m_varpeq/varpeq_plot
    4753              : !! NAME
    4754              : !!  varpeq_plot
    4755              : !!
    4756              : !! FUNCTION
    4757              : !! Compute polaron wavefunctions and atomic displacements in the supercell and write results to XSF files
    4758              : !!
    4759              : !! INPUTS
    4760              : !! wfk0_path=String with the path to the GS unperturbed WFK file.
    4761              : !! ngfft(18),ngfftf(18)=Coarse and Fine FFT meshes.
    4762              : !! dtset<dataset_type>=All input variables for this dataset.
    4763              : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
    4764              : !! comm=MPI communicator.
    4765              : !!
    4766              : !! OUTPUT
    4767              : !!
    4768              : !! SOURCE
    4769              : 
    4770            2 : subroutine varpeq_plot(wfk0_path, ngfft, dtset, dtfil, cryst, ebands, pawtab, psps, comm)
    4771              : 
    4772              : !Arguments ------------------------------------
    4773              :  character(len=*),intent(in) :: wfk0_path
    4774              :  integer,intent(in) :: ngfft(18) !,ngfftf(18)
    4775              :  type(dataset_type), intent(in) :: dtset
    4776              :  type(datafiles_type), intent(in) :: dtfil
    4777              :  type(crystal_t),intent(in) :: cryst
    4778              :  type(ebands_t),intent(in) :: ebands
    4779              :  type(pseudopotential_type),intent(in) :: psps
    4780              :  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
    4781              :  integer,intent(in) :: comm
    4782              : 
    4783              : !Local variables-------------------------------
    4784              : !scalars
    4785              :  integer,parameter :: master = 0, ndat1 = 1
    4786              :  integer :: my_rank, ib, irsp, ir, uc_idx, mpw, band, bstart, ir1, ir2, ir3, wp1, wp2, wp3, ds_nfft, idir
    4787              :  integer :: natom, natom3, nsppol, nspinor, nspden, nkibz, mband, spin, ik, sc_nfft, cnt, nproc, num_writes, ii, uc_nfft
    4788              :  integer :: ik_ibz, isym_k, trev_k, npw_k, istwf_k, npw_kq_ibz, istwf_k_ibz, nkpg_k, ierr, nk, spinor, spad, nkbz, ncid
    4789              :  integer :: nqibz, iq, iq_ibz, isym_q, trev_q, qptopt, uc_iat, sc_iat, nu, nqbz, ip, ds_iscale
    4790              :  logical :: isirr_k, isirr_q, have_scell_q, use_displaced_scell
    4791              :  real(dp) :: cpu_all, wall_all, gflops_all, spread, kdotr
    4792              :  real(dp) :: psign
    4793              :  character(len=500) :: msg
    4794              :  character(len=fnlen) :: path
    4795          104 :  type(varpeq_t) :: vpq
    4796            2 :  type(wfd_t) :: wfd
    4797            2 :  type(supercell_type), target :: scell_q, scell_k
    4798            2 :  type(krank_t) :: krank_ibz, qrank_ibz
    4799              :  complex(dp) :: a_nk, bstar_qnu, cphase, cphase_tr, c3tmp(3)
    4800              :  complex(gwp) :: c123, c23, c3
    4801              : !arrays
    4802              :  integer :: sc_ngfft(18), ds_ngfft(18), mapl_k(6), kptrlatt_(3,3), qptrlatt_(3,3)
    4803              :  integer :: units(2), work_ngfft(18), gmax(3), g0_k(3), mapl_qq(6), g0_q(3), ngqpt(3)
    4804            4 :  integer,allocatable :: nband(:,:), wfd_istwfk(:), kg_k(:,:), gbound_k(:,:)
    4805              :  real(dp),parameter :: origin0(3) = zero
    4806              :  real(dp) :: kk(3), kk_ibz(3), kk_sc(3), qq(3), qq_ibz(3), center_cart(3)
    4807            4 :  real(dp),allocatable :: kpg_k(:,:), ug_k(:,:), work(:,:,:,:), pol_rhor(:), qibz(:,:)
    4808            2 :  real(dp),allocatable :: pheigvec_qibz(:,:,:,:)
    4809            2 :  real(dp),allocatable :: displ_cart_qbz(:,:,:,:), pheigvec_qbz(:,:,:,:)  !displ_red_qbz(:,:,:,:), displ_cart_qibz(:,:,:,:),
    4810            2 :  real(dp),allocatable :: phfreqs_ibz(:,:), pheigvec_cart_ibz(:,:,:,:,:) !, pheigvec_cart_qbz(:,:,:,:)
    4811            2 :  real(dp),allocatable :: sc_displ_cart_re(:,:,:,:), sc_displ_cart_im(:,:,:,:)
    4812            2 :  real(dp), contiguous, pointer :: xcart_ptr(:,:)
    4813            2 :  logical,allocatable :: bks_mask(:,:,:),keep_ur(:,:,:)
    4814            2 :  complex(gwp),allocatable :: ur_k(:,:), ds_ur_k(:,:), pol_wfr(:,:,:), sc_ceikr_1d(:,:)
    4815              : !----------------------------------------------------------------------
    4816              : 
    4817            6 :  units = [std_out, ab_out]
    4818            2 :  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
    4819              : 
    4820              :  ! Read A_nk and B_qnu and other useful tables from file
    4821            2 :  call vpq%ncread(dtfil%filvpqin, comm, keep_open=.false.)
    4822              :  !call wrtout(std_out, " Reading done")
    4823              : 
    4824            2 :  psign = -1
    4825            2 :  if (vpq%pkind == "hole") psign = 1
    4826              : 
    4827              :  ! Copy important dimensions
    4828            2 :  natom = cryst%natom; natom3 = 3 * natom; nsppol = ebands%nsppol; nspinor = ebands%nspinor; nspden = dtset%nspden
    4829            2 :  nkibz = ebands%nkpt; mband = ebands%mband
    4830              : 
    4831            2 :  if (dtfil%filgstorein == ABI_NOFILE) then
    4832            0 :    call wrtout(units, "gstore_filepath is not specified in input. Cannot compute polaron-induced displacements!")
    4833            0 :    have_scell_q = .false.
    4834              : 
    4835              :  else
    4836              :    ! Start by reading ph displacements and frequencies in the IBZ from the gstore file.
    4837              :    ! First compute displaced supercell then polaron wf so that we can use both when writing the XSF file.
    4838            2 :    call wrtout(units, sjoin(" Computing polaron-induced displacements. Reading phonons from: ", dtfil%filgstorein))
    4839            2 :    call cwtime(cpu_all, wall_all, gflops_all, "start")
    4840            2 :    have_scell_q = .true.
    4841              : 
    4842            2 :    NCF_CHECK(nctk_open_read(ncid, dtfil%filgstorein, comm))
    4843            2 :    NCF_CHECK(nctk_get_dim(ncid, "gstore_nqibz", nqibz))
    4844              :    !NCF_CHECK(nctk_get_dim(ncid, "gstore_nqbz", nqbz))
    4845              : 
    4846              :    ! TODO: Wrap phstore API?
    4847              :    ! Encapsulate this part as we're gonna re-use it to deal with hopping
    4848              :    !call gstore_read_ph_qibz(dtfil%filgstorein, ph, comm)
    4849              :    !call ph%free()
    4850              : 
    4851            6 :    ABI_MALLOC(qibz, (3, nqibz))
    4852            8 :    ABI_MALLOC(phfreqs_ibz, (natom3, nqibz))
    4853           12 :    ABI_MALLOC(pheigvec_cart_ibz, (2, 3, cryst%natom, cryst%natom * 3, nqibz))
    4854            2 :    if (nproc > 1) then
    4855            0 :      NCF_CHECK(nctk_set_collective(ncid, vid("gstore_qibz")))
    4856            0 :      NCF_CHECK(nctk_set_collective(ncid, vid("phfreqs_ibz")))
    4857            0 :      NCF_CHECK(nctk_set_collective(ncid, vid("pheigvec_cart_ibz")))
    4858              :    end if
    4859            2 :    NCF_CHECK(nf90_get_var(ncid, vid("gstore_qibz"), qibz))
    4860            2 :    NCF_CHECK(nf90_get_var(ncid, vid("phfreqs_ibz"), phfreqs_ibz))
    4861            2 :    NCF_CHECK(nf90_get_var(ncid, vid("pheigvec_cart_ibz"), pheigvec_cart_ibz))
    4862            2 :    NCF_CHECK(nf90_get_var(ncid, vid("gstore_ngqpt"), ngqpt))
    4863            2 :    NCF_CHECK(nf90_get_var(ncid, vid("gstore_qptopt"), qptopt))
    4864            2 :    NCF_CHECK(nf90_close(ncid))
    4865              : 
    4866            8 :    ABI_MALLOC(pheigvec_qibz, (2, 3, cryst%natom, natom3))
    4867            8 :    ABI_MALLOC(displ_cart_qbz, (2, 3, cryst%natom, cryst%natom * 3))
    4868            6 :    ABI_MALLOC(pheigvec_qbz, (2, 3, cryst%natom, 3*cryst%natom))
    4869              : 
    4870            8 :    nqbz = product(ngqpt)
    4871            2 :    call kptrlatt_from_ngkpt(ngqpt, qptrlatt_)
    4872            2 :    call qrank_ibz%from_kptrlatt(nqibz, qibz, qptrlatt_, compute_invrank=.false.)
    4873              : 
    4874            2 :    call scell_q%init(cryst%natom, qptrlatt_, cryst%rprimd, cryst%typat, cryst%xcart, cryst%znucl, xyz_order="xyz")
    4875              : 
    4876        18240 :    ABI_CALLOC(sc_displ_cart_re, (3, scell_q%natom, vpq%nstates, nsppol))
    4877        18238 :    ABI_CALLOC(sc_displ_cart_im, (3, scell_q%natom, vpq%nstates, nsppol))
    4878              : 
    4879            2 :    cnt = 0
    4880            4 :    do spin=1,nsppol
    4881          628 :      do iq=1,vpq%nq_spin(spin)
    4882          624 :        cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism inside comm.
    4883         2496 :        qq = vpq%qpts_spin(:, iq, spin)
    4884              :        ! Note symrec here
    4885          624 :        if (kpts_map("symrec", qptopt, cryst, qrank_ibz, 1, qq, mapl_qq) /= 0) then
    4886            0 :          ABI_ERROR("Cannot map qBZ to IBZ!")
    4887              :        end if
    4888          624 :        iq_ibz = mapl_qq(1); isym_q = mapl_qq(2)
    4889          624 :        trev_q = mapl_qq(6); g0_q = mapl_qq(3:5)
    4890              :        ! Don't test if umklapp == 0 because we use the periodic gauge:
    4891              :        !
    4892              :        !      phfreq(q+G) = phfreq(q) and eigvec(q) = eigvec(q+G)
    4893              :        !
    4894          624 :        isirr_q = (isym_q == 1 .and. trev_q == 0)
    4895         2496 :        qq_ibz = qibz(:, iq_ibz)
    4896              :        !if (all(abs(qq_ibz) < tol6)) cycle
    4897        79872 :        pheigvec_qibz = pheigvec_cart_ibz(:,:,:,:,iq_ibz)
    4898              : 
    4899          624 :        if (isirr_q) then
    4900              :          ! Compute phonon displacements in Cartesian coordinates
    4901           34 :          call phdispl_from_eigvec(cryst%natom, cryst%ntypat, cryst%typat, cryst%amu, pheigvec_qibz, displ_cart_qbz)
    4902              : 
    4903              :        else
    4904              :          ! Rotate phonon eigenvectors from q_ibz to q_bz.
    4905              :          ! This part is needed to enforce the gauge in the ph eigenvectors, including e(-q) = e(q)^*
    4906          590 :          call pheigvec_rotate(cryst, qq_ibz, isym_q, trev_q, pheigvec_qibz, pheigvec_qbz, displ_cart_qbz)
    4907              :        end if
    4908              : 
    4909              :        ! Phase due to the primitive translation (default: 0)
    4910         2496 :        cphase_tr = exp(-j_dpc * two_pi * dot_product(qq, dtset%vpq_trvec))
    4911              : 
    4912      2625302 :        do sc_iat=1, scell_q%natom
    4913      2624676 :          uc_iat = scell_q%atom_indexing(sc_iat)
    4914              :          ! Compute phase e^{iq.R}
    4915     10498704 :          cphase = exp(+j_dpc * two_pi * dot_product(qq, scell_q%uc_indexing(:, sc_iat)))
    4916      5252892 :          do ip=1,vpq%nstates
    4917              :            ! Summing over ph modes.
    4918     21017820 :            do nu=1,natom3
    4919              :              ! skip acoustic modes at Gamma
    4920     15765552 :              if (abs(phfreqs_ibz(nu, iq_ibz)) < tol12) cycle
    4921              : 
    4922     15751884 :              bstar_qnu = conjg(vpq%b_spin(nu, iq, ip, spin)) * cphase_tr / sqrt(phfreqs_ibz(nu, iq_ibz))
    4923     63007536 :              c3tmp = (displ_cart_qbz(1,:,uc_iat,nu) + j_dpc * displ_cart_qbz(2,:,uc_iat,nu)) * bstar_qnu * cphase
    4924     63007536 :              sc_displ_cart_re(:,sc_iat,ip,spin) = sc_displ_cart_re(:,sc_iat,ip,spin) + real(c3tmp)
    4925     65635128 :              sc_displ_cart_im(:,sc_iat,ip,spin) = sc_displ_cart_im(:,sc_iat,ip,spin) + aimag(c3tmp) ! This to check if the imag part is zero.
    4926              :            end do
    4927              :          end do ! ip
    4928              :        end do ! sc_iat
    4929              : 
    4930              :      end do ! iq
    4931              :    end do ! spin
    4932              : 
    4933            2 :    ABI_FREE(qibz)
    4934            2 :    ABI_FREE(phfreqs_ibz)
    4935            2 :    ABI_FREE(pheigvec_cart_ibz)
    4936            2 :    ABI_FREE(displ_cart_qbz)
    4937            2 :    ABI_FREE(pheigvec_qbz)
    4938            2 :    ABI_FREE(pheigvec_qibz)
    4939            2 :    call qrank_ibz%free()
    4940              : 
    4941            2 :    call xmpi_sum_master(sc_displ_cart_re, master, comm, ierr)
    4942            2 :    call xmpi_sum_master(sc_displ_cart_im, master, comm, ierr)
    4943        18232 :    sc_displ_cart_re = psign * sqrt2 * sc_displ_cart_re / nqbz
    4944        18232 :    sc_displ_cart_im = psign * sqrt2 * sc_displ_cart_im / nqbz
    4945              : 
    4946              :    ! Write polaron-induced displacements in XSF format.
    4947            2 :    if (my_rank == master) then
    4948              :      ! Handle spin-polarized case by writing two XSF files.
    4949            4 :      do spin=1,nsppol
    4950              :        ! Handle multiple polaronic states for each spin.
    4951            8 :        do ip=1,vpq%nstates
    4952              :          write(msg, "(2(a,i0),a,es16.6)") &
    4953        18228 :            " For spin: ", spin, ": pstate: ", ip, ": maxval(abs(sc_displ_cart_re)): ", maxval(abs(sc_displ_cart_re(:,:,ip,spin)))
    4954            4 :          call wrtout(units, msg)
    4955              :          write(msg, "(2(a,i0),a,es16.6)") &
    4956        18228 :            " For spin: ", spin, ": pstate: ", ip, ": maxval(abs(sc_displ_cart_im)): ", maxval(abs(sc_displ_cart_im(:,:,ip,spin)))
    4957            4 :          call wrtout(units, msg)
    4958              : 
    4959              :          ! Here we displace the atoms in the supercell for this spin (only master has the correct values)
    4960        18232 :          scell_q%xcart = scell_q%xcart_ref + sc_displ_cart_re(:,:,ip,spin)
    4961              : 
    4962            4 :          path = strcat(dtfil%filnam_ds(4), "_pstate_", itoa(ip), "_POLARON_DISPL_VECTORS.xsf")
    4963            4 :          if (nsppol == 2) path = strcat(dtfil%filnam_ds(4), strcat("_spin_", itoa(spin)), "_pstate_", itoa(ip), "_POLARON_DISPL_VECTORS.xsf")
    4964            4 :          call wrtout(units, sjoin(" Writing displacement vectors to:", path))
    4965            6 :          call scell_q%write_xsf(path)
    4966              :        end do
    4967              :      end do
    4968              :    end if
    4969              : 
    4970            2 :    ABI_FREE(sc_displ_cart_im)
    4971              :    call cwtime_report(" Computation of polaron-induced displacements completed:", cpu_all, wall_all, gflops_all, &
    4972            4 :                       pre_str=ch10, end_str=ch10)
    4973              :  end if
    4974              : 
    4975            2 :  call wrtout(std_out, " varpeq_plot: computing polaron wavefunction in real space.", pre_newlines=1)
    4976              : 
    4977            2 :  call krank_ibz%from_kptrlatt(ebands%nkpt, ebands%kptns, ebands%kptrlatt, compute_invrank=.false.)
    4978              : 
    4979              :  ! Initialize the wave function descriptor.
    4980            8 :  ABI_MALLOC(nband, (nkibz, nsppol))
    4981           10 :  ABI_MALLOC(bks_mask, (mband, nkibz, nsppol))
    4982            8 :  ABI_MALLOC(keep_ur, (mband, nkibz, nsppol))
    4983         1328 :  nband = mband; bks_mask = .false.; keep_ur = .false.
    4984              : 
    4985              :  ! Here we use brange_spin to select the number of bands that should be read and stored in memory.
    4986              :  ! For the time being, spin and k-points are not MPI-distributed inside comm.
    4987            4 :  do spin=1,nsppol
    4988            2 :    bstart = vpq%brange_spin(1, spin)
    4989          120 :    do ik=1, vpq%nk_spin(spin)
    4990          464 :      kk = vpq%kpts_spin(:, ik, spin)
    4991              :      ! Note symrel option
    4992          116 :      if (kpts_map("symrel", ebands%kptopt, cryst, krank_ibz, 1, kk, mapl_k) /= 0) then
    4993            0 :        write(msg, '(4a)' )"k-mesh is not closed!",ch10, "k-point could not be generated from a symmetrical one.",trim(ltoa(kk))
    4994            0 :        ABI_ERROR(msg)
    4995              :      end if
    4996          116 :      ik_ibz = mapl_k(1)
    4997          288 :      do ib=1,vpq%nb_spin(spin)
    4998          286 :        band = bstart + ib - 1; bks_mask(band, ik_ibz, spin) = .true.
    4999              :      end do
    5000              :    end do
    5001              :  end do
    5002              : 
    5003              :  ! Impose istwfk = 1 for all k-points. This is also done in respfn (see inkpts)
    5004              :  ! wfd_read_wfk will handle a possible conversion if WFK contains istwfk /= 1.
    5005            6 :  ABI_MALLOC(wfd_istwfk, (nkibz))
    5006           90 :  wfd_istwfk = 1
    5007              : 
    5008              :  call wfd%init(cryst, pawtab, psps, keep_ur, mband, nband, nkibz, nsppol, bks_mask,&
    5009              :                dtset%nspden, dtset%nspinor, dtset%ecut, dtset%ecutsm, dtset%dilatmx, wfd_istwfk, ebands%kptns, ngfft, &
    5010            2 :                dtset%nloalg, dtset%prtvol, dtset%pawprtvol, comm)
    5011              : 
    5012            4 :  call wfd%print([std_out], header="Wavefunctions for varpeq_plot")
    5013              : 
    5014            2 :  if (dtset%boxcutmin >= two) then
    5015            2 :    call wrtout(std_out, " To decrease the size of the FFT mesh and the size of the XSF file, reduce boxcutmin from 2 to e.g. 1.1")
    5016              :  end if
    5017              : 
    5018            2 :  ABI_FREE(nband)
    5019            2 :  ABI_FREE(keep_ur)
    5020            2 :  ABI_FREE(wfd_istwfk)
    5021            2 :  ABI_FREE(bks_mask)
    5022              : 
    5023              :  ! Read wavefunctions.
    5024            2 :  call wfd%read_wfk(wfk0_path, iomode_from_fname(wfk0_path))
    5025              : 
    5026            2 :  call cwtime(cpu_all, wall_all, gflops_all, "start")
    5027            2 :  call wrtout(std_out, " Computing mpw and gmax needed to allocate workspace array.")
    5028            4 :  do spin=1,nsppol
    5029            2 :    nk = vpq%nk_spin(spin)
    5030              :    call ephtk_get_mpw_gmax(nk, vpq%kpts_spin(:, 1:nk, spin), dtset%ecut, cryst%gmet, mpw, gmax, comm, &
    5031            4 :                            init_with_zero=spin==1)
    5032              :  end do
    5033              : 
    5034              :  ! Init work_ngfft
    5035            8 :  gmax = gmax + 4 ! FIXME: this is to account for umklapp, should also consider Gamma-only and istwfk
    5036            8 :  gmax = 2*gmax + 1
    5037            2 :  call ngfft_seq(work_ngfft, gmax)
    5038              :  !write(std_out,*)"work_ngfft(1:3): ",work_ngfft(1:3)
    5039           10 :  ABI_MALLOC(work, (2, work_ngfft(4), work_ngfft(5), work_ngfft(6)))
    5040              : 
    5041            2 :  call wrtout(std_out, sjoin(" Building supercell from ngkpt:", ltoa(vpq%ngkpt)))
    5042              :  ! note xyz_order="xyz"
    5043            2 :  call kptrlatt_from_ngkpt(vpq%ngkpt, kptrlatt_)
    5044            2 :  call scell_k%init(cryst%natom, kptrlatt_, cryst%rprimd, cryst%typat, cryst%xcart, cryst%znucl, xyz_order="xyz")
    5045              : 
    5046              :  ! There are three meshes.
    5047              :  ! ngfft: mesh in the unit cell used to compute u(r) via FFT
    5048              :  ! ds_ngfft: coarse mesh used to downsample u(r). Note ngfft(1:3)/ds_ngfft(1:3) = ds_iscale
    5049              :  ! sc_ngfft: mesh in the real space supercell computed as ds_ngfft * vqp%ngkpt
    5050              :  !           the polaron wavefunction is defined on this mesh.
    5051              : 
    5052            2 :  ds_iscale = dtset%vpq_mesh_fact
    5053            2 :  ds_ngfft = ngfft
    5054            8 :  ds_ngfft(1:3) = ngfft(1:3) / ds_iscale
    5055           14 :  ABI_CHECK(all(ds_ngfft(1:6) > 0), "ds_iscale too large and ds_ngfft == 0")
    5056            2 :  ds_ngfft(4:6) = ds_ngfft(4:6)     ! No augmentation
    5057            8 :  ds_nfft =  product(ds_ngfft(1:3)) ! Total number of points in the supercell
    5058              : 
    5059            8 :  sc_ngfft(1:3) = vpq%ngkpt(1:3) * ds_ngfft(1:3)
    5060            8 :  sc_ngfft(4:6) = sc_ngfft(1:3)    ! No augmentation
    5061            8 :  sc_nfft = product(sc_ngfft(1:3)) ! Total number of points in the supercell
    5062              : 
    5063            2 :  call wrtout(std_out, " Computing polaron wavefunction in the real-space supercell...")
    5064            2 :  call wrtout(std_out, sjoin(" Using vpq_mesh_fact:", itoa(ds_iscale)))
    5065              :  call wrtout(std_out, sjoin(" Memory required by pol_wfr:", &
    5066            2 :              ftoa(two*sc_nfft*nspinor*vpq%nstates*nsppol*storage_size(one)/eight*b2Mb), " (Mb) <<< MEM"))
    5067              : 
    5068            8 :  nkbz = product(vpq%ngkpt)
    5069            2 :  uc_nfft = wfd%nfft
    5070            6 :  ABI_MALLOC(kg_k, (3, mpw))
    5071            8 :  ABI_MALLOC(gbound_k, (2*wfd%mgfft+8, 2))
    5072            6 :  ABI_MALLOC(ur_k, (uc_nfft*nspinor, ndat1))
    5073            2 :  if (ds_iscale /= 1) then
    5074            6 :    ABI_MALLOC(ds_ur_k, (ds_nfft*nspinor, ndat1))
    5075              :  end if
    5076              : 
    5077       747943 :  ABI_CALLOC(pol_wfr, (sc_nfft*nspinor, vpq%nstates, nsppol)) ! Init output with zeros.
    5078           12 :  ABI_MALLOC(sc_ceikr_1d, (maxval(sc_ngfft(1:3)), 3))
    5079              : 
    5080            2 :  cnt = 0
    5081            4 :  do spin=1,nsppol
    5082            2 :    bstart = vpq%brange_spin(1, spin)
    5083            2 :    nk = vpq%nk_spin(spin)
    5084          120 :    do ik=1, nk
    5085          116 :      cnt = cnt + 1; if (mod(cnt, nproc) /= my_rank) cycle ! MPI parallelism inside comm.
    5086              : 
    5087          464 :      kk = vpq%kpts_spin(:, ik, spin)
    5088          116 :      if (kpts_map("symrel", ebands%kptopt, cryst, krank_ibz, 1, kk, mapl_k) /= 0) then
    5089            0 :        write(msg, '(4a)' )"k-mesh is not closed!",ch10, "k-point could not be generated from a symmetrical one.",trim(ltoa(kk))
    5090            0 :        ABI_ERROR(msg)
    5091              :      end if
    5092              : 
    5093          464 :      ik_ibz = mapl_k(1); isym_k = mapl_k(2); trev_k = mapl_k(6); g0_k = mapl_k(3:5)
    5094          452 :      isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
    5095          464 :      kk_ibz = ebands%kptns(:, ik_ibz)
    5096          116 :      istwf_k_ibz = wfd%istwfk(ik_ibz); npw_kq_ibz = wfd%npwarr(ik_ibz)
    5097              : 
    5098              :      ! Get npw_k, kg_k for this k-point.
    5099              :      call wfd%get_gvec_gbound(cryst%gmet, dtset%ecut, kk, ik_ibz, isirr_k, dtset%nloalg, &  ! in
    5100          116 :                               istwf_k, npw_k, kg_k, nkpg_k, kpg_k, gbound_k)                ! out
    5101              : 
    5102          348 :      ABI_MALLOC(ug_k, (2, npw_k*nspinor))
    5103          464 :      kk_sc = kk * vpq%ngkpt
    5104              : 
    5105              :      ! Precompute 1d phases e^{ik_j R_j} on the supercell.
    5106          464 :      do idir=1,3
    5107        24935 :        do ii=0,sc_ngfft(idir) - 1
    5108        24471 :          kdotr = two_pi * (kk_sc(idir) * (ii / dble(sc_ngfft(idir))))
    5109        24819 :          sc_ceikr_1d(ii+1, idir) = dcmplx(cos(kdotr), sin(kdotr))
    5110              :        end do
    5111              :      end do
    5112              : 
    5113              :      ! Phase due to the primitive translation (default: 0)
    5114          464 :      cphase_tr = exp(-j_dpc * two_pi * dot_product(kk, dtset%vpq_trvec))
    5115              : 
    5116              :      ! Sum over bands
    5117          286 :      do ib=1,vpq%nb_spin(spin)
    5118          170 :        band = bstart + ib - 1
    5119              :        ! Get periodic part on the real space FFT mesh in ur_k
    5120              :        call wfd%rotate_cg(band, ndat1, spin, kk_ibz, npw_k, kg_k, istwf_k, &
    5121          170 :                           cryst, mapl_k, gbound_k, work_ngfft, work, ug_k, urs_kbz=ur_k)
    5122              :        !print *, "int_omega dr |u(r)}^2:", sum(abs(ur_k(:,1)) ** 2) / uc_nfft
    5123              : 
    5124              :        ! Use linear interpolate to downsample from ngfft to ds_ngfft.
    5125          170 :        if (ds_iscale /= 1) then
    5126          170 :          call interpolate_ur(ngfft, nspinor*ndat1, ur_k, ds_ngfft, ds_ur_k)
    5127              :          !print *, "int_omega dr |ds_u(r)}^2:", sum(abs(ds_ur_k(:,1)) ** 2) / product(ds_ngfft(1:3))
    5128              :        end if
    5129              : 
    5130              :        ! Accumulate for each polaron state.
    5131          618 :        do ip=1,vpq%nstates
    5132          332 :          a_nk = vpq%a_spin(ib, ik, ip, spin) * cphase_tr
    5133          834 :          do spinor=1,nspinor
    5134          332 :            spad = (spinor - 1) * sc_nfft
    5135              : 
    5136          664 :            if (ds_iscale == 1) then
    5137              :                ! Loop over the points in the R supercell without downsampling.
    5138            0 :                ir = 0
    5139            0 :                do ir3=0,sc_ngfft(3)-1
    5140              :                  ! The FFT index of the point wrapped into the unit cell.
    5141            0 :                  wp3 = modulo(ir3, ngfft(3))
    5142            0 :                  c3 = sc_ceikr_1d(ir3+1, 3)
    5143            0 :                  do ir2=0,sc_ngfft(2)-1
    5144            0 :                    wp2 = modulo(ir2, ngfft(2))
    5145            0 :                    c23 = sc_ceikr_1d(ir2+1, 2) * c3
    5146            0 :                    do ir1=0,sc_ngfft(1)-1
    5147            0 :                      wp1 = modulo(ir1, ngfft(1))
    5148            0 :                      c123 = sc_ceikr_1d(ir1+1, 1) * c23
    5149            0 :                      uc_idx = 1 + wp1 + wp2*ngfft(1) + wp3*ngfft(1)*ngfft(2)
    5150            0 :                      ir = ir + 1; irsp = ir + spad
    5151            0 :                      pol_wfr(irsp, ip, spin) = pol_wfr(irsp, ip, spin) + a_nk * ur_k(uc_idx,1) * c123
    5152              :                    end do
    5153              :                  end do
    5154              :                end do
    5155              :             else
    5156              :                ! Loop over the points in the supercell with downsampling
    5157          332 :                ir = 0
    5158        18209 :                do ir3=0,sc_ngfft(3)-1
    5159              :                  ! The FFT index of the point wrapped into the unit cell.
    5160        17877 :                  wp3 = modulo(ir3, ds_ngfft(3))
    5161        17877 :                  c3 = sc_ceikr_1d(ir3+1, 3)
    5162      1051760 :                  do ir2=0,sc_ngfft(2)-1
    5163      1033551 :                    wp2 = modulo(ir2, ds_ngfft(2))
    5164      1033551 :                    c23 = sc_ceikr_1d(ir2+1, 2) * c3
    5165     65429931 :                    do ir1=0,sc_ngfft(1)-1
    5166     64378503 :                      wp1 = modulo(ir1, ds_ngfft(1))
    5167     64378503 :                      c123 = sc_ceikr_1d(ir1+1, 1) * c23
    5168     64378503 :                      uc_idx = 1 + wp1 + wp2*ds_ngfft(1) + wp3*ds_ngfft(1)*ds_ngfft(2)
    5169     64378503 :                      ir = ir + 1; irsp = ir + spad
    5170              :                      ! Note the use of the downsampled ds_ur_k here.
    5171     65412054 :                      pol_wfr(irsp, ip, spin) = pol_wfr(irsp, ip, spin) + a_nk * ds_ur_k(uc_idx,1) * c123
    5172              :                    end do
    5173              :                  end do
    5174              :                end do
    5175              :             end if
    5176              : 
    5177              : end do
    5178              :        end do ! ip
    5179              :      end do ! ib
    5180              : 
    5181          116 :      ABI_FREE(ug_k)
    5182          118 :      ABI_FREE(kpg_k)
    5183              :    end do ! ik
    5184              :  end do ! spin
    5185              : 
    5186            2 :  ABI_FREE(kg_k)
    5187            2 :  ABI_FREE(work)
    5188            2 :  ABI_FREE(ur_k)
    5189            2 :  ABI_SFREE(ds_ur_k)
    5190            2 :  ABI_FREE(gbound_k)
    5191            2 :  ABI_FREE(sc_ceikr_1d)
    5192            2 :  call krank_ibz%free()
    5193              : 
    5194              :  ! Collect pol_wfr on the master rank who's gonna write the polaron density in XSF format.
    5195            2 :  call xmpi_sum_master(pol_wfr, master, comm, ierr)
    5196              : 
    5197            2 :  if (my_rank == master) then
    5198       747935 :    pol_wfr = pol_wfr / (nkbz * sqrt(cryst%ucvol))
    5199              :    ! FIXME: Here we're gonna have another big allocation
    5200            6 :    ABI_MALLOC(pol_rhor, (sc_nfft))
    5201              : 
    5202              :    ! Here decide if we are gonna write the polaron wavefunctions with_diplaced atoms or not.
    5203           26 :    use_displaced_scell = all(kptrlatt_ == qptrlatt_) .and. have_scell_q
    5204            2 :    num_writes = 1; if (use_displaced_scell) num_writes = 2
    5205              : 
    5206            2 :    if (nspinor == 1) then
    5207              :      ! Handle spin-polarized case by writing two XSF files.
    5208            4 :      do spin=1,nsppol
    5209              :        ! Handle multiple polaronic states for each spin.
    5210            8 :        do ip=1,vpq%nstates
    5211              :          write(msg, "(2(a,i0),a,es16.6)")&
    5212          506 :            " For spin: ", spin, ": pstate: ", ip, ": 1/N_k \sum_nk |A_nk|^2 = ", sum(abs(vpq%a_spin(:,:,ip,spin))**2) / nkbz
    5213            4 :          call wrtout(units, msg)
    5214       747935 :          pol_rhor = abs(pol_wfr(:, ip, spin)) ** 2
    5215            4 :          write(msg, "(2(a,i0),a,es16.6)")" Polaron density for spin: ", spin, ": pstate: ", ip, &
    5216       747947 :                                          " integrates to: ", sum(pol_rhor) * cryst%ucvol / product(ds_ngfft(1:3))
    5217            4 :          call wrtout(units, msg)
    5218       747935 :          write(msg, "(a,es16.6)")" maxval(abs(aimag(pol_wfr))): ", maxval(abs(aimag(pol_wfr(:, ip, spin))))
    5219            4 :          call wrtout(std_out, msg)
    5220            4 :          call center_and_spread(cryst, vpq%ngkpt, sc_ngfft, pol_rhor, center_cart, spread, units)
    5221              : 
    5222           14 :          do ii=1,num_writes
    5223            8 :            if (ii == 1) then
    5224            4 :              xcart_ptr => scell_k%xcart
    5225            4 :              path = strcat(dtfil%filnam_ds(4), "_pstate_", itoa(ip), "_POLARON.xsf")
    5226            4 :              if (nsppol == 2) path = strcat(dtfil%filnam_ds(4), strcat("_spin_", itoa(spin)), "_pstate_", itoa(ip), "_POLARON.xsf")
    5227            4 :              call wrtout(units, strcat("- Writing the polaron wavefunction with undisplaced atoms to: ", path))
    5228              :            else
    5229            4 :              path = strcat(dtfil%filnam_ds(4), "_pstate_", itoa(ip), "_POLARON_DISPL.xsf")
    5230            4 :              if (nsppol == 2) path = strcat(dtfil%filnam_ds(4), strcat("_spin_", itoa(spin)), "_pstate_", itoa(ip), "_POLARON_DISPL.xsf")
    5231            4 :             call wrtout(units, strcat("- Writing the polaron wavefunction with displaced atoms to: ", path))
    5232              : 
    5233              :              ! Here we displace the atoms in the supercell for this spin (only master has the correct values)
    5234        18232 :              scell_q%xcart = scell_q%xcart_ref + sc_displ_cart_re(:,:,ip,spin)
    5235            4 :              xcart_ptr => scell_q%xcart
    5236              :            end if
    5237              : 
    5238              :            call write_xsf(path, sc_ngfft(1), sc_ngfft(2), sc_ngfft(3), pol_rhor, scell_k%rprimd, origin0, &
    5239           12 :                           scell_k%natom, scell_k%ntypat, scell_k%typat, xcart_ptr, scell_k%znucl, 0)
    5240              :          end do ! ii
    5241              :        end do ! ip
    5242              :      end do ! spin
    5243              : 
    5244              :    else
    5245              :      ! Spinor wavefunctions.
    5246            0 :      do ip=1,vpq%nstates
    5247              :        write(msg, "(2(a,i0),a,es16.6)")&
    5248            0 :          " For spin: ", spin, ": pstate: ", ip, ": 1/N_k \sum_nk |A_nk|^2 = ", sum(abs(vpq%a_spin(:,:,ip,spin))**2) / nkbz
    5249            0 :        call wrtout(units, msg)
    5250              : 
    5251            0 :        pol_rhor(:) = abs(pol_wfr(1:sc_nfft, ip, 1)) ** 2
    5252            0 :        pol_rhor(:) = abs(pol_wfr(sc_nfft+1:, ip, 1)) ** 2 + pol_rhor(:)
    5253            0 :        write(msg, "(2(a,i0),a,es16.6)")" Polaron density for spin: ", spin, ": pstate: ", ip, &
    5254            0 :                                        " integrates to: ", sum(pol_rhor) * cryst%ucvol / product(ds_ngfft(1:3))
    5255            0 :        call wrtout(units, msg)
    5256            0 :        write(msg, "(a,es16.6)")" maxval(abs(aimag(pol_wfr))): ", maxval(abs(aimag(pol_wfr(:, ip, 1))))
    5257            0 :        call wrtout(units, msg)
    5258            0 :        call center_and_spread(cryst, vpq%ngkpt, sc_ngfft, pol_rhor, center_cart, spread, units)
    5259              : 
    5260            0 :        spin = 1
    5261            0 :        do ii=1,num_writes
    5262            0 :          if (ii == 1) then
    5263            0 :            xcart_ptr => scell_k%xcart
    5264            0 :            path = strcat(dtfil%filnam_ds(4), "_pstate_", itoa(ip), "_POLARON.xsf")
    5265            0 :           call wrtout(units, strcat("- Writing the polaron wavefunction with undisplaced atoms to: ", path))
    5266              :          else
    5267            0 :            path = strcat(dtfil%filnam_ds(4), "_pstate_", itoa(ip), "_POLARON_DISPL.xsf")
    5268            0 :           call wrtout(units, strcat("- Writing the polaron wavefunction with displaced atoms to: ", path))
    5269              : 
    5270              :            ! Here we displace the atoms in the supercell for this spin (only master has the correct values)
    5271            0 :            scell_q%xcart = scell_q%xcart_ref + sc_displ_cart_re(:,:,ip,spin)
    5272            0 :            xcart_ptr => scell_q%xcart
    5273              :          end if
    5274              : 
    5275              :          call write_xsf(path, sc_ngfft(1), sc_ngfft(2), sc_ngfft(3), pol_rhor, scell_k%rprimd, origin0, &
    5276            0 :                         scell_k%natom, scell_k%ntypat, scell_k%typat, xcart_ptr, scell_k%znucl, 0)
    5277              :        end do ! ii
    5278              :      end do ! ip
    5279              :    end if
    5280            2 :    ABI_FREE(pol_rhor)
    5281              :  end if ! master
    5282              : 
    5283            2 :  call cwtime_report(" Computation of polaron wavefunction completed", cpu_all, wall_all, gflops_all, pre_str=ch10, end_str=ch10)
    5284              : 
    5285            2 :  ABI_SFREE(sc_displ_cart_re)
    5286            2 :  ABI_FREE(pol_wfr)
    5287              : 
    5288            8 :  call wfd%free(); call scell_q%free(); call scell_k%free(); call vpq%free()
    5289              : 
    5290              : contains
    5291           10 : integer function vid(var_name)
    5292              :   character(len=*),intent(in) :: var_name
    5293           10 :   vid = nctk_idname(ncid, var_name)
    5294              : end function vid
    5295              : 
    5296              : end subroutine varpeq_plot
    5297              : !!***
    5298              : 
    5299            4 : subroutine center_and_spread(prim_cryst, ncells, sc_ngfft, rhor, center_cart, spread, units)
    5300              : 
    5301              : !Arguments ------------------------------------
    5302              :  type(crystal_t),intent(in) :: prim_cryst
    5303              :  integer,intent(in) :: ncells(3), sc_ngfft(18)
    5304              :  real(dp),intent(in) :: rhor(sc_ngfft(1), sc_ngfft(2), sc_ngfft(3))
    5305              :  !real(dp),intent(in) :: rhor(sc_ngfft(4), sc_ngfft(5), sc_ngfft(6)) ! FIXME
    5306              :  real(dp),intent(out) :: center_cart(3), spread
    5307              :  integer,intent(in) :: units(:)
    5308              : 
    5309              : !Local variables-------------------------------
    5310              :  integer :: i1, i2, i3, nfft, num_cells
    5311              :  real(dp) :: rr(3), rcart(3), rmr0(3), sc_rprimd(3,3), center_red(3), r2_mean, fwhm
    5312              :  character(len=500) :: msg
    5313              : !----------------------------------------------------------------------
    5314              : 
    5315           16 :  nfft = product(sc_ngfft(1:3))
    5316           16 :  sc_rprimd(:,1) = prim_cryst%rprimd(:,1) * ncells(1)
    5317           16 :  sc_rprimd(:,2) = prim_cryst%rprimd(:,2) * ncells(2)
    5318           16 :  sc_rprimd(:,3) = prim_cryst%rprimd(:,3) * ncells(3)
    5319           16 :  num_cells = product(ncells)
    5320              : 
    5321              :  ! Compute center_cart = \int r rhor(r) dr
    5322            4 :  center_cart = zero !; r2_mean = zero
    5323          217 :  do i3=1,sc_ngfft(3)
    5324          213 :    rr(3) = (i3 - one) / sc_ngfft(3)
    5325        12376 :    do i2=1,sc_ngfft(2)
    5326        12159 :      rr(2) = (i2 - one) / sc_ngfft(2)
    5327       760299 :      do i1=1,sc_ngfft(1)
    5328       747927 :        rr(1) = (i1 - one) / sc_ngfft(1)
    5329              :        ! Go to cartesian coordinates.
    5330      9723051 :        rcart = matmul(sc_rprimd, rr)
    5331      2991708 :        center_cart = center_cart + rhor(i1, i2, i3) * rcart
    5332       760086 :        r2_mean = r2_mean + rhor(i1, i2, i3) * dot_product(rcart, rcart)
    5333              :      end do
    5334              :    end do
    5335              :  end do
    5336              : 
    5337              :  !center_cart = matmul(sc_rprimd, center_cart)
    5338           16 :  center_cart = center_cart * num_cells * prim_cryst%ucvol / (one*nfft)
    5339              :  !r2_mean = r2_mean * num_cells * prim_cryst%ucvol / (one*nfft)
    5340              :  !spread = sqrt(r2_mean - dot_product(center_cart, center_cart))
    5341              :  !write(msg, "(a,2(es16.6,a))")" Polaron spread: ", spread, " (Bohr)", spread * Bohr_Ang, " (Ang)"
    5342              :  !call wrtout(units, msg)
    5343              : 
    5344              :  ! Compute = \int (r - center_cart)^2 rhor dr = <r^2> - <r>^2
    5345            4 :  spread = zero
    5346          217 :  do i3=1,sc_ngfft(3)
    5347          213 :    rr(3) = (i3 - one) / sc_ngfft(3)
    5348        12376 :    do i2=1,sc_ngfft(2)
    5349        12159 :      rr(2) = (i2 - one) / sc_ngfft(2)
    5350       760299 :      do i1=1,sc_ngfft(1)
    5351       747927 :        rr(1) = (i1 - one) / sc_ngfft(1)
    5352              :        ! Go to cartesian coordinates.
    5353     11966832 :        rmr0 = matmul(sc_rprimd, rr) - center_cart
    5354      3003867 :        spread = spread + rhor(i1, i2, i3) * dot_product(rmr0, rmr0)
    5355              :      end do
    5356              :    end do
    5357              :  end do
    5358            4 :  spread = sqrt(spread * num_cells * prim_cryst%ucvol / (one*nfft))
    5359              : 
    5360            4 :  call xcart2xred(1, prim_cryst%rprimd, center_cart, center_red)
    5361            4 :  call wrtout(units, sjoin(" Polaron center in Cartesian coordinates: ", ltoa(center_cart), " (Bohr)"))
    5362            4 :  call wrtout(units, sjoin(" Fractional coordinates in terms of the primitive cell:", ltoa(center_red)))
    5363            4 :  write(msg, "(a,2(es16.6,a))")" Polaron spread: ", spread, " (Bohr)", spread * Bohr_Ang, " (Ang)"
    5364            4 :  call wrtout(units, msg)
    5365              :  ! full width at half-maximum
    5366            4 :  fwhm = (two * sqrt(two * log(two))) * spread
    5367            4 :  write(msg, "(a,2(es16.6,a))")" Full width at half-maximum (FWHM) ", fwhm, " (Bohr) ", fwhm * Bohr_Ang, " (Ang)"
    5368            4 :  call wrtout(units, msg)
    5369              : 
    5370            4 : end subroutine center_and_spread
    5371              : 
    5372       110592 : end module m_varpeq
    5373              : !!***
        

Generated by: LCOV version 2.3-1