TABLE OF CONTENTS
ABINIT/symlatt [ Functions ]
NAME
symlatt
FUNCTION
From the unit cell vectors (rprimd) and the corresponding metric tensor, find the Bravais lattice and its symmetry operations (ptsymrel). 1) Find the shortest possible primitive vectors for the lattice 2) Determines the holohedral group of the lattice, and the axes to be used for the conventional cell (this is a delicate part, in which the centering of the reduced cell must be taken into account) The idea is to determine the basis vectors of the conventional cell from the reduced cell basis vectors. 3) Generate the symmetry operations of the holohedral group
COPYRIGHT
Copyright (C) 2000-2018 ABINIT group (XG) This file is distributed under the terms of the GNU General Public License, see ~abinit/COPYING or http://www.gnu.org/copyleft/gpl.txt . For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
INPUTS
msym=default maximal number of symmetries rprimd(3,3)=dimensional primitive translations for real space (bohr) tolsym=tolerance for the symmetries
OUTPUT
bravais(11): bravais(1)=iholohedry bravais(2)=center bravais(3:11)=coordinates of rprim in the axes of the conventional bravais lattice (*2 if center/=0) nptsym=number of point symmetries of the Bravais lattice ptsymrel(3,3,1:msym)= nptsym point-symmetry operations of the Bravais lattice in real space in terms of primitive translations.
NOTES
WARNING: bravais(1) might be given a negative value in another routine, if the cell is non-primitive. The holohedral groups are numbered as follows (see international tables for crystallography (1983), p. 13) iholohedry=1 triclinic 1bar iholohedry=2 monoclinic 2/m iholohedry=3 orthorhombic mmm iholohedry=4 tetragonal 4/mmm iholohedry=5 trigonal 3bar m iholohedry=6 hexagonal 6/mmm iholohedry=7 cubic m3bar m Centering center=0 no centering center=-1 body-centered center=-3 face-centered center=1 A-face centered center=2 B-face centered center=3 C-face centered
PARENTS
ingeo,inqpt,m_ab7_symmetry,m_effective_potential_file,m_tdep_sym m_use_ga,symanal,symbrav,thmeig
CHILDREN
holocell,matr3inv,smallprim,symrelrot,wrtout
SOURCE
69 #if defined HAVE_CONFIG_H 70 #include "config.h" 71 #endif 72 73 #include "abi_common.h" 74 75 76 subroutine symlatt(bravais,msym,nptsym,ptsymrel,rprimd,tolsym) 77 78 use defs_basis 79 use m_errors 80 use m_profiling_abi 81 82 !This section has been created automatically by the script Abilint (TD). 83 !Do not modify the following lines by hand. 84 #undef ABI_FUNC 85 #define ABI_FUNC 'symlatt' 86 use interfaces_14_hidewrite 87 use interfaces_32_util 88 use interfaces_41_geometry, except_this_one => symlatt 89 !End of the abilint section 90 91 implicit none 92 93 !Arguments ------------------------------------ 94 !scalars 95 integer,intent(in) :: msym 96 integer,intent(out) :: nptsym 97 real(dp),intent(in) :: tolsym 98 !arrays 99 integer,intent(out) :: bravais(11),ptsymrel(3,3,msym) 100 real(dp),intent(in) :: rprimd(3,3) 101 102 !Local variables------------------------------- 103 !scalars 104 integer,parameter :: mgen=4 105 integer :: center,fact,found,foundc,ia,ib,icase,igen,iholohedry,ii,index,isym 106 integer :: itrial,jj,jsym,ngen=0,orthogonal,sign12,sign13,sign23,sumsign 107 real(dp) :: determinant,norm2a,norm2b,norm2c,norm2trial,reduceda,reducedb,sca 108 real(dp) :: scalarprod,scb,trace,val 109 character(len=500) :: message 110 !arrays 111 integer,parameter :: list_holo(7)=(/7,6,4,3,5,2,1/) 112 integer :: ang90(3),equal(3),gen(3,3,mgen),gen2xy(3,3),gen2y(3,3),gen2z(3,3) 113 integer :: gen3(3,3),gen6(3,3),icoord(3,3),identity(3,3),nvecta(3),nvectb(3) 114 integer :: order(mgen) 115 real(dp) :: axes(3,3),axesinvt(3,3),cell_base(3,3),coord(3,3),metmin(3,3) 116 real(dp) :: minim(3,3),scprods(3,3),vecta(3),vectb(3),vectc(3),vin1(3),vin2(3),vext(3) 117 118 !************************************************************************** 119 120 identity(:,:)=0 ; identity(1,1)=1 ; identity(2,2)=1 ; identity(3,3)=1 121 nvecta(1)=2 ; nvectb(1)=3 122 nvecta(2)=1 ; nvectb(2)=3 123 nvecta(3)=1 ; nvectb(3)=2 124 125 !-------------------------------------------------------------------------- 126 !Reduce the input vectors to a set of minimal vectors 127 call smallprim(metmin,minim,rprimd) 128 129 !DEBUG 130 !write(std_out,*)' symlatt : minim(:,1)=',minim(:,1) 131 !write(std_out,*)' symlatt : minim(:,2)=',minim(:,2) 132 !write(std_out,*)' symlatt : minim(:,3)=',minim(:,3) 133 !ENDDEBUG 134 135 !-------------------------------------------------------------------------- 136 !Examine the angles and vector lengths 137 ang90(:)=0 138 if(metmin(1,2)**2<tolsym**2*metmin(1,1)*metmin(2,2))ang90(3)=1 139 if(metmin(1,3)**2<tolsym**2*metmin(1,1)*metmin(3,3))ang90(2)=1 140 if(metmin(2,3)**2<tolsym**2*metmin(2,2)*metmin(3,3))ang90(1)=1 141 equal(:)=0 142 if(abs(metmin(1,1)-metmin(2,2))<tolsym*half*(metmin(1,1)+metmin(2,2)))equal(3)=1 143 if(abs(metmin(1,1)-metmin(3,3))<tolsym*half*(metmin(1,1)+metmin(3,3)))equal(2)=1 144 if(abs(metmin(2,2)-metmin(3,3))<tolsym*half*(metmin(2,2)+metmin(3,3)))equal(1)=1 145 146 !DEBUG 147 !write(std_out,*)' ang90=',ang90(:) 148 !write(std_out,*)' equal=',equal(:) 149 !ENDDEBUG 150 151 !----------------------------------------------------------------------- 152 !Identification of the centering 153 154 foundc=0 155 !Default values 156 fact=1 ; center=0 157 cell_base(:,:)=minim(:,:) 158 159 !Examine each holohedral group 160 !This search is ordered : should not be happy with tetragonal, 161 !while there is FCC ... 162 do index=1,6 163 164 ! If the holohedry is already found, exit 165 if(foundc==1)exit 166 167 ! Initialize the target holohedry 168 iholohedry=list_holo(index) 169 170 ! DEBUG 171 ! write(std_out,*)' symlatt : trial holohedry',iholohedry 172 ! ENDDEBUG 173 174 orthogonal=0 175 if(iholohedry==7 .or. iholohedry==4 .or. iholohedry==3)orthogonal=1 176 177 ! Now, will examine different working hypothesis. 178 ! The set of these hypothesis is thought to cover all possible cases ... 179 180 ! Working hypothesis : the basis is orthogonal 181 if(ang90(1)+ang90(2)+ang90(3)==3 .and. orthogonal==1)then 182 fact=1 ; center=0 183 cell_base(:,:)=minim(:,:) 184 ! Checks that the basis vectors are OK for the target holohedry 185 call holocell(cell_base,0,foundc,iholohedry,tolsym) 186 end if 187 188 ! Select one trial direction 189 do itrial=1,3 190 191 ! If the holohedry is already found, exit 192 if(foundc==1)exit 193 194 ia=nvecta(itrial) ; ib=nvectb(itrial) 195 196 ! This is in case of hexagonal holohedry 197 if(foundc==0 .and. iholohedry==6 .and. ang90(ia)==1 .and. ang90(ib)==1 .and. equal(itrial)==1 )then 198 reduceda=metmin(ib,ia)/metmin(ia,ia) 199 fact=1 ; center=0 200 if(abs(reduceda+0.5d0)<tolsym)then 201 cell_base(:,1)=minim(:,ia) 202 cell_base(:,2)=minim(:,ib) 203 cell_base(:,3)=minim(:,itrial) 204 ! Checks that the basis vectors are OK for the target holohedry 205 call holocell(cell_base,0,foundc,iholohedry,tolsym) 206 else if(abs(reduceda-0.5d0)<tolsym)then 207 cell_base(:,1)=minim(:,ia) 208 cell_base(:,2)=minim(:,ib)-minim(:,ia) 209 cell_base(:,3)=minim(:,itrial) 210 ! Checks that the basis vectors are OK for the target holohedry 211 call holocell(cell_base,0,foundc,iholohedry,tolsym) 212 end if 213 end if 214 215 ! Working hypothesis : the conventional cell is orthogonal, 216 ! and the two other vectors are axes of the conventional cell 217 if(foundc==0 .and. orthogonal==1 .and. ang90(itrial)==1)then 218 219 ! Compute the reduced coordinate of trial vector in the basis 220 ! of the two other vectors 221 reduceda=metmin(itrial,ia)/metmin(ia,ia) 222 reducedb=metmin(itrial,ib)/metmin(ib,ib) 223 cell_base(:,ia)=minim(:,ia) 224 cell_base(:,ib)=minim(:,ib) 225 if( (abs(abs(reduceda)-0.5d0)<tolsym .and. abs(reducedb)<tolsym ) .or. & 226 & ( abs(reduceda)<tolsym .and. abs(abs(reducedb)-0.5d0)<tolsym) )then 227 if(abs(abs(reduceda)-0.5d0)<tolsym)center=ib 228 if(abs(abs(reducedb)-0.5d0)<tolsym)center=ia 229 fact=2 230 cell_base(:,itrial)= & 231 & (minim(:,itrial)-reduceda*minim(:,ia)-reducedb*minim(:,ib) )*2.0d0 232 call holocell(cell_base,0,foundc,iholohedry,tolsym) 233 else if( abs(abs(reduceda)-0.5d0)<tolsym .and.& 234 & abs(abs(reducedb)-0.5d0)<tolsym ) then 235 fact=2 ; center=-1 236 cell_base(:,itrial)= & 237 & (minim(:,itrial)-reduceda*minim(:,ia)-reducedb*minim(:,ib) )*2.0d0 238 call holocell(cell_base,0,foundc,iholohedry,tolsym) 239 end if 240 end if 241 242 ! Working hypothesis : the conventional cell is orthogonal, and 243 ! the trial vector is one of the future axes, and the face perpendicular to it is centered 244 if(foundc==0 .and. iholohedry==3 .and. & 245 & ang90(ia)==1 .and. ang90(ib)==1 .and. equal(itrial)==1 )then 246 fact=2 ; center=itrial 247 cell_base(:,ia)=minim(:,ia)+minim(:,ib) 248 cell_base(:,ib)=minim(:,ia)-minim(:,ib) 249 cell_base(:,itrial)=minim(:,itrial) 250 ! Checks that the basis vectors are OK for the target holohedry 251 call holocell(cell_base,0,foundc,iholohedry,tolsym) 252 end if 253 254 ! DEBUG 255 ! write(std_out,*)' after test_b, foundc=',foundc 256 ! ENDDEBUG 257 258 ! Working hypothesis : the conventional cell is orthogonal, and 259 ! the trial vector is one of the future axes 260 if(foundc==0 .and. orthogonal==1)then 261 ! Compute the projection of the two other vectors on the trial vector 262 reduceda=metmin(itrial,ia)/metmin(itrial,itrial) 263 reducedb=metmin(itrial,ib)/metmin(itrial,itrial) 264 ! If both projections are half-integer, one might have found an axis 265 if( abs(abs(reduceda)-0.5d0)<tolsym .and.& 266 & abs(abs(reducedb)-0.5d0)<tolsym ) then 267 vecta(:)=minim(:,ia)-reduceda*minim(:,itrial) 268 vectb(:)=minim(:,ib)-reducedb*minim(:,itrial) 269 norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2 270 norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2 271 scalarprod=vecta(1)*vectb(1)+vecta(2)*vectb(2)+vecta(3)*vectb(3) 272 ! Note the order of selection : body-centered is prefered 273 ! over face centered, which is correct for the tetragonal case 274 if(abs(norm2a-norm2b)<tolsym*half*(norm2a+norm2b))then 275 ! The lattice is body centered 276 fact=2 ; center=-1 277 cell_base(:,ia)=vecta(:)+vectb(:) 278 cell_base(:,ib)=vecta(:)-vectb(:) 279 cell_base(:,itrial)=minim(:,itrial) 280 call holocell(cell_base,0,foundc,iholohedry,tolsym) 281 else if(abs(scalarprod)<tolsym*half*(norm2a+norm2b))then 282 ! The lattice is face centered 283 fact=2 ; center=-3 284 cell_base(:,ia)=2.0d0*vecta(:) 285 cell_base(:,ib)=2.0d0*vectb(:) 286 cell_base(:,itrial)=minim(:,itrial) 287 call holocell(cell_base,0,foundc,iholohedry,tolsym) 288 end if 289 end if 290 end if 291 292 ! DEBUG 293 ! write(std_out,*)' after test_c, foundc=',foundc 294 ! ENDDEBUG 295 296 ! Working hypothesis : the conventional cell is orthogonal, 297 ! and body centered with no basis vector being an axis, 298 ! in which case the basis vectors must be equal (even for orthorhombic) 299 if(foundc==0 .and. orthogonal==1 .and. & 300 & equal(1)==1 .and. equal(2)==1 .and. equal(3)==1 )then 301 ! Compute the combination of the two other vectors 302 vecta(:)=minim(:,ia)+minim(:,ib) 303 vectb(:)=minim(:,ia)-minim(:,ib) 304 norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2 305 norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2 306 ! Project the trial vector on the first of the two vectors 307 reduceda=( minim(1,itrial)*vecta(1)+ & 308 & minim(2,itrial)*vecta(2)+ & 309 & minim(3,itrial)*vecta(3) )/norm2a 310 reducedb=( minim(1,itrial)*vectb(1)+ & 311 & minim(2,itrial)*vectb(2)+ & 312 & minim(3,itrial)*vectb(3) )/norm2b 313 if( abs(abs(reduceda)-0.5d0)<tolsym )then 314 ! The first vector is an axis 315 fact=2 ; center=-1 316 cell_base(:,ia)=vecta(:) 317 vecta(:)=minim(:,itrial)-reduceda*vecta(:) 318 vectb(:)=0.5d0*vectb(:) 319 cell_base(:,ib)=vecta(:)+vectb(:) 320 cell_base(:,itrial)=vecta(:)-vectb(:) 321 call holocell(cell_base,0,foundc,iholohedry,tolsym) 322 else if( abs(abs(reducedb)-0.5d0)<tolsym )then 323 ! The second vector is an axis 324 fact=2 ; center=-1 325 cell_base(:,ib)=vectb(:) 326 vectb(:)=minim(:,itrial)-reducedb*vectb(:) 327 vecta(:)=0.5d0*vecta(:) 328 cell_base(:,ia)=vectb(:)+vecta(:) 329 cell_base(:,itrial)=vectb(:)-vecta(:) 330 call holocell(cell_base,0,foundc,iholohedry,tolsym) 331 end if 332 end if 333 334 ! Working hypothesis : the conventional cell is orthogonal, 335 ! and face centered, in the case where two minimal vectors are equal 336 if(foundc==0 .and. orthogonal==1 .and. equal(itrial)==1 ) then 337 ! Compute the combination of these two vectors 338 vecta(:)=minim(:,ia)+minim(:,ib) 339 vectb(:)=minim(:,ia)-minim(:,ib) 340 norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2 341 norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2 342 ! Project the trial vector on the two vectors 343 reduceda=( minim(1,itrial)*vecta(1)+ & 344 & minim(2,itrial)*vecta(2)+ & 345 & minim(3,itrial)*vecta(3) )/norm2a 346 reducedb=( minim(1,itrial)*vectb(1)+ & 347 & minim(2,itrial)*vectb(2)+ & 348 & minim(3,itrial)*vectb(3) )/norm2b 349 if( (abs(abs(reduceda)-0.5d0)<tolsym .and. abs(reducedb)<tolsym ) .or. & 350 & ( abs(reduceda)<tolsym .and. abs(abs(reducedb)-0.5d0)<tolsym) )then 351 fact=2 ; center=-3 352 cell_base(:,itrial)= & 353 & (minim(:,itrial)-reduceda*vecta(:)-reducedb*vectb(:) )*2.0d0 354 cell_base(:,ia)=vecta(:) 355 cell_base(:,ib)=vectb(:) 356 call holocell(cell_base,0,foundc,iholohedry,tolsym) 357 end if 358 end if 359 360 ! Working hypothesis : the conventional cell is orthogonal, 361 ! face centered, but no two vectors are on the same "square" 362 if(foundc==0 .and. orthogonal==1)then 363 ! Compute the combination of these two vectors 364 vecta(:)=minim(:,ia)+minim(:,ib) 365 vectb(:)=minim(:,ia)-minim(:,ib) 366 norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2 367 norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2 368 ! The trial vector length must be equal to one of these lengths 369 if(abs(metmin(itrial,itrial)-norm2a)<tolsym*norm2a)then 370 fact=2 ; center=-3 371 cell_base(:,ia)=vecta(:)+minim(:,itrial) 372 cell_base(:,ib)=vecta(:)-minim(:,itrial) 373 ! Project vectb perpendicular to cell_base(:,ia) and cell_base(:,ib) 374 norm2a=cell_base(1,ia)**2+cell_base(2,ia)**2+cell_base(3,ia)**2 375 norm2b=cell_base(1,ib)**2+cell_base(2,ib)**2+cell_base(3,ib)**2 376 reduceda=( cell_base(1,ia)*vectb(1)+ & 377 & cell_base(2,ia)*vectb(2)+ & 378 & cell_base(3,ia)*vectb(3) )/norm2a 379 reducedb=( cell_base(1,ib)*vectb(1)+ & 380 & cell_base(2,ib)*vectb(2)+ & 381 & cell_base(3,ib)*vectb(3) )/norm2b 382 if( abs(abs(reduceda)-0.5d0)<tolsym .and. & 383 & abs(abs(reducedb)-0.5d0)<tolsym )then 384 cell_base(:,itrial)=vectb(:)-reduceda*cell_base(:,ia)-reducedb*cell_base(:,ib) 385 call holocell(cell_base,0,foundc,iholohedry,tolsym) 386 end if 387 else if(abs(metmin(itrial,itrial)-norm2b)<tolsym*norm2b)then 388 fact=2 ; center=-3 389 cell_base(:,ia)=vectb(:)+minim(:,itrial) 390 cell_base(:,ib)=vectb(:)-minim(:,itrial) 391 ! Project vecta perpendicular to cell_base(:,ia) and cell_base(:,ib) 392 norm2a=cell_base(1,ia)**2+cell_base(2,ia)**2+cell_base(3,ia)**2 393 norm2b=cell_base(1,ib)**2+cell_base(2,ib)**2+cell_base(3,ib)**2 394 reduceda=( cell_base(1,ia)*vecta(1)+ & 395 & cell_base(2,ia)*vecta(2)+ & 396 & cell_base(3,ia)*vecta(3) )/norm2a 397 reducedb=( cell_base(1,ib)*vecta(1)+ & 398 & cell_base(2,ib)*vecta(2)+ & 399 & cell_base(3,ib)*vecta(3) )/norm2b 400 if( abs(abs(reduceda)-0.5d0)<tolsym .and. & 401 & abs(abs(reducedb)-0.5d0)<tolsym )then 402 cell_base(:,itrial)=vecta(:)-reduceda*cell_base(:,ia)-reducedb*cell_base(:,ib) 403 call holocell(cell_base,0,foundc,iholohedry,tolsym) 404 end if 405 end if 406 end if 407 408 ! Working hypothesis : the cell is rhombohedral, and 409 ! the three minimal vectors have same length and same absolute scalar product 410 if(foundc==0 .and. iholohedry==5 .and. & 411 & equal(1)==1 .and. equal(2)==1 .and. equal(3)==1 )then 412 if( abs(abs(metmin(1,2))-abs(metmin(1,3)))<tolsym*metmin(1,1) .and. & 413 & abs(abs(metmin(1,2))-abs(metmin(2,3)))<tolsym*metmin(2,2) )then 414 fact=1 ; center=0 415 cell_base(:,:)=minim(:,:) 416 ! One might have to change the sign of one of the vectors 417 sign12=1 ; sign13=1 ; sign23=1 418 if(metmin(1,2)<0.0d0)sign12=-1 419 if(metmin(1,3)<0.0d0)sign13=-1 420 if(metmin(2,3)<0.0d0)sign23=-1 421 sumsign=sign12+sign13+sign23 422 if(sumsign==-1)then 423 if(sign12==1)cell_base(:,3)=-cell_base(:,3) 424 if(sign13==1)cell_base(:,2)=-cell_base(:,2) 425 if(sign23==1)cell_base(:,1)=-cell_base(:,1) 426 else if(sumsign==1)then 427 if(sign12==-1)cell_base(:,3)=-cell_base(:,3) 428 if(sign13==-1)cell_base(:,2)=-cell_base(:,2) 429 if(sign23==-1)cell_base(:,1)=-cell_base(:,1) 430 end if 431 call holocell(cell_base,0,foundc,iholohedry,tolsym) 432 end if 433 end if 434 435 ! DEBUG 436 ! write(std_out,*)' after test_3a, foundc=',foundc 437 ! write(std_out,*)' after test_3a, itrial=',itrial 438 ! write(std_out,*)' after test_3a, equal(:)=',equal(:) 439 ! ENDDEBUG 440 441 ! Working hypothesis : the cell is rhombohedral, one vector 442 ! is parallel to the trigonal axis 443 if(foundc==0 .and. iholohedry==5 .and. equal(itrial)==1 )then 444 vecta(:)=minim(:,ia) ; vectb(:)=minim(:,ib) 445 norm2trial=minim(1,itrial)**2+minim(2,itrial)**2+minim(3,itrial)**2 446 reduceda=( minim(1,itrial)*vecta(1)+ & 447 & minim(2,itrial)*vecta(2)+ & 448 & minim(3,itrial)*vecta(3) )/norm2trial 449 reducedb=( minim(1,itrial)*vectb(1)+ & 450 & minim(2,itrial)*vectb(2)+ & 451 & minim(3,itrial)*vectb(3) )/norm2trial 452 ! DEBUG 453 ! write(std_out,*)' reduceda,reducedb=',reduceda,reducedb 454 ! ENDDEBUG 455 if(abs(abs(reduceda)-1.0d0/3.0d0)<tolsym .and. & 456 & abs(abs(reducedb)-1.0d0/3.0d0)<tolsym ) then 457 ! Possibly change of sign to make positive the scalar product with 458 ! the vector parallel to the trigonal axis 459 if(reduceda<zero)vecta(:)=-vecta(:) 460 if(reducedb<zero)vectb(:)=-vectb(:) 461 ! Projection on the orthogonal plane 462 vecta(:)=vecta(:)-abs(reduceda)*cell_base(:,itrial) 463 vectb(:)=vectb(:)-abs(reducedb)*cell_base(:,itrial) 464 ! These two vectors should have an angle of 120 degrees 465 norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2 466 scalarprod=vecta(1)*vectb(1)+vecta(2)*vectb(2)+vecta(3)*vectb(3) 467 ! DEBUG 468 ! write(std_out,*)' norm2a,scalarprod=',norm2a,scalarprod 469 ! ENDDEBUG 470 if(abs(two*scalarprod+norm2a)<tolsym*norm2a)then 471 fact=1 ; center=0 472 if(scalarprod>0.0d0)vectb(:)=-vectb(:) 473 ! Now vecta and vectb have an angle of 120 degrees 474 cell_base(:,1)=cell_base(:,itrial)/3.0d0+vecta(:) 475 cell_base(:,2)=cell_base(:,itrial)/3.0d0+vectb(:) 476 cell_base(:,3)=cell_base(:,itrial)/3.0d0-vecta(:)-vectb(:) 477 ! DEBUG 478 ! write(std_out,*)' cell_base(:,1)=',cell_base(:,1) 479 ! write(std_out,*)' cell_base(:,2)=',cell_base(:,2) 480 ! write(std_out,*)' cell_base(:,3)=',cell_base(:,3) 481 ! ENDDEBUG 482 call holocell(cell_base,0,foundc,iholohedry,tolsym) 483 end if 484 end if 485 end if 486 487 ! Working hypothesis : the cell is rhombohedral, one vector 488 ! is in the plane perpendicular to the trigonal axis 489 if(foundc==0 .and. iholohedry==5 .and. equal(itrial)==1 ) then 490 vecta(:)=minim(:,ia)+minim(:,ib) 491 vectb(:)=minim(:,ia)-minim(:,ib) 492 norm2trial=cell_base(1,itrial)**2+cell_base(2,itrial)**2+cell_base(3,itrial)**2 493 norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2 494 norm2b=vecta(1)**2+vecta(2)**2+vecta(3)**2 495 reduceda=( cell_base(1,itrial)*vecta(1)+ & 496 & cell_base(2,itrial)*vecta(2)+ & 497 & cell_base(3,itrial)*vecta(3) )/norm2trial 498 reducedb=( cell_base(1,itrial)*vectb(1)+ & 499 & cell_base(2,itrial)*vectb(2)+ & 500 & cell_base(3,itrial)*vectb(3) )/norm2trial 501 if(abs(norm2trial-norm2a)<tolsym*norm2a .and. & 502 & abs(abs(2*reduceda)-norm2trial)<tolsym*norm2trial )then 503 fact=1 ; center=0 504 cell_base(:,1)=minim(:,ia) 505 cell_base(:,2)=-minim(:,ib) 506 cell_base(:,3)=-minim(:,ib)+2*reduceda*minim(:,itrial) 507 call holocell(cell_base,0,foundc,iholohedry,tolsym) 508 else if (abs(norm2trial-norm2b)<tolsym*norm2b .and. & 509 & abs(abs(2*reducedb)-norm2trial)<tolsym*norm2trial )then 510 fact=1 ; center=0 511 cell_base(:,1)=minim(:,ia) 512 cell_base(:,2)=minim(:,ib) 513 cell_base(:,3)=minim(:,ib)+2*reducedb*minim(:,itrial) 514 call holocell(cell_base,0,foundc,iholohedry,tolsym) 515 end if 516 end if 517 518 ! Working hypothesis : the cell is rhombohedral, two vectors 519 ! are in the plane perpendicular to the trigonal axis 520 if(foundc==0 .and. iholohedry==5 .and. equal(itrial)==1 ) then 521 vecta(:)=minim(:,ia) ; vectb(:)=minim(:,ib) 522 norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2 523 norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2 524 scalarprod=vecta(1)*vectb(1)+vecta(2)*vectb(2)+vecta(3)*vectb(3) 525 if(abs(abs(2*scalarprod)-norm2a)<tolsym*norm2a)then 526 ! This is in order to have 120 angle between vecta and vectb 527 if(scalarprod>0.0d0)vectb(:)=-vectb(:) 528 reduceda=( cell_base(1,itrial)*vecta(1)+ & 529 & cell_base(2,itrial)*vecta(2)+ & 530 & cell_base(3,itrial)*vecta(3) )/norm2a 531 reducedb=( cell_base(1,itrial)*vectb(1)+ & 532 & cell_base(2,itrial)*vectb(2)+ & 533 & cell_base(3,itrial)*vectb(3) )/norm2b 534 fact=1 ; center=0 535 cell_base(:,1)=minim(:,itrial) 536 if(abs(reduceda-0.5d0)<tolsym .and. abs(reducedb)<tolsym )then 537 cell_base(:,2)=minim(:,itrial)-vecta(:) 538 cell_base(:,3)=minim(:,itrial)-vecta(:)-vectb(:) 539 call holocell(cell_base,0,foundc,iholohedry,tolsym) 540 else if(abs(reduceda-0.5d0)<tolsym.and. abs(reducedb+0.5d0)<tolsym )then 541 cell_base(:,2)=minim(:,itrial)-vecta(:) 542 cell_base(:,3)=minim(:,itrial)+vectb(:) 543 call holocell(cell_base,0,foundc,iholohedry,tolsym) 544 else if(abs(reduceda)<tolsym .and. abs(reducedb+0.5d0)<tolsym )then 545 cell_base(:,2)=minim(:,itrial)+vectb(:) 546 cell_base(:,3)=minim(:,itrial)+vecta(:)+vectb(:) 547 call holocell(cell_base,0,foundc,iholohedry,tolsym) 548 else if(abs(reduceda+0.5d0)<tolsym .and. abs(reducedb)<tolsym)then 549 cell_base(:,2)=minim(:,itrial)+vecta(:) 550 cell_base(:,3)=minim(:,itrial)+vecta(:)+vectb(:) 551 call holocell(cell_base,0,foundc,iholohedry,tolsym) 552 else if(abs(reduceda+0.5d0)<tolsym .and. abs(reducedb-0.5d0)<tolsym)then 553 cell_base(:,2)=minim(:,itrial)+vecta(:) 554 cell_base(:,3)=minim(:,itrial)-vectb(:) 555 call holocell(cell_base,0,foundc,iholohedry,tolsym) 556 else if(abs(reduceda)<tolsym .and. abs(reducedb-0.5d0)<tolsym )then 557 cell_base(:,2)=minim(:,itrial)-vectb(:) 558 cell_base(:,3)=minim(:,itrial)-vecta(:)-vectb(:) 559 call holocell(cell_base,0,foundc,iholohedry,tolsym) 560 end if 561 end if 562 end if 563 564 ! Working hypothesis : monoclinic holohedry, primitive. Then, two angles are 90 degrees 565 if(foundc==0 .and. iholohedry==2 .and. & 566 & ang90(ia)==1 .and. ang90(ib)==1 ) then 567 fact=1 ; center=0 568 cell_base(:,1)=minim(:,ia) 569 cell_base(:,2)=minim(:,itrial) 570 cell_base(:,3)=minim(:,ib) 571 ! Checks that the basis vectors are OK for the target holohedry 572 call holocell(cell_base,0,foundc,iholohedry,tolsym) 573 end if 574 575 ! Monoclinic holohedry, one-face-centered cell 576 ! Working hypothesis, two vectors have equal length. 577 do icase=1,5 578 if(foundc==0 .and. iholohedry==2 .and. equal(itrial)==1 ) then 579 vecta(:)=cell_base(:,ia)+cell_base(:,ib) 580 vectb(:)=cell_base(:,ia)-cell_base(:,ib) 581 norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2 582 norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2 583 ! The minim(:,trial) vector belongs to the 584 ! plane parallel to the cell_base(:,ia),cell_base(:,ib) plane 585 ! In that plane, must try minim(:,itrial), 586 ! as well as the 4 different combinations of 587 ! minim(:,itrial) with the vectors in the plane 588 if(icase==1)vectc(:)=minim(:,itrial) 589 if(icase==2)vectc(:)=minim(:,itrial)+cell_base(:,ia) 590 if(icase==3)vectc(:)=minim(:,itrial)+cell_base(:,ib) 591 if(icase==4)vectc(:)=minim(:,itrial)-cell_base(:,ia) 592 if(icase==5)vectc(:)=minim(:,itrial)-cell_base(:,ib) 593 norm2c=vectc(1)**2+vectc(2)**2+vectc(3)**2 594 sca=vectc(1)*vecta(1)+& 595 & vectc(2)*vecta(2)+& 596 & vectc(3)*vecta(3) 597 scb=vectc(1)*vectb(1)+& 598 & vectc(2)*vectb(2)+& 599 & vectc(3)*vectb(3) 600 ! DEBUG 601 ! write(std_out,*)' symlatt : test iholohedry=2, sca,scb=',sca,scb 602 ! ENDDEBUG 603 if(abs(sca)<tolsym*sqrt(norm2c*norm2a) .or. abs(scb)<tolsym*sqrt(norm2c*norm2b))then 604 fact=2 ; center=3 605 ! The itrial direction is centered 606 cell_base(:,3)=vectc(:) 607 if(abs(sca)<tolsym*sqrt(norm2c*norm2a))then 608 cell_base(:,2)=vecta(:) 609 cell_base(:,1)=vectb(:) 610 call holocell(cell_base,0,foundc,iholohedry,tolsym) 611 else if(abs(scb)<tolsym*sqrt(norm2c*norm2b))then 612 cell_base(:,2)=vectb(:) 613 cell_base(:,1)=vecta(:) 614 call holocell(cell_base,0,foundc,iholohedry,tolsym) 615 end if 616 end if 617 end if 618 end do ! icase=1,5 619 620 ! Monoclinic holohedry, one-face-centered cell, but non equivalent. 621 ! This case, one pair of vectors is orthogonal 622 if(foundc==0 .and. iholohedry==2 .and. ang90(itrial)==1) then 623 vecta(:)=minim(:,ia) 624 vectb(:)=minim(:,ib) 625 norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2 626 norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2 627 ! Project the trial vector on the two vectors 628 reduceda=( minim(1,itrial)*vecta(1)+ & 629 & minim(2,itrial)*vecta(2)+ & 630 & minim(3,itrial)*vecta(3) )/norm2a 631 reducedb=( minim(1,itrial)*vectb(1)+ & 632 & minim(2,itrial)*vectb(2)+ & 633 & minim(3,itrial)*vectb(3) )/norm2b 634 if(abs(abs(reduceda)-0.5d0)<tolsym .or. abs(abs(reducedb)-0.5d0)<tolsym) then 635 fact=2 ; center=3 636 if(abs(abs(reduceda)-0.5d0)<tolsym)then 637 cell_base(:,2)=vecta(:) 638 cell_base(:,3)=vectb(:) 639 cell_base(:,1)=2*(minim(:,itrial)-reduceda*vecta(:)) 640 call holocell(cell_base,0,foundc,iholohedry,tolsym) 641 else if(abs(abs(reducedb)-0.5d0)<tolsym)then 642 cell_base(:,2)=vectb(:) 643 cell_base(:,3)=vecta(:) 644 cell_base(:,1)=2*(minim(:,itrial)-reducedb*vectb(:)) 645 call holocell(cell_base,0,foundc,iholohedry,tolsym) 646 end if 647 end if 648 end if 649 650 ! Monoclinic holohedry, one-face-centered cell, but non equivalent. 651 ! This case, no pair of vectors is orthogonal, no pair of vector of equal lentgh 652 if(foundc==0 .and. iholohedry==2)then 653 ! Try to find a vector that belongs to the mediator plane, or the binary vector. 654 ! There must be one such vector, if centered monoclinic and no pair of vectors of equal length, 655 ! either among the three vectors, or among one of their differences or sums. 656 ! And there must be, among the two other vectors, one vector whose projection 657 ! on this vector is half the length of this vector. 658 vecta(:)=minim(:,ia) 659 vectb(:)=minim(:,ib) 660 ! Try the different possibilities for the vector on which the projection will be half ... 661 do ii=1,5 662 if(ii==1)vectc(:)=minim(:,itrial) 663 if(ii==2)vectc(:)=minim(:,itrial)+vecta(:) 664 if(ii==3)vectc(:)=minim(:,itrial)-vecta(:) 665 if(ii==4)vectc(:)=minim(:,itrial)+vectb(:) 666 if(ii==5)vectc(:)=minim(:,itrial)-vectb(:) 667 norm2trial=vectc(1)**2+vectc(2)**2+vectc(3)**2 668 ! Project the two vectors on the trial vector 669 reduceda=( vectc(1)*vecta(1)+vectc(2)*vecta(2)+vectc(3)*vecta(3) )/norm2trial 670 reducedb=( vectc(1)*vectb(1)+vectc(2)*vectb(2)+vectc(3)*vectb(3) )/norm2trial 671 found=0 672 if(abs(abs(reduceda)-0.5d0)<tolsym)then 673 vin1(:)=vectc(:) 674 vin2(:)=2.0d0*(vecta(:)-reduceda*vectc(:)) 675 vext(:)=vectb(:) 676 found=1 677 else if(abs(abs(reducedb)-0.5d0)<tolsym)then 678 vin1(:)=vectc(:) 679 vin2(:)=2.0d0*(vectb(:)-reduceda*vectc(:)) 680 vext(:)=vecta(:) 681 found=1 682 end if 683 if(found==1)exit 684 end do 685 ! Now, vin1 and vin2 are perpendicular to each other, and in the plane that contains the binary vector. 686 ! One of them must be the binary vector if any. 687 ! On the other hand, vext is out-of-plane. Might belong to the mediator plane or not. 688 ! If C monoclinc, then the projection of this vext on the binary vector will be either 0 or +1/2 or -1/2. 689 ! The binary axis must be stored in cell_base(:,2) for conventional C-cell 690 if(found==1)then 691 found=0 692 693 ! Test vin1 being the binary axis 694 norm2trial=vin1(1)**2+vin1(2)**2+vin1(3)**2 695 reduceda=(vext(1)*vin1(1)+vext(2)*vin1(2)+vext(3)*vin1(3))/norm2trial 696 if(abs(reduceda)<tolsym)then ! vin1 is the binary axis and vext is in the mediator plane 697 found=1 698 cell_base(:,1)=vin2(:) 699 cell_base(:,2)=vin1(:) 700 cell_base(:,3)=vext(:) 701 else if(abs(abs(reduceda)-0.5d0)<tolsym)then ! vin1 is the binary axis and vext has +1/2 or -1/2 as projection 702 found=1 703 cell_base(:,1)=vin2(:) 704 cell_base(:,2)=vin1(:) 705 cell_base(:,3)=vext(:)-reduceda*vin1(:)+vin2(:)*half 706 else 707 ! Test vin2 being the binary axis 708 norm2trial=vin2(1)**2+vin2(2)**2+vin2(3)**2 709 reduceda=(vext(1)*vin2(1)+vext(2)*vin2(2)+vext(3)*vin2(3))/norm2trial 710 if(abs(reduceda)<tolsym)then ! vin2 is the binary axis and vext is in the mediator plane 711 found=1 712 cell_base(:,1)=vin1(:) 713 cell_base(:,2)=vin2(:) 714 cell_base(:,3)=vext(:) 715 else if(abs(abs(reduceda)-0.5d0)<tolsym)then ! vin2 is the binary axis and vext has +1/2 or -1/2 as projection 716 found=1 717 cell_base(:,1)=vin1(:) 718 cell_base(:,2)=vin2(:) 719 cell_base(:,3)=vext(:)-reduceda*vin2(:)+vin1(:)*half 720 end if 721 end if 722 723 if(found==1)then 724 fact=2 ; center=3 725 call holocell(cell_base,0,foundc,iholohedry,tolsym) 726 end if 727 end if 728 end if 729 730 end do ! Do-loop on three different directions 731 end do ! Do-loop on different target holohedries 732 733 if(foundc==0)then 734 iholohedry=1 ; fact=1 ; center=0 735 cell_base(:,:)=minim(:,:) 736 end if 737 738 !DEBUG 739 !write(std_out,*)' symlatt : done with centering tests, foundc=',foundc 740 !write(std_out,*)' center=',center 741 !write(std_out,*)' iholohedry=',iholohedry 742 !ENDDEBUG 743 744 !-------------------------------------------------------------------------- 745 !Final check on the Bravais lattice, using the basis vectors 746 747 !Recompute the metric tensor 748 if(foundc==1)then 749 do ii=1,3 750 metmin(:,ii)=cell_base(1,:)*cell_base(1,ii)+& 751 & cell_base(2,:)*cell_base(2,ii)+& 752 & cell_base(3,:)*cell_base(3,ii) 753 end do 754 end if 755 756 !Examine the angles and vector lengths 757 ang90(:)=0 758 if(metmin(1,2)**2<tolsym**2*metmin(1,1)*metmin(2,2))ang90(3)=1 759 if(metmin(1,3)**2<tolsym**2*metmin(1,1)*metmin(3,3))ang90(2)=1 760 if(metmin(2,3)**2<tolsym**2*metmin(2,2)*metmin(3,3))ang90(1)=1 761 equal(:)=0 762 if(abs(metmin(1,1)-metmin(2,2))<tolsym*half*(metmin(1,1)+metmin(2,2)))equal(3)=1 763 if(abs(metmin(1,1)-metmin(3,3))<tolsym*half*(metmin(1,1)+metmin(3,3)))equal(2)=1 764 if(abs(metmin(2,2)-metmin(3,3))<tolsym*half*(metmin(2,2)+metmin(3,3)))equal(1)=1 765 766 !DEBUG 767 !write(std_out,*)' symlatt : recompute the metric tensor ' 768 !write(std_out,*)' ang90=',ang90 769 !write(std_out,*)' equal=',equal 770 !ENDDEBUG 771 772 !The axes will be aligned with the previously determined 773 !basis vectors, EXCEPT for the tetragonal cell, see later 774 axes(:,:)=cell_base(:,:) 775 776 found=0 777 !Check orthogonal conventional cells 778 if(ang90(1)+ang90(2)+ang90(3)==3)then 779 780 ! Cubic system 781 if(equal(1)+equal(2)+equal(3)==3)then 782 ! However, one-face centered is not admitted 783 if(center==0 .or. center==-1 .or. center==-3)then 784 iholohedry=7 ; found=1 785 if(center==0)then 786 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is cP (primitive cubic)' 787 else if(center==-1)then 788 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is cI (body-centered cubic)' 789 else if(center==-3)then 790 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is cF (face-centered cubic)' 791 end if 792 end if 793 end if 794 795 ! Tetragonal system 796 if(found==0 .and. & 797 & (equal(1)==1 .or. equal(2)==1 .or. equal(3)==1) )then 798 ! However, one-face centered or face-centered is not admitted 799 if(center==0 .or. center==-1)then 800 iholohedry=4 ; found=1 801 if(equal(1)==1)then 802 axes(:,3)=cell_base(:,1) ; axes(:,1)=cell_base(:,2) ; axes(:,2)=cell_base(:,3) 803 else if(equal(2)==1)then 804 axes(:,3)=cell_base(:,2) ; axes(:,2)=cell_base(:,1) ; axes(:,1)=cell_base(:,3) 805 else if(equal(3)==1)then 806 axes(:,:)=cell_base(:,:) 807 end if 808 if(center==0)then 809 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is tP (primitive tetragonal)' 810 else if(center==-1)then 811 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is tI (body-centered tetragonal)' 812 end if 813 end if 814 end if 815 816 ! Orthorhombic system 817 if(found==0)then 818 iholohedry=3 ; found=1 819 axes(:,:)=cell_base(:,:) 820 if(center==0)then 821 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is oP (primitive orthorhombic)' 822 else if(center==-1)then 823 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is oI (body-centered orthorhombic)' 824 else if(center==1 .or. center==2 .or. center==3)then 825 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is oC (one-face-centered orthorhombic)' 826 else if(center==-3)then 827 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is oF (face-centered orthorhombic)' 828 end if 829 end if 830 831 else 832 833 ! Hexagonal system 834 if(found==0 .and. ang90(1)==1 .and. ang90(2)==1 .and. equal(3)==1 .and. (2*metmin(2,1)+metmin(1,1))<tolsym*metmin(1,1))then 835 iholohedry=6 ; found=1 836 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is hP (primitive hexagonal)' 837 end if 838 839 ! Rhombohedral system 840 if(found==0 .and. equal(1)+equal(2)+equal(3)==3 .and. & 841 & abs(metmin(2,1)-metmin(3,2))<tolsym*metmin(2,2) .and. & 842 & abs(metmin(2,1)-metmin(3,1))<tolsym*metmin(1,1) )then 843 iholohedry=5 ; found=1 844 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is hR (rhombohedral)' 845 end if 846 847 ! Monoclinic system 848 if(found==0 .and. ang90(1)+ang90(2)+ang90(3)==2 )then 849 iholohedry=2 ; found=1 850 if(center==0)then 851 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is mP (primitive monoclinic)' 852 else if(center==3)then 853 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is mC (one-face-centered monoclinic)' 854 end if 855 end if 856 857 ! Triclinic system 858 if(found==0)then 859 iholohedry=1 ; found=1 860 write(message,'(a,a)')ch10,' symlatt : the Bravais lattice is aP (primitive triclinic)' 861 end if 862 863 end if 864 865 call wrtout(std_out,message,'COLL') 866 867 !-------------------------------------------------------------------------- 868 !Make sure that axes form a right-handed coordinate system 869 !(Note : this should be done in the body of the routine, 870 !by making changes that leave the sign of the mixed product of the three 871 !vectors invariant) 872 determinant=axes(1,1)*axes(2,2)*axes(3,3) & 873 & +axes(1,2)*axes(2,3)*axes(3,1) & 874 & +axes(1,3)*axes(3,2)*axes(2,1) & 875 & -axes(1,1)*axes(3,2)*axes(2,3) & 876 & -axes(1,3)*axes(2,2)*axes(3,1) & 877 & -axes(1,2)*axes(2,1)*axes(3,3) 878 if(determinant<0.0d0)then 879 axes(:,:)=-axes(:,:) 880 end if 881 882 !-------------------------------------------------------------------------- 883 !Prefer symmetry axes on the same side as the primitive axes, 884 !when the changes are allowed 885 do 886 do ia=1,3 887 scprods(ia,:)=axes(1,ia)*rprimd(1,:)+& 888 & axes(2,ia)*rprimd(2,:)+& 889 & axes(3,ia)*rprimd(3,:) 890 norm2trial=sum(axes(:,ia)**2) 891 scprods(ia,:)=scprods(ia,:)/sqrt(norm2trial) 892 end do 893 do ia=1,3 894 norm2trial=sum(rprimd(:,ia)**2) 895 scprods(:,ia)=scprods(:,ia)/sqrt(norm2trial) 896 end do 897 898 ! One should now try all the generators of the 899 ! proper rotations of each Bravais lattice, coupled with change of 900 ! signs of each vector. This is not done systematically in what follows ... 901 ! Here, the third axis is left unchanged 902 if(iholohedry/=5)then 903 if(scprods(1,1)<-tolsym .and. scprods(2,2)<-tolsym)then 904 axes(:,1)=-axes(:,1) ; axes(:,2)=-axes(:,2) 905 cycle 906 end if 907 end if 908 ! The first (or second) axis is left unchanged 909 if(iholohedry/=5 .and. iholohedry/=6)then 910 if(scprods(2,2)<-tolsym .and. scprods(3,3)<-tolsym)then 911 axes(:,2)=-axes(:,2) ; axes(:,3)=-axes(:,3) 912 cycle 913 end if 914 if(scprods(1,1)<-tolsym .and. scprods(3,3)<-tolsym)then 915 axes(:,1)=-axes(:,1) ; axes(:,3)=-axes(:,3) 916 cycle 917 end if 918 end if 919 ! Permutation of the three axis 920 if(iholohedry==5 .or. iholohedry==7)then 921 trace=scprods(1,1)+scprods(2,2)+scprods(3,3) 922 if(trace+tolsym< scprods(1,2)+scprods(2,3)+scprods(3,1))then 923 vecta(:)=axes(:,1) ; axes(:,1)=axes(:,3) 924 axes(:,3)=axes(:,2); axes(:,2)=vecta(:) 925 cycle 926 end if 927 if(trace+tolsym < scprods(1,3)+scprods(2,1)+scprods(3,2))then 928 vecta(:)=axes(:,1) ; axes(:,1)=axes(:,2) 929 axes(:,2)=axes(:,3); axes(:,3)=vecta(:) 930 cycle 931 end if 932 ! This case is observed when the three new vectors 933 ! are pointing opposite to the three original vectors 934 ! One takes their opposite, then switch to of them, then process 935 ! them again in the loop 936 if(sum(scprods(:,:))<tolsym)then 937 axes(:,1)=-axes(:,1) 938 vecta(:)=-axes(:,2) 939 axes(:,2)=-axes(:,3) 940 axes(:,3)=vecta(:) 941 cycle 942 end if 943 end if 944 exit 945 ! Other cases might be coded ... 946 end do 947 948 !-------------------------------------------------------------------------- 949 950 !DEBUG 951 !write(std_out,'(a,3es14.6,a,3es14.6,a,3es14.6)')' rprimd=',& 952 !& rprimd(:,1),ch10,rprimd(:,2),ch10,rprimd(:,3) 953 !write(std_out,'(a,3es14.6,a,3es14.6,a,3es14.6)')' axes =',& 954 !& axes(:,1),ch10,axes(:,2),ch10,axes(:,3) 955 !ENDDEBUG 956 957 !Compute the coordinates of rprimd in the system defined by axes(:,:) 958 call matr3inv(axes,axesinvt) 959 do ii=1,3 960 coord(:,ii)=rprimd(1,ii)*axesinvt(1,:)+ & 961 & rprimd(2,ii)*axesinvt(2,:)+ & 962 & rprimd(3,ii)*axesinvt(3,:) 963 end do 964 965 !Check that the coordinates are integers, or half-integer in 966 !the case there is a centering, and generate integer coordinates 967 do ii=1,3 968 do jj=1,3 969 val=coord(ii,jj)*fact 970 if(abs(val-nint(val))>fact*tolsym)then 971 write(message,'(4a,a,3es18.10,a,a,3es18.10,a,a,3es18.10,a,a,i4)')& 972 & 'One of the coordinates of rprimd in axes is non-integer,',ch10,& 973 & 'or non-half-integer (if centering).',ch10,& 974 & 'coord=',coord(:,1),ch10,& 975 & ' ',coord(:,2),ch10,& 976 & ' ',coord(:,3),ch10,& 977 & 'fact=',fact 978 MSG_BUG(message) 979 end if 980 icoord(ii,jj)=nint(val) 981 end do 982 end do 983 984 !Store the bravais lattice characteristics 985 bravais(1)=iholohedry 986 bravais(2)=center 987 bravais(3:5)=icoord(1:3,1) 988 bravais(6:8)=icoord(1:3,2) 989 bravais(9:11)=icoord(1:3,3) 990 991 !-------------------------------------------------------------------------- 992 !Initialize the set of symmetries 993 !Bravais lattices are always invariant under identity and inversion 994 995 !Identity and inversion 996 ptsymrel(:,:,1)=identity(:,:) ; ptsymrel(:,:,2)=-identity(:,:) 997 nptsym=2 998 999 !Keep this for IFCv70 compiler 1000 if(nptsym/=2)then 1001 write(message,'(a,a,a,a)')ch10,& 1002 & ' symlatt : BUG -',ch10,& 1003 & ' Crazy error, compiler bug ' 1004 call wrtout(std_out,message,'COLL') 1005 end if 1006 1007 !-------------------------------------------------------------------------- 1008 !Initialize some generators 1009 !gen6 is defined in a coordinated system with gamma=120 degrees 1010 gen6(:,:)=0 ; gen6(3,3)=1 ; gen6(1,1)=1 ; gen6(1,2)=-1 ; gen6(2,1)=1 1011 gen3(:,:)=0 ; gen3(1,2)=1 ; gen3(2,3)=1 ; gen3(3,1)=1 1012 gen2xy(:,:)=0 ; gen2xy(2,1)=1 ; gen2xy(1,2)=1; gen2xy(3,3)=1 1013 gen2y(:,:)=0 ; gen2y(1,1)=-1; gen2y(2,2)=1 ; gen2y(3,3)=-1 1014 gen2z(:,:)=0 ; gen2z(1,1)=-1; gen2z(2,2)=-1; gen2z(3,3)=1 1015 1016 !-------------------------------------------------------------------------- 1017 1018 !Define the generators for each holohedry (inversion is already included) 1019 if(iholohedry==6)then 1020 ngen=2 1021 gen(:,:,1)=gen2xy(:,:) ; order(1)=2 1022 gen(:,:,2)=gen6(:,:) ; order(2)=6 1023 else if(iholohedry==5)then 1024 ngen=2 1025 gen(:,:,1)=gen2xy(:,:) ; order(1)=2 1026 gen(:,:,2)=gen3(:,:) ; order(2)=3 1027 else 1028 gen(:,:,1)=gen2y(:,:) ; order(1)=2 1029 gen(:,:,2)=gen2z(:,:) ; order(2)=2 1030 gen(:,:,3)=gen2xy(:,:) ; order(3)=2 1031 gen(:,:,4)=gen3(:,:) ; order(4)=3 1032 if(iholohedry<=4)ngen=iholohedry-1 1033 if(iholohedry==7)ngen=4 1034 end if 1035 1036 !Build the point symmetry operations from generators, in the reduced system 1037 !of coordinates defined by axes(:,:) 1038 if(ngen/=0)then 1039 do igen=1,ngen 1040 do isym=1+nptsym,order(igen)*nptsym 1041 jsym=isym-nptsym 1042 do ii=1,3 1043 ptsymrel(:,ii,isym)=gen(:,1,igen)*ptsymrel(1,ii,jsym)+ & 1044 & gen(:,2,igen)*ptsymrel(2,ii,jsym)+ & 1045 & gen(:,3,igen)*ptsymrel(3,ii,jsym) 1046 end do 1047 end do 1048 nptsym=order(igen)*nptsym 1049 1050 end do 1051 end if 1052 1053 !-------------------------------------------------------------------------- 1054 1055 !Transform symmetry matrices in the system defined by rprimd 1056 call symrelrot(nptsym,axes,rprimd,ptsymrel,tolsym) 1057 1058 end subroutine symlatt