TABLE OF CONTENTS
ABINIT/testkgrid [ Functions ]
NAME
testkgrid
FUNCTION
Test different grids of k points. The algorithm used is based on the idea of testing different one-dimensional sets of possible k point grids. It is not exhaustive (other families could be included), but should do a respectable job in all cases. The Monkhorst-Pack set of grids (defined with respect to symmetry axes, and not primitive axes) is always tested.
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) iout=unit number for echoed output msym=default maximal number of symmetries nsym=number of symetries prtkpt=if non-zero, will write the characteristics of k grids, then stop rprimd(3,3)=dimensional real space primitive translations (bohr) 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
kptrlatt(3,3)=k-point lattice specification nshiftk=number of k-point shifts in shiftk (always 1 from this routine) shiftk(3,210)=shift vectors for k point generation
SIDE EFFECTS
kptrlen=length of the smallest real space supercell vector associated with the lattice of k points.
NOTES
Note that nkpt can be computed by calling this routine with input value nkpt=0 Note that kptopt is always =1 in this routine.
PARENTS
inkpts,m_ab7_kpoints
CHILDREN
getkgrid,leave_new,matr3inv,metric,smallprim,wrtout,xmpi_abort
SOURCE
53 #if defined HAVE_CONFIG_H 54 #include "config.h" 55 #endif 56 57 #include "abi_common.h" 58 59 subroutine testkgrid(bravais,iout,kptrlatt,kptrlen,& 60 & msym,nshiftk,nsym,prtkpt,rprimd,shiftk,symafm,symrel,vacuum) 61 62 use defs_basis 63 use m_errors 64 use m_profiling_abi 65 use m_xmpi 66 67 use m_geometry, only : metric 68 69 !This section has been created automatically by the script Abilint (TD). 70 !Do not modify the following lines by hand. 71 #undef ABI_FUNC 72 #define ABI_FUNC 'testkgrid' 73 use interfaces_14_hidewrite 74 use interfaces_16_hideleave 75 use interfaces_32_util 76 use interfaces_41_geometry 77 use interfaces_56_recipspace, except_this_one => testkgrid 78 !End of the abilint section 79 80 implicit none 81 82 !Arguments ------------------------------------ 83 !scalars 84 integer,intent(in) :: iout,msym,nsym,prtkpt 85 integer,intent(out) :: nshiftk 86 real(dp),intent(inout) :: kptrlen 87 !arrays 88 integer,intent(in) :: bravais(11),symafm(msym),symrel(3,3,msym),vacuum(3) 89 integer,intent(out) :: kptrlatt(3,3) 90 real(dp),intent(in) :: rprimd(3,3) 91 real(dp),intent(inout) :: shiftk(3,210) !vz_i 92 93 !Local variables------------------------------- 94 !scalars 95 integer,parameter :: kptopt=1,mkpt_list=100000 96 integer :: ang90,center,dirvacuum,equal,igrid,igrid_current,iholohedry,ii,init_mult,iscale,iscf 97 integer :: iset,mult1,mult2,mult3,ndims,nkpt,nkpt_current,nkpt_trial,nset 98 real(dp) :: buffer_scale,determinant,fact,factor,kptrlen_current,kptrlen_max,kptrlen_target 99 real(dp) :: kptrlen_trial,length1,length2,length3,length_axis1,length_axis2 100 real(dp) :: length_axis3,merit_factor,mult1h,mult2h,mult3h,reduceda,reducedb 101 real(dp) :: sca,scb,scc,surface,ucvol 102 character(len=500) :: message 103 !arrays 104 integer :: kptrlatt_current(3,3),kptrlatt_trial(3,3) 105 integer,allocatable :: grid_list(:) 106 real(dp) :: axes(3,3),gmet(3,3),gprimd(3,3),matrix1(3,3),matrix2(3,3) 107 real(dp) :: metmin(3,3),minim(3,3),r2d(3,3),rmet(3,3),rsuper(3,3) 108 real(dp) :: shiftk_current(3,210),shiftk_trial(3,210) 109 real(dp),allocatable :: kpt(:,:),kptrlen_list(:),wtk(:) 110 111 ! ************************************************************************* 112 113 kptrlen_target=kptrlen 114 115 !The vacuum array must be made of 0 or 1 116 do ii=1,3 117 if(vacuum(ii)/=0 .and. vacuum(ii)/=1)then 118 write(message,'(a,a,a,i1,a,i3,a,a)')& 119 & 'The values of vacuum must be 0 or 1.',ch10,& 120 & 'However, the input vacuum(',ii,') is',vacuum(ii),ch10,& 121 & 'Action : correct vacuum in your input file.' 122 MSG_ERROR(message) 123 end if 124 end do 125 126 !Specific preparation for 2-dimensional system 127 if(sum(vacuum(:))==1)then 128 129 ! Make the non-active vector orthogonal to the active vectors, 130 ! and take it along the z direction 131 if(vacuum(1)==1)then 132 r2d(1,3)=rprimd(2,2)*rprimd(3,3)-rprimd(3,2)*rprimd(2,3) 133 r2d(2,3)=rprimd(3,2)*rprimd(1,3)-rprimd(1,2)*rprimd(3,3) 134 r2d(3,3)=rprimd(1,2)*rprimd(2,3)-rprimd(2,2)*rprimd(1,3) 135 r2d(:,1)=rprimd(:,2) 136 r2d(:,2)=rprimd(:,3) 137 dirvacuum=1 138 else if(vacuum(2)==1)then 139 r2d(1,3)=rprimd(2,3)*rprimd(3,1)-rprimd(3,3)*rprimd(2,1) 140 r2d(2,3)=rprimd(3,3)*rprimd(1,1)-rprimd(1,3)*rprimd(3,1) 141 r2d(3,3)=rprimd(1,3)*rprimd(2,1)-rprimd(2,3)*rprimd(1,1) 142 r2d(:,1)=rprimd(:,3) 143 r2d(:,2)=rprimd(:,1) 144 dirvacuum=2 145 else if(vacuum(3)==1)then 146 r2d(1,3)=rprimd(2,1)*rprimd(3,2)-rprimd(3,1)*rprimd(2,2) 147 r2d(2,3)=rprimd(3,1)*rprimd(1,2)-rprimd(1,1)*rprimd(3,2) 148 r2d(3,3)=rprimd(1,1)*rprimd(2,2)-rprimd(2,1)*rprimd(1,2) 149 r2d(:,1)=rprimd(:,1) 150 r2d(:,2)=rprimd(:,2) 151 dirvacuum=3 152 end if 153 surface=sqrt(sum(r2d(:,3)**2)) 154 ! Identify the 2-D Bravais lattice 155 ! DEBUG 156 ! write(std_out,*)' r2d=',r2d(:,:) 157 ! ENDDEBUG 158 call metric(gmet,gprimd,-1,rmet,r2d,ucvol) 159 call smallprim(metmin,minim,r2d) 160 ! DEBUG 161 ! write(std_out,*)' minim=',minim(:,:) 162 ! ENDDEBUG 163 ang90=0 ; equal=0 ; center=0 164 axes(:,:)=minim(:,:) 165 if(abs(metmin(1,2))<tol8)ang90=1 166 if(abs(metmin(1,1)-metmin(2,2))<tol8)equal=1 167 if(ang90==1)then 168 if(equal==1)iholohedry=4 169 if(equal==0)iholohedry=2 170 else if(equal==1)then 171 reduceda=metmin(1,2)/metmin(1,1) 172 if(abs(reduceda+0.5_dp)<tol8)then 173 iholohedry=3 174 else if(abs(reduceda-0.5_dp)<tol8)then 175 iholohedry=3 176 ! Use conventional axes 177 axes(:,2)=minim(:,2)-minim(:,1) 178 else 179 iholohedry=2 ; center=1 180 axes(:,1)=minim(:,1)+minim(:,2) 181 axes(:,2)=minim(:,2)-minim(:,1) 182 end if 183 else 184 reduceda=metmin(1,2)/metmin(1,1) 185 reducedb=metmin(1,2)/metmin(2,2) 186 if(abs(reduceda+0.5_dp)<tol8)then 187 iholohedry=2 ; center=1 188 axes(:,2)=2.0_dp*minim(:,2)+minim(:,1) 189 else if(abs(reduceda-0.5_dp)<tol8)then 190 iholohedry=2 ; center=1 191 axes(:,2)=2.0_dp*minim(:,2)-minim(:,1) 192 else if(abs(reducedb+0.5_dp)<tol8)then 193 iholohedry=2 ; center=1 194 axes(:,1)=2.0_dp*minim(:,1)+minim(:,2) 195 else if(abs(reducedb-0.5_dp)<tol8)then 196 iholohedry=2 ; center=1 197 axes(:,1)=2.0_dp*minim(:,1)-minim(:,2) 198 else 199 iholohedry=1 200 end if 201 end if 202 ! Make sure that axes form a right-handed coordinate system 203 determinant=axes(1,1)*axes(2,2)*axes(3,3) & 204 & +axes(1,2)*axes(2,3)*axes(3,1) & 205 & +axes(1,3)*axes(3,2)*axes(2,1) & 206 & -axes(1,1)*axes(3,2)*axes(2,3) & 207 & -axes(1,3)*axes(2,2)*axes(3,1) & 208 & -axes(1,2)*axes(2,1)*axes(3,3) 209 if(determinant<zero)then 210 axes(:,1)=-axes(:,1) 211 end if 212 ! Prefer symmetry axes on the same side as the primitive axes 213 sca=axes(1,1)*r2d(1,1)+axes(2,1)*r2d(2,1)+axes(3,1)*r2d(3,1) 214 scb=axes(1,2)*r2d(1,2)+axes(2,2)*r2d(2,2)+axes(3,2)*r2d(3,2) 215 scc=axes(1,3)*rprimd(1,dirvacuum)& 216 & +axes(2,3)*rprimd(2,dirvacuum)& 217 & +axes(3,3)*rprimd(3,dirvacuum) 218 if(sca<-tol8 .and. scb<-tol8)then 219 axes(:,1)=-axes(:,1) ; sca=-sca 220 axes(:,2)=-axes(:,2) ; scb=-scb 221 end if 222 ! Doing this might change the angle between vectors, so that 223 ! the cell is not conventional anymore 224 ! if(sca<-tol8 .and. scc<-tol8)then 225 ! axes(:,1)=-axes(:,1) ; sca=-sca 226 ! axes(:,3)=-axes(:,3) ; scc=-scc 227 ! end if 228 ! if(scb<-tol8 .and. scc<-tol8)then 229 ! axes(:,2)=-axes(:,2) ; scb=-scb 230 ! axes(:,3)=-axes(:,3) ; scc=-scc 231 ! end if 232 length_axis1=sqrt(axes(1,1)**2+axes(2,1)**2+axes(3,1)**2) 233 length_axis2=sqrt(axes(1,2)**2+axes(2,2)**2+axes(3,2)**2) 234 235 ! DEBUG 236 ! write(std_out,*)' testkgrid : iholohedry, center =',iholohedry,center 237 ! write(std_out,*)' testkgrid : axis 1=',axes(:,1) 238 ! write(std_out,*)' testkgrid : axis 2=',axes(:,2) 239 ! write(std_out,*)' testkgrid : axis 3=',axes(:,3) 240 ! write(std_out,*)' testkgrid : length_axis=',length_axis1,length_axis2 241 ! ENDDEBUG 242 243 ! End special treatment of 2-D case 244 end if 245 246 !3-dimensional system 247 if(sum(vacuum(:))==0)then 248 iholohedry=bravais(1) 249 center=bravais(2) 250 fact=1.0_dp 251 if(center/=0)fact=0.5_dp 252 matrix1(:,1)=bravais(3:5)*fact 253 matrix1(:,2)=bravais(6:8)*fact 254 matrix1(:,3)=bravais(9:11)*fact 255 call matr3inv(matrix1,matrix2) 256 do ii=1,3 257 axes(:,ii)=rprimd(:,1)*matrix2(ii,1)+rprimd(:,2)*matrix2(ii,2)+rprimd(:,3)*matrix2(ii,3) 258 end do 259 length_axis1=sqrt(axes(1,1)**2+axes(2,1)**2+axes(3,1)**2) 260 length_axis2=sqrt(axes(1,2)**2+axes(2,2)**2+axes(3,2)**2) 261 length_axis3=sqrt(axes(1,3)**2+axes(2,3)**2+axes(3,3)**2) 262 ! DEBUG 263 ! write(std_out,*)' testkgrid : axes=',axes(:,:) 264 ! write(std_out,*)' length_axis=',length_axis1,length_axis2,length_axis3 265 ! ENDDEBUG 266 end if 267 268 !This routine examine only primitive k lattices. 269 nshiftk=1 270 271 !If prtkpt/=0, will examine more grids than strictly needed 272 buffer_scale=one 273 if(prtkpt/=0)buffer_scale=two 274 275 if(prtkpt/=0)then 276 write(message,'(a,a,a,a,a,a,a,a)' )ch10,& 277 & ' testkgrid : will perform the analysis of a series of k-grids.',ch10,& 278 & ' Note that kptopt=1 in this analysis, irrespective of its input value.',ch10,ch10,& 279 & ' Grid# kptrlatt shiftk kptrlen nkpt iset',ch10 280 call wrtout(std_out,message,'COLL') 281 call wrtout(iout,message,'COLL') 282 ABI_ALLOCATE(grid_list,(mkpt_list)) 283 ABI_ALLOCATE(kptrlen_list,(mkpt_list)) 284 grid_list(:)=0 285 kptrlen_list(:)=0.0_dp 286 end if 287 288 if(sum(vacuum(:))==3)then 289 290 kptrlatt(:,:)=0 291 kptrlatt(1,1)=1 292 kptrlatt(2,2)=1 293 kptrlatt(3,3)=1 294 shiftk(:,1)=0.0_dp 295 kptrlen=1000.0_dp 296 nkpt_current=1 297 igrid_current=1 298 299 if(prtkpt/=0)then 300 write(message,& 301 & '(a,3i4,a,es14.4,a,es14.4,i8,i6,a,a,3i4,a,es14.4,a,a,3i4,a,es14.4,a)' )& 302 & ' 1 ',kptrlatt(:,1),' ',shiftk(1,1),' ',kptrlen,1,1,ch10,& 303 & ' ',kptrlatt(:,2),' ',shiftk(2,1),ch10,& 304 & ' ',kptrlatt(:,3),' ',shiftk(3,1),ch10 305 call wrtout(std_out,message,'COLL') 306 call wrtout(iout,message,'COLL') 307 ! The unit cell volume is fake 308 ucvol=kptrlen**3 309 end if 310 311 else 312 313 nkpt=0 ; nkpt_current=0 ; iscf=1 ; iset=1 314 kptrlen_current=0.0_dp 315 mult1=0 ; mult2=0 ; mult3=0 ; init_mult=1 316 ABI_ALLOCATE(kpt,(3,nkpt)) 317 ABI_ALLOCATE(wtk,(nkpt)) 318 call metric(gmet,gprimd,-1,rmet,rprimd,ucvol) 319 320 ! Loop on different grids, the upper limit is only to avoid an infinite loop 321 do igrid=1,1000 322 323 kptrlatt_trial(:,:)=0 324 kptrlatt_trial(1,1)=1 325 kptrlatt_trial(2,2)=1 326 kptrlatt_trial(3,3)=1 327 shiftk_trial(:,1)=0.0_dp 328 329 ! 1-dimensional system 330 if(sum(vacuum(:))==2)then 331 if(vacuum(1)==0)then 332 kptrlatt_trial(1,1)=2*igrid ; shiftk_trial(1,1)=0.5_dp 333 else if(vacuum(2)==0)then 334 kptrlatt_trial(2,2)=2*igrid ; shiftk_trial(2,1)=0.5_dp 335 else if(vacuum(3)==0)then 336 kptrlatt_trial(3,3)=2*igrid ; shiftk_trial(3,1)=0.5_dp 337 end if 338 end if 339 340 ! 2-dimensional system 341 if(sum(vacuum(:))==1)then 342 343 ! Treat hexagonal holohedries separately 344 if(iholohedry==3)then 345 346 ! write(std_out,*)' testkgrid : 2D, hexagonal' 347 348 mult1=mult1+1 349 nset=4 350 if(iset==1)then 351 rsuper(:,1)=axes(:,1)*mult1 352 rsuper(:,2)=axes(:,2)*mult1 353 shiftk_trial(:,1)=0.0_dp 354 else if(iset==2)then 355 rsuper(:,1)=(axes(:,1)-axes(:,2)) *mult1 356 rsuper(:,2)=(axes(:,1)+2*axes(:,2))*mult1 357 shiftk_trial(1,1)=1.0_dp/3.0_dp 358 shiftk_trial(2,1)=1.0_dp/3.0_dp 359 else if(iset==3)then 360 rsuper(:,1)=(axes(:,1)-axes(:,2)) *mult1 361 rsuper(:,2)=(axes(:,1)+2*axes(:,2))*mult1 362 shiftk_trial(:,1)=0.0_dp 363 else if(iset==4)then 364 rsuper(:,1)=axes(:,1)*mult1 365 rsuper(:,2)=axes(:,2)*mult1 366 shiftk_trial(1,1)=0.5_dp 367 shiftk_trial(2,1)=0.5_dp 368 end if 369 370 else 371 ! Now treat all other holohedries 372 length1=length_axis1*mult1 373 length2=length_axis2*mult2 374 ! DEBUG 375 ! write(std_out,*)' testkgrid : (2d) length=',length1,length2 376 ! ENDDEBUG 377 if(abs(length1-length2)<tol8)then 378 mult1=mult1+1 379 mult2=mult2+1 380 else if(length1>length2)then 381 mult2=mult2+1 382 else if(length2>length1)then 383 mult1=mult1+1 384 end if 385 nset=4 386 ! iset==5 and 6 are allowed only for centered lattice 387 if(center==1)nset=6 388 if(iset==1 .or. iset==2)then 389 rsuper(:,1)=axes(:,1)*mult1 390 rsuper(:,2)=axes(:,2)*mult2 391 else if(iset==3 .or. iset==4)then 392 rsuper(:,1)=axes(:,1)*mult1-axes(:,2)*mult2 393 rsuper(:,2)=axes(:,1)*mult1+axes(:,2)*mult2 394 else if(iset==5 .or. iset==6)then 395 rsuper(:,1)=axes(:,1)*(mult1-0.5_dp)-axes(:,2)*(mult2-0.5_dp) 396 rsuper(:,2)=axes(:,1)*(mult1-0.5_dp)+axes(:,2)*(mult2-0.5_dp) 397 end if 398 ! This was the easiest way to code all even mult1 and mult2 pairs : 399 ! make separate series for this possibility. 400 if(iset==2 .or. iset==4 .or. iset==6)then 401 rsuper(:,1)=2.0_dp*rsuper(:,1) 402 rsuper(:,2)=2.0_dp*rsuper(:,2) 403 end if 404 shiftk_trial(1,1)=0.5_dp 405 shiftk_trial(2,1)=0.5_dp 406 407 end if 408 409 ! Put back the inactive direction 410 if(dirvacuum==1)then 411 rsuper(:,3)=rsuper(:,1) 412 shiftk_trial(3,1)=shiftk_trial(1,1) 413 rsuper(:,1)=rprimd(:,1) 414 shiftk_trial(1,1)=0.0_dp 415 else if(dirvacuum==2)then 416 rsuper(:,3)=rsuper(:,1) 417 shiftk_trial(3,1)=shiftk_trial(1,1) 418 rsuper(:,1)=rsuper(:,2) 419 shiftk_trial(1,1)=shiftk_trial(2,1) 420 rsuper(:,2)=rprimd(:,2) 421 shiftk_trial(2,1)=0.0_dp 422 else if(dirvacuum==3)then 423 rsuper(:,3)=rprimd(:,3) 424 shiftk_trial(3,1)=0.0_dp 425 end if 426 427 ! The supercell and the corresponding shift have been generated ! 428 ! Convert cartesian coordinates into kptrlatt_trial 429 do ii=1,3 430 kptrlatt_trial(:,ii)=nint( gprimd(1,:)*rsuper(1,ii)+& 431 & gprimd(2,:)*rsuper(2,ii)+& 432 & gprimd(3,:)*rsuper(3,ii) ) 433 end do 434 435 ! End of 2-dimensional system 436 end if 437 438 ! 3-dimensional system 439 if(sum(vacuum(:))==0)then 440 ! Treat hexagonal holohedries separately 441 if(iholohedry==6)then 442 length1=length_axis1*mult1 443 length3=length_axis3*mult3 444 ! DEBUG 445 ! write(std_out,*)' testkgrid : (hex) lengths=',length1,length2 446 ! ENDDEBUG 447 if(abs(length1-length3)<tol8)then 448 mult1=mult1+1 449 mult3=mult3+1 450 else if(length1>length3)then 451 mult3=mult3+1 452 else if(length3>length1)then 453 mult1=mult1+1 454 end if 455 nset=4 456 if(iset==1)then 457 rsuper(:,1)=axes(:,1)*mult1 458 rsuper(:,2)=axes(:,2)*mult1 459 rsuper(:,3)=axes(:,3)*mult3 460 shiftk_trial(:,1)=0.0_dp 461 shiftk_trial(3,1)=0.5_dp 462 else if(iset==2)then 463 rsuper(:,1)=(axes(:,1)-axes(:,2)) *mult1 464 rsuper(:,2)=(axes(:,1)+2*axes(:,2))*mult1 465 rsuper(:,3)=axes(:,3)*mult3 466 shiftk_trial(1,1)=1.0_dp/3.0_dp 467 shiftk_trial(2,1)=1.0_dp/3.0_dp 468 shiftk_trial(3,1)=0.5_dp 469 else if(iset==3)then 470 rsuper(:,1)=(axes(:,1)-axes(:,2)) *mult1 471 rsuper(:,2)=(axes(:,1)+2*axes(:,2))*mult1 472 rsuper(:,3)=axes(:,3)*mult3 473 shiftk_trial(:,1)=0.0_dp 474 shiftk_trial(3,1)=0.5_dp 475 else if(iset==4)then 476 rsuper(:,1)=axes(:,1)*mult1 477 rsuper(:,2)=axes(:,2)*mult1 478 rsuper(:,3)=axes(:,3)*mult3 479 shiftk_trial(:,1)=0.5_dp 480 end if 481 482 else 483 ! Now treat all other holohedries 484 length1=length_axis1*mult1 485 length2=length_axis2*mult2 486 length3=length_axis3*mult3 487 ! DEBUG 488 ! write(std_out,*)' testkgrid : length=',length1,length2,length3 489 ! ENDDEBUG 490 if(length2>length1+tol8 .and. length3>length1+tol8)then 491 mult1=mult1+1 492 else if(length1>length2+tol8 .and. length3>length2+tol8)then 493 mult2=mult2+1 494 else if(length1>length3+tol8 .and. length2>length3+tol8)then 495 mult3=mult3+1 496 else if(abs(length2-length3)<tol8 .and. & 497 & abs(length1-length3)<tol8 .and. & 498 & abs(length1-length2)<tol8 )then 499 mult1=mult1+1 ; mult2=mult2+1 ; mult3=mult3+1 500 else if(abs(length1-length2)<tol8)then 501 mult1=mult1+1 ; mult2=mult2+1 502 else if(abs(length1-length3)<tol8)then 503 mult1=mult1+1 ; mult3=mult3+1 504 else if(abs(length2-length3)<tol8)then 505 mult2=mult2+1 ; mult3=mult3+1 506 end if 507 nset=6 508 if(center==-1 .or. center==-3)nset=8 509 if(iset==1 .or. iset==2)then 510 ! Simple lattice of k points 511 rsuper(:,1)=axes(:,1)*mult1 512 rsuper(:,2)=axes(:,2)*mult2 513 rsuper(:,3)=axes(:,3)*mult3 514 shiftk_trial(:,1)=0.5_dp 515 else if(iset==3 .or. iset==4)then 516 ! FCC lattice of k points = BCC lattice in real space 517 rsuper(:,1)=-axes(:,1)*mult1+axes(:,2)*mult2+axes(:,3)*mult3 518 rsuper(:,2)= axes(:,1)*mult1-axes(:,2)*mult2+axes(:,3)*mult3 519 rsuper(:,3)= axes(:,1)*mult1+axes(:,2)*mult2-axes(:,3)*mult3 520 shiftk_trial(:,1)=0.5_dp 521 else if(iset==5 .or. iset==6)then 522 ! BCC lattice of k points = FCC lattice in real space 523 rsuper(:,1)= axes(:,2)*mult2+axes(:,3)*mult3 524 rsuper(:,2)= axes(:,1)*mult1 +axes(:,3)*mult3 525 rsuper(:,3)= axes(:,1)*mult1+axes(:,2)*mult2 526 ! The BCC lattice has no empty site with full symmetry 527 shiftk_trial(:,1)=0.0_dp 528 else if(iset==7 .or. iset==8)then 529 ! iset==7 and 8 are allowed only for centered lattice 530 mult1h=mult1-0.5_dp 531 mult2h=mult2-0.5_dp 532 mult3h=mult3-0.5_dp 533 if(center==-1)then 534 ! FCC lattice of k points = BCC lattice in real space 535 rsuper(:,1)=-axes(:,1)*mult1h+axes(:,2)*mult2h+axes(:,3)*mult3h 536 rsuper(:,2)= axes(:,1)*mult1h-axes(:,2)*mult2h+axes(:,3)*mult3h 537 rsuper(:,3)= axes(:,1)*mult1h+axes(:,2)*mult2h-axes(:,3)*mult3h 538 shiftk_trial(:,1)=0.5_dp 539 else if(center==-3)then 540 ! BCC lattice of k points = FCC lattice in real space 541 rsuper(:,1)= axes(:,2)*mult2h+axes(:,3)*mult3h 542 rsuper(:,2)= axes(:,1)*mult1h +axes(:,3)*mult3h 543 rsuper(:,3)= axes(:,1)*mult1h+axes(:,2)*mult2h 544 ! The BCC lattice has no empty site with full symmetry 545 shiftk_trial(:,1)=0.0_dp 546 end if 547 end if 548 ! This was the easiest way to code all even mult1, mult2, mult3 triplets : 549 ! make separate series for this possibility. 550 if(2*(iset/2)==iset)then 551 rsuper(:,1)=2.0_dp*rsuper(:,1) 552 rsuper(:,2)=2.0_dp*rsuper(:,2) 553 rsuper(:,3)=2.0_dp*rsuper(:,3) 554 end if 555 end if 556 557 ! DEBUG 558 ! write(std_out,*)' testkgrid : gprimd=',gprimd(:,:) 559 ! write(std_out,*)' testkgrid : rsuper=',rsuper(:,:) 560 ! write(std_out,*)' testkgrid : iset =',iset 561 ! ENDDEBUG 562 563 564 ! The supercell and the corresponding shift have been generated ! 565 ! Convert cartesian coordinates into kptrlatt_trial 566 do ii=1,3 567 kptrlatt_trial(:,ii)=nint( gprimd(1,:)*rsuper(1,ii)+& 568 & gprimd(2,:)*rsuper(2,ii)+& 569 & gprimd(3,:)*rsuper(3,ii) ) 570 end do 571 572 ! End of 3-dimensional system 573 end if 574 575 ! DEBUG 576 ! write(std_out,*)' testkgrid : before getkgrid' 577 ! write(std_out,*)' testkgrid : rprimd=',rprimd(:,:) 578 ! write(std_out,*)' testkgrid : kptrlatt_trial=',kptrlatt_trial(:,:) 579 ! ENDDEBUG 580 581 call getkgrid(0,0,iscf,kpt,& 582 & kptopt,kptrlatt_trial,kptrlen_trial,& 583 & msym,nkpt,nkpt_trial,nshiftk,nsym,rprimd,& 584 & shiftk_trial,symafm,symrel,vacuum,wtk) 585 586 ! DEBUG 587 ! write(std_out,*)' testkgrid : after getkgrid' 588 ! ENDDEBUG 589 590 ! In case one does not need the full list of grids, will take a shortcut, and go to one of the last grids of the series, 591 ! that generates a kptrlen_trial that is just below kptrlen. 592 if(prtkpt==0 .and. init_mult==1 .and. kptrlen_trial<(half-tol8)*kptrlen )then 593 iscale=int((one-tol8)*kptrlen/kptrlen_trial) 594 mult1=mult1*iscale 595 mult2=mult2*iscale 596 mult3=mult3*iscale 597 init_mult=0 598 ! DEBUG 599 ! write(std_out,*)' testkgrid : iscale=',iscale 600 ! ENDDEBUG 601 kptrlatt_trial(:,:)=kptrlatt_trial(:,:)*iscale 602 call getkgrid(0,0,iscf,kpt,& 603 & kptopt,kptrlatt_trial,kptrlen_trial,& 604 & msym,nkpt,nkpt_trial,nshiftk,nsym,rprimd,& 605 & shiftk_trial,symafm,symrel,vacuum,wtk) 606 end if 607 608 if( (kptrlen_trial+tol8>kptrlen*(1.0_dp+tol8) .and. nkpt_current==0) .or. & 609 & (kptrlen_trial+tol8>kptrlen*(1.0_dp+tol8) .and. nkpt_trial<nkpt_current) .or. & 610 & (nkpt_trial==nkpt_current .and. kptrlen_trial>kptrlen_current*(1.0_dp+tol8)))then 611 612 kptrlatt_current(:,:)=kptrlatt_trial(:,:) 613 nkpt_current=nkpt_trial 614 shiftk_current(:,:)=shiftk_trial(:,:) 615 kptrlen_current=kptrlen_trial 616 igrid_current=igrid 617 end if 618 619 if(prtkpt/=0)then 620 write(message,'(i5,a,3i4,a,es14.4,a,es14.4,i8,i6,a,a,3i4,a,es14.4,a,a,3i4,a,es14.4,a)' )& 621 & igrid,' ',kptrlatt_trial(:,1),' ',shiftk_trial(1,1),& 622 & ' ',kptrlen_trial,nkpt_trial,iset,ch10,& 623 & ' ',kptrlatt_trial(:,2),' ',shiftk_trial(2,1),ch10,& 624 & ' ',kptrlatt_trial(:,3),' ',shiftk_trial(3,1),ch10 625 call wrtout(std_out,message,'COLL') 626 call wrtout(iout,message,'COLL') 627 628 ! Keep track of this grid, if it is worth 629 if(kptrlen_trial > kptrlen_list(nkpt_trial)*(1.0_dp+tol8))then 630 grid_list(nkpt_trial)=igrid 631 kptrlen_list(nkpt_trial)=kptrlen_trial 632 end if 633 end if 634 635 ! Treat 1-D case 636 if( sum(vacuum(:))==2 .and. kptrlen_trial>buffer_scale*(1.0_dp+tol8)*kptrlen )exit 637 638 ! Treat 2-D case or 3-D case 639 if( sum(vacuum(:))<=1 .and. kptrlen_trial>buffer_scale*(1.0_dp+tol8)*kptrlen )then 640 ! The present set of sets of k points is finished : 641 ! either it was the last, or one has to go to the next one 642 if(iset==nset)exit 643 iset=iset+1 644 mult1=0 ; mult2=0 ; mult3=0 ; init_mult=1 645 end if 646 647 end do ! igrid=1,1000 648 649 ABI_DEALLOCATE(kpt) 650 ABI_DEALLOCATE(wtk) 651 652 kptrlatt(:,:)=kptrlatt_current(:,:) 653 shiftk(:,:)=shiftk_current(:,:) 654 kptrlen=kptrlen_current 655 656 end if ! test on the number of dimensions 657 658 if(prtkpt/=0)then 659 660 ! sqrt(1/2) comes from the FCC packing, the best one 661 factor=sqrt(0.5_dp)/ucvol/dble(nsym) 662 ndims=3 663 if(sum(vacuum(:))/=0)then 664 if(sum(vacuum(:))==1)then 665 ! sqrt(3/4) comes from the hex packing, the best one 666 ! one multiplies by 2 because nsym is likely twice the number 667 ! of symmetries that can be effectively used in 2D 668 ndims=2 ; factor=sqrt(0.75_dp)/surface/dble(nsym)*2 669 write(message,'(2a)' )ch10,' Note that the system is bi-dimensional.' 670 else if(sum(vacuum(:))==2)then 671 ndims=1 ; factor=1/ucvol 672 write(message,'(2a)' )ch10,' Note that the system is uni-dimensional.' 673 else if(sum(vacuum(:))==3)then 674 ndims=0 675 write(message,'(2a)' )ch10,' Note that the system is zero-dimensional.' 676 end if 677 call wrtout(std_out,message,'COLL') 678 call wrtout(iout,message,'COLL') 679 end if 680 681 ! The asymptotic value of the merit factor is determined 682 ! by the set of symmetries : in 3D, if it includes the 683 ! inversion symmetry, the limit will be 1, if not, it 684 ! will be two. In 2D, if it includes the inversion symmetry 685 ! and an operation that maps z on -z, it will tend to one, 686 ! while if only one of these operations is present, 687 ! it will tend to two, and if none is present, it will tend to four. 688 write(message,'(11a)' )ch10,& 689 & ' List of best grids, ordered by nkpt.',ch10,& 690 & ' (stop at a value of kptrlen 20% larger than the target value).',ch10,& 691 & ' (the merit factor will tend to one or two in 3 dimensions)',ch10,& 692 & ' (and to one, two or four in 2 dimensions)',ch10,ch10,& 693 & ' nkpt kptrlen grid# merit_factor' 694 call wrtout(std_out,message,'COLL') 695 call wrtout(iout,message,'COLL') 696 697 kptrlen_max=0.0_dp 698 do ii=1,mkpt_list 699 if(kptrlen_list(ii)>kptrlen_max*(1.0_dp+tol8))then 700 kptrlen_max=kptrlen_list(ii) 701 merit_factor=kptrlen_max**ndims/dble(ii)*factor 702 write(message, '(i6,es14.4,i6,f12.4)' )ii,kptrlen_max,grid_list(ii),merit_factor 703 call wrtout(std_out,message,'COLL') 704 call wrtout(iout,message,'COLL') 705 end if 706 if(kptrlen_max>1.2_dp*(1.0_dp-tol8)*kptrlen_target)exit 707 end do 708 709 write(message,'(a,a,es14.4,a,a,i6,a,a,a,es14.4,a,i6)' )ch10,& 710 & ' For target kptrlen=',kptrlen_target,',',& 711 & ' the selected grid is number',igrid_current,',',ch10,& 712 & ' giving kptrlen=',kptrlen_current,' with nkpt=',nkpt_current 713 call wrtout(std_out,message,'COLL') 714 call wrtout(iout,message,'COLL') 715 716 write(message,'(a,a,a,a)' )ch10,& 717 & ' testkgrid : stop after analysis of a series of k-grids.',ch10,& 718 & ' For usual production runs, set prtkpt back to 0 (the default).' 719 call wrtout(std_out,message,'COLL',do_flush=.True.) 720 call wrtout(iout,message,'COLL',do_flush=.True.) 721 722 call xmpi_abort() 723 call leave_new('PERS',exit_status=0,print_config=.false.) 724 725 end if 726 727 end subroutine testkgrid