TABLE OF CONTENTS


ABINIT/m_gstore [ Modules ]

[ Top ] [ Modules ]

NAME

 m_gstore

FUNCTION

  This module implements the gstore_t object that allows one to **precompute"" the e-ph matrix elements g
  and store them in memory with a MPI-distributed data structure.

  This approach is the most CPU-efficient one when one has to deal with
  algorithms in which the same g(q, k) is required several (many) times.
  Typical examples are iterative solvers for non-linear equations that are called inside a loop over T.
  At each iteration, indeed, we need g(q, k) and computing these quantities from scratch
  would be very expensive.

  Note that g depends on the two wave vectors (q, k), two electron band indices (m, n),
  phonon mode nu with momentum q and spin index if nsppol == 2 (collinear case).

  g(q, k) is therefore a sloppy notation for:

          g(q, k) = <k + q, m, spin| \Delta_{q, \nu} V^{spin}_{scf} | k, n, spin>

  There are lots of technical details that should be discussed but, roughly speaking,
  the gqk API allows one to:

   - select whether q or k should be in the IBZ or in the BZ.
     NB: It is not possible to use the IBZ both for q and k as g(Sk, q) = g(k, S^{-1}q)
     thus one has to select the appropriate zones beforehand.

   - filter bands and/or k/q wavevectors according to some criterion.
     In superconductors, for instance, only k/k+q states on the Fermi surface are needed.
     In semiconductors, one can include only k, k+q inside an energy window around the band edge.

  - whether the code should compute and store the complex valued g or |g|^2.
    Expression depending of |g|^2 are gauge-invariant provided that all degenerate states are summed over.
    On the contrary, the complex valued g is gauge-dependent and hic sunt leones.
    In Abinit, the g elements are computed within the same gauge by reconstructing Bloch states
    in the BZ from the IBZ by using a deterministic symmetrization algorithm
    Client code reading the e-ph matrix elements produced by ABINIT is expected to follow the
    same conventions, especially if one needs to mix g with wavefunctions in the BZ.

  At the level of the API, we have three different routines.

      1) gstore_new builds the object, defines the BZ sampling type (e.g. k in the IBZ, q in the BZ)
         and implements filtering techniques. The MPI grid is automatically generated at this level

      2) gstore_compute evaluates the e-ph matrix elements in parallel and dumps the results to GSTORE.nc

      3) gstore%from_ncpath reconstructs the object from GSTORE.nc

  In a typical scenario, one uses eph_task 11 to generate GSTORE.nc i.e. steps 1) and 2).
  Then one introduces a new value of eph_task in which we read the object from file and call
  a specialized routine that implements the "post-processing" steps needed to compute the physical properties of interest.

  Now, let's discuss the MPI-distribution.

  The (q, k) matrix is distributed inside a 2D cartesian grid using block distribution.
  This is schematic representation for 4 procs with 2 procs for k and 2 procs for q:

                 k-axis (kpt_comm)
              |--------------------
              |         |         |
              |   P00   |   P01   |
              |         |         |
    q-axis    |--------------------
  (qpt_comm)  |         |         |
              |   P10   |   P11   |
              |         |         |
              |--------------------

  Each processor stores all the (band_1, band_2) transitions for a given (q, k) pair.

  Perturbations can be optionally distributed along a third axis (pert_comm).
  Note, however, that the parallelism over perturbations is not expected to be the most efficient
  although it allows one to reduce the memory required to store the scattering potential in the supercell
  as we can distribute W(r, R, 3 * natom) over the last dimension.

  For electronic properties, one usually uses k-points in the IBZ and q-points in the BZ.
  hence the parallelism over q-points is the most efficient one in terms of wall-time.
  Keep in mind, however, that the k-point parallelism allows one to reduce the memory allocated for the
  wavefunctions. Using some procs for k-point is also beneficial in terms of performance
  as we reduce load imbalance with the number of procs in qpt_comm does not divide nqbz.

  NB: If nsppol == 2, we create two gqk objects, one for each spin.
  The reason is that dimensions such as the number of effective bands/q-points/k-points
  depends on spin if filters are employed.

COPYRIGHT

  Copyright (C) 2008-2024 ABINIT group (MG)
  This file is distributed under the terms of the
  GNU General Public License, see ~abinit/COPYING
  or http://www.gnu.org/copyleft/gpl.txt .

SOURCE

 97 #if defined HAVE_CONFIG_H
 98 #include "config.h"
 99 #endif
100 
101 #include "abi_common.h"
102 
103 module m_gstore
104 
105  use defs_basis
106  use m_abicore
107  use m_xmpi
108  use m_errors
109  use m_htetra
110  use libtetrabz
111  use m_ebands
112  use, intrinsic :: iso_c_binding
113  use netcdf
114  use m_nctk
115  use m_wfk
116  use m_ddb
117  use m_ddk
118  use m_dvdb
119  use m_crystal
120  use m_fft
121  use m_hamiltonian
122  use m_pawcprj
123  use m_dtset
124  use m_dtfil
125  use m_wfd
126  use m_ephtk
127  use m_mkffnl
128 
129  use defs_abitypes,    only : mpi_type
130  use m_time,           only : cwtime, cwtime_report, sec2str
131  use m_fstrings,       only : tolower, itoa, ftoa, sjoin, ktoa, ltoa, strcat, replace_ch0
132  !use m_yaml,           only : yamldoc_t
133  use m_numeric_tools,  only : arth, get_diag, isdiagmat
134  use m_krank,          only : krank_t, krank_new, krank_from_kptrlatt, get_ibz2bz, star_from_ibz_idx
135  use m_io_tools,       only : iomode_from_fname
136  use m_special_funcs,  only : gaussian
137  use m_copy,           only : alloc_copy
138  use m_fftcore,        only : ngfft_seq, get_kg
139  use m_cgtools,        only : cg_zdotc
140  use m_kg,             only : getph, mkkpg
141  use defs_datatypes,   only : ebands_t, pseudopotential_type
142  use m_hdr,            only : hdr_type, fform_from_ext, hdr_ncread
143  use m_symtk,          only : matr3inv
144  use m_kpts,           only : kpts_ibz_from_kptrlatt, kpts_timrev_from_kptopt, kpts_map, kpts_sort, kpts_pack_in_stars
145  use m_getgh1c,        only : getgh1c, rf_transgrid_and_pack, getgh1c_setup
146  use m_ifc,            only : ifc_type
147  use m_phonons,        only : pheigvec_rotate
148  use m_pawang,         only : pawang_type
149  use m_pawrad,         only : pawrad_type
150  use m_pawtab,         only : pawtab_type
151  use m_pawfgr,         only : pawfgr_type
152 
153  implicit none
154 
155  private

m_gstore/gqk_dbldelta_qpt [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gqk_dbldelta_qpt

FUNCTION

  Note that k/q weights are not included in dbldelta_q

INPUTS

OUTPUT

SOURCE

2281 subroutine gqk_dbldelta_qpt(gqk, my_iq, gstore, eph_intmeth, eph_fsmear, qpt, weight_q, dbldelta_q)
2282 
2283 !Arguments ------------------------------------
2284  class(gqk_t),intent(in) :: gqk
2285  class(gstore_t),target,intent(inout) :: gstore
2286  integer,intent(in) :: my_iq, eph_intmeth
2287  real(dp),intent(in) :: eph_fsmear
2288  real(dp),intent(out) :: qpt(3), weight_q, dbldelta_q(gqk%nb, gqk%nb, gqk%my_nk)
2289 
2290 !Local variables ------------------------------
2291 !scalars
2292  real(dp), parameter :: min_smear = tol9
2293  integer :: nb, nkbz, spin, my_ik, ib, ib1, ib2, band1, band2, nesting, ebands_timrev
2294  integer :: ik_ibz, isym_k, trev_k, tsign_k, g0_k(3)
2295  integer :: ikq_ibz, isym_kq, trev_kq, tsign_kq, g0_kq(3)
2296  integer :: ii, i1, i2, i3, cnt, ik_bz, ltetra
2297  real(dp) :: g1, g2, sigma !, weight_k !, cpu, wall, gflops
2298  logical :: isirr_k, isirr_kq, use_adaptive
2299  type(ebands_t), pointer :: ebands
2300  type(crystal_t), pointer :: cryst
2301  type(krank_t) :: my_krank
2302 !arrays
2303  integer :: nge(3), ngw(3)
2304  integer,allocatable :: my_kqmap(:,:), kmesh_map(:,:)
2305  real(dp) :: kk(3), kmesh_cartvec(3,3), rlatt(3,3), klatt(3,3), vb_k(3, gqk%nb), vb_kq(3, gqk%nb)
2306  real(dp),allocatable :: eig_k(:,:), eig_kq(:,:), kmesh(:,:), wght_bz(:,:,:)
2307 
2308 !----------------------------------------------------------------------
2309 
2310  nb = gqk%nb; nkbz = gstore%nkbz; spin = gqk%spin
2311 
2312  ebands => gstore%ebands; cryst => gstore%cryst
2313  ebands_timrev = kpts_timrev_from_kptopt(ebands%kptopt)
2314 
2315  call gqk%myqpt(my_iq, gstore, weight_q, qpt)
2316 
2317  ! The double delta with tetra is ill-defined for q == 0. In this case we fall back to gaussian.
2318  nesting = merge(1, 0, abs(eph_intmeth) == 2 .and. all(abs(qpt) < tol12))
2319 
2320  rlatt = gstore%ebands%kptrlatt; call matr3inv(rlatt, klatt)
2321  kmesh_cartvec(:, 1) = cryst%gprimd(:,1)*klatt(1,1) + cryst%gprimd(:,2)*klatt(2,1) + cryst%gprimd(:,3)*klatt(3,1)
2322  kmesh_cartvec(:, 2) = cryst%gprimd(:,1)*klatt(1,2) + cryst%gprimd(:,2)*klatt(2,2) + cryst%gprimd(:,3)*klatt(3,2)
2323  kmesh_cartvec(:, 3) = cryst%gprimd(:,1)*klatt(1,3) + cryst%gprimd(:,2)*klatt(2,3) + cryst%gprimd(:,3)*klatt(3,3)
2324  ! TODO: It seems that two_pi is not needed here!
2325 
2326  if (abs(eph_intmeth) == 1 .or. nesting /= 0) then
2327    use_adaptive = eph_fsmear < zero .or. abs(eph_intmeth) == 2
2328    if (use_adaptive) then
2329      ABI_CHECK(allocated(gqk%vk_cart_ibz), "vk_cart_ibz should be allocated when use_adaptive is .True.")
2330    end if
2331 
2332    ! Find k + q in the IBZ for all my k-points.
2333    ABI_MALLOC(my_kqmap, (6, gqk%my_nk))
2334    if (kpts_map("symrel", ebands_timrev, cryst, gstore%krank_ibz, gqk%my_nk, gqk%my_kpts, my_kqmap, qpt=qpt) /= 0) then
2335      ABI_ERROR(sjoin("Cannot map k+q to IBZ with qpt:", ktoa(qpt)))
2336    end if
2337 
2338    ! Init default sigma
2339    sigma = eph_fsmear
2340 
2341    do my_ik=1,gqk%my_nk
2342      kk = gqk%my_kpts(:, my_ik)
2343 
2344      ik_ibz = gqk%my_k2ibz(1, my_ik); isym_k = gqk%my_k2ibz(2, my_ik)
2345      trev_k = gqk%my_k2ibz(6, my_ik); g0_k = gqk%my_k2ibz(3:5, my_ik)
2346      isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
2347      tsign_k = 1; if (trev_k == 1) tsign_k = -1
2348 
2349      ikq_ibz = my_kqmap(1, my_ik); isym_kq = my_kqmap(2, my_ik)
2350      trev_kq = my_kqmap(6, my_ik); g0_kq = my_kqmap(3:5, my_ik)
2351      isirr_kq = (isym_kq == 1 .and. trev_kq == 0 .and. all(g0_kq == 0))
2352      tsign_kq = 1; if (trev_kq == 1) tsign_kq = -1
2353 
2354      if (use_adaptive) then
2355        ! If k or k+q is not in the IBZ, we need to recostruct the value by symmetry using v(Sq) = S v(q).
2356        ! Use transpose(R) because we are using the tables for the wavefunctions
2357        ! In this case listkk has been called with symrec and use_symrec=False
2358        ! so q_bz = S^T q_ibz where S is the isym_kq symmetry
2359        vb_k = gqk%vk_cart_ibz(:,:,ik_ibz)
2360        vb_kq = gqk%vk_cart_ibz(:,:,ikq_ibz)
2361 
2362        if (.not. isirr_k) then
2363          do ib=1,nb
2364            vb_k(:,ib) = tsign_k * matmul(transpose(cryst%symrel_cart(:,:,isym_k)), vb_k(:,ib))
2365          end do
2366        end if
2367        if (.not. isirr_kq) then
2368          do ib=1,nb
2369            vb_kq(:,ib) = tsign_kq * matmul(transpose(cryst%symrel_cart(:,:,isym_kq)), vb_kq(:,ib))
2370          end do
2371        end if
2372      end if
2373 
2374      do ib2=1,nb
2375        band2 = ib2 + gqk%bstart - 1
2376        if (use_adaptive) then
2377          sigma = max(maxval([(abs(dot_product(vb_k(:, ib2), kmesh_cartvec(:,ii))), ii=1,3)]), min_smear)
2378          !write(std_out, *)"sigma:", sigma * Ha_eV
2379        end if
2380        g2 = gaussian(ebands%eig(band2, ik_ibz, spin) - ebands%fermie, sigma)
2381 
2382        do ib1=1,nb
2383          band1 = ib1 + gqk%bstart - 1
2384          if (use_adaptive) then
2385            sigma = max(maxval([(abs(dot_product(vb_kq(:, ib1), kmesh_cartvec(:,ii))), ii=1,3)]), min_smear)
2386          end if
2387          g1 = gaussian(ebands%eig(band1, ikq_ibz, spin) - ebands%fermie, sigma)
2388          dbldelta_q(ib1, ib2, my_ik) = g1 * g2 ! / fs%nktot
2389        end do
2390 
2391      end do
2392    end do
2393 
2394    ABI_FREE(my_kqmap)
2395 
2396  else if (abs(eph_intmeth) == 2) then
2397 
2398    ABI_CHECK(isdiagmat(ebands%kptrlatt), "kptrlatt must be diagonal when tetra is used.")
2399    ABI_CHECK(ebands%nshiftk == 1, "nshiftk must be 1 when tetra is used")
2400    nge = get_diag(ebands%kptrlatt); ngw = nge
2401    ABI_CHECK(nkbz == product(nge(1:3)), "Wrong nge")
2402 
2403    ! Compute eig_k and eig_kq in full BZ for the relevant bands around Ef.
2404    ABI_MALLOC(kmesh, (3, nkbz))
2405    ABI_MALLOC(eig_k, (nb, nkbz))
2406    ABI_MALLOC(eig_kq, (nb, nkbz))
2407 
2408    ! Technical problems:
2409    !
2410    ! 1) libtetrabz works with the BZ and assume a certaing ordering of the k-points (see below)
2411    !    so we have to fill the array with eig_k and eig_kq from the IBZ by remapping the libtetra kk
2412    !    to the Abinit IBZ
2413 
2414    ! 2) The dbldelta weights are given in the BZ, while the caller requires weights for k in the IBZ
2415    !    and moreover only for the IBZ k-point treated by this MPI proc.
2416 
2417    ik_bz = 0
2418    do i3=0,nge(3) - 1
2419      do i2=0,nge(2) - 1
2420        do i1=0,nge(1) - 1
2421          ik_bz = ik_bz + 1
2422          kk = ([i1, i2, i3] + ebands%shiftk(:, 1)) / nge(:)
2423          kmesh(:, ik_bz) = kk
2424        end do
2425      end do
2426    end do
2427 
2428    ! Map libtetra BZ mesh to IBZ and fill eig_k
2429    !call cwtime(cpu, wall, gflops, "start")
2430    ABI_MALLOC(kmesh_map, (6, nkbz))
2431 
2432    ! Find correspondence between libtetra mesh and the IBZ.
2433    if (kpts_map("symrec", ebands_timrev, cryst, gstore%krank_ibz, nkbz, kmesh, kmesh_map) /= 0) then
2434      ABI_ERROR("Cannot map libtetra mesh to IBZ")
2435    end if
2436 
2437    do ik_bz=1,nkbz
2438      ik_ibz = kmesh_map(1, ik_bz)
2439      eig_k(:, ik_bz) = ebands%eig(gqk%bstart:gqk%bstop, ik_ibz, spin) - ebands%fermie
2440    end do
2441 
2442    ! Map libtetra BZ mesh + q to IBZ and fill eig_kq
2443    if (kpts_map("symrec", ebands_timrev, cryst, gstore%krank_ibz, nkbz, kmesh, kmesh_map, qpt=qpt) /= 0) then
2444      ABI_ERROR(sjoin("Cannot map libtetra k+q to IBZ with qpt:", ktoa(qpt)))
2445    end if
2446 
2447    do ik_bz=1,nkbz
2448      ikq_ibz = kmesh_map(1, ik_bz)
2449      eig_kq(:, ik_bz) = ebands%eig(gqk%bstart:gqk%bstop, ikq_ibz, spin) - ebands%fermie
2450    end do
2451 
2452    ABI_FREE(kmesh_map)
2453    !call cwtime_report(" kmesh_map", cpu, wall, gflops)
2454 
2455    ! Call libtetra routine to compute weights for double delta integration.
2456    ! Note that libtetra assumes Ef set to zero.
2457    ! TODO: Average weights over degenerate states?
2458    ! NB: This is a bootleneck, can pass comm_kp
2459 
2460    ! Select option for double delta with tetra.
2461    !  2 for the optimized tetrahedron method.
2462    ! -2 for the linear tetrahedron method.
2463    ltetra = 0
2464    if (eph_intmeth ==  2) ltetra = 2
2465    if (eph_intmeth == -2) ltetra = 1
2466 
2467    ABI_MALLOC(wght_bz, (nb, nb, nkbz))
2468    call libtetrabz_dbldelta(ltetra, gstore%cryst%gprimd, nb, nge, eig_k, eig_kq, ngw, wght_bz) !, comm=comm)
2469    !call cwtime_report(" libtetrabz_dbldelta", cpu, wall, gflops)
2470 
2471    my_krank = krank_new(gqk%my_nk, gqk%my_kpts)
2472 
2473    ! Reindex from full BZ to my set of kpoints and rescale weights.
2474    cnt = 0
2475    do ik_bz=1,nkbz
2476      my_ik = my_krank%get_index(kmesh(:, ik_bz))
2477      if (my_ik /= -1) then
2478        dbldelta_q(:,:,my_ik) = wght_bz(:,:,ik_bz) * gstore%nkbz
2479        cnt = cnt + 1
2480      end if
2481    end do
2482 
2483    ! FIXME: bug if k-point (and q-point) parallelism.
2484    ABI_CHECK(cnt == gqk%my_nk, sjoin("cnt != my_nk, ", itoa(cnt), itoa(gqk%my_nk)))
2485    call my_krank%free()
2486    !call cwtime_report(" transfer", cpu, wall, gflops)
2487 
2488    ABI_FREE(wght_bz)
2489    ABI_FREE(kmesh)
2490    ABI_FREE(eig_k)
2491    ABI_FREE(eig_kq)
2492 
2493  else
2494    ABI_ERROR(sjoin("Invalid eph_intmeth:", itoa(eph_intmeth)))
2495  end if
2496 
2497 end subroutine gqk_dbldelta_qpt

