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)).
COPYRIGHT
Copyright (C) 1999-2018 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 . For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
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 mpi_enreg = information about MPI parallelization 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
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.
PARENTS
nonlinear
CHILDREN
dgelss,getkgrid,wrtout,xmpi_max
SOURCE
81 #if defined HAVE_CONFIG_H 82 #include "config.h" 83 #endif 84 85 #include "abi_common.h" 86 87 88 subroutine getshell(gmet,kneigh,kg_neigh,kptindex,kptopt,kptrlatt,kpt2,& 89 & kpt3,mkmem,mkmem_max,mpi_enreg,mvwtk,& 90 & nkpt2,nkpt3,nneigh,nshiftk,rmet,rprimd,shiftk,wtk2) 91 92 use defs_basis 93 use defs_abitypes 94 use m_profiling_abi 95 use m_xmpi 96 use m_errors 97 use m_linalg_interfaces 98 99 !This section has been created automatically by the script Abilint (TD). 100 !Do not modify the following lines by hand. 101 #undef ABI_FUNC 102 #define ABI_FUNC 'getshell' 103 use interfaces_14_hidewrite 104 use interfaces_56_recipspace 105 !End of the abilint section 106 107 implicit none 108 109 !Arguments ------------------------------------ 110 !scalars 111 integer,intent(in) :: kptopt,mkmem,nkpt2,nkpt3 112 integer,intent(inout) :: nshiftk 113 integer,intent(out) :: mkmem_max,nneigh 114 type(MPI_type),intent(in) :: mpi_enreg 115 !arrays 116 integer,intent(inout) :: kptrlatt(3,3) 117 integer,intent(out) :: kneigh(30,nkpt2),kptindex(2,nkpt3),kg_neigh(30,nkpt2,3) 118 real(dp),intent(in) :: gmet(3,3),kpt2(3,nkpt2),rmet(3,3),rprimd(3,3) 119 real(dp),intent(in) :: shiftk(3,nshiftk),wtk2(nkpt2) 120 real(dp),intent(out) :: kpt3(3,nkpt3),mvwtk(30,nkpt2) 121 122 !Local variables------------------------------- 123 !scalars 124 integer :: bis,flag,ier,ii,ikpt,ikpt2,ikpt3,ineigh,info,irank,is1,ishell 125 integer :: jj,kptopt_used,mkmem_cp,nkpt_computed,nshell,nsym1,orig 126 integer :: spaceComm,wtkflg, coord1, coord2, coord3 127 real(dp) :: dist_,kptrlen,last_dist,max_dist,resdm,s1 128 character(len=500) :: message 129 !arrays 130 integer :: neigh(0:6,nkpt2),symafm_dummy(1),vacuum(3) 131 integer,allocatable :: symrel1(:,:,:) 132 real(dp) :: dist(6),dk(3),dk_(3),mat(6,6),rvec(6),sgval(6) 133 real(dp) :: shiftk_(3,210),work(30) 134 real(dp),allocatable :: tnons1(:,:),wtk3(:) 135 136 !************************************************************************ 137 138 !In case of MPI //: compute maximum number of k-points per processor 139 if (xmpi_paral == 1) then 140 spaceComm=mpi_enreg%comm_cell 141 mkmem_cp=mkmem 142 call xmpi_max(mkmem_cp,mkmem_max,spaceComm,ier) 143 else 144 mkmem_max = mkmem 145 end if 146 147 !------------- In case kptopt = 2 set up the whole k-point grid ------------- 148 149 !kpt3(3,nkpt3) = reduced coordinates of k-points in the full BZ 150 151 if (kptopt == 3) then 152 153 ABI_ALLOCATE(wtk3,(nkpt3)) 154 kpt3(:,:) = kpt2(:,:) 155 wtk3(:) = wtk2(:) 156 do ikpt = 1,nkpt3 157 kptindex(1,ikpt) = ikpt 158 kptindex(2,ikpt) = 0 159 end do 160 161 else if (kptopt == 2) then 162 163 ABI_ALLOCATE(wtk3,(nkpt3)) 164 ii = 5 ; kptopt_used = 3 165 symafm_dummy(1) = 1 166 shiftk_(:,:) = 0._dp 167 shiftk_(:,1:nshiftk) = shiftk(:,1:nshiftk) 168 169 nsym1 = 1 170 ABI_ALLOCATE(symrel1,(3,3,nsym1)) 171 ABI_ALLOCATE(tnons1,(3,nsym1)) 172 symrel1(:,:,1) = 0 173 symrel1(1,1,1) = 1 ; symrel1(2,2,1) = 1 ; symrel1(3,3,1) = 1 174 tnons1(:,:) = 0._dp 175 vacuum(:) = 0 176 177 call getkgrid(0,0,ii,kpt3,kptopt_used,kptrlatt,& 178 & kptrlen,nsym1,nkpt3,nkpt_computed,nshiftk,nsym1,& 179 & rprimd,shiftk_,symafm_dummy,symrel1,& 180 & vacuum,wtk3) 181 182 if (nkpt_computed /= nkpt3) then 183 write(message,'(a,a,a,a,i4,a,a,i4)')& 184 & ' The number of k-points in the whole BZ, nkpt_computed= ',nkpt_computed,ch10,& 185 & ' is not twice the number of k-points in half the BZ, nkpt3=',nkpt3 186 MSG_BUG(message) 187 end if 188 189 kptindex(:,:) = 0 190 do ikpt3 = 1, nkpt3 191 192 flag = 1 193 do ikpt2 = 1, nkpt2 194 195 ! In case, the k-points differ only by one reciprocal lattice 196 ! vector, apply shift of one g-vector to kpt(:,ikpt3) 197 198 dk_(:) = kpt3(:,ikpt3) - kpt2(:,ikpt2) 199 dk(:) = dk_(:) - nint(dk_(:)) 200 if (dk(1)*dk(1) + dk(2)*dk(2) + dk(3)*dk(3) < tol10) then 201 do ii = 1, 3 202 if ((dk(ii)*dk(ii) < tol10).and.(dk_(ii)*dk_(ii) > tol10)) then 203 kpt3(ii,ikpt3) = -1._dp*kpt3(ii,ikpt3) 204 end if 205 end do 206 end if 207 208 dk_(:) = kpt3(:,ikpt3) + kpt2(:,ikpt2) 209 dk(:) = dk_(:) - nint(dk_(:)) 210 if (dk(1)*dk(1) + dk(2)*dk(2) + dk(3)*dk(3) < tol10) then 211 do ii = 1, 3 212 if ((dk(ii)*dk(ii) < tol10).and.(dk_(ii)*dk_(ii) > tol10)) then 213 kpt3(ii,ikpt3) = -1._dp*kpt3(ii,ikpt3) 214 end if 215 end do 216 end if 217 218 dk(:) = kpt3(:,ikpt3) - kpt2(:,ikpt2) 219 if (dk(1)*dk(1) + dk(2)*dk(2) + dk(3)*dk(3) < tol10) then 220 kptindex(1,ikpt3) = ikpt2 221 kptindex(2,ikpt3) = 0 ! no use of time-reversal symmetry 222 flag = 0 223 exit 224 end if 225 226 dk(:) = kpt3(:,ikpt3) + kpt2(:,ikpt2) 227 if (dk(1)*dk(1) + dk(2)*dk(2) + dk(3)*dk(3) < tol10) then 228 kptindex(1,ikpt3) = ikpt2 229 kptindex(2,ikpt3) = 1 ! use time-reversal symmetry 230 flag = 0 231 exit 232 end if 233 234 end do ! ikpt2 235 236 if (flag == 1) then 237 write(message,'(a,i0)')' Could not find a symmetric k-point for ikpt3= ',ikpt3 238 MSG_BUG(message) 239 end if 240 end do ! ikpt3 241 242 else 243 message = ' the only values for kptopt that are allowed are 2 and 3 ' 244 MSG_ERROR(message) 245 end if ! condition on kptopt 246 247 248 !--------- Compute the weights required for the Marzari-Vanderbilt --------- 249 !--------- finite difference formula --------------------------------------- 250 251 252 !Initialize distance between k-points 253 !The trace of gmet is an upper limit for its largest eigenvalue. Since the 254 !components of the distance vectors do not exceed 1, 3. * Tr[gmet] is 255 !an upper limit for the squared shell radius. 256 !we take something two times larger to make a bug checking. 257 dist_ = 0._dp 258 do ii = 1,3 259 dist_ = dist_ + gmet(ii,ii) 260 end do 261 max_dist = 3._dp * dist_ * 2._dp 262 write(std_out,*)'max_dist',max_dist 263 264 !Calculate an upper limit for the residuum 265 resdm = rmet(1,1)*rmet(1,1) + rmet(2,2)*rmet(2,2) + rmet(3,3)*rmet(3,3)& 266 & + rmet(1,2)*rmet(1,2) + rmet(2,3)*rmet(2,3) + rmet(3,1)*rmet(3,1) 267 268 !Initialize shell loop 269 ishell = 0 270 last_dist = 0._dp 271 wtkflg = 0 272 kneigh(:,:) = 0 273 kg_neigh(:,:,:) = 0 274 neigh(:,:) = 0 275 276 !Loop over shells until the residuum is zero 277 do while ((wtkflg == 0).and.(resdm > tol8)) 278 ! Advance shell counter 279 ishell = ishell + 1 280 281 ! Initialize shell radius with upper limit 282 dist(ishell) = max_dist 283 ! !! border_flag = 1 284 285 ! Find the (squared) radius of the next shell 286 ! !write(std_out,*)'gmet' 287 ! !do ikpt=1,3 288 ! !write(std_out,*)gmet(ikpt,:) 289 ! !enddo 290 ! !write(std_out,*)kpt3(:,1) 291 do ikpt = 1,nkpt3 292 ! !write(std_out,*)ikpt 293 ! !write(std_out,*)kpt3(:,ikpt) 294 dk(:) = kpt3(:,1) - kpt3(:,ikpt) 295 ! !!dk_(:) = dk(:) - nint(dk(:)) 296 ! !!dist_ = 0._dp 297 ! !!do ii = 1,3 298 ! !! do jj = 1,3 299 ! !! dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 300 ! !! end do 301 ! !!end do 302 ! !!write(std_out,*)'dist_1', dist_ 303 ! !! dist_ = 0._dp 304 ! !! do ii = 1,3 305 ! !! do jj = 1,3 306 ! !! dist_ = dist_ + dk(ii)*gmet(ii,jj)*dk(jj) 307 ! !! end do 308 ! !! end do 309 ! !!write(std_out,*)'dist_2',dist_ 310 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 311 do coord2 = 0,1 312 do coord3 = 0,1 313 ! !! if ((coord1/=0).or.(coord2/=0).or.(coord3/=0)) then 314 dist_ = 0._dp 315 dk_(:) = dk(:) - nint(dk(:)) 316 dk_(1) = dk_(1) + real(coord1,dp) 317 dk_(2) = dk_(2) + real(coord2,dp) 318 dk_(3) = dk_(3) + real(coord3,dp) 319 do ii = 1,3 320 do jj = 1,3 321 dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 322 end do 323 end do 324 ! Note : for ipkt3 = 1, coord1 = coord2 = coord3 = 0, the distance is 0 ; 325 ! but the next "if" statement is false with the tol8 criteria and the k-point 326 ! should be ignored even for ishell = 1 and last_dist= 0. 327 ! !$write(std_out,*)ikpt,coord1,coord2,coord3 328 ! !$write(std_out,*)dk_ 329 ! !$write(std_out,*)'dist_2', dist_ 330 ! !! end if 331 if ((dist_ < dist(ishell)).and.(dist_ - last_dist > tol8)) then 332 dist(ishell) = dist_ 333 end if 334 end do 335 end do 336 end do 337 338 ! !! if ((dist_ < dist(ishell)).and.(dist_ - last_dist > tol8)) then 339 ! !! dist(ishell) = dist_ 340 ! !! border_flag = 0 341 ! !! end if 342 end do 343 344 ! !! if (border_flag==1) then !we haven't found any shell in the interior of the BZ, we need to search on the border 345 ! !!write(std_out,*)ch10 346 ! !!write(std_out,*)'search on the border' 347 ! !! do ikpt = 1,nkpt3 348 ! !! dk(:) = kpt3(:,1) - kpt3(:,ikpt) 349 ! !! do coord1 = 0,1 350 ! !! do coord2 = 0,1 351 ! !! do coord3 = 0,1 352 ! !! if ((coord1/=0).or.(coord2/=0).or.(coord3/=0)) then 353 ! !! dist_ = 0._dp 354 ! !! dk_(:) = dk(:) - nint(dk(:)) 355 ! !! dk_(1) = dk_(1) + real(coord1,dp) 356 ! !! dk_(2) = dk_(2) + real(coord2,dp) 357 ! !! dk_(3) = dk_(3) + real(coord3,dp) 358 ! !! do ii = 1,3 359 ! !! do jj = 1,3 360 ! !! dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 361 ! !! end do 362 ! !! end do 363 ! !!write(std_out,*)ikpt,coord1,coord2,coord3 364 ! !!write(std_out,*)dk_ 365 ! !!write(std_out,*)'dist_2', dist_ 366 ! !! end if 367 ! !! if ((dist_ < dist(ishell)).and.(dist_ - last_dist > tol8)) then 368 ! !! dist(ishell) = dist_ 369 ! !! end if 370 ! !! end do 371 ! !! end do 372 ! !! end do 373 ! !! end do 374 ! !! endif 375 376 ! DEBUG 377 ! !write(std_out,*)ch10 378 ! write(std_out,*)'ishell, dist = ',ishell,dist(ishell) 379 ! ENDDEBUG 380 381 if (max_dist-dist(ishell)<tol8) then 382 write(message,'(a,i0)')' Cannot find shell number',ishell 383 MSG_BUG(message) 384 end if 385 386 last_dist = dist(ishell) 387 388 ! For each k-point in halft the BZ get the shells of nearest neighbours. 389 ! These neighbours can be out of the zone sampled by kpt2. 390 ! !$write(std_out,*)'nkpt2', nkpt2, 'nkpt3', nkpt3 391 do ikpt2 = 1, nkpt2 ! k-points in half the BZ 392 orig = sum(neigh(0:ishell-1,ikpt2)) 393 ! !write(std_out,*)'ikpt2, orig', ikpt2,orig 394 ! !write(std_out,*) kpt2(:,ikpt2) 395 nneigh = 0 396 do ikpt3 = 1, nkpt3 ! whole k-point grid 397 ! !! if(border_flag==0)then 398 dk(:) = kpt3(:,ikpt3) - kpt2(:,ikpt2) 399 ! !! dk_(:) = dk(:) - nint(dk(:)) 400 ! !! dist_ = 0._dp 401 do coord1 = -1,1 402 do coord2 = -1,1 403 do coord3 = -1,1 404 ! !! if ((coord1/=0).or.(coord2/=0).or.(coord3/=0)) then 405 dist_ = 0._dp 406 dk_(:) = dk(:) - nint(dk(:)) 407 dk_(1) = dk_(1) + real(coord1,dp) 408 dk_(2) = dk_(2) + real(coord2,dp) 409 dk_(3) = dk_(3) + real(coord3,dp) 410 do ii = 1,3 411 do jj = 1,3 412 dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 413 end do 414 end do 415 if (abs(dist_ - dist(ishell)) < tol8) then 416 nneigh = nneigh + 1 417 kneigh(orig+nneigh,ikpt2) = ikpt3 418 kg_neigh(orig+nneigh,ikpt2,1) = coord1 419 kg_neigh(orig+nneigh,ikpt2,2) = coord2 420 kg_neigh(orig+nneigh,ikpt2,3) = coord3 421 end if 422 ! !! end if 423 end do 424 end do 425 end do 426 ! !write(std_out,*)'ikpt3', ikpt3 427 ! !write(std_out,*) kpt3(:,ikpt3) 428 ! write(std_out,*) kpt2(:,ikpt2) 429 ! !write(std_out,*) dk 430 ! write(std_out,*) dk_ 431 ! !! do ii = 1,3 432 ! !! do jj = 1,3 433 ! !! dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 434 ! !! end do 435 ! !! end do 436 ! !write(std_out,*)'dist_', dist_ 437 ! !! if (abs(dist_ - dist(ishell)) < tol8) then 438 ! !! nneigh = nneigh + 1 439 ! !! kneigh(orig+nneigh,ikpt2) = ikpt3 440 ! !! end if 441 ! !! else !search on the border 442 ! !! dk(:) = kpt3(:,ikpt3) - kpt2(:,ikpt2) 443 ! !! do coord1 = -1,1 444 ! !! do coord2 = -1,1 445 ! !! do coord3 = -1,1 446 ! !! if ((coord1/=0).or.(coord2/=0).or.(coord3/=0)) then 447 ! !! dist_ = 0._dp 448 ! !! dk_(:) = dk(:) - nint(dk(:)) 449 ! !! dk_(1) = dk_(1) + real(coord1,dp) 450 ! !! dk_(2) = dk_(2) + real(coord2,dp) 451 ! !! dk_(3) = dk_(3) + real(coord3,dp) 452 ! !! do ii = 1,3 453 ! !! do jj = 1,3 454 ! !! dist_ = dist_ + dk_(ii)*gmet(ii,jj)*dk_(jj) 455 ! !! end do 456 ! !! end do 457 ! !! if (abs(dist_ - dist(ishell)) < tol8) then 458 ! !! nneigh = nneigh + 1 459 ! !! kneigh(orig+nneigh,ikpt2) = ikpt3 460 ! !! kneigh_border(orig+nneigh,ikpt2,1) = real(coord1,dp) 461 ! !! kneigh_border(orig+nneigh,ikpt2,2) = real(coord2,dp) 462 ! !! kneigh_border(orig+nneigh,ikpt2,3) = real(coord3,dp) 463 ! !! end if 464 ! !! end if 465 ! !! end do 466 ! !! end do 467 ! !! end do 468 ! !! end if 469 end do 470 neigh(ishell,ikpt2) = nneigh 471 end do 472 473 474 ! Check if the number of points in shell number ishell 475 ! is the same for each k-point 476 477 flag = 1 478 do ikpt = 1,nkpt2 479 if (neigh(ishell,ikpt) /= nneigh) flag = 0 480 end do 481 482 if (flag == 0) then 483 write(message,'(a,i0,a,a)')& 484 & ' The number of points in shell number',ishell,' is not the same',& 485 & ' for each k-point.' 486 MSG_BUG(message) 487 end if 488 489 if (nneigh == 0) then 490 write(message,'(a,a,a,a)') ch10,& 491 & ' getshell: BUG - ',ch10,& 492 & ' Cannot find enough neighbor shells' 493 call wrtout(ab_out,message,'COLL') 494 call wrtout(std_out, message,'COLL') 495 wtkflg = 1 496 end if 497 498 ! Calculate the total number of neighbors 499 nneigh = sum(neigh(1:ishell,1)) 500 ! DEBUG 501 write(std_out,*)'ishell = ',ishell,'nneigh = ',nneigh 502 ! ENDDEBUG 503 504 ! Find the weights needed to compute the finite difference expression 505 ! of the ddk 506 ! ********************************************************************** 507 508 ! mvwtk(:,:) = 0._dp 509 510 ! The weights are calculated for ikpt=1. The results are copied later 511 ikpt = 1 512 513 ! Calculate the coefficients of the linear system to be solved 514 mat(:,:) = 0._dp 515 do is1 = 1, ishell 516 orig = sum(neigh(0:is1-1,ikpt)) 517 bis = orig + neigh(is1,ikpt) 518 do ineigh = orig+1, bis 519 dk_(:) = kpt3(:,kneigh(ineigh,ikpt)) - kpt2(:,ikpt) 520 dk(:) = dk_(:) - nint(dk_(:)) 521 dk(:) = dk(:) + real(kg_neigh(ineigh,ikpt,:),dp) 522 mat(1,is1) = mat(1,is1) + dk(1)*dk(1) 523 mat(2,is1) = mat(2,is1) + dk(2)*dk(2) 524 mat(3,is1) = mat(3,is1) + dk(3)*dk(3) 525 mat(4,is1) = mat(4,is1) + dk(1)*dk(2) 526 mat(5,is1) = mat(5,is1) + dk(2)*dk(3) 527 mat(6,is1) = mat(6,is1) + dk(3)*dk(1) 528 end do 529 end do 530 531 rvec(1) = rmet(1,1) 532 rvec(2) = rmet(2,2) 533 rvec(3) = rmet(3,3) 534 rvec(4) = rmet(1,2) 535 rvec(5) = rmet(2,3) 536 rvec(6) = rmet(3,1) 537 538 ! DEBUG 539 do ii = 1, 6 540 write(std_out,*)mat(ii,1:ishell), ' : ', rvec(ii) 541 end do 542 ! ENDDEBUG 543 544 ! Solve the linear least square problem 545 call dgelss(6,ishell,1,mat,6,rvec,6,sgval,tol8,irank,work,30,info) 546 547 if( info /= 0 ) then 548 write(message,'(3a,i0,a)')& 549 & ' Singular-value decomposition of the linear system determining the',ch10,& 550 & ' weights failed (info).',info,ch10 551 MSG_COMMENT(message) 552 wtkflg = 1 553 end if 554 555 ! Check that the system has maximum rank 556 if( irank == ishell ) then 557 ! System has full rank. Calculate the residuum 558 s1 = resdm 559 resdm = 0._dp 560 do is1 = ishell + 1, 6 561 resdm = resdm + rvec(is1) * rvec(is1) 562 end do 563 564 if( ishell == 6 .and. resdm > tol8 ) then 565 write(message,'(4a)')& 566 & ' Linear system determining the weights could not be solved',ch10,& 567 & ' This should not happen.',ch10 568 MSG_COMMENT(message) 569 wtkflg = 1 570 end if 571 else 572 ! The system is rank deficient 573 ishell = ishell - 1 574 ! DEBUG 575 write(std_out,*) 'Shell not linear independent from previous shells. Skipped.' 576 ! ENDDEBUG 577 end if 578 579 ! DEBUG 580 write(std_out,*) ishell, nneigh, irank, resdm 581 ! ENDDEBUG 582 583 ! end of loop over shells 584 end do 585 586 !Copy weights 587 ikpt=1 588 do is1 = 1, ishell 589 orig = sum(neigh(0:is1-1,ikpt)) 590 bis = orig + neigh(is1,ikpt) 591 mvwtk(orig+1:bis,1) = rvec(is1) 592 end do 593 do ikpt = 2,nkpt2 594 mvwtk(1:nneigh,ikpt) = mvwtk(1:nneigh,1) 595 end do ! ikpt 596 597 !Report weights 598 write(std_out,*) 'Neighbors', neigh(1:ishell,1) 599 write(std_out,*) 'Weights', rvec(1:ishell) 600 write(std_out,*) mvwtk(1:nneigh,1) 601 602 !Check the computed weights 603 if (wtkflg == 0) then 604 do ikpt = 1, nkpt2 605 do ii = 1,3 606 do jj = 1,3 607 s1 = 0._dp 608 do ineigh = 1, nneigh 609 dk_(:) = kpt3(:,kneigh(ineigh,ikpt)) - kpt2(:,ikpt) 610 dk(:) = dk_(:) - nint(dk_(:)) 611 dk(:) = dk(:) + real(kg_neigh(ineigh,ikpt,:),dp) 612 s1 = s1 + dk(ii)*dk(jj)*mvwtk(ineigh,ikpt) 613 end do 614 if (abs(s1 - rmet(ii,jj)) > tol6) wtkflg = 1 615 end do 616 end do 617 end do 618 619 if (wtkflg /= 0) then 620 write(message,'(a,a,a,a)') ch10,& 621 & ' getshell : BUG -',ch10,& 622 & ' The calculated weights do not solve the linear system for all k-points.' 623 call wrtout(ab_out,message,'COLL') 624 call wrtout(std_out, message,'COLL') 625 end if 626 end if 627 628 if (wtkflg /= 0) then 629 630 message = ' There is a problem with the finite difference expression of the ddk ' 631 MSG_BUG(message) 632 633 else 634 635 nshell = ishell 636 637 write(message,'(a,a,a,a,a,a,a,i3,a,a,f16.7)') ch10,& 638 & ' getshell : finite difference formula of Marzari and Vanderbilt',ch10,& 639 & ' (see Marzari and Vanderbilt, PRB 56, 12847 (1997), Appendix B)',& 640 & ch10,ch10,& 641 & ' number of first neighbours : ', neigh(1,1),ch10,& 642 & ' weight : ',mvwtk(1,1) 643 call wrtout(ab_out,message,'COLL') 644 call wrtout(std_out, message,'COLL') 645 646 if (nshell > 1) then 647 is1 = neigh(1,1) + 1 648 write(message,'(a,a,i3,a,a,f16.7)')ch10,& 649 & ' number of second neighbours : ', neigh(2,1),ch10,& 650 & ' weight : ',mvwtk(is1,1) 651 call wrtout(ab_out,message,'COLL') 652 call wrtout(std_out, message,'COLL') 653 end if 654 655 if (nshell > 2) then 656 is1 = sum(neigh(1:2,1)) + 1 657 write(message,'(a,a,i3,a,a,f16.7)')ch10,& 658 & ' number of third neighbours : ', neigh(3,1),ch10,& 659 & ' weight : ',mvwtk(is1,1) 660 call wrtout(ab_out,message,'COLL') 661 call wrtout(std_out, message,'COLL') 662 end if 663 664 if (nshell > 3) then 665 is1 = sum(neigh(1:3,1)) + 1 666 write(message,'(a,a,i3,a,a,f16.7)')ch10,& 667 & ' number of fourth neighbours : ', neigh(4,1),ch10,& 668 & ' weight : ',mvwtk(is1,1) 669 call wrtout(ab_out,message,'COLL') 670 call wrtout(std_out, message,'COLL') 671 end if 672 673 if (nshell > 4) then 674 is1 = sum(neigh(1:4,1)) + 1 675 write(message,'(a,a,i3,a,a,f16.7)')ch10,& 676 & ' number of fifth neighbours : ', neigh(5,1),ch10,& 677 & ' weight : ',mvwtk(is1,1) 678 call wrtout(ab_out,message,'COLL') 679 call wrtout(std_out, message,'COLL') 680 end if 681 682 if (nshell > 5) then 683 is1 = sum(neigh(1:5,1)) + 1 684 write(message,'(a,a,i3,a,a,f16.7)')ch10,& 685 & ' number of sixth neighbours : ', neigh(6,1),ch10,& 686 & ' weight : ',mvwtk(is1,1) 687 call wrtout(ab_out,message,'COLL') 688 call wrtout(std_out, message,'COLL') 689 end if 690 691 end if 692 693 694 695 !---------------------------------------------------------------------------- 696 697 if (allocated(tnons1)) then 698 ABI_DEALLOCATE(tnons1) 699 end if 700 if (allocated(symrel1)) then 701 ABI_DEALLOCATE(symrel1) 702 end if 703 704 ABI_DEALLOCATE(wtk3) 705 706 707 end subroutine getshell