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-11-09 13:21:34 Functions: 87.0 % 69 60
Branches: 48.1 % 5109 2458

             Branch data     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