m_gstore/gqk_free [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gqk_free

FUNCTION

  Free dynamic memory.

SOURCE

2510 subroutine gqk_free(gqk)
2511 
2512 !Arguments ------------------------------------
2513  class(gqk_t),intent(inout) :: gqk
2514 !----------------------------------------------------------------------
2515 
2516  ABI_SFREE(gqk%my_k2ibz)
2517  ABI_SFREE(gqk%my_kpts)
2518  ABI_SFREE(gqk%my_wtk)
2519  ABI_SFREE(gqk%my_q2ibz)
2520  ABI_SFREE(gqk%my_q2bz)
2521  ABI_SFREE(gqk%my_wnuq)
2522  ABI_SFREE(gqk%my_displ_cart)
2523  ABI_SFREE(gqk%my_g)
2524  ABI_SFREE(gqk%my_g2)
2525  ABI_SFREE(gqk%my_iperts)
2526  ABI_SFREE(gqk%vk_cart_ibz)
2527  ABI_SFREE(gqk%vkmat_cart_ibz)
2528 
2529  ! Free communicators
2530  call gqk%kpt_comm%free()
2531  call gqk%qpt_comm%free()
2532  call gqk%pert_comm%free()
2533  call gqk%qpt_pert_comm%free()
2534  call gqk%grid_comm%free()
2535 
2536 end subroutine gqk_free

m_gstore/gqk_myqpt [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gqk_myqpt

FUNCTION

  Return the weight and the reduced coordinates of the q-point from the local index my_iq

INPUTS

OUTPUT

SOURCE

2233 pure subroutine gqk_myqpt(gqk, my_iq, gstore, weight, qpt)
2234 
2235 !Arguments ------------------------------------
2236  class(gqk_t),intent(in) :: gqk
2237  class(gstore_t),intent(in) :: gstore
2238  integer,intent(in) :: my_iq
2239  real(dp),intent(out) :: weight, qpt(3)
2240 
2241 !Local variables ------------------------------
2242 !scalars
2243  integer :: iq_ibz, isym_q, trev_q, tsign_q, g0_q(3)
2244  logical :: isirr_q
2245 
2246 !----------------------------------------------------------------------
2247 
2248  iq_ibz = gqk%my_q2ibz(1, my_iq); isym_q = gqk%my_q2ibz(2, my_iq)
2249  trev_q = gqk%my_q2ibz(6, my_iq); g0_q = gqk%my_q2ibz(3:5, my_iq)
2250  isirr_q = (isym_q == 1 .and. trev_q == 0 .and. all(g0_q == 0))
2251  tsign_q = 1; if (trev_q == 1) tsign_q = -1
2252 
2253  ! NB: Use symrec convention for q
2254  qpt = tsign_q * matmul(gstore%cryst%symrec(:,:,isym_q), gstore%qibz(:, iq_ibz)) + g0_q
2255 
2256  select case(gstore%qzone)
2257  case ("ibz")
2258    weight = gstore%wtq(iq_ibz)
2259  case ("bz")
2260    weight = one / gstore%nqbz
2261  end select
2262 
2263 end subroutine gqk_myqpt

m_gstore/gqk_t [ Types ]

[ Top ] [ m_gstore ] [ Types ]

NAME

 gqk_t

FUNCTION

  This object stores MPI-distributed e-ph matrix elements for
  a given spin index (if collinear magnetism i.e. nsppol 2).
  local dimensions and arrays start with `my_`,
  global dimensions start with `glob_

SOURCE

172 type, public :: gqk_t
173 
174   integer :: cplex = -1
175   ! 1 if |g|^2 should be stored
176   ! 2 if complex valued g (mind the gauge)
177 
178   integer :: spin = -1
179   ! Spin index.
180 
181   integer :: natom3 = -1
182   ! 3 * natom
183   ! Mainly used to dimension arrays
184 
185   integer :: nb = -1
186   ! Number of bands included in the calculation for this spin
187   ! Global as this dimension is not MPI-distributed due to (m, n) pairs.
188   ! NB: nb is not necessarily equal to nband.
189 
190   integer :: bstart = -1, bstop = -1
191   ! The first band starts at bstart.
192   ! The last band is bstop (global indices)
193 
194   integer :: my_npert = -1
195   ! Number of perturbations treated by this MPI rank.
196 
197   integer :: glob_nk = -1, glob_nq = -1
198   ! Total number of k/q points in global matrix.
199   ! Note that k-points/q-points can be filtered.
200   ! Use kzone, qzone and kfilter to interpret these dimensions.
201 
202   integer :: my_nk = -1, my_nq = -1
203   ! Number of k/q points treated by this MPI proc.
204   ! Used to loop and allocate local arrays.
205 
206   integer :: my_kstart = -1, my_qstart = -1
207   ! Index of the first k/q point in the global matrix treated by this MPI proc
208 
209   integer,allocatable :: my_k2ibz(:,:)
210   ! (6, my_nk)
211   ! Mapping my_kpoints --> kibz
212 
213   !integer,allocatable :: my_k2bz(:,:)
214   ! (my_nk)
215   ! Mapping my_kpoints --> ik_bz
216 
217   real(dp),allocatable :: my_kpts(:,:)
218   ! (3, my_nkpt)
219   ! k-points treated by this MPI proc.
220 
221   real(dp),allocatable :: my_wtk(:)
222   ! (my_nkpt)
223   ! k-point weights
224 
225   integer,allocatable :: my_q2ibz(:,:)
226   ! (6, my_nq)
227   ! Mapping my_qpoints --> qibz
228 
229   integer,allocatable :: my_q2bz(:)
230   ! (my_nq)
231   ! Mapping my_iq index --> iq_bz index in the full BZ
232 
233   !integer,allocatable :: my_q2glob(:)
234   ! (my_nq)
235   ! Mapping my_iq index --> global index in the g(q, k) matrix.
236 
237   real(dp),allocatable :: vk_cart_ibz(:,:,:)
238   ! (3, nb, nkibz)
239   ! Diagonal v_{m, m,k} for k in the IBZ.
240   ! Values in the BZ can be reconstructed by symmetry.
241   ! Allocated if gstore%with_vk == 1
242 
243   real(dp),allocatable :: vkmat_cart_ibz(:,:,:,:,:)
244   ! (3, nb, nb, nkibz)
245   ! v_{m, n,k} for the k in the IBZ
246   ! Allocated if gstore%with_vk in (1, 2)
247 
248   integer,allocatable :: my_iperts(:)
249   ! (my_npert)
250   ! List of perturbation indices treated by this MPI proc.
251   ! Contiguous indices.
252 
253   complex(dp), allocatable :: my_g(:,:,:,:,:)
254   ! (my_npert, nb, my_nq, nb, my_nk)
255   ! (       p, b1,     q, b2, k)  -->  <k+q, b1| D_{q,p}H |k, b2>
256   ! e-ph matrix elements g (local buffer). Allocated if cplex == 2
257 
258   real(dp), allocatable :: my_g2(:,:,:,:,:)
259   ! (my_npert, nb, my_nq, nb, my_nk)
260   ! |g|^2 (local buffer). Allocated if cplex == 1
261 
262   integer :: coords_qkp(3)
263   ! Coordinates of this processor in the (q, k, pert) Cartesian grid.
264 
265   type(xcomm_t) :: kpt_comm
266    ! MPI communicator over k-points
267 
268   type(xcomm_t) :: qpt_comm
269    ! MPI communicator over q-points
270 
271   type(xcomm_t) :: pert_comm
272    ! MPI communicator over atomic perturbations.
273 
274   type(xcomm_t) :: qpt_pert_comm
275    ! MPI communicator over the 2d grid (qpt, atomic perturbations)
276 
277   type(xcomm_t) :: grid_comm
278    ! MPI communicator for full (q,k,pert) grid.
279 
280   real(dp),allocatable :: my_wnuq(:,:)
281   ! (my_npert, my_nq)
282   ! Phonon frequencies in Ha (MPI distributed)
283 
284   real(dp),allocatable :: my_displ_cart(:,:,:,:,:)
285   ! (2, 3, cryst%natom, my_npert, my_nq))
286   ! Phonon displacements (MPI distributed)
287 
288  contains
289 
290   procedure :: myqpt => gqk_myqpt
291   ! Return the q-point and the weight from my local index my_iq
292 
293   !procedure :: my_qweight => gqk_my_qweight
294   ! Return the q-point weight from my local index my_iq
295 
296   procedure :: dbldelta_qpt => gqk_dbldelta_qpt
297   ! Compute weights for the double delta.
298 
299   procedure :: free => gqk_free
300   ! Free memory
301 
302  end type gqk_t

m_gstore/gstore_calc_my_phonons [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_calc_my_phonons

FUNCTION

  Compute and store ph frequencies and optionally the displacements for all
  the q-points treated by this MPI rank.
  TODO: Rewrite this part, Read stuff from the IBZ and symmetrize.

INPUTS

OUTPUT

SOURCE

1948 subroutine gstore_calc_my_phonons(gstore, store_phdispl)
1949 
1950 !Arguments ------------------------------------
1951  class(gstore_t),target,intent(inout) :: gstore
1952  logical,intent(in) :: store_phdispl
1953 
1954 !Local variables-------------------------------
1955  integer :: my_is, my_iq, ierr
1956  real(dp) :: weight_q, cpu, wall, gflops, qpt(3)
1957  type(crystal_t),pointer :: cryst
1958  type(gqk_t),pointer :: gqk
1959  real(dp),allocatable :: phfrq(:), displ_cart(:,:,:,:)
1960 
1961 !----------------------------------------------------------------------
1962 
1963  call cwtime(cpu, wall, gflops, "start")
1964  cryst => gstore%cryst
1965 
1966  ABI_MALLOC(displ_cart, (2, 3, cryst%natom, 3 * cryst%natom))
1967  ABI_MALLOC(phfrq, (3 * cryst%natom))
1968 
1969  do my_is=1,gstore%my_nspins
1970    gqk => gstore%gqk(my_is)
1971 
1972    ABI_RECALLOC(gqk%my_wnuq, (gqk%my_npert, gqk%my_nq))
1973    if (store_phdispl) then
1974      ABI_RECALLOC(gqk%my_displ_cart, (2, 3, cryst%natom, gqk%my_npert, gqk%my_nq))
1975    end if
1976 
1977    do my_iq=1,gqk%my_nq
1978      if (gqk%kpt_comm%skip(my_iq)) cycle ! MPI parallelism inside kpt_comm
1979 
1980      ! Get phonon frequencies and eigenvectors for this q-point.
1981      ! FIXME: Perhaps it's better if we compute everything at q_ibz and then rotate
1982      ! so that we are guaranteed to have e(-q) == e(q)^*
1983      call gqk%myqpt(my_iq, gstore, weight_q, qpt)
1984      call gstore%ifc%fourq(cryst, qpt, phfrq, displ_cart)
1985 
1986      gqk%my_wnuq(:, my_iq) = phfrq(gqk%my_iperts(:))
1987      if (store_phdispl) gqk%my_displ_cart(:,:,:,:,my_iq) = displ_cart(:,:,:,gqk%my_iperts(:))
1988    end do
1989 
1990    ! Note that the computation is replicated across the perturbation communicator.
1991    ! This should not represent a problem since the phase in the displacement is fixed in dfpt_phfrq
1992    ! hence results should be coherent across different procs.
1993    call xmpi_sum(gqk%my_wnuq, gqk%kpt_comm%value, ierr)
1994    if (store_phdispl) call xmpi_sum(gqk%my_displ_cart, gqk%kpt_comm%value, ierr)
1995  end do ! my_is
1996 
1997  ABI_FREE(displ_cart)
1998  ABI_FREE(phfrq)
1999 
2000  call cwtime_report(" gstore_calc_my_phonons", cpu, wall, gflops)
2001 
2002 end subroutine gstore_calc_my_phonons

m_gstore/gstore_compute [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

  gstore_compute

FUNCTION

  Compute MPI-distributed e-ph matrix elements

INPUTS

 wk0_path=String with the path to the GS unperturbed WFK file.
 ngfft(18),ngfftf(18)=Coarse and Fine FFT meshes.
 dtset<dataset_type>=All input variables for this dataset.
 ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
 dvdb<dbdb_type>=Database with the DFPT SCF potentials.
 ifc<ifc_type>=interatomic force constants and corresponding real space grid info.
 pawfgr <type(pawfgr_type)>=fine grid parameters and related data
 pawang<pawang_type)>=PAW angular mesh and related data.
 pawrad(ntypat*usepaw)<pawrad_type>=Paw radial mesh and related data.
 pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
 psps<pseudopotential_type>=Variables related to pseudopotentials.
 comm=MPI communicator.

OUTPUT

SOURCE

2566 subroutine gstore_compute(gstore, wfk0_path, ngfft, ngfftf, dtset, cryst, ebands, dvdb, ifc, &
2567                           pawfgr, pawang, pawrad, pawtab, psps, mpi_enreg, comm)
2568 
2569 !Arguments ------------------------------------
2570 !scalars
2571  class(gstore_t),target,intent(inout) :: gstore
2572  character(len=*),intent(in) :: wfk0_path
2573  integer,intent(in) :: comm
2574  type(dataset_type),intent(in) :: dtset
2575  type(crystal_t),intent(in) :: cryst
2576  type(ebands_t),intent(in) :: ebands
2577  type(dvdb_t),intent(inout) :: dvdb
2578  type(pawang_type),intent(in) :: pawang
2579  type(pseudopotential_type),intent(in) :: psps
2580  type(pawfgr_type),intent(in) :: pawfgr
2581  type(ifc_type),intent(in) :: ifc
2582  type(mpi_type),intent(in) :: mpi_enreg
2583 !arrays
2584  integer,intent(in) :: ngfft(18),ngfftf(18)
2585  type(pawrad_type),intent(in) :: pawrad(psps%ntypat*psps%usepaw)
2586  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
2587 
2588 !Local variables ------------------------------
2589 !scalars
2590  integer,parameter :: tim_getgh1c = 1, berryopt0 = 0, ider0 = 0, idir0 = 0, LOG_MODQ = 5
2591  integer,parameter :: useylmgr = 0, useylmgr1 = 0, master = 0, ndat1 = 1
2592  integer :: my_rank,nproc,mband,nsppol,nkibz,idir,ipert,ebands_timrev, iq_bz
2593  integer :: cplex,natom,natom3,ipc,nspinor, nskip_tetra_kq
2594  integer :: bstart_k,bstart_kq,nband_k,nband_kq,band_k, ib_k, ib_kq !ib1,ib2, band_kq,
2595  integer :: ik_ibz,ikq_ibz,isym_k,isym_kq,trev_k,trev_kq
2596  integer :: my_ik, my_is, comm_rpt, my_npert, my_ip, my_iq, spin,istwf_k,istwf_kq,npw_k,npw_kq
2597  integer :: mpw, nb,ierr,cnt, n1,n2,n3,n4,n5,n6,nspden,ndone
2598  integer :: sij_opt,usecprj,usevnl,optlocal,optnl,opt_gvnlx1
2599  integer :: nfft,nfftf,mgfft,mgfftf, nkpg, nkpg1, qbuf_size, iqbuf_cnt, root_ncid, spin_ncid, ncerr
2600  integer :: ii, my_nqibz, iq_start, iq_ibz, isym_q, trev_q, prev_iqbz
2601  real(dp) :: cpu, wall, gflops, cpu_q, wall_q, gflops_q, cpu_all, wall_all, gflops_all
2602  real(dp) :: ecut, eshift, eig0nk, weight_q, weight_k
2603  logical :: gen_eigenpb, isirr_k, isirr_kq, isirr_q, print_time
2604  type(wfd_t) :: wfd
2605  type(gs_hamiltonian_type) :: gs_hamkq
2606  type(rf_hamiltonian_type) :: rf_hamkq
2607  type(ddkop_t) :: ddkop
2608  type(gqk_t),pointer :: gqk
2609  character(len=500) :: msg
2610 !arrays
2611  integer :: g0_k(3), g0_kq(3), g0_q(3), work_ngfft(18),gmax(3),indkk_kq(6,1)
2612  integer(i1b),allocatable :: itreat_qibz(:)
2613  integer,allocatable :: kg_k(:,:), kg_kq(:,:), nband(:,:), wfd_istwfk(:), qselect(:)
2614  integer,allocatable :: my_pinfo(:,:), pert_table(:,:)
2615  integer,allocatable :: iq_buf(:,:), done_qbz_spin(:,:), my_iqibz_inds(:)
2616  real(dp) :: kk_bz(3),kq_bz(3),kk_ibz(3),kq_ibz(3), qq_bz(3), qq_ibz(3), vk(3)
2617  real(dp) :: phfrq(3*cryst%natom), ylmgr_dum(1,1,1)
2618  real(dp),allocatable :: displ_cart_qibz(:,:,:,:), displ_red_qibz(:,:,:,:), pheigvec_qibz(:,:,:,:)
2619  real(dp),allocatable :: displ_cart_qbz(:,:,:,:), displ_red_qbz(:,:,:,:), pheigvec_qbz(:,:,:,:)
2620  real(dp),allocatable :: grad_berry(:,:), kinpw1(:), kpg1_k(:,:), kpg_k(:,:), dkinpw(:)
2621  real(dp),allocatable :: ffnlk(:,:,:,:), ffnl1(:,:,:,:), ph3d(:,:,:), ph3d1(:,:,:)
2622  real(dp),allocatable :: v1scf(:,:,:,:), gkk_atm(:,:,:,:),gkq_nu(:,:,:,:)
2623  real(dp),allocatable :: bras_kq(:,:,:), kets_k(:,:,:), h1kets_kq(:,:,:), cgwork(:,:)
2624  real(dp),allocatable :: ph1d(:,:), vlocal(:,:,:,:), vlocal1(:,:,:,:,:)
2625  real(dp),allocatable :: ylm_kq(:,:), ylm_k(:,:), ylmgr_kq(:,:,:)
2626  real(dp),allocatable :: dummy_vtrial(:,:), gvnlx1(:,:), work(:,:,:,:)
2627  real(dp),allocatable :: gs1c(:,:), vk_cart_ibz(:,:,:) !, vkmat_cart_ibz(:,:,:,:)
2628  real(dp),allocatable :: my_gbuf(:,:,:,:,:,:), buf_wqnu(:,:), buf_eigvec_cart(:,:,:,:,:)
2629  logical,allocatable :: bks_mask(:,:,:),keep_ur(:,:,:)
2630  type(pawcprj_type),allocatable  :: cwaveprj0(:,:)
2631 
2632 !************************************************************************
2633 
2634  ! This parameter defines the size of the q-buffer used to store the g(k, q) e-ph matrix elements
2635  ! for all the k-point treated by this MPI rank.
2636  ! Increasing the buffer size increases the memory requirements
2637  ! but it leads to better performance as the number of IO operations is decreased.
2638  ! TODO: Should compute it on the basis of my_nkpt and my_nqpt
2639  qbuf_size = 4
2640  call wrtout(std_out, sjoin(" Begin computation of e-ph matrix elements with qbuf_size:", itoa(qbuf_size)))
2641 
2642  if (psps%usepaw == 1) then
2643    ABI_ERROR("PAW not implemented")
2644    ABI_UNUSED((/pawang%nsym, pawrad(1)%mesh_size/))
2645  end if
2646 
2647  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
2648  call cwtime(cpu_all, wall_all, gflops_all, "start")
2649 
2650  ! Copy important dimensions
2651  natom = cryst%natom; natom3 = 3 * natom; nsppol = ebands%nsppol; nspinor = ebands%nspinor; nspden = dtset%nspden
2652  nkibz = ebands%nkpt; mband = ebands%mband
2653  ebands_timrev = kpts_timrev_from_kptopt(ebands%kptopt)
2654 
2655  ! FFT meshes
2656  nfftf = product(ngfftf(1:3)); mgfftf = maxval(ngfftf(1:3))
2657  nfft = product(ngfft(1:3)) ; mgfft = maxval(ngfft(1:3))
2658  n1 = ngfft(1); n2 = ngfft(2); n3 = ngfft(3)
2659  n4 = ngfft(4); n5 = ngfft(5); n6 = ngfft(6)
2660 
2661  ! Open the DVDB file
2662  call dvdb%open_read(ngfftf, xmpi_comm_self)
2663 
2664  do my_is=1,gstore%my_nspins
2665    spin = gstore%my_spins(my_is)
2666    gqk => gstore%gqk(my_is)
2667    if (gqk%pert_comm%nproc > 1) then
2668      ! Activate parallelism over perturbations
2669      ! Build table with list of perturbations treated by this CPU inside pert_comm
2670      ABI_WARNING("pert_comm%nproc > 1 not tested")
2671      call ephtk_set_pertables(cryst%natom, my_npert, pert_table, my_pinfo, gqk%pert_comm%value)
2672      call dvdb%set_pert_distrib(my_npert, natom3, my_pinfo, pert_table, gqk%pert_comm%value)
2673      ABI_CHECK(all(my_pinfo(3, :) == gqk%my_iperts), "my_pinfo(3, :) != gqk%my_iperts")
2674      ABI_FREE(my_pinfo)
2675      ABI_FREE(pert_table)
2676    end if
2677  end do
2678 
2679  !call wrtout([std_out, ab_out], " Cannot find eph_ngqpt_fine q-points in DVDB --> Activating Fourier interpolation.")
2680  ! Prepare Fourier interpolation of DFPT potentials.
2681  comm_rpt = xmpi_comm_self
2682  !comm_rpt = bqs_comm%value
2683  call dvdb%ftinterp_setup(dtset%ddb_ngqpt, gstore%qptopt, 1, dtset%ddb_shiftq, nfftf, ngfftf, comm_rpt)
2684 
2685  ! Build q-cache in the *dense* IBZ using the global mask qselect and itreat_qibz.
2686  ABI_MALLOC(itreat_qibz, (gstore%nqibz))
2687  ABI_MALLOC(qselect, (gstore%nqibz))
2688  qselect = 0; itreat_qibz = 0
2689  call dvdb%ftqcache_build(nfftf, ngfftf, gstore%nqibz, gstore%qibz, dtset%dvdb_qcache_mb, qselect, itreat_qibz, gstore%comm)
2690  ABI_FREE(itreat_qibz)
2691  ABI_FREE(qselect)
2692 
2693  ! Initialize the wave function descriptor.
2694  ! Only wavefunctions for the symmetrical imagine of the k/k+q wavevectors treated by this MPI rank are stored.
2695 
2696  ABI_MALLOC(nband, (nkibz, nsppol))
2697  ABI_MALLOC(bks_mask, (mband, nkibz, nsppol))
2698  ABI_MALLOC(keep_ur, (mband, nkibz, nsppol))
2699  nband = mband; bks_mask = .False.; keep_ur = .False.
2700 
2701  call gstore%fill_bks_mask(mband, nkibz, nsppol, bks_mask)
2702 
2703  ! Impose istwfk = 1 for all k-points. This is also done in respfn (see inkpts)
2704  ! wfd_read_wfk will handle a possible conversion if WFK contains istwfk /= 1.
2705  ABI_MALLOC(wfd_istwfk, (nkibz))
2706  wfd_istwfk = 1
2707  ecut = dtset%ecut
2708 
2709  call wfd_init(wfd, cryst, pawtab, psps, keep_ur, mband, nband, nkibz, nsppol, bks_mask,&
2710    nspden, nspinor, ecut, dtset%ecutsm, dtset%dilatmx, wfd_istwfk, ebands%kptns, ngfft,&
2711    dtset%nloalg, dtset%prtvol, dtset%pawprtvol, comm)
2712 
2713  call wfd%print(header="Wavefunctions for GSTORE calculation")
2714 
2715  ABI_FREE(nband)
2716  ABI_FREE(keep_ur)
2717  ABI_FREE(wfd_istwfk)
2718  ABI_FREE(bks_mask)
2719 
2720  ! Read wavefunctions.
2721  call wfd%read_wfk(wfk0_path, iomode_from_fname(wfk0_path))
2722 
2723  ! one-dimensional structure factor information on the coarse grid.
2724  ABI_MALLOC(ph1d, (2, 3*(2*mgfft+1)*natom))
2725  call getph(cryst%atindx, natom, n1, n2, n3, ph1d, cryst%xred)
2726 
2727  ! mpw is the maximum number of plane-waves over k and k+q where k and k+q are in the BZ.
2728  ! we also need the max components of the G-spheres (k, k+q) in order to allocate the workspace array work
2729  ! that will be used to symmetrize the wavefunctions in G-space.
2730  call gstore%get_mpw_gmax(ecut, mpw, gmax)
2731 
2732  ! Init work_ngfft
2733  gmax = gmax + 4 ! FIXME: this is to account for umklapp
2734  gmax = 2*gmax + 1
2735  call ngfft_seq(work_ngfft, gmax)
2736  !write(std_out,*)"work_ngfft(1:3): ",work_ngfft(1:3)
2737  ABI_MALLOC(work, (2, work_ngfft(4), work_ngfft(5), work_ngfft(6)))
2738 
2739  ! Allow PW-arrays dimensioned with mpw
2740  ABI_MALLOC(kg_k, (3, mpw))
2741  ABI_MALLOC(kg_kq, (3, mpw))
2742 
2743  ! Spherical Harmonics for useylm == 1.
2744  ABI_MALLOC(ylm_k, (mpw, psps%mpsang*psps%mpsang*psps%useylm))
2745  ABI_MALLOC(ylm_kq, (mpw, psps%mpsang*psps%mpsang*psps%useylm))
2746  ABI_MALLOC(ylmgr_kq, (mpw, 3, psps%mpsang*psps%mpsang*psps%useylm*useylmgr1))
2747 
2748  usecprj = 0
2749  ABI_MALLOC(cwaveprj0, (natom, nspinor*usecprj))
2750 
2751  ! Prepare call to getgh1c
2752  usevnl = 0
2753  optlocal = 1    ! local part of H^(1) is computed in gh1c=<G|H^(1)|C>
2754  optnl = 2       ! non-local part of H^(1) is totally computed in gh1c=<G|H^(1)|C>
2755  opt_gvnlx1 = 0  ! gvnlx1 is output
2756  ABI_MALLOC(gvnlx1, (2, usevnl))
2757  ABI_MALLOC(grad_berry, (2, nspinor*(berryopt0/4)))
2758 
2759  ! This part is taken from dfpt_vtorho
2760  !==== Initialize most of the Hamiltonian (and derivative) ====
2761  !1) Allocate all arrays and initialize quantities that do not depend on k and spin.
2762  !2) Perform the setup needed for the non-local factors:
2763  ! Norm-conserving: Constant kleimann-Bylander energies are copied from psps to gs_hamk.
2764  ! PAW: Initialize the overlap coefficients and allocate the Dij coefficients.
2765 
2766  call init_hamiltonian(gs_hamkq, psps, pawtab, nspinor, nsppol, nspden, natom, &
2767    dtset%typat, cryst%xred, nfft, mgfft, ngfft, cryst%rprimd, dtset%nloalg, &
2768    comm_atom=mpi_enreg%comm_atom, mpi_atmtab=mpi_enreg%my_atmtab, mpi_spintab=mpi_enreg%my_isppoltab, &
2769    usecprj=usecprj, ph1d=ph1d, nucdipmom=dtset%nucdipmom, gpu_option=dtset%gpu_option)
2770 
2771  ! Allocate vlocal. Note nvloc
2772  ! I set vlocal to huge to trigger possible bugs (DFPT routines should not access the data)
2773  ABI_MALLOC(vlocal, (n4, n5, n6, gs_hamkq%nvloc))
2774  vlocal = huge(one)
2775 
2776  ! Allocate work space arrays.
2777  ABI_MALLOC(displ_cart_qbz, (2, 3, cryst%natom, natom3))
2778  ABI_MALLOC(displ_cart_qibz, (2, 3, cryst%natom, natom3))
2779  ABI_MALLOC(displ_red_qbz, (2, 3, cryst%natom, natom3))
2780  ABI_MALLOC(displ_red_qibz, (2, 3, cryst%natom, natom3))
2781  ABI_MALLOC(pheigvec_qbz, (2, 3, cryst%natom, 3*cryst%natom))
2782  ABI_MALLOC(pheigvec_qibz, (2, 3, cryst%natom, 3*cryst%natom))
2783 
2784  ABI_CALLOC(dummy_vtrial, (nfftf, nspden))
2785 
2786  ! Create ddkop object to compute group velocities (if needed)
2787  ddkop = ddkop_new(dtset, cryst, pawtab, psps, wfd%mpi_enreg, mpw, wfd%ngfft)
2788 
2789  ! Open GSTORE file, and read table used for restarting.
2790  NCF_CHECK(nctk_open_modify(root_ncid, gstore%path, gstore%comm))
2791 
2792  ABI_MALLOC(done_qbz_spin, (gstore%nqbz, nsppol))
2793  NCF_CHECK(nf90_get_var(root_ncid, nctk_idname(root_ncid, "gstore_done_qbz_spin"), done_qbz_spin))
2794  gstore%wfk0_path = wfk0_path
2795  if (my_rank == master) then
2796    NCF_CHECK(nf90_put_var(root_ncid, root_vid("gstore_wfk0_path"), trim(gstore%wfk0_path)))
2797  end if
2798 
2799  if (my_rank == master) call gstore%print(std_out)
2800 
2801  ndone = count(done_qbz_spin == 1)
2802 
2803  ! NB: Write phonon data here as we are not guaranteed to have all the IBZ q-points
2804  ! inside the loop over my_iq if filtering has been used.
2805  ! TODO: Write phdata only if eph_task == -11
2806  if (ndone == 0) then
2807    call wrtout(std_out, " Computing phonon frequencies and displacements in the IBZ")
2808    call cwtime(cpu, wall, gflops, "start")
2809 
2810    call xmpi_split_block(gstore%nqibz, gstore%comm, my_nqibz, my_iqibz_inds)
2811    ABI_MALLOC(buf_wqnu, (natom3, my_nqibz))
2812    ABI_MALLOC(buf_eigvec_cart, (2, 3, natom, natom3, my_nqibz))
2813 
2814    do ii=1,my_nqibz
2815      iq_ibz = my_iqibz_inds(ii)
2816      !call ifc%fourq(cryst, gstore%qibz(:, iq_ibz), buf_wqnu(:,ii), buf_displ_cart(:,:,:,:,ii))
2817      call ifc%fourq(cryst, gstore%qibz(:, iq_ibz), buf_wqnu(:,ii), displ_cart_qibz, &
2818                     out_eigvec=buf_eigvec_cart(:,:,:,:,ii))
2819    end do
2820    if (nproc > 1 .and. gstore%nqibz >= nproc) then
2821      NCF_CHECK(nctk_set_collective(root_ncid, root_vid("phfreqs_ibz")))
2822      NCF_CHECK(nctk_set_collective(root_ncid, root_vid("pheigvec_cart_ibz")))
2823    end if
2824 
2825    if (my_nqibz > 0) then
2826      iq_start = my_iqibz_inds(1)
2827      ncerr = nf90_put_var(root_ncid, root_vid("phfreqs_ibz"), buf_wqnu, start=[1, iq_start], count=[natom3, my_nqibz])
2828      NCF_CHECK(ncerr)
2829      ncerr = nf90_put_var(root_ncid, root_vid("pheigvec_cart_ibz"), buf_eigvec_cart, &
2830                           start=[1,1,1,1,iq_start], count=[2, 3, natom, natom3, my_nqibz])
2831      NCF_CHECK(ncerr)
2832    end if
2833 
2834    ABI_FREE(my_iqibz_inds)
2835    ABI_FREE(buf_wqnu)
2836    ABI_FREE(buf_eigvec_cart)
2837    call cwtime_report(" phonon computation + output", cpu, wall, gflops)
2838  else
2839    call wrtout(std_out, &
2840                sjoin(" Restarting GSTORE calculation. Found: ", itoa(ndone), " (qpt, spin) entries already computed"))
2841  end if
2842 
2843  if (gstore%with_vk /= 0 .and. ndone == 0) then
2844    call wrtout(std_out, " Computing and writing velocity operator matrix elements in the IBZ")
2845    call wrtout(std_out, " Note that not all the k-points in the IBZ are computed when kfilter is activated!")
2846    call cwtime(cpu, wall, gflops, "start")
2847 
2848    ! On disk, we have:
2849    !
2850    !    nctkarr_t("vk_cart_ibz", "dp", "three, nb, gstore_nkibz"))
2851    !    nctkarr_t("vkmat_cart_ibz", "dp", "two, three, nb, nb, gstore_nkibz")))
2852 
2853    ABI_MALLOC(cgwork, (2, mpw*wfd%nspinor))
2854 
2855    do my_is=1,gstore%my_nspins
2856      spin = gstore%my_spins(my_is)
2857      gqk => gstore%gqk(my_is)
2858 
2859      if (gstore%with_vk == 1) then
2860        ABI_CALLOC(vk_cart_ibz, (3, gqk%nb, gstore%nkibz))
2861      else
2862        ABI_ERROR("with_vk 2")
2863      end if
2864 
2865      cnt = 0
2866      do my_ik=1,gqk%my_nk
2867        ! The k-point and the symmetries relating the BZ k-point to the IBZ.
2868        kk_bz = gqk%my_kpts(:, my_ik)
2869        weight_k = gqk%my_wtk(my_ik)
2870 
2871        ik_ibz = gqk%my_k2ibz(1, my_ik); isym_k = gqk%my_k2ibz(2, my_ik)
2872        trev_k = gqk%my_k2ibz(6, my_ik); g0_k = gqk%my_k2ibz(3:5,my_ik)
2873        isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
2874        if (.not. isirr_k) cycle
2875 
2876        ! parallelize inside (q, pert) so that only one proc in the 3D grid
2877        ! computes vk for this kpt in the BZ and we can use xmpi_sum_master.
2878        cnt = cnt + 1
2879        if (gqk%qpt_pert_comm%skip(cnt)) cycle
2880 
2881        kk_ibz = ebands%kptns(:,ik_ibz)
2882        npw_k = wfd%npwarr(ik_ibz); istwf_k = wfd%istwfk(ik_ibz)
2883        call ddkop%setup_spin_kpoint(dtset, cryst, psps, spin, kk_ibz, istwf_k, npw_k, wfd%kdata(ik_ibz)%kg_k)
2884 
2885        select case (gstore%with_vk)
2886        case (1)
2887          do ib_k=1,gqk%nb
2888            band_k = ib_k + gqk%bstart - 1
2889            call wfd%copy_cg(band_k, ik_ibz, spin, cgwork)
2890            vk = ddkop%get_vdiag(ebands%eig(band_k, ik_ibz, spin), istwf_k, npw_k, wfd%nspinor, cgwork, cwaveprj0)
2891            vk_cart_ibz(:, ib_k, ik_ibz) = vk
2892          end do
2893 
2894        case (2)
2895          ABI_ERROR("with_vk 2")
2896          !do ib_k=1,nband_k
2897          !  band_k = ib_k + bstart_k - 1
2898          !end do
2899        end select
2900      end do ! my_ik
2901 
2902      call xmpi_sum_master(vk_cart_ibz, master, gqk%grid_comm%value, ierr)
2903      if (gqk%grid_comm%me == master) then
2904        NCF_CHECK(nf90_inq_ncid(root_ncid, strcat("gqk", "_spin", itoa(spin)), spin_ncid))
2905        NCF_CHECK(nf90_put_var(spin_ncid, spin_vid("vk_cart_ibz"), vk_cart_ibz))
2906      end if
2907      ABI_SFREE(vk_cart_ibz)
2908    end do ! my_is
2909 
2910    ABI_FREE(cgwork)
2911    call cwtime_report(sjoin(" Computation of v_k group velocities with with_vk:", itoa(gstore%with_vk)), cpu, wall, gflops)
2912  end if
2913 
2914  ! Loop over my spins.
2915  do my_is=1,gstore%my_nspins
2916    spin = gstore%my_spins(my_is)
2917    gqk => gstore%gqk(my_is)
2918    my_npert = gqk%my_npert
2919    NCF_CHECK(nf90_inq_ncid(root_ncid, strcat("gqk", "_spin", itoa(spin)), spin_ncid))
2920 
2921    ! Allocate workspace for wavefunctions using mpw and nb
2922    nb = gqk%nb
2923    ABI_MALLOC(bras_kq, (2, mpw*nspinor, nb))
2924    ABI_MALLOC(kets_k, (2, mpw*nspinor, nb))
2925    ABI_MALLOC(h1kets_kq, (2, mpw*nspinor, nb))
2926    ABI_MALLOC(gkk_atm, (2, nb, nb, natom3))
2927    ABI_MALLOC(gkq_nu, (2, nb, nb, natom3))
2928    ABI_MALLOC(iq_buf, (2, qbuf_size))
2929 
2930    ! Inside the loops we compute gkq_nu(2, nb, nb, natom3)
2931    ABI_MALLOC_OR_DIE(my_gbuf, (gqk%cplex, nb, nb, natom3, gqk%my_nk, qbuf_size), ierr)
2932 
2933    ! Loop over my set of q-points
2934    prev_iqbz = -1
2935    do my_iq=1,gqk%my_nq
2936      print_time = my_rank == 0 .and. (my_iq <= LOG_MODQ .or. mod(my_iq, LOG_MODQ) == 0)
2937      if (print_time) call cwtime(cpu_q, wall_q, gflops_q, "start")
2938      iq_bz = gqk%my_q2bz(my_iq)
2939      if (done_qbz_spin(iq_bz, spin) == 1) cycle
2940 
2941      call gqk%myqpt(my_iq, gstore, weight_q, qq_bz)
2942 
2943      iq_ibz = gqk%my_q2ibz(1, my_iq); isym_q = gqk%my_q2ibz(2, my_iq)
2944      trev_q = gqk%my_q2ibz(6, my_iq); g0_q = gqk%my_q2ibz(3:5,my_iq)
2945      ! Don't test if umklapp == 0 because we use the periodic gauge:
2946      !
2947      !      phfreq(q+G) = phfreq(q) and eigvec(q) = eigvec(q+G)
2948      !
2949      !isirr_q = (isym_q == 1 .and. trev_q == 0 .and. all(g0_q == 0))
2950      isirr_q = (isym_q == 1 .and. trev_q == 0)
2951      qq_ibz = gstore%qibz(:, iq_ibz)
2952 
2953      nskip_tetra_kq = 0
2954      iqbuf_cnt = 1 + mod(my_iq - 1, qbuf_size)
2955      iq_buf(:, iqbuf_cnt) = [my_iq, iq_bz]
2956 
2957      if (iq_ibz /= prev_iqbz) then
2958        ! Get phonon frequencies and eigenvectors for the corresponding q-point in the IBZ.
2959        call ifc%fourq(cryst, qq_ibz, phfrq, displ_cart_qibz, out_displ_red=displ_red_qibz, out_eigvec=pheigvec_qibz)
2960        prev_iqbz = iq_ibz
2961      end if
2962 
2963      if (isirr_q) then
2964        displ_cart_qbz = displ_cart_qibz; displ_red_qbz = displ_red_qibz; pheigvec_qbz = pheigvec_qibz
2965      else
2966        ! Rotate phonon eigenvectors from q_ibz to q_bz.
2967        ! This part is needed to enforce the gauge in the ph eigenvectors, including e(-q) = e(q)^*
2968        call pheigvec_rotate(cryst, qq_ibz, isym_q, trev_q, pheigvec_qibz, pheigvec_qbz, displ_cart_qbz, &
2969                             displ_red_qbz=displ_red_qbz)
2970      end if
2971 
2972      !call ifc%fourq(cryst, qq_bz, phfrq, displ_cart_qbz, out_displ_red=displ_red_qbz, out_eigvec=pheigvec_qbz))
2973      ! Use Fourier interpolation of DFPT potentials to get my_npert potentials.
2974      !cplex = 2
2975      !ABI_MALLOC(v1scf, (cplex, nfft, nspden, dvdb%my_npert))
2976      !call dvdb%ftinterp_qpt(qq_bz, nfftf, ngfftf, v1scf, dvdb%comm_rpt)
2977 
2978      ! Version with qcache.
2979      call dvdb%get_ftqbz(cryst, qq_bz, qq_ibz, gqk%my_q2ibz(:, my_iq), cplex, nfftf, ngfftf, v1scf, &
2980                          gqk%pert_comm%value)
2981 
2982      ! Allocate vlocal1 with correct cplex. Note nvloc and my_npert.
2983      ABI_MALLOC(vlocal1, (cplex*n4, n5, n6, gs_hamkq%nvloc, my_npert))
2984 
2985      ! Set up local potential vlocal1 with proper dimensioning from vtrial1 taking into account the spin.
2986      do my_ip=1,my_npert
2987        call rf_transgrid_and_pack(spin, nspden, psps%usepaw, cplex, nfftf, nfft, ngfft, gs_hamkq%nvloc,&
2988                  pawfgr, mpi_enreg, dummy_vtrial, v1scf(:,:,:,my_ip), vlocal, vlocal1(:,:,:,:,my_ip))
2989      end do
2990 
2991      ! Continue to initialize the GS Hamiltonian
2992      call gs_hamkq%load_spin(spin, vlocal=vlocal, with_nonlocal=.true.)
2993 
2994      ! Loop over my k-points
2995      do my_ik=1,gqk%my_nk
2996        ! Set entry to zero. Important as there are cycle instructions inside these loops
2997        ! and we don't want to write random numbers to disk.
2998        my_gbuf(:,:,:,:, my_ik, iqbuf_cnt) = zero
2999 
3000        ! The k-point and the symmetries relating the BZ k-point to the IBZ.
3001        kk_bz = gqk%my_kpts(:, my_ik)
3002        weight_k = gqk%my_wtk(my_ik)
3003 
3004        ik_ibz = gqk%my_k2ibz(1, my_ik); isym_k = gqk%my_k2ibz(2, my_ik)
3005        trev_k = gqk%my_k2ibz(6, my_ik); g0_k = gqk%my_k2ibz(3:5,my_ik)
3006        isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
3007        kk_ibz = ebands%kptns(:,ik_ibz)
3008 
3009        ! Number of bands crossing the Fermi level at k
3010        !bstart_k = fs%bstart_cnt_ibz(1, ik_ibz); nband_k = fs%bstart_cnt_ibz(2, ik_ibz)
3011        bstart_k = gqk%bstart; nband_k = gqk%nb
3012 
3013        ! ============================================
3014        ! Find symmetrical image of k+q in in the kIBZ
3015        ! ============================================
3016        kq_bz = kk_bz + qq_bz
3017 
3018        if (kpts_map("symrel", ebands_timrev, cryst, gstore%krank_ibz, 1, kq_bz, indkk_kq) /= 0) then
3019          write(msg, '(3a)' ) &
3020           "Cannot find k+q in kmesh", ch10, 'Action: check your WFK file and the (k, q) point input variables.'
3021           ABI_ERROR(msg)
3022        end if
3023 
3024        ikq_ibz = indkk_kq(1, 1); isym_kq = indkk_kq(2, 1)
3025        trev_kq = indkk_kq(6, 1); g0_kq = indkk_kq(3:5, 1)
3026        isirr_kq = (isym_kq == 1 .and. trev_kq == 0 .and. all(g0_kq == 0))
3027        kq_ibz = ebands%kptns(:, ikq_ibz)
3028 
3029        ! If we have used the KERANGE trick, we may have k or k+q points with just one G component set to zero
3030        ! so we skip this transition immediately. This should happen only if fsewin > sigma_erange.
3031        if (wfd%npwarr(ik_ibz) == 1 .or. wfd%npwarr(ikq_ibz) == 1) cycle
3032 
3033        if (gstore%kfilter == "fs_tetra") then
3034          ! Check tetra delta(e_{k+q}) and cycle if all the weights at k+q are zero.
3035          if (all(abs(gstore%delta_ef_kibz_spin(:, ikq_ibz, spin)) == zero)) then
3036            nskip_tetra_kq = nskip_tetra_kq + 1; cycle
3037          end if
3038        end if
3039 
3040        ! Number of bands crossing the Fermi level at k+q
3041        !bstart_kq = fs%bstart_cnt_ibz(1, ikq_ibz); nband_kq = fs%bstart_cnt_ibz(2, ikq_ibz)
3042        bstart_kq = gqk%bstart; nband_kq = gqk%nb
3043        ABI_CHECK(nband_k <= nb .and. nband_kq <= nb, "wrong nband")
3044 
3045        ! Get npw_k, kg_k and symmetrize wavefunctions from IBZ (if needed).
3046        call wfd%sym_ug_kg(ecut, kk_bz, kk_ibz, bstart_k, nband_k, spin, mpw, gqk%my_k2ibz(:, my_ik), cryst, &
3047                           work_ngfft, work, istwf_k, npw_k, kg_k, kets_k)
3048 
3049        ! Get npw_kq, kg_kq and symmetrize wavefunctions from IBZ (if needed).
3050        call wfd%sym_ug_kg(ecut, kq_bz, kq_ibz, bstart_kq, nband_kq, spin, mpw, indkk_kq(:,1), cryst, &
3051                           work_ngfft, work, istwf_kq, npw_kq, kg_kq, bras_kq)
3052 
3053        ! if PAW, one has to solve a generalized eigenproblem
3054        ! Be careful here because I will need sij_opt==-1
3055        gen_eigenpb = psps%usepaw == 1; sij_opt = 0; if (gen_eigenpb) sij_opt = 1
3056        ABI_MALLOC(gs1c, (2, npw_kq*nspinor*((sij_opt+1)/2)))
3057 
3058        ! Set up the spherical harmonics (Ylm) at k and k+q. See also dfpt_looppert
3059        !if (psps%useylm == 1) then
3060        !   optder = 0; if (useylmgr == 1) optder = 1
3061        !   call initylmg(cryst%gprimd, kg_k, kk_bz, mkmem1, mpi_enreg, psps%mpsang, mpw, nband, mkmem1,&
3062        !     [npw_k], dtset%nsppol, optder, cryst%rprimd, ylm_k, ylmgr)
3063        !   call initylmg(cryst%gprimd, kg_kq, kq_bz, mkmem1, mpi_enreg, psps%mpsang, mpw, nband, mkmem1,&
3064        !     [npw_kq], dtset%nsppol, optder, cryst%rprimd, ylm_kq, ylmgr_kq)
3065        !end if
3066 
3067        ! Compute k+G vectors
3068        nkpg = 3 * dtset%nloalg(3)
3069        ABI_MALLOC(kpg_k, (npw_k, nkpg))
3070        if (nkpg > 0) call mkkpg(kg_k, kpg_k, kk_bz, nkpg, npw_k)
3071 
3072        ! Compute nonlocal form factors ffnlk at (k+G)
3073        ABI_MALLOC(ffnlk, (npw_k, 1, psps%lmnmax, psps%ntypat))
3074        call mkffnl_objs(cryst, psps, 1, ffnlk, ider0, idir0, kg_k, kpg_k, kk_bz, nkpg, npw_k, ylm_k, ylmgr_dum, &
3075                         comm=gqk%pert_comm%value) !, request=ffnlk_request)
3076 
3077        ! Compute k+q+G vectors
3078        nkpg1 = 3 * dtset%nloalg(3)
3079        ABI_MALLOC(kpg1_k, (npw_kq, nkpg1))
3080        if (nkpg1 > 0) call mkkpg(kg_kq, kpg1_k, kq_bz, nkpg1, npw_kq)
3081 
3082        ! Compute nonlocal form factors ffnl1 at (k+q+G)
3083        ABI_MALLOC(ffnl1, (npw_kq, 1, psps%lmnmax, psps%ntypat))
3084        call mkffnl_objs(cryst, psps, 1, ffnl1, ider0, idir0, kg_kq, kpg1_k, kq_bz, nkpg1, npw_kq, ylm_kq, ylmgr_kq, &
3085                         comm=gqk%pert_comm%value) ! request=ffnl1_request)
3086 
3087        ! Loop over my atomic perturbations and compute gkk_atm.
3088        gkk_atm = zero
3089        do my_ip=1,my_npert
3090          idir = dvdb%my_pinfo(1, my_ip); ipert = dvdb%my_pinfo(2, my_ip); ipc = dvdb%my_pinfo(3, my_ip)
3091 
3092          ! Prepare application of the NL part.
3093          call init_rf_hamiltonian(cplex, gs_hamkq, ipert, rf_hamkq, has_e1kbsc=.true.)
3094 
3095          call rf_hamkq%load_spin(spin, vlocal1=vlocal1(:,:,:,:,my_ip), with_nonlocal=.true.)
3096 
3097          ! This call is not optimal because there are quantities in out that do not depend on idir,ipert
3098          call getgh1c_setup(gs_hamkq, rf_hamkq, dtset, psps, kk_bz, kq_bz, idir, ipert, &             ! In
3099                             cryst%natom, cryst%rmet, cryst%gprimd, cryst%gmet, istwf_k, &             ! In
3100                             npw_k, npw_kq, useylmgr1, kg_k, ylm_k, kg_kq, ylm_kq, ylmgr_kq, &         ! In
3101                             dkinpw, nkpg, nkpg1, kpg_k, kpg1_k, kinpw1, ffnlk, ffnl1, ph3d, ph3d1, &  ! Out
3102                             reuse_kpg_k=1, reuse_kpg1_k=1, reuse_ffnlk=1, reuse_ffnl1=1)              ! Reuse some arrays
3103 
3104          ! Calculate dvscf * psi_k, results stored in h1kets_kq on the k+q sphere.
3105          ! Compute H(1) applied to GS wavefunction Psi(0)
3106          do ib_k=1,nband_k
3107            band_k = ib_k + bstart_k - 1
3108            eig0nk = ebands%eig(band_k, ik_ibz, spin)
3109            ! Use scissor shift on 0-order eigenvalue
3110            eshift = eig0nk - dtset%dfpt_sciss
3111 
3112            call getgh1c(berryopt0, kets_k(:,:,ib_k), cwaveprj0, h1kets_kq(:,:,ib_k), &
3113                         grad_berry, gs1c, gs_hamkq, gvnlx1, idir, ipert, eshift, mpi_enreg, optlocal, &
3114                         optnl, opt_gvnlx1, rf_hamkq, sij_opt, tim_getgh1c, usevnl)
3115          end do
3116 
3117          call rf_hamkq%free()
3118          ABI_FREE(kinpw1)
3119          ABI_FREE(dkinpw)
3120          ABI_FREE(ph3d)
3121          ABI_SFREE(ph3d1)
3122 
3123          ! Calculate elphmat(j,i) = <psi_{k+q,j}|dvscf_q*psi_{k,i}> for this perturbation.
3124          ! No need to handle istwf_kq because it's always 1.
3125          do ib_k=1,nband_k
3126            do ib_kq=1,nband_kq
3127              gkk_atm(:, ib_kq, ib_k, ipc) = cg_zdotc(npw_kq*nspinor, bras_kq(1,1,ib_kq), h1kets_kq(1,1,ib_k))
3128            end do
3129          end do
3130 
3131        end do ! my_ip
3132 
3133        ABI_FREE(gs1c)
3134        ABI_FREE(ffnlk)
3135        ABI_FREE(ffnl1)
3136        ABI_FREE(kpg1_k)
3137        ABI_FREE(kpg_k)
3138 
3139        ! Collect gkk_atm inside pert_comm so that all procs can operate on the data.
3140        if (gqk%pert_comm%nproc > 1) call xmpi_sum(gkk_atm, gqk%pert_comm%value, ierr)
3141 
3142        ! Get g in the phonon representation.
3143        call ephtk_gkknu_from_atm(nb, nb, 1, natom, gkk_atm, phfrq, displ_red_qbz, gkq_nu)
3144 
3145        ! Save e-ph matrix elements in the buffer.
3146        select case (gqk%cplex)
3147        case (1)
3148          my_gbuf(1,:,:,:, my_ik, iqbuf_cnt) = gkq_nu(1,:,:,:) ** 2 + gkq_nu(2,:,:,:) ** 2
3149        case (2)
3150          my_gbuf(:,:,:,:, my_ik, iqbuf_cnt) = gkq_nu
3151        end select
3152      end do ! my_ik
3153 
3154      ABI_FREE(v1scf)
3155      ABI_FREE(vlocal1)
3156 
3157      ! Dump buffers
3158      if (iqbuf_cnt == qbuf_size) call dump_data()
3159 
3160      if (print_time) then
3161        write(msg,'(2(a,i0),a)')" My q-point [", my_iq, "/", gqk%my_nq, "]"
3162        call cwtime_report(msg, cpu_q, wall_q, gflops_q); if (my_iq == LOG_MODQ) call wrtout(std_out, "...", do_flush=.True.)
3163      end if
3164      !if (my_rank == master) then
3165      !  ! Print cache stats.
3166      !  !call dvdb%ft_qcache%report_stats()
3167      !end if
3168    end do ! my_iq
3169 
3170    ! Dump the remainder.
3171    if (iqbuf_cnt /= 0) call dump_data()
3172 
3173    ABI_FREE(iq_buf)
3174    ABI_FREE(my_gbuf)
3175    ABI_FREE(bras_kq)
3176    ABI_FREE(kets_k)
3177    ABI_FREE(h1kets_kq)
3178    ABI_FREE(gkk_atm)
3179    ABI_FREE(gkq_nu)
3180  end do ! my_is
3181 
3182  call cwtime_report(" GSTORE computation done", cpu_all, wall_all, gflops_all, pre_str=ch10, end_str=ch10) !, comm=gstore%comm)
3183  call gstore%print(std_out, header="GSTORE at the end of gstore%compute")
3184 
3185  !call xmpi_barrier(gstore%comm)
3186  NCF_CHECK(nf90_close(root_ncid))
3187 
3188  ! Free memory
3189  ABI_FREE(gvnlx1)
3190  ABI_FREE(grad_berry)
3191  ABI_FREE(dummy_vtrial)
3192  ABI_FREE(work)
3193  ABI_FREE(ph1d)
3194  ABI_FREE(vlocal)
3195  ABI_FREE(kg_k)
3196  ABI_FREE(kg_kq)
3197  ABI_FREE(ylm_k)
3198  ABI_FREE(ylm_kq)
3199  ABI_FREE(ylmgr_kq)
3200  ABI_FREE(displ_cart_qbz)
3201  ABI_FREE(displ_cart_qibz)
3202  ABI_FREE(displ_red_qbz)
3203  ABI_FREE(displ_red_qibz)
3204  ABI_FREE(pheigvec_qbz)
3205  ABI_FREE(pheigvec_qibz)
3206  ABI_FREE(done_qbz_spin)
3207 
3208  call pawcprj_free(cwaveprj0)
3209  ABI_FREE(cwaveprj0)
3210  call ddkop%free()
3211  call gs_hamkq%free()
3212  call wfd%free()
3213 
3214 contains
3215 
3216 subroutine dump_data()
3217 
3218  ! This function is called inside the double loop over (my_is, my_iq) or when we exit
3219  ! from the my_iq loop to dump the remainder that is still in the q-buffer,
3220  ! All the MPI procs in the (kpt_comm x pert_comm) grid shall call this contained routine
3221  ! as we have side-effects i.e. iqbuf_cnt set to 0.
3222 
3223  ! On disk we have the global arrays:
3224  !
3225  !      nctkarr_t("gvals", "dp", "gstore_cplex, nb, nb, natom3, glob_nk, glob_nq")
3226  !
3227  ! while the local MPI buffers are dimensioned as follows:
3228  !
3229  !      my_gbuf(2, nb, nb, natom3, gqk%my_nk, qbuf_size)
3230 
3231  ! If parallelism over pertubation is activated, only the procs treating the first perturbation
3232  ! i.e. the procs treating different k-points for this q are involved in IO
3233  ! as all the local buffers store results for all natom3 pertubations.
3234 
3235  integer :: ii, iq_bz, iq_glob, my_iq
3236 
3237  if (gqk%coords_qkp(3) /= 0) goto 10 ! Yes, I'm very proud of this GOTO.
3238 
3239  !iq_buf(:, iqbuf_cnt) = [my_iq, iq_bz]
3240  my_iq = iq_buf(1, 1)
3241  iq_glob = my_iq + gqk%my_qstart - 1
3242 
3243  ! NB: this is an individual IO operation
3244  ncerr = nf90_put_var(spin_ncid, spin_vid("gvals"), my_gbuf, &
3245                       start=[1, 1, 1, 1, gqk%my_kstart, iq_glob], &
3246                       count=[gqk%cplex, gqk%nb, gqk%nb, gqk%natom3, gqk%my_nk, iqbuf_cnt] &
3247                      )
3248  NCF_CHECK(ncerr)
3249 
3250  ! Only one proc sets the entry in done_qbz_spin to 1 for all the q-points in the buffer.
3251  if (all(gqk%coords_qkp(2:3) == [0, 0]))  then
3252    do ii=1,iqbuf_cnt
3253      iq_bz = iq_buf(2, ii)
3254      NCF_CHECK(nf90_put_var(root_ncid, root_vid("gstore_done_qbz_spin"), 1, start=[iq_bz, spin]))
3255    end do
3256  end if
3257 
3258  ! Zero the counter before returning
3259 10 iqbuf_cnt = 0
3260 
3261 end subroutine dump_data
3262 
3263 integer function root_vid(vname)
3264   character(len=*),intent(in) :: vname
3265   root_vid = nctk_idname(root_ncid, vname)
3266 end function root_vid
3267 
3268 integer function spin_vid(vname)
3269   character(len=*),intent(in) :: vname
3270   spin_vid = nctk_idname(spin_ncid, vname)
3271 end function spin_vid
3272 
3273 end subroutine gstore_compute

m_gstore/gstore_distribute_spins [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_distribute_spins

FUNCTION

INPUTS

OUTPUT

SOURCE

 956 subroutine gstore_distribute_spins(gstore, mband, gstore_brange, nproc_spin, comm_spin, comm)
 957 
 958 !Arguments ------------------------------------
 959 !scalars
 960  class(gstore_t),target,intent(inout) :: gstore
 961  integer,intent(in) :: mband, comm, gstore_brange(2, gstore%nsppol)
 962  integer,intent(out) :: nproc_spin(gstore%nsppol), comm_spin(gstore%nsppol)
 963 
 964 !Local variables-------------------------------
 965 !scalars
 966  integer :: spin, my_rank, ierr, color, nsppol, all_nproc
 967 !arrays
 968  integer :: buff_spin(2)
 969 !----------------------------------------------------------------------
 970 
 971  all_nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
 972  nsppol = gstore%nsppol
 973 
 974  gstore%my_nspins = 0
 975  ABI_MALLOC(gstore%brange_spin, (2, nsppol))
 976 
 977  do spin=1,nsppol
 978    ! NB: If MPI_UNDEFINED is passed as the colour value, the subgroup in which the calling
 979    ! MPI process will be placed is MPI_COMM_NULL
 980    color = 1
 981    if (nsppol == 2 .and. all_nproc > 1) then
 982      color = xmpi_undefined
 983      if (spin == 1 .and. my_rank <= (all_nproc - 1) / 2) color = 1
 984      if (spin == 2 .and. my_rank > (all_nproc - 1) / 2) color = 1
 985    end if
 986 
 987    call xmpi_comm_split(comm, color, my_rank, comm_spin(spin), ierr)
 988    if (comm_spin(spin) /= xmpi_undefined) then
 989      gstore%my_nspins = gstore%my_nspins + 1
 990      buff_spin(gstore%my_nspins) = spin
 991    end if
 992 
 993    nproc_spin(spin) = xmpi_comm_size(comm_spin(spin))
 994 
 995    gstore%brange_spin(:, spin) = [1, mband]
 996    if (all(gstore_brange /= 0)) gstore%brange_spin(:, spin) = gstore_brange(:, spin)
 997 
 998    ABI_CHECK_IRANGE(gstore%brange_spin(1, spin), 1, mband, "gstore_brange(1, spin)")
 999    ABI_CHECK_IRANGE(gstore%brange_spin(2, spin), 1, mband, "gstore_brange(2, spin)")
1000    ABI_CHECK(gstore%brange_spin(1, spin) <= gstore%brange_spin(2, spin), "brange_spin(1, spin) <= brange_spin(2, spin)")
1001  end do
1002 
1003  ABI_MALLOC(gstore%my_spins, (gstore%my_nspins))
1004  gstore%my_spins = buff_spin(1:gstore%my_nspins)
1005  ABI_MALLOC(gstore%gqk, (gstore%my_nspins))
1006 
1007 end subroutine gstore_distribute_spins

m_gstore/gstore_fill_bks_mask [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_fill_bks_mask

FUNCTION

  Fills the bks_mask array defining the set of states that should be read from file
  by this MPI rank when computing the e-ph matrix elements.

INPUTS

OUTPUT

SOURCE

1786 subroutine gstore_fill_bks_mask(gstore, mband, nkibz, nsppol, bks_mask)
1787 
1788 !Arguments ------------------------------------
1789  class(gstore_t),target,intent(inout) :: gstore
1790  integer,intent(in) :: mband, nkibz, nsppol
1791  logical,intent(out) :: bks_mask(mband, nkibz, nsppol)
1792 
1793 !Local variables-------------------------------
1794 !scalars
1795  integer :: my_is, my_ik, my_iq, spin, ik_ibz, iqk_ibz, ebands_timrev
1796  real(dp) :: weight_q, cpu, wall, gflops
1797  type(gqk_t),pointer :: gqk
1798  type(crystal_t),pointer :: cryst
1799 !arrays
1800  integer,allocatable :: map_kq(:,:)
1801  real(dp) :: qpt(3)
1802 
1803 !----------------------------------------------------------------------
1804 
1805  call cwtime(cpu, wall, gflops, "start")
1806 
1807  bks_mask = .False.
1808  cryst => gstore%cryst
1809 
1810  ebands_timrev = kpts_timrev_from_kptopt(gstore%ebands%kptopt)
1811 
1812  do my_is=1,gstore%my_nspins
1813    gqk => gstore%gqk(my_is)
1814    spin = gstore%my_spins(my_is)
1815 
1816    ! We need the image of this k in the IBZ.
1817    do my_ik=1,gqk%my_nk
1818      ik_ibz = gqk%my_k2ibz(1, my_ik)
1819      bks_mask(gqk%bstart:gqk%bstart + gqk%nb - 1, ik_ibz, spin) = .True.
1820    end do
1821 
1822    ! as well as the image of k+q in the IBZ.
1823    ABI_MALLOC(map_kq, (6, gqk%my_nk))
1824 
1825    do my_iq=1,gqk%my_nq
1826      call gqk%myqpt(my_iq, gstore, weight_q, qpt)
1827 
1828      if (kpts_map("symrel", ebands_timrev, cryst, gstore%krank_ibz, gqk%my_nk, gqk%my_kpts, map_kq, qpt=qpt) /= 0) then
1829        ABI_ERROR(sjoin("Cannot map k+q to IBZ with qpt:", ktoa(qpt)))
1830      end if
1831 
1832      do my_ik=1,gqk%my_nk
1833        iqk_ibz = map_kq(1, my_ik)
1834        bks_mask(gqk%bstart:gqk%bstop, iqk_ibz, spin) = .True.
1835      end do
1836    end do
1837 
1838    ABI_FREE(map_kq)
1839  end do
1840 
1841  call cwtime_report(" gstore_fill_bks_mask", cpu, wall, gflops)
1842 
1843 end subroutine gstore_fill_bks_mask

m_gstore/gstore_filter_erange__ [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_filter_erange__

FUNCTION

 Filter k-points and q-points according to an energy range.

INPUTS

OUTPUT

SOURCE

1526 subroutine gstore_filter_erange__(gstore, qbz, qbz2ibz, qibz2bz, kbz, kibz, kbz2ibz, kibz2bz, &
1527                                   select_qbz_spin, select_kbz_spin)
1528 
1529 !Arguments ------------------------------------
1530 !scalars
1531  class(gstore_t),target,intent(inout) :: gstore
1532  real(dp),intent(in) :: qbz(3, gstore%nqbz)
1533  real(dp),target,intent(in) :: kbz(3, gstore%nqbz), kibz(3, gstore%nkibz)
1534  integer,intent(in) :: qbz2ibz(6,gstore%nqbz), qibz2bz(gstore%nqibz)
1535  integer,intent(in) :: kbz2ibz(6,gstore%nkbz), kibz2bz(gstore%nkibz)
1536  integer,intent(out) :: select_qbz_spin(gstore%nqbz, gstore%nsppol)
1537  integer,intent(out) :: select_kbz_spin(gstore%nkbz, gstore%nsppol)
1538 
1539 !Local variables-------------------------------
1540 !scalars
1541  integer,parameter :: tetra_opt0 = 0
1542  integer :: nsppol, cnt, spin, ii, all_nproc, my_rank, comm, ebands_timrev, band ! ierr,
1543  integer :: ik_bz, ik_ibz, iflag, nk_in_star, gap_err
1544  logical :: assume_gap
1545  real(dp) :: ee, abs_erange1, abs_erange2, vmax, cmin
1546  type(ebands_t),pointer :: ebands
1547  type(crystal_t),pointer :: cryst
1548  type(gaps_t) :: gaps
1549 !arrays
1550  integer,allocatable :: kstar_bz_inds(:)
1551 !----------------------------------------------------------------------
1552 
1553  comm = gstore%comm
1554  all_nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
1555 
1556  ! filter k and k + q points according to erange and define gstore%brange_spin automatically.
1557  ! NB: here we recompute brange_spin
1558  call wrtout(std_out, sjoin(" Filtering k-points using gstore_erange:", &
1559                             ltoa(reshape(gstore%erange_spin, [2 * gstore%nsppol]) * Ha_eV), "(eV)"))
1560 
1561  cryst => gstore%cryst; ebands => gstore%ebands; nsppol = gstore%nsppol
1562 
1563  assume_gap = .not. all(gstore%erange_spin < zero)
1564  gaps = ebands_get_gaps(ebands, gap_err)
1565  if (assume_gap) call gaps%print(unit=std_out) !, header=msg)
1566 
1567  ebands_timrev = kpts_timrev_from_kptopt(ebands%kptopt)
1568 
1569  select_kbz_spin = 0; cnt = 0
1570 
1571  do spin=1,nsppol
1572    gstore%brange_spin(:, spin) = [huge(1), -huge(1)]
1573    abs_erange1 = abs(gstore%erange_spin(1, spin))
1574    abs_erange2 = abs(gstore%erange_spin(2, spin))
1575 
1576    if (assume_gap) then
1577      ! Get CBM and VBM with some tolerance
1578      vmax = gaps%vb_max(spin) + tol2 * eV_Ha
1579      cmin = gaps%cb_min(spin) - tol2 * eV_Ha
1580    else
1581      vmax = ebands%fermie
1582      cmin = ebands%fermie
1583    end if
1584 
1585    do band=1, ebands%mband
1586      do ik_ibz=1,gstore%nkibz
1587        !cnt = cnt + 1; if (mod(cnt, all_nproc) /= my_rank) cycle ! MPI parallelism inside comm
1588 
1589        ! Use iflag to filter k-points.
1590        ee = ebands%eig(band, ik_ibz, spin)
1591        iflag = 0
1592 
1593        if (abs_erange1 > zero) then
1594          if (ee <= vmax .and. vmax - ee <= abs_erange1) then
1595            iflag = 1 !; write(std_out, *), "Adding valence band", band, " with ee [eV]: ", ee * Ha_eV
1596          end if
1597        end if
1598        if (abs_erange2 > zero) then
1599          if (ee >= cmin .and. ee - cmin <= abs_erange2) then
1600            iflag = 1 !; write(std_out, *)"Adding conduction band", band, " with ee [eV]: ", ee * Ha_eV
1601          end if
1602        end if
1603 
1604        if (iflag == 1) then
1605          gstore%brange_spin(1, spin) = min(gstore%brange_spin(1, spin), band)
1606          gstore%brange_spin(2, spin) = max(gstore%brange_spin(2, spin), band)
1607 
1608          select case (gstore%kzone)
1609          case ("ibz")
1610            ik_bz = kibz2bz(ik_ibz)
1611            select_kbz_spin(ik_bz, spin) = iflag
1612 
1613          case ("bz")
1614            call star_from_ibz_idx(ik_ibz, gstore%nkbz, kbz2ibz, nk_in_star, kstar_bz_inds)
1615            ABI_CHECK(nk_in_star > 0, "Something wrong in star_from_ibz_idx")
1616            do ii=1,nk_in_star
1617              ik_bz = kstar_bz_inds(ii)
1618              select_kbz_spin(ik_bz, spin) = iflag
1619            end do
1620            ABI_FREE(kstar_bz_inds)
1621          end select
1622        end if
1623 
1624      end do ! band
1625    end do ! ik_ibz
1626 
1627    !call wrtout(std_out, sjoin("brange_spin:", ltoa(gstore%brange_spin(:, spin))))
1628    !call wrtout(std_out, sjoin("count_select_kbz:", itoa(count(select_kbz_spin == 1))))
1629 
1630    if (any(gstore%brange_spin(:, spin) == [huge(1), -huge(1)])) then
1631      ABI_ERROR("Empty list of states inside gstore_erange")
1632    end if
1633  end do ! spin
1634 
1635  !call xmpi_sum(select_kbz_spin, comm, ierr)
1636  call recompute_select_qbz_spin(gstore, qbz, qbz2ibz, qibz2bz, kbz, kibz, kbz2ibz, kibz2bz, &
1637                                 select_kbz_spin, select_qbz_spin)
1638 
1639  call gaps%free()
1640 
1641 end subroutine gstore_filter_erange__

m_gstore/gstore_filter_fs_tetra__ [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_filter_fs_tetra__

FUNCTION

  Compute delta(e_k - e_F) with the tetrahedron method. Use weights to filter k-points.
  Include only those q-points such that there exists at least one k on the FS with k + q on the FS.
  Also, store and precompute gstore%delta_ef_kibz_spin(max_nb, gstore%nkibz, nsppol)
  to be used to filter inside gstore%compute.

INPUTS

OUTPUT

SOURCE

1395 subroutine gstore_filter_fs_tetra__(gstore, qbz, qbz2ibz, qibz2bz, kbz, kibz, kbz2ibz, kibz2bz, &
1396                                     select_qbz_spin, select_kbz_spin)
1397 
1398 !Arguments ------------------------------------
1399 !scalars
1400  class(gstore_t),target,intent(inout) :: gstore
1401  real(dp),intent(in) :: qbz(3, gstore%nqbz)
1402  real(dp),target,intent(in) :: kbz(3, gstore%nqbz), kibz(3, gstore%nkibz)
1403  integer,intent(in) :: qbz2ibz(6,gstore%nqbz), qibz2bz(gstore%nqibz)
1404  integer,intent(in) :: kbz2ibz(6,gstore%nkbz), kibz2bz(gstore%nkibz)
1405  integer,intent(out) :: select_qbz_spin(gstore%nqbz, gstore%nsppol)
1406  integer,intent(out) :: select_kbz_spin(gstore%nkbz, gstore%nsppol)
1407 
1408 !Local variables-------------------------------
1409 !scalars
1410  integer,parameter :: tetra_opt0 = 0
1411  integer :: nsppol, ierr, cnt, spin, band, ib, ii, max_nb, all_nproc, my_rank, comm, ebands_timrev
1412  integer :: ik_bz, ik_ibz, iflag, nk_in_star
1413  real(dp) :: max_occ
1414  character(len=80) :: errorstring
1415  type(ebands_t),pointer :: ebands
1416  type(crystal_t),pointer :: cryst
1417  type(htetra_t) :: ktetra
1418 !arrays
1419  integer,allocatable :: indkk(:), kstar_bz_inds(:)
1420  real(dp):: rlatt(3,3), klatt(3,3), delta_theta_ef(2) ! qpt(3),
1421  real(dp),allocatable :: eig_ibz(:)
1422 !----------------------------------------------------------------------
1423 
1424  comm = gstore%comm
1425  all_nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
1426 
1427  ! Use the tetrahedron method to filter k- and k+q points on the FS in metals
1428  ! and define gstore%brange_spin automatically.
1429  call wrtout(std_out, sjoin(" Filtering k-points using:", gstore%kfilter))
1430 
1431  ! NB: here we recompute brange_spin
1432  cryst => gstore%cryst
1433  ebands => gstore%ebands
1434  nsppol = gstore%nsppol
1435 
1436  ebands_timrev = kpts_timrev_from_kptopt(ebands%kptopt)
1437 
1438  call ebands_get_bands_e0(ebands, ebands%fermie, gstore%brange_spin, ierr)
1439  ABI_CHECK(ierr == 0, "Error in ebands_get_bands_e0")
1440 
1441  ABI_MALLOC(indkk, (gstore%nkbz))
1442  indkk(:) = kbz2ibz(1, :)
1443 
1444  rlatt = ebands%kptrlatt; call matr3inv(rlatt, klatt)
1445  call htetra_init(ktetra, indkk, gstore%cryst%gprimd, klatt, kbz, gstore%nkbz, gstore%kibz, gstore%nkibz, &
1446                   ierr, errorstring, gstore%comm)
1447  ABI_CHECK(ierr == 0, errorstring)
1448 
1449  ABI_MALLOC(eig_ibz, (gstore%nkibz))
1450  max_occ = two / (ebands%nspinor * nsppol)
1451  select_kbz_spin = 0
1452 
1453  max_nb = maxval(gstore%brange_spin(2, :) - gstore%brange_spin(1, :) + 1)
1454  ABI_CALLOC(gstore%delta_ef_kibz_spin, (max_nb, gstore%nkibz, gstore%nsppol))
1455 
1456  cnt = 0
1457  do spin=1,nsppol
1458    do band=gstore%brange_spin(1, spin), gstore%brange_spin(2, spin)
1459      ib = band - gstore%brange_spin(1, spin) + 1
1460      eig_ibz = ebands%eig(band, :, spin)
1461 
1462      do ik_ibz=1,gstore%nkibz
1463        cnt = cnt + 1; if (mod(cnt, all_nproc) /= my_rank) cycle ! MPI parallelism inside comm
1464 
1465        call ktetra%get_onewk_wvals(ik_ibz, tetra_opt0, 1, [ebands%fermie], max_occ, &
1466                                    gstore%nkibz, eig_ibz, delta_theta_ef)
1467 
1468        gstore%delta_ef_kibz_spin(ib, ik_ibz, spin) = delta_theta_ef(1)
1469 
1470        iflag = merge(1, 0, abs(delta_theta_ef(1)) > zero)
1471 
1472        ! Use iflag to filter k-points.
1473        select case (gstore%kzone)
1474        case ("ibz")
1475          ik_bz = kibz2bz(ik_ibz)
1476          select_kbz_spin(ik_bz, spin) = select_kbz_spin(ik_bz, spin) + iflag
1477 
1478        case ("bz")
1479          call star_from_ibz_idx(ik_ibz, gstore%nkbz, kbz2ibz, nk_in_star, kstar_bz_inds)
1480          ABI_CHECK(nk_in_star > 0, "Something wrong in star_from_ibz_idx")
1481          do ii=1,nk_in_star
1482            ik_bz = kstar_bz_inds(ii)
1483            select_kbz_spin(ik_bz, spin) = select_kbz_spin(ik_bz, spin) + iflag
1484          end do
1485          ABI_FREE(kstar_bz_inds)
1486        end select
1487      end do
1488 
1489    end do
1490  end do
1491 
1492  !call ktetra%print(std_out)
1493 
1494  call xmpi_sum(select_kbz_spin, comm, ierr)
1495  call xmpi_sum(gstore%delta_ef_kibz_spin, comm, ierr)
1496 
1497  ! Now the tricky part as we want to remove q-points that
1498  ! do not lead to any scattering process between two states on the FS
1499  ! Remember that k+q is always a sub-mesh of the input ebands k-mesh.
1500 
1501  call recompute_select_qbz_spin(gstore, qbz, qbz2ibz, qibz2bz, kbz, kibz, kbz2ibz, kibz2bz, &
1502                                 select_kbz_spin, select_qbz_spin)
1503 
1504  ABI_FREE(eig_ibz)
1505  ABI_FREE(indkk)
1506  call ktetra%free()
1507 
1508 end subroutine gstore_filter_fs_tetra__

m_gstore/gstore_free [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_free

FUNCTION

  Free dynamic memory.

SOURCE

2190 subroutine gstore_free(gstore)
2191 
2192 !Arguments ------------------------------------
2193  class(gstore_t),intent(inout) :: gstore
2194 
2195 !Local variables-------------------------------
2196  integer :: my_is
2197 !----------------------------------------------------------------------
2198 
2199  do my_is=1,gstore%my_nspins
2200    call gstore%gqk(my_is)%free()
2201  end do
2202  ABI_SFREE(gstore%gqk)
2203 
2204  ABI_SFREE(gstore%delta_ef_kibz_spin)
2205  ABI_SFREE(gstore%qibz)
2206  ABI_SFREE(gstore%wtq)
2207  ABI_SFREE(gstore%my_spins)
2208  ABI_SFREE(gstore%brange_spin)
2209  ABI_SFREE(gstore%glob_nk_spin)
2210  ABI_SFREE(gstore%glob_nq_spin)
2211  ABI_SFREE(gstore%erange_spin)
2212 
2213  call gstore%krank_ibz%free()
2214 
2215 end subroutine gstore_free

m_gstore/gstore_from_ncpath [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_from_ncpath

FUNCTION

  Reconstruct a gstore object from a GSTORE.nc netcdf file.

INPUTS

SOURCE

3289 subroutine gstore_from_ncpath(gstore, path, with_cplex, dtset, cryst, ebands, ifc, comm)
3290 
3291 !Arguments ------------------------------------
3292  class(gstore_t),target,intent(out) :: gstore
3293  character(len=*),intent(in) :: path
3294  integer,intent(in) :: with_cplex
3295  type(dataset_type),intent(in) :: dtset
3296  integer,intent(in) :: comm
3297  class(crystal_t),target,intent(in) :: cryst
3298  class(ebands_t),target,intent(in) :: ebands
3299  class(ifc_type),target,intent(in) :: ifc
3300 
3301 !Local variables-------------------------------
3302 !scalars
3303  integer,parameter :: master = 0
3304  integer :: my_rank, ncid, spin, spin_ncid, nproc, ierr, fform, max_nb, ib, natom, natom3
3305  integer :: max_nq, max_nk, gstore_cplex, ncerr, my_is, my_iq, iq_glob, my_ik, ik_glob, my_ip, ipert
3306  integer :: iq_ibz, isym_q, trev_q, tsign_q, g0_q(3)
3307  real(dp) :: cpu, wall, gflops
3308  character(len=10) :: priority
3309  logical :: store_phdispl, isirr_q
3310  type(hdr_type) :: wfk0_hdr
3311  type(crystal_t) :: gstore_cryst
3312  type(gqk_t),pointer :: gqk
3313 !arrays
3314  integer :: ibuffer(9), nproc_spin(ebands%nsppol), comm_spin(ebands%nsppol), brange_spin(2, ebands%nsppol)
3315  integer,allocatable :: qglob2bz(:,:), kglob2bz(:,:), qbz2ibz(:,:), kbz2ibz(:,:)
3316  real(dp) :: qq_ibz(3)
3317  real(dp),allocatable :: gwork_q(:,:,:,:,:), slice_bb(:,:,:)
3318  real(dp),allocatable :: phfreqs_ibz(:,:), pheigvec_cart_ibz(:,:,:,:,:)
3319  real(dp),allocatable :: pheigvec_cart_qbz(:,:,:,:), displ_cart_qbz(:,:,:,:)
3320 
3321 ! *************************************************************************
3322 
3323  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
3324 
3325  ! Set basic parameters.
3326  gstore%comm = comm
3327  gstore%nsppol = dtset%nsppol
3328  gstore%path = path
3329 
3330  ! Get references to other data structures.
3331  gstore%cryst => cryst
3332  gstore%ebands => ebands
3333  gstore%ifc => ifc
3334  gstore%kibz => ebands%kptns
3335  natom = cryst%natom
3336  natom3 = cryst%natom * 3
3337 
3338  ABI_CALLOC(gstore%erange_spin, (2, gstore%nsppol))
3339  ABI_MALLOC(gstore%glob_nk_spin, (gstore%nsppol))
3340  ABI_MALLOC(gstore%glob_nq_spin, (gstore%nsppol))
3341 
3342  ! =======================================================
3343  ! Master node reads basic objects and gstore dimensions
3344  ! =======================================================
3345 
3346  if (my_rank == master) then
3347    call wrtout([std_out, ab_out], sjoin(" Initializing gstore object from:", path, ch10))
3348    ABI_CHECK(path /= ABI_NOFILE, "Use getgstore_filepath to specify the path to GSTORE.nc")
3349    NCF_CHECK(nctk_open_read(ncid, path, xmpi_comm_self))
3350    !NCF_CHECK(cryst%ncwrite(ncid))
3351 
3352    ! TODO Should compare ebands_file with input ebands
3353    !NCF_CHECK(ebands_ncwrite(ebands, ncid))
3354 
3355    call hdr_ncread(wfk0_hdr, ncid, fform)
3356    ABI_CHECK(fform /= 0, sjoin("Error while reading:", path))
3357 
3358    ! Read gstore dimensions
3359    NCF_CHECK(nctk_get_dim(ncid, "gstore_cplex", gstore_cplex))
3360    NCF_CHECK(nctk_get_dim(ncid, "gstore_nkibz", gstore%nkibz))
3361    NCF_CHECK(nctk_get_dim(ncid, "gstore_nkbz", gstore%nkbz))
3362    NCF_CHECK(nctk_get_dim(ncid, "gstore_nqibz", gstore%nqibz))
3363    NCF_CHECK(nctk_get_dim(ncid, "gstore_nqbz", gstore%nqbz))
3364    NCF_CHECK(nctk_get_dim(ncid, "gstore_max_nq", max_nq))
3365    NCF_CHECK(nctk_get_dim(ncid, "gstore_max_nk", max_nk))
3366    NCF_CHECK(nctk_get_dim(ncid, "gstore_max_nb", max_nb))
3367 
3368    ! Read gstore variables
3369    NCF_CHECK(nf90_get_var(ncid, vid("gstore_with_vk"), gstore%with_vk))
3370    NCF_CHECK(nf90_get_var(ncid, vid("gstore_qptopt"), gstore%qptopt))
3371    NCF_CHECK(nf90_get_var(ncid, vid("gstore_kzone"), gstore%kzone))
3372    call replace_ch0(gstore%kzone)
3373    NCF_CHECK(nf90_get_var(ncid, vid("gstore_qzone"), gstore%qzone))
3374    call replace_ch0(gstore%qzone)
3375    NCF_CHECK(nf90_get_var(ncid, vid("gstore_kfilter"), gstore%kfilter))
3376    call replace_ch0(gstore%kfilter)
3377    NCF_CHECK(nf90_get_var(ncid, vid("gstore_wfk0_path"), gstore%wfk0_path))
3378    call replace_ch0(gstore%wfk0_path)
3379 
3380    ABI_MALLOC(gstore%qibz, (3, gstore%nqibz))
3381    ABI_MALLOC(gstore%wtq, (gstore%nqibz))
3382    NCF_CHECK(nf90_get_var(ncid, vid("gstore_brange_spin"), brange_spin))
3383    NCF_CHECK(nf90_get_var(ncid, vid("gstore_erange_spin"), gstore%erange_spin))
3384    NCF_CHECK(nf90_get_var(ncid, vid("gstore_qibz"), gstore%qibz))
3385    NCF_CHECK(nf90_get_var(ncid, vid("gstore_wtq"), gstore%wtq))
3386 
3387    ABI_MALLOC(qbz2ibz, (6, gstore%nqbz))
3388    ABI_MALLOC(kbz2ibz, (6, gstore%nkbz))
3389    NCF_CHECK(nf90_get_var(ncid, vid("gstore_qbz2ibz"), qbz2ibz))
3390    NCF_CHECK(nf90_get_var(ncid, vid("gstore_kbz2ibz"), kbz2ibz))
3391 
3392    ABI_MALLOC(qglob2bz, (max_nq, gstore%nsppol))
3393    ABI_MALLOC(kglob2bz, (max_nk, gstore%nsppol))
3394    NCF_CHECK(nf90_get_var(ncid, vid("gstore_qglob2bz"), qglob2bz))
3395    NCF_CHECK(nf90_get_var(ncid, vid("gstore_kglob2bz"), kglob2bz))
3396    NCF_CHECK(nf90_get_var(ncid, vid("gstore_glob_nq_spin"), gstore%glob_nq_spin))
3397    NCF_CHECK(nf90_get_var(ncid, vid("gstore_glob_nk_spin"), gstore%glob_nk_spin))
3398 
3399    ! Read optional variables:
3400    if (gstore%kfilter == "fs_tetra") then
3401      ABI_MALLOC(gstore%delta_ef_kibz_spin, (max_nb, gstore%nkibz, gstore%nsppol))
3402      NCF_CHECK(nf90_get_var(ncid, vid("gstore_delta_ef_kibz_spin"), gstore%delta_ef_kibz_spin))
3403    end if
3404 
3405    NCF_CHECK(nf90_close(ncid))
3406 
3407    ! =================
3408    ! Consistency check
3409    ! =================
3410    gstore_cryst = wfk0_hdr%get_crystal()
3411    !call gstore_cryst%print(header="crystal structure from WFK file")
3412 
3413    if (cryst%compare(gstore_cryst, header=" Comparing input crystal with the one from GSTORE file") /= 0) then
3414      ABI_ERROR("Crystal structure from input and GSTORE do not agree! Check messages above!")
3415    end if
3416    call gstore_cryst%free()
3417 
3418    if (gstore_cplex == 1 .and. with_cplex == 2) then
3419      ABI_ERROR("GSTORE file contains |g| while Abinit needs complex g. Regenerate GSTORE file with gstore_cplex 2")
3420    end if
3421  end if ! master
3422 
3423  if (nproc > 1) then
3424    ! Broadcast the header.
3425    call wfk0_hdr%bcast(master, my_rank, comm)
3426 
3427    ! Broadcast dimensions.
3428    if (my_rank == master) then
3429      ibuffer = [gstore_cplex, gstore%nkibz, gstore%nkbz, gstore%nqibz, gstore%nqbz, &
3430                 gstore%with_vk, max_nq, max_nk, max_nb]
3431    end if
3432    call xmpi_bcast(ibuffer, master, comm, ierr)
3433 
3434    if (my_rank /= master) then
3435      ! Other MPI procs need to store dims and allocate memory before the bcast.
3436      gstore_cplex = ibuffer(1)
3437      gstore%nkibz = ibuffer(2)
3438      gstore%nkbz = ibuffer(3)
3439      gstore%nqibz = ibuffer(4)
3440      gstore%nqbz = ibuffer(5)
3441      gstore%with_vk = ibuffer(6)
3442      max_nq = ibuffer(7)
3443      max_nk = ibuffer(8)
3444      max_nb = ibuffer(9)
3445 
3446      ABI_MALLOC(gstore%qibz, (3, gstore%nqibz))
3447      ABI_MALLOC(gstore%wtq, (gstore%nqibz))
3448      ABI_MALLOC(qbz2ibz, (6, gstore%nqbz))
3449      ABI_MALLOC(kbz2ibz, (6, gstore%nkbz))
3450      ABI_MALLOC(qglob2bz, (max_nq, gstore%nsppol))
3451      ABI_MALLOC(kglob2bz, (max_nk, gstore%nsppol))
3452    end if
3453 
3454    call xmpi_bcast(gstore%qptopt, master, comm, ierr)
3455    call xmpi_bcast(gstore%kzone, master, comm, ierr)
3456    call xmpi_bcast(gstore%qzone, master, comm, ierr)
3457    call xmpi_bcast(gstore%kfilter, master, comm, ierr)
3458    call xmpi_bcast(gstore%wfk0_path, master, comm, ierr)
3459    call xmpi_bcast(brange_spin, master, comm, ierr)
3460    call xmpi_bcast(gstore%erange_spin, master, comm, ierr)
3461    call xmpi_bcast(gstore%qibz, master, comm, ierr)
3462    call xmpi_bcast(gstore%wtq, master, comm, ierr)
3463    call xmpi_bcast(qbz2ibz, master, comm, ierr)
3464    call xmpi_bcast(kbz2ibz, master, comm, ierr)
3465    call xmpi_bcast(qglob2bz, master, comm, ierr)
3466    call xmpi_bcast(kglob2bz, master, comm, ierr)
3467    call xmpi_bcast(gstore%glob_nq_spin, master, comm, ierr)
3468    call xmpi_bcast(gstore%glob_nk_spin, master, comm, ierr)
3469 
3470    if (gstore%kfilter == "fs_tetra") then
3471      if (my_rank /= master) then
3472        ABI_MALLOC(gstore%delta_ef_kibz_spin, (max_nb, gstore%nkibz, gstore%nsppol))
3473      end if
3474      call xmpi_bcast(gstore%delta_ef_kibz_spin, master, comm, ierr)
3475    end if
3476 
3477  end if
3478 
3479  ! Construct crystal and ebands from the GS WFK file.
3480  !ebands_file = wfk_read_ebands(wfk0_path, comm, out_hdr=wfk0_hdr)
3481  call wfk0_hdr%vs_dtset(dtset)
3482  call wfk0_hdr%free()
3483 
3484  ! Distribute spins, create indirect mapping to spin index and init gstore%brange_spin
3485  call gstore%distribute_spins__(ebands%mband, brange_spin, nproc_spin, comm_spin, comm)
3486 
3487  ! Compute krank
3488  gstore%krank_ibz = krank_from_kptrlatt(gstore%nkibz, gstore%kibz, ebands%kptrlatt, compute_invrank=.False.)
3489 
3490  ! Set MPI grid. Also define priority according to eph_task.
3491  call priority_from_eph_task(dtset%eph_task, priority)
3492 
3493  call gstore%set_mpi_grid__(with_cplex, dtset%eph_np_pqbks, priority, nproc_spin, comm_spin)
3494 
3495  ! At this point, we have the Cartesian grid (one per spin if any)
3496  ! and we can finally allocate and distribute other arrays.
3497  call gstore%malloc__(with_cplex, max_nq, qglob2bz, max_nk, kglob2bz, qbz2ibz, kbz2ibz)
3498 
3499  ABI_FREE(qglob2bz)
3500  ABI_FREE(kglob2bz)
3501  ABI_FREE(qbz2ibz)
3502  ABI_FREE(kbz2ibz)
3503 
3504  call xmpi_comm_free(comm_spin)
3505 
3506  ! Now we read the big arrays with MPI-IO and hdf5 groups.
3507  ! Note the loop over spin as each gqk has its own dimensions.
3508  ! Recall the shape on the arrays:
3509  !
3510  ! In memory, we have allocated:
3511  !
3512  !    my_g(my_npert, nb, my_nq, nb, my_nk) if with_cplex == 2 (complex array)
3513  !
3514  ! or
3515  !
3516  !    my_g2(my_npert, nb, my_nq, nb, my_nk) if with_cplex == 1
3517  !
3518  ! On disk, we have:
3519  !
3520  !   nctkarr_t("gvals", "dp", "gstore_cplex, nb, nb, natom3, glob_nk, glob_nq")
3521  !
3522  ! so gstore_cplex == 1 and with_cplex == 2 are not compatible.
3523  !
3524  call cwtime(cpu, wall, gflops, "start")
3525 
3526  ! ========================================
3527  ! Load phonon frequencies and eigenvectors
3528  ! ========================================
3529 
3530  ! nctkarr_t("phfreqs_ibz", "dp", "natom3, gstore_nqibz")
3531  ! nctkarr_t("pheigvec_cart_ibz", "dp", "two, three, natom, natom3, gstore_nqibz")
3532  ABI_MALLOC(phfreqs_ibz, (natom3, gstore%nqibz))
3533  ABI_MALLOC(pheigvec_cart_ibz, (2, 3, cryst%natom, cryst%natom * 3, gstore%nqibz))
3534  ABI_MALLOC(pheigvec_cart_qbz, (2, 3, cryst%natom, cryst%natom * 3))
3535  ABI_MALLOC(displ_cart_qbz, (2, 3, cryst%natom, cryst%natom * 3))
3536 
3537  NCF_CHECK(nctk_open_read(ncid, gstore%path, gstore%comm))
3538 
3539  if (nproc > 1) then
3540    NCF_CHECK(nctk_set_collective(ncid, vid("phfreqs_ibz")))
3541  end if
3542  NCF_CHECK(nf90_get_var(ncid, vid("phfreqs_ibz"), phfreqs_ibz))
3543  if (nproc > 1) then
3544    NCF_CHECK(nctk_set_collective(ncid, vid("pheigvec_cart_ibz")))
3545  end if
3546  NCF_CHECK(nf90_get_var(ncid, vid("pheigvec_cart_ibz"), pheigvec_cart_ibz))
3547  NCF_CHECK(nf90_close(ncid))
3548 
3549  store_phdispl = .True.
3550  do my_is=1,gstore%my_nspins
3551    gqk => gstore%gqk(my_is)
3552 
3553    ABI_MALLOC(gqk%my_wnuq, (gqk%my_npert, gqk%my_nq))
3554    if (store_phdispl) then
3555      ABI_MALLOC(gqk%my_displ_cart, (2, 3, cryst%natom, gqk%my_npert, gqk%my_nq))
3556    end if
3557 
3558    do my_iq=1,gqk%my_nq
3559      iq_ibz = gqk%my_q2ibz(1, my_iq); isym_q = gqk%my_q2ibz(2, my_iq)
3560      trev_q = gqk%my_q2ibz(6, my_iq); g0_q = gqk%my_q2ibz(3:5, my_iq)
3561      !isirr_q = (isym_q == 1 .and. trev_q == 0 .and. all(g0_q == 0))
3562      isirr_q = (isym_q == 1 .and. trev_q == 0)
3563      tsign_q = 1; if (trev_q == 1) tsign_q = -1
3564      qq_ibz = gstore%qibz(:, iq_ibz)
3565      call pheigvec_rotate(cryst, qq_ibz, isym_q, trev_q, pheigvec_cart_ibz(:,:,:,:,iq_ibz), &
3566                           pheigvec_cart_qbz, displ_cart_qbz)
3567 
3568      gqk%my_wnuq(:, my_iq) = phfreqs_ibz(gqk%my_iperts(:), iq_ibz)
3569      if (store_phdispl) gqk%my_displ_cart(:,:,:,:,my_iq) = displ_cart_qbz(:,:,:,gqk%my_iperts(:))
3570    end do ! my_iq
3571  end do ! my_is
3572 
3573  ABI_FREE(phfreqs_ibz)
3574  ABI_SFREE(pheigvec_cart_ibz)
3575  ABI_SFREE(displ_cart_qbz)
3576  ABI_FREE(pheigvec_cart_qbz)
3577 
3578  do spin=1,gstore%nsppol
3579    my_is = gstore%spin2my_is(spin)
3580 
3581    if (my_is /= 0) then
3582      gqk => gstore%gqk(my_is)
3583 
3584      NCF_CHECK(nctk_open_read(ncid, gstore%path, gqk%grid_comm%value))
3585      NCF_CHECK(nf90_inq_ncid(ncid, strcat("gqk", "_spin", itoa(spin)), spin_ncid))
3586 
3587      !NCF_CHECK(nf90_get_var(spin_ncid, spin_vid("bstart"), gqk%bstart))
3588      !NCF_CHECK(nf90_get_var(spin_ncid, spin_vid("bstop"), gqk%bstop))
3589 
3590      ! gstore_cplex defines the data on disk while
3591      ! cplex defines what we want to store in memory
3592      ABI_MALLOC_OR_DIE(gwork_q, (gstore_cplex, gqk%nb, gqk%nb, gqk%natom3, gqk%glob_nk), ierr)
3593      ABI_MALLOC(slice_bb, (gstore_cplex, gqk%nb, gqk%nb))
3594 
3595      do my_iq=1,gqk%my_nq
3596         iq_glob = my_iq + gqk%my_qstart - 1
3597 
3598         ! Read q-slice (individual IO)
3599         ncerr = nf90_get_var(spin_ncid, spin_vid("gvals"), gwork_q, start=[1, 1, 1, 1, 1, iq_glob]) ! count=[])
3600         NCF_CHECK(ncerr)
3601 
3602         do my_ik=1,gqk%my_nk
3603           ik_glob = my_ik + gqk%my_kstart - 1
3604           do my_ip=1,gqk%my_npert
3605             ipert = gqk%my_iperts(my_ip)
3606             slice_bb = gwork_q(:,:,:, ipert, ik_glob)
3607 
3608             ! Put data in the right place and handle conversion g --> |g|^2
3609             if (with_cplex == gstore_cplex) then
3610               if (with_cplex == 1) gqk%my_g2(my_ip,:,my_iq,:,my_ik) = slice_bb(1,:,:)
3611               if (with_cplex == 2) gqk%my_g(my_ip,:,my_iq,:,my_ik) = slice_bb(1,:,:) + j_dpc * slice_bb(2,:,:)
3612             else
3613               if (with_cplex == 1 .and. gstore_cplex == 2) then
3614                 gqk%my_g2(my_ip, :, my_iq, :, my_ik) = slice_bb(1,:,:) ** 2 + slice_bb(2,:,:) ** 2
3615               else
3616                 ABI_ERROR("Conversion from g2 on file to g_cplx in memory is not possible!")
3617               end if
3618             end if
3619 
3620           end do
3621         end do
3622 
3623      end do ! my_iq
3624 
3625      ABI_FREE(gwork_q)
3626      ABI_FREE(slice_bb)
3627 
3628      ! ==============================================
3629      ! Read matrix elements of the velocity operator
3630      ! ==============================================
3631      if (gstore%with_vk == 1) then
3632        if (gqk%grid_comm%nproc > 1) then
3633          NCF_CHECK(nctk_set_collective(spin_ncid, spin_vid("vk_cart_ibz")))
3634        end if
3635        NCF_CHECK(nf90_get_var(spin_ncid, spin_vid("vk_cart_ibz"), gqk%vk_cart_ibz))
3636 
3637      else if (gstore%with_vk == 2) then
3638        if (gqk%grid_comm%nproc > 1) then
3639          NCF_CHECK(nctk_set_collective(spin_ncid, spin_vid("vkmat_cart_ibz")))
3640        end if
3641        NCF_CHECK(nf90_get_var(spin_ncid, spin_vid("vkmat_cart_ibz"), gqk%vkmat_cart_ibz))
3642 
3643        ! Tranfer diagonal terms to vk_cart_ibz.
3644        do ib=1,gqk%nb
3645          gqk%vk_cart_ibz(:, ib, :) = gqk%vkmat_cart_ibz(1, :, ib, ib, :)
3646        end do
3647      end if
3648 
3649      NCF_CHECK(nf90_close(ncid))
3650    end if
3651 
3652    call xmpi_barrier(gstore%comm)
3653  end do ! spin
3654 
3655  call cwtime_report(" gstore_from_ncpath", cpu, wall, gflops)
3656 
3657 contains
3658 integer function vid(vname)
3659   character(len=*),intent(in) :: vname
3660   vid = nctk_idname(ncid, vname)
3661 end function vid
3662 
3663 integer function spin_vid(vname)
3664   character(len=*),intent(in) :: vname
3665   spin_vid = nctk_idname(spin_ncid, vname)
3666 end function spin_vid
3667 
3668 end subroutine gstore_from_ncpath

m_gstore/gstore_get_a2fw [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_get_a2fw

FUNCTION

  Compute a^2F(omega)

INPUTS

OUTPUT

SOURCE

2103 subroutine gstore_get_a2fw(gstore, dtset, nw, wmesh, a2fw)
2104 
2105 !Arguments ------------------------------------
2106  class(gstore_t),target,intent(inout) :: gstore
2107  type(dataset_type),intent(in) :: dtset
2108  integer,intent(in) :: nw
2109  real(dp),intent(in) :: wmesh(nw)
2110  real(dp),intent(out) :: a2fw(nw)
2111 
2112 !Local variables-------------------------------
2113  integer :: my_is, my_ik, my_iq, my_ip, ib_k, ib_kq, ierr
2114  real(dp) :: g2, w_nuq, weight_k, weight_q, cpu, wall, gflops
2115  type(gqk_t), pointer :: gqk
2116 !arrays
2117  real(dp) :: qpt(3)
2118  real(dp),allocatable :: dbldelta_q(:,:,:), g2_mnkp(:,:,:,:), deltaw_nuq(:)
2119 
2120 !----------------------------------------------------------------------
2121 
2122  call wrtout(std_out, sjoin(" Computing a^2F(w) with ph_smear:", ftoa(dtset%ph_smear * Ha_meV), "(meV)"))
2123  ABI_CHECK(gstore%qzone == "bz", "gstore_get_lambda_iso_iw assumes qzone == `bz`")
2124  call cwtime(cpu, wall, gflops, "start")
2125 
2126  ABI_MALLOC(deltaw_nuq, (nw))
2127  a2fw = zero
2128 
2129  do my_is=1,gstore%my_nspins
2130    gqk => gstore%gqk(my_is)
2131 
2132    ABI_CHECK(allocated(gqk%my_g2), "my_g2 is not allocated")
2133    ABI_CHECK(allocated(gqk%my_wnuq), "my_wnuq is not allocated")
2134 
2135    ! Weights for delta(e_{m k+q}) delta(e_{n k}) for my list of k-points.
2136    ABI_MALLOC(dbldelta_q, (gqk%nb, gqk%nb, gqk%my_nk))
2137    ABI_MALLOC(g2_mnkp, (gqk%nb, gqk%nb, gqk%my_nk, gqk%my_npert))
2138 
2139    do my_iq=1,gqk%my_nq
2140      ! Compute integration weights for the double delta.
2141      call gqk%dbldelta_qpt(my_iq, gstore, dtset%eph_intmeth, dtset%eph_fsmear, qpt, weight_q, dbldelta_q)
2142 
2143      ! Copy data to improve memory access in the loops below.
2144      do my_ip=1,gqk%my_npert
2145        g2_mnkp(:,:,:,my_ip) = gqk%my_g2(my_ip,:,my_iq,:,:)
2146      end do
2147 
2148      do my_ip=1,gqk%my_npert
2149        w_nuq = gqk%my_wnuq(my_ip, my_iq)
2150        deltaw_nuq = gaussian(wmesh - w_nuq, dtset%ph_smear)
2151        do my_ik=1,gqk%my_nk
2152          !weight_k = gqk%my_kweight(my_ik, gstore)
2153          weight_k = gqk%my_wtk(my_ik)
2154          do ib_k=1,gqk%nb
2155            do ib_kq=1,gqk%nb
2156              g2 = g2_mnkp(ib_kq, ib_k, my_ik, my_ip)
2157              a2fw(:) = a2fw(:) + deltaw_nuq(:) * g2 * weight_k * weight_q * dbldelta_q(ib_kq, ib_k, my_ik)
2158            end do
2159          end do
2160        end do
2161      end do
2162    end do ! my_iq
2163 
2164    ABI_FREE(dbldelta_q)
2165    ABI_FREE(g2_mnkp)
2166  end do ! my_is
2167 
2168  ABI_FREE(deltaw_nuq)
2169 
2170  ! Take into account collinear spin and N(eF) TODO
2171  a2fw = a2fw * (two / (gstore%nsppol * dtset%nspinor))
2172  call xmpi_sum(a2fw, gstore%comm, ierr)
2173 
2174  call cwtime_report(" gstore_get_a2fw", cpu, wall, gflops)
2175 
2176 end subroutine gstore_get_a2fw

m_gstore/gstore_get_lambda_iso_iw [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_get_lambda_iso_iw

FUNCTION

  Compute isotropic lambda along the imaginary axis

INPUTS

OUTPUT

SOURCE

2020 subroutine gstore_get_lambda_iso_iw(gstore, dtset, nw, imag_w, lambda)
2021 
2022 !Arguments ------------------------------------
2023  class(gstore_t),target,intent(inout) :: gstore
2024  type(dataset_type),intent(in) :: dtset
2025  integer,intent(in) :: nw
2026  real(dp),intent(in) :: imag_w(nw)
2027  real(dp),intent(out) :: lambda(nw)
2028 
2029 !Local variables-------------------------------
2030  integer :: my_is, my_ik, my_iq, my_ip, ib_k, ib_kq, ierr
2031  real(dp) :: g2, w_nuq, weight_k, weight_q
2032  type(gqk_t), pointer :: gqk
2033 !arrays
2034  real(dp) :: qpt(3)
2035  real(dp),allocatable :: dbldelta_q(:,:,:), g2_pmnk(:,:,:,:)
2036 
2037 !----------------------------------------------------------------------
2038 
2039  ABI_CHECK(gstore%qzone == "bz", "gstore_get_lambda_iso_iw assumes qzone == `bz`")
2040  lambda = zero
2041 
2042  do my_is=1,gstore%my_nspins
2043    gqk => gstore%gqk(my_is)
2044 
2045    ABI_CHECK(allocated(gqk%my_g2), "my_g2 is not allocated")
2046    ABI_CHECK(allocated(gqk%my_wnuq), "my_wnuq is not allocated")
2047 
2048    ! Weights for delta(e_{m k+q}) delta(e_{n k}) for my list of k-points.
2049    ABI_MALLOC(dbldelta_q, (gqk%nb, gqk%nb, gqk%my_nk))
2050    ABI_MALLOC(g2_pmnk, (gqk%my_npert, gqk%nb, gqk%nb, gqk%my_nk))
2051 
2052    do my_iq=1,gqk%my_nq
2053      ! Compute integration weights for the double delta.
2054      call gqk%dbldelta_qpt(my_iq, gstore, dtset%eph_intmeth, dtset%eph_fsmear, qpt, weight_q, dbldelta_q)
2055 
2056      ! Copy data to improve memory access in the loops below.
2057      g2_pmnk = gqk%my_g2(:,:,my_iq,:,:)
2058 
2059      do my_ik=1,gqk%my_nk
2060        !weight_k = gqk%my_kweight(my_ik, gstore)
2061        weight_k = gqk%my_wtk(my_ik)
2062        do ib_k=1,gqk%nb
2063          do ib_kq=1,gqk%nb
2064            do my_ip=1,gqk%my_npert
2065              g2 = g2_pmnk(my_ip, ib_kq, ib_k, my_ik)
2066              ! TODO: handle w_nuq ~ 0
2067              w_nuq = gqk%my_wnuq(my_ip, my_iq)
2068              lambda(:) = lambda(:) + &
2069                two * w_nuq / (imag_w(:) ** 2 + w_nuq ** 2) * g2 * weight_k * weight_q * dbldelta_q(ib_kq, ib_k, my_ik)
2070            end do
2071          end do
2072        end do
2073      end do
2074    end do ! my_iq
2075 
2076    ABI_FREE(dbldelta_q)
2077    ABI_FREE(g2_pmnk)
2078  end do ! my_is
2079 
2080  ! Take into account collinear spin
2081  lambda = lambda * (two / (gstore%nsppol * dtset%nspinor))
2082 
2083  call xmpi_sum(lambda, gstore%comm, ierr)
2084 
2085 end subroutine gstore_get_lambda_iso_iw

m_gstore/gstore_get_mpw_gmax [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_get_mpw_gmax

FUNCTION

INPUTS

OUTPUT

SOURCE

1860 subroutine gstore_get_mpw_gmax(gstore, ecut, mpw, gmax)
1861 
1862 !Arguments ------------------------------------
1863  class(gstore_t),target,intent(in) :: gstore
1864  real(dp),intent(in) :: ecut
1865  integer,intent(out) :: mpw, gmax(3)
1866 
1867 !Local variables-------------------------------
1868  integer,parameter :: istwfk1 = 1
1869  integer :: my_is, my_ik, my_iq, spin, onpw, ii, ipw, ierr, my_mpw
1870  real(dp) :: weight_q, cpu, wall, gflops !weight_k,
1871  type(gqk_t),pointer :: gqk
1872 !arrays
1873  integer :: my_gmax(3)
1874  integer,allocatable :: gtmp(:,:)
1875  real(dp) :: kk(3), qpt(3)
1876 
1877 !----------------------------------------------------------------------
1878 
1879  mpw = 0; gmax = 0
1880 
1881  ! TODO: This is an hotspot due to the double loop over k and q.
1882  ! Should use a geometrical approach to compute mpw and gmax.
1883 
1884  call wrtout(std_out, " Computing mpw. This may take some time for dense k/q meshes...")
1885  call cwtime(cpu, wall, gflops, "start")
1886 
1887  do my_is=1,gstore%my_nspins
1888    gqk => gstore%gqk(my_is)
1889    spin = gstore%my_spins(my_is)
1890 
1891    do my_ik=1,gqk%my_nk
1892      kk = gqk%my_kpts(:, my_ik)
1893 
1894      ! Compute G sphere, returning npw. Note istwfk == 1.
1895      call get_kg(kk, istwfk1, ecut, gstore%cryst%gmet, onpw, gtmp)
1896      mpw = max(mpw, onpw)
1897      do ipw=1,onpw
1898        do ii=1,3
1899          gmax(ii) = max(gmax(ii), abs(gtmp(ii,ipw)))
1900        end do
1901      end do
1902      ABI_FREE(gtmp)
1903 
1904      do my_iq=1,gqk%my_nq
1905        call gqk%myqpt(my_iq, gstore, weight_q, qpt)
1906 
1907        ! TODO: g0 umklapp here can enter into play!
1908        ! gmax could not be large enough!
1909        call get_kg(kk + qpt, 1, ecut, gstore%cryst%gmet, onpw, gtmp)
1910        mpw = max(mpw, onpw)
1911        do ipw=1,onpw
1912          do ii=1,3
1913           gmax(ii) = max(gmax(ii), abs(gtmp(ii,ipw)))
1914          end do
1915        end do
1916        ABI_FREE(gtmp)
1917      end do
1918 
1919    end do ! my_ik
1920  end do ! my_is
1921 
1922  my_mpw = mpw; call xmpi_max(my_mpw, mpw, gstore%comm, ierr)
1923  my_gmax = gmax; call xmpi_max(my_gmax, gmax, gstore%comm, ierr)
1924 
1925  call wrtout(std_out, sjoin(' Optimal value of mpw: ', itoa(mpw)))
1926  call cwtime_report(" gmax and mpw", cpu, wall, gflops)
1927 
1928 end subroutine gstore_get_mpw_gmax

m_gstore/gstore_init [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_init

FUNCTION

 Initialize the object

INPUTS

 path=Filename of the output GSTORE.nc file

OUTPUT

SOURCE

498 subroutine gstore_init(gstore, path, dtset, wfk0_hdr, cryst, ebands, ifc, comm)
499 
500 !Arguments ------------------------------------
501 !scalars
502  class(gstore_t),target,intent(out) :: gstore
503  integer,intent(in) :: comm
504  character(len=*),intent(in) :: path
505  type(dataset_type),intent(in) :: dtset
506  type(hdr_type),intent(in) :: wfk0_hdr
507  class(crystal_t),target,intent(in) :: cryst
508  class(ebands_t),target,intent(in) :: ebands
509  class(ifc_type),target,intent(in) :: ifc
510 
511 !Local variables-------------------------------
512 !scalars
513  integer,parameter :: master = 0
514  integer :: all_nproc, my_rank, ierr, my_nshiftq, nsppol, spin, natom3, cnt, qtimrev
515  integer :: ik_ibz, ik_bz, iq_bz, iq_ibz, ebands_timrev, max_nq, max_nk, ncid, spin_ncid, ncerr, gstore_fform
516  real(dp) :: cpu, wall, gflops
517  character(len=10) :: priority
518  !character(len=5000) :: msg
519  type(krank_t) :: qrank
520 !arrays
521  integer :: ngqpt(3), qptrlatt(3,3), comm_spin(ebands%nsppol), nproc_spin(ebands%nsppol)
522  !integer :: glob_nk_spin(ebands%nsppol), glob_nq_spin(ebands%nsppol)
523  integer,allocatable :: qbz2ibz(:,:), kbz2ibz(:,:), kibz2bz(:), qibz2bz(:), qglob2bz(:,:), kglob2bz(:,:)
524  integer,allocatable :: select_qbz_spin(:,:), select_kbz_spin(:,:) !, done_qbz_spin(:,:)
525  real(dp):: my_shiftq(3,1)
526  real(dp),allocatable :: qbz(:,:), wtk(:), kibz(:,:), kbz(:,:)
527  !integer :: out_kptrlatt(3,3)
528  !real(dp),allocatable :: out_kibz(:,:), out_wtk(:)
529 
530 !----------------------------------------------------------------------
531 
532  call cwtime(cpu, wall, gflops, "start")
533  all_nproc = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
534  natom3 = 3 * cryst%natom; nsppol = ebands%nsppol
535 
536  ! Set basic parameters.
537  gstore%comm = comm
538  gstore%nsppol = nsppol
539  gstore%path = path
540 
541  ! Get references to other data structures.
542  gstore%cryst => cryst
543  gstore%ebands => ebands
544  gstore%ifc => ifc
545  gstore%kibz => ebands%kptns
546 
547  ! Set metadata.
548  gstore%kzone =  dtset%gstore_kzone; gstore%qzone = dtset%gstore_qzone; gstore%kfilter = dtset%gstore_kfilter
549  gstore%with_vk = dtset%gstore_with_vk
550 
551  ABI_CALLOC(gstore%erange_spin, (2, nsppol))
552  gstore%erange_spin = dtset%gstore_erange(:, 1:nsppol)
553 
554  if (any(gstore%erange_spin /= zero)) then
555    ABI_CHECK(gstore%kfilter == "none", sjoin("kfilter should be none when erange is used while it is:", gstore%kfilter))
556    gstore%kfilter = "erange"
557  end if
558 
559  if (gstore%kzone == "ibz" .and. gstore%qzone == "ibz") then
560    ABI_ERROR("The combination kzone = 'ibz' and qzone = 'ibz' is not allowed!")
561  end if
562 
563  ! TODO
564  !gstore%kptrlatt(3, 3)
565  !gstore%kshift(3, 1)
566  !gstore%qptrlatt(3, 3)
567  !gstore%qshift(3, 1)
568 
569  ! Distribute spins, create indirect mapping to spin index and init gstore%brange_spin
570  ABI_CHECK_ILEQ(dtset%mband, ebands%mband, "dtset%mband > ebands%mband")
571  call gstore%distribute_spins__(dtset%mband, dtset%gstore_brange, nproc_spin, comm_spin, comm)
572 
573  ! Define q-mesh: either from DVDB (no interpolation) or eph_ngqpt_fine (Fourier interpolation)
574  ngqpt = dtset%ddb_ngqpt; my_nshiftq = 1; my_shiftq(:,1) = dtset%ddb_shiftq
575  if (all(dtset%eph_ngqpt_fine /= 0)) then
576    ngqpt = dtset%eph_ngqpt_fine; my_shiftq = 0
577  end if
578 
579  ! TODO: Should fix bz2ibz to use the same conventions as krank and listkk
580  ! NB: only sigmaph seems to be using this optional argument
581 
582  ! Setup qIBZ, weights and BZ.
583  ! Assume qptopt == kptopt unless value is specified in input
584  qptrlatt = 0; qptrlatt(1, 1) = ngqpt(1); qptrlatt(2, 2) = ngqpt(2); qptrlatt(3, 3) = ngqpt(3)
585  gstore%qptopt = ebands%kptopt; if (dtset%qptopt /= 0) gstore%qptopt = dtset%qptopt
586  qtimrev = kpts_timrev_from_kptopt(gstore%qptopt)
587 
588  !call wrtout(std_out, sjoin(" Generating q-IBZ for with qptopt:", itoa(gstore%qptopt)))
589  call kpts_ibz_from_kptrlatt(cryst, qptrlatt, gstore%qptopt, my_nshiftq, my_shiftq, &
590                              gstore%nqibz, gstore%qibz, gstore%wtq, gstore%nqbz, qbz)
591                              !new_kptrlatt=gstore%qptrlatt, new_shiftk=gstore%qshift,
592                              !bz2ibz=new%ind_qbz2ibz)  # FIXME
593 
594  ! HM: the bz2ibz produced above is incomplete, I do it here using listkk
595  ABI_MALLOC(qbz2ibz, (6, gstore%nqbz))
596 
597  qrank = krank_from_kptrlatt(gstore%nqibz, gstore%qibz, qptrlatt, compute_invrank=.False.)
598 
599  if (kpts_map("symrec", qtimrev, cryst, qrank, gstore%nqbz, qbz, qbz2ibz) /= 0) then
600    ABI_ERROR("Cannot map qBZ to IBZ!")
601  end if
602  call qrank%free()
603 
604  ! Order qbz by stars and rearrange entries in qbz2ibz table.
605  call kpts_pack_in_stars(gstore%nqbz, qbz, qbz2ibz)
606 
607  !call kpts_print_kmap(std_out, qibz, qbz, qbz2ibz)
608  !do iq_bz=1,gstore%nqbz
609  !  print *, "iq_bz -> iq_ibz", qbz2ibz(1, iq_bz), qbz(:, iq_bz)
610  !end do
611 
612  call get_ibz2bz(gstore%nqibz, gstore%nqbz, qbz2ibz, qibz2bz, ierr)
613  ABI_CHECK(ierr == 0, "Something wrong in symmetry tables for q-points!")
614 
615  ! Get full BZ associated to ebands
616  call kpts_ibz_from_kptrlatt(cryst, ebands%kptrlatt, ebands%kptopt, ebands%nshiftk, ebands%shiftk, &
617                              gstore%nkibz, kibz, wtk, gstore%nkbz, kbz) !, bz2ibz=bz2ibz)
618                              !new_kptrlatt=gstore%kptrlatt, new_shiftk=gstore%kshift,
619                              !bz2ibz=new%ind_qbz2ibz)  # FIXME
620 
621  ! In principle kibz should be equal to ebands%kptns
622  ABI_CHECK(gstore%nkibz == ebands%nkpt, "nkibz != ebands%nkpt")
623  ABI_CHECK(all(abs(gstore%kibz - kibz) < tol12), "ebands%kibz != kibz")
624  ABI_FREE(kibz)
625 
626  ! Note symrel and use_symrec=.False. in get_mapping.
627  ! This means that this table can be used to symmetrize wavefunctions in cgtk_rotate.
628  ! TODO This ambiguity should be removed. Change cgtk_rotate so that we can use the symrec convention.
629 
630  ABI_MALLOC(kbz2ibz, (6, gstore%nkbz))
631  ebands_timrev = kpts_timrev_from_kptopt(ebands%kptopt)
632  gstore%krank_ibz = krank_from_kptrlatt(gstore%nkibz, gstore%kibz, ebands%kptrlatt, compute_invrank=.False.)
633  if (kpts_map("symrel", ebands_timrev, cryst, gstore%krank_ibz, gstore%nkbz, kbz, kbz2ibz) /= 0) then
634    ABI_ERROR("Cannot map kBZ to IBZ!")
635  end if
636 
637  call get_ibz2bz(gstore%nkibz, gstore%nkbz, kbz2ibz, kibz2bz, ierr)
638  ABI_CHECK(ierr == 0, "Something wrong in symmetry tables for k-points")
639 
640  ! These tables are used to exclude q/k points
641  ! We use the full BZ because this mask can be also used when points are restricted to the IBZ
642  ! provided we convert from ik_ibz to ik_bz. Note that both arrays are initialized with zeros.
643  ABI_ICALLOC(select_qbz_spin, (gstore%nqbz, nsppol))
644  ABI_ICALLOC(select_kbz_spin, (gstore%nkbz, nsppol))
645 
646  select case (gstore%kzone)
647  case ("ibz")
648    do spin=1,nsppol
649      do ik_ibz=1,gstore%nkibz
650        ik_bz = kibz2bz(ik_ibz); select_kbz_spin(ik_bz, spin) = 1
651      end do
652    end do
653 
654  case ("bz")
655    select_kbz_spin = 1
656 
657  case default
658    ABI_ERROR(sjoin("Invalid kzone:", gstore%kzone))
659  end select
660 
661  select case (gstore%qzone)
662  case ("ibz")
663    do spin=1,nsppol
664      do iq_ibz=1, gstore%nqibz
665        iq_bz = qibz2bz(iq_ibz); select_qbz_spin(iq_bz, spin) = 1
666      end do
667    end do
668 
669  case ("bz")
670     select_qbz_spin = 1
671 
672  case default
673    ABI_ERROR(sjoin("Invalid qzone:", gstore%qzone))
674  end select
675 
676  ! Here we filter the electronic wavevectors k and recompute select_qbz_spin and select_kbz_spin.
677 
678  select case (gstore%kfilter)
679  case ("none")
680    continue
681 
682  case ("erange")
683    call gstore%filter_erange__(qbz, qbz2ibz, qibz2bz, kbz, gstore%kibz, kbz2ibz, kibz2bz, &
684                                select_qbz_spin, select_kbz_spin)
685 
686  case ("fs_tetra")
687    ! Use the tetrahedron method to filter k- and k+q points on the FS in metals
688    ! and define gstore%brange_spin automatically.
689    call gstore%filter_fs_tetra__(qbz, qbz2ibz, qibz2bz, kbz, gstore%kibz, kbz2ibz, kibz2bz, &
690                                  select_qbz_spin, select_kbz_spin)
691  case default
692    ABI_ERROR(sjoin("Invalid kfilter:", gstore%kfilter))
693  end select
694 
695  ! Total number of k/q points for each spin after filtering (if any)
696  ABI_MALLOC(gstore%glob_nk_spin, (nsppol))
697  ABI_MALLOC(gstore%glob_nq_spin, (nsppol))
698  gstore%glob_nk_spin(:) = count(select_kbz_spin > 0, dim=1)
699  gstore%glob_nq_spin(:) = count(select_qbz_spin > 0, dim=1)
700 
701  ! We need another table mapping the global index in the gqk matrix to the q/k index in the BZ
702  ! so that one can extract the symmetry tables computed above.
703  ! Again this is needed as the global sizes of the gqk matrix
704  ! is not necessarily equal to the size of the BZ/IBZ if we have filtered the wave vectors.
705 
706  max_nq = maxval(gstore%glob_nq_spin) ! Max dim over spin
707  max_nk = maxval(gstore%glob_nk_spin)
708  ABI_ICALLOC(qglob2bz, (max_nq, nsppol))
709  ABI_ICALLOC(kglob2bz, (max_nk, nsppol))
710 
711  do spin=1,nsppol
712    cnt = 0
713    do iq_bz=1,gstore%nqbz
714      if (select_qbz_spin(iq_bz, spin) /= 0) then
715        cnt = cnt + 1; qglob2bz(cnt, spin) = iq_bz
716      end if
717    end do
718 
719    cnt = 0
720    do ik_bz=1,gstore%nkbz
721      if (select_kbz_spin(ik_bz, spin) /= 0) then
722        cnt = cnt + 1; kglob2bz(cnt, spin) = ik_bz
723      end if
724    end do
725  end do
726 
727  ! =============================================
728  ! Initialize gqk basic dimensions and MPI grid
729  ! =============================================
730  !priority = "qk"
731  call priority_from_eph_task(dtset%eph_task, priority)
732 
733  call gstore%set_mpi_grid__(dtset%gstore_cplex, dtset%eph_np_pqbks, priority, nproc_spin, comm_spin)
734  call xmpi_comm_free(comm_spin)
735 
736  ! At this point, we have the Cartesian grid (one per spin if any)
737  ! and we can finally allocate and distribute other arrays.
738  call gstore%malloc__(0, max_nq, qglob2bz, max_nk, kglob2bz, qbz2ibz, kbz2ibz)
739 
740  ! Initialize GSTORE.nc file i.e. define dimensions and arrays
741  ! Entries such as the e-ph matrix elements will be filled afterwards in gstore_compute.
742  ! Master node writes basic objects and gstore dimensions
743 
744  if (my_rank == master) then
745    NCF_CHECK(nctk_open_create(ncid, gstore%path, xmpi_comm_self))
746 
747    ! Write the abinit header with metadata, structure and occupancies.
748    gstore_fform = fform_from_ext("GSTORE.nc")
749    NCF_CHECK(wfk0_hdr%ncwrite(ncid, gstore_fform, spinat=dtset%spinat, nc_define=.True.))
750    !NCF_CHECK(gstore%cryst%ncwrite(ncid))
751 
752    ! Add eigenvalues and occupations.
753    NCF_CHECK(ebands_ncwrite(gstore%ebands, ncid))
754 
755    ! Write gstore dimensions
756    ncerr = nctk_def_dims(ncid, [ &
757       nctkdim_t("gstore_nkibz", gstore%nkibz), &
758       nctkdim_t("gstore_nkbz", gstore%nkbz), &
759       nctkdim_t("gstore_nqibz", gstore%nqibz), &
760       nctkdim_t("gstore_nqbz", gstore%nqbz), &
761       nctkdim_t("gstore_max_nq", max_nq), &
762       nctkdim_t("gstore_max_nk", max_nk), &
763       nctkdim_t("gstore_max_nb", maxval(gstore%brange_spin(2, :) - gstore%brange_spin(1, :) + 1) ), &
764       nctkdim_t("natom", gstore%cryst%natom), &
765       nctkdim_t("natom3", 3 * gstore%cryst%natom), &
766       nctkdim_t("gstore_cplex", dtset%gstore_cplex) &
767    ], defmode=.True.)
768    NCF_CHECK(ncerr)
769 
770    ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "gstore_with_vk", "gstore_qptopt"])
771    NCF_CHECK(ncerr)
772    !ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "fermi_energy", "smearing_width"])
773    !NCF_CHECK(ncerr)
774 
775    ncerr = nctk_def_arrays(ncid, [ &
776      nctkarr_t("gstore_qibz", "dp", "three, gstore_nqibz"), &
777      nctkarr_t("gstore_qbz", "dp", "three, gstore_nqbz"), &
778      nctkarr_t("gstore_wtq", "dp", "gstore_nqibz"), &
779      nctkarr_t("gstore_kbz", "dp", "three, gstore_nkbz"), &
780      nctkarr_t("gstore_kzone", "c", "fnlen"), &
781      nctkarr_t("gstore_qzone", "c", "fnlen"), &
782      nctkarr_t("gstore_kfilter", "c", "fnlen"), &
783      nctkarr_t("gstore_wfk0_path", "c", "fnlen"), &
784      nctkarr_t("gstore_brange_spin", "i", "two, number_of_spins"), &
785      nctkarr_t("gstore_erange_spin", "dp", "two, number_of_spins"), &
786      nctkarr_t("phfreqs_ibz", "dp", "natom3, gstore_nqibz"), &
787      nctkarr_t("pheigvec_cart_ibz", "dp", "two, three, natom, natom3, gstore_nqibz"), &
788      nctkarr_t("gstore_glob_nq_spin", "i", "number_of_spins"), &
789      nctkarr_t("gstore_glob_nk_spin", "i", "number_of_spins"), &
790      nctkarr_t("gstore_done_qbz_spin", "i", "gstore_nqbz, number_of_spins"), &
791      nctkarr_t("gstore_kbz2ibz", "i", "six, gstore_nkbz"), &
792      nctkarr_t("gstore_qbz2ibz", "i", "six, gstore_nqbz"), &
793      nctkarr_t("gstore_qglob2bz", "i", "gstore_max_nq, number_of_spins"), &
794      nctkarr_t("gstore_kglob2bz", "i", "gstore_max_nk, number_of_spins") &
795    ])
796    NCF_CHECK(ncerr)
797 
798    ! internal table used to restart computation. Init with zeros.
799    NCF_CHECK(nf90_def_var_fill(ncid, vid("gstore_done_qbz_spin"), NF90_FILL, zero))
800 
801    ! Optional arrays
802    if (allocated(gstore%delta_ef_kibz_spin)) then
803      ncerr = nctk_def_arrays(ncid, &
804        nctkarr_t("gstore_delta_ef_kibz_spin", "dp", "gstore_max_nb, gstore_nkibz, number_of_spins"))
805    end if
806    NCF_CHECK(ncerr)
807 
808    NCF_CHECK(nctk_set_datamode(ncid))
809    NCF_CHECK(nf90_put_var(ncid, vid("gstore_with_vk"), gstore%with_vk))
810    NCF_CHECK(nf90_put_var(ncid, vid("gstore_qptopt"), gstore%qptopt))
811    NCF_CHECK(nf90_put_var(ncid, vid("gstore_kzone"), trim(gstore%kzone)))
812    NCF_CHECK(nf90_put_var(ncid, vid("gstore_qzone"), trim(gstore%qzone)))
813    NCF_CHECK(nf90_put_var(ncid, vid("gstore_kfilter"), trim(gstore%kfilter)))
814 
815    ! Write arrays
816    NCF_CHECK(nf90_put_var(ncid, vid("gstore_qibz"), gstore%qibz))
817    NCF_CHECK(nf90_put_var(ncid, vid("gstore_qbz"), qbz))
818    NCF_CHECK(nf90_put_var(ncid, vid("gstore_wtq"), gstore%wtq))
819    NCF_CHECK(nf90_put_var(ncid, vid("gstore_kbz"), kbz))
820    NCF_CHECK(nf90_put_var(ncid, vid("gstore_brange_spin"), gstore%brange_spin))
821    NCF_CHECK(nf90_put_var(ncid, vid("gstore_erange_spin"), gstore%erange_spin))
822    NCF_CHECK(nf90_put_var(ncid, vid("gstore_glob_nq_spin"), gstore%glob_nq_spin))
823    NCF_CHECK(nf90_put_var(ncid, vid("gstore_glob_nk_spin"), gstore%glob_nk_spin))
824    NCF_CHECK(nf90_put_var(ncid, vid("gstore_kbz2ibz"), kbz2ibz))
825    NCF_CHECK(nf90_put_var(ncid, vid("gstore_qbz2ibz"), qbz2ibz))
826    NCF_CHECK(nf90_put_var(ncid, vid("gstore_qglob2bz"), qglob2bz))
827    NCF_CHECK(nf90_put_var(ncid, vid("gstore_kglob2bz"), kglob2bz))
828    ! NB: kibz has been already written by ebands%ncwrite
829 
830    if (allocated(gstore%delta_ef_kibz_spin)) then
831      NCF_CHECK(nf90_put_var(ncid, vid("gstore_delta_ef_kibz_spin"), gstore%delta_ef_kibz_spin))
832    end if
833 
834    do spin=1,gstore%nsppol
835      ! Create group for this spin.
836      NCF_CHECK(nf90_def_grp(ncid, strcat("gqk", "_spin", itoa(spin)), spin_ncid))
837 
838      ! Dimensions in gqk_spin group
839      ncerr = nctk_def_dims(spin_ncid, [ &
840         nctkdim_t("nb", gstore%brange_spin(2, spin) - gstore%brange_spin(1, spin) + 1), &
841         nctkdim_t("glob_nk", gstore%glob_nk_spin(spin)), &
842         nctkdim_t("glob_nq", gstore%glob_nq_spin(spin))  &
843      ], defmode=.True.)
844      NCF_CHECK(ncerr)
845 
846      ! Define scalars
847      ncerr = nctk_def_iscalars(spin_ncid, [character(len=nctk_slen) :: "bstart"])
848      NCF_CHECK(ncerr)
849 
850      ! arrays in gqk_spin group with the precious stuff. Note glob dimensions
851      ncerr = nctk_def_arrays(spin_ncid, [ &
852        nctkarr_t("gvals", "dp", "gstore_cplex, nb, nb, natom3, glob_nk, glob_nq") &
853      ])
854      NCF_CHECK(ncerr)
855 
856      ! IMPORTANT: Init with zeros.
857      NCF_CHECK(nf90_def_var_fill(spin_ncid, vid_spin("gvals"), NF90_FILL, zero))
858 
859      select case(gstore%with_vk)
860      case (1)
861        ! Diagonal terms only
862        NCF_CHECK(nctk_def_arrays(spin_ncid, nctkarr_t("vk_cart_ibz", "dp", "three, nb, gstore_nkibz")))
863        NCF_CHECK(nf90_def_var_fill(spin_ncid, vid_spin("vk_cart_ibz"), NF90_FILL, zero))
864      case (2)
865        ! Full (nb x nb) matrix.
866        NCF_CHECK(nctk_def_arrays(spin_ncid, nctkarr_t("vkmat_cart_ibz", "dp", "two, three, nb, nb, gstore_nkibz")))
867        NCF_CHECK(nf90_def_var_fill(spin_ncid, vid_spin("vkmat_cart_ibz"), NF90_FILL, zero))
868      end select
869 
870      ! Write (small) data
871      NCF_CHECK(nctk_set_datamode(spin_ncid))
872      NCF_CHECK(nf90_put_var(spin_ncid, vid_spin("bstart"), gstore%brange_spin(1, spin)))
873    end do ! spin
874 
875    NCF_CHECK(nf90_close(ncid))
876  end if ! master
877 
878  call xmpi_barrier(gstore%comm)
879 
880  ABI_FREE(wtk)
881  ABI_FREE(kbz)
882  ABI_FREE(qbz)
883  ABI_FREE(qibz2bz)
884  ABI_FREE(kibz2bz)
885  ABI_FREE(select_qbz_spin)
886  ABI_FREE(select_kbz_spin)
887  ABI_FREE(qglob2bz)
888  ABI_FREE(kglob2bz)
889  ABI_FREE(qbz2ibz)
890  ABI_FREE(kbz2ibz)
891 
892  call cwtime_report(" gstore_init:", cpu, wall, gflops)
893 
894 contains
895  integer function vid(vname)
896    character(len=*),intent(in) :: vname
897    vid = nctk_idname(NCID, vname)
898  end function vid
899  integer function vid_spin(vname)
900    character(len=*),intent(in) :: vname
901    vid_spin = nctk_idname(SPIN_NCID, vname)
902  end function vid_spin
903 
904 end subroutine gstore_init

m_gstore/gstore_malloc__ [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_malloc__

FUNCTION

 Allocate memory.

INPUTS

OUTPUT

SOURCE

1258 subroutine gstore_malloc__(gstore, with_cplex, max_nq, qglob2bz, max_nk, kglob2bz, qbz2ibz, kbz2ibz)
1259 
1260 !Arguments ------------------------------------
1261 !scalars
1262  class(gstore_t),target,intent(inout) :: gstore
1263  integer,intent(in) :: with_cplex, max_nq, max_nk
1264  integer,intent(in) :: qglob2bz(max_nq, gstore%nsppol)
1265  integer,intent(in) :: kglob2bz(max_nk, gstore%nsppol)
1266  integer,intent(in) :: qbz2ibz(6, gstore%nqbz), kbz2ibz(6, gstore%nkbz)
1267 
1268 !Local variables-------------------------------
1269 !scalars
1270  integer :: spin, my_is, ierr, my_iq, my_ik, iq_glob, iq_bz, ik_glob, ik_bz
1271  integer :: ik_ibz, isym_k, trev_k, tsign_k, g0_k(3)
1272  logical :: isirr_k
1273  real(dp) :: mem_mb
1274  type(gqk_t),pointer :: gqk
1275 !arrays
1276  integer,allocatable :: myq2glob(:), myk2glob(:)
1277 !----------------------------------------------------------------------
1278 
1279  !gstore%max_nb = maxval(gstore%brange_spin(2, :) - gstore%brange_spin(1, :) + 1)
1280 
1281  do my_is=1,gstore%my_nspins
1282    gqk => gstore%gqk(my_is)
1283    spin = gstore%my_spins(my_is)
1284 
1285    ! Split q-points and transfer symmetry tables.
1286    ! Note that glob_nq and glob_nk does not necessarily correspond to the size of the BZ
1287    ! First of all we have to consider kzone
1288    ! Even if kzone == "bz" we may have filtered the wavevectors e.g. Fermi surface.
1289    call xmpi_split_block(gqk%glob_nq, gqk%qpt_comm%value, gqk%my_nq, myq2glob)
1290    ABI_CHECK(gqk%my_nq > 0, "my_nq == 0")
1291    gqk%my_qstart = myq2glob(1)
1292    ABI_FREE(myq2glob)
1293 
1294    ABI_MALLOC(gqk%my_q2ibz, (6, gqk%my_nq))
1295    ABI_MALLOC(gqk%my_q2bz, (gqk%my_nq))
1296 
1297    do my_iq=1,gqk%my_nq
1298      iq_glob = my_iq + gqk%my_qstart - 1
1299      iq_bz = qglob2bz(iq_glob, spin)
1300      gqk%my_q2ibz(:, my_iq) = qbz2ibz(:, iq_bz)
1301      gqk%my_q2bz(my_iq) = iq_bz
1302    end do
1303 
1304    ! Split k-points and transfer symmetry tables
1305    call xmpi_split_block(gqk%glob_nk, gqk%kpt_comm%value, gqk%my_nk, myk2glob)
1306    ABI_CHECK(gqk%my_nk > 0, "my_nk == 0")
1307    gqk%my_kstart = myk2glob(1)
1308    ABI_FREE(myk2glob)
1309 
1310    ABI_MALLOC(gqk%my_k2ibz, (6, gqk%my_nk))
1311    !ABI_MALLOC(gqk%my_k2bz, (gqk%my_nk))
1312    ABI_MALLOC(gqk%my_kpts, (3, gqk%my_nk))
1313    ABI_MALLOC(gqk%my_wtk, (gqk%my_nk))
1314 
1315    do my_ik=1,gqk%my_nk
1316      ik_glob = my_ik + gqk%my_kstart - 1
1317      ik_bz = kglob2bz(ik_glob, spin)
1318      gqk%my_k2ibz(:, my_ik) = kbz2ibz(:, ik_bz)
1319      !gqk%my_k2bz(my_ik) = ik_bz
1320 
1321      ik_ibz = gqk%my_k2ibz(1, my_ik); isym_k = gqk%my_k2ibz(2, my_ik)
1322      trev_k = gqk%my_k2ibz(6, my_ik); g0_k = gqk%my_k2ibz(3:5, my_ik)
1323      isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
1324      tsign_k = 1; if (trev_k == 1) tsign_k = -1
1325 
1326      !! symrel^T convention for k
1327      gqk%my_kpts(:, my_ik) = tsign_k * matmul(transpose(gstore%cryst%symrel(:,:,isym_k)), gstore%kibz(:, ik_ibz)) + g0_k
1328 
1329      select case(gstore%kzone)
1330      case ("ibz")
1331        gqk%my_wtk(my_ik) = gstore%ebands%wtk(ik_ibz)
1332      case ("bz")
1333        gqk%my_wtk(my_ik) = one / gstore%nkbz
1334      end select
1335    end do
1336 
1337    ! Allocate storage for MPI-distributed e-ph matrix elements.
1338    if (with_cplex > 0) then
1339      mem_mb = with_cplex * gqk%my_npert * gqk%nb ** 2 * gqk%my_nq * gqk%my_nk * eight * b2Mb
1340      call wrtout(std_out, sjoin(" Local memory for e-ph matrix elements:", ftoa(mem_mb, fmt="f8.1"), " [Mb] <<< MEM"))
1341 
1342      ! The initialization with zero is important as not all the g are computed when we filter in k-space.
1343      ! Abinit postprocessing tools will operate of the full my_g array
1344      ! and we don't want to trigger floating point exceptions.
1345      select case (with_cplex)
1346      case (1)
1347        ABI_MALLOC_OR_DIE(gqk%my_g2, (gqk%my_npert, gqk%nb, gqk%my_nq, gqk%nb, gqk%my_nk), ierr)
1348        gqk%my_g2 = zero
1349      case (2)
1350         ABI_MALLOC_OR_DIE(gqk%my_g, (gqk%my_npert, gqk%nb, gqk%my_nq, gqk%nb, gqk%my_nk), ierr)
1351         gqk%my_g = zero
1352      case default
1353        ABI_ERROR(sjoin("Wrong with_cplex:", itoa(with_cplex)))
1354      end select
1355 
1356      ! Allocate storage for MPI-distributed dH/dk matrix elements.
1357      if (any(gstore%with_vk == [1, 2])) then
1358        mem_mb = 3 * gqk%nb * gqk%my_nk * eight * b2Mb
1359        call wrtout(std_out, sjoin(" Memory for diagonal vk_cart_ibz:", ftoa(mem_mb, fmt="f8.1"), " [Mb] <<< MEM"))
1360        ABI_MALLOC_OR_DIE(gqk%vk_cart_ibz, (3, gqk%nb, gstore%nkibz), ierr)
1361        gqk%vk_cart_ibz = zero
1362      end if
1363 
1364      if (gstore%with_vk == 2) then
1365        mem_mb = two * 3 * gqk%nb ** 2 * gqk%my_nk * eight * b2Mb
1366        call wrtout(std_out, sjoin(" Memory for vkmat_cart_ibz:", ftoa(mem_mb, fmt="f8.1"), " [Mb] <<< MEM"))
1367        ABI_MALLOC_OR_DIE(gqk%vkmat_cart_ibz, (2, 3, gqk%nb, gqk%nb, gstore%nkibz), ierr)
1368        gqk%vkmat_cart_ibz = zero
1369      end if
1370    end if
1371 
1372  end do ! my_is
1373 
1374 end subroutine gstore_malloc__

m_gstore/gstore_print [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_print

FUNCTION

  Print info on the gstore object.

INPUTS

OUTPUT

SOURCE

1180 subroutine gstore_print(gstore, unit, header, prtvol)
1181 
1182 !Arguments ------------------------------------
1183  class(gstore_t),target,intent(inout) :: gstore
1184  integer,intent(in) :: unit
1185  character(len=*),optional,intent(in) :: header
1186  integer,optional,intent(in) :: prtvol
1187 
1188 !Local variables ------------------------------
1189  integer :: my_is, spin, my_prtvol
1190  type(gqk_t),pointer :: gqk
1191  !character(len=500) :: msg
1192  !type(yamldoc_t) :: ydoc
1193 !----------------------------------------------------------------------
1194 
1195  my_prtvol = 0; if (present(prtvol)) my_prtvol = prtvol
1196 
1197  if (present(header)) then
1198    call wrtout(unit, header)
1199  else
1200    call wrtout(unit, " === Gstore parameters ===")
1201  end if
1202  !call ebands_print(gstore%ebands, header="Electron bands", unit=unit, prtvol=my_prtvol)
1203  call wrtout(unit, sjoin(" kzone:", gstore%kzone))
1204  call wrtout(unit, sjoin(" kfilter:", gstore%kfilter))
1205  call wrtout(unit, sjoin(" nkibz:", itoa(gstore%nkibz)))
1206  call wrtout(unit, sjoin(" nkbz:", itoa(gstore%nkbz)))
1207  call wrtout(unit, sjoin(" glob_nk_spin:", ltoa(gstore%glob_nk_spin)))
1208  call wrtout(unit, sjoin(" qzone:", gstore%qzone))
1209  call wrtout(unit, sjoin(" nqibz:", itoa(gstore%nqibz)))
1210  call wrtout(unit, sjoin(" nqbz:", itoa(gstore%nqbz)))
1211  call wrtout(unit, sjoin(" glob_nq_spin:", ltoa(gstore%glob_nq_spin)))
1212  call wrtout(unit, sjoin(" kptopt:", itoa(gstore%ebands%kptopt)))
1213  call wrtout(unit, sjoin(" qptopt:", itoa(gstore%qptopt)))
1214  call wrtout(unit, sjoin(" with_vk:", itoa(gstore%with_vk)))
1215 
1216  do my_is=1,gstore%my_nspins
1217    spin = gstore%my_spins(my_is)
1218    gqk => gstore%gqk(my_is)
1219    call wrtout(unit, sjoin(ch10, " === MPI distribution ==="))
1220    call wrtout(unit, sjoin("P Number of CPUs for parallelism over perturbations: ", itoa(gqk%pert_comm%nproc)))
1221    call wrtout(unit, sjoin("P Number of perturbations treated by this CPU: ",  itoa(gqk%my_npert)))
1222    call wrtout(unit, sjoin("P Number of CPUs for parallelism over q-points: ", itoa(gqk%qpt_comm%nproc)))
1223    call wrtout(unit, sjoin("P Number of CPUs for parallelism over k-points: ", itoa(gqk%kpt_comm%nproc)))
1224    call wrtout(unit, sjoin(" gqk_cplex:", itoa(gqk%cplex)), pre_newlines=1)
1225    call wrtout(unit, sjoin(" gqk_bstart:", itoa(gqk%bstart)))
1226    call wrtout(unit, sjoin(" gqk_bstop:", itoa(gqk%bstop)))
1227    call wrtout(unit, sjoin(" gqk_nb:", itoa(gqk%nb)))
1228    call wrtout(unit, sjoin(" gqk_my_npert:", itoa(gqk%my_npert)))
1229    call wrtout(unit, sjoin(" gqk_my_nk:", itoa(gqk%my_nk)))
1230    call wrtout(unit, sjoin(" gqk_my_nq:", itoa(gqk%my_nq)))
1231    !if (gqk%cplex == 1) then
1232    !  write(msg,'(a,f8.1,a)')'- Local memory allocated for |g|^2 array: ',ABI_MEM_MB(gqk%my_g2),' [Mb] <<< MEM'
1233    !  call wrtout(unit, msg) !; print *, "my_g2 shape:", shape(gqk%my_g2)
1234    !else
1235    !  write(msg,'(a,f8.1,a)')'- Local memory allocated for g array: ',ABI_MEM_MB(gqk%my_g),' [Mb] <<< MEM'
1236    !  call wrtout(unit, msg) !; print *, "my_g shape:", shape(gqk%my_g)
1237    !end if
1238  end do
1239 
1240 end subroutine gstore_print

m_gstore/gstore_set_mpi_grid__ [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_set_mpi_grid__

FUNCTION

INPUTS

OUTPUT

SOURCE

1023 subroutine gstore_set_mpi_grid__(gstore, gstore_cplex, eph_np_pqbks, priority, nproc_spin, comm_spin)
1024 
1025 !Arguments ------------------------------------
1026 !scalars
1027  class(gstore_t),target,intent(inout) :: gstore
1028  integer,intent(in) :: gstore_cplex
1029  integer,intent(in) :: eph_np_pqbks(5), nproc_spin(gstore%nsppol), comm_spin(gstore%nsppol)
1030  character(len=*),intent(in) :: priority
1031 
1032 !Local variables-------------------------------
1033 !scalars
1034  integer,parameter :: master = 0, ndims = 3
1035  integer :: spin, my_is, np, my_rank, ierr !, ii
1036  type(gqk_t),pointer :: gqk
1037  character(len=5000) :: msg
1038  character(len=10) :: order
1039  integer :: comm_cart, me_cart, dims(ndims)
1040  logical :: reorder, periods(ndims), keepdim(ndims)
1041 !----------------------------------------------------------------------
1042 
1043  my_rank = xmpi_comm_rank(gstore%comm)
1044 
1045  do my_is=1,gstore%my_nspins
1046    spin = gstore%my_spins(my_is)
1047    gqk => gstore%gqk(my_is)
1048 
1049    gqk%spin = spin; gqk%natom3 = 3 * gstore%cryst%natom; gqk%cplex = gstore_cplex
1050    ABI_CHECK_IRANGE(gqk%cplex, 1, 2, "gstore_cplex")
1051 
1052    ! Compute bstart and band size for this spin.
1053    gqk%bstart = gstore%brange_spin(1, spin)
1054    gqk%bstop = gstore%brange_spin(2, spin)
1055    gqk%nb = gstore%brange_spin(2, spin) - gstore%brange_spin(1, spin) + 1
1056 
1057    ! Store global shape of the q/k matrix for this spin.
1058    gqk%glob_nq = gstore%glob_nq_spin(spin)
1059    gqk%glob_nk = gstore%glob_nk_spin(spin)
1060  end do
1061 
1062  do my_is=1,gstore%my_nspins
1063    spin = gstore%my_spins(my_is)
1064    gqk => gstore%gqk(my_is)
1065 
1066    ! Init for sequential execution.
1067    gqk%qpt_comm%nproc = 1; gqk%kpt_comm%nproc = 1; gqk%pert_comm%nproc = 1
1068    gqk%my_npert = gqk%natom3
1069 
1070    if (any(eph_np_pqbks /= 0)) then
1071      ! Use parameters from input file. Need to perform sanity check though.
1072      gqk%pert_comm%nproc = eph_np_pqbks(1)
1073      gqk%qpt_comm%nproc  = eph_np_pqbks(2)
1074      ABI_CHECK(eph_np_pqbks(3) == 1, "Band parallelism not implemented in gstore")
1075      gqk%kpt_comm%nproc = eph_np_pqbks(4)
1076      !gqk%spin_comm%nproc = eph_np_pqbks(5)
1077      gqk%my_npert = gqk%natom3 / gqk%pert_comm%nproc
1078      ABI_CHECK(gqk%my_npert > 0, "pert_comm_nproc cannot be greater than 3 * natom.")
1079      ABI_CHECK(mod(gqk%natom3, gqk%pert_comm%nproc) == 0, "pert_comm_nproc must divide 3 * natom.")
1080 
1081    else
1082      ! Automatic grid generation (hopefully smart)
1083      ! Keep in mind that in gstore_build, the first loop is over q-points
1084      ! in order to reduce the number of interpolations of the DFPT potentials in q-space
1085      ! hence the q-point parallelism is expected to be more efficient.
1086      ! On the other hand, the k-point parallelism and the perturbation parallelism
1087      ! allow one to reduce the memory requirements associated to the wavefunctions (kpt) and
1088      ! the scattering potentials in the supercell (perturbations).
1089      ! Here we try to optimize performance but it's clear that for large systems the user
1090      ! should specify eph_np_pqbks in the input file.
1091 
1092      select case (priority)
1093      case ("q")
1094        order = "1"
1095      case ("k")
1096        order = "2"
1097      case ("kq")
1098        order = "21"
1099      case ("qk")
1100        order = "12"
1101      case default
1102        ABI_ERROR(sjoin("Wrong priority:", priority))
1103      end select
1104 
1105      np = nproc_spin(spin)
1106      call xmpi_distrib_2d(np, order, gqk%glob_nq, gqk%glob_nk, gqk%qpt_comm%nproc, gqk%kpt_comm%nproc, ierr)
1107      ABI_CHECK(ierr == 0, sjoin("Cannot distribute nprocs:", itoa(np), " with priority: ", priority))
1108      !if (ierr /= 0) call xmpi_distrib_2d_extra(np, gqk%qpt_comm%nproc, gqk%kpt_comm%nproc, gqk%pert_comm%nproc, ierr)
1109    end if
1110 
1111    ! Consistency check.
1112    if (gqk%pert_comm%nproc * gqk%qpt_comm%nproc * gqk%kpt_comm%nproc /= nproc_spin(spin)) then
1113      write(msg, "(a,i0,3a, 4(a,1x,i0))") &
1114        "Cannot create 3d Cartesian grid with total nproc: ", nproc_spin(spin), ch10, &
1115        "Idle processes are not supported. The product of the `nproc_*` vars should be equal to nproc.", ch10, &
1116        "qpt_nproc (", gqk%qpt_comm%nproc, ") x kpt_nproc (", gqk%kpt_comm%nproc, ")  x kpt_nproc", gqk%pert_comm%nproc, &
1117        ") != ", nproc_spin(spin)
1118      ABI_ERROR(msg)
1119    end if
1120 
1121  end do ! my_is
1122 
1123  ! For each spin treated by this rank, create 3D cartesian communicator: (q-points, k-points, perturbations)
1124  periods(:) = .False.; reorder = .False.
1125 
1126  do my_is=1,gstore%my_nspins
1127    spin = gstore%my_spins(my_is)
1128    gqk => gstore%gqk(my_is)
1129 
1130    dims = [gqk%qpt_comm%nproc, gqk%kpt_comm%nproc, gqk%pert_comm%nproc]
1131 
1132    ! Note comm_spin(spin)
1133    gqk%grid_comm = xcomm_from_mpi_int(comm_spin(spin))
1134 
1135 #ifdef HAVE_MPI
1136    call MPI_CART_CREATE(gqk%grid_comm, ndims, dims, periods, reorder, comm_cart, ierr)
1137 
1138    ! Find the index and coordinates of the current processor
1139    call MPI_COMM_RANK(comm_cart, me_cart, ierr)
1140    call MPI_CART_COORDS(comm_cart, me_cart, ndims, gqk%coords_qkp, ierr)
1141 
1142    ! Create communicator for q-points
1143    keepdim = .False.; keepdim(1) = .True.; call gqk%qpt_comm%from_cart_sub(comm_cart, keepdim)
1144    ! Create communicator for k-points
1145    keepdim = .False.; keepdim(2) = .True.; call gqk%kpt_comm%from_cart_sub(comm_cart, keepdim)
1146    ! Create communicator for perturbations.
1147    keepdim = .False.; keepdim(3) = .True.; call gqk%pert_comm%from_cart_sub(comm_cart, keepdim)
1148    ! Create communicator for the (qpt, pert) 2D grid
1149    keepdim = .False.; keepdim(1) = .True.; keepdim(3) = .True.; call gqk%qpt_pert_comm%from_cart_sub(comm_cart, keepdim)
1150    call xmpi_comm_free(comm_cart)
1151 #endif
1152 
1153    ! Distribute perturbations inside per_comm using block distribution.
1154    call xmpi_split_block(gqk%natom3, gqk%pert_comm%value, gqk%my_npert, gqk%my_iperts)
1155  end do ! my_is
1156 
1157  if (my_rank == master) then
1158    call gstore%print(std_out)
1159    call gstore%print(ab_out)
1160  end if
1161 
1162 end subroutine gstore_set_mpi_grid__

m_gstore/gstore_spin2my_is [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 gstore_spin2my_is

FUNCTION

  Return the local spin index from the global spin index.
  0 if this spin is not treated by this MPI proc.

INPUTS

OUTPUT

SOURCE

1754 integer pure function gstore_spin2my_is(gstore, spin) result(my_is)
1755 
1756 !Arguments ------------------------------------
1757  class(gstore_t),intent(in) :: gstore
1758  integer,intent(in) :: spin
1759 
1760 !----------------------------------------------------------------------
1761 
1762  do my_is=1,gstore%my_nspins
1763    if (gstore%my_spins(my_is) == spin) return
1764  end do
1765  my_is = 0
1766 
1767 end function gstore_spin2my_is

m_gstore/gstore_t [ Types ]

[ Top ] [ m_gstore ] [ Types ]

NAME

 gstore_t

FUNCTION

 This object stores:

    - pointers to the cyrstalline structure, the KS bands, the IFCs.
    - arrays that do not depend on the spin such as the IBZ and weights for k/q-points.
    - metadata such as kzone, qzone and kfilter that are needed to interpret
      the storage mode used for the g(k, q)

 NB: the e-ph matrix element are stored in gstore%qqk(my_is)
     where my_is counts the number of spins treated by this MPI processor.

NOTES

SOURCE

326 type, public :: gstore_t
327 
328   integer :: nsppol
329    ! Number of independent spin polarizations.
330 
331   integer :: my_nspins = 0
332    ! Number of collinear spins treated by this MPI rank
333 
334   integer :: nkibz = -1, nqibz = -1
335   ! Number of k/q points in the IBZ.
336 
337   integer :: nkbz = -1, nqbz = -1
338   ! Number of k/q points in the BZ.
339 
340   integer :: comm
341    ! Global communicator
342    ! Inherited by the caller thus we don't free it in gstore_free.
343 
344   integer :: with_vk = 0
345   ! 0 if group velocities should not be computed
346   ! 1 to compute diagonal terms only
347   ! 2 to compute diagonal and off-diagonal terms
348 
349   integer :: qptopt = -1
350   !  qptopt=option for the generation of q points (defines whether spatial symmetries and/or time-reversal can be used)
351 
352   character(len=fnlen) :: path = " "
353   ! Path to the nc file associated to the gstore
354 
355   character(len=fnlen) :: wfk0_path = " "
356 
357   character(len=fnlen) :: kzone = " ", qzone = " "
358    ! Specifies whether k- or q-points are in the BZ or in the IBZ.
359    ! Possible values are "ibz" or "bz".
360    ! Note that the combination ("ibz", "ibz") is not allowed
361 
362   character(len=fnlen) :: kfilter = "none"
363   ! Specifies the tecnique used to filter k-points.
364   ! Possible values: "none", "fs_tetra", "erange".
365 
366   real(dp),allocatable :: erange_spin(:, :)
367   ! (2, nsppol)
368   ! Energy window. zero if not used. Requires kfilter == "erange"
369 
370   type(crystal_t), pointer :: cryst => null()
371 
372   type(ebands_t), pointer :: ebands => null()
373 
374   type(ifc_type), pointer :: ifc => null()
375 
376   type(krank_t) :: krank_ibz !, qrank
377   ! Object used to find k-points in the IBZ and map BZ to IBZ.
378 
379   integer,allocatable :: my_spins(:)
380    ! (%my_nspins)
381    ! Indirect table giving the spin indices treated by this MPI rank.
382    ! Used only in the collinear case with nsppol = 2.
383 
384   integer,allocatable :: brange_spin(:, :)
385   ! (2, nsppol)
386 
387   !integer :: max_nb = -1
388   ! Max number of bands over spin
389 
390   integer,allocatable :: glob_nk_spin(:), glob_nq_spin(:)
391   ! (nsppol)
392 
393   real(dp), contiguous, pointer :: kibz(:,:)
394   ! k-points in the IBZ. Points to ebands%kptns
395   ! (3, nkibz)
396 
397   real(dp),allocatable :: delta_ef_kibz_spin(:,:,:)
398   ! (nb, gstore%nkibz, nsppol))
399   ! Tetrahedron weights at eF in the IBZ.
400 
401   real(dp), allocatable :: qibz(:,:)
402   ! (3, nqibz)
403   ! q-points in the IBZ
404 
405   real(dp), allocatable :: wtq(:)
406   ! (nqibz)
407   ! q-points weights in the IBZ
408 
409   !integer :: qptrlatt(3, 3) = -1  ! kptrlatt(3, 3) = -1,
410    ! k-mesh and q-mesh
411 
412   !real(dp),allocatable :: kshift(:, :), qshift(:, :)
413   ! k/q-mesh shift (well, q-mesh is usually gamma-centered)
414 
415   type(gqk_t), allocatable :: gqk(:)
416   ! (my_nspins)
417   ! Datastructure storing e-ph matrix elements.
418 
419   !type(htetra_t) :: ktetra
420   ! Used to evaluate integrals in k-space with the tetrahedron method.
421 
422   !type(htetra_t) :: qtetra
423   ! Used to evaluate integrals in q-space with the tetrahedron method.
424 
425 contains
426 
427   procedure :: fill_bks_mask => gstore_fill_bks_mask
428   ! Fill the table used to read (b, k, s) wavefunctions from the WFK file
429   ! keeping into account the distribution of the e-ph matrix elements.
430 
431   procedure :: get_mpw_gmax => gstore_get_mpw_gmax
432 
433   procedure :: spin2my_is => gstore_spin2my_is
434   !  Return the local spin index from the global spin index.
435   !  0 if this spin is not treated by this MPI proc.
436 
437   procedure :: free => gstore_free
438   ! Free memory
439 
440   procedure :: print => gstore_print
441   ! Print info on the object
442 
443   procedure, private :: distribute_spins__ => gstore_distribute_spins
444   ! Distribute spins (nsppol = 2) and create indirect mapping to spin index.
445 
446   procedure, private :: set_mpi_grid__ => gstore_set_mpi_grid__
447   ! Set the MPI cartesian grid
448 
449   procedure, private :: malloc__ => gstore_malloc__
450   ! Allocate local buffers once the MPI grid has been initialized.
451 
452   procedure, private :: filter_fs_tetra__ => gstore_filter_fs_tetra__
453   ! Select k-points on the FS using the tetrahedron method
454 
455   procedure, private :: filter_erange__ => gstore_filter_erange__
456   ! Select k-points inside an energy window
457 
458   procedure :: compute => gstore_compute
459   ! Compute e-ph matrix elements.
460 
461   procedure :: calc_my_phonons => gstore_calc_my_phonons
462   ! Helper function to compute ph quantities for all q-points treated by the MPI proc.
463 
464   procedure :: get_lambda_iso_iw => gstore_get_lambda_iso_iw
465   ! Compute isotropic lamdda(iw) along the imaginary axis.
466 
467   procedure :: get_a2fw => gstore_get_a2fw
468   ! Compute Eliashberg function a^2F(w).
469 
470   procedure :: from_ncpath => gstore_from_ncpath
471   ! Reconstruct object from netcdf file
472 
473   procedure :: init => gstore_init
474   ! Build object
475 
476 end type gstore_t

m_gstore/priority_from_eph_task [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 priority_from_eph_task

FUNCTION

INPUTS

OUTPUT

SOURCE

921 subroutine priority_from_eph_task(eph_task, priority)
922 
923 !Arguments ------------------------------------
924  integer,intent(in) :: eph_task
925  character(len=*),intent(out) :: priority
926 !----------------------------------------------------------------------
927 
928  select case (eph_task)
929  case (11)
930    priority = "qk"
931  case (12, -12)
932    priority = "q"
933  case (14)
934    priority = "kq"
935  case default
936    ABI_ERROR(sjoin("Please register default priority for eph_task:", itoa(eph_task)))
937  end select
938 
939 end subroutine priority_from_eph_task

m_gstore/recompute_select_qbz_spin [ Functions ]

[ Top ] [ m_gstore ] [ Functions ]

NAME

 recompute_select_qbz_spin

FUNCTION

 Recompute select_qbz_spin table after the filtering on the k-points.

INPUTS

OUTPUT

SOURCE

1657 subroutine recompute_select_qbz_spin(gstore, qbz, qbz2ibz, qibz2bz, kbz, kibz, kbz2ibz, kibz2bz, &
1658                                      select_kbz_spin, select_qbz_spin)
1659 
1660 !Arguments ------------------------------------
1661 !scalars
1662  class(gstore_t),target,intent(inout) :: gstore
1663 !arrays
1664  real(dp),intent(in) :: qbz(3, gstore%nqbz)
1665  integer,intent(in) :: qbz2ibz(6,gstore%nqbz), qibz2bz(gstore%nqibz)
1666  integer,intent(in) :: kbz2ibz(6,gstore%nkbz), kibz2bz(gstore%nkibz)
1667  real(dp),target,intent(in) :: kibz(3, gstore%nkibz), kbz(3, gstore%nkbz)
1668  integer,intent(in) :: select_kbz_spin(gstore%nkbz, gstore%nsppol)
1669  integer,intent(out) :: select_qbz_spin(gstore%nqbz, gstore%nsppol)
1670 
1671 !Local variables-------------------------------
1672 !scalars
1673  integer :: all_nproc, my_rank, ierr
1674  integer :: ii, iq_bz, iq_ibz, ikq_ibz, ikq_bz, len_kpts_ptr, ebands_timrev
1675 !arrays
1676  integer,allocatable :: map_kq(:,:)
1677  real(dp):: qpt(3)
1678  real(dp),contiguous, pointer :: kpts_ptr(:,:)
1679 
1680 ! *************************************************************************
1681 
1682  ABI_UNUSED(kbz2ibz)
1683  ABI_UNUSED(qbz2ibz)
1684 
1685  all_nproc = xmpi_comm_size(gstore%comm); my_rank = xmpi_comm_rank(gstore%comm)
1686  ebands_timrev = kpts_timrev_from_kptopt(gstore%ebands%kptopt)
1687 
1688  select_qbz_spin = 0
1689 
1690  if (gstore%kzone == "ibz") kpts_ptr => kibz
1691  if (gstore%kzone == "bz")  kpts_ptr => kbz
1692  len_kpts_ptr = size(kpts_ptr, dim=2)
1693  ABI_MALLOC(map_kq, (6, len_kpts_ptr))
1694 
1695  select case (gstore%qzone)
1696  case ("ibz")
1697    do iq_ibz=1,gstore%nqibz
1698      if (mod(iq_ibz, all_nproc) /= my_rank) cycle ! MPI parallelism.
1699      qpt = gstore%qibz(:, iq_ibz)
1700      iq_bz = qibz2bz(iq_ibz)
1701      ! k + q_ibz --> k IBZ --> k BZ
1702 
1703      if (kpts_map("symrel", ebands_timrev, gstore%cryst, gstore%krank_ibz, len_kpts_ptr, kpts_ptr, map_kq, qpt=qpt) /= 0) then
1704        ABI_ERROR("Cannot map k+q to IBZ!")
1705      end if
1706 
1707      do ii=1,len_kpts_ptr
1708        ikq_ibz = map_kq(1, ii)
1709        ikq_bz = kibz2bz(ikq_ibz)
1710        select_qbz_spin(iq_bz, :) = select_qbz_spin(iq_bz, :) + select_kbz_spin(ikq_bz, :)
1711      end do
1712    end do ! iq_ibz
1713 
1714  case ("bz")
1715    do iq_bz=1,gstore%nqbz
1716      if (mod(iq_bz, all_nproc) /= my_rank) cycle ! MPI parallelism.
1717      qpt = qbz(:, iq_bz)
1718      !iq_ibz = qbz2ibz(1, iq_bz)
1719      ! k + q_bz --> k IBZ --> k BZ
1720 
1721      if (kpts_map("symrel", ebands_timrev, gstore%cryst, gstore%krank_ibz, len_kpts_ptr, kpts_ptr, map_kq, qpt=qpt) /= 0) then
1722        ABI_ERROR("Cannot map k+q to IBZ!")
1723      end if
1724 
1725      do ii=1,len_kpts_ptr
1726        ikq_ibz = map_kq(1, ii)
1727        ikq_bz = kibz2bz(ikq_ibz)
1728        select_qbz_spin(iq_bz, :) = select_qbz_spin(iq_bz, :) + select_kbz_spin(ikq_bz, :)
1729      end do
1730    end do
1731  end select
1732 
1733  call xmpi_sum(select_qbz_spin, gstore%comm, ierr)
1734 
1735  ABI_FREE(map_kq)
1736 
1737 end subroutine recompute_select_qbz_spin