TABLE OF CONTENTS
- ABINIT/m_dynmat
- m_dynmat/asria_calc
- m_dynmat/asria_corr
- m_dynmat/asrif9
- m_dynmat/asrprs
- m_dynmat/axial9
- m_dynmat/bigbx9
- m_dynmat/canat9
- m_dynmat/canct9
- m_dynmat/cart29
- m_dynmat/cart39
- m_dynmat/chkph3
- m_dynmat/chkrp9
- m_dynmat/chneu9
- m_dynmat/d2cart_to_red
- m_dynmat/d2sym3
- m_dynmat/d3sym
- m_dynmat/dfpt_phfrq
- m_dynmat/dist9
- m_dynmat/dymfz9
- m_dynmat/dynmat_dq
- m_dynmat/ftgam
- m_dynmat/ftgam_init
- m_dynmat/ftifc_q2r
- m_dynmat/ftifc_r2q
- m_dynmat/gtdyn9
- m_dynmat/ifclo9
- m_dynmat/make_bigbox
- m_dynmat/massmult_and_breaksym
- m_dynmat/nanal9
- m_dynmat/q0dy3_apply
- m_dynmat/q0dy3_calc
- m_dynmat/symdm9
- m_dynmat/symdyma
- m_dynmat/sytens
- m_dynmat/wght9
- m_dynmat/wings3
ABINIT/m_dynmat [ Modules ]
NAME
m_dynmat
FUNCTION
This module provides low-level tools to operate on the dynamical matrix
COPYRIGHT
Copyright (C) 2014-2018 ABINIT group (XG, JCC, MJV, NH, RC, MVeithen, MM, MG) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt .
TODO
Use more explicative names for the procedures!
PARENTS
CHILDREN
SOURCE
24 #if defined HAVE_CONFIG_H 25 #include "config.h" 26 #endif 27 28 #include "abi_common.h" 29 30 module m_dynmat 31 32 use defs_basis 33 use m_profiling_abi 34 use m_errors 35 use m_linalg_interfaces 36 37 use m_fstrings, only : itoa, sjoin 38 use m_numeric_tools, only : wrap2_pmhalf, mkherm 39 use m_cgtools, only : fxphas_seq 40 use m_ewald, only : ewald9 41 42 implicit none 43 44 private 45 46 public :: asria_calc ! Calculate the correction for the Acoustic sum rule on 47 ! the InterAtomic Forces or on the dynamical matrix directly 48 public :: asria_corr ! Imposition of the Acoustic sum rule on the InterAtomic Forces 49 ! or on the dynamical matrix directly from the previously calculated d2asr 50 public :: asrprs ! Imposition of the Acoustic sum rule on the InterAtomic Forces Plus Rotational Symmetry 51 public :: cart29 ! Transform a second-derivative matrix from reduced coordinates to cartesian coordinates, and also 52 ! 1) add the ionic part of the effective charges, 53 ! 2) normalize the electronic dielectric tensor, and add the vacuum polarisation 54 public :: cart39 ! Transform a vector from reduced coordinates to cartesian coordinates, 55 ! taking into account the perturbation from which it was derived, 56 ! and also check the existence of the new values. 57 public :: d2cart_to_red ! Transform a second-derivative matrix 58 ! from cartesian to reduced coordinate. 59 public :: chkph3 ! Check the completeness of the dynamical matrix 60 public :: chneu9 ! Imposition of the Acoustic sum rule on the Effective charges 61 public :: d2sym3 ! Build (nearly) all the other matrix elements that can be build using symmetries. 62 public :: q0dy3_apply ! Takes care of the inclusion of the ewald q=0 term in the dynamical matrix 63 public :: q0dy3_calc ! Calculate the q=0 correction term to the dynamical matrix 64 public :: symdyma ! Symmetrize the dynamical matrices 65 public :: wings3 ! Suppress the wings of the cartesian 2DTE for which the diagonal element is not known 66 public :: asrif9 ! Imposes the Acoustic Sum Rule to Interatomic Forces 67 public :: make_bigbox ! Generates a Big Box of R points for the Fourier Transforms the dynamical matrix 68 public :: bigbx9 ! Helper functions that faciliates the generation of a Big Box containing 69 public :: canat9 ! From reduced to canonical coordinates 70 public :: canct9 ! Convert from canonical coordinates to cartesian coordinates 71 public :: chkrp9 ! Check if the rprim used for the definition of the unit cell (in the 72 ! inputs) are consistent with the rprim used in the routine generating the Big Box 73 public :: dist9 ! Compute the distance between atoms in the big box 74 public :: ftifc_q2r ! Fourier transform of the dynamical matrices to obtain interatomic forces (real space). 75 public :: ftifc_r2q ! Fourier transform of the interatomic forces to obtain dynamical matrices (reciprocal space). 76 public :: dynmat_dq ! Compute the derivative D(q)/dq via Fourier transform of the interatomic forces 77 public :: ifclo9 ! Convert from cartesian coordinates to local coordinates 78 public :: wght9 ! Generates a weight to each R points of the Big Box and for each pair of atoms 79 public :: d3sym ! Given a set of calculated elements of the 3DTE matrix, 80 ! build (nearly) all the other matrix elements that can be build using symmetries. 81 public :: sytens ! Determines the set of irreductible elements of the non-linear optical susceptibility 82 ! and Raman tensors 83 public :: symdm9 ! Generate the dynamical matrix in the full BZ from the irreducible q-points. 84 public :: axial9 ! Generates the local coordinates system from the knowledge of the first vector (longitudinal) and 85 ! the ifc matrix in cartesian coordinates 86 public :: dymfz9 ! Multiply the dynamical matrix by a phase shift to account for normalized canonical coordinates. 87 public :: nanal9 ! Subtract/Add the non-analytical part from one dynamical matrix with number iqpt. 88 public :: gtdyn9 ! Generates a dynamical matrix from interatomic force constants and 89 ! long-range electrostatic interactions. 90 public :: dfpt_phfrq ! Diagonalize IFC(q), return phonon frequencies and eigenvectors. 91 ! If q is Gamma, the non-analytical behaviour can be included. 92 public :: massmult_and_breaksym ! Multiply IFC(q) by atomic masses. 93 94 ! TODO: Change name, 95 public :: ftgam 96 public :: ftgam_init 97 98 99 ! ************************************************************************* 100 101 contains
m_dynmat/asria_calc [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
asria_calc
FUNCTION
Calculate the correction for the Acoustic sum rule on the InterAtomic Forces or on the dynamical matrix directly
INPUTS
asr=(0 => no ASR, 1 or 2=> the diagonal element is modified to give the ASR, 5 => impose hermitian solution using lapack call) d2cart=matrix of second derivatives of total energy, in cartesian coordinates mpert =maximum number of ipert natom=number of atom
OUTPUT
d2asr=matrix used to store the correction needed to fulfill the acoustic sum rule.
PARENTS
dfpt_gatherdy,m_ddb,m_effective_potential_file
CHILDREN
SOURCE
130 subroutine asria_calc(asr,d2asr,d2cart,mpert,natom) 131 132 133 !This section has been created automatically by the script Abilint (TD). 134 !Do not modify the following lines by hand. 135 #undef ABI_FUNC 136 #define ABI_FUNC 'asria_calc' 137 !End of the abilint section 138 139 implicit none 140 141 !Arguments ------------------------------- 142 !scalars 143 integer,intent(in) :: asr,mpert,natom 144 !arrays 145 real(dp),intent(in) :: d2cart(2,3,mpert,3,mpert) 146 real(dp),intent(out) :: d2asr(2,3,natom,3,natom) 147 148 !Local variables------------------------------- 149 !scalars 150 integer :: idir1,idir2,ii,ipert1,ipert2 151 integer :: constrank, imatelem, iconst, nconst, nd2_packed, info 152 !character(len=500) :: message 153 !arrays 154 integer, allocatable :: packingindex(:,:,:,:) 155 real(dp), allocatable :: constraints(:,:,:) 156 real(dp), allocatable :: d2cart_packed(:,:) 157 real(dp), allocatable :: singvals(:) 158 real(dp), allocatable :: constr_rhs(:,:) 159 real(dp), allocatable :: work(:,:),rwork(:) 160 161 ! ********************************************************************* 162 163 d2asr = zero 164 165 if (asr==0) return 166 167 !call wrtout(std_out,' asria_calc: calculation of the correction to the ASR for the interatomic forces.') 168 do ipert1=1,natom 169 do idir1=1,3 170 do idir2=1,3 171 172 ! Compute d2asr 173 do ipert2=1,natom 174 d2asr(:,idir1,ipert1,idir2,ipert1)=& 175 & d2asr(:,idir1,ipert1,idir2,ipert1)+& 176 & d2cart(:,idir1,ipert1,idir2,ipert2) 177 end do 178 end do 179 end do 180 end do 181 182 !holistic method: overwrite d2asr with hermitian solution 183 if (asr == 5) then 184 nconst = 9*natom 185 nd2_packed = 3*natom*(3*natom+1)/2 186 ABI_ALLOCATE(constraints,(2,nconst, nd2_packed)) 187 ABI_ALLOCATE(d2cart_packed,(2,nd2_packed)) 188 ABI_ALLOCATE(constr_rhs,(2,nd2_packed)) 189 ABI_ALLOCATE(singvals,(nconst)) 190 ABI_ALLOCATE(work,(2,3*nd2_packed)) 191 ABI_ALLOCATE(rwork,(5*nd2_packed)) 192 ABI_ALLOCATE(packingindex,(3,natom,3,natom)) 193 ii=1 194 packingindex=-1 195 do ipert2=1,natom 196 do idir2=1,3 197 do ipert1=1,ipert2-1 198 do idir1=1,3 199 packingindex(idir1,ipert1,idir2,ipert2) = ii 200 ii = ii+1 201 end do 202 end do 203 do idir1=1,idir2 204 packingindex(idir1,ipert2,idir2,ipert2) = ii 205 ii = ii+1 206 end do 207 end do 208 end do 209 ! setup constraint matrix 210 constraints = zero 211 do ipert1=1,natom 212 do idir1=1,3 213 do idir2=1,3 214 iconst = idir2+3*(idir1-1 + 3*(ipert1-1)) 215 ! set all atom forces, this component 216 do ipert2=1,natom 217 imatelem = packingindex(idir1,ipert1,idir2,ipert2) 218 if (imatelem == -1) then 219 imatelem = packingindex(idir2,ipert2,idir1,ipert1) 220 end if 221 constraints(1,iconst,imatelem) = one 222 end do 223 end do 224 end do 225 end do 226 227 d2cart_packed = -999.0d0 228 do ipert2=1,natom 229 do idir2=1,3 230 do ipert1=1,natom 231 do idir1=1,3 232 imatelem = packingindex(idir1,ipert1,idir2,ipert2) 233 if (imatelem == -1) cycle 234 d2cart_packed(:,imatelem) = d2cart(:,idir1,ipert1,idir2,ipert2) 235 end do 236 end do 237 end do 238 end do 239 constr_rhs = zero 240 constr_rhs(1,1:nconst) = matmul(constraints(1,:,:),d2cart_packed(1,:)) 241 constr_rhs(2,1:nconst) = matmul(constraints(1,:,:),d2cart_packed(2,:)) 242 243 ! lwork = 3*nd2_packed 244 call zgelss (nconst,nd2_packed,1,constraints,nconst,constr_rhs,nd2_packed,& 245 & singvals,-one,constrank,work,3*nd2_packed,rwork,info) 246 ABI_CHECK(info == 0, sjoin('zgelss returned:', itoa(info))) 247 248 ! unpack 249 do ipert2=1,natom 250 do idir2=1,3 251 do ipert1=1,natom 252 do idir1=1,3 253 imatelem = packingindex(idir1,ipert1,idir2,ipert2) 254 if (imatelem == -1) then 255 imatelem = packingindex(idir2,ipert2,idir1,ipert1) 256 ! NOTE: should complex conjugate the correction below. 257 end if 258 d2asr(:,idir1,ipert1,idir2,ipert2) = constr_rhs(:,imatelem) 259 end do 260 end do 261 end do 262 end do 263 264 ABI_DEALLOCATE(constraints) 265 ABI_DEALLOCATE(d2cart_packed) 266 ABI_DEALLOCATE(singvals) 267 ABI_DEALLOCATE(constr_rhs) 268 ABI_DEALLOCATE(work) 269 ABI_DEALLOCATE(rwork) 270 ABI_DEALLOCATE(packingindex) 271 end if 272 273 end subroutine asria_calc
m_dynmat/asria_corr [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
asria_corr
FUNCTION
Imposition of the Acoustic sum rule on the InterAtomic Forces or on the dynamical matrix directly from the previously calculated d2asr
INPUTS
asr=(0 => no ASR, 1 or 2=> the diagonal element is modified to give the ASR, 5 => impose hermitian solution using lapack call) d2asr=matrix used to store the correction needed to fulfill the acoustic sum rule. mpert =maximum number of ipert natom=number of atom
OUTPUT
Input/Output: d2cart=matrix of second derivatives of total energy, in cartesian coordinates
PARENTS
ddb_elast,ddb_internalstr,dfpt_gatherdy,m_ddb,thmeig
CHILDREN
SOURCE
305 subroutine asria_corr(asr,d2asr,d2cart,mpert,natom) 306 307 308 !This section has been created automatically by the script Abilint (TD). 309 !Do not modify the following lines by hand. 310 #undef ABI_FUNC 311 #define ABI_FUNC 'asria_corr' 312 !End of the abilint section 313 314 implicit none 315 316 !Arguments ------------------------------- 317 !scalars 318 integer,intent(in) :: asr,mpert,natom 319 !arrays 320 real(dp),intent(in) :: d2asr(2,3,natom,3,natom) 321 real(dp),intent(inout) :: d2cart(2,3,mpert,3,mpert) 322 323 !Local variables------------------------------- 324 !scalars 325 integer :: idir1,idir2,ipert1,ipert2 326 327 ! ********************************************************************* 328 329 if (asr==0) return 330 !call wrtout(std_out,' asria_corr: imposition of the ASR for the interatomic forces.','COLL') 331 332 ! Remove d2asr 333 do ipert2=1,natom 334 do idir2=1,3 335 do ipert1=1,natom 336 do idir1=1,3 337 d2cart(:,idir1,ipert1,idir2,ipert2)= d2cart(:,idir1,ipert1,idir2,ipert2) - d2asr(:,idir1,ipert1,idir2,ipert2) 338 end do 339 end do 340 end do 341 end do 342 343 end subroutine asria_corr
m_dynmat/asrif9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
asrif9
FUNCTION
Imposes the Acoustic Sum Rule to Interatomic Forces
INPUTS
asr= Option for the imposition of the ASR 0 => no ASR, 1 => modify "asymmetrically" the diagonal element 2 => modify "symmetrically" the diagonal element natom= Number of atoms in the unit cell nrpt= Number of R points in the Big Box rpt(3,nprt)= Canonical coordinates of the R points in the unit cell These coordinates are normalized (=> * acell(3)!!) wghatm(natom,natom,nrpt)= Weight associated to the couple of atoms and the R vector atmfrc(3,natom,3,natom,nrpt)= Interatomic Forces
OUTPUT
atmfrc(3,natom,3,natom,nrpt)= ASR-imposed Interatomic Forces
TODO
List of ouput should be included.
PARENTS
ddb_hybrid,m_ifc,m_tdep_abitypes
CHILDREN
SOURCE
2462 subroutine asrif9(asr,atmfrc,natom,nrpt,rpt,wghatm) 2463 2464 2465 !This section has been created automatically by the script Abilint (TD). 2466 !Do not modify the following lines by hand. 2467 #undef ABI_FUNC 2468 #define ABI_FUNC 'asrif9' 2469 !End of the abilint section 2470 2471 implicit none 2472 2473 !Arguments ------------------------------- 2474 !scalars 2475 integer,intent(in) :: asr,natom,nrpt 2476 !arrays 2477 real(dp),intent(in) :: rpt(3,nrpt),wghatm(natom,natom,nrpt) 2478 real(dp),intent(inout) :: atmfrc(3,natom,3,natom,nrpt) 2479 2480 !Local variables ------------------------- 2481 !scalars 2482 integer :: found,ia,ib,irpt,izero,mu,nu 2483 real(dp) :: sumifc 2484 2485 ! ********************************************************************* 2486 2487 DBG_ENTER("COLL") 2488 2489 if(asr==1.or.asr==2)then 2490 2491 found=0 2492 ! Search for the R vector which is equal to ( 0 , 0 , 0 ) 2493 ! This vector leaves the atom a on itself ! 2494 do irpt=1,nrpt 2495 if (all(abs(rpt(:,irpt))<=1.0d-10)) then 2496 found=1 2497 izero=irpt 2498 end if 2499 if (found==1) exit 2500 end do 2501 2502 if(found==0)then 2503 MSG_BUG('Not able to find the vector R=(0,0,0).') 2504 end if 2505 2506 do mu=1,3 2507 do nu=1,3 2508 do ia=1,natom 2509 sumifc=zero 2510 do ib=1,natom 2511 2512 ! Get the sumifc of interatomic forces acting on the atom ia, 2513 ! either in a symmetrical manner, or an unsymmetrical one. 2514 if(asr==1)then 2515 do irpt=1,nrpt 2516 sumifc=sumifc+wghatm(ia,ib,irpt)*atmfrc(mu,ia,nu,ib,irpt) 2517 end do 2518 else if(asr==2)then 2519 do irpt=1,nrpt 2520 sumifc=sumifc+& 2521 & (wghatm(ia,ib,irpt)*atmfrc(mu,ia,nu,ib,irpt)+& 2522 & wghatm(ia,ib,irpt)*atmfrc(nu,ia,mu,ib,irpt))/2 2523 end do 2524 end if 2525 end do 2526 2527 ! Correct the self-interaction in order to fulfill the ASR 2528 atmfrc(mu,ia,nu,ia,izero)=atmfrc(mu,ia,nu,ia,izero)-sumifc 2529 if(asr==2)then 2530 atmfrc(nu,ia,mu,ia,izero)=atmfrc(mu,ia,nu,ia,izero) 2531 end if 2532 2533 end do 2534 end do 2535 end do 2536 end if 2537 2538 DBG_EXIT("COLL") 2539 2540 end subroutine asrif9
m_dynmat/asrprs [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
asrprs
FUNCTION
Imposition of the Acoustic sum rule on the InterAtomic Forces Plus Rotational Symmetry
INPUTS
asr=(3 => 1D systems, all elements are modified to give ASR and rotational symmetry) (4 => 0D systems, all elements are modified to give ASR and rotational symmetry) asrflg=(1 => the correction to enforce asr is computed from d2cart, but NOT applied; 2 => one uses the previously determined correction) minvers=previously calculated inverted coefficient matrix mpert =maximum number of ipert natom=number of atom rotinv=(1,2,3 => for linear systems along x,y,z 4 => non-linear molecule xcart=cartesian coordinates of the ions
OUTPUT
(see side effects)
SIDE EFFECTS
Input/Output: d2cart=matrix of second derivatives of total energy, in cartesian coordinates minvers=inverse of the supermatrix for future application of the corrections
PARENTS
m_ddb
CHILDREN
SOURCE
385 subroutine asrprs(asr,asrflag,rotinv,uinvers,vtinvers,singular,d2cart,mpert,natom,xcart) 386 387 388 !This section has been created automatically by the script Abilint (TD). 389 !Do not modify the following lines by hand. 390 #undef ABI_FUNC 391 #define ABI_FUNC 'asrprs' 392 use interfaces_14_hidewrite 393 !End of the abilint section 394 395 implicit none 396 397 !Arguments ------------------------------------ 398 !scalars 399 integer,intent(in) :: asr,asrflag,mpert,natom,rotinv 400 !arrays 401 real(dp),intent(in) :: xcart(3,natom) 402 real(dp),intent(inout) :: d2cart(2,3,mpert,3,mpert) 403 real(dp),intent(inout) :: singular(1:3*natom*(3*natom-1)/2) 404 real(dp),intent(inout) :: uinvers(1:3*natom*(3*natom-1)/2,1:3*natom*(3*natom-1)/2) 405 real(dp),intent(inout) :: vtinvers(1:3*natom*(3*natom-1)/2,1:3*natom*(3*natom-1)/2) 406 407 !Local variables------------------------------- 408 !scalars 409 integer :: column,idir1,idir2,ii,info,ipert1,ipert2,jj,n3,row,superdim 410 real(dp) :: rcond,test 411 ! real(dp) :: tau ! tau is present but commented out in this routine 412 character(len=500) :: message 413 !arrays 414 integer :: check(3,natom,3) 415 real(dp) :: tmp(natom,3,3),weightf(1:natom,1:natom) 416 real(dp),allocatable :: d2cartold(:,:,:,:,:),d2vecc(:),d2veccnew(:),d2vecr(:) 417 real(dp),allocatable :: d2vecrnew(:),superm(:,:),umatrix(:,:),vtmatrix(:) 418 real(dp),allocatable :: work(:) 419 420 ! ********************************************************************* 421 422 if(asr/=3 .and. asr/=4)then 423 write(message,'(3a,i0)')& 424 & 'The argument asr should be 3 or 4,',ch10,& 425 & 'however, asr = ',asr 426 MSG_BUG(message) 427 end if 428 429 if (asr==3.or.asr==4)then 430 write(message, '(a,a)' ) ch10, & 431 & 'asrprs: imposition of the ASR for the interatomic forces and rotational invariance' 432 call wrtout(std_out,message,'COLL') 433 end if 434 435 write(message,'(a,i6)')' asrflag is', asrflag 436 call wrtout(std_out,message,'COLL') 437 call wrtout(ab_out,message,'COLL') 438 439 !variables for the dimensions of the matrices 440 441 !n1=3*natom*(3*natom-1)/2 442 !n2=9*natom 443 n3=3*natom 444 445 superdim=9*natom*(natom-1)/2+n3 446 447 ABI_ALLOCATE(d2vecr,(1:superdim)) 448 ABI_ALLOCATE(d2vecc,(1:superdim)) 449 d2vecr=0d0 450 d2vecc=0d0 451 452 !should be changed set to delta function for debugging 453 weightf=1d0 454 !tau=1d-10 455 do ii=1, natom 456 ! do jj=1, ii-1 457 ! weightf(ii,jj)= & 458 ! & ((xcart(1,ii)-xcart(1,jj))**2+(xcart(2,ii)-xcart(2,jj))**2+(xcart(3,ii)-xcart(3,jj))**2)**tau 459 ! enddo 460 weightf(ii,ii)=0d0 461 end do 462 463 ABI_ALLOCATE(d2cartold,(2,3,mpert,3,mpert)) 464 465 d2cartold=d2cart 466 467 !setup vector with uncorrected derivatives 468 469 do ipert1=1, natom 470 do ipert2=1, ipert1-1 471 do idir1=1,3 472 do idir2=1,3 473 row=n3+9*(ipert1-1)*(ipert1-2)/2+9*(ipert2-1)+3*(idir1-1)+idir2 474 if(abs(d2cart(1,idir1,ipert1,idir2,ipert2))<1d-6)then 475 d2cart(1,idir1,ipert1,idir2,ipert2)=0d0 476 else 477 d2vecr(row)=4*weightf(ipert1,ipert2)*d2cart(1,idir1,ipert1,idir2,ipert2) 478 end if 479 if(abs(d2cart(2,idir1,ipert1,idir2,ipert2))<1d-6) then 480 d2cart(2,idir1,ipert1,idir2,ipert2)=0d0 481 else 482 d2vecc(row)=4*weightf(ipert1,ipert2)*d2cart(2,idir1,ipert1,idir2,ipert2) 483 end if 484 end do 485 end do 486 end do 487 end do 488 489 if(asrflag==1) then !calculate the pseudo-inverse of the supermatrix 490 ABI_ALLOCATE(superm,(1:superdim,1:superdim)) 491 492 superm=0d0 493 494 ! Setting up the supermatrix containing G, A, D 495 496 do ipert1=1, natom 497 do idir1=1, 3 498 ! Setting up G 499 idir2=mod(idir1,3)+1 500 row=3*(ipert1-1)+idir1 501 do ipert2=1, ipert1-1 502 column=9*(ipert1-1)*(ipert1-2)/2+9*(ipert2-1)+3*(rotinv-1)+idir1 503 superm(column,row)=xcart(idir2,ipert2)-xcart(idir2,ipert1) 504 column=9*(ipert1-1)*(ipert1-2)/2+9*(ipert2-1)+3*(rotinv-1)+idir2 505 superm(column,row)=xcart(idir1,ipert1)-xcart(idir1,ipert2) 506 end do 507 do ipert2=ipert1+1, natom 508 column=9*(ipert2-1)*(ipert2-2)/2+9*(ipert1-1)+3*(idir1-1)+rotinv 509 superm(column,row)=xcart(idir2,ipert2)-xcart(idir2,ipert1) 510 column=9*(ipert2-1)*(ipert2-2)/2+9*(ipert1-1)+3*(idir2-1)+rotinv 511 superm(column,row)=xcart(idir1,ipert1)-xcart(idir1,ipert2) 512 end do 513 end do 514 do idir1=1, 3 515 ! Setting up D 516 idir2=mod(idir1,3)+1 517 ii=mod(idir1+1,3)+1 518 do ipert2=1, ipert1-1 519 row=n3+9*(ipert1-1)*(ipert1-2)/2+9*(ipert2-1)+3*(rotinv-1)+idir1 520 column=9*natom*(natom-1)/2+3*(ipert1-1)+idir1 521 superm(column,row)=superm(column,row)+xcart(idir2,ipert2)-xcart(idir2,ipert1) 522 column=9*natom*(natom-1)/2+3*(ipert1-1)+ii 523 superm(column,row)=superm(column,row)+xcart(ii,ipert1)-xcart(ii,ipert2) 524 row=n3+9*(ipert1-1)*(ipert1-2)/2+9*(ipert2-1)+3*(idir1-1)+rotinv 525 column=9*natom*(natom-1)/2+3*(ipert2-1)+idir1 526 superm(column,row)=superm(column,row)+xcart(idir2,ipert1)-xcart(idir2,ipert2) 527 column=9*natom*(natom-1)/2+3*(ipert2-1)+ii 528 superm(column,row)=superm(column,row)+xcart(ii,ipert2)-xcart(ii,ipert1) 529 end do 530 ! Setting up A 531 do idir2=1, 3 532 do ipert2=1, ipert1-1 533 column=9*(ipert1-1)*(ipert1-2)/2+9*(ipert2-1)+3*(idir1-1)+idir2 534 row=n3+column 535 superm(column,row)=4*weightf(ipert1,ipert2) 536 end do 537 end do 538 end do 539 end do 540 541 ! calculate the pseudo-inverse of the supermatrix 542 543 ABI_ALLOCATE(work,(1:6*superdim)) 544 ABI_ALLOCATE(vtmatrix,(1:superdim)) 545 ABI_ALLOCATE(umatrix,(1:superdim,1:superdim)) 546 547 ! singular value decomposition of superm 548 549 call dgesvd('A','O',superdim,superdim,superm,superdim,singular,umatrix,superdim, & 550 & vtmatrix, 1, work,6*superdim,info) 551 ABI_CHECK(info == 0, sjoin('dgesvd returned:', itoa(info))) 552 553 ABI_DEALLOCATE(vtmatrix) 554 ABI_DEALLOCATE(work) 555 556 write(message, '(a,es16.8,es16.8)' )& 557 & ' Largest and smallest values from svd', singular(1), singular(superdim) 558 call wrtout(std_out,message,'COLL') 559 call wrtout(ab_out,message,'COLL') 560 561 ! Invert U and V**T, orthogonal matrices 562 563 do ii=1, superdim 564 do jj=1, superdim 565 uinvers(ii,jj)=umatrix(jj,ii) 566 vtinvers(ii,jj)=superm(jj,ii) 567 end do 568 end do 569 570 ABI_DEALLOCATE(umatrix) 571 ABI_DEALLOCATE(superm) 572 573 write(message,'(a,a)')' asrprs: done with asrflag 1', ch10 574 call wrtout(std_out,message,'COLL') 575 576 end if !asrflag=1 577 578 if(asrflag==2) then 579 580 ABI_ALLOCATE(d2vecrnew,(1:superdim)) 581 ABI_ALLOCATE(d2veccnew,(1:superdim)) 582 583 ! Calculate V**T**-1 Sigma**-1 U**-1 *rhs 584 585 do ii=1, superdim 586 d2vecrnew(ii)=0d0 587 d2veccnew(ii)=0d0 588 do jj=1, superdim 589 d2vecrnew(ii)=d2vecrnew(ii)+uinvers(ii,jj)*d2vecr(jj) 590 d2veccnew(ii)=d2veccnew(ii)+uinvers(ii,jj)*d2vecc(jj) 591 end do 592 end do 593 594 rcond=1d-10*singular(1) 595 do ii=1, superdim 596 if(singular(ii)>rcond) then 597 d2vecrnew(ii)=d2vecrnew(ii)/singular(ii) 598 d2veccnew(ii)=d2veccnew(ii)/singular(ii) 599 else 600 d2vecrnew(ii)=0d0 601 d2veccnew(ii)=0d0 602 end if 603 end do 604 605 do ii=1, superdim 606 d2vecr(ii)=0d0 607 d2vecc(ii)=0d0 608 do jj=1, superdim 609 d2vecr(ii)=d2vecr(ii)+vtinvers(ii,jj)*d2vecrnew(jj) 610 d2vecc(ii)=d2vecc(ii)+vtinvers(ii,jj)*d2veccnew(jj) 611 end do 612 end do 613 614 ! Store vector back into the matrix of 2nd order derivates 615 616 do ipert1=1, natom 617 do ipert2=1, ipert1-1 618 do idir1=1,3 619 do idir2=1,3 620 row=9*(ipert1-1)*(ipert1-2)/2+9*(ipert2-1)+3*(idir1-1)+idir2 621 d2cart(1,idir1,ipert1,idir2,ipert2)=d2vecr(row) 622 d2cart(2,idir1,ipert1,idir2,ipert2)=d2vecc(row) 623 d2cart(1,idir2,ipert2,idir1,ipert1)=d2vecr(row) 624 d2cart(2,idir2,ipert2,idir1,ipert1)=d2vecc(row) 625 end do 626 end do 627 end do 628 end do 629 630 ABI_DEALLOCATE(d2vecrnew) 631 ABI_DEALLOCATE(d2veccnew) 632 633 check=0 634 635 do ipert1=1, natom 636 do idir1=1, 3 637 do idir2=1, 3 638 d2cart(1,idir1,ipert1,idir2,ipert1)=0d0 639 d2cart(2,idir1,ipert1,idir2,ipert1)=0d0 640 tmp(ipert1,idir1,idir2)=0d0 641 do ipert2=1, natom 642 if(ipert2/=ipert1) then 643 tmp(ipert1,idir1,idir2)=tmp(ipert1,idir1,idir2) & 644 & -d2cart(1,idir1,ipert1,idir2,ipert2) & 645 & -d2cart(1,idir2,ipert2,idir1,ipert1) 646 end if 647 end do 648 end do 649 end do 650 end do 651 652 do ipert1=1, natom 653 do idir1=1, 3 654 do idir2=1, 3 655 d2cart(1,idir1,ipert1,idir2,ipert1)=tmp(ipert1,idir1,idir2)/2 656 d2cart(1,idir2,ipert1,idir1,ipert1)=d2cart(1,idir1,ipert1,idir2,ipert1) 657 end do 658 end do 659 end do 660 661 write(std_out,*) 'this should all be zero' 662 663 do ipert1=1, natom 664 do idir1=1, 3 665 do idir2=1, 3 666 test=0d0 667 do ipert2=1, natom 668 test=test+d2cart(1,idir1,ipert1,idir2,ipert2)+d2cart(1,idir2,ipert2,idir1,ipert1) 669 end do 670 write(std_out,'(i3,i3,i3,es11.3)') idir1,ipert1,idir2,test 671 672 write(message, '(i3,i3,i3,es11.3)' ) idir1,ipert1,idir2,test 673 call wrtout(ab_out,message,'COLL') 674 675 end do 676 end do 677 end do 678 679 write(std_out,*) 'these as well' 680 do ipert2=1, natom 681 do idir1=1, 3 682 do idir2=1, 3 683 test=0d0 684 do ipert1=1, natom 685 test=test+d2cart(1,idir1,ipert1,idir2,ipert2) 686 end do 687 write(std_out,'(i3,i3,i3,i3,es11.3)') idir1,ipert1,idir2,ipert2,test 688 end do 689 end do 690 end do 691 692 write(message,'(a,a)')' asrprs: done with asrflag 2', ch10 693 call wrtout(std_out,message,'COLL') 694 695 end if !ends asrflag=2 696 697 ABI_DEALLOCATE(d2vecr) 698 ABI_DEALLOCATE(d2vecc) 699 ABI_DEALLOCATE(d2cartold) 700 701 end subroutine asrprs
m_dynmat/axial9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
axial9
FUNCTION
Generates the local coordinates system from the knowledge of the first vector (longitudinal) and the ifc matrix in cartesian coordinates
INPUTS
ifccar(3,3)= matrix of interatomic force constants in cartesian coordinates vect1(3)= cartesian coordinates of the first local vector
OUTPUT
vect2(3)= cartesian coordinates of the second local vector vect3(3)= cartesian coordinates of the third local vector
PARENTS
m_ifc
CHILDREN
SOURCE
5039 subroutine axial9(ifccar,vect1,vect2,vect3) 5040 5041 5042 !This section has been created automatically by the script Abilint (TD). 5043 !Do not modify the following lines by hand. 5044 #undef ABI_FUNC 5045 #define ABI_FUNC 'axial9' 5046 !End of the abilint section 5047 5048 implicit none 5049 5050 !Arguments ------------------------------- 5051 !arrays 5052 real(dp),intent(in) :: ifccar(3,3),vect1(3) 5053 real(dp),intent(out) :: vect2(3),vect3(3) 5054 5055 !Local variables ------------------------- 5056 !scalars 5057 integer :: flag,ii,itrial,jj 5058 real(dp) :: innorm,scprod 5059 !arrays 5060 real(dp) :: work(3) 5061 5062 ! ********************************************************************* 5063 5064 do jj=1,3 5065 work(jj)=zero 5066 do ii=1,3 5067 work(jj)=work(jj)+ifccar(jj,ii)*vect1(ii) 5068 end do 5069 end do 5070 5071 flag=0 5072 do itrial=1,4 5073 scprod=zero 5074 do ii=1,3 5075 scprod=scprod+work(ii)*vect1(ii) 5076 end do 5077 5078 do ii=1,3 5079 work(ii)=work(ii)-vect1(ii)*scprod 5080 end do 5081 5082 scprod=zero 5083 do ii=1,3 5084 scprod=scprod+work(ii)**2 5085 end do 5086 5087 if(scprod<1.0d-10)then 5088 work(1:3)=zero 5089 if(itrial>1)work(itrial-1)=1.0_dp 5090 else 5091 flag=1 5092 end if 5093 5094 if(flag==1)exit 5095 end do 5096 5097 innorm=scprod**(-0.5_dp) 5098 do ii=1,3 5099 vect2(ii)=work(ii)*innorm 5100 end do 5101 5102 vect3(1)=vect1(2)*vect2(3)-vect1(3)*vect2(2) 5103 vect3(2)=vect1(3)*vect2(1)-vect1(1)*vect2(3) 5104 vect3(3)=vect1(1)*vect2(2)-vect1(2)*vect2(1) 5105 5106 end subroutine axial9
m_dynmat/bigbx9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
bigbx9
FUNCTION
Generation of a Big Box containing all the R points in the cartesian real space needed to Fourier Transforms the dynamical matrix into its corresponding interatomic force.
INPUTS
brav= Bravais Lattice (1 or -1=S.C.;2=F.C.C.;3=BCC;4=Hex.) choice= if 0, simply count nrpt ; if 1, checks that the input mrpt is the same as nrpt, and generate rpt(3,mrpt) mrpt=dimension of rpt ngqpt(3)= Numbers used to generate the q points to sample the Brillouin zone using an homogeneous grid nqshft= number of q-points in the repeated cell for the Brillouin zone sampling When nqshft is not 1, but 2 or 4 (only other allowed values), the limits for the big box have to be extended by a factor of 2. rprim(3,3)= Normalized coordinates in real space !!! IS THIS CORRECT?
OUTPUT
cell= (nrpt,3) Give the index of the the cell and irpt nprt= Number of R points in the Big Box rpt(3,mrpt)= Canonical coordinates of the R points in the unit cell These coordinates are normalized (=> * acell(3)!!) (output only if choice=1)
PARENTS
m_dynmat
CHILDREN
SOURCE
2661 subroutine bigbx9(brav,cell,choice,mrpt,ngqpt,nqshft,nrpt,rprim,rpt) 2662 2663 2664 !This section has been created automatically by the script Abilint (TD). 2665 !Do not modify the following lines by hand. 2666 #undef ABI_FUNC 2667 #define ABI_FUNC 'bigbx9' 2668 !End of the abilint section 2669 2670 implicit none 2671 2672 !Arguments ------------------------------- 2673 !scalars 2674 integer,intent(in) :: brav,choice,mrpt,nqshft 2675 integer,intent(out) :: nrpt 2676 !arrays 2677 integer,intent(in) :: ngqpt(3) 2678 real(dp),intent(in) :: rprim(3,3) 2679 real(dp),intent(out) :: rpt(3,mrpt) 2680 integer,intent(out) :: cell(3,mrpt) 2681 2682 !Local variables ------------------------- 2683 !In some cases, the atoms coordinates are not packed in the 2684 ! [0,1]^3 cube. Then, the parameter "buffer" might be increased, 2685 !to search relevant pairs of atoms in bigger boxes than usual. 2686 !scalars 2687 integer,parameter :: buffer=1 2688 integer :: irpt,lim1,lim2,lim3,lqshft,r1,r2,r3 2689 character(len=500) :: msg 2690 2691 ! ********************************************************************* 2692 2693 lqshft=1 2694 if(nqshft/=1)lqshft=2 2695 2696 2697 !Simple Cubic Lattice 2698 if (abs(brav)==1) then 2699 lim1=((ngqpt(1))+1)*lqshft+buffer 2700 lim2=((ngqpt(2))+1)*lqshft+buffer 2701 lim3=((ngqpt(3))+1)*lqshft+buffer 2702 nrpt=(2*lim1+1)*(2*lim2+1)*(2*lim3+1) 2703 if(choice/=0)then 2704 if (nrpt/=mrpt) then 2705 write(msg,'(2(a,i0))')' nrpt=',nrpt,' is not equal to mrpt= ',mrpt 2706 MSG_BUG(msg) 2707 end if 2708 irpt=0 2709 do r1=-lim1,lim1 2710 do r2=-lim2,lim2 2711 do r3=-lim3,lim3 2712 irpt=irpt+1 2713 rpt(1,irpt)=r1*rprim(1,1)+r2*rprim(1,2)+r3*rprim(1,3) 2714 rpt(2,irpt)=r1*rprim(2,1)+r2*rprim(2,2)+r3*rprim(2,3) 2715 rpt(3,irpt)=r1*rprim(3,1)+r2*rprim(3,2)+r3*rprim(3,3) 2716 cell(1,irpt)=r1;cell(2,irpt)=r2;cell(3,irpt)=r3 2717 end do 2718 end do 2719 end do 2720 end if 2721 2722 ! Face Centered Cubic Lattice 2723 else if (brav==2) then 2724 lim1=((ngqpt(1)+3)/4)*lqshft+buffer 2725 lim2=((ngqpt(2)+3)/4)*lqshft+buffer 2726 lim3=((ngqpt(3)+3)/4)*lqshft+buffer 2727 nrpt=(2*lim1+1)*(2*lim2+1)*(2*lim3+1)*4 2728 if(choice/=0)then 2729 if (nrpt/=mrpt) then 2730 write(msg,'(2(a,i0))')' nrpt=',nrpt,' is not equal to mrpt= ',mrpt 2731 MSG_BUG(msg) 2732 end if 2733 irpt=0 2734 do r1=-lim1,lim1 2735 do r2=-lim2,lim2 2736 do r3=-lim3,lim3 2737 irpt=irpt+4 2738 rpt(1,irpt-3)=r1 2739 rpt(2,irpt-3)=r2 2740 rpt(3,irpt-3)=r3 2741 rpt(1,irpt-2)=r1 2742 rpt(2,irpt-2)=r2+0.5 2743 rpt(3,irpt-2)=r3+0.5 2744 rpt(1,irpt-1)=r1+0.5 2745 rpt(2,irpt-1)=r2 2746 rpt(3,irpt-1)=r3+0.5 2747 rpt(1,irpt)=r1+0.5 2748 rpt(2,irpt)=r2+0.5 2749 rpt(3,irpt)=r3 2750 !TEST_AM 2751 ! cell(irpt-3,1)=r1;cell(irpt-3,2)=r2;cell(irpt-3,3)=r3 2752 cell(1,irpt)=r1;cell(2,irpt)=r2;cell(3,irpt)=r3 2753 end do 2754 end do 2755 end do 2756 end if 2757 2758 ! Body Centered Cubic Lattice 2759 else if (brav==3) then 2760 lim1=((ngqpt(1)+3)/4)*lqshft+buffer 2761 lim2=((ngqpt(2)+3)/4)*lqshft+buffer 2762 lim3=((ngqpt(3)+3)/4)*lqshft+buffer 2763 nrpt=(2*lim1+1)*(2*lim2+1)*(2*lim3+1)*2 2764 if(choice/=0)then 2765 if(nrpt/=mrpt) then 2766 write(msg,'(2(a,i0))')' nrpt= ',nrpt,' is not equal to mrpt= ',mrpt 2767 MSG_BUG(msg) 2768 end if 2769 irpt=0 2770 do r1=-lim1,lim1 2771 do r2=-lim2,lim2 2772 do r3=-lim3,lim3 2773 irpt=irpt+2 2774 rpt(1,irpt-1)=r1 2775 rpt(2,irpt-1)=r2 2776 rpt(3,irpt-1)=r3 2777 rpt(1,irpt)=r1+0.5 2778 rpt(2,irpt)=r2+0.5 2779 rpt(3,irpt)=r3+0.5 2780 !TEST_AM 2781 ! cell(irpt-1,1)=r1;cell(irpt-1,2)=r2;cell(irpt-1,3)=r3 2782 cell(1,irpt)=r1;cell(2,irpt)=r2;cell(3,irpt)=r3 2783 end do 2784 end do 2785 end do 2786 end if 2787 2788 ! Hexagonal Lattice 2789 else if (brav==4) then 2790 lim1=(ngqpt(1)+1)*lqshft+buffer 2791 lim2=(ngqpt(2)+1)*lqshft+buffer 2792 lim3=((ngqpt(3)/2)+1)*lqshft+buffer 2793 nrpt=(2*lim1+1)*(2*lim2+1)*(2*lim3+1) 2794 if(choice/=0)then 2795 if(nrpt/=mrpt)then 2796 write(msg,'(2(a,i0))')' nrpt=',nrpt,' is not equal to mrpt=',mrpt 2797 MSG_BUG(msg) 2798 end if 2799 irpt=0 2800 do r1=-lim1,lim1 2801 do r2=-lim2,lim2 2802 do r3=-lim3,lim3 2803 irpt=irpt+1 2804 rpt(1,irpt)=r1*rprim(1,1)+r2*rprim(1,2)+r3*rprim(1,3) 2805 rpt(2,irpt)=r1*rprim(2,1)+r2*rprim(2,2)+r3*rprim(2,3) 2806 rpt(3,irpt)=r1*rprim(3,1)+r2*rprim(3,2)+r3*rprim(3,3) 2807 cell(1,irpt)=r1;cell(2,irpt)=r2;cell(3,irpt)=r3 2808 end do 2809 end do 2810 end do 2811 end if 2812 2813 else 2814 write(msg,'(a,i0,a)')' The value of brav= ',brav,' is not allowed (should be -1, 1, 2 or 4).' 2815 MSG_BUG(msg) 2816 end if 2817 2818 end subroutine bigbx9
m_dynmat/canat9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
canat9
FUNCTION
Transforms an atom whose coordinates (xred*rprim) would not be in the chosen unit cell used to generate the interatomic forces to its correspondent (rcan) in canonical coordinates.
INPUTS
brav= Bravais Lattice (1 or -1=S.C.;2=F.C.C.;3=BCC;4=Hex.) natom= Number of atoms in the unit cell rprim(3,3)= Normalized coordinates of primitive vectors
OUTPUT
rcan(3,natom) = Atomic position in canonical coordinates trans(3,natom) = Atomic translations : xred = rcan + trans
PARENTS
m_ifc
CHILDREN
SOURCE
2849 subroutine canat9(brav,natom,rcan,rprim,trans,xred) 2850 2851 2852 !This section has been created automatically by the script Abilint (TD). 2853 !Do not modify the following lines by hand. 2854 #undef ABI_FUNC 2855 #define ABI_FUNC 'canat9' 2856 use interfaces_14_hidewrite 2857 !End of the abilint section 2858 2859 implicit none 2860 2861 !Arguments ------------------------------- 2862 !scalars 2863 integer,intent(in) :: brav,natom 2864 !arrays 2865 real(dp),intent(in) :: rprim(3,3),xred(3,natom) 2866 real(dp),intent(out) :: rcan(3,natom),trans(3,natom) 2867 2868 !Local variables ------------------------- 2869 !scalars 2870 integer :: found,iatom,ii 2871 character(len=500) :: message 2872 !arrays 2873 real(dp) :: dontno(3,4),rec(3),rok(3),shift(3),tt(3) 2874 2875 ! ********************************************************************* 2876 2877 DBG_ENTER("COLL") 2878 2879 !Normalization of the cartesian atomic coordinates 2880 !If not normalized : rcan(i) <- rcan(i) * acell(i) 2881 do iatom=1,natom 2882 rcan(:,iatom)=xred(1,iatom)*rprim(:,1)+& 2883 & xred(2,iatom)*rprim(:,2)+& 2884 & xred(3,iatom)*rprim(:,3) 2885 end do 2886 2887 !Study of the different cases for the Bravais lattice: 2888 2889 !Simple Cubic Lattice 2890 if (abs(brav)==1) then 2891 2892 do iatom=1,natom 2893 2894 ! Canon will produces these coordinate transformations 2895 ! (Note : here we still use reduced coordinates ) 2896 call wrap2_pmhalf(xred(1,iatom),rok(1),shift(1)) 2897 call wrap2_pmhalf(xred(2,iatom),rok(2),shift(2)) 2898 call wrap2_pmhalf(xred(3,iatom),rok(3),shift(3)) 2899 2900 ! New coordinates : rcan 2901 rcan(:,iatom)=rok(1)*rprim(:,1)+& 2902 & rok(2)*rprim(:,2)+& 2903 & rok(3)*rprim(:,3) 2904 ! Translations between New and Old coordinates 2905 tt(:)=xred(1,iatom)*rprim(:,1)+& 2906 & xred(2,iatom)*rprim(:,2)+& 2907 & xred(3,iatom)*rprim(:,3) 2908 trans(:,iatom)=tt(:)-rcan(:,iatom) 2909 end do 2910 2911 else if (brav==2) then 2912 ! Face Centered Lattice 2913 ! Special possible translations in the F.C.C. case 2914 dontno(:,:)=zero 2915 dontno(2,2)=0.5_dp 2916 dontno(3,2)=0.5_dp 2917 dontno(1,3)=0.5_dp 2918 dontno(3,3)=0.5_dp 2919 dontno(1,4)=0.5_dp 2920 dontno(2,4)=0.5_dp 2921 do iatom=1,natom 2922 found=0 2923 do ii=1,4 2924 if (found==1) exit 2925 ! Canon will produces these coordinate transformations 2926 call wrap2_pmhalf(rcan(1,iatom)+dontno(1,ii),rok(1),shift(1)) 2927 call wrap2_pmhalf(rcan(2,iatom)+dontno(2,ii),rok(2),shift(2)) 2928 call wrap2_pmhalf(rcan(3,iatom)+dontno(3,ii),rok(3),shift(3)) 2929 ! In the F.C.C., ABS[ Ri ] + ABS[ Rj ] < or = 1/2 2930 ! The equal signs has been treated using a tolerance parameter 2931 ! not to have twice the same point in the unit cell ! 2932 rok(1)=rok(1)-1.0d-10 2933 rok(2)=rok(2)-2.0d-10 2934 rok(3)=rok(3)-5.0d-10 2935 if (abs(rok(1))+abs(rok(2))<=0.5_dp) then 2936 if (abs(rok(1))+abs(rok(3))<=0.5_dp) then 2937 if (abs(rok(2))+abs(rok(3))<=0.5_dp) then 2938 tt(:)=rcan(:,iatom) 2939 ! New coordinates : rcan 2940 rcan(1,iatom)=rok(1)+1.0d-10 2941 rcan(2,iatom)=rok(2)+2.0d-10 2942 rcan(3,iatom)=rok(3)+5.0d-10 2943 ! Translations between New and Old coordinates 2944 trans(:,iatom)=tt(:)-rcan(:,iatom) 2945 found=1 2946 end if 2947 end if 2948 end if 2949 end do 2950 end do 2951 2952 else if (brav==3) then 2953 ! Body Centered Cubic Lattice 2954 ! Special possible translations in the B.C.C. case 2955 2956 dontno(:,1)=zero 2957 dontno(:,2)=0.5_dp 2958 do iatom=1,natom 2959 found=0 2960 do ii=1,2 2961 if (found==1) exit 2962 ! Canon will produce these coordinate transformations 2963 call wrap2_pmhalf(rcan(1,iatom)+dontno(1,ii),rok(1),shift(1)) 2964 call wrap2_pmhalf(rcan(2,iatom)+dontno(2,ii),rok(2),shift(2)) 2965 call wrap2_pmhalf(rcan(3,iatom)+dontno(3,ii),rok(3),shift(3)) 2966 ! In the F.C.C., ABS[ Ri ] < or = 1/2 2967 ! and ABS[ R1 ] + ABS[ R2 ] + ABS[ R3 ] < or = 3/4 2968 ! The equal signs has been treated using a tolerance parameter 2969 ! not to have twice the same point in the unit cell ! 2970 rok(1)=rok(1)-1.0d-10 2971 rok(2)=rok(2)-2.0d-10 2972 rok(3)=rok(3)-5.0d-10 2973 if(abs(rok(1))+abs(rok(2))+abs(rok(3))<=0.75_dp)then 2974 if ( abs(rok(1))<=0.5_dp .and.& 2975 & abs(rok(2))<=0.5_dp .and.& 2976 & abs(rok(3))<=0.5_dp ) then 2977 tt(:)=rcan(:,iatom) 2978 ! New coordinates : rcan 2979 rcan(1,iatom)=rok(1)+1.0d-10 2980 rcan(2,iatom)=rok(2)+2.0d-10 2981 rcan(3,iatom)=rok(3)+5.0d-10 2982 ! Translations between New and Old coordinates 2983 trans(:,iatom)=tt(:)-rcan(:,iatom) 2984 found=1 2985 end if 2986 end if 2987 end do 2988 end do 2989 2990 else if (brav==4) then 2991 ! Hexagonal Lattice 2992 ! In this case, it is easier first to work in reduced coordinates space ! 2993 do iatom=1,natom 2994 ! Passage from the reduced space to the "lozenge" cell 2995 rec(1)=xred(1,iatom)-0.5_dp 2996 rec(2)=xred(2,iatom)-0.5_dp 2997 rec(3)=xred(3,iatom) 2998 ! Canon will produces these coordinate transformations 2999 call wrap2_pmhalf(rec(1),rok(1),shift(1)) 3000 call wrap2_pmhalf(rec(2),rok(2),shift(2)) 3001 call wrap2_pmhalf(rec(3),rok(3),shift(3)) 3002 rec(1)=rok(1)+0.5_dp 3003 rec(2)=rok(2)+0.5_dp 3004 rec(3)=rok(3) 3005 ! Passage in Cartesian Normalized Coordinates 3006 rcan(:,iatom)=rec(1)*rprim(:,1)+& 3007 & rec(2)*rprim(:,2)+& 3008 & rec(3)*rprim(:,3) 3009 ! Use of a tolerance parameter not to have twice the same point 3010 ! in the unit cell ! 3011 rcan(1,iatom)=rcan(1,iatom)-1.0d-10 3012 rcan(2,iatom)=rcan(2,iatom)-2.0d-10 3013 ! Passage to the honey-com hexagonal unit cell ! 3014 if (rcan(1,iatom)>0.5_dp) then 3015 rcan(1,iatom)=rcan(1,iatom)-1.0_dp 3016 end if 3017 if (rcan(1,iatom)>zero.and.rcan(1,iatom)+sqrt(3.0_dp)*rcan& 3018 & (2,iatom)>1.0_dp) then 3019 rcan(1,iatom)=rcan(1,iatom)-0.5_dp 3020 rcan(2,iatom)=rcan(2,iatom)-sqrt(3.0_dp)*0.5_dp 3021 end if 3022 if (rcan(1,iatom)<=zero.and.sqrt(3.0_dp)*rcan(2,iatom)-rcan& 3023 & (1,iatom)>1.0_dp) then 3024 rcan(1,iatom)=rcan(1,iatom)+0.5_dp 3025 rcan(2,iatom)=rcan(2,iatom)-sqrt(3.0_dp)*0.5_dp 3026 end if 3027 ! Translations between New and Old coordinates 3028 tt(:)=xred(1,iatom)*rprim(:,1)+xred(2,iatom)*rprim(:,2)& 3029 & +xred(3,iatom)*rprim(:,3) 3030 trans(:,iatom)=tt(:)-rcan(:,iatom) 3031 end do 3032 3033 ! End of the possible cases for brav : -1, 1, 2, 4. 3034 else 3035 3036 write(message, '(a,i0,a,a,a)' )& 3037 & 'The required value of brav=',brav,' is not available.',ch10,& 3038 & 'It should be -1, 1,2 or 4 .' 3039 MSG_BUG(message) 3040 end if 3041 3042 call wrtout(std_out,' Canonical Atomic Coordinates ',"COLL") 3043 3044 do iatom=1,natom 3045 write(message, '(a,i5,3es18.8)' )' atom',iatom,rcan(1,iatom),rcan(2,iatom),rcan(3,iatom) 3046 call wrtout(std_out,message,'COLL') 3047 end do 3048 3049 DBG_EXIT("COLL") 3050 3051 end subroutine canat9
m_dynmat/canct9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
canct9
FUNCTION
Convert from canonical coordinates to cartesian coordinates a vector defined by its index=ib+natom*(irpt-1)
INPUTS
acell(3)=length scales by which rprim is to be multiplied gprim(3,3)=dimensionless primitive translations in reciprocal space index= index of the atom natom=number of atoms in unit cell nrpt= Number of R points in the Big Box rcan(3,natom)=canonical coordinates of atoms rprim(3,3)=dimensionless primitive translations in real space rpt(3,nrpt)=canonical coordinates of the points in the BigBox.
OUTPUT
ib=number of the atom in the unit cell irpt= number of the unit cell to which belong the atom rcart(3)=cartesian coordinate of the atom indexed by index.
PARENTS
ddb_hybrid,m_ifc
CHILDREN
SOURCE
3087 subroutine canct9(acell,gprim,ib,index,irpt,natom,nrpt,rcan,rcart,rprim,rpt) 3088 3089 3090 !This section has been created automatically by the script Abilint (TD). 3091 !Do not modify the following lines by hand. 3092 #undef ABI_FUNC 3093 #define ABI_FUNC 'canct9' 3094 !End of the abilint section 3095 3096 implicit none 3097 3098 !Arguments ------------------------------- 3099 !scalars 3100 integer,intent(in) :: index,natom,nrpt 3101 integer,intent(out) :: ib,irpt 3102 !arrays 3103 real(dp),intent(in) :: acell(3),gprim(3,3),rcan(3,natom),rprim(3,3) 3104 real(dp),intent(in) :: rpt(3,nrpt) 3105 real(dp),intent(out) :: rcart(3) 3106 3107 !Local variables ------------------------- 3108 !scalars 3109 integer :: jj 3110 !arrays 3111 real(dp) :: xred(3) 3112 3113 ! ********************************************************************* 3114 3115 irpt=(index-1)/natom+1 3116 ib=index-natom*(irpt-1) 3117 3118 !Transform the canonical coordinates to reduced coord. 3119 do jj=1,3 3120 xred(jj)=gprim(1,jj)*(rpt(1,irpt)+rcan(1,ib))& 3121 & +gprim(2,jj)*(rpt(2,irpt)+rcan(2,ib))& 3122 & +gprim(3,jj)*(rpt(3,irpt)+rcan(3,ib)) 3123 end do 3124 3125 !Then to cartesian coordinates (here the position of the atom b) 3126 do jj=1,3 3127 rcart(jj)=xred(1)*acell(1)*rprim(jj,1)+& 3128 & xred(2)*acell(2)*rprim(jj,2)+& 3129 & xred(3)*acell(3)*rprim(jj,3) 3130 end do 3131 3132 end subroutine canct9
m_dynmat/cart29 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
cart29
FUNCTION
Transform a second-derivative matrix from reduced coordinates to cartesian coordinates, and also 1) add the ionic part of the effective charges, 2) normalize the electronic dielectric tensor, and add the vacuum polarisation
INPUTS
blkflg(3,mpert,3,mpert,nblok)= ( 1 if the element of the dynamical matrix has been calculated ; 0 otherwise ) blkval(2,3,mpert,3,mpert,nblok)=DDB values gprimd(3,3)=basis vector in the reciprocal space iblok=number of the blok that will be transformed mpert =maximum number of ipert natom=number of atom nblok=number of blocks (dimension of blkflg and blkval) ntypat=number of atom types rprimd(3,3)=basis vector in the real space typat(natom)=integer label of each type of atom (1,2,...) ucvol=unit cell volume zion(ntypat)=charge corresponding to the atom type
OUTPUT
carflg(3,mpert,3,mpert)= ( 1 if the element of the cartesian 2DTE matrix has been calculated correctly ; 0 otherwise ) d2cart(2,3,mpert,3,mpert)= dynamical matrix, effective charges, dielectric tensor,.... all in cartesian coordinates
PARENTS
dfpt_gatherdy,m_ddb
CHILDREN
SOURCE
748 subroutine cart29(blkflg,blkval,carflg,d2cart,& 749 & gprimd,iblok,mpert,natom,nblok,ntypat,rprimd,typat,ucvol,zion) 750 751 752 !This section has been created automatically by the script Abilint (TD). 753 !Do not modify the following lines by hand. 754 #undef ABI_FUNC 755 #define ABI_FUNC 'cart29' 756 !End of the abilint section 757 758 implicit none 759 760 !Arguments ------------------------------- 761 !scalars 762 integer,intent(in) :: iblok,mpert,natom,nblok,ntypat 763 real(dp),intent(in) :: ucvol 764 !arrays 765 integer,intent(in) :: blkflg(3,mpert,3,mpert,nblok),typat(natom) 766 integer,intent(out) :: carflg(3,mpert,3,mpert) 767 real(dp),intent(in) :: blkval(2,3,mpert,3,mpert,nblok),gprimd(3,3),rprimd(3,3) 768 real(dp),intent(in) :: zion(ntypat) 769 real(dp),intent(out) :: d2cart(2,3,mpert,3,mpert) 770 771 !Local variables ------------------------- 772 !scalars 773 integer :: idir1,idir2,ii,ipert1,ipert2 774 !arrays 775 integer :: flg1(3),flg2(3) 776 real(dp) :: vec1(3),vec2(3) 777 778 ! ********************************************************************* 779 780 !First, copy the data blok in place. 781 d2cart(:,:,:,:,:)=blkval(:,:,:,:,:,iblok) 782 783 !Cartesian coordinates transformation (in two steps) 784 !First step 785 do ipert1=1,mpert 786 do ipert2=1,mpert 787 do ii=1,2 788 do idir1=1,3 789 do idir2=1,3 790 vec1(idir2)=d2cart(ii,idir1,ipert1,idir2,ipert2) 791 ! Note here blkflg 792 flg1(idir2)=blkflg(idir1,ipert1,idir2,ipert2,iblok) 793 end do 794 call cart39(flg1,flg2,gprimd,ipert2,natom,rprimd,vec1,vec2) 795 do idir2=1,3 796 d2cart(ii,idir1,ipert1,idir2,ipert2)=vec2(idir2) 797 ! And here carflg 798 carflg(idir1,ipert1,idir2,ipert2)=flg2(idir2) 799 end do 800 end do 801 end do 802 end do 803 end do 804 805 !Second step 806 do ipert1=1,mpert 807 do ipert2=1,mpert 808 do ii=1,2 809 do idir2=1,3 810 do idir1=1,3 811 vec1(idir1)=d2cart(ii,idir1,ipert1,idir2,ipert2) 812 ! Note here carflg 813 flg1(idir1)=carflg(idir1,ipert1,idir2,ipert2) 814 end do 815 call cart39(flg1,flg2,gprimd,ipert1,natom,rprimd,vec1,vec2) 816 do idir1=1,3 817 d2cart(ii,idir1,ipert1,idir2,ipert2)=vec2(idir1) 818 ! And here carflg again 819 carflg(idir1,ipert1,idir2,ipert2)=flg2(idir1) 820 end do 821 end do 822 end do 823 end do 824 end do 825 826 !For the dielectric tensor, takes into account the volume 827 !of the unit cell, and add the unit matrix (polarization of the vacuum) 828 do idir1=1,3 829 do idir2=1,3 830 do ii=1,2 831 d2cart(ii,idir1,natom+2,idir2,natom+2)=& 832 & -four_pi/ucvol*d2cart(ii,idir1,natom+2,idir2,natom+2) 833 end do 834 end do 835 end do 836 837 do idir1=1,3 838 d2cart(1,idir1,natom+2,idir1,natom+2)=& 839 & 1.0_dp+d2cart(1,idir1,natom+2,idir1,natom+2) 840 end do 841 842 !Add the ionic charges to delta z to get the effective charges 843 do ipert1=1,natom 844 do idir1=1,3 845 d2cart(1,idir1,ipert1,idir1,natom+2)=& 846 & zion(typat(ipert1))+d2cart(1,idir1,ipert1,idir1,natom+2) 847 end do 848 end do 849 do ipert2=1,natom 850 do idir2=1,3 851 d2cart(1,idir2,natom+2,idir2,ipert2)=& 852 & zion(typat(ipert2))+d2cart(1,idir2,natom+2,idir2,ipert2) 853 end do 854 end do 855 856 !For the piezoelectric tensor, takes into account the volume of the unit cell 857 do ipert2=natom+3,natom+4 858 do idir1=1,3 859 do idir2=1,3 860 do ii=1,2 861 d2cart(ii,idir1,natom+2,idir2,ipert2)=& 862 & (1.0_dp/ucvol)*d2cart(ii,idir1,natom+2,idir2,ipert2) 863 d2cart(ii,idir2,ipert2,idir1,natom+2)=& 864 & (1.0_dp/ucvol)*d2cart(ii,idir2,ipert2,idir1,natom+2) 865 end do 866 end do 867 end do 868 end do 869 870 end subroutine cart29
m_dynmat/cart39 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
cart39
FUNCTION
Transform a vector from reduced coordinates to cartesian coordinates, taking into account the perturbation from which it was derived, and also check the existence of the new values.
INPUTS
flg1(3)=tell if information of each component of vec1 is valid gprimd(3,3)=basis vector in the reciprocal space ipert=number of the perturbation natom=number of atom rprimd(3,3)=basis vector in the real space vec1(3)=input vector, in reduced coordinates
OUTPUT
flg2(3)=tell if information of each component of vec2 is valid vec2(3)=output vector, in cartesian coordinates
PARENTS
dfpt_gatherdy,m_ddb,m_dynmat
CHILDREN
SOURCE
904 subroutine cart39(flg1,flg2,gprimd,ipert,natom,rprimd,vec1,vec2) 905 906 907 !This section has been created automatically by the script Abilint (TD). 908 !Do not modify the following lines by hand. 909 #undef ABI_FUNC 910 #define ABI_FUNC 'cart39' 911 !End of the abilint section 912 913 implicit none 914 915 !Arguments ------------------------------- 916 !scalars 917 integer,intent(in) :: ipert,natom 918 !arrays 919 integer,intent(in) :: flg1(3) 920 integer,intent(out) :: flg2(3) 921 real(dp),intent(in) :: gprimd(3,3),rprimd(3,3),vec1(3) 922 real(dp),intent(out) :: vec2(3) 923 924 !Local variables ------------------------- 925 !scalars 926 integer :: idir,ii 927 928 ! ********************************************************************* 929 930 !Treat phonon-type perturbation 931 if(ipert>=1.and.ipert<=natom)then 932 933 do idir=1,3 934 vec2(idir)=zero 935 flg2(idir)=1 936 do ii=1,3 937 if(abs(gprimd(idir,ii))>1.0d-10)then 938 if(flg1(ii)==1)then 939 vec2(idir)=vec2(idir)+gprimd(idir,ii)*vec1(ii) 940 else 941 flg2(idir)=0 942 end if 943 end if 944 end do 945 if(flg2(idir)==0)vec2(idir)=zero 946 end do 947 948 ! Treat electric field perturbation 949 else if(ipert==natom+2) then 950 ! OCL SCALAR 951 do idir=1,3 952 vec2(idir)=zero 953 flg2(idir)=1 954 ! OCL SCALAR 955 do ii=1,3 956 if(abs(rprimd(idir,ii))>1.0d-10)then 957 if(flg1(ii)==1)then 958 vec2(idir)=vec2(idir)+rprimd(idir,ii)*vec1(ii)/two_pi 959 else 960 flg2(idir)=0 961 end if 962 end if 963 end do 964 if(flg2(idir)==0)vec2(idir)=zero 965 end do 966 967 ! Treat other perturbations 968 else 969 do idir=1,3 970 vec2(idir)=vec1(idir) 971 flg2(idir)=flg1(idir) 972 end do 973 end if 974 975 end subroutine cart39
m_dynmat/chkph3 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
chkph3
FUNCTION
Check the completeness of the dynamical matrix and eventually send a warning
INPUTS
carflg(3,mpert,3,mpert)= ( 1 if the element of the cartesian 2DTE matrix has been calculated correctly ; 0 otherwise ) idir = direction of the eventual electric field mpert =maximum number of ipert natom=number of atoms in unit cell
OUTPUT
eventually send a warning message
PARENTS
respfn
CHILDREN
SOURCE
1168 subroutine chkph3(carflg,idir,mpert,natom) 1169 1170 1171 !This section has been created automatically by the script Abilint (TD). 1172 !Do not modify the following lines by hand. 1173 #undef ABI_FUNC 1174 #define ABI_FUNC 'chkph3' 1175 use interfaces_14_hidewrite 1176 !End of the abilint section 1177 1178 implicit none 1179 1180 !Arguments ------------------------------- 1181 !scalars 1182 integer,intent(in) :: idir,mpert,natom 1183 !arrays 1184 integer,intent(in) :: carflg(3,mpert,3,mpert) 1185 1186 !Local variables ------------------------- 1187 !scalars 1188 integer :: idir1,idir2,ipert1,ipert2,send 1189 character(len=500) :: message 1190 1191 ! ********************************************************************* 1192 1193 send=0 1194 1195 !Check the elements of the analytical part of the dynamical matrix 1196 do ipert2=1,natom 1197 do idir2=1,3 1198 do ipert1=1,natom 1199 do idir1=1,3 1200 if(carflg(idir1,ipert1,idir2,ipert2)==0)then 1201 send=1 1202 end if 1203 end do 1204 end do 1205 end do 1206 end do 1207 1208 !If some electric field is present 1209 if(idir/=0)then 1210 1211 ! Check the dielectric constant 1212 if(carflg(idir,natom+2,idir,natom+2)==0)then 1213 send=1 1214 end if 1215 1216 ! Check the effective charges 1217 do ipert1=1,natom 1218 do idir1=1,3 1219 if(carflg(idir1,ipert1,idir,natom+2)==0)then 1220 send=1 1221 end if 1222 end do 1223 end do 1224 1225 end if 1226 1227 !If needed, send the message 1228 if(send==1)then 1229 write(message, '(a,a,a,a)' )& 1230 & ' chkph3 : WARNING -',ch10,& 1231 & ' The dynamical matrix was incomplete :',& 1232 & ' phonon frequencies may be wrong ...' 1233 call wrtout(std_out,message,'COLL') 1234 call wrtout(ab_out,message,'COLL') 1235 end if 1236 1237 end subroutine chkph3
m_dynmat/chkrp9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
chkrp9
FUNCTION
Check if the rprim used for the definition of the unit cell (in the inputs) are consistent with the rprim used in the routine generating the Big Box needed to generate the interatomic forces.
INPUTS
brav=bravais lattice (1 or -1=simple lattice,2=face centered lattice, 3=centered lattice,4=hexagonal lattice) rprimd(3,3)=dimensional primitive translations for real space (bohr)
OUTPUT
(only checking)
PARENTS
m_ifc
CHILDREN
SOURCE
3161 subroutine chkrp9(brav,rprim) 3162 3163 3164 !This section has been created automatically by the script Abilint (TD). 3165 !Do not modify the following lines by hand. 3166 #undef ABI_FUNC 3167 #define ABI_FUNC 'chkrp9' 3168 !End of the abilint section 3169 3170 implicit none 3171 3172 !Arguments ------------------------------- 3173 !scalars 3174 integer,intent(in) :: brav 3175 !arrays 3176 real(dp),intent(in) :: rprim(3,3) 3177 3178 !Local variables ------------------------- 3179 !scalars 3180 integer :: ii,jj 3181 character(len=500) :: message 3182 3183 ! ********************************************************************* 3184 3185 if (abs(brav)==1) then 3186 ! Simple Cubic Lattice No condition in this case ! 3187 continue 3188 3189 else if (brav==2) then 3190 ! Face Centered Lattice 3191 do ii=1,3 3192 do jj=1,3 3193 if ( ( ii==jj .and. abs(rprim(ii,jj))>tol10) .or.& 3194 & ( ii/=jj .and. abs(rprim(ii,jj)-.5_dp)>tol10) ) then 3195 write(message, '(a,a,a,a,a,a,a,a,a,a,a)' )& 3196 & 'The input variable rprim does not correspond to the',ch10,& 3197 & 'fixed rprim to be used with brav=2 and ifcflag=1 :',ch10,& 3198 & ' 0 1/2 1/2',ch10,& 3199 & ' 1/2 0 1/2',ch10,& 3200 & ' 1/2 1/2 0 ',ch10,& 3201 & 'Action: rebuild your DDB by using the latter rprim.' 3202 MSG_ERROR(message) 3203 end if 3204 end do 3205 end do 3206 3207 else if (brav==3) then 3208 ! Body Centered Cubic Lattice 3209 do ii=1,3 3210 do jj=1,3 3211 if ( ( ii==jj .and. abs(rprim(ii,jj)+.5_dp)>tol10) .or.& 3212 & ( ii/=jj .and. abs(rprim(ii,jj)-.5_dp)>tol10) ) then 3213 write(message, '(a,a,a,a,a,a,a,a,a,a,a)' )& 3214 & 'The input variable rprim does not correspond to the',ch10,& 3215 & 'fixed rprim to be used with brav=3 and ifcflag=1 :',ch10,& 3216 & ' -1/2 1/2 1/2',ch10,& 3217 & ' 1/2 -1/2 1/2',ch10,& 3218 & ' 1/2 1/2 -1/2',ch10,& 3219 & 'Action: rebuild your DDB by using the latter rprim.' 3220 MSG_ERROR(message) 3221 end if 3222 end do 3223 end do 3224 3225 else if (brav==4) then 3226 ! Hexagonal Lattice 3227 if (abs(rprim(1,1)-1.0_dp)>tol10 .or. & 3228 & abs(rprim(3,3)-1.0_dp)>tol10 .or. & 3229 & abs(rprim(2,1) )>tol10 .or. & 3230 & abs(rprim(3,1) )>tol10 .or. & 3231 & abs(rprim(1,3) )>tol10 .or. & 3232 & abs(rprim(2,3) )>tol10 .or. & 3233 & abs(rprim(3,2) )>tol10 .or. & 3234 & abs(rprim(1,2)+0.5_dp)>tol10 .or. & 3235 & abs(rprim(2,2)-0.5_dp*sqrt(3.0_dp))>tol10 ) then 3236 write(message, '(a,a,a,a,a,a,a,a,a,a,a)' )& 3237 & 'The input variable rprim does not correspond to the',ch10,& 3238 & 'fixed rprim to be used with brav=4 and ifcflag=1 :',ch10,& 3239 & ' 1 0 0',ch10,& 3240 & ' -1/2 sqrt[3]/2 0',ch10,& 3241 & ' 0 0 1',ch10,& 3242 & 'Action: rebuild your DDB by using the latter rprim.' 3243 MSG_ERROR(message) 3244 end if 3245 3246 else 3247 3248 write(message, '(a,i4,a,a,a,a,a)' )& 3249 & 'The value of brav=',brav,' is not allowed.',ch10,& 3250 & 'Only -1, 1,2,3 or 4 are allowed.',ch10,& 3251 & 'Action: change the value of brav in your input file.' 3252 MSG_ERROR(message) 3253 end if 3254 3255 end subroutine chkrp9
m_dynmat/chneu9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
chneu9
FUNCTION
Imposition of the Acoustic sum rule on the Effective charges and suppress the imaginary part of the dynamical matrix
INPUTS
chneut=(0 => no ASR, 1 => equal repartition,2 => weighted repartition ) mpert =maximum number of ipert natom=number of atom ntypat=number of types of atoms in unit cell selectz=selection of some parts of the effective charge tensor attached to one atom. (0=> no selection, 1=> trace only, 2=> symmetric part only) typat(natom)=type of the atom zion(ntypat)=atomic charge for every type of atom
SIDE EFFECTS
Input/Output d2cart=matrix of second derivatives of total energy, in cartesian coordinates
PARENTS
dfpt_gatherdy,m_ddb
CHILDREN
SOURCE
1272 subroutine chneu9(chneut,d2cart,mpert,natom,ntypat,selectz,typat,zion) 1273 1274 1275 !This section has been created automatically by the script Abilint (TD). 1276 !Do not modify the following lines by hand. 1277 #undef ABI_FUNC 1278 #define ABI_FUNC 'chneu9' 1279 use interfaces_14_hidewrite 1280 !End of the abilint section 1281 1282 implicit none 1283 1284 !Arguments ------------------------------- 1285 !scalars 1286 integer,intent(in) :: chneut,mpert,natom,ntypat,selectz 1287 !arrays 1288 integer,intent(in) :: typat(natom) 1289 real(dp),intent(in) :: zion(ntypat) 1290 real(dp),intent(inout) :: d2cart(2,3,mpert,3,mpert) 1291 1292 !Local variables ------------------------- 1293 !scalars 1294 integer :: idir1,idir2,ii,ipert1,ipert2 1295 character(len=500) :: message 1296 !arrays 1297 real(dp) :: sumwght(2) 1298 real(dp),allocatable :: wghtat(:) 1299 1300 ! ********************************************************************* 1301 1302 ABI_ALLOCATE(wghtat,(natom)) 1303 1304 !In case of acoustic sum rule imposition, compute the weights on each atom. 1305 if (chneut==1)then 1306 1307 ! The weight is the same for all atom 1308 do ipert1=1,natom 1309 wghtat(ipert1)=1./natom 1310 end do 1311 1312 else if (chneut==2) then 1313 1314 ! The weight is proportional to the diagonal electronic screening charge of the atom 1315 sumwght(1)=zero 1316 do ipert1=1,natom 1317 wghtat(ipert1)=zero 1318 do idir1=1,3 1319 wghtat(ipert1)=wghtat(ipert1)+& 1320 & d2cart(1,idir1,ipert1,idir1,natom+2)+& 1321 & d2cart(1,idir1,natom+2,idir1,ipert1)-2*zion(typat(ipert1)) 1322 end do 1323 sumwght(1)=sumwght(1)+wghtat(ipert1) 1324 end do 1325 1326 ! Normalize the weights to unity 1327 do ipert1=1,natom 1328 wghtat(ipert1)=wghtat(ipert1)/sumwght(1) 1329 end do 1330 end if 1331 1332 !Calculation of the violation of the charge neutrality 1333 !and imposition of the charge neutrality condition 1334 if (chneut/=0)then 1335 write(message, '(a,a,a,a,a,a,a)' )& 1336 & ' The violation of the charge neutrality conditions',ch10,& 1337 & ' by the effective charges is as follows :',ch10,& 1338 & ' atom electric field',ch10,& 1339 & ' displacement direction ' 1340 call wrtout(ab_out,message,'COLL') 1341 do idir1=1,3 1342 do idir2=1,3 1343 do ii=1,2 1344 sumwght(ii)=zero 1345 do ipert1=1,natom 1346 sumwght(ii)=sumwght(ii)+d2cart(ii,idir1,ipert1,idir2,natom+2) 1347 end do 1348 do ipert1=1,natom 1349 d2cart(ii,idir1,ipert1,idir2,natom+2)=& 1350 & d2cart(ii,idir1,ipert1,idir2,natom+2)-sumwght(ii)*wghtat(ipert1) 1351 end do 1352 end do 1353 write(message, '(i8,i16,2f16.6)' ) idir1,idir2,sumwght(1),sumwght(2) 1354 call wrtout(ab_out,message,'COLL') 1355 end do 1356 end do 1357 write(message, '(a)' )' ' 1358 call wrtout(ab_out,message,'COLL') 1359 1360 ! The same for the symmetrical part 1361 do idir1=1,3 1362 do idir2=1,3 1363 do ii=1,2 1364 sumwght(ii)=zero 1365 do ipert2=1,natom 1366 sumwght(ii)=sumwght(ii)+d2cart(ii,idir1,natom+2,idir2,ipert2) 1367 end do 1368 do ipert2=1,natom 1369 d2cart(ii,idir1,natom+2,idir2,ipert2)=& 1370 & d2cart(ii,idir1,natom+2,idir2,ipert2)-sumwght(ii)*wghtat(ipert2) 1371 end do 1372 end do 1373 end do 1374 end do 1375 end if 1376 1377 !Selection of the trace of the effective charge tensor attached to each atom 1378 if(selectz==1)then 1379 do ipert1=1,natom 1380 do ii=1,2 1381 sumwght(ii)=zero 1382 do idir1=1,3 1383 sumwght(ii)=sumwght(ii)+d2cart(ii,idir1,ipert1,idir1,natom+2) 1384 end do 1385 do idir1=1,3 1386 do idir2=1,3 1387 d2cart(ii,idir1,ipert1,idir2,natom+2)=zero 1388 end do 1389 end do 1390 do idir1=1,3 1391 d2cart(ii,idir1,ipert1,idir1,natom+2)=sumwght(ii)/3.0_dp 1392 end do 1393 end do 1394 end do 1395 ! Do the same for the symmetrical part of d2cart 1396 do ipert2=1,natom 1397 do ii=1,2 1398 sumwght(ii)=zero 1399 do idir1=1,3 1400 sumwght(ii)=sumwght(ii)+d2cart(ii,idir1,natom+2,idir1,ipert2) 1401 end do 1402 do idir1=1,3 1403 do idir2=1,3 1404 d2cart(ii,idir1,natom+2,idir2,ipert2)=zero 1405 end do 1406 end do 1407 do idir1=1,3 1408 d2cart(ii,idir1,natom+2,idir1,ipert2)=sumwght(ii)/3.0_dp 1409 end do 1410 end do 1411 end do 1412 end if 1413 1414 !Selection of the symmetric part of the effective charge tensor attached to each atom 1415 if(selectz==2)then 1416 do ipert1=1,natom 1417 do ii=1,2 1418 do idir1=1,3 1419 do idir2=1,3 1420 sumwght(ii)=(d2cart(ii,idir1,ipert1,idir2,natom+2)& 1421 & +d2cart(ii,idir2,ipert1,idir1,natom+2))/2.0_dp 1422 d2cart(ii,idir1,ipert1,idir2,natom+2)=sumwght(ii) 1423 d2cart(ii,idir2,ipert1,idir1,natom+2)=sumwght(ii) 1424 end do 1425 end do 1426 end do 1427 end do 1428 ! Do the same for the symmetrical part of d2cart 1429 do ipert1=1,natom 1430 do ii=1,2 1431 do idir1=1,3 1432 do idir2=1,3 1433 sumwght(ii)=(d2cart(ii,idir1,ipert1,idir2,natom+2)& 1434 & +d2cart(ii,idir2,ipert1,idir1,natom+2))/2.0_dp 1435 d2cart(ii,idir1,ipert1,idir2,natom+2)=sumwght(ii) 1436 d2cart(ii,idir2,ipert1,idir1,natom+2)=sumwght(ii) 1437 end do 1438 end do 1439 end do 1440 end do 1441 end if 1442 1443 !Write the effective charge tensor 1444 write(message, '(a,a,a,a,a,a,a)' )& 1445 & ' Effective charge tensors after ',ch10,& 1446 & ' imposition of the charge neutrality,',ch10,& 1447 & ' and eventual restriction to some part :',ch10,& 1448 & ' atom displacement ' 1449 call wrtout(ab_out,message,'COLL') 1450 1451 do ipert1=1,natom 1452 do idir1=1,3 1453 write(message, '(2i10,3es16.6)' )ipert1,idir1,& 1454 & (d2cart(1,idir1,ipert1,idir2,natom+2),idir2=1,3) 1455 call wrtout(ab_out,message,'COLL') 1456 end do 1457 end do 1458 1459 !Zero the imaginary part of the dynamical matrix 1460 write(message, '(a)' )' Now, the imaginary part of the dynamical matrix is zeroed ' 1461 call wrtout(ab_out,message,'COLL') 1462 call wrtout(std_out,message,'COLL') 1463 1464 do ipert1=1,natom 1465 do ipert2=1,natom 1466 do idir1=1,3 1467 do idir2=1,3 1468 d2cart(2,idir1,ipert1,idir2,ipert2)=zero 1469 end do 1470 end do 1471 end do 1472 end do 1473 1474 ABI_DEALLOCATE(wghtat) 1475 1476 end subroutine chneu9
m_dynmat/d2cart_to_red [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
d2cart_to_red
FUNCTION
Transform a second-derivative matrix from cartesian coordinates to reduced coordinate. Also, 1) remove the ionic part of the effective charges, 2) remove the vacuum polarisation from the dielectric tensor and scale it with the unit cell volume In short, does the inverse operation of cart29.
INPUTS
d2cart(2,3,mpert,3,mpert)= second-derivative matrix in cartesian coordinates gprimd(3,3)=basis vector in the reciprocal space rprimd(3,3)=basis vector in the real space mpert =maximum number of ipert natom=number of atom
OUTPUT
d2red(2,3,mpert,3,mpert)= second-derivative matrix in reduced coordinates
PARENTS
ddb_interpolate
CHILDREN
SOURCE
1012 subroutine d2cart_to_red(d2cart, d2red, gprimd, rprimd, mpert, natom, & 1013 & ntypat,typat,ucvol,zion) 1014 1015 1016 !This section has been created automatically by the script Abilint (TD). 1017 !Do not modify the following lines by hand. 1018 #undef ABI_FUNC 1019 #define ABI_FUNC 'd2cart_to_red' 1020 !End of the abilint section 1021 1022 implicit none 1023 1024 !Arguments ------------------------------- 1025 !scalars 1026 integer,intent(in) :: mpert,natom,ntypat 1027 real(dp),intent(in) :: ucvol 1028 !arrays 1029 integer,intent(in) :: typat(natom) 1030 real(dp),intent(in) :: d2cart(2,3,mpert,3,mpert) 1031 real(dp),intent(out) :: d2red(2,3,mpert,3,mpert) 1032 real(dp),intent(in) :: gprimd(3,3),rprimd(3,3) 1033 real(dp),intent(in) :: zion(ntypat) 1034 1035 !Local variables ------------------------- 1036 !scalars 1037 integer :: idir1,idir2,ii,ipert1,ipert2 1038 real(dp) :: fac 1039 !arrays 1040 integer :: flg1(3),flg2(3) 1041 real(dp) :: vec1(3),vec2(3) 1042 1043 ! ********************************************************************* 1044 1045 flg1 = one 1046 flg2 = one 1047 1048 d2red = d2cart 1049 1050 !Remove the ionic charges to z to get the change in effective charges 1051 do ipert1=1,natom 1052 do idir1=1,3 1053 d2red(1,idir1,ipert1,idir1,natom+2)=& 1054 & d2red(1,idir1,ipert1,idir1,natom+2) - zion(typat(ipert1)) 1055 end do 1056 end do 1057 do ipert2=1,natom 1058 do idir2=1,3 1059 d2red(1,idir2,natom+2,idir2,ipert2)=& 1060 & d2red(1,idir2,natom+2,idir2,ipert2) - zion(typat(ipert2)) 1061 end do 1062 end do 1063 1064 ! Remove the vacuum polarizability from the dielectric tensor 1065 do idir1=1,3 1066 d2red(1,idir1,natom+2,idir1,natom+2)=& 1067 & d2red(1,idir1,natom+2,idir1,natom+2) - 1.0_dp 1068 end do 1069 1070 ! Scale the dielectric tensor with the volue of the unit cell 1071 do idir1=1,3 1072 do idir2=1,3 1073 do ii=1,2 1074 d2red(ii,idir1,natom+2,idir2,natom+2)=& 1075 & - (ucvol / four_pi) * d2red(ii,idir1,natom+2,idir2,natom+2) 1076 end do 1077 end do 1078 end do 1079 1080 !For the piezoelectric tensor, takes into account the volume of the unit cell 1081 do ipert2=natom+3,natom+4 1082 do idir1=1,3 1083 do idir2=1,3 1084 do ii=1,2 1085 d2red(ii,idir1,natom+2,idir2,ipert2)=& 1086 & (ucvol)*d2red(ii,idir1,natom+2,idir2,ipert2) 1087 d2red(ii,idir2,ipert2,idir1,natom+2)=& 1088 & (ucvol)*d2red(ii,idir2,ipert2,idir1,natom+2) 1089 end do 1090 end do 1091 end do 1092 end do 1093 1094 ! Reduced coordinates transformation (in two steps) 1095 ! Note that rprimd and gprimd are swapped, compared to what cart39 expects 1096 ! A factor of (2pi) ** 2 is added to transform the electric field perturbations 1097 1098 !First step 1099 do ipert1=1,mpert 1100 fac = one; if (ipert1==natom+2) fac = two_pi ** 2 1101 1102 do ipert2=1,mpert 1103 do ii=1,2 1104 do idir1=1,3 1105 do idir2=1,3 1106 vec1(idir2)=d2red(ii,idir1,ipert1,idir2,ipert2) 1107 end do 1108 ! Transform vector from cartesian to reduced coordinates 1109 call cart39(flg1,flg2,transpose(rprimd),ipert1,natom,transpose(gprimd),vec1,vec2) 1110 do idir2=1,3 1111 d2red(ii,idir1,ipert1,idir2,ipert2)=vec2(idir2) * fac 1112 end do 1113 end do 1114 end do 1115 end do 1116 end do 1117 1118 !Second step 1119 do ipert1=1,mpert 1120 do ipert2=1,mpert 1121 fac = one; if (ipert2==natom+2) fac = two_pi ** 2 1122 1123 do ii=1,2 1124 do idir2=1,3 1125 do idir1=1,3 1126 vec1(idir1)=d2red(ii,idir1,ipert1,idir2,ipert2) 1127 end do 1128 ! Transform vector from cartestian to reduced coordinates 1129 call cart39(flg1,flg2,transpose(rprimd),ipert2,natom,transpose(gprimd),vec1,vec2) 1130 do idir1=1,3 1131 d2red(ii,idir1,ipert1,idir2,ipert2)=vec2(idir1) * fac 1132 end do 1133 end do 1134 end do 1135 end do 1136 end do 1137 1138 1139 end subroutine d2cart_to_red
m_dynmat/d2sym3 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
d2sym3
FUNCTION
Given a set of calculated elements of the 2DTE matrix d2, build (nearly) all the other matrix elements that can be build using symmetries. 1. Perform first some completion by symmetrisation (exchange) over the two defining perturbations 2. For each element, uses every symmetry, and build the element, in case EITHER all the needed elements are available, OR the only missing is itself OR the perturbation is the electric field, in a diamond symmetry (the last case was coded rather dirty)
INPUTS
indsym(4,nsym,natom)=indirect indexing array : for each isym,iatom, fourth element is label of atom into which iatom is sent by INVERSE of symmetry operation isym; first three elements are the primitive translations which must be subtracted after the transformation to get back to the original unit cell. mpert =maximum number of ipert natom= number of atoms nsym=number of space group symmetries qpt(3)=wavevector of the perturbation symq(4,2,nsym)= (integer) three first numbers define the G vector ; fourth number is zero if the q-vector is not preserved, is 1 otherwise second index is one without time-reversal symmetry, two with time-reversal symmetry symrec(3,3,nsym)=3x3 matrices of the group symmetries (reciprocal space) symrel(3,3,nsym)=3x3 matrices of the group symmetries (real space) timrev=1 if the time-reversal symmetry preserves the wavevector, modulo a reciprocal lattice vector, timrev=0 otherwise
SIDE EFFECTS
Input/Output d2(2,3,mpert,3,mpert)= matrix of the 2DTE blkflg(3,mpert,3,mpert)= ( 1 if the element of the dynamical matrix has been calculated ; 0 otherwise)
NOTES
The complete search would be to have the possibility of a set of missing elements. See notes of July 2, 1994, in the blue notebook 'computer codes' The partial solution adopted here takes into account some mirror symmetries as well as the tetrahedral symmetry of the diamond lattice On 010331, replaced the loops up to mpert by loops up to natom+2, because of a crash bug under Windows. However, the problem lies likely in the use of the indsym array.
PARENTS
completeperts,m_ddb,respfn
CHILDREN
SOURCE
1541 subroutine d2sym3(blkflg,d2,indsym,mpert,natom,nsym,qpt,symq,symrec,symrel,timrev) 1542 1543 1544 !This section has been created automatically by the script Abilint (TD). 1545 !Do not modify the following lines by hand. 1546 #undef ABI_FUNC 1547 #define ABI_FUNC 'd2sym3' 1548 !End of the abilint section 1549 1550 implicit none 1551 1552 !Arguments ------------------------------- 1553 !scalars 1554 integer,intent(in) :: mpert,natom,nsym,timrev 1555 !arrays 1556 integer,intent(in) :: indsym(4,nsym,natom),symq(4,2,nsym) 1557 integer,intent(in),target :: symrec(3,3,nsym),symrel(3,3,nsym) 1558 integer,intent(inout) :: blkflg(3,mpert,3,mpert) 1559 real(dp),intent(in) :: qpt(3) 1560 real(dp),intent(inout) :: d2(2,3,mpert,3,mpert) 1561 1562 !Local variables ------------------------- 1563 !scalars 1564 logical, parameter :: do_final_sym=.true. 1565 logical :: qzero 1566 integer :: exch12,found,idir1,idir2,idisy1,idisy2,ipert1,ipert2 1567 integer :: ipesy1,ipesy2,isgn,isym,ithree,itirev,noccur,nsym_used,quit,quit1 1568 real(dp) :: arg1,arg2,im,norm,re,sumi,sumr,xi,xr 1569 !arrays 1570 integer,pointer :: sym1_(:,:,:),sym2_(:,:,:) 1571 real(dp),allocatable :: d2tmp1(:,:,:),d2tmp2(:,:,:),d2work(:,:,:,:,:) 1572 1573 ! ********************************************************************* 1574 1575 qzero=(qpt(1)**2+qpt(2)**2+qpt(3)**2<tol16) 1576 1577 !Here look after exchange of 1 and 2 axis, 1578 !for electric field in diamond symmetry 1579 exch12=0 1580 if (qzero) then 1581 do isym=1,nsym 1582 exch12=1 1583 if(symrel(1,1,isym)/=0)exch12=0 1584 if(symrel(1,2,isym)/=1)exch12=0 1585 if(symrel(1,3,isym)/=0)exch12=0 1586 if(symrel(2,1,isym)/=1)exch12=0 1587 if(symrel(2,2,isym)/=0)exch12=0 1588 if(symrel(2,3,isym)/=0)exch12=0 1589 if(symrel(3,1,isym)/=0)exch12=0 1590 if(symrel(3,2,isym)/=0)exch12=0 1591 if(symrel(3,3,isym)/=1)exch12=0 1592 ! if(exch12==1) write(std_out,*)' d2sym3 : found exchange 1 2 =',isym 1593 if(exch12==1)exit 1594 end do 1595 end if 1596 1597 !Exchange of perturbations 1598 1599 !Consider two cases : either time-reversal symmetry 1600 !conserves the wavevector, or not 1601 if(timrev==0)then 1602 1603 ! do ipert1=1,mpert See notes 1604 do ipert1=1,min(natom+2,mpert) 1605 do idir1=1,3 1606 1607 ! Since the matrix is hermitian, the diagonal elements are real 1608 d2(2,idir1,ipert1,idir1,ipert1)=zero 1609 1610 ! do ipert2=1,mpert See notes 1611 do ipert2=1,min(natom+2,mpert) 1612 do idir2=1,3 1613 1614 ! If an element exists 1615 if(blkflg(idir1,ipert1,idir2,ipert2)==1)then 1616 1617 ! Either complete the symmetric missing element 1618 if(blkflg(idir2,ipert2,idir1,ipert1)==0)then 1619 1620 d2(1,idir2,ipert2,idir1,ipert1)= d2(1,idir1,ipert1,idir2,ipert2) 1621 d2(2,idir2,ipert2,idir1,ipert1)=-d2(2,idir1,ipert1,idir2,ipert2) 1622 1623 blkflg(idir2,ipert2,idir1,ipert1)=1 1624 1625 ! Or symmetrize (the matrix is hermitian) in case both exists 1626 ! (Note : this opportunity has been disabled for more 1627 ! obvious search for bugs in the code ) 1628 ! else 1629 ! sumr=d2(1,idir2,ipert2,idir1,ipert1)+d2(1,idir1,ipert1,idir2,ipert2) 1630 ! sumi=d2(1,idir2,ipert2,idir1,ipert1)-d2(1,idir1,ipert1,idir2,ipert2) 1631 ! d2(1,idir2,ipert2,idir1,ipert1)=half*sumr 1632 ! d2(1,idir1,ipert1,idir2,ipert2)=half*sumr 1633 ! d2(2,idir2,ipert2,idir1,ipert1)=half*sumi 1634 ! d2(2,idir1,ipert1,idir2,ipert2)=-half*sumi 1635 end if 1636 end if 1637 1638 end do 1639 end do 1640 1641 end do 1642 end do 1643 1644 ! Here, case with time-reversal symmetry 1645 else 1646 1647 ! do ipert1=1,mpert See notes 1648 do ipert1=1,min(natom+2,mpert) 1649 do idir1=1,3 1650 ! do ipert2=1,mpert See notes 1651 do ipert2=1,min(natom+2,mpert) 1652 do idir2=1,3 1653 d2(2,idir1,ipert1,idir2,ipert2)=zero 1654 1655 ! If an element exists 1656 if(blkflg(idir1,ipert1,idir2,ipert2)==1)then 1657 1658 ! Either complete the symmetric missing element 1659 if(blkflg(idir2,ipert2,idir1,ipert1)==0)then 1660 1661 d2(1,idir2,ipert2,idir1,ipert1)=d2(1,idir1,ipert1,idir2,ipert2) 1662 blkflg(idir2,ipert2,idir1,ipert1)=1 1663 1664 ! Or symmetrize (the matrix is hermitian) in case both exists 1665 ! (Note : this opportunity has been disabled for more 1666 ! obvious search for bugs in the code ) 1667 ! else 1668 ! sumr=d2(1,idir2,ipert2,idir1,ipert1)+d2(1,idir1,ipert1,idir2,ipert2) 1669 ! d2(1,idir2,ipert2,idir1,ipert1)=half*sumr 1670 ! d2(1,idir1,ipert1,idir2,ipert2)=half*sumr 1671 end if 1672 1673 end if 1674 end do 1675 end do 1676 end do 1677 end do 1678 end if 1679 1680 !Big Big Loop : symmetrize three times, because 1681 !of some cases in which one element is not yet available 1682 !at the first pass, and even at the second one ! 1683 do ithree=1,3 1684 1685 ! Big loop on all elements 1686 ! do ipert1=1,mpert See notes 1687 do ipert1=1,min(natom+2,mpert) 1688 1689 ! Select the symmetries according to pertubation 1 1690 if (ipert1<=natom)then 1691 sym1_ => symrec 1692 else 1693 sym1_ => symrel 1694 end if 1695 1696 do idir1=1,3 1697 ! do ipert2=1,mpert See notes 1698 do ipert2=1,min(natom+2,mpert) 1699 1700 ! Select the symmetries according to pertubation 2 1701 if (ipert2<=natom)then 1702 sym2_ => symrec 1703 else 1704 sym2_ => symrel 1705 end if 1706 1707 do idir2=1,3 1708 1709 ! Will get element (idir1,ipert1,idir2,ipert2) 1710 ! so this element should not yet be present ... 1711 if(blkflg(idir1,ipert1,idir2,ipert2)/=1)then 1712 1713 d2(1,idir1,ipert1,idir2,ipert2)=zero 1714 d2(2,idir1,ipert1,idir2,ipert2)=zero 1715 1716 ! Loop on all symmetries, including time-reversal 1717 quit1=0 1718 do isym=1,nsym 1719 do itirev=1,2 1720 isgn=3-2*itirev 1721 1722 if(symq(4,itirev,isym)/=0)then 1723 found=1 1724 1725 ! Here select the symmetric of ipert1 1726 if(ipert1<=natom)then 1727 ipesy1=indsym(4,isym,ipert1) 1728 else if(ipert1==(natom+2).and.qzero)then 1729 ipesy1=ipert1 1730 else 1731 found=0 1732 end if 1733 1734 ! Here select the symmetric of ipert2 1735 if(ipert2<=natom)then 1736 ipesy2=indsym(4,isym,ipert2) 1737 else if(ipert2==(natom+2).and.qzero)then 1738 ipesy2=ipert2 1739 else 1740 found=0 1741 end if 1742 1743 ! Now that a symmetric perturbation has been obtained, 1744 ! including the expression of the symmetry matrix, see 1745 ! if the symmetric values are available 1746 if( found==1 ) then 1747 1748 sumr=zero 1749 sumi=zero 1750 noccur=0 1751 quit=0 1752 do idisy1=1,3 1753 do idisy2=1,3 1754 if(sym1_(idir1,idisy1,isym)/=0 .and. sym2_(idir2,idisy2,isym)/=0 )then 1755 if(blkflg(idisy1,ipesy1,idisy2,ipesy2)==1)then 1756 sumr=sumr+sym1_(idir1,idisy1,isym)*sym2_(idir2,idisy2,isym)*& 1757 & d2(1,idisy1,ipesy1,idisy2,ipesy2) 1758 sumi=sumi+sym1_(idir1,idisy1,isym)*sym2_(idir2,idisy2,isym)*& 1759 & d2(2,idisy1,ipesy1,idisy2,ipesy2) 1760 1761 ! Here, in case the symmetric of the element 1762 ! is the element, or the symmetric with 1763 ! respect to permutation of perturbations 1764 ! (some more conditions on the time-reversal 1765 ! symmetry must be fulfilled although) 1766 else if( idisy1==idir1 .and. ipesy1==ipert1& 1767 & .and. idisy2==idir2 .and. ipesy2==ipert2& 1768 & .and.(isgn==1 .or. timrev==1 & 1769 & .or. (idir1==idir2 .and. ipert1==ipert2)))& 1770 & then 1771 noccur=noccur+sym1_(idir1,idisy1,isym)*sym2_(idir2,idisy2,isym) 1772 else if( idisy1==idir2 .and. ipesy1==ipert2& 1773 & .and. idisy2==idir1 .and. ipesy2==ipert1& 1774 & .and.(isgn==-1 .or. timrev==1& 1775 & .or. (idir1==idir2 .and. ipert1==ipert2)))& 1776 & then 1777 noccur=noccur+sym1_(idir1,idisy1,isym)*sym2_(idir2,idisy2,isym) 1778 1779 ! Here, electric field case 1780 else if( exch12==1 .and. & 1781 & ipert1==natom+2 .and. ipert2==natom+2& 1782 & .and.(( idisy1+idir1 ==3 & 1783 & .and. idisy2==3 .and. idir2==3)& 1784 & .or. ( idisy1+idir2 ==3& 1785 & .and. idisy2==3 .and. idir1==3)& 1786 & .or. ( idisy2+idir2 ==3& 1787 & .and. idisy1==3 .and. idir1==3)& 1788 & .or. ( idisy2+idir1 ==3& 1789 & .and. idisy1==3 .and. idir2==3)))& 1790 & then 1791 noccur=noccur+sym1_(idir1,idisy1,isym)*sym2_(idir2,idisy2,isym) 1792 1793 else 1794 ! Not found 1795 found=0 1796 quit=1 1797 exit 1798 end if 1799 1800 end if 1801 end do 1802 if(quit==1)exit 1803 end do 1804 end if 1805 1806 ! Now, if still found, put the correct value into array d2 1807 if(found==1)then 1808 1809 ! In case of phonons, need to take into account the 1810 ! time-reversal symmetry, and the shift back to the unit cell 1811 ! 1812 ! XG990712 : I am not sure this must be kept for electric field ... 1813 ! 1) Consider time-reversal symmetry 1814 sumi=isgn*sumi 1815 1816 if(ipert1<=natom .and. ipert2<=natom)then 1817 ! 2) Shift the atoms back to the unit cell. 1818 arg1=two_pi*( qpt(1)*indsym(1,isym,ipert1)& 1819 & +qpt(2)*indsym(2,isym,ipert1)& 1820 & +qpt(3)*indsym(3,isym,ipert1) ) 1821 arg2=two_pi*( qpt(1)*indsym(1,isym,ipert2)& 1822 & +qpt(2)*indsym(2,isym,ipert2)& 1823 & +qpt(3)*indsym(3,isym,ipert2) ) 1824 re=cos(arg1)*cos(arg2)+sin(arg1)*sin(arg2) 1825 ! XG010117 Must use isgn 1826 im=isgn*(cos(arg2)*sin(arg1)-cos(arg1)*sin(arg2)) 1827 else 1828 re=one 1829 im=zero 1830 end if 1831 1832 ! Final check, could still fail if the 1833 ! element was its own symmetric 1834 if (abs(1.0_dp-re*noccur)< 1.0d-6.and.abs(im*noccur) <1.0d-6) then 1835 found=0 1836 end if 1837 1838 end if 1839 1840 if(found==1)then 1841 1842 if(noccur==0)then 1843 d2(1,idir1,ipert1,idir2,ipert2)=re*sumr-im*sumi 1844 d2(2,idir1,ipert1,idir2,ipert2)=re*sumi+im*sumr 1845 else 1846 ! See page July 2, 1994 in computer codes notebook 1847 xr=re*sumr-im*sumi 1848 xi=re*sumi+im*sumr 1849 norm=one+noccur**2-two*re*noccur 1850 xr=xr/norm 1851 xi=xi/norm 1852 d2(1,idir1,ipert1,idir2,ipert2)=& 1853 & (one-re*noccur)*xr-im*noccur*xi 1854 d2(2,idir1,ipert1,idir2,ipert2)=& 1855 & (one-re*noccur)*xi+im*noccur*xr 1856 end if 1857 1858 ! The element has been constructed ! 1859 blkflg(idir1,ipert1,idir2,ipert2)=1 1860 1861 quit1=1 1862 exit ! Exit loop on symmetry operations 1863 end if 1864 1865 ! End loop on all symmetries + time-reversal 1866 end if 1867 end do 1868 if(quit1==1)exit 1869 end do 1870 1871 end if 1872 end do ! End big loop on all elements 1873 end do 1874 end do 1875 end do 1876 1877 end do ! End Big Big Loop 1878 1879 !MT oct. 20, 2014: 1880 !Once the matrix has been built, it does not necessarily fulfill the correct symmetries. 1881 !It has just been filled up from rows or columns that only fulfill symmetries perserving 1882 !one particular perturbation. 1883 !An additional symmetrization might solve this (do not consider TR-symmetry) 1884 if (do_final_sym) then 1885 ABI_ALLOCATE(d2tmp1,(2,3,3)) 1886 ABI_ALLOCATE(d2tmp2,(2,3,3)) 1887 ABI_ALLOCATE(d2work,(2,3,mpert,3,mpert)) 1888 d2work(:,:,:,:,:)=d2(:,:,:,:,:) 1889 do ipert1=1,min(natom+2,mpert) 1890 if ((ipert1==natom+1.or.ipert1==natom+10.or.ipert1==natom+11).or.(ipert1==natom+2.and.(.not.qzero))) cycle 1891 if (ipert1<=natom)then 1892 sym1_ => symrec 1893 else 1894 sym1_ => symrel 1895 end if 1896 do ipert2=1,min(natom+2,mpert) 1897 ! if (any(blkflg(:,ipert1,:,ipert2)==0)) cycle 1898 if ((ipert2==natom+1.or.ipert2==natom+10.or.ipert2==natom+11).or.(ipert2==natom+2.and.(.not.qzero))) cycle 1899 if (ipert2<=natom)then 1900 sym2_ => symrec 1901 else 1902 sym2_ => symrel 1903 end if 1904 nsym_used=0 1905 d2tmp2(:,:,:)=zero 1906 do isym=1,nsym 1907 if (symq(4,1,isym)==1) then 1908 ipesy1=ipert1;if (ipert1<=natom) ipesy1=indsym(4,isym,ipert1) 1909 ipesy2=ipert2;if (ipert2<=natom) ipesy2=indsym(4,isym,ipert2) 1910 if (all(blkflg(:,ipesy1,:,ipesy2)==1)) then 1911 nsym_used=nsym_used+1 1912 re=one;im=zero 1913 if (ipert1<=natom.and.ipert2<=natom.and.(.not.qzero)) then 1914 arg1=two_pi*(qpt(1)*(indsym(1,isym,ipert1)-indsym(1,isym,ipert2)) & 1915 & +qpt(2)*(indsym(2,isym,ipert1)-indsym(2,isym,ipert2)) & 1916 & +qpt(3)*(indsym(3,isym,ipert1)-indsym(3,isym,ipert2))) 1917 re=cos(arg1);im=sin(arg1) 1918 end if 1919 d2tmp1(:,:,:)=zero 1920 do idir2=1,3 !kappa 1921 do idir1=1,3 !mu 1922 do idisy1=1,3 !nu 1923 d2tmp1(:,idir1,idir2)=d2tmp1(:,idir1,idir2) & 1924 & +sym1_(idir1,idisy1,isym)*d2(:,idisy1,ipesy1,idir2,ipesy2) 1925 end do 1926 end do 1927 end do 1928 do idir2=1,3 !mu 1929 do idir1=1,3 !kappa 1930 do idisy2=1,3 !nu 1931 d2tmp2(1,idir1,idir2)=d2tmp2(1,idir1,idir2) & 1932 & +sym2_(idir2,idisy2,isym)*(d2tmp1(1,idir1,idisy2)*re-d2tmp1(2,idir1,idisy2)*im) 1933 d2tmp2(2,idir1,idir2)=d2tmp2(2,idir1,idir2) & 1934 & +sym2_(idir2,idisy2,isym)*(d2tmp1(1,idir1,idisy2)*im+d2tmp1(2,idir1,idisy2)*re) 1935 end do 1936 end do 1937 end do 1938 end if 1939 end if 1940 end do ! isym 1941 if (nsym_used>0) d2work(:,1:3,ipert1,1:3,ipert2)=d2tmp2(:,1:3,1:3)/dble(nsym_used) 1942 end do !ipert2 1943 end do !ipert1 1944 if (mpert>=natom) d2(:,1:3,1:natom,1:3,1:natom)=d2work(:,1:3,1:natom,1:3,1:natom) 1945 if (mpert>=natom+2) then 1946 d2(:,1:3,natom+2,1:3,1:natom)=d2work(:,1:3,natom+2,1:3,1:natom) 1947 d2(:,1:3,1:natom,1:3,natom+2)=d2work(:,1:3,1:natom,1:3,natom+2) 1948 d2(:,1:3,natom+2,1:3,natom+2)=d2work(:,1:3,natom+2,1:3,natom+2) 1949 end if 1950 ABI_DEALLOCATE(d2tmp1) 1951 ABI_DEALLOCATE(d2tmp2) 1952 ABI_DEALLOCATE(d2work) 1953 end if 1954 1955 end subroutine d2sym3
m_dynmat/d3sym [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
d3sym
FUNCTION
Given a set of calculated elements of the 3DTE matrix, build (nearly) all the other matrix elements that can be build using symmetries.
INPUTS
indsym(4,nsym,natom)=indirect indexing array : for each isym,iatom, fourth element is label of atom into which iatom is sent by INVERSE of symmetry operation isym; first three elements are the primitive translations which must be subtracted after the transformation to get back to the original unit cell. mpert =maximum number of ipert natom= number of atoms nsym=number of space group symmetries symrec(3,3,nsym)=3x3 matrices of the group symmetries (reciprocal space) symrel(3,3,nsym)=3x3 matrices of the group symmetries (real space)
SIDE EFFECTS
Input/Output blkflg(3,mpert,3,mpert,3,mpert)= matrix that indicates if an element of d3 is available (1 if available, 0 otherwise) d3(2,3,mpert,3,mpert,3,mpert)= matrix of the 3DTE
PARENTS
m_ddb,nonlinear
CHILDREN
SOURCE
4238 subroutine d3sym(blkflg,d3,indsym,mpert,natom,nsym,symrec,symrel) 4239 4240 4241 !This section has been created automatically by the script Abilint (TD). 4242 !Do not modify the following lines by hand. 4243 #undef ABI_FUNC 4244 #define ABI_FUNC 'd3sym' 4245 !End of the abilint section 4246 4247 implicit none 4248 4249 !Arguments ------------------------------- 4250 !scalars 4251 integer,intent(in) :: mpert,natom,nsym 4252 !arrays 4253 integer,intent(in) :: indsym(4,nsym,natom),symrec(3,3,nsym),symrel(3,3,nsym) 4254 integer,intent(inout) :: blkflg(3,mpert,3,mpert,3,mpert) 4255 real(dp),intent(inout) :: d3(2,3,mpert,3,mpert,3,mpert) 4256 4257 !Local variables ------------------------- 4258 !scalars 4259 integer :: found,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert,idisy1,idisy2,idisy3 4260 integer :: ipesy1,ipesy2,ipesy3,isym,ithree 4261 real(dp) :: sumi,sumr 4262 !arrays 4263 integer :: sym1(3,3),sym2(3,3),sym3(3,3) 4264 4265 ! ********************************************************************* 4266 4267 !DEBUG 4268 !write(std_out,*)'d3sym : enter' 4269 !do i1dir = 1, 3 4270 !do i2dir = 1, 3 4271 !do i3dir = 1, 3 4272 !write(std_out,*)i1dir,i2dir,i3dir,blkflg(i1dir,natom+2,i2dir,natom+2,i3dir,natom+2) 4273 !end do 4274 !end do 4275 !end do 4276 !stop 4277 !ENDDEBUG 4278 4279 !First, take into account the permutations symmetry of 4280 !(i1pert,i1dir) and (i3pert,i3dir) 4281 4282 do i1pert = 1, mpert 4283 do i2pert = 1, mpert 4284 4285 do i3pert = 1, mpert 4286 4287 do i1dir = 1, 3 4288 do i2dir = 1, 3 4289 do i3dir = 1, 3 4290 4291 if ((blkflg(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1).and. & 4292 & (blkflg(i3dir,i3pert,i2dir,i2pert,i1dir,i1pert)/=1)) then 4293 4294 d3(:,i3dir,i3pert,i2dir,i2pert,i1dir,i1pert) = & 4295 & d3(:,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) 4296 4297 blkflg(i3dir,i3pert,i2dir,i2pert,i1dir,i1pert) = 1 4298 4299 end if 4300 4301 end do 4302 end do 4303 end do 4304 4305 end do 4306 end do 4307 end do 4308 4309 !Big Big Loop : symmetrize three times, because 4310 !of some cases in which one element is not yet available 4311 !at the first pass, and even at the second one ! 4312 4313 do ithree=1,3 4314 4315 ! Loop over perturbations 4316 do i1pert = 1, mpert 4317 do i2pert = 1, mpert 4318 do i3pert = 1, mpert 4319 4320 do i1dir = 1, 3 4321 do i2dir = 1, 3 4322 do i3dir = 1, 3 4323 4324 ! Will get element (idir1,ipert1,idir2,ipert2) 4325 ! so this element should not yet be present ... 4326 if(blkflg(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)/=1)then 4327 4328 d3(:,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = 0_dp 4329 4330 do isym = 1, nsym 4331 4332 found = 1 4333 4334 if (i1pert <= natom) then 4335 ipesy1 = indsym(4,isym,i1pert) 4336 sym1(:,:) = symrec(:,:,isym) 4337 else if (i1pert == natom + 2) then 4338 ipesy1 = i1pert 4339 sym1(:,:) = symrel(:,:,isym) 4340 else 4341 found = 0 4342 end if 4343 4344 if (i2pert <= natom) then 4345 ipesy2 = indsym(4,isym,i2pert) 4346 sym2(:,:) = symrec(:,:,isym) 4347 else if (i2pert == natom + 2) then 4348 ipesy2 = i2pert 4349 sym2(:,:) = symrel(:,:,isym) 4350 else 4351 found = 0 4352 end if 4353 4354 if (i3pert <= natom) then 4355 ipesy3 = indsym(4,isym,i3pert) 4356 sym3(:,:) = symrec(:,:,isym) 4357 else if (i3pert == natom + 2) then 4358 ipesy3 = i3pert 4359 sym3(:,:) = symrel(:,:,isym) 4360 else 4361 found = 0 4362 end if 4363 4364 sumr = 0_dp ; sumi = 0_dp; 4365 do idisy1 = 1, 3 4366 do idisy2 = 1, 3 4367 do idisy3 = 1, 3 4368 4369 if ((sym1(i1dir,idisy1) /=0).and.(sym2(i2dir,idisy2) /=0) & 4370 & .and.(sym3(i3dir,idisy3) /=0)) then 4371 4372 if (blkflg(idisy1,ipesy1,idisy2,ipesy2,idisy3,ipesy3) == 1) then 4373 4374 sumr = sumr + sym1(i1dir,idisy1)*sym2(i2dir,idisy2)*& 4375 & sym3(i3dir,idisy3)*d3(1,idisy1,ipesy1,idisy2,ipesy2,idisy3,ipesy3) 4376 sumi = sumi + sym1(i1dir,idisy1)*sym2(i2dir,idisy2)*& 4377 & sym3(i3dir,idisy3)*d3(2,idisy1,ipesy1,idisy2,ipesy2,idisy3,ipesy3) 4378 4379 else 4380 4381 found = 0 4382 4383 end if 4384 4385 end if 4386 4387 end do 4388 end do 4389 end do 4390 4391 if (found == 1) then 4392 d3(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = sumr 4393 d3(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = sumi 4394 blkflg(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = 1 4395 end if 4396 4397 end do ! isym 4398 4399 end if ! blkflg 4400 4401 ! Close loop over perturbations 4402 end do 4403 end do 4404 end do 4405 end do 4406 end do 4407 end do 4408 4409 end do ! close loop over ithree 4410 4411 end subroutine d3sym
m_dynmat/dfpt_phfrq [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
dfpt_phfrq
FUNCTION
Get the phonon frequencies and eigenvectors (as well as the corresponding displacements) If q is at Gamma, the non-analytical behaviour can be included. Then, the effective dielectric tensor, the effective charges and oscillator strengths for the limiting direction are also returned
INPUTS
amu(ntypat)=mass of the atoms (atomic mass unit) matrix (diagonal in the atoms) d2cart(2,3,mpert,3,mpert)=dynamical matrix, effective charges, dielectric tensor,.... all in cartesian coordinates indsym(4,msym*natom)=indirect indexing array : for each isym,iatom, fourth element is label of atom into which iatom is sent by INVERSE of symmetry operation isym; first three elements are the primitive translations which must be subtracted after the transformation to get back to the original unit cell. mpert =maximum number of ipert msym=maximum number of symmetries natom=number of atoms in unit cell nsym=number of space group symmetries ntypat=number of atom types qphnrm=(described above) qphon(3)= to be divided by qphnrm, give the phonon wavevector; if qphnrm==0.0_dp, then the wavevector is zero (Gamma point) and qphon gives the direction of the induced electric field in **CARTESIAN** coordinates. in the latter case, if qphon is zero, no non-analytical contribution is included. rprimd(3,3)=dimensional primitive translations (bohr) symdynmat=if 1, (re)symmetrize the dynamical matrix, except if Gamma wavevector with electric field added. symrel(3,3,nsym)=matrices of the group symmetries (real space) typat(natom)=integer label of each type of atom (1,2,...) ucvol=unit cell volume
OUTPUT
displ(2*3*natom*3*natom)= at the end, contains the displacements of atoms in cartesian coordinates. The first index means either the real or the imaginary part, The second index runs on the direction and the atoms displaced The third index runs on the modes. eigval(3*natom)=contains the eigenvalues of the dynamical matrix eigvec(2*3*natom*3*natom)= at the end, contains the eigenvectors of the dynamical matrix in cartesian coordinates. phfrq(3*natom)=phonon frequencies (square root of the dynamical matrix eigenvalues, except if these are negative, and in this case, give minus the square root of the absolute value of the matrix eigenvalues). Hartree units.
NOTES
1) One makes the dynamical matrix hermitian... 2) In case of q=Gamma, only the real part is used.
PARENTS
anaddb,m_ddb,m_effective_potential_file,m_ifc,m_phonons,respfn,thmeig
CHILDREN
SOURCE
5503 subroutine dfpt_phfrq(amu,displ,d2cart,eigval,eigvec,indsym,& 5504 & mpert,msym,natom,nsym,ntypat,phfrq,qphnrm,qphon,rprimd,& 5505 & symdynmat,symrel,symafm,typat,ucvol) 5506 5507 5508 !This section has been created automatically by the script Abilint (TD). 5509 !Do not modify the following lines by hand. 5510 #undef ABI_FUNC 5511 #define ABI_FUNC 'dfpt_phfrq' 5512 !End of the abilint section 5513 5514 implicit none 5515 5516 !Arguments ------------------------------- 5517 !scalars 5518 integer,intent(in) :: mpert,msym,natom,nsym,ntypat,symdynmat 5519 real(dp),intent(in) :: qphnrm,ucvol 5520 !arrays 5521 integer,intent(in) :: indsym(4,msym*natom),symrel(3,3,nsym),typat(natom) 5522 integer,intent(in) :: symafm(nsym) 5523 real(dp),intent(in) :: amu(ntypat),d2cart(2,3,mpert,3,mpert),rprimd(3,3) 5524 real(dp),intent(inout) :: qphon(3) 5525 real(dp),intent(out) :: displ(2*3*natom*3*natom),eigval(3*natom) 5526 real(dp),intent(out) :: eigvec(2*3*natom*3*natom),phfrq(3*natom) 5527 5528 !Local variables ------------------------- 5529 !scalars 5530 integer :: analyt,i1,i2,idir1,idir2,ier,ii,imode,ipert1,ipert2 5531 integer :: jmode,indexi,indexj,index 5532 real(dp) :: epsq,norm,qphon2 5533 logical,parameter :: debug = .False. 5534 real(dp) :: sc_prod 5535 !arrays 5536 real(dp) :: qptn(3),dum(2,0) 5537 real(dp),allocatable :: matrx(:,:),zeff(:,:),zhpev1(:,:),zhpev2(:) 5538 5539 ! ********************************************************************* 5540 5541 !Prepare the diagonalisation: analytical part. 5542 !Note: displ is used as work space here 5543 i1=0 5544 do ipert1=1,natom 5545 do idir1=1,3 5546 i1=i1+1 5547 i2=0 5548 do ipert2=1,natom 5549 do idir2=1,3 5550 i2=i2+1 5551 index=i1+3*natom*(i2-1) 5552 displ(2*index-1)=d2cart(1,idir1,ipert1,idir2,ipert2) 5553 displ(2*index )=d2cart(2,idir1,ipert1,idir2,ipert2) 5554 end do 5555 end do 5556 end do 5557 end do 5558 5559 !Determine the analyticity of the matrix. 5560 analyt=1; if(abs(qphnrm)<tol8) analyt=0 5561 if(abs(qphon(1))<tol8.and.abs(qphon(2))<tol8.and.abs(qphon(3))<tol8) analyt=2 5562 5563 !In case of q=Gamma, only the real part is used 5564 if(analyt==0 .or. analyt==2)then 5565 do i1=1,3*natom 5566 do i2=1,3*natom 5567 index=i1+3*natom*(i2-1) 5568 displ(2*index)=zero 5569 end do 5570 end do 5571 end if 5572 5573 !In the case the non-analyticity is required : 5574 ! MG: the tensor is in cartesian coordinates and this means that qphon must be in 5575 ! given in Cartesian coordinates. 5576 if(analyt==0)then 5577 5578 ! Normalize the limiting direction 5579 qphon2=qphon(1)**2+qphon(2)**2+qphon(3)**2 5580 qphon(:)=qphon(:)/sqrt(qphon2) 5581 5582 ! Get the dielectric constant for the limiting direction 5583 epsq=zero 5584 do idir1=1,3 5585 do idir2=1,3 5586 epsq= epsq + qphon(idir1)*qphon(idir2) * d2cart(1,idir1,natom+2,idir2,natom+2) 5587 end do 5588 end do 5589 5590 ABI_ALLOCATE(zeff,(3,natom)) 5591 5592 ! Get the effective charges for the limiting direction 5593 do idir1=1,3 5594 do ipert1=1,natom 5595 zeff(idir1,ipert1)=zero 5596 do idir2=1,3 5597 zeff(idir1,ipert1) = zeff(idir1,ipert1) + qphon(idir2)* d2cart(1,idir1,ipert1,idir2,natom+2) 5598 end do 5599 end do 5600 end do 5601 5602 ! Get the non-analytical part of the dynamical matrix, and suppress its imaginary part. 5603 i1=0 5604 do ipert1=1,natom 5605 do idir1=1,3 5606 i1=i1+1 5607 i2=0 5608 do ipert2=1,natom 5609 do idir2=1,3 5610 i2=i2+1 5611 index=i1+3*natom*(i2-1) 5612 displ(2*index-1)=displ(2*index-1)+four_pi/ucvol*zeff(idir1,ipert1)*zeff(idir2,ipert2)/epsq 5613 displ(2*index )=zero 5614 end do 5615 end do 5616 end do 5617 end do 5618 5619 ABI_DEALLOCATE(zeff) 5620 end if ! End of the non-analyticity treatment : 5621 5622 ! Multiply IFC(q) by masses 5623 call massmult_and_breaksym(natom, ntypat, typat, amu, displ) 5624 5625 !*********************************************************************** 5626 !Diagonalize the dynamical matrix 5627 5628 !Symmetrize the dynamical matrix 5629 !FIXME: swap the next 2 lines and update test files to include symmetrization for Gamma point too (except in non-analytic case) 5630 !if (symdynmat==1 .and. analyt > 0) then 5631 if (symdynmat==1 .and. analyt == 1) then 5632 qptn(:)=qphon(:) 5633 if (analyt==1) qptn(:)=qphon(:)/qphnrm 5634 call symdyma(displ,indsym,natom,nsym,qptn,rprimd,symrel,symafm) 5635 end if 5636 5637 ier=0; ii=1 5638 ABI_ALLOCATE(matrx,(2,(3*natom*(3*natom+1))/2)) 5639 do i2=1,3*natom 5640 do i1=1,i2 5641 matrx(1,ii)=displ(1+2*(i1-1)+2*(i2-1)*3*natom) 5642 matrx(2,ii)=displ(2+2*(i1-1)+2*(i2-1)*3*natom) 5643 ii=ii+1 5644 end do 5645 end do 5646 5647 ABI_ALLOCATE(zhpev1,(2,2*3*natom-1)) 5648 ABI_ALLOCATE(zhpev2,(3*3*natom-2)) 5649 5650 call ZHPEV ('V','U',3*natom,matrx,eigval,eigvec,3*natom,zhpev1,zhpev2,ier) 5651 ABI_CHECK(ier == 0, sjoin('zhpev returned:', itoa(ier))) 5652 5653 ABI_DEALLOCATE(matrx) 5654 ABI_DEALLOCATE(zhpev1) 5655 ABI_DEALLOCATE(zhpev2) 5656 5657 if (debug) then 5658 ! Check the orthonormality of the eigenvectors 5659 do imode=1,3*natom 5660 do jmode=imode,3*natom 5661 indexi=2*3*natom*(imode-1) 5662 indexj=2*3*natom*(jmode-1) 5663 sc_prod=sum(eigvec(indexi+1:indexi+6*natom)*eigvec(indexj+1:indexj+6*natom)) 5664 write(std_out,'(a,2i4,a,es16.6)')' imode,jmode=',imode,jmode,' real scalar product =',sc_prod 5665 end do 5666 end do 5667 end if 5668 5669 !*********************************************************************** 5670 5671 !Get the phonon frequencies (negative by convention, if 5672 !the eigenvalue of the dynamical matrix is negative) 5673 do imode=1,3*natom 5674 if(eigval(imode)>=1.0d-16)then 5675 phfrq(imode)=sqrt(eigval(imode)) 5676 else if(eigval(imode)>=-1.0d-16)then 5677 phfrq(imode)=zero 5678 else 5679 phfrq(imode)=-sqrt(-eigval(imode)) 5680 end if 5681 end do 5682 5683 !Fix the phase of the eigenvectors 5684 call fxphas_seq(eigvec,dum,0,0,1,3*natom*3*natom,0,3*natom,3*natom,0) 5685 5686 !Normalise the eigenvectors 5687 do imode=1,3*natom 5688 norm=zero 5689 do idir1=1,3 5690 do ipert1=1,natom 5691 i1=idir1+(ipert1-1)*3 5692 index=i1+3*natom*(imode-1) 5693 norm=norm+eigvec(2*index-1)**2+eigvec(2*index)**2 5694 end do 5695 end do 5696 norm=sqrt(norm) 5697 do idir1=1,3 5698 do ipert1=1,natom 5699 i1=idir1+(ipert1-1)*3 5700 index=i1+3*natom*(imode-1) 5701 eigvec(2*index-1)=eigvec(2*index-1)/norm 5702 eigvec(2*index)=eigvec(2*index)/norm 5703 end do 5704 end do 5705 end do 5706 5707 !Get the phonon displacements 5708 do imode=1,3*natom 5709 do idir1=1,3 5710 do ipert1=1,natom 5711 i1=idir1+(ipert1-1)*3 5712 index=i1+3*natom*(imode-1) 5713 displ(2*index-1)=eigvec(2*index-1) / sqrt(amu(typat(ipert1))*amu_emass) 5714 displ(2*index )=eigvec(2*index ) / sqrt(amu(typat(ipert1))*amu_emass) 5715 end do 5716 end do 5717 end do 5718 5719 if (debug) then 5720 write(std_out,'(a)')' Phonon eigenvectors and displacements ' 5721 do imode=1,3*natom 5722 indexi=2*3*natom*(imode-1) 5723 write(std_out,'(a,i4,a,12es16.6)')' imode=',imode,' eigvec(1:6*natom)=',eigvec(indexi+1:indexi+6*natom) 5724 write(std_out,'(a,i4,a,12es16.6)')' imode=',imode,' displ(1:6*natom)=',displ(indexi+1:indexi+6*natom) 5725 end do 5726 5727 ! Check the orthonormality of the eigenvectors 5728 do imode=1,3*natom 5729 do jmode=imode,3*natom 5730 indexi=2*3*natom*(imode-1) 5731 indexj=2*3*natom*(jmode-1) 5732 sc_prod=sum(eigvec(indexi+1:indexi+6*natom)*eigvec(indexj+1:indexj+6*natom)) 5733 write(std_out,'(a,2i4,a,es16.6)')' imode,jmode=',imode,jmode,' real scalar product =',sc_prod 5734 end do 5735 end do 5736 end if 5737 5738 end subroutine dfpt_phfrq
m_dynmat/dist9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
dist9
FUNCTION
Compute the distance between atoms
INPUTS
acell(3)=length scales by which rprim is to be multiplied dist(natom,natom,nrpt)=distances between atoms gprim(3,3)=dimensionless primitive translations in reciprocal space natom=number of atoms in unit cell nrpt= Number of R points in the Big Box rcan(3,natom)=canonical coordinates of atoms rprim(3,3)=dimensionless primitive translations in real space rpt(3,nrpt)=cartesian coordinates of the points in the BigBox.
OUTPUT
dist(natom,natom,nrpt)=distances between atoms
PARENTS
m_ifc
CHILDREN
SOURCE
3287 subroutine dist9(acell,dist,gprim,natom,nrpt,rcan,rprim,rpt) 3288 3289 3290 !This section has been created automatically by the script Abilint (TD). 3291 !Do not modify the following lines by hand. 3292 #undef ABI_FUNC 3293 #define ABI_FUNC 'dist9' 3294 !End of the abilint section 3295 3296 implicit none 3297 3298 !Arguments ------------------------------- 3299 !scalars 3300 integer,intent(in) :: natom,nrpt 3301 !arrays 3302 real(dp),intent(in) :: acell(3),gprim(3,3),rcan(3,natom),rprim(3,3) 3303 real(dp),intent(in) :: rpt(3,nrpt) 3304 real(dp),intent(out) :: dist(natom,natom,nrpt) 3305 3306 !Local variables ------------------------- 3307 !scalars 3308 integer :: ia,ib,ii,irpt 3309 !arrays 3310 real(dp) :: ra(3),rb(3),rdiff(3),red(3),rptcar(3),xred(3) 3311 3312 ! ********************************************************************* 3313 3314 !BIG loop on all generic atoms 3315 do ia=1,natom 3316 3317 ! First transform canonical coordinates to reduced coordinates 3318 do ii=1,3 3319 xred(ii)=gprim(1,ii)*rcan(1,ia)+gprim(2,ii)*rcan(2,ia)& 3320 & +gprim(3,ii)*rcan(3,ia) 3321 end do 3322 ! Then to cartesian coordinates 3323 ra(:)=xred(1)*acell(1)*rprim(:,1)+xred(2)*acell(2)*rprim(:,2)+& 3324 & xred(3)*acell(3)*rprim(:,3) 3325 do ib=1,natom 3326 do ii=1,3 3327 xred(ii)=gprim(1,ii)*rcan(1,ib)+gprim(2,ii)*rcan(2,ib)& 3328 & +gprim(3,ii)*rcan(3,ib) 3329 end do 3330 do ii=1,3 3331 rb(ii)=xred(1)*acell(1)*rprim(ii,1)+& 3332 & xred(2)*acell(2)*rprim(ii,2)+& 3333 & xred(3)*acell(3)*rprim(ii,3) 3334 end do 3335 do irpt=1,nrpt 3336 ! First transform it to reduced coordinates 3337 do ii=1,3 3338 red(ii)=gprim(1,ii)*rpt(1,irpt)+gprim(2,ii)*rpt(2,irpt)& 3339 & +gprim(3,ii)*rpt(3,irpt) 3340 end do 3341 ! Then to cartesian coordinates 3342 do ii=1,3 3343 rptcar(ii)=red(1)*acell(1)*rprim(ii,1)+& 3344 & red(2)*acell(2)*rprim(ii,2)+& 3345 & red(3)*acell(3)*rprim(ii,3) 3346 end do 3347 do ii=1,3 3348 rdiff(ii)=-rptcar(ii)+ra(ii)-rb(ii) 3349 end do 3350 dist(ia,ib,irpt)=(rdiff(1)**2+rdiff(2)**2+rdiff(3)**2)**0.5 3351 3352 end do 3353 3354 end do 3355 end do 3356 3357 end subroutine dist9
m_dynmat/dymfz9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
dymfz9
FUNCTION
As the subroutine canatm has transformed the coordinates of the atoms in normalized canonical coordinates, the corresponding dynamical matrix should be multiplied by a phase shift corresponding to the translation between New and Old coordinates of its two corresponding atoms.
INPUTS
dynmat = non-phase shifted dynamical matrices natom = number of atoms nqpt = number of qpoints gprim = reciprocal lattice vectors (cartesian but dimensionless) option=1 : the matrices are transformed from the old (tn) coordinate system to the new (normalized canonical) 2 : the matrices are restored from the normalized canonical coordinate system to the usual (tn) one... rcan = canonical coordinates of atoms spqpt = qpoint coordinates (reduced reciprocal) trans = Atomic translations : xred = rcan + trans
OUTPUT
dynmat = phase shifted dynamical matrices
PARENTS
m_dynmat,m_ifc
CHILDREN
SOURCE
5146 subroutine dymfz9(dynmat,natom,nqpt,gprim,option,spqpt,trans) 5147 5148 5149 !This section has been created automatically by the script Abilint (TD). 5150 !Do not modify the following lines by hand. 5151 #undef ABI_FUNC 5152 #define ABI_FUNC 'dymfz9' 5153 !End of the abilint section 5154 5155 implicit none 5156 5157 !Arguments ------------------------------- 5158 !scalars 5159 integer,intent(in) :: natom,nqpt,option 5160 !arrays 5161 real(dp),intent(in) :: gprim(3,3),spqpt(3,nqpt),trans(3,natom) 5162 real(dp),intent(inout) :: dynmat(2,3,natom,3,natom,nqpt) 5163 5164 !Local variables ------------------------- 5165 !scalars 5166 integer :: ia,ib,iqpt,mu,nu 5167 real(dp) :: im,ktrans,re 5168 !arrays 5169 real(dp) :: kk(3) 5170 5171 ! ********************************************************************* 5172 5173 DBG_ENTER("COLL") 5174 5175 do iqpt=1,nqpt 5176 ! Definition of q in normalized reciprocal space 5177 kk(1)=spqpt(1,iqpt)*gprim(1,1)+spqpt(2,iqpt)*gprim(1,2)+spqpt(3,iqpt)*gprim(1,3) 5178 kk(2)=spqpt(1,iqpt)*gprim(2,1)+spqpt(2,iqpt)*gprim(2,2)+spqpt(3,iqpt)*gprim(2,3) 5179 kk(3)=spqpt(1,iqpt)*gprim(3,1)+spqpt(2,iqpt)*gprim(3,2)+spqpt(3,iqpt)*gprim(3,3) 5180 5181 if(option==1)then 5182 kk(1)=-kk(1) 5183 kk(2)=-kk(2) 5184 kk(3)=-kk(3) 5185 end if 5186 5187 do ia=1,natom 5188 do ib=1,natom 5189 ! Product of q with the differences between the two atomic translations 5190 ktrans=kk(1)*(trans(1,ia)-trans(1,ib))+kk(2)*(trans(2,ia)-& 5191 & trans(2,ib))+kk(3)*(trans(3,ia)-trans(3,ib)) 5192 do mu=1,3 5193 do nu=1,3 5194 re=dynmat(1,mu,ia,nu,ib,iqpt) 5195 im=dynmat(2,mu,ia,nu,ib,iqpt) 5196 ! Transformation of the Old dynamical matrices by New ones by multiplication by a phase shift 5197 dynmat(1,mu,ia,nu,ib,iqpt)=re*cos(two_pi*ktrans)-im*sin(two_pi*ktrans) 5198 dynmat(2,mu,ia,nu,ib,iqpt)=re*sin(two_pi*ktrans)+im*cos(two_pi*ktrans) 5199 end do 5200 end do 5201 end do 5202 end do 5203 end do 5204 5205 DBG_EXIT("COLL") 5206 5207 end subroutine dymfz9
m_dynmat/dynmat_dq [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
dynmat_dq
FUNCTION
Compute the derivative D(q)/dq of the dynamical matrix via Fourier transform of the interatomic forces
INPUTS
qpt(3)= Reduced coordinates of the q vector in reciprocal space natom= Number of atoms in the unit cell gprim(3,3)= Normalized coordinates in reciprocal space nrpt= Number of R points in the Big Box rpt(3,nprt)= Canonical coordinates of the R points in the unit cell These coordinates are normalized (=> * acell(3)!!) atmfrc(3,natom,3,natom,nrpt)= Interatomic Forces in real space wghatm(natom,natom,nrpt)= Weights associated to a pair of atoms and to a R vector
OUTPUT
dddq(2,3,natom,3,natom,3)= Derivate of the dynamical matrix in cartesian coordinates. The tree directions are stored in the last dimension. These coordinates are normalized (=> * acell(3)!!)
PARENTS
m_ifc
CHILDREN
SOURCE
3610 subroutine dynmat_dq(qpt,natom,gprim,nrpt,rpt,atmfrc,wghatm,dddq) 3611 3612 3613 !This section has been created automatically by the script Abilint (TD). 3614 !Do not modify the following lines by hand. 3615 #undef ABI_FUNC 3616 #define ABI_FUNC 'dynmat_dq' 3617 !End of the abilint section 3618 3619 implicit none 3620 3621 !Arguments ------------------------------- 3622 !scalars 3623 integer,intent(in) :: natom,nrpt 3624 !arrays 3625 real(dp),intent(in) :: gprim(3,3),rpt(3,nrpt),qpt(3) 3626 real(dp),intent(in) :: wghatm(natom,natom,nrpt) 3627 real(dp),intent(in) :: atmfrc(3,natom,3,natom,nrpt) 3628 real(dp),intent(out) :: dddq(2,3,natom,3,natom,3) 3629 3630 !Local variables ------------------------- 3631 !scalars 3632 integer :: ia,ib,irpt,mu,nu,ii 3633 real(dp) :: im,kr,re 3634 !arrays 3635 real(dp) :: kk(3),fact(2,3) 3636 3637 ! ********************************************************************* 3638 3639 dddq = zero 3640 3641 do irpt=1,nrpt 3642 ! Calculation of the k coordinates in Normalized Reciprocal coordinates 3643 kk(1) = qpt(1)*gprim(1,1)+ qpt(2)*gprim(1,2) + qpt(3)*gprim(1,3) 3644 kk(2) = qpt(1)*gprim(2,1)+ qpt(2)*gprim(2,2) + qpt(3)*gprim(2,3) 3645 kk(3) = qpt(1)*gprim(3,1)+ qpt(2)*gprim(3,2) + qpt(3)*gprim(3,3) 3646 3647 ! Product of k and r 3648 kr=kk(1)*rpt(1,irpt)+kk(2)*rpt(2,irpt)+kk(3)*rpt(3,irpt) 3649 3650 ! Get phase factor 3651 re=cos(two_pi*kr); im=sin(two_pi*kr) 3652 3653 ! Inner loop on atoms and directions 3654 do ib=1,natom 3655 do ia=1,natom 3656 if (abs(wghatm(ia,ib,irpt))>1.0d-10) then 3657 ! take into account rotation due to i. 3658 fact(1,:) = -im * wghatm(ia,ib,irpt) * rpt(:,irpt) 3659 fact(2,:) = re * wghatm(ia,ib,irpt) * rpt(:,irpt) 3660 do nu=1,3 3661 do mu=1,3 3662 ! Real and imaginary part of the dynamical matrices 3663 ! Atmfrc should be real 3664 do ii=1,3 3665 dddq(1,mu,ia,nu,ib,ii) = dddq(1,mu,ia,nu,ib,ii) + fact(1,ii) * atmfrc(mu,ia,nu,ib,irpt) 3666 dddq(2,mu,ia,nu,ib,ii) = dddq(2,mu,ia,nu,ib,ii) + fact(2,ii) * atmfrc(mu,ia,nu,ib,irpt) 3667 end do 3668 end do 3669 end do 3670 end if 3671 end do 3672 end do 3673 end do 3674 3675 end subroutine dynmat_dq
m_dynmat/ftgam [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
ftgam
FUNCTION
If qtor=1 (q->r): Generates the Fourier transform of the recip space gkk matrices to obtain the real space ones. If qtor=0 (r->q): Generates the Fourier transform of the real space gkk matrices to obtain the reciprocal space ones.
INPUTS
natom= Number of atoms in the unit cell nqpt= Number of q points in the Brillouin zone if qtor=0 this number is read in the input file nrpt= Number of R points in the Big Box qtor= ( q to r : see above ) rpt(3,nprt)= Canonical coordinates of the R points in the unit cell These coordinates are normalized (=> * acell(3)!!) qpt_full(3,nqpt)= Reduced coordinates of the q vectors in reciprocal space if qtor=0 these vectors are read in the input file wghatm(natom,natom,nrpt)= Weights associated to a pair of atoms and to a R vector
OUTPUT
(see side effects)
SIDE EFFECTS
Input/output gam_qpt(2,3*natom*3*natom,nqpt) = gamma matrices in recip space coming from the Derivative Data Base gam_rpt(2,3*natom*3*natom,nrpt) = gamma matrices in real space stored in file unit_gkk_rpt
PARENTS
elphon,get_tau_k,integrate_gamma_alt,m_phgamma,mka2f,mka2f_tr mka2f_tr_lova,mkph_linwid
CHILDREN
NOTES
copied from ftiaf9.f recip to real space: real space is forced to disk file unit_gkk_rpt recip space depends on gkqwrite and unitgkq3 real to recip space: real space is forced to disk file unit_gkk_rpt recip space is necessarily in memory in gkk_qpt real space elements are complex, but could be reduced, as (-r) = (+r)*
SOURCE
5880 subroutine ftgam (wghatm,gam_qpt,gam_rpt,natom,nqpt,nrpt,qtor,coskr, sinkr) 5881 5882 5883 !This section has been created automatically by the script Abilint (TD). 5884 !Do not modify the following lines by hand. 5885 #undef ABI_FUNC 5886 #define ABI_FUNC 'ftgam' 5887 !End of the abilint section 5888 5889 implicit none 5890 5891 !Arguments ------------------------------- 5892 !scalars 5893 integer,intent(in) :: natom,nqpt,nrpt,qtor 5894 !arrays 5895 real(dp),intent(in) :: wghatm(natom,natom,nrpt) 5896 real(dp),intent(inout) :: gam_qpt(2,3*natom*3*natom,nqpt) 5897 real(dp),intent(inout) :: gam_rpt(2,3*natom*3*natom,nrpt) 5898 real(dp),intent(in) :: coskr(nqpt,nrpt) 5899 real(dp),intent(in) :: sinkr(nqpt,nrpt) 5900 5901 !Local variables ------------------------- 5902 !scalars 5903 integer :: iatom,idir,ip,iqpt,irpt,jatom,jdir 5904 real(dp) :: im,re 5905 character(len=500) :: message 5906 5907 ! ********************************************************************* 5908 5909 select case (qtor) 5910 ! 5911 case (1) !Recip to real space 5912 gam_rpt(:,:,:) = zero 5913 do irpt=1,nrpt 5914 do iqpt=1,nqpt 5915 ! Get the phase factor with normalization! 5916 re=coskr(iqpt,irpt) 5917 im=sinkr(iqpt,irpt) 5918 do ip=1,3*natom*3*natom 5919 ! Real and imaginary part of the real-space gam matrices 5920 gam_rpt(1,ip,irpt) = gam_rpt(1,ip,irpt)& 5921 & +re*gam_qpt(1,ip,iqpt) & 5922 & +im*gam_qpt(2,ip,iqpt) 5923 gam_rpt(2,ip,irpt) = gam_rpt(2,ip,irpt)& 5924 & +re*gam_qpt(2,ip,iqpt) & 5925 & -im*gam_qpt(1,ip,iqpt) 5926 end do 5927 end do 5928 end do 5929 gam_rpt = gam_rpt/nqpt 5930 ! 5931 case (0) ! Recip space from real space 5932 5933 gam_qpt(:,:,:)=zero 5934 5935 do irpt=1,nrpt 5936 do iqpt=1,nqpt 5937 5938 do iatom=1,natom 5939 do jatom=1,natom 5940 re = coskr(iqpt,irpt)*wghatm(iatom,jatom,irpt) 5941 im = sinkr(iqpt,irpt)*wghatm(iatom,jatom,irpt) 5942 5943 do idir=1,3 5944 do jdir=1,3 5945 ! Get phase factor 5946 5947 ip= jdir + (jatom-1)*3 + (idir-1)*3*natom + (iatom-1)*9*natom 5948 ! Real and imaginary part of the interatomic forces 5949 gam_qpt(1,ip,iqpt)=& 5950 & gam_qpt(1,ip,iqpt)& 5951 & +re*gam_rpt(1,ip,irpt)& 5952 & -im*gam_rpt(2,ip,irpt) 5953 ! !DEBUG 5954 gam_qpt(2,ip,iqpt)=& 5955 & gam_qpt(2,ip,iqpt)& 5956 & +im*gam_rpt(1,ip,irpt)& 5957 & +re*gam_rpt(2,ip,irpt) 5958 ! !ENDDEBUG 5959 5960 end do ! end jdir 5961 end do ! end idir 5962 end do 5963 end do ! end iatom 5964 5965 end do ! end iqpt 5966 end do ! end irpt 5967 5968 case default ! There is no other space to Fourier transform from 5969 write(message,'(a,i0,a)' )' The only allowed values for qtor are 0 or 1, while qtor=',qtor,' has been required.' 5970 MSG_BUG(message) 5971 end select 5972 5973 end subroutine ftgam
m_dynmat/ftgam_init [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
ftgam_init
FUNCTION
Generates the sin and cos phases for the Fourier transform of the gkk matrices
INPUTS
gprim = reciprocal space vectors to get cartesian coord for qpt nqpt= Number of q points in the Brillouin zone nrpt= Number of R points in the Big Box rpt(3,nprt)= Canonical coordinates of the R points in the unit cell These coordinates are normalized (=> * acell(3)!!) qpt_full(3,nqpt)= Reduced coordinates of the q vectors in reciprocal space if qtor=0 these vectors are read in the input file
OUTPUT
coskr, sinkr = cosine and sine of phase factors for given r and q points
PARENTS
elphon,get_tau_k,integrate_gamma_alt,m_phgamma,mka2f,mka2f_tr mka2f_tr_lova,mkph_linwid
CHILDREN
SOURCE
6004 subroutine ftgam_init (gprim,nqpt,nrpt,qpt_full,rpt,coskr, sinkr) 6005 6006 6007 !This section has been created automatically by the script Abilint (TD). 6008 !Do not modify the following lines by hand. 6009 #undef ABI_FUNC 6010 #define ABI_FUNC 'ftgam_init' 6011 !End of the abilint section 6012 6013 implicit none 6014 6015 !Arguments ------------------------------- 6016 !scalars 6017 integer,intent(in) :: nqpt,nrpt 6018 !arrays 6019 real(dp),intent(in) :: gprim(3,3),rpt(3,nrpt),qpt_full(3,nqpt) 6020 real(dp),intent(out) :: coskr(nqpt,nrpt) 6021 real(dp),intent(out) :: sinkr(nqpt,nrpt) 6022 6023 !Local variables ------------------------- 6024 !scalars 6025 integer :: iqpt,irpt 6026 real(dp) :: kr 6027 !arrays 6028 real(dp) :: kk(3) 6029 6030 ! ********************************************************************* 6031 6032 ! Prepare the phase factors 6033 do iqpt=1,nqpt 6034 ! Calculation of the k coordinates in Normalized Reciprocal coordinates 6035 kk(1)= qpt_full(1,iqpt)*gprim(1,1)+& 6036 & qpt_full(2,iqpt)*gprim(1,2)+& 6037 & qpt_full(3,iqpt)*gprim(1,3) 6038 6039 kk(2)= qpt_full(1,iqpt)*gprim(2,1)+& 6040 & qpt_full(2,iqpt)*gprim(2,2)+& 6041 & qpt_full(3,iqpt)*gprim(2,3) 6042 6043 kk(3)= qpt_full(1,iqpt)*gprim(3,1)+& 6044 & qpt_full(2,iqpt)*gprim(3,2)+& 6045 & qpt_full(3,iqpt)*gprim(3,3) 6046 do irpt=1,nrpt 6047 ! Product of k and r 6048 kr = kk(1)*rpt(1,irpt)+ kk(2)*rpt(2,irpt)+ kk(3)*rpt(3,irpt) 6049 coskr(iqpt,irpt)=cos(two_pi*kr) 6050 sinkr(iqpt,irpt)=sin(two_pi*kr) 6051 end do 6052 end do 6053 6054 end subroutine ftgam_init
m_dynmat/ftifc_q2r [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
ftifc_q2r
FUNCTION
Generates the Fourier transform of the dynamical matrices to obtain interatomic forces (real space).
INPUTS
dynmat(2,3,natom,3,natom,nqpt)= Dynamical matrices coming from the Derivative Data Base gprim(3,3)= Normalized coordinates in reciprocal space natom= Number of atoms in the unit cell nqpt= Number of q points in the Brillouin zone nrpt= Number of R points in the Big Box rpt(3,nprt)= Canonical coordinates of the R points in the unit cell These coordinates are normalized (=> * acell(3)!!) spqpt(3,nqpt)= Reduced coordinates of the q vectors in reciprocal space
OUTPUT
atmfrc(3,natom,3,natom,nrpt)= Interatomic Forces in real space !! We used the imaginary part just for debugging !
PARENTS
m_ifc
CHILDREN
SOURCE
3392 subroutine ftifc_q2r(atmfrc,dynmat,gprim,natom,nqpt,nrpt,rpt,spqpt) 3393 3394 3395 !This section has been created automatically by the script Abilint (TD). 3396 !Do not modify the following lines by hand. 3397 #undef ABI_FUNC 3398 #define ABI_FUNC 'ftifc_q2r' 3399 !End of the abilint section 3400 3401 implicit none 3402 3403 !Arguments ------------------------------- 3404 !scalars 3405 integer,intent(in) :: natom,nqpt,nrpt 3406 !arrays 3407 real(dp),intent(in) :: gprim(3,3),rpt(3,nrpt),spqpt(3,nqpt) 3408 real(dp),intent(out) :: atmfrc(3,natom,3,natom,nrpt) 3409 real(dp),intent(in) :: dynmat(2,3,natom,3,natom,nqpt) 3410 3411 !Local variables ------------------------- 3412 !scalars 3413 integer :: ia,ib,iqpt,irpt,mu,nu 3414 real(dp) :: im,kr,re 3415 !arrays 3416 real(dp) :: kk(3) 3417 3418 ! ********************************************************************* 3419 3420 DBG_ENTER("COLL") 3421 3422 !Interatomic Forces from Dynamical Matrices 3423 atmfrc = zero 3424 do irpt=1,nrpt 3425 do iqpt=1,nqpt 3426 3427 ! Calculation of the k coordinates in Normalized Reciprocal coordinates 3428 kk(1)=spqpt(1,iqpt)*gprim(1,1)+spqpt(2,iqpt)*gprim(1,2)+spqpt(3,iqpt)*gprim(1,3) 3429 kk(2)=spqpt(1,iqpt)*gprim(2,1)+spqpt(2,iqpt)*gprim(2,2)+spqpt(3,iqpt)*gprim(2,3) 3430 kk(3)=spqpt(1,iqpt)*gprim(3,1)+spqpt(2,iqpt)*gprim(3,2)+spqpt(3,iqpt)*gprim(3,3) 3431 3432 ! Product of k and r 3433 kr=kk(1)*rpt(1,irpt)+kk(2)*rpt(2,irpt)+kk(3)*rpt(3,irpt) 3434 3435 ! Get the phase factor 3436 re=cos(two_pi*kr) 3437 im=sin(two_pi*kr) 3438 3439 ! Now, big inner loops on atoms and directions 3440 3441 ! The indices are ordered to give better speed 3442 do ib=1,natom 3443 do nu=1,3 3444 do ia=1,natom 3445 do mu=1,3 3446 ! Real and imaginary part of the interatomic forces 3447 atmfrc(mu,ia,nu,ib,irpt)=atmfrc(mu,ia,nu,ib,irpt)& 3448 & +re*dynmat(1,mu,ia,nu,ib,iqpt)& 3449 & +im*dynmat(2,mu,ia,nu,ib,iqpt) 3450 ! The imaginary part should be equal to zero !!!!!! 3451 ! atmfrc(2,mu,ia,nu,ib,irpt)=atmfrc(2,mu,ia,nu,ib,irpt) 3452 ! & +re*dynmat(2,mu,ia,nu,ib,iqpt) 3453 ! & -im*dynmat(1,mu,ia,nu,ib,iqpt) 3454 end do 3455 end do 3456 end do 3457 end do 3458 3459 end do 3460 end do 3461 3462 !The sumifc has to be weighted by a normalization factor of 1/nqpt 3463 atmfrc = atmfrc/nqpt 3464 3465 DBG_EXIT("COLL") 3466 3467 end subroutine ftifc_q2r
m_dynmat/ftifc_r2q [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
ftifc_r2q
FUNCTION
(r->q): Generates the Fourier transform of the interatomic forces to obtain dynamical matrices (reciprocal space).
INPUTS
atmfrc(3,natom,3,natom,nrpt)= Interatomic Forces in real space gprim(3,3)= Normalized coordinates in reciprocal space natom= Number of atoms in the unit cell nqpt= Number of q points in the Brillouin zone nrpt= Number of R points in the Big Box rpt(3,nprt)= Canonical coordinates of the R points in the unit cell These coordinates are normalized (=> * acell(3)!!) spqpt(3,nqpt)= Reduced coordinates of the q vectors in reciprocal space wghatm(natom,natom,nrpt)= Weights associated to a pair of atoms and to a R vector
OUTPUT
dynmat(2,3,natom,3,natom,nqpt)= Dynamical matrices coming from the Derivative Data Base
PARENTS
m_dynmat
CHILDREN
SOURCE
3503 subroutine ftifc_r2q(atmfrc,dynmat,gprim,natom,nqpt,nrpt,rpt,spqpt,wghatm) 3504 3505 3506 !This section has been created automatically by the script Abilint (TD). 3507 !Do not modify the following lines by hand. 3508 #undef ABI_FUNC 3509 #define ABI_FUNC 'ftifc_r2q' 3510 !End of the abilint section 3511 3512 implicit none 3513 3514 !Arguments ------------------------------- 3515 !scalars 3516 integer,intent(in) :: natom,nqpt,nrpt 3517 !arrays 3518 real(dp),intent(in) :: gprim(3,3),rpt(3,nrpt),spqpt(3,nqpt) 3519 real(dp),intent(in) :: wghatm(natom,natom,nrpt) 3520 real(dp),intent(in) :: atmfrc(3,natom,3,natom,nrpt) 3521 real(dp),intent(out) :: dynmat(2,3,natom,3,natom,nqpt) 3522 3523 !Local variables ------------------------- 3524 !scalars 3525 integer :: ia,ib,iqpt,irpt,mu,nu 3526 real(dp) :: facti,factr,im,kr,re 3527 !arrays 3528 real(dp) :: kk(3) 3529 3530 ! ********************************************************************* 3531 3532 dynmat = zero 3533 3534 do iqpt=1,nqpt 3535 do irpt=1,nrpt 3536 3537 ! Calculation of the k coordinates in Normalized Reciprocal coordinates 3538 kk(1)=spqpt(1,iqpt)*gprim(1,1)+spqpt(2,iqpt)* gprim(1,2)+spqpt(3,iqpt)*gprim(1,3) 3539 kk(2)=spqpt(1,iqpt)*gprim(2,1)+spqpt(2,iqpt)* gprim(2,2)+spqpt(3,iqpt)*gprim(2,3) 3540 kk(3)=spqpt(1,iqpt)*gprim(3,1)+spqpt(2,iqpt)* gprim(3,2)+spqpt(3,iqpt)*gprim(3,3) 3541 3542 ! Product of k and r 3543 kr=kk(1)*rpt(1,irpt)+kk(2)*rpt(2,irpt)+kk(3)*rpt(3,irpt) 3544 3545 ! Get phase factor 3546 re=cos(two_pi*kr) 3547 im=sin(two_pi*kr) 3548 3549 ! Inner loop on atoms and directions 3550 do ib=1,natom 3551 do ia=1,natom 3552 if(abs(wghatm(ia,ib,irpt))>1.0d-10)then 3553 factr=re*wghatm(ia,ib,irpt) 3554 facti=im*wghatm(ia,ib,irpt) 3555 do nu=1,3 3556 do mu=1,3 3557 ! Real and imaginary part of the dynamical matrices 3558 dynmat(1,mu,ia,nu,ib,iqpt)=dynmat(1,mu,ia,nu,ib,iqpt)& 3559 & +factr*atmfrc(mu,ia,nu,ib,irpt) 3560 ! Atmfrc should be real 3561 ! & -im*wghatm(ia,ib,irpt)*atmfrc(2,mu,ia,nu,ib,irpt) 3562 dynmat(2,mu,ia,nu,ib,iqpt)=dynmat(2,mu,ia,nu,ib,iqpt)& 3563 & +facti*atmfrc(mu,ia,nu,ib,irpt) 3564 ! Atmfrc should be real 3565 ! & +re*wghatm(ia,ib,irpt)*atmfrc(2,mu,ia,nu,ib,irpt) 3566 end do 3567 end do 3568 end if 3569 end do 3570 end do 3571 end do 3572 end do 3573 3574 end subroutine ftifc_r2q
m_dynmat/gtdyn9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
gtdyn9
FUNCTION
Generates a dynamical matrix from interatomic force constants and long-range electrostatic interactions.
INPUTS
acell(3)=length scales by which rprim is to be multiplied atmfrc(3,natom,3,natom,nrpt) = Interatomic Forces in real space (imaginary part only for debugging) dielt(3,3) = dielectric tensor dipdip= if 0, no dipole-dipole interaction was subtracted in atmfrc if 1, atmfrc has been build without dipole-dipole part dyewq0(3,3,natom)= Ewald part of the dynamical matrix, at q=0. gmet(3,3)= metric tensor in reciprocal space. gprim(3,3)= Normalized coordinates in reciprocal space mpert =maximum number of ipert natom= Number of atoms in the unit cell nrpt= Number of R points in the Big Box qphnrm= Normalisation coefficient for qpt qpt(3)= Reduced coordinates of the q vectors in reciprocal space rmet(3,3)= Metric tensor in real space. rprim(3,3)= dimensionless primitive translations in real space rpt(3,nprt)= Canonical coordinates of the R points in the unit cell These coordinates are normalized (=> * acell(3)!!) trans(3,natom)= Atomic translations : xred = rcan + trans ucvol= unit cell volume wghatm(natom,natom,nrpt)= Weights associated to a pair of atoms and to a R vector xred(3,natom)= relative coords of atoms in unit cell (dimensionless) zeff(3,3,natom)=effective charge on each atom, versus electric field and atomic displacement
OUTPUT
d2cart(2,3,mpert,3,mpert)=dynamical matrix obtained for the wavevector qpt (normalized using qphnrm)
PARENTS
anaddb,ddb_interpolate,m_effective_potential_file,m_ifc,m_phonons
CHILDREN
SOURCE
5349 subroutine gtdyn9(acell,atmfrc,dielt,dipdip,& 5350 & dyewq0,d2cart,gmet,gprim,mpert,natom,& 5351 & nrpt,qphnrm,qpt,rmet,rprim,rpt,& 5352 & trans,ucvol,wghatm,xred,zeff) 5353 5354 5355 !This section has been created automatically by the script Abilint (TD). 5356 !Do not modify the following lines by hand. 5357 #undef ABI_FUNC 5358 #define ABI_FUNC 'gtdyn9' 5359 !End of the abilint section 5360 5361 implicit none 5362 5363 !Arguments ------------------------------- 5364 !scalars 5365 integer,intent(in) :: dipdip,mpert,natom,nrpt 5366 real(dp),intent(in) :: qphnrm,ucvol 5367 !arrays 5368 real(dp),intent(in) :: acell(3),dielt(3,3),gmet(3,3),gprim(3,3),qpt(3) 5369 real(dp),intent(in) :: rmet(3,3),rprim(3,3),rpt(3,nrpt) 5370 real(dp),intent(in) :: trans(3,natom),wghatm(natom,natom,nrpt),xred(3,natom) 5371 real(dp),intent(in) :: zeff(3,3,natom) 5372 real(dp),intent(in) :: atmfrc(3,natom,3,natom,nrpt) 5373 real(dp),intent(in) :: dyewq0(3,3,natom) 5374 real(dp),intent(out) :: d2cart(2,3,mpert,3,mpert) 5375 5376 !Local variables ------------------------- 5377 !scalars 5378 integer,parameter :: nqpt1=1,option2=2,sumg0=0,plus1=1,iqpt1=1 5379 integer :: i1,i2,ib,nsize 5380 !arrays 5381 real(dp) :: qphon(3) 5382 real(dp),allocatable :: dq(:,:,:,:,:),dyew(:,:,:,:,:) 5383 5384 ! ********************************************************************* 5385 5386 ABI_ALLOCATE(dq,(2,3,natom,3,natom)) 5387 5388 !Get the normalized wavevector 5389 if(abs(qphnrm)<1.0d-7)then 5390 qphon(1:3)=zero 5391 else 5392 qphon(1:3)=qpt(1:3)/qphnrm 5393 end if 5394 5395 !Generate the analytical part from the interatomic forces 5396 call ftifc_r2q (atmfrc,dq,gprim,natom,nqpt1,nrpt,rpt,qphon,wghatm) 5397 5398 !The analytical dynamical matrix dq has been generated 5399 !in the normalized canonical coordinate system. Now, the 5400 !phase is modified, in order to recover the usual (xred) coordinate of atoms. 5401 call dymfz9(dq,natom,nqpt1,gprim,option2,qphon,trans) 5402 5403 if (dipdip==1) then 5404 ! Add the non-analytical part 5405 ! Compute dyew(2,3,natom,3,natom)= Ewald part of the dynamical matrix, 5406 ! second energy derivative wrt xred(3,natom) in Hartrees 5407 ! (Denoted A-bar in the notes) 5408 ABI_ALLOCATE(dyew,(2,3,natom,3,natom)) 5409 5410 call ewald9(acell,dielt,dyew,gmet,gprim,natom,qphon,rmet,rprim,sumg0,ucvol,xred,zeff) 5411 call q0dy3_apply(natom,dyewq0,dyew) 5412 call nanal9(dyew,dq,iqpt1,natom,nqpt1,plus1) 5413 5414 ABI_DEALLOCATE(dyew) 5415 end if 5416 5417 !Copy the dynamical matrix in the proper location 5418 5419 !First zero all the elements 5420 nsize=2*(3*mpert)**2 5421 d2cart = zero 5422 5423 !Copy the elements from dq to d2cart 5424 d2cart(:,:,1:natom,:,1:natom)=dq(:,:,1:natom,:,1:natom) 5425 5426 !In case we have the gamma point, 5427 if(qphon(1)**2+qphon(2)**2+qphon(3)**2<1.d-14)then 5428 ! Copy the effective charge and dielectric constant in the final array 5429 do i1=1,3 5430 do i2=1,3 5431 d2cart(1,i1,natom+2,i2,natom+2)=dielt(i1,i2) 5432 do ib=1,natom 5433 d2cart(1,i1,natom+2,i2,ib)=zeff(i1,i2,ib) 5434 d2cart(1,i2,ib,i1,natom+2)=zeff(i1,i2,ib) 5435 end do 5436 end do 5437 end do 5438 end if 5439 5440 ABI_DEALLOCATE(dq) 5441 5442 end subroutine gtdyn9
m_dynmat/ifclo9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
ifclo9
FUNCTION
Convert from cartesian coordinates to local coordinates the 3*3 interatomic force constant matrix
INPUTS
ifccar(3,3)= matrix of interatomic force constants in cartesian coordinates vect1(3)= cartesian coordinates of the first local vector vect2(3)= cartesian coordinates of the second local vector vect3(3)= cartesian coordinates of the third local vector
OUTPUT
ifcloc(3,3)= matrix of interatomic force constants in local coordinates
PARENTS
m_ifc
CHILDREN
SOURCE
3705 subroutine ifclo9(ifccar,ifcloc,vect1,vect2,vect3) 3706 3707 3708 !This section has been created automatically by the script Abilint (TD). 3709 !Do not modify the following lines by hand. 3710 #undef ABI_FUNC 3711 #define ABI_FUNC 'ifclo9' 3712 !End of the abilint section 3713 3714 implicit none 3715 3716 !Arguments ------------------------------- 3717 !arrays 3718 real(dp),intent(in) :: ifccar(3,3),vect1(3),vect2(3),vect3(3) 3719 real(dp),intent(out) :: ifcloc(3,3) 3720 3721 !Local variables ------------------------- 3722 !scalars 3723 integer :: ii,jj 3724 !arrays 3725 real(dp) :: work(3,3) 3726 3727 ! ********************************************************************* 3728 3729 do jj=1,3 3730 do ii=1,3 3731 work(jj,ii)=zero 3732 end do 3733 do ii=1,3 3734 work(jj,1)=work(jj,1)+ifccar(jj,ii)*vect1(ii) 3735 work(jj,2)=work(jj,2)+ifccar(jj,ii)*vect2(ii) 3736 work(jj,3)=work(jj,3)+ifccar(jj,ii)*vect3(ii) 3737 end do 3738 end do 3739 3740 do jj=1,3 3741 do ii=1,3 3742 ifcloc(ii,jj)=zero 3743 end do 3744 do ii=1,3 3745 ifcloc(1,jj)=ifcloc(1,jj)+vect1(ii)*work(ii,jj) 3746 ifcloc(2,jj)=ifcloc(2,jj)+vect2(ii)*work(ii,jj) 3747 ifcloc(3,jj)=ifcloc(3,jj)+vect3(ii)*work(ii,jj) 3748 end do 3749 end do 3750 3751 end subroutine ifclo9
m_dynmat/make_bigbox [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
make_bigbox
FUNCTION
Helper functions that faciliates the generation of a Big Box containing all the R points in the cartesian real space needed to Fourier Transform the dynamical matrix into its corresponding interatomic force. See bigbx9 for the algorithm.
INPUTS
brav= Bravais Lattice (1 or -1=S.C.;2=F.C.C.;3=BCC;4=Hex.) ngqpt(3)= Numbers used to generate the q points to sample the Brillouin zone using an homogeneous grid nqshft= number of q-points in the repeated cell for the Brillouin zone sampling When nqshft is not 1, but 2 or 4 (only other allowed values), the limits for the big box have to be extended by a factor of 2. rprim(3,3)= Normalized coordinates in real space !!! IS THIS CORRECT?
OUTPUT
cell= (nrpt,3) Give the index of the the cell and irpt nprt= Number of R points in the Big Box rpt(3,nrpt)= Canonical coordinates of the R points in the unit cell These coordinates are normalized (=> * acell(3)!!) The array is allocated here with the proper dimension. Client code is responsible for the deallocation.
PARENTS
m_ifc
CHILDREN
SOURCE
2579 subroutine make_bigbox(brav,cell,ngqpt,nqshft,rprim,nrpt,rpt) 2580 2581 2582 !This section has been created automatically by the script Abilint (TD). 2583 !Do not modify the following lines by hand. 2584 #undef ABI_FUNC 2585 #define ABI_FUNC 'make_bigbox' 2586 !End of the abilint section 2587 2588 implicit none 2589 2590 !Arguments ------------------------------- 2591 !scalars 2592 integer,intent(in) :: brav,nqshft 2593 integer,intent(out) :: nrpt 2594 !arrays 2595 integer,intent(in) :: ngqpt(3) 2596 real(dp),intent(in) :: rprim(3,3) 2597 real(dp),allocatable,intent(out) :: rpt(:,:) 2598 integer,allocatable,intent(out) :: cell(:,:) 2599 2600 !Local variables ------------------------- 2601 !scalars 2602 integer :: choice,mrpt 2603 !arrays 2604 real(dp) :: dummy_rpt(3,1) 2605 integer:: dummy_cell(1,3) 2606 2607 ! ********************************************************************* 2608 2609 ! Compute the number of points (cells) in real space 2610 choice=0 2611 call bigbx9(brav,dummy_cell,choice,1,ngqpt,nqshft,mrpt,rprim,dummy_rpt) 2612 2613 ! Now we can allocate and calculate the points and the weights. 2614 nrpt = mrpt 2615 ABI_ALLOCATE(rpt,(3,nrpt)) 2616 ABI_ALLOCATE(cell,(3,nrpt)) 2617 2618 choice=1 2619 call bigbx9(brav,cell,choice,mrpt,ngqpt,nqshft,nrpt,rprim,rpt) 2620 2621 end subroutine make_bigbox
m_dynmat/massmult_and_breaksym [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
mult_masses_and_break_symms
FUNCTION
Multiply the IFC(q) by the atomic masses, slightly break symmetry to make tests more portable and make the matrix hermitian before returning.
INPUTS
amu(ntypat)=mass of the atoms (atomic mass unit) matrix (diagonal in the atoms) natom=number of atoms in unit cell ntypat=number of atom types typat(natom)=integer label of each type of atom (1,2,...)
SIDE EFFECTS
mat(2*3*natom*3*natom)=Multiplies by atomic masses in output.
PARENTS
CHILDREN
SOURCE
5765 subroutine massmult_and_breaksym(natom, ntypat, typat, amu, mat) 5766 5767 5768 !This section has been created automatically by the script Abilint (TD). 5769 !Do not modify the following lines by hand. 5770 #undef ABI_FUNC 5771 #define ABI_FUNC 'massmult_and_breaksym' 5772 !End of the abilint section 5773 5774 implicit none 5775 5776 !Arguments ------------------------------- 5777 !scalars 5778 integer,intent(in) :: natom,ntypat 5779 !arrays 5780 integer,intent(in) :: typat(natom) 5781 real(dp),intent(in) :: amu(ntypat) 5782 real(dp),intent(inout) :: mat(2*3*natom*3*natom) 5783 5784 !Local variables ------------------------- 5785 !scalars 5786 integer :: i1,i2,idir1,idir2,index,ipert1,ipert2 5787 real(dp),parameter :: break_symm=1.0d-12 5788 !real(dp),parameter :: break_symm=zero 5789 real(dp) :: fac 5790 !arrays 5791 real(dp) :: nearidentity(3,3) 5792 5793 ! ********************************************************************* 5794 5795 !This slight breaking of the symmetry allows the 5796 !results to be more portable between machines 5797 nearidentity(:,:)=one 5798 nearidentity(1,1)=one+break_symm 5799 nearidentity(3,3)=one-break_symm 5800 5801 !Include the masses in the dynamical matrix 5802 do ipert1=1,natom 5803 do ipert2=1,natom 5804 fac=1.0_dp/sqrt(amu(typat(ipert1))*amu(typat(ipert2)))/amu_emass 5805 do idir1=1,3 5806 do idir2=1,3 5807 i1=idir1+(ipert1-1)*3 5808 i2=idir2+(ipert2-1)*3 5809 index=i1+3*natom*(i2-1) 5810 mat(2*index-1)=mat(2*index-1)*fac*nearidentity(idir1,idir2) 5811 mat(2*index )=mat(2*index )*fac*nearidentity(idir1,idir2) 5812 ! This is to break slightly the translation invariance, and make 5813 ! the automatic tests more portable 5814 if(ipert1==ipert2 .and. idir1==idir2)then 5815 mat(2*index-1)=mat(2*index-1)+break_symm*natom/amu_emass/idir1*0.01_dp 5816 end if 5817 end do 5818 end do 5819 end do 5820 end do 5821 5822 ! Make the dynamical matrix hermitian 5823 call mkherm(mat,3*natom) 5824 5825 end subroutine massmult_and_breaksym
m_dynmat/nanal9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
nanal9
FUNCTION
If plus=0 then substracts the non-analytical part from one dynamical matrices, with number iqpt. If plus=1 then adds the non-analytical part to the dynamical matrices, with number iqpt.
INPUTS
dyew(2,3,natom,3,natom)= Non-analytical part natom= Number of atoms in the unit cell iqpt= Referenced q point for the dynamical matrix nqpt= Number of q points plus= (see above)
OUTPUT
dynmat(2,3,natom,3,natom,nqpt)= Dynamical matrices coming from the Derivative Data Base
PARENTS
m_dynmat,m_ifc
CHILDREN
SOURCE
5240 subroutine nanal9(dyew,dynmat,iqpt,natom,nqpt,plus) 5241 5242 5243 !This section has been created automatically by the script Abilint (TD). 5244 !Do not modify the following lines by hand. 5245 #undef ABI_FUNC 5246 #define ABI_FUNC 'nanal9' 5247 !End of the abilint section 5248 5249 implicit none 5250 5251 !Arguments ------------------------------- 5252 !scalars 5253 integer,intent(in) :: iqpt,natom,nqpt,plus 5254 !arrays 5255 real(dp),intent(in) :: dyew(2,3,natom,3,natom) 5256 real(dp),intent(inout) :: dynmat(2,3,natom,3,natom,nqpt) 5257 5258 !Local variables ------------------------- 5259 !scalars 5260 integer :: ia,ib,mu,nu 5261 character(len=500) :: message 5262 5263 ! ********************************************************************* 5264 5265 if (plus==0) then 5266 5267 do ia=1,natom 5268 do ib=1,natom 5269 do mu=1,3 5270 do nu=1,3 5271 ! The following four lines are OK 5272 dynmat(1,mu,ia,nu,ib,iqpt)=dynmat(1,mu,ia,nu,ib,iqpt) - dyew(1,mu,ia,nu,ib) 5273 dynmat(2,mu,ia,nu,ib,iqpt)=dynmat(2,mu,ia,nu,ib,iqpt) - dyew(2,mu,ia,nu,ib) 5274 end do 5275 end do 5276 end do 5277 end do 5278 5279 else if (plus==1) then 5280 ! write(std_out,*)' nanal9 : now, only the analytic part ' 5281 ! write(std_out,*)' nanal9 : now, only the ewald part ' 5282 do ia=1,natom 5283 do ib=1,natom 5284 do mu=1,3 5285 do nu=1,3 5286 dynmat(1,mu,ia,nu,ib,iqpt)=dynmat(1,mu,ia,nu,ib,iqpt) + dyew(1,mu,ia,nu,ib) 5287 dynmat(2,mu,ia,nu,ib,iqpt)=dynmat(2,mu,ia,nu,ib,iqpt) + dyew(2,mu,ia,nu,ib) 5288 end do 5289 end do 5290 end do 5291 end do 5292 5293 else 5294 write(message,'(a,a,a,i0,a)' )& 5295 & 'The argument "plus" must be equal to 0 or 1.',ch10,& 5296 & 'The value ',plus,' is not available.' 5297 MSG_BUG(message) 5298 end if 5299 5300 end subroutine nanal9
m_dynmat/q0dy3_apply [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
q0dy3_apply
FUNCTION
Takes care of the inclusion of the ewald q=0 term in the dynamical matrix - corrects the dyew matrix provided as input
INPUTS
dyewq0(3,3,natom) = part needed to correct the dynamical matrix for atom self-interaction. natom= number of atom in the unit cell
OUTPUT
SIDE EFFECTS
dyew(2,3,natom,3,natom)= dynamical matrix corrected on output
NOTES
Should be used just after each call to dfpt_ewald, for both q==0 and the real wavelength. The q0dy3_apply should be used in conjunction with the subroutine dfpt_ewald (or ewald9): First, the call of dfpt_ewald with q==0 should be done, then the call to q0dy3_calc will produce the dyewq0 matrix from the (q=0) dyew matrix Second, the call of dfpt_ewald with the real q (either =0 or diff 0) should be done, then the call to q0dy3_apply will produce the correct dynamical matrix dyew starting from the previously calculated dyewq0 and the bare(non-corrected) dyew matrix
PARENTS
m_dynmat,m_ifc,respfn
CHILDREN
SOURCE
2000 subroutine q0dy3_apply(natom,dyewq0,dyew) 2001 2002 2003 !This section has been created automatically by the script Abilint (TD). 2004 !Do not modify the following lines by hand. 2005 #undef ABI_FUNC 2006 #define ABI_FUNC 'q0dy3_apply' 2007 !End of the abilint section 2008 2009 implicit none 2010 2011 !Arguments ------------------------------- 2012 !scalars 2013 integer,intent(in) :: natom 2014 !arrays 2015 real(dp),intent(in) :: dyewq0(3,3,natom) 2016 real(dp),intent(inout) :: dyew(2,3,natom,3,natom) 2017 2018 !Local variables ------------------------- 2019 !scalars 2020 integer :: ia,mu,nu 2021 2022 ! ********************************************************************* 2023 2024 do mu=1,3 2025 do nu=1,3 2026 do ia=1,natom 2027 dyew(1,mu,ia,nu,ia)=dyew(1,mu,ia,nu,ia)-dyewq0(mu,nu,ia) 2028 end do 2029 end do 2030 end do 2031 2032 end subroutine q0dy3_apply
m_dynmat/q0dy3_calc [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
q0dy3_calc
FUNCTION
Calculate the q=0 correction term to the dynamical matrix
INPUTS
dyew(2,3,natom,3,natom)= dynamical matrix input, non-corrected, for q=0 if option=1 or 2 natom= number of atom in the unit cell option= either 1 or 2: 1: use dyew to calculate dyewq0 symmetrical form 2: use dyew to calculate dyewq0 symmetrical form
OUTPUT
dyewq0(3,3,natom) = part needed to correct the dynamical matrix for atom self-interaction.
NOTES
Should be used just after each call to dfpt_ewald, for both q==0 and the real wavelength. If option=1 or 2, q0dy3_calc uses an Ewald dynamical matrix at q=0, called dyew, to produce a contracted form called dyewq0 : either: in an unsymmetrical form (if option=1), or in a symmetrical form (if option=2). The q0dy3_calc should be used in conjunction with the subroutine dfpt_ewald (or ewald9). First, the call of dfpt_ewald with q==0 should be done , then the call to q0dy3_calc will produce the dyewq0 matrix from the (q=0) dyew matrix Second, the call of dfpt_ewald with the real q (either =0 or diff 0) should be done, then the call to q0dy3_apply will produce the correct dynamical matrix dyew starting from the previously calculated dyewq0 and the bare(non-corrected) dyew matrix
PARENTS
ddb_hybrid,m_ifc,respfn
CHILDREN
SOURCE
2084 subroutine q0dy3_calc(natom,dyewq0,dyew,option) 2085 2086 2087 !This section has been created automatically by the script Abilint (TD). 2088 !Do not modify the following lines by hand. 2089 #undef ABI_FUNC 2090 #define ABI_FUNC 'q0dy3_calc' 2091 !End of the abilint section 2092 2093 implicit none 2094 2095 !Arguments ------------------------------- 2096 !scalars 2097 integer,intent(in) :: natom,option 2098 !arrays 2099 real(dp),intent(in) :: dyew(2,3,natom,3,natom) 2100 real(dp),intent(out) :: dyewq0(3,3,natom) 2101 2102 !Local variables ------------------------- 2103 !scalars 2104 integer :: ia,ib,mu,nu 2105 character(len=500) :: message 2106 2107 ! ********************************************************************* 2108 2109 if(option==1.or.option==2)then 2110 do mu=1,3 2111 do nu=1,3 2112 do ia=1,natom 2113 dyewq0(mu,nu,ia)=zero 2114 do ib=1,natom 2115 dyewq0(mu,nu,ia)=dyewq0(mu,nu,ia)+dyew(1,mu,ia,nu,ib) 2116 end do 2117 end do 2118 end do 2119 end do 2120 else 2121 write (message, '(3a)')& 2122 & 'option should be 1 or 2.',ch10,& 2123 & 'action: correct calling routine' 2124 MSG_BUG(message) 2125 end if 2126 2127 if(option==2)then 2128 do ia=1,natom 2129 do mu=1,3 2130 do nu=mu,3 2131 dyewq0(mu,nu,ia)=(dyewq0(mu,nu,ia)+dyewq0(nu,mu,ia))/2 2132 dyewq0(nu,mu,ia)=dyewq0(mu,nu,ia) 2133 end do 2134 end do 2135 end do 2136 end if 2137 2138 end subroutine q0dy3_calc
m_dynmat/symdm9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
symdm9
FUNCTION
Use the set of special k points calculated by the Monkhorst & Pack Technique. Check if all the informations for the k points are present in the DDB to determine their dynamical matrices. Generate the dynamical matrices of the set of k points which samples homogeneously the entire Brillouin zone.
INPUTS
blkflg(nsize,nblok)= flag of existence for each element of the DDB blknrm(1,nblok)=norm of qpt providing normalization blkqpt(1<ii<9,nblok)=q vector of a phonon mode (ii=1,2,3) blktyp(nblok)=1 or 2 depending on non-stationary or stationary block 3 for third order derivatives blkval(2,3*mpert*3*mpert,nblok)= all the dynamical matrices gprim(3,3)=dimensionless primitive translations in reciprocal space indsym = mapping of atoms under symops mpert =maximum number of ipert natom=number of atoms in unit cell nblok=number of blocks in the DDB nqpt=number of special q points nsym=number of space group symmetries rfmeth = 1 if non-stationary block 2 if stationary block 3 if third order derivatives rprim(3,3)=dimensionless primitive translations in real space spqpt(3,nqpt)=set of special q points generated by the Monkhorst & Pack Method symrec(3,3,nsym)=3x3 matrices of the group symmetries (reciprocal space) symrel(3,3,nsym)=3x3 matrices of the group symmetries (real space)
OUTPUT
dynmat(2,3,natom,3,natom,nqpt)=dynamical matrices relative to the q points of the B.Z. sampling [qmissing]=Allocatable array with the indices of the q-points in the BZ that could not be obtained by symmetry. If qmissing is present, the routine does not stop if the full BZ cannot be reconstructed. The caller is responsible for filling the missing entries.
TODO
* A full description of the inputs should be included
NOTES
Time-reversal symmetry is always assumed
PARENTS
m_ifc
CHILDREN
SOURCE
4729 subroutine symdm9(blkflg,blknrm,blkqpt,blktyp,blkval,& 4730 & dynmat,gprim,indsym,mpert,natom,nblok,nqpt,nsym,rfmeth,& 4731 & rprim,spqpt,symrec,symrel,qmissing) 4732 4733 4734 !This section has been created automatically by the script Abilint (TD). 4735 !Do not modify the following lines by hand. 4736 #undef ABI_FUNC 4737 #define ABI_FUNC 'symdm9' 4738 use interfaces_14_hidewrite 4739 !End of the abilint section 4740 4741 implicit none 4742 4743 !Arguments ------------------------------- 4744 !scalars 4745 integer,intent(in) :: mpert,natom,nblok,nqpt,nsym,rfmeth 4746 !arrays 4747 integer,intent(in) :: blkflg(3,mpert,3,mpert,nblok),blktyp(nblok) 4748 integer,intent(in) :: indsym(4,nsym,natom),symrec(3,3,nsym),symrel(3,3,nsym) 4749 integer,allocatable,optional,intent(out) :: qmissing(:) 4750 real(dp),intent(in) :: blknrm(3,nblok),blkqpt(9,nblok) 4751 real(dp),intent(in) :: blkval(2,3*mpert*3*mpert,nblok),gprim(3,3),rprim(3,3) 4752 real(dp),intent(in) :: spqpt(3,nqpt) 4753 real(dp),intent(out) :: dynmat(2,3,natom,3,natom,nqpt) 4754 4755 !Local variables ------------------------- 4756 !tol sets tolerance for equality of q points between those of 4757 !the DDB and those of the sampling grid 4758 !scalars 4759 integer :: ia,ib,iblok,idir1,idir2,ii,ipert1,ipert2,iqpt,isym,jj,kk,ll 4760 integer :: mu,nu,q1,q2,nqmiss 4761 real(dp),parameter :: tol=2.d-8 4762 real(dp) :: arg1,arg2,im,re,sumi,sumr 4763 logical :: allow_qmiss 4764 character(len=500) :: message 4765 !arrays 4766 integer,allocatable :: qtest(:,:) 4767 integer :: qmiss_(nqpt) 4768 real(dp) :: qq(3),qsym(6),ss(3,3) 4769 real(dp),allocatable :: ddd(:,:,:,:,:) 4770 4771 ! ********************************************************************* 4772 ! Initialize output (some q-points might not be reconstructed if qmissing is present) 4773 dynmat = huge(one) 4774 allow_qmiss = (present(qmissing)) 4775 4776 ABI_ALLOCATE(ddd,(2,3,natom,3,natom)) 4777 !Check if the blkqpt points and their symmetrics are sufficient 4778 !in the DDB to retrieve all the q points of the B.Z. sampling 4779 4780 !Initialization of a test variable 4781 ! qtest(iqpt,1)=iblok 4782 ! qtest(iqpt,2)=isym 4783 ! qtest(iqpt,3)=time_reversal 4784 ABI_ALLOCATE(qtest,(nqpt,3)) 4785 do iqpt=1,nqpt 4786 qtest(iqpt,1)=0 4787 end do 4788 4789 !Q points coming from the DDB 4790 !write(std_out,*)' Nbr. of Blocks -> ',nblok 4791 4792 do iblok=1,nblok 4793 4794 if (blktyp(iblok)==rfmeth) then 4795 qq(1)=blkqpt(1,iblok)/blknrm(1,iblok) 4796 qq(2)=blkqpt(2,iblok)/blknrm(1,iblok) 4797 qq(3)=blkqpt(3,iblok)/blknrm(1,iblok) 4798 4799 ! Calculation of the symmetric points (including Time Reversal) 4800 do isym=1,nsym 4801 qsym(1)=qq(1)*symrec(1,1,isym)+qq(2)*symrec(1,2,isym)+qq(3)*symrec(1,3,isym) 4802 qsym(2)=qq(1)*symrec(2,1,isym)+qq(2)*symrec(2,2,isym)+qq(3)*symrec(2,3,isym) 4803 qsym(3)=qq(1)*symrec(3,1,isym)+qq(2)*symrec(3,2,isym)+qq(3)*symrec(3,3,isym) 4804 4805 ! Dont forget the Time Reversal symmetry 4806 qsym(4)=-qq(1)*symrec(1,1,isym)-qq(2)*symrec(1,2,isym)-qq(3)*symrec(1,3,isym) 4807 qsym(5)=-qq(1)*symrec(2,1,isym)-qq(2)*symrec(2,2,isym)-qq(3)*symrec(2,3,isym) 4808 qsym(6)=-qq(1)*symrec(3,1,isym)-qq(2)*symrec(3,2,isym)-qq(3)*symrec(3,3,isym) 4809 4810 ! Comparison between the q points and their symmetric points 4811 ! and the set of q points which samples the entire Brillouin zone 4812 do iqpt=1,nqpt 4813 4814 if (mod(abs(spqpt(1,iqpt)-qsym(1))+tol,1._dp)<2*tol)then 4815 if (mod(abs(spqpt(2,iqpt)-qsym(2))+tol,1._dp)<2*tol)then 4816 if (mod(abs(spqpt(3,iqpt)-qsym(3))+tol,1._dp)<2*tol)then 4817 4818 ! write(std_out,*)' q point from the DDB ! ' 4819 ! write(std_out,*)' block -> ',iblok 4820 ! write(std_out,*)' sym. -> ',isym 4821 ! write(std_out,*)' No Time Reversal ' 4822 ! write(std_out,*)'(',qsym(1),',',qsym(2),',',qsym(3),')' 4823 ! write(std_out,*)' ' 4824 4825 qtest(iqpt,1)=iblok 4826 qtest(iqpt,2)=isym 4827 qtest(iqpt,3)=0 4828 end if 4829 end if 4830 end if 4831 4832 if (mod(abs(spqpt(1,iqpt)-qsym(4))+tol,1._dp)<2*tol)then 4833 if (mod(abs(spqpt(2,iqpt)-qsym(5))+tol,1._dp)<2*tol)then 4834 if (mod(abs(spqpt(3,iqpt)-qsym(6))+tol,1._dp)<2*tol)then 4835 4836 ! write(std_out,*)' q point from the DDB ! ' 4837 ! write(std_out,*)' block -> ',iblok 4838 ! write(std_out,*)' sym. -> ',isym 4839 ! write(std_out,*)' Time Reversal ' 4840 ! write(std_out,*)'(',qsym(4),',',qsym(5),',',qsym(6),')' 4841 ! write(std_out,*)' ' 4842 4843 qtest(iqpt,1)=iblok 4844 qtest(iqpt,2)=isym 4845 qtest(iqpt,3)=1 4846 end if 4847 end if 4848 end if 4849 4850 end do ! End of the loop on the q points of the sampling 4851 end do ! End of the loop on the symmetries 4852 4853 end if 4854 end do ! End of the loop on the q points of the DDB 4855 4856 ! Check if all the informations relatives to the q points sampling are found in the DDB; 4857 ! if not => stop message 4858 nqmiss = 0 4859 do iqpt=1,nqpt 4860 if (qtest(iqpt,1)==0) then 4861 nqmiss = nqmiss + 1 4862 qmiss_(nqmiss) = iqpt 4863 write(message, '(a,a,a)' )& 4864 & ' symdm9 : the bloks found in the DDB are characterized',ch10,& 4865 & ' by the following wavevectors :' 4866 call wrtout(std_out,message,'COLL') 4867 do iblok=1,nblok 4868 write(message, '(a,4d20.12)')& 4869 & ' ',blkqpt(1,iblok),blkqpt(2,iblok),blkqpt(3,iblok),blknrm(1,iblok) 4870 call wrtout(std_out,message,'COLL') 4871 end do 4872 write(message, '(a,a,a,i0,a,a,a,3es16.6,a,a,a,a)' )& 4873 & 'Information is missing in the DDB.',ch10,& 4874 & 'The dynamical matrix number ',iqpt,' cannot be built,',ch10,& 4875 & 'since no block with wavevector',spqpt(1:3,iqpt),ch10,& 4876 & 'has been found.',ch10,& 4877 & 'Action: add the required blok in the DDB, or modify your input file.' 4878 if (.not.allow_qmiss) then 4879 MSG_ERROR(message) 4880 else 4881 !continue 4882 MSG_COMMENT(message) 4883 end if 4884 end if 4885 end do 4886 4887 ! Will return a list with the index of the q-points that could not be symmetrized. 4888 if (allow_qmiss) then 4889 ABI_ALLOCATE(qmissing, (nqmiss)) 4890 if (nqmiss > 0) qmissing = qmiss_(1:nqmiss) 4891 end if 4892 4893 !Generation of the dynamical matrices relative to the q points 4894 !of the set which samples the entire Brillouin zone 4895 do iqpt=1,nqpt 4896 q1=qtest(iqpt,1) 4897 q2=qtest(iqpt,2) 4898 ! Skip this q-point if don't have enough info and allow_qmiss 4899 if (allow_qmiss .and. q1==0) cycle 4900 4901 ! Check if the symmetry accompagnied with time reversal : q <- -q 4902 if (qtest(iqpt,3)==0) then 4903 do ii=1,3 4904 qq(ii)=blkqpt(ii,q1)/blknrm(1,q1) 4905 do jj=1,3 4906 ss(ii,jj)=zero 4907 do kk=1,3 4908 do ll=1,3 4909 ss(ii,jj)=ss(ii,jj)+rprim(ii,kk)*gprim(jj,ll)*symrel(kk,ll,q2) 4910 end do 4911 end do 4912 end do 4913 end do 4914 ! write(std_out,*)"ss",ss 4915 else 4916 do ii=1,3 4917 qq(ii)=-blkqpt(ii,q1)/blknrm(1,q1) 4918 do jj=1,3 4919 ss(ii,jj)=zero 4920 do kk=1,3 4921 do ll=1,3 4922 ss(ii,jj)=ss(ii,jj)+rprim(ii,kk)*gprim(jj,ll)*symrel(kk,ll,q2) 4923 end do 4924 end do 4925 end do 4926 end do 4927 end if 4928 ! 4929 ! Check whether all the information is contained in the DDB 4930 do ipert2=1,natom 4931 do idir2=1,3 4932 do ipert1=1,natom 4933 do idir1=1,3 4934 if(blkflg(idir1,ipert1,idir2,ipert2,q1)/=1)then 4935 write(message, '(a,a,a,i6,a,a,a,4i4,a,a,a,a)' )& 4936 & 'Informations are missing in the DDB.',ch10,& 4937 & 'In block',q1,' the following element is missing :',ch10,& 4938 & 'idir1,ipert1,idir2,ipert2=',idir1,ipert1,idir2,ipert2,ch10,& 4939 & 'Action: add the required information in the DDB,',ch10,& 4940 & 'or modify your input file.' 4941 MSG_ERROR(message) 4942 end if 4943 end do 4944 end do 4945 end do 4946 end do 4947 4948 ! Read the dynamical matrices in the DDB 4949 do ipert2=1,natom 4950 do idir2=1,3 4951 do ipert1=1,natom 4952 do idir1=1,3 4953 ddd(:,idir1,ipert1,idir2,ipert2)=blkval(:,idir1+3*(ipert1-1+mpert*(idir2-1+3*(ipert2-1))),q1) 4954 end do 4955 end do 4956 end do 4957 end do 4958 4959 ! Calculation of the dynamical matrix of a symmetrical q point 4960 do ia=1,natom 4961 do ib=1,natom 4962 ! write(std_out,*)'atom-> ',ia,indsym(4,q2,ia) 4963 ! write(std_out,*)'atom-> ',ib,indsym(4,q2,ib) 4964 arg1=two_pi*(qq(1)*indsym(1,q2,ia)+qq(2)*indsym(2,q2,ia)+qq(3)*indsym(3,q2,ia)) 4965 arg2=two_pi*(qq(1)*indsym(1,q2,ib)+qq(2)*indsym(2,q2,ib)+qq(3)*indsym(3,q2,ib)) 4966 re=cos(arg1)*cos(arg2)+sin(arg1)*sin(arg2) 4967 im=cos(arg2)*sin(arg1)-cos(arg1)*sin(arg2) 4968 ! write(std_out,*)'re : ',re, 'im : ',im 4969 do mu=1,3 4970 do nu=1,3 4971 ! write(std_out,*)' ' 4972 sumr=zero 4973 sumi=zero 4974 do ii=1,3 4975 do jj=1,3 4976 ! If there is Time Reversal : D.M. <- Complex Conjugate D.M. 4977 if (qtest(iqpt,3)==0) then 4978 sumr=sumr+ss(mu,ii)*ss(nu,jj)*ddd(1,ii,indsym(4,q2,ia),jj,indsym(4,q2,ib)) 4979 sumi=sumi+ss(mu,ii)*ss(nu,jj)*ddd(2,ii,indsym(4,q2,ia),jj,indsym(4,q2,ib)) 4980 else 4981 sumr=sumr+ss(mu,ii)*ss(nu,jj)*ddd(1,ii,indsym(4,q2,ia),jj,indsym(4,q2,ib)) 4982 sumi=sumi-ss(mu,ii)*ss(nu,jj)*ddd(2,ii,indsym(4,q2,ia),jj,indsym(4,q2,ib)) 4983 end if 4984 end do 4985 end do 4986 4987 ! Dynmat -> Dynamical Matrix for the q point of the sampling 4988 ! write(std_out,*)' Sumr -> ',mu,nu,sumr 4989 ! write(std_out,*)' Sumi -> ',mu,nu,sumi 4990 dynmat(1,mu,ia,nu,ib,iqpt)=re*sumr-im*sumi 4991 dynmat(2,mu,ia,nu,ib,iqpt)=re*sumi+im*sumr 4992 4993 ! DEBUG 4994 ! if((ia==2 .or. ia==3) .and. ib==1)then 4995 ! write(std_out,'(5i3,2es16.8)' )mu,ia,nu,ib,iqpt,dynmat(1:2,mu,ia,nu,ib,iqpt) 4996 ! end if 4997 ! ENDDEBUG 4998 4999 end do ! End loop on the coordinates 5000 end do 5001 5002 end do ! End loop on the ia atoms 5003 end do ! End loop on the ib atoms 5004 end do ! End loop on the q points of the sampling 5005 5006 ABI_DEALLOCATE(ddd) 5007 ABI_DEALLOCATE(qtest) 5008 5009 end subroutine symdm9
m_dynmat/symdyma [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
symdyma
FUNCTION
Symmetrize the dynamical matrices
INPUTS
indsym(4,nsym*natom)=indirect indexing array : for each isym,iatom, fourth element is label of atom into which iatom is sent by INVERSE of symmetry operation isym; first three elements are the primitive translations which must be subtracted after the transformation to get back to the original unit cell. natom=number of atoms in unit cell nsym=number of space group symmetries qptn(3)=normalized phonon wavevector rprimd(3,3)=dimensional primitive translations (bohr) symrel(3,3,nsym)=3x3 matrices of the group symmetries (real space)
SIDE EFFECTS
Input/Output dmati(2*3*natom*3*natom)=dynamical matrices in cartesian coordinates relative to the q points of the B.Z. sampling
NOTES
the procedure of the symmetrization of the dynamical matrix follows the equations in: Hendrikse et al., Computer Phys. Comm. 86, 297 (1995)
TODO
A full description of the equations should be included
PARENTS
m_dynmat,m_phgamma,relaxpol
CHILDREN
SOURCE
2182 subroutine symdyma(dmati,indsym,natom,nsym,qptn,rprimd,symrel,symafm) 2183 2184 2185 !This section has been created automatically by the script Abilint (TD). 2186 !Do not modify the following lines by hand. 2187 #undef ABI_FUNC 2188 #define ABI_FUNC 'symdyma' 2189 use interfaces_32_util 2190 !End of the abilint section 2191 2192 implicit none 2193 2194 !Arguments ------------------------------- 2195 !scalars 2196 integer,intent(in) :: natom,nsym 2197 !arrays 2198 integer,intent(in) :: indsym(4,nsym,natom),symrel(3,3,nsym) 2199 integer,intent(in) :: symafm(nsym) 2200 real(dp),intent(in) :: qptn(3),rprimd(3,3) 2201 real(dp),intent(inout) :: dmati(2*3*natom*3*natom) 2202 2203 !Local variables ------------------------- 2204 !scalars 2205 integer :: i1,i2,iat,idir,ii,index,isgn,isym,itirev,jat,jdir,jj,kk,ll 2206 integer :: niat,njat,timrev 2207 real(dp) :: arg1,arg2,dmint,im,re,sumi,sumr 2208 !arrays 2209 integer :: indij(natom,natom),symq(4,2,nsym),symrec(3,3,nsym) 2210 real(dp) :: TqR(3,3),TqS_(3,3),dynmat(2,3,natom,3,natom) 2211 real(dp) :: dynmatint(2*nsym,2,3,natom,3,natom),gprimd(3,3) 2212 real(dp) :: symcart(3,3,nsym) 2213 2214 ! ********************************************************************* 2215 2216 !0) initializations 2217 call matr3inv(rprimd,gprimd) 2218 do isym=1,nsym 2219 call mati3inv(symrel(:,:,isym),symrec(:,:,isym)) 2220 end do 2221 2222 TqR=zero 2223 TqS_=zero 2224 dynmat=zero 2225 2226 !Note: dynmat is used as work space here 2227 i1=0 2228 do iat=1,natom 2229 do idir=1,3 2230 i1=i1+1 2231 i2=0 2232 do jat=1,natom 2233 do jdir=1,3 2234 i2=i2+1 2235 index=i1+3*natom*(i2-1) 2236 dynmat(1,idir,iat,jdir,jat)=dmati(2*index-1) 2237 dynmat(2,idir,iat,jdir,jat)=dmati(2*index ) 2238 end do 2239 end do 2240 end do 2241 end do 2242 2243 !Transform symrel to cartesian coordinates (RC coding) 2244 !do isym=1,nsym 2245 !symcart(:,:,isym)=matmul(rprimd,matmul(dble(symrel(:,:,isym)),gprimd)) 2246 !end do 2247 2248 !Coding from symdm9 2249 do isym=1,nsym 2250 do jj=1,3 2251 symcart(:,jj,isym)=zero 2252 do kk=1,3 2253 do ll=1,3 2254 symcart(:,jj,isym)=symcart(:,jj,isym)+rprimd(:,kk)*gprimd(jj,ll)*symrel(kk,ll,isym) 2255 end do 2256 end do 2257 end do 2258 end do 2259 2260 2261 !Get the symq of the CURRENT Q POINT 2262 !mjv: set prtvol=0 for production runs. 2263 call littlegroup_q(nsym,qptn,symq,symrec,symafm,timrev,prtvol=0) 2264 2265 indij(:,:)=0 2266 dynmatint=zero 2267 2268 do isym=1,nsym ! loop over all the symmetries 2269 ! write(std_out,*) 'current symmetry',isym 2270 do itirev=1,2 ! loop over the time-reversal symmetry 2271 isgn=3-2*itirev ! to take into accont the time-reversal 2272 ! write(std_out,*) 'timereversal',isgn 2273 if (symq(4,itirev,isym)==1) then ! isym belongs to the wave vector point group 2274 ! write(std_out,*) 'isym belongs to the wave vector point group' 2275 do iat=1,natom ! loop over the atoms 2276 do jat=1,natom ! loop over the atoms 2277 niat=indsym(4,isym,iat) ! niat={R|t}iat 2278 njat=indsym(4,isym,jat) ! njat={R|t}jat 2279 indij(niat,njat)=indij(niat,njat)+1 2280 ! write(std_out,'(a,5i5)') 'current status:',iat,jat,niat,njat,indij(niat,njat) 2281 ! phase calculation, arg1 and arg2 because of two-atom derivative 2282 arg1=two_pi*( qptn(1)*indsym(1,isym,iat)+& 2283 & qptn(2)*indsym(2,isym,iat)+& 2284 & qptn(3)*indsym(3,isym,iat) ) 2285 arg2=two_pi*( qptn(1)*indsym(1,isym,jat)+& 2286 & qptn(2)*indsym(2,isym,jat)+& 2287 & qptn(3)*indsym(3,isym,jat) ) 2288 re=cos(arg1)*cos(arg2)+sin(arg1)*sin(arg2) 2289 im=isgn*(cos(arg2)*sin(arg1)-cos(arg1)*sin(arg2)) 2290 2291 do idir=1,3 ! loop over displacements 2292 do jdir=1,3 ! loop over displacements 2293 ! we pick the (iat,jat) (3x3) block of the dyn.mat. 2294 sumr=zero 2295 sumi=zero 2296 do ii=1,3 2297 do jj=1,3 2298 sumr=sumr+symcart(idir,ii,isym)*dynmat(1,ii,niat,jj,njat)*symcart(jdir,jj,isym) 2299 sumi=sumi+symcart(idir,ii,isym)*dynmat(2,ii,niat,jj,njat)*symcart(jdir,jj,isym) 2300 end do 2301 end do 2302 sumi=isgn*sumi 2303 2304 dynmatint(nsym*(itirev-1)+isym,1,idir,iat,jdir,jat)=re*sumr-im*sumi 2305 dynmatint(nsym*(itirev-1)+isym,2,idir,iat,jdir,jat)=re*sumi+im*sumr 2306 2307 end do 2308 end do 2309 end do 2310 end do ! end treatment of the (iat,jat) (3x3) block of dynmat 2311 end if ! symmetry check 2312 end do ! time-reversal 2313 end do ! symmetries 2314 2315 2316 !4) make the average, get the final symmetric dynamical matrix 2317 do iat=1,natom 2318 do jat=1,natom 2319 do idir=1,3 2320 do jdir=1,3 2321 dmint=zero 2322 do isym=1,2*nsym 2323 dmint=dmint+dynmatint(isym,1,idir,iat,jdir,jat) 2324 end do 2325 dynmat(1,idir,iat,jdir,jat)=dmint/dble(indij(iat,jat)) 2326 dmint=zero 2327 do isym=1,2*nsym 2328 dmint=dmint+dynmatint(isym,2,idir,iat,jdir,jat) 2329 end do 2330 dynmat(2,idir,iat,jdir,jat)=dmint/dble(indij(iat,jat)) 2331 end do 2332 end do 2333 end do 2334 end do 2335 2336 i1=0 2337 do iat=1,natom 2338 do idir=1,3 2339 i1=i1+1 2340 i2=0 2341 do jat=1,natom 2342 do jdir=1,3 2343 i2=i2+1 2344 index=i1+3*natom*(i2-1) 2345 dmati(2*index-1)=dynmat(1,idir,iat,jdir,jat) 2346 dmati(2*index )=dynmat(2,idir,iat,jdir,jat) 2347 end do 2348 end do 2349 end do 2350 end do 2351 2352 end subroutine symdyma
m_dynmat/sytens [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
sytens
FUNCTION
Determines the set of irreductible elements of the non-linear optical susceptibility and Raman tensors
INPUTS
indsym(4,nsym,natom)=indirect indexing array described above: for each isym,iatom, fourth element is label of atom into which iatom is sent by INVERSE of symmetry operation isym; first three elements are the primitive translations which must be subtracted after the transformation to get back to the original unit cell. mpert =maximum number of ipert natom= number of atoms nsym=number of space group symmetries symrec(3,3,nsym)=3x3 matrices of the group symmetries (reciprocal space) symrel(3,3,nsym)=3x3 matrices of the group symmetries (real space)
OUTPUT
(see side effects)
SIDE EFFECTS
rfpert(3,mpert,3,mpert,3,mpert) = array defining the type of perturbations that have to be computed At the input : 1 -> element has to be computed explicitely At the output : 1 -> element has to be computed explicitely -1 -> use symmetry operations to obtain the corresponding element -2 -> element is zero by symmetry
PARENTS
m_ddb,nonlinear,respfn
CHILDREN
SOURCE
4457 subroutine sytens(indsym,mpert,natom,nsym,rfpert,symrec,symrel) 4458 4459 use defs_basis 4460 use m_profiling_abi 4461 4462 !This section has been created automatically by the script Abilint (TD). 4463 !Do not modify the following lines by hand. 4464 #undef ABI_FUNC 4465 #define ABI_FUNC 'sytens' 4466 !End of the abilint section 4467 4468 implicit none 4469 4470 !Arguments ------------------------------- 4471 !scalars 4472 integer,intent(in) :: mpert,natom,nsym 4473 !arrays 4474 integer,intent(in) :: indsym(4,nsym,natom),symrec(3,3,nsym),symrel(3,3,nsym) 4475 integer,intent(inout) :: rfpert(3,mpert,3,mpert,3,mpert) 4476 4477 !Local variables ------------------------- 4478 !scalars 4479 integer :: flag,found,i1dir,i1dir_,i1pert,i1pert_,i2dir,i2dir_,i2pert,i2pert_ 4480 integer :: i3dir,i3dir_,i3pert,i3pert_,idisy1,idisy2,idisy3,ipesy1,ipesy2 4481 integer :: ipesy3,isym 4482 !arrays 4483 integer :: sym1(3,3),sym2(3,3),sym3(3,3) 4484 integer,allocatable :: pertsy(:,:,:,:,:,:) 4485 4486 !*********************************************************************** 4487 4488 !DEBUG 4489 !write(std_out,*)'sytens : enter' 4490 !write(std_out,*)'indsym = ' 4491 !write(std_out,*)indsym 4492 !stop 4493 !ENDDEBUG 4494 4495 ABI_ALLOCATE(pertsy,(3,mpert,3,mpert,3,mpert)) 4496 pertsy(:,:,:,:,:,:) = 0 4497 4498 !Loop over perturbations 4499 4500 do i1pert_ = 1, mpert 4501 do i2pert_ = 1, mpert 4502 do i3pert_ = 1, mpert 4503 4504 do i1dir_ = 1, 3 4505 do i2dir_ = 1, 3 4506 do i3dir_ = 1, 3 4507 4508 i1pert = (mpert - i1pert_ + 1) 4509 if (i1pert <= natom) i1pert = natom + 1 - i1pert 4510 i2pert = (mpert - i2pert_ + 1) 4511 if (i2pert <= natom) i2pert = natom + 1 - i2pert 4512 i3pert = (mpert - i3pert_ + 1) 4513 if (i3pert <= natom) i3pert = natom + 1 - i3pert 4514 4515 if (i1pert <= natom) then 4516 i1dir = i1dir_ ; i2dir = i2dir_ ; i3dir = i3dir_ 4517 else if (i2pert <= natom) then 4518 i1dir = i2dir_ ; i2dir = i1dir_ ; i3dir = i3dir_ 4519 else if (i3pert <= natom) then 4520 i1dir = i3dir_ ; i2dir = i2dir_ ; i3dir = i1dir_ 4521 else 4522 i1dir = i1dir_ ; i2dir = i2dir_ ; i3dir = i3dir_ 4523 end if 4524 4525 if (rfpert(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) /= 0) then 4526 4527 ! Loop over all symmetries 4528 4529 flag = 0 4530 do isym = 1, nsym 4531 4532 found = 1 4533 4534 ! Select the symmetric element of i1pert,i2pert,i3pert 4535 4536 if (i1pert <= natom) then 4537 ipesy1 = indsym(4,isym,i1pert) 4538 sym1(:,:) = symrec(:,:,isym) 4539 else if (i1pert == natom + 2) then 4540 ipesy1 = i1pert 4541 sym1(:,:) = symrel(:,:,isym) 4542 else 4543 found = 0 4544 end if 4545 4546 if (i2pert <= natom) then 4547 ipesy2 = indsym(4,isym,i2pert) 4548 sym2(:,:) = symrec(:,:,isym) 4549 else if (i2pert == natom + 2) then 4550 ipesy2 = i2pert 4551 sym2(:,:) = symrel(:,:,isym) 4552 else 4553 found = 0 4554 end if 4555 4556 if (i3pert <= natom) then 4557 ipesy3 = indsym(4,isym,i3pert) 4558 sym3(:,:) = symrec(:,:,isym) 4559 else if (i3pert == natom + 2) then 4560 ipesy3 = i3pert 4561 sym3(:,:) = symrel(:,:,isym) 4562 else 4563 found = 0 4564 end if 4565 4566 ! See if the symmetric element is available and check if some 4567 ! of the elements may be zeor. In the latter case, they do not need 4568 ! to be computed. 4569 4570 4571 if ((flag /= -1).and.& 4572 & (ipesy1==i1pert).and.(ipesy2==i2pert).and.(ipesy3==i3pert)) then 4573 flag = sym1(i1dir,i1dir)*sym2(i2dir,i2dir)*sym3(i3dir,i3dir) 4574 end if 4575 4576 4577 do idisy1 = 1, 3 4578 do idisy2 = 1, 3 4579 do idisy3 = 1, 3 4580 4581 if ((sym1(i1dir,idisy1) /= 0).and.(sym2(i2dir,idisy2) /= 0).and.& 4582 & (sym3(i3dir,idisy3) /= 0)) then 4583 if (pertsy(idisy1,ipesy1,idisy2,ipesy2,idisy3,ipesy3) == 0) then 4584 found = 0 4585 ! exit ! exit loop over symmetries 4586 end if 4587 end if 4588 4589 4590 if ((flag == -1).and.& 4591 & ((idisy1/=i1dir).or.(idisy2/=i2dir).or.(idisy3/=i3dir))) then 4592 if ((sym1(i1dir,idisy1)/=0).and.(sym2(i2dir,idisy2)/=0).and.& 4593 & (sym3(i3dir,idisy3)/=0)) then 4594 flag = 0 4595 end if 4596 end if 4597 4598 4599 4600 end do 4601 end do 4602 end do 4603 4604 4605 if (found == 1) then 4606 pertsy(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = -1 4607 end if 4608 4609 4610 ! In case a symmetry operation only changes the sign of an 4611 ! element, this element has to be equal to zero 4612 4613 if (flag == -1) then 4614 pertsy(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = -2 4615 exit 4616 end if 4617 4618 end do ! close loop on symmetries 4619 4620 4621 4622 ! If the elemetn i1pert,i2pert,i3pert is not symmetric 4623 ! to a basis element, it is a basis element 4624 4625 if (pertsy(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) > -1) then 4626 pertsy(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = 1 4627 end if 4628 4629 end if ! rfpert /= 0 4630 4631 end do ! close loop over perturbations 4632 end do 4633 end do 4634 end do 4635 end do 4636 end do 4637 4638 4639 !Now, take into account the permutation of (i1pert,i1dir) 4640 !and (i3pert,i3dir) 4641 4642 do i1pert = 1, mpert 4643 do i2pert = 1, mpert 4644 do i3pert = 1, mpert 4645 4646 do i1dir = 1, 3 4647 do i2dir = 1, 3 4648 do i3dir = 1, 3 4649 4650 if ((i1pert /= i3pert).or.(i1dir /= i3dir)) then 4651 4652 if ((pertsy(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) == 1).and.& 4653 & (pertsy(i3dir,i3pert,i2dir,i2pert,i1dir,i1pert) == 1)) then 4654 pertsy(i3dir,i3pert,i2dir,i2pert,i1dir,i1pert) = -1 4655 end if 4656 4657 end if 4658 4659 end do 4660 end do 4661 end do 4662 4663 end do 4664 end do 4665 end do 4666 4667 rfpert(:,:,:,:,:,:) = pertsy(:,:,:,:,:,:) 4668 4669 ABI_DEALLOCATE(pertsy) 4670 4671 4672 end subroutine sytens
m_dynmat/wght9 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
wght9
FUNCTION
Generates a weight to each R points of the Big Box and for each pair of atoms For each R points included in the space generates by moving the unit cell around each atom; the weight will be one. Border conditions are provided. The R points outside the chosen space will have a 0 weight.
INPUTS
brav = Bravais lattice (1 or -1=S.C.;2=F.C.C.;4=Hex. -1 is for old algo to find weights, =1 is for Wigner-Seitz algo) gprim(3,3)= Normalized coordinates in reciprocal space natom= Number of atoms in the unit cell ngqpt(6)= Numbers used to sample the Brillouin zone nqpt= Number of q points used in the homogeneous grid sampling the Brillouin zone nqshft=number of shift vectors in the repeated cell nrpt=Number of R points in the Big Box qshft(3,nqshft)=vectors that will be used to determine the shifts from (0. 0. 0.) rcan(3,natom)=Atomic position in canonical coordinates rpt(3,nprt)=Canonical coordinates of the R points in the unit cell These coordinates are normalized (=> * acell(3)) rprimd(3,3)=dimensional primitive translations for real space (bohr)
OUTPUT
wghatm(natom,natom,nrpt)= Weight associated to the couple of atoms and the R vector The vector r(atom2)-r(atom1)+rpt should be inside the moving box ngqpt(6)= can be modified
PARENTS
m_ifc
CHILDREN
SOURCE
3795 subroutine wght9(brav,gprim,natom,ngqpt,nqpt,nqshft,nrpt,qshft,rcan,rpt,rprimd,r_inscribed_sphere,wghatm) 3796 3797 3798 !This section has been created automatically by the script Abilint (TD). 3799 !Do not modify the following lines by hand. 3800 #undef ABI_FUNC 3801 #define ABI_FUNC 'wght9' 3802 use interfaces_14_hidewrite 3803 !End of the abilint section 3804 3805 implicit none 3806 3807 !Arguments ------------------------------- 3808 !scalars 3809 integer,intent(in) :: brav,natom,nqpt,nqshft,nrpt 3810 real(dp),intent(out) :: r_inscribed_sphere 3811 !arrays 3812 integer,intent(inout) :: ngqpt(9) 3813 real(dp),intent(in) :: gprim(3,3),qshft(3,4),rcan(3,natom),rpt(3,nrpt),rprimd(3,3) 3814 real(dp),intent(out) :: wghatm(natom,natom,nrpt) 3815 3816 !Local variables ------------------------- 3817 !scalars 3818 integer :: ia,ib,ii,jj,kk,iqshft,irpt,jqshft,nbordh,tok,new_wght,nptws,nreq 3819 integer :: idir 3820 real(dp), parameter :: tolsym=tol8 3821 real(dp) :: factor,sumwght,normsq,proj 3822 character(len=500) :: message 3823 !arrays 3824 integer :: nbord(9) 3825 real(dp) :: rdiff(9),red(3,3),ptws(4, 729),pp(3),rdiff_tmp(3) 3826 3827 ! ********************************************************************* 3828 3829 DBG_ENTER("COLL") 3830 3831 !First analyze the vectors qshft 3832 if(nqshft/=1)then 3833 3834 if(brav==4)then 3835 write(message,'(a,a,a,i5,a,a,a)' )& 3836 & 'For the time being, only nqshft=1',ch10,& 3837 & 'is allowed with brav=4, while it is nqshft=',nqshft,'.',ch10,& 3838 & 'Action: in the input file, correct either brav or nqshft.' 3839 MSG_ERROR(message) 3840 end if 3841 3842 if(nqshft==2)then 3843 ! Make sure that the q vectors form a BCC lattice 3844 do ii=1,3 3845 if(abs(abs(qshft(ii,1)-qshft(ii,2))-.5_dp)>1.d-10)then 3846 write(message, '(a,a,a,a,a,a,a)' )& 3847 & 'The test of the q1shft vectors shows that they',ch10,& 3848 & 'do not generate a body-centered lattice, which',ch10,& 3849 & 'is mandatory for nqshft=2.',ch10,& 3850 & 'Action: change the q1shft vectors in your input file.' 3851 MSG_ERROR(message) 3852 end if 3853 end do 3854 else if(nqshft==4)then 3855 ! Make sure that the q vectors form a FCC lattice 3856 do iqshft=1,3 3857 do jqshft=iqshft+1,4 3858 tok=0 3859 do ii=1,3 3860 ! Test on the presence of a +-0.5 difference 3861 if(abs(abs(qshft(ii,iqshft)-qshft(ii,jqshft))-.5_dp) <1.d-10) tok=tok+1 3862 ! Test on the presence of a 0 or +-1.0 difference 3863 if(abs(abs(qshft(ii,iqshft)-qshft(ii,jqshft))-1._dp) <1.d-10 .or.& 3864 & abs(qshft(ii,iqshft)-qshft(ii,jqshft)) < 1.d-10) tok=tok+4 3865 end do 3866 ! Test 1 should be satisfied twice, and test 2 once 3867 if(tok/=6)then 3868 write(message, '(7a)' )& 3869 & 'The test of the q1shft vectors shows that they',ch10,& 3870 & 'do not generate a face-centered lattice, which',ch10,& 3871 & 'is mandatory for nqshft=4.',ch10,& 3872 & 'Action: change the q1shft vectors in your input file.' 3873 MSG_ERROR(message) 3874 end if 3875 end do 3876 end do 3877 else 3878 write(message, '(a,i4,3a)' )& 3879 & 'nqshft must be 1, 2 or 4. It is nqshft=',nqshft,'.',ch10,& 3880 & 'Action: change nqshft in your input file.' 3881 MSG_ERROR(message) 3882 end if 3883 3884 end if 3885 3886 factor=0.5_dp 3887 if(brav==2 .or. brav==3)then 3888 factor=0.25_dp 3889 end if 3890 if(nqshft/=1)factor=factor*2 3891 3892 if (brav==1) then 3893 3894 ! Does not support multiple shifts 3895 if (nqshft/=1) then 3896 write(message, '(a)' ) 'This version of the weights does not support nqshft/=1.' 3897 MSG_ERROR(message) 3898 end if 3899 3900 ! Find the points of the lattice given by ngqpt*acell. These are used to define 3901 ! a Wigner-Seitz cell around the origin. The origin is excluded from the list. 3902 ! TODO : in principle this should be only -1 to +1 for ii jj kk! 3903 nptws=0 3904 do ii=-2,2 3905 do jj=-2,2 3906 do kk=-2,2 3907 do idir=1,3 3908 pp(idir)=ii*ngqpt(1)*rprimd(idir,1)+ jj*ngqpt(2)*rprimd(idir,2)+ kk*ngqpt(3)*rprimd(idir,3) 3909 end do 3910 normsq = pp(1)*pp(1)+pp(2)*pp(2)+pp(3)*pp(3) 3911 if (normsq > tol6) then 3912 nptws = nptws + 1 3913 ptws(:3,nptws) = pp(:) 3914 ptws(4,nptws) = half*normsq 3915 end if 3916 end do 3917 end do 3918 end do 3919 end if ! end new_wght 3920 3921 !DEBUG 3922 !write(std_out,*)'factor,ngqpt',factor,ngqpt(1:3) 3923 !ENDDEBUG 3924 3925 r_inscribed_sphere = sum((matmul(rprimd(:,:),ngqpt(1:3)))**2) 3926 do ii=-1,1 3927 do jj=-1,1 3928 do kk=-1,1 3929 if (ii==0 .and. jj==0 .and. kk==0) cycle 3930 do idir=1,3 3931 pp(idir)=ii*ngqpt(1)*rprimd(idir,1)+ jj*ngqpt(2)*rprimd(idir,2)+ kk*ngqpt(3)*rprimd(idir,3) 3932 end do 3933 normsq = pp(1)*pp(1)+pp(2)*pp(2)+pp(3)*pp(3) 3934 r_inscribed_sphere = min(r_inscribed_sphere, normsq) 3935 end do 3936 end do 3937 end do 3938 r_inscribed_sphere = sqrt(r_inscribed_sphere) 3939 3940 3941 !Begin the big loop on ia and ib 3942 do ia=1,natom 3943 do ib=1,natom 3944 3945 ! Simple Lattice 3946 if (abs(brav)==1) then 3947 ! In this case, it is better to work in reduced coordinates 3948 ! As rcan is in canonical coordinates, => multiplication by gprim 3949 do ii=1,3 3950 red(1,ii)= rcan(1,ia)*gprim(1,ii) +rcan(2,ia)*gprim(2,ii) +rcan(3,ia)*gprim(3,ii) 3951 red(2,ii)= rcan(1,ib)*gprim(1,ii) +rcan(2,ib)*gprim(2,ii) +rcan(3,ib)*gprim(3,ii) 3952 end do 3953 end if 3954 3955 do irpt=1,nrpt 3956 3957 ! Initialization of the weights to 1.0 3958 wghatm(ia,ib,irpt)=1.0_dp 3959 3960 ! Compute the difference vector 3961 3962 ! Simple Cubic Lattice 3963 if (abs(brav)==1) then 3964 ! Change of rpt to reduced coordinates 3965 do ii=1,3 3966 red(3,ii)= rpt(1,irpt)*gprim(1,ii) +rpt(2,irpt)*gprim(2,ii) +rpt(3,irpt)*gprim(3,ii) 3967 rdiff(ii)=red(2,ii)-red(1,ii)+red(3,ii) 3968 end do 3969 if (brav==1) then 3970 ! rdiff in cartesian coordinates 3971 do ii=1,3 3972 rdiff_tmp(ii)=rdiff(1)*rprimd(ii,1)+rdiff(2)*rprimd(ii,2)+rdiff(3)*rprimd(ii,3) 3973 end do 3974 rdiff(1:3)=rdiff_tmp(1:3) 3975 end if 3976 ! Other lattices 3977 else 3978 do ii=1,3 3979 rdiff(ii)=rcan(ii,ib)-rcan(ii,ia)+rpt(ii,irpt) 3980 end do 3981 end if 3982 3983 ! *************************************************************** 3984 3985 ! Assignement of weights 3986 3987 if(nqshft==1 .and. brav/=4)then 3988 3989 if (brav/=1) then 3990 do ii=1,3 3991 ! If the rpt vector is greater than 3992 ! the allowed space => weight = 0.0 3993 if (abs(rdiff(ii))-tol10>factor*ngqpt(ii)) then 3994 wghatm(ia,ib,irpt)=zero 3995 else if (abs(abs(rdiff(ii))-factor*ngqpt(ii)) <=1.0d-10) then 3996 ! If the point is in a boundary position => weight/2 3997 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/2 3998 end if 3999 end do 4000 else 4001 ! new weights 4002 wghatm(ia,ib,irpt)=zero 4003 nreq = 1 4004 do ii=1,nptws 4005 proj = rdiff(1)*ptws(1,ii)+rdiff(2)*ptws(2,ii)+rdiff(3)*ptws(3,ii) 4006 ! if rdiff closer to ptws than the origin the weight is zero 4007 ! if rdiff close to the origin with respect to all the other ptws the weight is 1 4008 ! if rdiff is equidistant from the origin and N other ptws the weight is 1/(N+1) 4009 if (proj-ptws(4,ii)>tolsym) then 4010 nreq = 0 4011 EXIT 4012 else if(abs(proj-ptws(4,ii))<=tolsym) then 4013 nreq=nreq+1 4014 end if 4015 end do 4016 if (nreq>0) then 4017 wghatm(ia,ib,irpt)=one/DBLE(nreq) 4018 end if 4019 end if 4020 4021 else if(brav==4)then 4022 ! Hexagonal 4023 4024 ! Examination of the X and Y boundaries in order to form an hexagon 4025 ! First generate the relevant boundaries 4026 rdiff(4)=0.5_dp*( rdiff(1)+sqrt(3.0_dp)*rdiff(2) ) 4027 ngqpt(4)=ngqpt(1) 4028 rdiff(5)=0.5_dp*( rdiff(1)-sqrt(3.0_dp)*rdiff(2) ) 4029 ngqpt(5)=ngqpt(1) 4030 4031 ! Test the four inequalities 4032 do ii=1,5 4033 if(ii/=2)then 4034 4035 nbord(ii)=0 4036 ! If the rpt vector is greater than 4037 ! the allowed space => weight = 0.0 4038 if (abs(rdiff(ii))-1.0d-10>factor*ngqpt(ii)) then 4039 wghatm(ia,ib,irpt)=zero 4040 else if (abs(abs(rdiff(ii))-factor*ngqpt(ii)) <=1.0d-10) then 4041 ! If the point is in a boundary position increment nbord(ii) 4042 nbord(ii)=1 4043 end if 4044 4045 end if 4046 end do 4047 4048 ! Computation of weights 4049 nbordh=nbord(1)+nbord(4)+nbord(5) 4050 if (nbordh==1) then 4051 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/2 4052 else if (nbordh==2) then 4053 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/3 4054 else if (nbordh/=0) then 4055 message = 'There is a problem of borders and weights (hex).' 4056 MSG_BUG(message) 4057 end if 4058 if (nbord(3)==1)then 4059 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/2 4060 end if 4061 4062 ! BCC packing of k-points 4063 else if(nqshft==2 .and. brav/=4)then 4064 4065 ! First, generate the relevant boundaries 4066 rdiff(4)= rdiff(1)+rdiff(2) 4067 rdiff(5)= rdiff(1)-rdiff(2) 4068 rdiff(6)= rdiff(1)+rdiff(3) 4069 rdiff(7)= rdiff(1)-rdiff(3) 4070 rdiff(8)= rdiff(3)+rdiff(2) 4071 rdiff(9)= rdiff(3)-rdiff(2) 4072 if(ngqpt(2)/=ngqpt(1) .or. ngqpt(3)/=ngqpt(1))then 4073 write(message, '(a,a,a,3i6,a,a,a,a)' )& 4074 & 'In the BCC case, the three ngqpt numbers ',ch10,& 4075 & ' ',ngqpt(1),ngqpt(2),ngqpt(3),ch10,& 4076 & 'should be equal.',ch10,& 4077 & 'Action: use identical ngqpt(1:3) in your input file.' 4078 MSG_ERROR(message) 4079 end if 4080 do ii=4,9 4081 ngqpt(ii)=ngqpt(1) 4082 end do 4083 4084 ! Test the relevant inequalities 4085 nbord(1)=0 4086 do ii=4,9 4087 ! If the rpt vector is greater than the allowed space => weight = 0.0 4088 if (abs(rdiff(ii))-1.0d-10>factor*ngqpt(ii)) then 4089 wghatm(ia,ib,irpt)=zero 4090 else if (abs(abs(rdiff(ii))-factor*ngqpt(ii)) <=1.0d-10) then 4091 ! If the point is in a boundary position increment nbord(1) 4092 nbord(1)=nbord(1)+1 4093 end if 4094 end do 4095 4096 ! Computation of weights 4097 if (nbord(1)==1) then 4098 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/2 4099 else if (nbord(1)==2) then 4100 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/3 4101 else if (nbord(1)==3) then 4102 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/4 4103 else if (nbord(1)==4) then 4104 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/6 4105 else if (nbord(1)/=0) then 4106 message = ' There is a problem of borders and weights (BCC).' 4107 MSG_ERROR(message) 4108 end if 4109 4110 ! FCC packing of k-points 4111 else if(nqshft==4 .and. brav/=4)then 4112 4113 ! First, generate the relevant boundaries 4114 rdiff(4)= (rdiff(1)+rdiff(2)+rdiff(3))*2._dp/3._dp 4115 rdiff(5)= (rdiff(1)-rdiff(2)+rdiff(3))*2._dp/3._dp 4116 rdiff(6)= (rdiff(1)+rdiff(2)-rdiff(3))*2._dp/3._dp 4117 rdiff(7)= (rdiff(1)-rdiff(2)-rdiff(3))*2._dp/3._dp 4118 if(ngqpt(2)/=ngqpt(1) .or. ngqpt(3)/=ngqpt(1))then 4119 write(message, '(a,a,a,3i6,a,a,a,a)' )& 4120 & 'In the FCC case, the three ngqpt numbers ',ch10,& 4121 & ' ',ngqpt(1),ngqpt(2),ngqpt(3),ch10,& 4122 & 'should be equal.',ch10,& 4123 & 'Action: use identical ngqpt(1:3) in your input file.' 4124 MSG_ERROR(message) 4125 end if 4126 do ii=4,7 4127 ngqpt(ii)=ngqpt(1) 4128 end do 4129 4130 ! Test the relevant inequalities 4131 nbord(1)=0 4132 do ii=1,7 4133 4134 ! If the rpt vector is greater than the allowed space => weight = 0.0 4135 if (abs(rdiff(ii))-1.0d-10>factor*ngqpt(ii)) then 4136 wghatm(ia,ib,irpt)=zero 4137 ! If the point is in a boundary position increment nbord(1) 4138 else if (abs(abs(rdiff(ii))-factor*ngqpt(ii)) <=1.0d-10) then 4139 nbord(1)=nbord(1)+1 4140 end if 4141 end do 4142 4143 ! Computation of weights 4144 if (nbord(1)==1) then 4145 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/2 4146 else if (nbord(1)==2) then 4147 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/3 4148 else if (nbord(1)==3) then 4149 wghatm(ia,ib,irpt)=wghatm(ia,ib,irpt)/4 4150 else if (nbord(1)/=0 .and. wghatm(ia,ib,irpt)>1.d-10) then 4151 ! Interestingly nbord(1)==4 happens for some points outside of the volume 4152 message = ' There is a problem of borders and weights (FCC).' 4153 MSG_BUG(message) 4154 end if 4155 4156 else 4157 write(message, '(3a,i0,a)' )& 4158 & 'One should not arrive here ... ',ch10,& 4159 & 'The value nqshft ',nqshft,' is not available' 4160 MSG_BUG(message) 4161 end if 4162 end do ! Assignement of weights is done 4163 4164 end do ! End of the double loop on ia and ib 4165 end do 4166 4167 ! Check the results 4168 do ia=1,natom 4169 do ib=1,natom 4170 sumwght=zero 4171 do irpt=1,nrpt 4172 ! Check if the sum of the weights is equal to the number of q points 4173 sumwght=sumwght+wghatm(ia,ib,irpt) 4174 ! write(std_out,'(a,3i5)' )' atom1, atom2, irpt ; rpt ; wghatm ',ia,ib,irpt 4175 ! write(std_out,'(3es16.6,es18.6)' )& 4176 ! & rpt(1,irpt),rpt(2,irpt),rpt(3,irpt),wghatm(ia,ib,irpt) 4177 end do 4178 if (abs(sumwght-nqpt)>tol10) then 4179 write(message, '(a,a,a,2i4,a,a,es14.4,a,a,i4)' )& 4180 & 'The sum of the weight is not equal to nqpt.',ch10,& 4181 & 'atoms :',ia,ib,ch10,& 4182 & 'The sum of the weights is : ',sumwght,ch10,& 4183 & 'The number of q points is : ',nqpt 4184 call wrtout(std_out,message,'COLL') 4185 write(message, '(13a)')& 4186 & 'This might have several sources.',ch10,& 4187 & 'If tolsym is larger than 1.0e-8, the atom positions might be loose',ch10,& 4188 & 'and the q point weights not computed properly.',ch10,& 4189 & 'Action: make input atomic positions more symmetric.',ch10,& 4190 & 'Otherwise, you might increase "buffer" in m_dynmat.F90 see bigbx9 subroutine, and recompile.',ch10,& 4191 & 'Actually, this can also happen when ngqpt is 0 0 0,',ch10,& 4192 & 'if abs(brav)/=1, in which case you should change brav to 1.' 4193 MSG_BUG(message) 4194 end if 4195 end do 4196 end do 4197 4198 DBG_EXIT("COLL") 4199 4200 end subroutine wght9
m_dynmat/wings3 [ Functions ]
[ Top ] [ m_dynmat ] [ Functions ]
NAME
wings3
FUNCTION
Suppress the wings of the cartesian 2DTE for which the diagonal element is not known
INPUTS
carflg(3,mpert,3,mpert)= ( 1 if the element of the cartesian 2DTE matrix has been calculated correctly ; 0 otherwise ) d2cart(2,3,mpert,3,mpert)= dynamical matrix, effective charges, dielectric tensor,.... all in cartesian coordinates mpert =maximum number of ipert
OUTPUT
d2cart(2,3,mpert,3,mpert) without the wings
PARENTS
respfn
CHILDREN
SOURCE
2383 subroutine wings3(carflg,d2cart,mpert) 2384 2385 2386 !This section has been created automatically by the script Abilint (TD). 2387 !Do not modify the following lines by hand. 2388 #undef ABI_FUNC 2389 #define ABI_FUNC 'wings3' 2390 !End of the abilint section 2391 2392 implicit none 2393 2394 !Arguments ------------------------------- 2395 !scalars 2396 integer,intent(in) :: mpert 2397 !arrays 2398 integer,intent(inout) :: carflg(3,mpert,3,mpert) 2399 real(dp),intent(inout) :: d2cart(2,3,mpert,3,mpert) 2400 2401 !Local variables ------------------------- 2402 !scalars 2403 integer :: idir,idir1,ipert,ipert1 2404 2405 ! ********************************************************************* 2406 2407 do ipert=1,mpert 2408 do idir=1,3 2409 if(carflg(idir,ipert,idir,ipert)==0)then 2410 do ipert1=1,mpert 2411 do idir1=1,3 2412 carflg(idir,ipert,idir1,ipert1)=0 2413 carflg(idir1,ipert1,idir,ipert)=0 2414 d2cart(1,idir,ipert,idir1,ipert1)=zero 2415 d2cart(2,idir,ipert,idir1,ipert1)=zero 2416 d2cart(1,idir1,ipert1,idir,ipert)=zero 2417 d2cart(2,idir1,ipert1,idir,ipert)=zero 2418 end do 2419 end do 2420 end if 2421 end do 2422 end do 2423 2424 end subroutine wings3