TABLE OF CONTENTS
ABINIT/m_nesting [ Modules ]
NAME
m_nesting
FUNCTION
This module provides functions to compute the nesting factor: N(\qq) = \sum_{mn\kk} \delta(\ee_{\kpq m}) \delta(\ee_{\kk n})
COPYRIGHT
Copyright (C) 2008-2024 ABINIT group (MG, MJV) 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
17 #if defined HAVE_CONFIG_H 18 #include "config.h" 19 #endif 20 21 #include "abi_common.h" 22 23 module m_nesting 24 25 use defs_basis 26 use m_errors 27 use m_abicore 28 use m_krank 29 use m_sort 30 31 use m_numeric_tools, only : wrap2_zero_one, interpol3d_0d 32 use m_io_tools, only : open_file 33 use m_bz_mesh, only : make_path 34 use m_pptools, only : printxsf 35 36 implicit none 37 38 private 39 40 public :: bfactor 41 public :: mknesting 42 public :: outnesting
m_nesting/bfactor [ Functions ]
[ Top ] [ m_nesting ] [ Functions ]
NAME
bfactor
FUNCTION
Calculate the nesting factor
INPUTS
nkptfull = number of k-points in full grid kptfull(3,nkptfull) = k-point grid nqpt = number of qpoints qpt(3,nqpt) = q-point grid (must be a subgrid of the k grid), the nesting factor will be calculated for each q point in this array nkpt = eventually reduced number of k-points weight(nband,nkpt) = integration weights for each k-point and band (NOT NORMALISED!!!) nband = number of bands
OUTPUT
nestfactor(nqpt) = array containing the nesting factor values
NOTES
Inspired to nmsq_gam_sumfs and mkqptequiv TODO : better use of symmetries to reduce the computational effort Must be called with kpt = full grid! Reduction by symmetry is not possible for q-dependent quantities (or not easy :)
SOURCE
77 subroutine bfactor(nkptfull,kptfull,nqpt,qpt,krank,nkpt,weight,nband,nestfactor) 78 79 !Arguments ------------------------------------ 80 !scalars 81 integer,intent(in) :: nband,nkptfull,nqpt,nkpt 82 !arrays 83 real(dp),intent(in) :: kptfull(3,nkptfull),qpt(3,nqpt),weight(nband,nkpt) 84 real(dp),intent(out) :: nestfactor(nqpt) 85 type(krank_t), intent(in) :: krank 86 87 !Local variables------------------------------- 88 !scalars 89 integer :: ib1,ib2,ikplusq_irr,ikpt 90 integer :: irank_kpt,ikpt_irr,iqpt,symrank_kpt 91 real(dp) :: w1,w2 92 !character(len=500) :: msg 93 !arrays 94 real(dp) :: kptpq(3) 95 96 ! ************************************************************************* 97 98 nestfactor(:)=zero 99 100 do iqpt=1,nqpt 101 do ikpt=1,nkptfull 102 irank_kpt = krank%get_rank(kptfull(:,ikpt)) 103 ikpt_irr = krank%invrank(irank_kpt) 104 105 kptpq(:) = kptfull(:,ikpt) + qpt(:,iqpt) 106 symrank_kpt = krank%get_rank(kptpq) 107 108 ikplusq_irr = krank%invrank(symrank_kpt) 109 if (ikplusq_irr == -1) then 110 ABI_ERROR('It looks like no kpoint equiv to k+q!') 111 end if 112 113 do ib1=1,nband 114 w1 = weight(ib1, ikpt_irr) ! weight for distance from the Fermi surface 115 if (w1 < tol6 ) cycle 116 do ib2=1,nband 117 w2 = weight(ib2, ikplusq_irr) ! weight for distance from the Fermi surface 118 if (w1 < tol6 ) cycle 119 nestfactor(iqpt) = nestfactor(iqpt) + w1 * w2 120 end do !ib2 121 end do !ib1 122 123 end do !ikpt 124 end do !iqpt 125 126 ! need prefactor of (1/nkptfull) for normalisation of integration 127 nestfactor(:) = (one/nkptfull) * nestfactor(:) 128 129 end subroutine bfactor
m_nesting/mknesting [ Functions ]
[ Top ] [ m_nesting ] [ Functions ]
NAME
mknesting
FUNCTION
Calculate the nesting factor over the dense k-grid, interpolate the values along a given q path and write the data on file in the X-Y format or in the XCrysden format (XSF)
INPUTS
nkpt = number of k points kpt(3,nkpt) = k points nkx, nky, nkz = number of k-point along each direction nband = number of bands to be considered in the calculation weight(nband,nkpt) = integration weights for each k-point and band nqpath = number of points requested along the trajectory qpath_vertices = vertices of the reciprocal space trajectory base_name = prefix of the output file gprimd(3,3) dimensional reciprocal lattice vectors gmet = metric in reciprocal space prtnest = flags governing the format of the output file
OUTPUT
Write data to file.
SOURCE
160 subroutine mknesting(nkpt,kpt,kptrlatt,nband,weight,nqpath,& 161 qpath_vertices,nqptfull,qptfull,base_name,gprimd,gmet,prtnest,qptrlatt,& 162 nsym,symrec) ! optional 163 164 !Arguments ------------------------------------ 165 !scalars 166 integer,intent(in) :: nband,nkpt,nqpath,prtnest 167 integer, intent(in) :: nqptfull 168 integer, intent(in), optional :: nsym 169 character(len=*),intent(in) :: base_name 170 !arrays 171 integer,intent(in) :: kptrlatt(3,3) 172 integer,intent(in),optional :: symrec(3,3,*) 173 real(dp),intent(in) :: gprimd(3,3),kpt(3,nkpt) 174 real(dp),intent(in) :: qptfull(3,nqptfull) 175 real(dp),intent(in) :: gmet(3,3) 176 real(dp),intent(in) :: qpath_vertices(3,nqpath) 177 real(dp),intent(in) :: weight(nband,nkpt) 178 integer,intent(in) :: qptrlatt(3,3) 179 180 !Local variables------------------------------- 181 !scalars 182 integer :: ikpt,jkpt 183 integer :: ik1, ik2, ik3, nkptfull 184 character(len=500) :: msg 185 type(krank_t) :: krank 186 !arrays 187 integer,allocatable :: tmprank(:),ktable(:) 188 character(len=fnlen) :: tmpname 189 real(dp),allocatable :: nestfactor(:),nestordered(:) 190 real(dp), allocatable :: kptfull(:,:) 191 192 ! ************************************************************************* 193 194 if (kptrlatt(1,2) /= 0 .or. kptrlatt(1,3) /= 0 .or. kptrlatt(2,1) /= 0 .or. & 195 kptrlatt(2,3) /= 0 .or. kptrlatt(3,1) /= 0 .or. kptrlatt(3,2) /= 0 ) then 196 write (msg,'(4a)')& 197 'kptrlatt should be diagonal in order to calculate the nesting factor,',ch10,& 198 'skipping the nesting factor calculation ',ch10 199 ABI_WARNING(msg) 200 return 201 end if 202 203 if (prtnest /= 1 .and. prtnest /= 2) then 204 ABI_BUG('prtnest should be 1 or 2') 205 end if 206 207 !write(msg,'(a,9(i0,1x))')' mknesting : kptrlatt = ',kptrlatt 208 !call wrtout(std_out,msg,'COLL') 209 210 nkptfull = kptrlatt(1,1)*kptrlatt(2,2)*kptrlatt(3,3) 211 ABI_CALLOC(nestordered, (nkptfull)) 212 ABI_MALLOC(kptfull,(3,nkptfull)) 213 214 ikpt = 0 215 do ik3 = 0, kptrlatt(3,3)-1 216 do ik2 = 0, kptrlatt(2,2)-1 217 do ik1 = 0, kptrlatt(1,1)-1 218 ikpt = ikpt+1 219 kptfull(:,ikpt) = [dble(ik1)/dble(kptrlatt(1,1)), dble(ik2)/dble(kptrlatt(2,2)),dble(ik3)/dble(kptrlatt(3,3))] 220 end do 221 end do 222 end do 223 224 ! NOTE: input weights are not normalised, the normalisation factor in introduced in bfactor 225 ! new version now puts kptfull in correct order before bfactor, so no need to re-order... 226 if (present(symrec)) then 227 ABI_CHECK(present(nsym), "error - provide nsym and symrec arguments together") 228 krank = krank_new(nkpt, kpt, nsym=nsym, symrec=symrec) 229 else 230 krank = krank_new(nkpt, kpt) 231 end if 232 233 call bfactor(nkptfull, kptfull, nkptfull, kptfull, krank, nkpt, weight, nband, nestordered) 234 235 !================================================================================================ 236 !use linear interpolation to plot the bfactor along the given q-path 237 ! 1) order the kpoints of the grid putting them in increasing x, then y, then z (FORTRAN convention) 238 ! 2) make table from input kpts to ordered kpts 239 ! 3) perform interpolation 240 !================================================================================================ 241 242 call outnesting(base_name,gmet,gprimd,kptrlatt,nestordered,nkptfull,nqpath,prtnest,qpath_vertices) 243 ABI_FREE(nestordered) 244 245 ! Now do the same, but for the nesting factor over the phonon qpoints only 246 ABI_MALLOC(nestfactor, (nqptfull)) 247 call bfactor(nkptfull,kptfull,nqptfull,qptfull,krank,nkpt,weight,nband,nestfactor) 248 249 call krank%free() 250 ABI_FREE(kptfull) 251 252 krank = krank_new(nqptfull, qptfull) 253 254 ABI_MALLOC(ktable,(nqptfull)) 255 do ikpt=1,nqptfull 256 ktable(ikpt) = ikpt 257 end do 258 259 ABI_MALLOC(tmprank, (nqptfull)) 260 do ikpt=1,nqptfull 261 tmprank(ikpt) = krank%get_rank(qptfull(:,ikpt)) 262 end do 263 call sort_int(nqptfull, tmprank, ktable) 264 ABI_FREE(tmprank) 265 call krank%free() 266 267 !fill the datagrid for the nesting factor using the Fortran convention and the conventional unit cell 268 !NOTE: the Fortran convention is a must if we want to plot the data 269 !in the BXSF format, useful for the linear interpolation since we use interpol3d_0d.F90 270 ABI_MALLOC(nestordered,(nqptfull)) 271 nestordered(:)=zero 272 do jkpt=1,nqptfull 273 ikpt = ktable(jkpt) 274 nestordered(ikpt)=nestfactor(jkpt) 275 end do 276 ABI_FREE(nestfactor) 277 ABI_FREE(ktable) 278 279 tmpname = trim(base_name)//"kplusq" 280 call outnesting(tmpname,gmet,gprimd,qptrlatt,nestordered,nqptfull,nqpath,prtnest,qpath_vertices) 281 282 ABI_FREE(nestordered) 283 284 end subroutine mknesting
m_nesting/outnesting [ Functions ]
[ Top ] [ m_nesting ] [ Functions ]
NAME
outnesting
FUNCTION
Write ou the nesting factors calculated in mknesting Data on file in the X-Y format (prtnest 1) or in the XCrysden format (XSF) (prtnest 2)
INPUTS
base_name = prefix of the output file gmet = metric in reciprocal space gprimd(3,3) dimensional reciprocal lattice vectors kptrlatt(3,3) basis vectors for k-grid nestordered = nesting function on full grid, points ordered in x, then y, then z nkpt = number of k points nqpath = number of points requested along the trajectory prtnest = flags governing the format of the output file qpath_vertices = vertices of the reciprocal space trajectory
OUTPUT
only write to file
SOURCE
314 subroutine outnesting(base_name,gmet,gprimd,kptrlatt,nestordered,nkpt,nqpath,prtnest,qpath_vertices) 315 316 !Arguments ------------------------------------ 317 integer,intent(in) :: nqpath,prtnest,nkpt 318 character(len=*),intent(in) :: base_name 319 !arrays 320 integer,intent(in) :: kptrlatt(3,3) 321 real(dp),intent(in) :: gprimd(3,3), gmet(3,3) 322 real(dp),intent(in) :: qpath_vertices(3,nqpath), nestordered(nkpt) 323 324 !Local variables------------------------------- 325 !scalars 326 integer :: unit_nest,nkx,nky,nkz,indx,ii,ipoint,npt_tot,realrecip 327 character(len=fnlen) :: fname 328 character(len=500) :: msg 329 real(dp) :: res(3), kval 330 !arrays 331 integer :: ndiv(nqpath-1) 332 real(dp),allocatable :: finepath(:,:) 333 real(dp) :: tmpkpt(3),origin(3),qpt(3) 334 ! dummy variables for call to printxsf 335 integer :: natom, ntypat, typat(1) 336 real(dp) :: xcart (3,1), znucl(1) 337 338 ! ************************************************************************* 339 340 ! Definition of the q path along which ph linwid will be interpolated 341 call make_path(nqpath,qpath_vertices,gmet,'G',20,ndiv,npt_tot,finepath) 342 343 nkx = kptrlatt(1,1) 344 nky = kptrlatt(2,2) 345 nkz = kptrlatt(3,3) 346 347 if (nkpt /= nkx*nky*nkz) then 348 write(msg,'(a,9(i0,1x),2x,i0)')' Wrong input value for kptrlatt ',kptrlatt, nkpt 349 ABI_BUG(msg) 350 end if 351 352 ! Open output file and write header 353 if (open_file(base_name,msg,newunit=unit_nest,status="unknown",form="formatted",action="write") /= 0) then 354 ABI_ERROR(msg) 355 end if 356 357 write(unit_nest,'(a)')'#' 358 write(unit_nest,'(a)')'# ABINIT package : Nesting factor file' 359 write(unit_nest,'(a)')'#' 360 write(unit_nest,'(a,i10,a)')'# Nesting factor calculated on ',npt_tot,' Q-points' 361 write(unit_nest,'(a)')'# Description of the Q-path :' 362 write(unit_nest,'(a,i10)')'# Number of line segments = ',nqpath-1 363 write(unit_nest,'(a)')'# Vertices of the Q-path and corresponding index = ' 364 indx=1 365 do ii=1,nqpath 366 write(unit_nest,'(a,3(E16.6,1x),i8)')'# ',qpath_vertices(:,ii),indx 367 if(ii<nqpath) indx=indx+ndiv(ii) 368 end do 369 write(unit_nest,'(a)')'#' 370 371 !Get qpoint along the q-path from finepath and interpolate the nesting factor 372 indx=1 373 374 write (unit_nest,'(a)')'# index nesting, qfrac_coords' 375 do ipoint=1, npt_tot 376 qpt(:) = finepath(:,ipoint) 377 call wrap2_zero_one(qpt, tmpkpt, res) 378 kval = interpol3d_0d(tmpkpt, nkx, nky, nkz, nestordered) 379 write(unit_nest,'(i5,e16.5,1x,3(es11.4,1x))')indx,kval,tmpkpt 380 indx = indx + 1 381 end do 382 383 close (unit_nest) 384 ABI_FREE(finepath) 385 386 if (prtnest==2) then 387 ! write also the nesting factor in the XSF format 388 fname = trim(base_name) // '_NEST_XSF' 389 390 if (open_file(fname,msg,newunit=unit_nest,status="unknown",form="formatted",action="write") /= 0) then 391 ABI_ERROR(msg) 392 end if 393 394 origin(:) = zero 395 realrecip = 1 !reciprocal space 396 natom = 1 397 ntypat = 1 398 typat = [1] 399 xcart = reshape ([zero, zero, zero], [3, 1]) 400 znucl = [one] 401 call printxsf(nkx,nky,nkz,nestordered,gprimd,origin,natom, ntypat, typat, xcart, znucl, unit_nest,realrecip) 402 403 close (unit_nest) 404 end if 405 406 end subroutine outnesting