TABLE OF CONTENTS
ABINIT/getshell [ Functions ]
NAME
getshell
FUNCTION
For each k-point, set up the shells of first neighbours and find the weigths required for the finite difference expression of Marzari and Vanderbilt (see PRB 56, 12847 (1997) [[cite:Marzari1997]]).
INPUTS
gmet(3,3) = metric tensor of reciprocal space kptopt = option for the generation of k points kptrlatt = k-point lattice specification kpt2(3,nkpt2) = reduced coordinates of the k-points in the reduced part of the BZ (see below) mkmem = number of k points which can fit in memory nkpt2 = number of k-points in the reduced BZ nkpt3 = number of k-points in the full BZ nshiftk = number of kpoint grid shifts rmet(3,3) = metric tensor of real space rprimd(3,3) = dimensional primitive translations (bohr) shiftk = shift vectors for k point generation wtk2 = weight assigned to each k point comm=MPI communicator
OUTPUT
kneigh(30,nkpt2) = for each k-point in the reduced part of the BZ kneigh stores the index (ikpt) of the neighbouring k-points kg_neigh(30,nkpt2,3) = kg-neigh takes values of -1, 0 or 1, and can be non-zero only for a single k-point, a line of k-points or a plane of k-points. The vector joining the ikpt2-th k-point to its ineigh-th nearest neighbour is : dk(:)-nint(dk(:))+real(kg_neigh(ineigh,ikpt2,:)) with dk(:)=kpt2(:,kneigh(ineigh,ikpt2))-kpt2(:,ikpt2) kptindex(2,nkpt3) kptindex(1,ikpt) = ikpt_rbz ikpt_rbz = index of the k-point in the reduced BZ ikpt = index of the k-point in the full BZ kptindex(2,ikpt) = 1: use time-reversal symmetry to transform the wavefunction at ikpt_rbz to the wavefunction at ikpt 0: ikpt belongs already to the reduced BZ (no transformation required) kpt3(3,nkpt3) = reduced coordinates of the k-points in the full BZ mvwtk(30,nkpt2) = weights required to evaluate the finite difference formula of Marzari and Vanderbilt, computed for each k-point in the reduced part of the BZ mkmem_max = maximal number of k-points on each processor (MPI //) nneigh = total number of neighbours required to evaluate the finite difference formula COMMENTS The array kpt2 holds the reduced coordinates of the k-points in the reduced part of the BZ. For example, in case time-reversal symmetry is used (kptopt = 2) kpt2 samples half the BZ. Since some of the neighbours of these k-points may lie outside the reduced BZ, getshell also needs the coordinates of the k-points in the full BZ. The coordinates of the k-points in the full BZ are stored in kpt3. The weights mvwtk are computed for the k-points kpt2. In case no symmetry is used to reduce the number of k-points, the arrays kpt2 and kpt3 are equal.
SOURCE
109 subroutine getshell(gmet,kneigh,kg_neigh,kptindex,kptopt,kptrlatt,kpt2,& 110 & kpt3,mkmem,mkmem_max,mvwtk,& 111 & nkpt2,nkpt3,nneigh,nshiftk,rmet,rprimd,shiftk,wtk2, comm) 112 113 !Arguments ------------------------------------ 114 !scalars 115 integer,intent(in) :: kptopt,mkmem,nkpt2,nkpt3,comm 116 integer,intent(inout) :: nshiftk 117 integer,intent(out) :: mkmem_max,nneigh 118 !arrays 119 integer,intent(inout) :: kptrlatt(3,3) 120 integer,intent(out) :: kneigh(30,nkpt2),kptindex(2,nkpt3),kg_neigh(30,nkpt2,3) 121 real(dp),intent(in) :: gmet(3,3),kpt2(3,nkpt2),rmet(3,3),rprimd(3,3) 122 real(dp),intent(in) :: shiftk(3,nshiftk),wtk2(nkpt2) 123 real(dp),intent(out) :: kpt3(3,nkpt3),mvwtk(30,nkpt2) 124 125 !Local variables------------------------------- 126 !scalars 127 integer :: bis,flag,ier,ii,ikpt,ikpt2,ikpt3,ineigh,info,irank,is1,ishell 128 integer :: jj,kptopt_used,mkmem_cp,nkpt_computed,nshell,nsym1,orig 129 integer :: wtkflg, coord1, coord2, coord3 130 real(dp) :: dist_,kptrlen,last_dist,max_dist,resdm,s1, max_err, my_tol 131 character(len=500) :: msg 132 !arrays 133 integer :: unts(2) 134 integer :: neigh(0:6,nkpt2),symafm_dummy(1),vacuum(3) 135 integer,allocatable :: symrel1(:,:,:) 136 real(dp) :: dist(6),dk(3),dk_(3),mat(6,6),rvec(6),sgval(6) 137 real(dp) :: shiftk_(3,MAX_NSHIFTK),work(30) 138 real(dp),allocatable :: tnons1(:,:),wtk3(:) 139 140 !************************************************************************ 141 142 !In case of MPI //: compute maximum number of k-points per processor 143 if (xmpi_paral == 1) then 144 mkmem_cp=mkmem 145 call xmpi_max(mkmem_cp,mkmem_max,comm,ier) 146 else 147 mkmem_max = mkmem 148 end if 149 150 unts = [std_out, ab_out] 151 152 !------------- In case kptopt = 2 set up the whole k-point grid ------------- 153 154 !kpt3(3,nkpt3) = reduced coordinates of k-points in the full BZ 155 156 if (kptopt == 3) then 157 158 ABI_MALLOC(wtk3,(nkpt3)) 159 kpt3(:,:) = kpt2(:,:) 160 wtk3(:) = wtk2(:) 161 do ikpt = 1,nkpt3 162 kptindex(1,ikpt) = ikpt 163 kptindex(2,ikpt) = 0 164 end do 165 166 else if (kptopt == 2) then 167 168 ABI_MALLOC(wtk3,(nkpt3)) 169 ii = 5 ; kptopt_used = 3 170 symafm_dummy(1) = 1 171 shiftk_(:,:) = 0._dp 172 shiftk_(:,1:nshiftk) = shiftk(:,1:nshiftk) 173 174 nsym1 = 1 175 ABI_MALLOC(symrel1,(3,3,nsym1)) 176 ABI_MALLOC(tnons1,(3,nsym1)) 177 symrel1(:,:,1) = 0 178 symrel1(1,1,1) = 1 ; symrel1(2,2,1) = 1 ; symrel1(3,3,1) = 1 179 tnons1(:,:) = 0._dp 180 vacuum(:) = 0 181 182 call getkgrid(0,0,ii,kpt3,kptopt_used,kptrlatt,& 183 kptrlen,nsym1,nkpt3,nkpt_computed,nshiftk,nsym1,& 184 rprimd,shiftk_,symafm_dummy,symrel1,& 185 vacuum,wtk3) 186 187 if (nkpt_computed /= nkpt3) then 188 write(msg,'(a,a,a,a,i0,a,a,i0)')& 189 ' The number of k-points in the whole BZ, nkpt_computed= ',nkpt_computed,ch10,& 190 ' is not twice the number of k-points in half the BZ, nkpt3=',nkpt3 191 ABI_BUG(msg) 192 end if 193 194 kptindex(:,:) = 0 195 do ikpt3 = 1, nkpt3 196 197 flag = 1 198 do ikpt2 = 1, nkpt2 199 200 ! In case the k-points differ only by one reciprocal lattice 201 ! vector, apply shift of one g-vector to kpt(:,ikpt3) 202 ! MJV 10/2019: this appears to be using time reversal sym, instead of the G vector... 203 ! could be equivalent to keep points inside the 1st BZ, but the code below is not consistent 204 ! with this comment 205 206 ! 207 ! here k3 = k2 + G 208 ! 209 dk_(:) = kpt3(:,ikpt3) - kpt2(:,ikpt2) 210 dk(:) = dk_(:) - nint(dk_(:)) 211 if (dk(1)*dk(1) + dk(2)*dk(2) + dk(3)*dk(3) < tol10) then 212 do ii = 1, 3 213 if ((dk(ii)*dk(ii) < tol10).and.(dk_(ii)*dk_(ii) > tol10)) then 214 ! transform k3 to -k3 215 ! TODO: I suspect this should be k3 -= G!! 216 kpt3(ii,ikpt3) = -1._dp*kpt3(ii,ikpt3) 217 end if 218 end do 219 end if 220 221 ! 222 ! here k3 = -k2 + G 223 ! 224 dk_(:) = kpt3(:,ikpt3) + kpt2(:,ikpt2) 225 dk(:) = dk_(:) - nint(dk_(:)) 226 if (dk(1)*dk(1) + dk(2)*dk(2) + dk(3)*dk(3) < tol10) then 227 do ii = 1, 3 228 if ((dk(ii)*dk(ii) < tol10).and.(dk_(ii)*dk_(ii) > tol10)) then 229 ! transform k3 to -k3 230 ! TODO: I suspect this should be k3 -= G!! 231 kpt3(ii,ikpt3) = -1._dp*kpt3(ii,ikpt3) 232 end if 233 end do 234 end if 235 236 237 ! 238 ! here k3 = k2 239 ! 240 dk(:) = kpt3(:,ikpt3) - kpt2(:,ikpt2) 241 if (dk(1)*dk(1) + dk(2)*dk(2) + dk(3)*dk(3) < tol10) then 242 kptindex(1,ikpt3) = ikpt2 243 kptindex(2,ikpt3) = 0 ! no use of time-reversal symmetry 244 flag = 0 245 exit 246 end if 247 248 ! 249 ! here k3 = -k2 250 ! 251 dk(:) = kpt3(:,ikpt3) + kpt2(:,ikpt2) 252 if (dk(1)*dk(1) + dk(2)*dk(2) + dk(3)*dk(3) < tol10) then 253 kptindex(1,ikpt3) = ikpt2 254 kptindex(2,ikpt3) = 1 ! use time-reversal symmetry 255 flag = 0 256 exit 257 end if 258 259 end do ! ikpt2 260 261 if (flag == 1) then 262 write(msg,'(a,i0)')' Could not find a symmetric k-point for ikpt3= ',ikpt3 263 ABI_BUG(msg) 264 end if 265 end do ! ikpt3 266 267 else 268 ABI_ERROR(' the only values for kptopt that are allowed are 2 and 3 ') 269 end if ! condition on kptopt 270 271 272 !--------- Compute the weights required for the Marzari-Vanderbilt --------- 273 !--------- finite difference formula --------------------------------------- 274 275 276 !Initialize distance between k-points 277 !The trace of gmet is an upper limit for its largest eigenvalue. Since the 278 !components of the distance vectors do not exceed 1, 3. * Tr[gmet] is 279 !an upper limit for the squared shell radius. 280 !we take something two times larger to make a bug checking. 281 dist_ = 0._dp 282 do ii = 1,3 283 dist_ = dist_ + gmet(ii,ii) 284 end do 285 max_dist = 3._dp * dist_ * 2._dp 286 write(std_out,*)'max_dist',max_dist 287 288 !Calculate an upper limit for the residuum 289 resdm = rmet(1,1)*rmet(1,1) + rmet(2,2)*rmet(2,2) + rmet(3,3)*rmet(3,3)& 290 & + rmet(1,2)*rmet(1,2) + rmet(2,3)*rmet(2,3) + rmet(3,1)*rmet(3,1) 291 292 !Initialize shell loop 293 ishell = 0 294 last_dist = 0._dp 295 wtkflg = 0 296 kneigh(:,:) = 0 297 kg_neigh(:,:,:) = 0 298 neigh(:,:) = 0 299 300 !Loop over shells until the residuum is zero 301 do while ((wtkflg == 0).and.(resdm > tol8)) 302 ! Advance shell counter 303 ishell = ishell + 1 304 305 ! Initialize shell radius with upper limit 306 dist(ishell) = max_dist 307 ! !! border_flag = 1 308 309 ! !write(std_out,*)'gmet' 310 ! !do ikpt=1,3 311 ! !write(std_out,*)gmet(ikpt,:) 312 ! !enddo 313 ! !write(std_out,*)kpt3(:,1) 314 315 ! Find the (squared) radius of the next shell 316 do ikpt = 1,nkpt3 317 ! !write(std_out,*)ikpt 318 ! !write(std_out,*)kpt3(:,ikpt) 319 dk(:) = kpt3(:,1) - kpt3(:,ikpt) 320 ! !!dk_(:) = dk(:) - nint(dk(:)) 321 ! !!dist_ = 0._dp 322 ! !!do ii = 1,3 323 ! !! do jj = 1,3 324 ! !! dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 325 ! !! end do 326 ! !!end do 327 ! !!write(std_out,*)'dist_1', dist_ 328 ! !! dist_ = 0._dp 329 ! !! do ii = 1,3 330 ! !! do jj = 1,3 331 ! !! dist_ = dist_ + dk(ii)*gmet(ii,jj)*dk(jj) 332 ! !! end do 333 ! !! end do 334 ! !!write(std_out,*)'dist_2',dist_ 335 do coord1 = 0,1 !three loop to search also on the border of the BZ, ie for the k-points (1,k2,k3) and the likes 336 do coord2 = 0,1 337 do coord3 = 0,1 338 ! !! if ((coord1/=0).or.(coord2/=0).or.(coord3/=0)) then 339 dist_ = 0._dp 340 dk_(:) = dk(:) - nint(dk(:)) 341 dk_(1) = dk_(1) + real(coord1,dp) 342 dk_(2) = dk_(2) + real(coord2,dp) 343 dk_(3) = dk_(3) + real(coord3,dp) 344 do ii = 1,3 345 do jj = 1,3 346 dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 347 end do 348 end do 349 ! Note : for ipkt3 = 1, coord1 = coord2 = coord3 = 0, the distance is 0 ; 350 ! but the next "if" statement is false with the tol8 criteria and the k-point 351 ! should be ignored even for ishell = 1 and last_dist= 0. 352 ! !$write(std_out,*)ikpt,coord1,coord2,coord3 353 ! !$write(std_out,*)dk_ 354 ! !$write(std_out,*)'dist_2', dist_ 355 ! !! end if 356 if ((dist_ < dist(ishell)).and.(dist_ - last_dist > tol8)) then 357 dist(ishell) = dist_ 358 end if 359 end do 360 end do 361 end do 362 363 ! !! if ((dist_ < dist(ishell)).and.(dist_ - last_dist > tol8)) then 364 ! !! dist(ishell) = dist_ 365 ! !! border_flag = 0 366 ! !! end if 367 end do 368 369 ! !! if (border_flag==1) then !we haven't found any shell in the interior of the BZ, we need to search on the border 370 ! !!write(std_out,*)ch10 371 ! !!write(std_out,*)'search on the border' 372 ! !! do ikpt = 1,nkpt3 373 ! !! dk(:) = kpt3(:,1) - kpt3(:,ikpt) 374 ! !! do coord1 = 0,1 375 ! !! do coord2 = 0,1 376 ! !! do coord3 = 0,1 377 ! !! if ((coord1/=0).or.(coord2/=0).or.(coord3/=0)) then 378 ! !! dist_ = 0._dp 379 ! !! dk_(:) = dk(:) - nint(dk(:)) 380 ! !! dk_(1) = dk_(1) + real(coord1,dp) 381 ! !! dk_(2) = dk_(2) + real(coord2,dp) 382 ! !! dk_(3) = dk_(3) + real(coord3,dp) 383 ! !! do ii = 1,3 384 ! !! do jj = 1,3 385 ! !! dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 386 ! !! end do 387 ! !! end do 388 ! !!write(std_out,*)ikpt,coord1,coord2,coord3 389 ! !!write(std_out,*)dk_ 390 ! !!write(std_out,*)'dist_2', dist_ 391 ! !! end if 392 ! !! if ((dist_ < dist(ishell)).and.(dist_ - last_dist > tol8)) then 393 ! !! dist(ishell) = dist_ 394 ! !! end if 395 ! !! end do 396 ! !! end do 397 ! !! end do 398 ! !! end do 399 ! !! endif 400 401 ! DEBUG 402 ! !write(std_out,*)ch10 403 ! write(std_out,*)'ishell, dist = ',ishell,dist(ishell) 404 ! ENDDEBUG 405 406 if (max_dist-dist(ishell)<tol8) then 407 write(msg,'(a,i0)')' Cannot find shell number',ishell 408 ABI_BUG(msg) 409 end if 410 411 last_dist = dist(ishell) 412 413 ! For each k-point in half the BZ get the shells of nearest neighbours. 414 ! These neighbours can be out of the zone sampled by kpt2. 415 ! !$write(std_out,*)'nkpt2', nkpt2, 'nkpt3', nkpt3 416 do ikpt2 = 1, nkpt2 ! k-points in half the BZ 417 orig = sum(neigh(0:ishell-1,ikpt2)) 418 ! !write(std_out,*)'ikpt2, orig', ikpt2,orig 419 ! !write(std_out,*) kpt2(:,ikpt2) 420 nneigh = 0 421 do ikpt3 = 1, nkpt3 ! whole k-point grid 422 ! !! if(border_flag==0)then 423 dk(:) = kpt3(:,ikpt3) - kpt2(:,ikpt2) 424 ! !! dk_(:) = dk(:) - nint(dk(:)) 425 ! !! dist_ = 0._dp 426 do coord1 = -1,1 427 do coord2 = -1,1 428 do coord3 = -1,1 429 ! !! if ((coord1/=0).or.(coord2/=0).or.(coord3/=0)) then 430 dist_ = 0._dp 431 dk_(:) = dk(:) - nint(dk(:)) 432 dk_(1) = dk_(1) + real(coord1,dp) 433 dk_(2) = dk_(2) + real(coord2,dp) 434 dk_(3) = dk_(3) + real(coord3,dp) 435 do ii = 1,3 436 do jj = 1,3 437 dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 438 end do 439 end do 440 if (abs(dist_ - dist(ishell)) < tol8) then 441 nneigh = nneigh + 1 442 kneigh(orig+nneigh,ikpt2) = ikpt3 443 kg_neigh(orig+nneigh,ikpt2,1) = coord1 444 kg_neigh(orig+nneigh,ikpt2,2) = coord2 445 kg_neigh(orig+nneigh,ikpt2,3) = coord3 446 end if 447 ! !! end if 448 end do 449 end do 450 end do 451 ! !write(std_out,*)'ikpt3', ikpt3 452 ! !write(std_out,*) kpt3(:,ikpt3) 453 ! write(std_out,*) kpt2(:,ikpt2) 454 ! !write(std_out,*) dk 455 ! write(std_out,*) dk_ 456 ! !! do ii = 1,3 457 ! !! do jj = 1,3 458 ! !! dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 459 ! !! end do 460 ! !! end do 461 ! !write(std_out,*)'dist_', dist_ 462 ! !! if (abs(dist_ - dist(ishell)) < tol8) then 463 ! !! nneigh = nneigh + 1 464 ! !! kneigh(orig+nneigh,ikpt2) = ikpt3 465 ! !! end if 466 ! !! else !search on the border 467 ! !! dk(:) = kpt3(:,ikpt3) - kpt2(:,ikpt2) 468 ! !! do coord1 = -1,1 469 ! !! do coord2 = -1,1 470 ! !! do coord3 = -1,1 471 ! !! if ((coord1/=0).or.(coord2/=0).or.(coord3/=0)) then 472 ! !! dist_ = 0._dp 473 ! !! dk_(:) = dk(:) - nint(dk(:)) 474 ! !! dk_(1) = dk_(1) + real(coord1,dp) 475 ! !! dk_(2) = dk_(2) + real(coord2,dp) 476 ! !! dk_(3) = dk_(3) + real(coord3,dp) 477 ! !! do ii = 1,3 478 ! !! do jj = 1,3 479 ! !! dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 480 ! !! end do 481 ! !! end do 482 ! !! if (abs(dist_ - dist(ishell)) < tol8) then 483 ! !! nneigh = nneigh + 1 484 ! !! kneigh(orig+nneigh,ikpt2) = ikpt3 485 ! !! kneigh_border(orig+nneigh,ikpt2,1) = real(coord1,dp) 486 ! !! kneigh_border(orig+nneigh,ikpt2,2) = real(coord2,dp) 487 ! !! kneigh_border(orig+nneigh,ikpt2,3) = real(coord3,dp) 488 ! !! end if 489 ! !! end if 490 ! !! end do 491 ! !! end do 492 ! !! end do 493 ! !! end if 494 end do 495 neigh(ishell,ikpt2) = nneigh 496 end do 497 498 499 ! Check if the number of points in shell number ishell 500 ! is the same for each k-point 501 502 flag = 1 503 do ikpt = 1,nkpt2 504 if (neigh(ishell,ikpt) /= nneigh) flag = 0 505 end do 506 507 if (flag == 0) then 508 write(msg,'(a,i0,a,a)')& 509 ' The number of points in shell number',ishell,' is not the same',& 510 ' for each k-point.' 511 ABI_BUG(msg) 512 end if 513 514 if (nneigh == 0) then 515 write(msg,'(a,a,a,a)') ch10,& 516 ' getshell: BUG - ',ch10,& 517 ' Cannot find enough neighbor shells' 518 call wrtout(unts, msg) 519 wtkflg = 1 520 end if 521 522 ! Calculate the total number of neighbors 523 nneigh = sum(neigh(1:ishell,1)) 524 ! DEBUG 525 !write(std_out,*)'ishell = ',ishell,'nneigh = ',nneigh 526 ! ENDDEBUG 527 528 ! Find the weights needed to compute the finite difference expression 529 ! of the ddk 530 ! ********************************************************************** 531 532 ! mvwtk(:,:) = 0._dp 533 534 ! The weights are calculated for ikpt=1. The results are copied later 535 ikpt = 1 536 537 ! Calculate the coefficients of the linear system to be solved 538 mat(:,:) = 0._dp 539 do is1 = 1, ishell 540 orig = sum(neigh(0:is1-1,ikpt)) 541 bis = orig + neigh(is1,ikpt) 542 do ineigh = orig+1, bis 543 dk_(:) = kpt3(:,kneigh(ineigh,ikpt)) - kpt2(:,ikpt) 544 dk(:) = dk_(:) - nint(dk_(:)) 545 dk(:) = dk(:) + real(kg_neigh(ineigh,ikpt,:),dp) 546 mat(1,is1) = mat(1,is1) + dk(1)*dk(1) 547 mat(2,is1) = mat(2,is1) + dk(2)*dk(2) 548 mat(3,is1) = mat(3,is1) + dk(3)*dk(3) 549 mat(4,is1) = mat(4,is1) + dk(1)*dk(2) 550 mat(5,is1) = mat(5,is1) + dk(2)*dk(3) 551 mat(6,is1) = mat(6,is1) + dk(3)*dk(1) 552 end do 553 end do 554 555 rvec(1) = rmet(1,1) 556 rvec(2) = rmet(2,2) 557 rvec(3) = rmet(3,3) 558 rvec(4) = rmet(1,2) 559 rvec(5) = rmet(2,3) 560 rvec(6) = rmet(3,1) 561 562 ! DEBUG 563 !write(std_out,*) " mat(1:6, 1:ishell) : rmet(1:6) for all 6 products dx^2... dxdy..." 564 !do ii = 1, 6 565 ! write(std_out,*) mat(ii,1:ishell), ' : ', rvec(ii) 566 !end do 567 ! ENDDEBUG 568 569 ! Solve the linear least square problem 570 call dgelss(6,ishell,1,mat,6,rvec,6,sgval,tol8,irank,work,30,info) 571 572 if( info /= 0 ) then 573 write(msg,'(3a,i0,a)')& 574 ' Singular-value decomposition of the linear system determining the',ch10,& 575 ' weights failed (info).',info,ch10 576 ABI_COMMENT(msg) 577 wtkflg = 1 578 end if 579 580 ! Check that the system has maximum rank 581 if( irank == ishell ) then 582 ! System has full rank. Calculate the residuum 583 s1 = resdm 584 resdm = 0._dp 585 do is1 = ishell + 1, 6 586 resdm = resdm + rvec(is1) * rvec(is1) 587 end do 588 589 if( ishell == 6 .and. resdm > tol8 ) then 590 write(msg,'(4a)')& 591 ' Linear system determining the weights could not be solved',ch10,& 592 ' This should not happen.',ch10 593 ABI_COMMENT(msg) 594 wtkflg = 1 595 end if 596 else 597 ! The system is rank deficient 598 ishell = ishell - 1 599 ! DEBUG 600 !write(std_out,*) 'Shell not linear independent from previous shells. Skipped.' 601 ! ENDDEBUG 602 end if 603 604 ! DEBUG 605 !write(std_out,*) "ishell, nneigh, irank, resdm ", ishell, nneigh, irank, resdm 606 ! ENDDEBUG 607 608 ! end of loop over shells 609 end do 610 611 !Copy weights 612 ikpt=1 613 do is1 = 1, ishell 614 orig = sum(neigh(0:is1-1,ikpt)) 615 bis = orig + neigh(is1,ikpt) 616 mvwtk(orig+1:bis,1) = rvec(is1) 617 end do 618 do ikpt = 2,nkpt2 619 mvwtk(1:nneigh,ikpt) = mvwtk(1:nneigh,1) 620 end do ! ikpt 621 622 !Report weights 623 write(std_out,*) 'Neighbors(1:ishell,1) ', neigh(1:ishell,1) 624 write(std_out,*) 'Weights (1:ishell) ', rvec(1:ishell) 625 write(std_out,*) mvwtk(1:nneigh,1) 626 627 !Check the computed weights 628 if (wtkflg == 0) then 629 max_err = zero 630 my_tol = five * tol6 631 do ikpt = 1, nkpt2 632 do ii = 1,3 633 do jj = 1,3 634 s1 = 0._dp 635 do ineigh = 1, nneigh 636 dk_(:) = kpt3(:,kneigh(ineigh,ikpt)) - kpt2(:,ikpt) 637 dk(:) = dk_(:) - nint(dk_(:)) 638 dk(:) = dk(:) + real(kg_neigh(ineigh,ikpt,:),dp) 639 s1 = s1 + dk(ii)*dk(jj)*mvwtk(ineigh,ikpt) 640 end do 641 if (abs(s1 - rmet(ii,jj)) > my_tol) then 642 max_err = max(max_err, abs(s1 - rmet(ii,jj))) 643 wtkflg = 1 644 end if 645 end do 646 end do 647 end do 648 649 if (wtkflg /= 0) then 650 write(msg,'(5a, 2(a, es16.8))') ch10,& 651 ' getshell: BUG -',ch10,& 652 ' The calculated weights do not solve the linear system for all k-points.', ch10, & 653 " max_err: ", max_err, " > tolerance: ", my_tol 654 call wrtout(unts, msg) 655 end if 656 end if 657 658 if (wtkflg /= 0) then 659 660 msg = ' There is a problem with the finite difference expression of the ddk '//ch10& 661 //' If you are very close to a symmetric structure, you might be confusing the algorithm with'//ch10& 662 //' sets of k-points which are not quite part of the same shell. Try rectifying angles and acell.' 663 ABI_BUG(msg) 664 665 else 666 667 nshell = ishell 668 669 write(msg,'(a,a,a,a,a,a,a,i3,a,a,f16.7)') ch10,& 670 ' getshell : finite difference formula of Marzari and Vanderbilt',ch10,& 671 ' (see Marzari and Vanderbilt, PRB 56, 12847 (1997), Appendix B)',& ! [[cite:Marzari1997]] 672 ch10,ch10,& 673 ' number of first neighbours : ', neigh(1,1),ch10,& 674 ' weight : ',mvwtk(1,1) 675 call wrtout(unts, msg) 676 677 if (nshell > 1) then 678 is1 = neigh(1,1) + 1 679 write(msg,'(a,a,i3,a,a,f16.7)')ch10,& 680 ' number of second neighbours : ', neigh(2,1),ch10,& 681 ' weight : ',mvwtk(is1,1) 682 call wrtout(unts, msg) 683 end if 684 685 if (nshell > 2) then 686 is1 = sum(neigh(1:2,1)) + 1 687 write(msg,'(a,a,i3,a,a,f16.7)')ch10,& 688 ' number of third neighbours : ', neigh(3,1),ch10,& 689 ' weight : ',mvwtk(is1,1) 690 call wrtout(unts, msg) 691 end if 692 693 if (nshell > 3) then 694 is1 = sum(neigh(1:3,1)) + 1 695 write(msg,'(a,a,i3,a,a,f16.7)')ch10,& 696 ' number of fourth neighbours : ', neigh(4,1),ch10,& 697 ' weight : ',mvwtk(is1,1) 698 call wrtout(unts, msg) 699 end if 700 701 if (nshell > 4) then 702 is1 = sum(neigh(1:4,1)) + 1 703 write(msg,'(a,a,i3,a,a,f16.7)')ch10,& 704 ' number of fifth neighbours : ', neigh(5,1),ch10,& 705 ' weight : ',mvwtk(is1,1) 706 call wrtout(unts, msg) 707 end if 708 709 if (nshell > 5) then 710 is1 = sum(neigh(1:5,1)) + 1 711 write(msg,'(a,a,i3,a,a,f16.7)')ch10,& 712 ' number of sixth neighbours : ', neigh(6,1),ch10,& 713 ' weight : ',mvwtk(is1,1) 714 call wrtout(unts, msg) 715 end if 716 717 end if 718 719 ABI_SFREE(tnons1) 720 ABI_SFREE(symrel1) 721 722 ABI_FREE(wtk3) 723 724 end subroutine getshell
ABINIT/m_getshell [ Modules ]
NAME
m_getshell
FUNCTION
COPYRIGHT
Copyright (C) 1999-2024 ABINIT group (MVeithen) 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
16 #if defined HAVE_CONFIG_H 17 #include "config.h" 18 #endif 19 20 #include "abi_common.h" 21 22 module m_getshell 23 24 use defs_basis 25 use m_abicore 26 use m_xmpi 27 use m_errors 28 use m_linalg_interfaces 29 30 use m_kpts, only : getkgrid 31 32 implicit none 33 34 private