TABLE OF CONTENTS
ABINIT/inkpts [ Functions ]
NAME
inkpts
FUNCTION
Initialize k points (list of k points, weights, storage) for one particular dataset, characterized by jdtset. Note that nkpt (and nkpthf) can be computed by calling this routine with input value of nkpt=0, provided kptopt/=0.
COPYRIGHT
Copyright (C) 1998-2018 ABINIT group (DCA, XG, GMR) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
INPUTS
bravais(11): bravais(1)=iholohedry bravais(2)=center bravais(3:11)=coordinates of rprim in the axes of the conventional bravais lattice (*2 if center/=0) chksymbreak= if 1, will check whether the k point grid is symmetric, and stop if not. impose_istwf_1= (optional argument): 0: no restriction on istwfk 1: impose istwfk=1 for all k points 2: impose istwfk=1 for all k points non equal to zero iout=unit number for echoed output iscf= ( <= 0 =>non-SCF), >0 => SCF) jdtset=number of the dataset looked for lenstr=actual length of the string kptopt=option for the generation of k points msym=default maximal number of symmetries nqpt=number of q points (0 or 1) nsym=number of symetries occopt=option for occupation numbers qptn(3)=reduced coordinates of eventual q point shift (already normalized). response=0 if GS case, =1 if RF case. rprimd(3,3)=dimensional real space primitive translations (bohr) string*(*)=character string containing all the input data. Initialized previously in instrng. symafm(nsym)=(anti)ferromagnetic part of symmetry operations symrel(3,3,nsym)=symmetry operations in real space in terms of primitive translations vacuum(3)=for each direction, 0 if no vacuum, 1 if vacuum
OUTPUT
fockdownsampling(3)=echo of input variable fockdownsampling(3) kptnrm=normalisation of k points kptrlatt_orig(3,3)=Original value of kptrlatt as specified in the input file (if kptopt/=0) kptrlatt(3,3)=k-point lattice specification (if kptopt/=0) kptrlen=length of the smallest real space supercell vector nshiftk_orig=Original number of k-point shifts (0 if not read) nshiftk=actual number of k-point shifts in shiftk (if kptopt/=0) shiftk(3,210)=shift vectors for k point generation (if kptopt/=0) If nkpt/=0 the following arrays are also output : istwfk(nkpt)=option parameters that describes the storage of wfs kpt(3,nkpt)=reduced coordinates of k points. kpthf(3,nkpthf)=reduced coordinates of k points for Fock operator. wtk(nkpt)=weight assigned to each k point. ngkpt(3)=Number of divisions along the three reduced directions (0 signals that this variable has not been used. shiftk_orig(3,210)=Original shifts read from the input file (0 signals that this variable has not been read).
SIDE EFFECTS
Input/output: nkpt=number of k points if non-zero at input, is only an input variable if zero at input, its actual value will be computed nkpthf=number of k points for Fock operator, computed if nkpt=0 at input
NOTES
Warning: this routine can be called with nkpt=0 (in which case it returns the true value of nkpt), which can lead to strange bugs in the debugging procedure, if one tries to print wtk or istwfk, in this case !
PARENTS
invars1,invars2
CHILDREN
getkgrid,intagm,metric,mknormpath,testkgrid,timab,wrtout
SOURCE
88 #if defined HAVE_CONFIG_H 89 #include "config.h" 90 #endif 91 92 #include "abi_common.h" 93 94 subroutine inkpts(bravais,chksymbreak,fockdownsampling,iout,iscf,istwfk,jdtset,& 95 & kpt,kpthf,kptopt,kptnrm,kptrlatt_orig,kptrlatt,kptrlen,lenstr,msym,& 96 & nkpt,nkpthf,nqpt,ngkpt,nshiftk,nshiftk_orig,shiftk_orig,nsym,& 97 & occopt,qptn,response,rprimd,shiftk,string,symafm,symrel,vacuum,wtk,& 98 & impose_istwf_1) ! Optional argument 99 100 use defs_basis 101 use m_profiling_abi 102 use m_errors 103 104 use m_geometry, only : metric 105 use m_cgtools, only : set_istwfk 106 use m_parser, only : intagm 107 108 !This section has been created automatically by the script Abilint (TD). 109 !Do not modify the following lines by hand. 110 #undef ABI_FUNC 111 #define ABI_FUNC 'inkpts' 112 use interfaces_14_hidewrite 113 use interfaces_18_timing 114 use interfaces_32_util 115 use interfaces_56_recipspace 116 !End of the abilint section 117 118 implicit none 119 120 !Arguments ------------------------------------ 121 !scalars 122 integer,intent(in) :: chksymbreak,iout,iscf,jdtset,kptopt,lenstr,msym,nqpt,nsym,occopt 123 integer,intent(in) :: response 124 integer,intent(in),optional :: impose_istwf_1 125 integer,intent(inout) :: nkpt,nkpthf 126 integer,intent(out) :: nshiftk,nshiftk_orig 127 integer,intent(out) :: fockdownsampling(3) 128 real(dp),intent(out) :: kptnrm,kptrlen 129 character(len=*),intent(in) :: string 130 !arrays 131 integer,intent(in) :: bravais(11),symafm(msym),symrel(3,3,msym),vacuum(3) 132 integer,intent(out) :: istwfk(nkpt),kptrlatt(3,3),kptrlatt_orig(3,3),ngkpt(3) 133 real(dp),intent(in) :: rprimd(3,3),qptn(3) 134 real(dp),intent(out) :: kpt(3,nkpt),kpthf(3,nkpthf),shiftk(3,210),wtk(nkpt),shiftk_orig(3,210) 135 136 !Local variables------------------------------- 137 !scalars 138 integer :: dkpt,ii,ikpt,jkpt,marr,ndiv_small,nkpt_computed 139 integer :: nsegment,prtkpt,tread,tread_kptrlatt,tread_ngkpt 140 real(dp) :: fraction,norm,ucvol,wtksum 141 character(len=500) :: message 142 !arrays 143 integer,allocatable :: ndivk(:),intarr(:) 144 real(dp) :: gmet(3,3),gprimd(3,3),kpoint(3),rmet(3,3),tsec(2) 145 real(dp),allocatable :: kptbounds(:,:),dprarr(:) 146 147 ! ************************************************************************* 148 149 call timab(192,1,tsec) 150 151 !Compute the maximum size of arrays intarr and dprarr 152 marr=max(3*nkpt,3*210) 153 ABI_ALLOCATE(intarr,(marr)) 154 ABI_ALLOCATE(dprarr,(marr)) 155 156 !Use zero to signal that these values have not been read. 157 ngkpt = 0 158 shiftk_orig = zero 159 kptrlatt_orig = 0; kptrlatt = 0 160 nshiftk_orig = 1; nshiftk = 1 161 162 ! MG: FIXME These values should be initialized because they are intent(out) 163 ! but several tests fails. So we keep this bug to avoid problems somewhere else 164 ! The initialization of the kpoints should be rewritten in a cleaner way 165 ! without all these side effects! 166 !shiftk = zero 167 ! Initializing these three variables is OK but we keep the bug to preserve the old behavior 168 !wtk = one 169 !kpt = zero 170 !istwfk = 1 171 172 !Initialize kptrlen 173 kptrlen=30.0_dp 174 call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'kptrlen',tread,'DPR') 175 if(tread==1)kptrlen=dprarr(1) 176 177 !Initialize kpt, kptnrm and wtk according to kptopt. 178 !For kptopt==0, one must have nkpt defined. 179 if(kptopt==0)then 180 181 kpt(:,:)=zero 182 call intagm(dprarr,intarr,jdtset,marr,3*nkpt,string(1:lenstr),'kpt',tread,'DPR') 183 if(tread==1) kpt(:,:)=reshape( dprarr(1:3*nkpt), [3,nkpt]) 184 185 kptnrm=one 186 call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'kptnrm',tread,'DPR') 187 if(tread==1) kptnrm=dprarr(1) 188 189 ! Only read wtk when iscf >0 or iscf=-1 or iscf=-3 or (iscf=-2 and response=1) 190 ! (this last option is for Zach Levine) 191 ! Normalize the k-point weights when occopt/=2 192 ! Check that k point weights add to 1 when occopt==2 193 if (iscf>0.or.iscf==-1.or.iscf==-3.or.(iscf==-2.and.response==1)) then 194 195 call intagm(dprarr,intarr,jdtset,marr,nkpt,string(1:lenstr),'wtk',tread,'DPR') 196 if(tread==1) wtk(1:nkpt)=dprarr(1:nkpt) 197 198 wtksum=sum(wtk(:)) 199 write(message,'(a,i0,a,f12.6)')' inkpts: Sum of ',nkpt,' k point weights is',wtksum 200 call wrtout(std_out,message,'COLL') 201 202 if (wtksum<1.d-6) then 203 write(message, '(6a)' )& 204 & 'This sum is too close to zero. ',ch10,& 205 & 'Action: correct the array wtk in the input file.' 206 MSG_ERROR(message) 207 end if 208 if (abs(wtksum - one)>1.d-06) then 209 if(occopt==2)then 210 write(message, '(a,1p,e18.8,a,a,a)' )& 211 & 'wtksum=',wtksum,' /=1.0 means wts do not add to 1 , while occopt=2.',ch10,& 212 & 'Action: correct the array wtk in input file.' 213 MSG_ERROR(message) 214 else 215 write(message,'(a,i0,a)')' With present occopt= ',occopt,', renormalize it to one' 216 call wrtout(std_out,message,'COLL') 217 norm=one/wtksum 218 wtk(1:nkpt)=wtk(1:nkpt)*norm 219 end if 220 end if 221 end if 222 223 else if (kptopt<0) then 224 225 ! Band structure calculation 226 nsegment=abs(kptopt) 227 228 if(iscf/=-2)then 229 write(message, '(3a,i0,3a)' ) & 230 & 'For a negative kptopt, iscf must be -2,',ch10,& 231 & 'while it is found to be ',iscf,'.',ch10,& 232 & 'Action: change the value of iscf in your input file, or change kptopt.' 233 MSG_ERROR(message) 234 end if 235 236 if(marr<3*nsegment+3)then 237 marr=3*nsegment+3 238 ABI_DEALLOCATE(dprarr) 239 ABI_DEALLOCATE(intarr) 240 ABI_ALLOCATE(dprarr,(marr)) 241 ABI_ALLOCATE(intarr,(marr)) 242 end if 243 244 ABI_ALLOCATE(kptbounds,(3,nsegment+1)) 245 ABI_ALLOCATE(ndivk,(nsegment)) 246 247 call intagm(dprarr,intarr,jdtset,marr,3*nsegment+3,string(1:lenstr),'kptbounds',tread,'DPR') 248 249 if(tread==1)then 250 kptbounds(:,:)=reshape( dprarr(1:3*nsegment+3), [3,nsegment+1]) 251 else 252 write(message,'(5a)') & 253 & 'When kptopt is negative, kptbounds must be initialized ',ch10,& 254 & 'in the input file, which is not the case.',ch10,& 255 & 'Action: initialize kptbounds in your input file, or change kptopt.' 256 MSG_ERROR(message) 257 end if 258 259 call intagm(dprarr,intarr,jdtset,marr,nsegment,string(1:lenstr),'ndivk',tread,'INT') 260 if(tread==1)then 261 ndivk(1:nsegment)=intarr(1:nsegment) 262 ! The 1 stand for the first point 263 nkpt_computed=1+sum(ndivk(1:nsegment)) 264 265 ! ndivk and ndivsm are mutually exclusive 266 call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'ndivsm',tread,'INT') 267 if (tread == 1) then 268 MSG_ERROR("ndivk and ndivsm are mutually exclusive. Choose only one variable") 269 end if 270 271 else 272 ! Calculate ndivk such as the path is normalized 273 ! Note that if both ndivk and ndivsm are defined in in input file, only ndivk is used ! 274 call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'ndivsm',tread,'INT') 275 if(tread==1)then 276 ndiv_small=intarr(1) 277 call metric(gmet,gprimd,std_out,rmet,rprimd,ucvol) 278 call mknormpath(nsegment+1,kptbounds,gmet,ndiv_small,ndivk,nkpt_computed) 279 else 280 write(message,'(5a)') & 281 & 'When kptopt is negative, ndivsm or ndivk must be initialized ',ch10,& 282 & 'in the input file, which is not the case.',ch10,& 283 & 'Action : initialize ndivsm or ndivk in your input file, or change kptopt.' 284 MSG_ERROR(message) 285 end if 286 end if 287 288 ! Check that the argument nkpt is coherent with nkpt_computed, 289 if(nkpt/=0 .and. nkpt/=nkpt_computed)then 290 write(message, '(a,i0,5a,i0,7a)' ) & 291 & 'The argument nkpt= ',nkpt,', does not match',ch10,& 292 & 'the number of k points generated by kptopt, ndivk, kptbounds,',ch10,& 293 & 'and the eventual symmetries, that is, nkpt= ',nkpt_computed,'.',ch10,& 294 & 'However, note that it might due to the user,',ch10,& 295 & 'if nkpt is explicitely defined in the input file.',ch10,& 296 & 'In this case, please check your input file.' 297 MSG_ERROR(message) 298 end if 299 300 if (nkpt/=0) then 301 ! the array kpt has the right dimension and we can generate the k-path 302 call intagm(dprarr,intarr,jdtset,marr,3*nsegment+3,string(1:lenstr),'kptbounds',tread,'DPR') 303 if(tread==1)then 304 kptbounds(:,:)=reshape( dprarr(1:3*nsegment+3), [3,nsegment+1]) 305 else 306 write(message, '(5a)') & 307 & 'When kptopt is negative, kptbounds must be initialized ',ch10,& 308 & 'in the input file, which is not the case.',ch10,& 309 & 'Action: initialize kptbounds in your input file, or change kptopt.' 310 MSG_ERROR(message) 311 end if 312 313 ! First k point 314 jkpt=1 315 kpt(:,1)=kptbounds(:,1) 316 do ii=1,nsegment 317 dkpt=ndivk(ii) 318 do ikpt=1,dkpt 319 fraction=dble(ikpt)/dble(dkpt) 320 kpt(:,ikpt+jkpt)=fraction *kptbounds(:,ii+1)+(one-fraction)*kptbounds(:,ii) 321 end do 322 jkpt=jkpt+dkpt 323 end do 324 325 end if 326 327 kptnrm=one 328 call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'kptnrm',tread,'DPR') 329 if(tread==1) kptnrm=dprarr(1) 330 331 ABI_DEALLOCATE(kptbounds) 332 ABI_DEALLOCATE(ndivk) 333 334 else if (kptopt>=1 .and. kptopt<=4) then 335 ! Read ngkpt 336 call intagm(dprarr,intarr,jdtset,marr,3,string(1:lenstr),'ngkpt',tread_ngkpt,'INT') 337 if(tread_ngkpt==1)then 338 ngkpt(1:3)=intarr(1:3) 339 do ii=1,3 340 if(ngkpt(ii)<1)then 341 write(message,'(a,i0,3a,i0,3a)') & 342 & 'The input variable ngkpt(',ii,') must be strictly positive,',ch10,& 343 & 'while it is found to be',ngkpt(ii),'.',ch10,& 344 & 'Action: change it in your input file, or change kptopt.' 345 MSG_ERROR(message) 346 end if 347 end do 348 end if 349 350 call intagm(dprarr,intarr,jdtset,marr,9,string(1:lenstr),'kptrlatt',tread_kptrlatt,'INT') 351 if(tread_kptrlatt==1) kptrlatt(:,:)=reshape(intarr(1:9), [3,3]) 352 353 if(tread_ngkpt==1 .and. tread_kptrlatt==1)then 354 write(message, '(5a)' ) & 355 & 'The input variables ngkpt and kptrlatt cannot both ',ch10,& 356 & 'be defined in the input file.',ch10,& 357 & 'Action : change one of ngkpt or kptrlatt in your input file.' 358 MSG_ERROR(message) 359 else if(tread_ngkpt==1)then 360 kptrlatt(:,:)=0 361 kptrlatt(1,1)=ngkpt(1) 362 kptrlatt(2,2)=ngkpt(2) 363 kptrlatt(3,3)=ngkpt(3) 364 ! Save kptrlatt for reference. 365 kptrlatt_orig = kptrlatt 366 end if 367 368 call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'nshiftk',tread,'INT') 369 if(tread==1)nshiftk=intarr(1) 370 371 if(nshiftk<1 .or. nshiftk>210 )then 372 write(message, '(3a,i0,3a)' )& 373 & 'The only allowed values of nshiftk are between 1 and 210,',ch10,& 374 & 'while it is found to be',nshiftk,'.',ch10,& 375 & 'Action: change the value of nshiftk in your input file, or change kptopt.' 376 MSG_ERROR(message) 377 end if 378 379 call intagm(dprarr,intarr,jdtset,marr,3*nshiftk,string(1:lenstr),'shiftk',tread,'DPR') 380 if(tread==1)then 381 shiftk(:,1:nshiftk)=reshape( dprarr(1:3*nshiftk), [3,nshiftk]) 382 ! Save input shifts as they will be changes in getkgrid. 383 nshiftk_orig = nshiftk 384 shiftk_orig(:,1:nshiftk) = shiftk(:,1:nshiftk) 385 else 386 if(nshiftk/=1)then 387 write(message, '(3a,i0,2a)' )& 388 & 'When nshiftk is not equal to 1, shiftk must be defined in the input file.',ch10,& 389 & 'However, shiftk is not defined, while nshiftk=',nshiftk,ch10,& 390 & 'Action: change the value of nshiftk in your input file, or define shiftk.' 391 MSG_ERROR(message) 392 end if 393 ! Default values used in indefo 394 nshiftk_orig = 1 395 shiftk_orig(:,1:nshiftk) = half 396 end if 397 398 prtkpt=0 399 call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'prtkpt',tread,'INT') 400 if(tread==1)prtkpt=intarr(1) 401 402 if(sum(abs(kptrlatt(:,:)))==0)then 403 kptrlatt_orig = 0 404 do ii=1,3 405 kptrlatt_orig(ii,ii) = ngkpt(ii) 406 end do 407 408 ! The parameters of the k lattice are not known, compute kptrlatt, nshiftk, shiftk. 409 call testkgrid(bravais,iout,kptrlatt,kptrlen,& 410 & msym,nshiftk,nsym,prtkpt,rprimd,shiftk,symafm,symrel,vacuum) 411 412 end if 413 414 fockdownsampling(:)=1 415 call intagm(dprarr,intarr,jdtset,marr,3,string(1:lenstr),'fockdownsampling',tread,'INT') 416 if(tread==1)fockdownsampling=intarr(1:3) 417 418 call getkgrid(chksymbreak,0,iscf,kpt,kptopt,kptrlatt,kptrlen,& 419 & msym,nkpt,nkpt_computed,nshiftk,nsym,rprimd,& 420 & shiftk,symafm,symrel,vacuum,wtk,nkpthf=nkpthf,kpthf=kpthf,downsampling=fockdownsampling) 421 422 kptnrm=one 423 424 else 425 426 write(message, '(3a,i0,3a)' ) & 427 & 'The only values of kptopt allowed are smaller than 4.',ch10,& 428 & 'The input value of kptopt is',kptopt,'.',ch10,& 429 & 'Action: change kptopt in your input file.' 430 MSG_ERROR(message) 431 end if 432 433 if(kptnrm<tol10)then 434 write(message, '(5a)' )& 435 & 'The input variable kptnrm is lower than 1.0d-10,',ch10,& 436 & 'while it must be a positive, non-zero number. ',ch10,& 437 & 'Action: correct the kptnrm in the input file.' 438 MSG_ERROR(message) 439 end if 440 441 !The k point number has been computed, and, if nkpt/=0, also the list of k points. 442 !Also nkpthf has been computed, and, if nkpt/=0, also the list kpthf. 443 444 !Now, determine istwfk, and eventually shift the k points by the value of qptn. 445 446 if(nkpt/=0)then 447 448 istwfk(1:nkpt)=0 449 call intagm(dprarr,intarr,jdtset,marr,nkpt,string(1:lenstr),'istwfk',tread,'INT') 450 if(tread==1) istwfk(1:nkpt)=intarr(1:nkpt) 451 452 if(response==1)istwfk(1:nkpt)=1 ! Impose istwfk=1 for RF calculations 453 454 ! Also impose istwfk=1 for spinor calculations 455 call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'nspinor',tread,'INT') 456 if(tread/=0 .and. intarr(1)/=1)istwfk(1:nkpt)=1 457 458 call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'pawspnorb',tread,'INT') 459 if(tread/=0 .and. intarr(1)/=0)istwfk(1:nkpt)=1 460 461 do ikpt=1,nkpt 462 if(istwfk(ikpt)==0)then 463 kpoint=kpt(:,ikpt)/kptnrm; if (nqpt/=0.and.response==0) kpoint=kpoint+qptn 464 istwfk(ikpt) = set_istwfk(kpoint) 465 end if 466 if (present(impose_istwf_1)) then 467 if (impose_istwf_1==1) then 468 istwfk(ikpt)=1 469 else if (impose_istwf_1==2.and.any(kpt(:,ikpt)>tol10)) then 470 istwfk(ikpt)=1 471 end if 472 end if 473 end do 474 end if 475 476 !If nkpt was to be computed, transfer it from nkpt_computed 477 if(nkpt==0)nkpt=nkpt_computed 478 479 ABI_DEALLOCATE(intarr) 480 ABI_DEALLOCATE(dprarr) 481 482 call timab(192,2,tsec) 483 484 end subroutine inkpts