LCOV - code coverage report
Current view: top level - src/41_geometry - m_symfind.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.6 % 1130 1013
Test Date: 2026-11-09 11:14:24 Functions: 100.0 % 6 6
Branches: 82.2 % 1886 1551

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_symfind
       2                 :             : !! NAME
       3                 :             : !!  m_symfind
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Symmetry finder high-level API.
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2000-2026 ABINIT group (XG, RC)
      10                 :             : !!  This file is distributed under the terms of the
      11                 :             : !!  GNU General Public License, see ~abinit/COPYING
      12                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : module m_symfind
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_errors
      26                 :             :  use m_abicore
      27                 :             :  use m_symlist
      28                 :             : 
      29                 :             : 
      30                 :             :  use m_matrix,    only : mati3inv, matr3inv, mati3det
      31                 :             :  use m_symtk,     only : chkprimit, symrelrot, symdet, symcharac, holocell, symatm, &
      32                 :             :                          smallprim, print_symmetries, sg_multable, symmetrize_tnons, symmetrize_xred
      33                 :             :  use m_geometry,  only : acrossb, xred2xcart
      34                 :             :  use m_spgdata,   only : getptgroupma, symptgroup, spgdata
      35                 :             : 
      36                 :             :  implicit none
      37                 :             : 
      38                 :             :  private
      39                 :             : !!***
      40                 :             : 
      41                 :             :  public :: symfind     ! From the symmetries of the Bravais lattice,
      42                 :             :                        ! select those that leave invariant the system, and generate tnons. Not always robust.
      43                 :             :  public :: symfind_expert  ! Wrap symfind to provide robust determination of the symmetries,
      44                 :             :                            ! for which resymmetrization of atomic positions and tnons is needed.
      45                 :             :  public :: symanal     ! Find the space group from the list of symmetries and lattice parameters
      46                 :             :  public :: symbrav     ! Determine the Bravais information from the list of symmetry operations, and the lattice vectors.
      47                 :             :  public :: symlatt     ! Find the Bravais lattice and its symmetry operations (ptsymrel).
      48                 :             :                        ! From the unit cell vectors (rprimd) and the corresponding metric tensor.
      49                 :             : 
      50                 :             : contains
      51                 :             : !!***
      52                 :             : 
      53                 :             : !!****f* m_symfind/symfind
      54                 :             : !! NAME
      55                 :             : !! symfind
      56                 :             : !!
      57                 :             : !! FUNCTION
      58                 :             : !! Symmetry finder.
      59                 :             : !! From the symmetries of the Bravais lattice (ptsymrel),
      60                 :             : !! select those that leave invariant the system, and generate
      61                 :             : !! the corresponding tnons vectors and symafm information.
      62                 :             : !! Unlike symfind_expert, does NOT resymmetrize atomic positions and tnons for more robust determination of the symmetries.
      63                 :             : !! The algorithm is explained in T.G. Worlton and J.L. Warren, Comp. Phys. Comm. 3, 88 (1972) [[cite:Worlton1972]]
      64                 :             : !!
      65                 :             : !! INPUTS
      66                 :             : !! chrgat(natom) (optional)=target charge for each atom. Not always used, it depends on the value of constraint_kind
      67                 :             : !! invardir_red (optional)=reduced coordinates of an invariant direction (only acting with symrel - not tnons)
      68                 :             : !! invaraxial_red (optional)=reduced coordinates of an axial vector, similar to invardir_red, but transforms with an additional
      69                 :             : !!                           deteminant factor under symrel operations
      70                 :             : !! invar_z (optional)= if 1, the z direction must stay invariant for all symrel applied ;
      71                 :             : !!                     if 2, z must stay invariant and also there cannot be any associated tnons along z.
      72                 :             : !! gprimd(3,3)=dimensional primitive translations for reciprocal space
      73                 :             : !! msym=default maximal number of symmetries
      74                 :             : !! natom=number of atoms in cell.
      75                 :             : !! nptsym=number of point symmetries of the Bravais lattice
      76                 :             : !! nspden= number of spin-density components. When 4, the three components of spinat are taken into account, instead of only z-component.
      77                 :             : !! nucdipmom(3,natom) (optional) array of nuclear dipole moments
      78                 :             : !! ptsymrel(3,3,1:msym)= nptsym point-symmetry operations
      79                 :             : !!   of the Bravais lattice in real space in terms
      80                 :             : !!   of primitive translations.
      81                 :             : !! spinat(3,natom)=initial spin of each atom, in unit of hbar/2.
      82                 :             : !! tolsym=tolerance for the symmetries
      83                 :             : !! typat(natom)=integer identifying type of atom.
      84                 :             : !! use_inversion=1 if inversion and improper rotations can be included in set of symmetries
      85                 :             : !! xred(3,natom)=reduced coordinates of atoms in terms of real space
      86                 :             : !!   primitive translations
      87                 :             : !!
      88                 :             : !! OUTPUT
      89                 :             : !! ierr (optional)=if non-zero, the symmetry operations do not form a group
      90                 :             : !! nsym=actual number of symmetries
      91                 :             : !! symafm(1:msym)=(anti)ferromagnetic part of nsym symmetry operations
      92                 :             : !! symrel(3,3,1:msym)= nsym symmetry operations in real space in terms
      93                 :             : !!  of primitive translations
      94                 :             : !! tnons(3,1:msym)=nonsymmorphic translations for each symmetry (would
      95                 :             : !!  be 0 0 0 each for a symmorphic space group)
      96                 :             : !!
      97                 :             : !! SOURCE
      98                 :             : 
      99                 :       18163 :  subroutine symfind(gprimd,msym,natom,nptsym,nspden,nsym,&
     100                 :       18163 :                     prtvol, ptsymrel,spinat,symafm,symrel,tnons,tolsym,typat,use_inversion,xred,&
     101                 :       35898 :                     chrgat,ierr,nucdipmom,invardir_red,invaraxial_red,invar_z)  ! Optional
     102                 :             : 
     103                 :             : !Arguments ------------------------------------
     104                 :             : !scalars
     105                 :             :  integer,intent(in) :: msym,natom,nptsym,nspden,use_inversion
     106                 :             :  integer,intent(in) :: prtvol
     107                 :             :  integer,optional,intent(in) :: invar_z
     108                 :             :  integer,optional,intent(out) :: ierr
     109                 :             :  integer,intent(out) :: nsym
     110                 :             :  real(dp),intent(in) :: tolsym
     111                 :             : !arrays
     112                 :             :  integer,intent(in) :: ptsymrel(3,3,msym),typat(natom)
     113                 :             :  integer,intent(inout) :: symafm(msym),symrel(3,3,msym) !vz_i
     114                 :             :  real(dp),intent(in) :: gprimd(3,3),spinat(3,natom),xred(3,natom)
     115                 :             :  real(dp),optional,intent(in) :: invardir_red(3),invaraxial_red(3),chrgat(natom)
     116                 :             :  real(dp),optional, intent(in) :: nucdipmom(3,natom)
     117                 :             :  real(dp),intent(inout) :: tnons(3,msym) !vz_i
     118                 :             : 
     119                 :             : !Local variables-------------------------------
     120                 :             : !scalars
     121                 :             :  integer :: found3,foundcl,iatom,iatom0,iatom1,iatom2,iatom3,iclass,iclass0,ierr_,ii
     122                 :             :  integer :: isym,jj,kk,natom0,nclass,ntrial,printed,trialafm,trialok
     123                 :             :  integer :: mm(3,3), detR
     124                 :             :  real(dp) :: det,diff1,diff2,diff3,diffr1,diffr2,diffr3,ndnorm,nucdipmomcl2,nucdipmomcl20
     125                 :             :  real(dp) :: spinat2,spinatcl2,spinatcl20,tolsym2
     126                 :             : ! TRUE if antiferro symmetries are used with non-collinear magnetism.
     127                 :             :  integer :: afm_noncoll=1 !For nspden==4.  If 1, all symops are permitted ; if 0 symafm must be 1.
     128                 :             : !For nspden=4. If noncoll_orthorhombic1, require the symmetry operations to be a subset of the orthorhombic symmetries, except if all spinat=0..
     129                 :             :  integer :: noncoll_orthorhombic=0
     130                 :             :  logical :: test_sameabsspin,test_samechrg
     131                 :             :  logical :: test_samenucdipmom
     132                 :             :  character(len=500) :: msg
     133                 :             : !arrays
     134                 :       18163 :  integer,allocatable :: class(:,:),natomcl(:),typecl(:)
     135                 :             :  real(dp) :: diff(3),invardir_red_rot(3),invaraxial_red_rot(3),hand2(3),hand3(3),ndtest(3),rprimd(3,3),spinat0(3),xred0(3)
     136                 :             :  !real(dp) :: symnucdipmom2(3)
     137                 :             :  real(dp) :: symnucdipmom2cart(3,3),symnucdipmom2red(3,3)
     138                 :             :  real(dp) :: symspinat1(3),symspinat2(3),symxred2(3),trialnons(3)
     139                 :       18163 :  real(dp),allocatable :: chrgat_(:)
     140                 :       18163 :  real(dp),allocatable :: chrgatcl(:)
     141                 :       18163 :  real(dp),allocatable :: local_nucdipmom(:,:,:),nucdipmomcl(:,:),nucdipmomred(:,:,:)
     142                 :       18163 :  real(dp),allocatable :: spinatcl(:,:),spinatred(:,:)
     143                 :             : !**************************************************************************
     144                 :             : 
     145                 :             : !write(std_out,'(a)')' m_symfind%symfind : enter '; call flush(std_out)
     146                 :             : 
     147   [ -  +  +  -  :       54489 :  ABI_MALLOC(local_nucdipmom,(3,3,natom))
          +  -  +  -  -  
                +  -  + ]
     148   [ +  +  +  +  :      601031 :  local_nucdipmom(:,:,:) = zero
                   +  + ]
     149         [ +  + ]:       18163 :  if(present(nucdipmom)) then
     150   [ +  +  +  + ]:      194669 :     local_nucdipmom(1:3,1,:) = nucdipmom(1:3,:)
     151                 :             :  end if
     152                 :             : !DEBUG
     153                 :             : ! if (prtvol>1) msg="remove me later"
     154                 :             : ! write(std_out,*)' symfind : enter'
     155                 :             : ! call flush(6)
     156                 :             : ! write(std_out,*)'   ptsymrel matrices are :'
     157                 :             : ! do isym=1,nptsym
     158                 :             : ! write(std_out,'(i4,4x,9i4)' )isym,ptsymrel(:,:,isym)
     159                 :             : ! end do
     160                 :             : ! write(std_out,*)' symfind : natom=',natom
     161                 :             : ! do iatom=1,natom
     162                 :             : ! write(std_out,*)'  atom number',iatom
     163                 :             : ! write(std_out,*)'   typat   =',typat(iatom)
     164                 :             : ! write(std_out,*)'   spinat  =',spinat(:,iatom)
     165                 :             : ! write(std_out,*)'   xred    =',xred(:,iatom)
     166                 :             : ! if (ANY(ABS(local_nucdipmom)>tol8)) then
     167                 :             : ! write(std_out,*)'   nucdipmom = ',local_nucdipmom(:,1,iatom)
     168                 :             : ! end if
     169                 :             : ! end do
     170                 :             : ! write(std_out,*)' '
     171                 :             : ! call flush(6)
     172                 :             : !ENDDEBUG
     173                 :             : 
     174                 :             :  ABI_UNUSED(prtvol)
     175                 :             : 
     176                 :             : !Find the number of classes of atoms (type, chrg and spinat must be identical,
     177                 :             : !spinat might differ by a sign, if aligned with the z direction, or,
     178                 :             : ! type and nucdipmom must be identical)
     179                 :             : !natomcl(iclass) will contain the number of atoms in the class
     180                 :             : !typecl(iclass) will contain the type of the atoms in the class
     181                 :             : !chrgcl(iclass) will contain the charge of the atoms in the class
     182                 :             : !spinatcl(1:3,iclass) will contain the spinat of the atoms in the class
     183                 :             : !class(1:natomclass(iclass),iclass) will contain the index of the
     184                 :             : !atoms belonging to the class
     185   [ +  -  -  +  :       72652 :  ABI_MALLOC(class,(natom+3,natom))
          +  -  -  +  +  
          -  +  -  +  -  
             -  +  -  + ]
     186   [ -  +  +  -  :       54489 :  ABI_MALLOC(natomcl,(natom))
          +  -  +  -  -  
                +  -  + ]
     187   [ -  +  +  -  :       36326 :  ABI_MALLOC(typecl,(natom))
             -  +  -  + ]
     188   [ -  +  +  -  :       54489 :  ABI_MALLOC(chrgat_,(natom))
          +  -  +  -  -  
                +  -  + ]
     189   [ -  +  +  -  :       36326 :  ABI_MALLOC(chrgatcl,(natom))
             -  +  -  + ]
     190   [ -  +  +  -  :       54489 :  ABI_MALLOC(spinatcl,(3,natom))
          +  -  +  -  -  
                +  -  + ]
     191   [ -  +  +  -  :       36326 :  ABI_MALLOC(nucdipmomcl,(3,natom))
             -  +  -  + ]
     192                 :             : 
     193                 :       18163 :  tolsym2=tolsym**2
     194                 :             : 
     195         [ +  + ]:       62999 :  chrgat_(:)=zero
     196         [ +  + ]:       18163 :  if(present(chrgat))then
     197         [ +  + ]:       62129 :    chrgat_(:)=chrgat(:)
     198                 :             :  endif
     199                 :             : 
     200                 :             :  ! for each nuclear dipole we need a local right handed coord system, so we can
     201                 :             :  ! test later for whether a symmetry operation preserves the circulation induced
     202                 :             :  ! by the dipole
     203         [ +  + ]:       62999 :  do iatom=1, natom
     204         [ +  + ]:      179344 :     ndnorm=sqrt(DOT_PRODUCT(local_nucdipmom(1:3,1,iatom),local_nucdipmom(1:3,1,iatom)))
     205                 :             : 
     206                 :             :     ! if nuclear dipole has effectively zero size, move on to the next atom
     207         [ +  + ]:       44836 :     if (ndnorm < tol8) cycle
     208                 :             : 
     209                 :             :     ! for testing purposes, we care only about direction so renormalize to unity
     210         [ +  + ]:         512 :     local_nucdipmom(1:3,1,iatom) = local_nucdipmom(1:3,1,iatom)/ndnorm
     211                 :             : 
     212                 :             :     ! make a random vector, each component is (0,1]
     213                 :         128 :     call random_number(ndtest)
     214                 :             : 
     215                 :             :     ! vector 2 is constructed to be orthogonal to original nuclear dipole moment vector
     216                 :         128 :     call acrossb(local_nucdipmom(1:3,1,iatom),ndtest(1:3),local_nucdipmom(1:3,2,iatom))
     217                 :             : 
     218                 :             :     ! vector 3 is orthogonal to 1 and 2, and 1,2,3 form a right-handed set
     219                 :       62999 :     call acrossb(local_nucdipmom(1:3,1,iatom),local_nucdipmom(1:3,2,iatom),local_nucdipmom(1:3,3,iatom))
     220                 :             :  end do
     221                 :             : 
     222                 :             :  ! need rprimd later to transform back to cart coords
     223                 :       18163 :  call matr3inv(gprimd,rprimd)
     224                 :             : 
     225                 :             : !write(std_out,'(a)')' m_symfind%symfind : before initialise with the first atom '; call flush(std_out)
     226                 :             : 
     227                 :             : !Initialise with the first atom
     228                 :       18163 :  nclass=1
     229                 :       18163 :  natomcl(1)=1
     230                 :       18163 :  typecl(1)=typat(1)
     231                 :       18163 :  chrgatcl(1)=chrgat_(1)
     232         [ +  + ]:       72652 :  spinatcl(:,1)=spinat(:,1)
     233         [ +  + ]:       72652 :  nucdipmomcl(:,1)=local_nucdipmom(:,1,1)
     234                 :       18163 :  class(1,1)=1
     235         [ +  + ]:       18163 :  if(natom>1)then
     236         [ +  + ]:       40435 :    do iatom=2,natom
     237                 :             : !    DEBUG
     238                 :             : !    write(std_out,*)' '
     239                 :             : !    write(std_out,*)' symfind : examine iatom=',iatom
     240                 :             : !    ENDDEBUG
     241                 :       39033 :      foundcl=0
     242         [ +  + ]:       39033 :      do iclass=1,nclass
     243                 :             : !      Compare the typat, chrg and spinat of atom iatom with existing ones.
     244                 :             : !      At this stage, admit either identical spinat, or spin-flip spinat.
     245         [ +  + ]:       39033 :        if( typat(iatom)==typecl(iclass)) then
     246                 :       20654 :          test_samechrg= (abs(chrgat_(iatom)-chrgatcl(iclass))<tolsym)
     247         [ +  + ]:       20654 :          if(nspden/=4)then
     248                 :       20010 :            test_sameabsspin=(abs(abs(spinat(3,iatom))-abs(spinatcl(3,iclass)))<tolsym)
     249                 :             :          else if(nspden==4)then
     250                 :         644 :            spinat2  =spinat(1,iatom)**2+spinat(2,iatom)**2+spinat(3,iatom)**2
     251                 :         644 :            spinatcl2=spinatcl(1,iclass)**2+spinatcl(2,iclass)**2+spinatcl(3,iclass)**2
     252                 :         644 :            test_sameabsspin=abs(spinat2-spinatcl2)<tolsym
     253                 :             :          endif
     254                 :             :          test_samenucdipmom= &
     255                 :             : &             abs(local_nucdipmom(1,1,iatom)-nucdipmomcl(1,iclass))<tolsym .and. &
     256                 :             : &             abs(local_nucdipmom(2,1,iatom)-nucdipmomcl(2,iclass))<tolsym .and. &
     257   [ +  -  +  -  :       20654 : &             abs(local_nucdipmom(3,1,iatom)-nucdipmomcl(3,iclass))<tolsym
                   -  + ]
     258                 :             :          ! note in the following test, m_chkinp/chkinp has already prevented nucdipmom to be
     259                 :             :          ! nonzero when spinat is nonzero
     260   [ +  +  +  - ]:       20654 :          if( test_samechrg .and. test_sameabsspin .and. test_samenucdipmom ) then
     261                 :             : !          write(std_out,*)' symfind : find it belongs to class iclass=',iclass
     262                 :             : !          write(std_out,*)' symfind : spinat(:,iatom)=',spinat(:,iatom)
     263                 :             : !          write(std_out,*)' symfind : spinatcl(:,iclass)=',spinatcl(:,iclass)
     264                 :             : !          write(std_out,*)' symfind : test_sameabsspin=',test_sameabsspin
     265                 :             : !          write(std_out,*)' '
     266                 :       20572 :            natomcl(iclass)=natomcl(iclass)+1
     267                 :       20572 :            class(natomcl(iclass),iclass)=iatom
     268                 :             :            foundcl=1
     269                 :             :            exit
     270                 :             :          end if
     271                 :             :        end if
     272                 :             :      end do
     273                 :             : !    If no class with these characteristics exist, create one
     274                 :       13762 :      if(foundcl==0)then
     275                 :        6101 :        nclass=nclass+1
     276                 :        6101 :        natomcl(nclass)=1
     277                 :        6101 :        typecl(nclass)=typat(iatom)
     278                 :        6101 :        chrgatcl(nclass)=chrgat_(iatom)
     279         [ +  + ]:       24404 :        spinatcl(:,nclass)=spinat(:,iatom)
     280         [ +  + ]:       24404 :        nucdipmomcl(:,nclass)=local_nucdipmom(:,1,iatom)
     281                 :        6101 :        class(1,nclass)=iatom
     282                 :             :      end if
     283                 :             :    end do
     284                 :             :  end if
     285                 :             : 
     286                 :             : !write(std_out,*)' '
     287                 :             : !write(std_out,*)' symfind : found ',nclass,' nclass of atoms'
     288                 :             : !do iclass=1,nclass
     289                 :             : !write(std_out,*)'  class number',iclass
     290                 :             : !write(std_out,*)'   natomcl =',natomcl(iclass)
     291                 :             : !write(std_out,*)'   typecl  =',typecl(iclass)
     292                 :             : !write(std_out,*)'   spinatcl=',spinatcl(:,iclass)
     293                 :             : !write(std_out,*)'   class   =',(class(iatom,iclass),iatom=1,natomcl(iclass))
     294                 :             : !end do
     295                 :             : !write(std_out,*)' '
     296                 :             : 
     297                 :             : !write(std_out,'(a)')' m_symfind%symfind : before select the class '; call flush(std_out)
     298                 :             : 
     299                 :             : !Select the class with the least number of atoms, and non-zero spinat if any
     300                 :             : !It is important to select a magnetic class of atom, if any, otherwise
     301                 :             : !the determination of the initial (inclusive) set of symmetries takes only
     302                 :             : !non-magnetic symmetries, and not both magnetic and non-magnetic ones, see later.
     303                 :             : !On the contrary, the chrgat_ data does not play any role, it is invariant upon atomic-centered  symmetries
     304                 :       18163 :  iclass0=1
     305                 :       18163 :  natom0=natomcl(1)
     306                 :       18163 :  spinatcl20=spinatcl(1,1)**2+spinatcl(2,1)**2+spinatcl(3,1)**2
     307                 :       18163 :  nucdipmomcl20=nucdipmomcl(1,1)**2+nucdipmomcl(2,1)**2+nucdipmomcl(3,1)**2
     308         [ +  + ]:       18163 :  if(nclass>1)then
     309         [ +  + ]:       11834 :    do iclass=2,nclass
     310                 :        6101 :      spinatcl2=spinatcl(1,iclass)**2+spinatcl(2,iclass)**2+spinatcl(3,iclass)**2
     311                 :        6101 :      nucdipmomcl2=nucdipmomcl(1,iclass)**2+nucdipmomcl(2,iclass)**2+nucdipmomcl(3,iclass)**2
     312                 :             :      if( (natomcl(iclass)<natom0 &
     313                 :             : &          .and. .not. (spinatcl20>tolsym .and. spinatcl2<tolsym) &
     314                 :             : &          .and. .not. (nucdipmomcl20>tolsym .and. nucdipmomcl2<tolsym) )  &
     315                 :             : &     .or. (spinatcl20<tolsym .and. spinatcl2>tolsym) &
     316   [ +  +  +  +  :       11834 : &     .or. (nucdipmomcl20<tolsym .and. nucdipmomcl2>tolsym)) then
          -  +  -  +  -  
          -  +  +  +  +  
             +  +  +  + ]
     317                 :        6101 :        iclass0=iclass
     318                 :        6101 :        natom0=natomcl(iclass)
     319                 :        6101 :        spinatcl20=spinatcl2
     320                 :        6101 :        nucdipmomcl20=nucdipmomcl2
     321                 :             :      end if
     322                 :             :    end do
     323                 :             :  end if
     324                 :             : 
     325                 :       18163 :  printed=0
     326                 :             : 
     327                 :             : !If non-collinear spinat have to be used, transfer them in reduced coordinates
     328         [ +  + ]:       18163 :  if (nspden==4) then
     329   [ -  +  +  -  :        1092 :    ABI_MALLOC(spinatred,(3,natom))
             -  +  -  + ]
     330         [ +  + ]:        1890 :    do iatom=1,natom
     331         [ +  + ]:        5922 :      do ii=1,3
     332                 :        5376 :        spinatred(1:3,iatom)=MATMUL(TRANSPOSE(gprimd),spinat(1:3,iatom))
     333                 :             :      end do
     334                 :             :    end do
     335                 :             :  end if
     336                 :             : 
     337                 :             : !write(std_out,*)' '
     338                 :             : !write(std_out,*)' symfind : has selected iclass0=',iclass0
     339                 :             : !write(std_out,*)'  # iatom  xred                          spinat       (spinatred if nspden=4) '
     340                 :             : !do iatom0=1,natomcl(iclass0)
     341                 :             : !iatom=class(iatom0,iclass0)
     342                 :             : !if(nspden/=4)then
     343                 :             : !  write(std_out,'(2i4,6f10.4)' )iatom0,iatom,xred(:,iatom),spinat(:,iatom)
     344                 :             : !else if(nspden==4)then
     345                 :             : !  write(std_out,'(2i4,9f10.4)' )iatom0,iatom,xred(:,iatom),spinat(:,iatom),spinatred(:,iatom)
     346                 :             : !endif
     347                 :             : !end do
     348                 :             : !write(std_out,*)' '
     349                 :             : 
     350                 :             :  !represent nuclear dipole moments in reduced coords
     351   [ -  +  +  -  :       36326 :  ABI_MALLOC(nucdipmomred,(3,3,natom))
             -  +  -  + ]
     352         [ +  + ]:       62999 :  do iatom=1,natom
     353         [ +  + ]:      197507 :     do ii=1,3
     354                 :      179344 :        nucdipmomred(1:3,ii,iatom)=MATMUL(TRANSPOSE(gprimd),local_nucdipmom(1:3,ii,iatom))
     355                 :             :     end do
     356                 :             :  end do
     357                 :             : 
     358                 :             : !write(std_out,'(a)')' m_symfind%symfind : before big loop '; call flush(std_out)
     359                 :             : 
     360                 :             : !Big loop over each symmetry operation of the Bravais lattice
     361                 :       18163 :  nsym=0
     362         [ +  + ]:      761883 :  do isym=1,nptsym
     363                 :             : 
     364                 :             : !write(std_out,'(a,i4)')' m_symfind%symfind : enter loop isym=',isym; call flush(std_out)
     365                 :             : 
     366         [ +  + ]:      743720 :    if(present(invardir_red))then
     367                 :             : !    ji: Check whether symmetry operation leaves invardir_red invariant
     368                 :             :      invardir_red_rot(:) = ptsymrel(:,1,isym)*invardir_red(1) +  &
     369                 :             : &     ptsymrel(:,2,isym)*invardir_red(2) +  &
     370         [ +  + ]:     2939488 : &     ptsymrel(:,3,isym)*invardir_red(3)
     371         [ +  + ]:     2939488 :      diff(:)=invardir_red(:)-invardir_red_rot(:)
     372         [ +  + ]:      734872 :      if( (diff(1)**2+diff(2)**2+diff(3)**2) > tolsym**2 ) cycle
     373                 :             :    endif
     374                 :             : 
     375                 :             : ! check whether symmetry operation leaves invaraxial_red invariant (axial vector)
     376         [ +  + ]:      740760 :   if(present(invaraxial_red))then
     377                 :             : !!    CALL MatrixHyb_getDet(symref_hyb(isym), detR)
     378   [ +  +  +  + ]:     9514856 :     mm(:,:) = ptsymrel(:,:,isym)
     379                 :      731912 :     call mati3det(mm,detR)
     380                 :             :     invaraxial_red_rot(:) = detR * (&
     381                 :             :       ptsymrel(:,1,isym)*invaraxial_red(1) +  &
     382                 :             : &     ptsymrel(:,2,isym)*invaraxial_red(2) +  &
     383         [ +  + ]:     2927648 : &     ptsymrel(:,3,isym)*invaraxial_red(3) )
     384         [ +  + ]:     2927648 :     diff(:)=invaraxial_red(:)-invaraxial_red_rot(:)
     385                 :             : 
     386         [ +  + ]:      731912 :     if( (diff(1)**2+diff(2)**2+diff(3)**2) > tolsym**2 ) cycle
     387                 :             :    endif
     388                 :             : 
     389                 :             : !write(std_out,'(a,i4)')' m_symfind%symfind : 1'; call flush(std_out)
     390                 :             : 
     391                 :             :    det=ptsymrel(1,1,isym)*ptsymrel(2,2,isym)*ptsymrel(3,3,isym)+&
     392                 :             : &     ptsymrel(2,1,isym)*ptsymrel(3,2,isym)*ptsymrel(1,3,isym)+&
     393                 :             : &     ptsymrel(1,2,isym)*ptsymrel(2,3,isym)*ptsymrel(3,1,isym) - &
     394                 :             : &     (ptsymrel(3,1,isym)*ptsymrel(2,2,isym)*ptsymrel(1,3,isym)+&
     395                 :             : &     ptsymrel(2,1,isym)*ptsymrel(1,2,isym)*ptsymrel(3,3,isym)+&
     396                 :      739976 : &     ptsymrel(3,2,isym)*ptsymrel(2,3,isym)*ptsymrel(1,1,isym))
     397   [ +  +  +  + ]:      739976 :    if(use_inversion==0 .and. det==-1) cycle
     398                 :             : 
     399                 :             : !write(std_out,'(a,i4)')' m_symfind%symfind : 2'; call flush(std_out)
     400                 :             : 
     401                 :             : !  jellium slab and spatially varying chemical potential cases:
     402                 :             : !  (actually, an inversion symmetry/mirror plane perpendicular to z symmetry operation might still be allowed... TO BE DONE !)
     403         [ +  + ]:      729612 :    if(present(invar_z))then
     404         [ +  + ]:      720772 :      if (invar_z/=0) then
     405                 :             : !      check whether symmetry operation produce a rotation only in the xy plane
     406                 :             :        if (ptsymrel(1,3,isym)/=0 .or. ptsymrel(2,3,isym)/=0 .or. &
     407   [ +  +  +  +  :        1856 :            ptsymrel(3,1,isym)/=0 .or. ptsymrel(3,2,isym)/=0 ) cycle
             -  +  -  + ]
     408                 :             : !      check whether symmetry operation does not change the z
     409         [ +  + ]:         832 :        if( ptsymrel(3,3,isym)/=1 ) cycle
     410                 :             :      end if
     411                 :             :    end if
     412                 :             : 
     413                 :             : !write(std_out,'(a,i4)')' m_symfind%symfind : 3'; call flush(std_out)
     414                 :             : 
     415                 :             : !  If noncoll_orthorhombic=1, require orthorhombic operations of symmetries, except if spinat=0.
     416   [ +  +  -  + ]:      728172 :    if (nspden==4 .and. noncoll_orthorhombic==1)then
     417   [ #  #  #  #  :           0 :      if(sum(abs(spinat(:,:)))>tol14)then
                   #  # ]
     418                 :             :        if( ptsymrel(1,3,isym)/=0 .or. ptsymrel(2,3,isym)/=0 .or. &
     419                 :             : &          ptsymrel(1,2,isym)/=0 .or. ptsymrel(3,2,isym)/=0 .or. &
     420   [ #  #  #  #  :           0 : &          ptsymrel(2,1,isym)/=0 .or. ptsymrel(3,2,isym)/=0 ) cycle
          #  #  #  #  #  
                      # ]
     421                 :             :      endif
     422                 :             :    endif
     423                 :             : 
     424                 :             : !write(std_out,'(a,i4)')' m_symfind%symfind : 4'; call flush(std_out)
     425                 :             : 
     426                 :             : !  Select a tentative set of associated translations
     427                 :             : !  First compute the symmetric of the first atom in the smallest class,
     428                 :             : !  using the point symmetry, and also the symmetric of spinat(red).
     429                 :      728172 :    iatom0=class(1,iclass0)
     430                 :             :    xred0(:)=ptsymrel(:,1,isym)*xred(1,iatom0)+ &
     431                 :             :             ptsymrel(:,2,isym)*xred(2,iatom0)+ &
     432         [ +  + ]:     2912688 :             ptsymrel(:,3,isym)*xred(3,iatom0)
     433         [ +  + ]:      728172 :    if (nspden/=4) then
     434         [ +  + ]:     2857744 :      spinat0(:)=spinat(:,iatom0)
     435                 :             :    else
     436                 :             :      spinat0(:)=det*(&
     437                 :             :             ptsymrel(:,1,isym)*spinatred(1,iatom0)+ &
     438                 :             : &           ptsymrel(:,2,isym)*spinatred(2,iatom0)+ &
     439         [ +  + ]:       54944 : &           ptsymrel(:,3,isym)*spinatred(3,iatom0))
     440                 :             :      ! spinat should be treated as an axial vector
     441                 :             :      ! i.e. the improper part of a symm. op. has no effect on spinat
     442                 :             :    endif
     443                 :             : 
     444                 :             : !write(std_out,'(a,i4)')' m_symfind%symfind : 5'; call flush(std_out)
     445                 :             : 
     446                 :             : !  From the set of possible images, deduce tentative translations,
     447                 :             : !  and magnetic factor then test whether it send each atom on a symmetric one
     448                 :             :    ntrial=0
     449         [ +  + ]:     2027991 :    do ii=1,natom0
     450                 :             :      !write(std_out,'(a,2i4)')' symfind : loop isym,ii=',isym,ii
     451                 :     1281656 :      iatom1=class(ii,iclass0)
     452                 :             : 
     453                 :             : !    The tentative translation is found
     454         [ +  + ]:     5126624 :      trialnons(:)=xred(:,iatom1)-xred0(:)
     455                 :             : !    Compare the spinat vectors
     456         [ +  + ]:     1281656 :      if (nspden/=4) then
     457         [ +  + ]:     5045488 :        symspinat1(:)=spinat(:,iatom1)
     458                 :             :      else
     459         [ +  + ]:       81136 :        symspinat1(:)=spinatred(:,iatom1)
     460                 :             :      end if
     461                 :             : 
     462                 :             :      !write(std_out,'(a,6f10.4)')' symspinat1,spinat0=',symspinat1(:),spinat0(:)
     463                 :             : 
     464                 :     1281656 :      trialafm=1
     465   [ +  +  +  + ]:     5126624 :      if(sum(abs(symspinat1(:)-spinat0(:)))>tolsym)then
     466                 :       16966 :        trialafm=-1
     467   [ +  +  +  - ]:       16966 :        if(nspden==4 .and. afm_noncoll==0)cycle
     468   [ +  +  +  + ]:       67864 :        if(sum(abs(symspinat1(:)+spinat0(:)))>tolsym)cycle
     469                 :             :      endif
     470                 :             : 
     471   [ +  +  -  + ]:     5087232 :      if(sum(abs(local_nucdipmom(:,1,iatom1)-local_nucdipmom(:,1,iatom0)))>tolsym)then
     472                 :             :        write(msg,'(3a,3i5)')&
     473                 :           0 :        'Problem with matching the nuclear dipole moment within a class.',ch10,&
     474                 :           0 :        'isym,iatom0,iatom1=',isym,iatom0,iatom1
     475                 :           0 :        ABI_ERROR(msg)
     476                 :             :      end if
     477                 :             : 
     478                 :             : !    jellium slab case: check whether symmetry operation has no translational
     479                 :             : !    component along z
     480         [ +  + ]:     1271808 :      if(present(invar_z))then
     481   [ +  +  +  - ]:     1258596 :        if( invar_z==2 .and. abs(trialnons(3)) > tolsym ) cycle
     482                 :             :      endif
     483                 :             :      trialok=1
     484                 :             : 
     485                 :             : !     write(std_out, '(a,i3,a,i3,a,i3,a,3f12.4,i3)') ' Try isym=',isym,' sending iatom0 ',iatom0,' to iatom1 ',iatom1,' with trialnons(:),trialafm =',trialnons(:),trialafm
     486                 :             : 
     487                 :             : !    Loop over all classes, then all atoms in the class,
     488                 :             : !    to find whether they have a symmetric
     489         [ +  + ]:     2086166 :      do iclass=1,nclass
     490         [ +  + ]:     4186758 :        do jj=1,natomcl(iclass)
     491                 :             : 
     492                 :     3372400 :          iatom2=class(jj,iclass)
     493                 :             : !        Generate the tentative symmetric position of iatom2
     494                 :             :          symxred2(:)=ptsymrel(:,1,isym)*xred(1,iatom2)+ &
     495                 :             : &         ptsymrel(:,2,isym)*xred(2,iatom2)+ &
     496         [ +  + ]:    13489600 : &         ptsymrel(:,3,isym)*xred(3,iatom2)+ trialnons(:)
     497                 :             : !        Generate the tentative symmetric spinat of iatom2
     498         [ +  + ]:     3372400 :          if (nspden/=4) then
     499         [ +  + ]:    13391744 :            symspinat2(:)=trialafm*spinat(:,iatom2)
     500                 :             :          else
     501                 :             :            symspinat2(:)=trialafm*det*(ptsymrel(:,1,isym)*spinatred(1,iatom2)+ &
     502                 :             : &           ptsymrel(:,2,isym)*spinatred(2,iatom2)+ &
     503         [ +  + ]:       97856 : &           ptsymrel(:,3,isym)*spinatred(3,iatom2))
     504                 :             :          end if
     505                 :             :          !        Generate the tentative symmetric nucdipmom of iatom2
     506         [ +  + ]:    13489600 :          do kk = 1, 3
     507                 :             :             symnucdipmom2red(:,kk)=ptsymrel(:,1,isym)*nucdipmomred(1,kk,iatom2)+ &
     508                 :             :                  &           ptsymrel(:,2,isym)*nucdipmomred(2,kk,iatom2)+ &
     509         [ +  + ]:    40468800 :                  &           ptsymrel(:,3,isym)*nucdipmomred(3,kk,iatom2)
     510                 :             :             ! transform back to cart coords for final comparison to nucdipmom
     511   [ +  +  +  +  :   165247600 :             symnucdipmom2cart(:,kk)=MATMUL(rprimd,symnucdipmom2red(:,kk))
                   +  + ]
     512                 :             :          end do
     513                 :             : 
     514                 :             : !        write(std_out,'(a,i4,a,3f8.4,a,3f8.4,a,3f8.4)')&
     515                 :             : !           ' Test iatom2=',iatom2,' at xred=',xred(:,iatom2),'. Is sent to',symxred2(:),' with symspinat2=',symspinat2(:)
     516                 :             : !        write(std_out,'(a,3f8.4)')' and nucdipmom2=',symnucdipmom2cart(:,1)
     517                 :             : 
     518                 :             : !        Check whether there exists an atom of the same class at the
     519                 :             : !        same location, with the correct spinat and nuclear dipole moment circulation
     520         [ +  + ]:    28461684 :          do kk=1,natomcl(iclass)
     521                 :             : 
     522                 :    27780217 :            found3=1
     523                 :    27780217 :            iatom3=class(kk,iclass)
     524                 :             : !          Check the location
     525                 :    27780217 :            diffr1=xred(1,iatom3)-symxred2(1)
     526                 :    27780217 :            diff1=diffr1-nint(diffr1)
     527         [ +  + ]:    27780217 :            if(diff1**2>tolsym2)then
     528                 :             :              found3=0 ; cycle
     529                 :             :            else
     530                 :     6111514 :              diffr2=xred(2,iatom3)-symxred2(2)
     531                 :     6111514 :              diff2=diffr2-nint(diffr2)
     532         [ +  + ]:     6111514 :              if(diff2**2>tolsym2)then
     533                 :             :                found3=0 ; cycle
     534                 :             :              else
     535                 :     3310919 :                diffr3=xred(3,iatom3)-symxred2(3)
     536                 :     3310919 :                diff3=diffr3-nint(diffr3)
     537         [ +  + ]:     3310919 :                if( (diff1**2+diff2**2+diff3**2) > tolsym**2 )then
     538                 :             :                  found3=0 ; cycle
     539                 :             :                endif
     540                 :             :              endif
     541                 :             :            endif
     542                 :             : !          Check the spinat
     543         [ +  + ]:     2693485 :            if (nspden/=4) then
     544         [ +  + ]:    10693884 :              diff(:)=spinat(:,iatom3)-symspinat2(:)
     545                 :             :            else
     546         [ +  + ]:       80056 :              diff(:)=spinatred(:,iatom3)-symspinat2(:)
     547                 :             :            end if
     548         [ +  + ]:     2693485 :            if( (diff(1)**2+diff(2)**2+diff(3)**2) > tolsym**2 )then
     549                 :             :              found3=0
     550                 :             :              cycle
     551                 :             :            endif
     552                 :             :            ! Check the nucdipmom
     553                 :             :            ! hand3 gives original circulation sense of nuclear dipole
     554                 :     2693293 :            call acrossb(local_nucdipmom(1:3,2,iatom3),local_nucdipmom(1:3,3,iatom3),hand3)
     555                 :             : 
     556                 :             :            ! hand2 gives circulation sense of tentative, symmetry equivalent nuclear dipole
     557                 :     2693293 :            call acrossb(symnucdipmom2cart(1:3,2),symnucdipmom2cart(1:3,3),hand2)
     558                 :             : 
     559         [ +  + ]:    10773172 :            diff(:)=hand3(:)-hand2(:)
     560   [ +  +  +  +  :    10766508 :            if( any(abs(diff)>tolsym) )found3=0
                   +  + ]
     561                 :             : 
     562                 :             :            !diff(:)=symnucdipmom2cart(:,1) - local_nucdipmom(:,1,iatom3)
     563                 :             :            !if ( any(abs(diff)>tolsym) ) found3=0
     564                 :             : 
     565                 :      681467 :            if(found3==1)exit
     566                 :             :          end do ! End loop over iatom3
     567                 :             : 
     568         [ +  + ]:     4186758 :          if(found3==0)then
     569                 :             :            trialok=0
     570                 :             :            exit
     571                 :             :          end if
     572                 :             :        end do ! End loop over iatom2
     573                 :             : 
     574         [ +  + ]:     2086166 :        if(trialok==0)exit
     575                 :             :      end do ! End loop over all classes
     576                 :             : 
     577                 :             :      !write(std_out,*)' For trial isym=',isym,', trialok = ',trialok
     578                 :             :      !write(std_out,*)' '
     579                 :             : 
     580         [ +  + ]:     2015528 :      if(trialok==1)then
     581                 :      590341 :        nsym=nsym+1
     582         [ -  + ]:      590341 :        if(nsym>msym)then
     583                 :             :          write(msg,'(a,i0,2a,i0,4a)')&
     584                 :           0 :          'The number of symmetries (including non-symmorphic translations) is: ', nsym, ch10,&
     585                 :           0 :          'is larger than maxnsym: ',msym,ch10,&
     586                 :           0 :          'Action: increase maxnsym in the input, or take a cell that is primitive, ',ch10,&
     587                 :           0 :          'or at least smaller than the present one.'
     588                 :           0 :         ABI_ERROR(msg)
     589                 :             :        end if
     590                 :             :        ntrial=ntrial+1
     591   [ +  +  +  + ]:     7674433 :        symrel(:,:,nsym)=ptsymrel(:,:,isym)
     592                 :      590341 :        symafm(nsym)=trialafm
     593         [ +  + ]:     2361364 :        tnons(:,nsym)=trialnons(:)-nint(trialnons(:)-tolsym)
     594                 :             :      end if
     595                 :             : 
     596                 :             :    end do ! End the loop on tentative translations
     597                 :             :  end do ! End big loop over each symmetry operation of the Bravais lattice
     598                 :             : 
     599                 :             : !write(std_out,'(a)')' m_symfind%symfind : after big loop, will call ABI_FREE '; call flush(std_out)
     600                 :             : 
     601                 :       18163 :  ABI_FREE(class)
     602                 :       18163 :  ABI_FREE(natomcl)
     603                 :       18163 :  ABI_FREE(chrgat_)
     604                 :       18163 :  ABI_FREE(chrgatcl)
     605                 :       18163 :  ABI_FREE(spinatcl)
     606                 :       18163 :  ABI_FREE(typecl)
     607         [ -  + ]:       18163 :  ABI_FREE(local_nucdipmom)
     608                 :       18163 :  ABI_FREE(nucdipmomcl)
     609         [ -  + ]:       18163 :  ABI_FREE(nucdipmomred)
     610         [ +  + ]:       18163 :  if (nspden==4)   then
     611         [ -  + ]:         546 :    ABI_FREE(spinatred)
     612                 :             :  end if
     613                 :             : 
     614                 :             : !write(std_out,'(a,i6)')' m_symfind%symfind : call sg_multable, nsym= ',nsym; call flush(std_out)
     615                 :             : 
     616                 :             : ! The algorithm in sg_multable is still cubic in nsym, so avoid calling it uselessly when nsym is too large
     617   [ +  +  +  - ]:       18163 :  if(present(ierr) .or. nsym<=384)then
     618                 :       18163 :    call sg_multable(nsym, symafm, symrel, ierr_, tnons=tnons, tnons_tol=tolsym)
     619                 :             :  else
     620                 :           0 :    ierr_=0
     621                 :             :  endif
     622                 :             : 
     623                 :             : !write(std_out,'(a)')' m_symfind%symfind : call print_symmetries, ierr_= ',ierr_; call flush(std_out)
     624                 :             : 
     625   [ +  +  +  + ]:       18164 :  if (ierr_/=0) call print_symmetries([std_out], nsym, symrel, tnons, symafm)
     626                 :             : 
     627         [ +  + ]:       18163 :  if(.not.present(ierr))then
     628         [ -  + ]:        9160 :    ABI_CHECK(ierr_==0,"Error in group closure")
     629                 :             :  else
     630                 :        9003 :    ierr=ierr_
     631                 :             :  endif
     632                 :             : 
     633                 :             : !write(msg,'(a,I0,es16.6,a)')' symfind : exit, nsym, tolsym=',nsym,tolsym,ch10
     634                 :             : !write(msg,'(2a)') trim(msg),'   symrel matrices, symafm and tnons are :'
     635                 :             : !call wrtout(std_out,msg)
     636                 :             : !do isym=1,nsym
     637                 :             : !  write(msg,'(i4,4x,3i4,2x,3i4,2x,3i4,4x,i4,4x,3f8.4)' ) isym,symrel(:,:,isym),symafm(isym),tnons(:,isym)
     638                 :             : !  call wrtout(std_out,msg)
     639                 :             : !end do
     640                 :             : !stop
     641                 :             : 
     642                 :             : !write(std_out,'(a)')' m_symfind%symfind : exit '; call flush(std_out)
     643                 :             : 
     644   [ +  +  +  +  :       54275 : end subroutine symfind
                   -  + ]
     645                 :             : !!***
     646                 :             : 
     647                 :             : !!****f* m_symfind/symfind_expert
     648                 :             : !! NAME
     649                 :             : !! symfind_expert
     650                 :             : !!
     651                 :             : !! FUNCTION
     652                 :             : !! Symmetry finder, with an added layer of robustness compared to symfind,
     653                 :             : !! and for which resymmetrization of atomic positions and tnons is needed..
     654                 :             : !! From the symmetries of the Bravais lattice (ptsymrel),
     655                 :             : !! select those that leave invariant the system, and generate
     656                 :             : !! the corresponding tnons vectors and symafm information.
     657                 :             : !! Unlike symfind_expert, does NOT resymmetrize atomic positions and tnons for more robust determination of the symmetries.
     658                 :             : !! The algorithm is explained in T.G. Worlton and J.L. Warren, Comp. Phys. Comm. 3, 88 (1972) [[cite:Worton1972]]
     659                 :             : !!
     660                 :             : !! INPUTS
     661                 :             : !! chrgat(natom) (optional)=target charge for each atom. Not always used, it depends on the value of constraint_kind
     662                 :             : !! invardir_red (optional)=reduced coordinates of an invariant direction (only acting with symrel - not tnons)
     663                 :             : !! invaraxial_red (optional)=reduced coordinates of an axial vector, similar to invardir_red, but transforms with an additional
     664                 :             : !!                           deteminant factor under symrel operations
     665                 :             : !! invar_z (optional)= if 1, the z direction must stay invariant for all symrel applied ;
     666                 :             : !!                     if 2, z must stay invariant and also there cannot be any associated tnons along z.
     667                 :             : !! gprimd(3,3)=dimensional primitive translations for reciprocal space
     668                 :             : !! msym=default maximal number of symmetries
     669                 :             : !! natom=number of atoms in cell.
     670                 :             : !! nptsym=number of point symmetries of the Bravais lattice
     671                 :             : !! nspden= number of spin-density components. When 4, the three components of spinat are taken into account, instead of only z-component.
     672                 :             : !! nucdipmom(3,natom) (optional) array of nuclear dipole moments
     673                 :             : !  pawspnorb=flag: 1 if spin-orbit coupling is activated
     674                 :             : !! ptsymrel(3,3,1:msym)= nptsym point-symmetry operations
     675                 :             : !!   of the Bravais lattice in real space in terms of primitive translations.
     676                 :             : !! spinat(3,natom)=initial spin of each atom, in unit of hbar/2.
     677                 :             : !! tolsym=tolerance for the symmetries
     678                 :             : !! typat(natom)=integer identifying type of atom.
     679                 :             : !! usepaw= 0 for non paw calculation; =1 for paw calculation
     680                 :             : !!
     681                 :             : !! OUTPUT
     682                 :             : !! nsym=actual number of symmetries
     683                 :             : !! symafm(1:msym)=(anti)ferromagnetic part of nsym symmetry operations
     684                 :             : !! symrel(3,3,1:msym)= nsym symmetry operations in real space in terms of primitive translations
     685                 :             : !! tnons(3,1:msym)=nonsymmorphic translations for each symmetry (would be 0 0 0 each for a symmorphic space group)
     686                 :             : !!
     687                 :             : !! SIDE EFFECTS
     688                 :             : !! xred(3,natom)=reduced coordinates of atoms in terms of real space
     689                 :             : !!   primitive translations. Might be changed during the resymmetrization.
     690                 :             : !!
     691                 :             : !! SOURCE
     692                 :             : 
     693                 :        9002 : subroutine symfind_expert(gprimd,msym,natom,nptsym,nspden,nsym,&
     694                 :        9002 :   pawspnorb,prtvol,ptsymrel,spinat,symafm,symrel,tnons,tolsym,typat,usepaw,xred,&
     695                 :             :   chrgat,nucdipmom,invardir_red,invaraxial_red,invar_z)  ! Optional - although for the time being all are required ...
     696                 :             : 
     697                 :             : !Arguments ------------------------------------
     698                 :             : !scalars
     699                 :             :  integer,intent(in) :: msym,natom,nptsym,nspden,pawspnorb,usepaw
     700                 :             :  integer,intent(in) :: prtvol
     701                 :             :  integer,optional,intent(in) :: invar_z
     702                 :             :  integer,intent(out) :: nsym
     703                 :             :  real(dp),intent(in) :: tolsym
     704                 :             : !arrays
     705                 :             :  integer,intent(in) :: ptsymrel(3,3,msym),typat(natom)
     706                 :             :  integer,intent(inout) :: symafm(msym),symrel(3,3,msym) !vz_i
     707                 :             :  real(dp),intent(in) :: gprimd(3,3),spinat(3,natom)
     708                 :             :  real(dp),intent(inout) :: xred(3,natom)
     709                 :             :  real(dp),optional,intent(in) :: invardir_red(3),invaraxial_red(3),chrgat(natom)
     710                 :             :  real(dp),optional, intent(in) :: nucdipmom(3,natom)
     711                 :             :  real(dp),intent(inout) :: tnons(3,msym) !vz_i
     712                 :             : 
     713                 :             : !Local variables-------------------------------
     714                 :             : !scalars
     715                 :             :  integer, save :: print_comment_tolsym=1
     716                 :             :  integer :: fixed_mismatch,mismatch_fft_tnons
     717                 :             :  integer :: ierr,isym,use_inversion
     718                 :             :  character(len=1000) :: msg
     719                 :             : !arrays
     720                 :        9002 :  integer,allocatable :: indsym(:,:,:),symrec(:,:,:)
     721                 :        9002 :  real(dp),allocatable :: tnons_new(:,:)
     722                 :             : !**************************************************************************
     723                 :             : 
     724                 :             : ! write(std_out,*)' m_symfind%symfind_expert : enter '
     725                 :             : 
     726                 :        9002 :  use_inversion=1
     727   [ +  +  +  +  :        9002 :  if (usepaw == 1 .and. (nspden==4.or.pawspnorb>0)) then
                   +  + ]
     728                 :         239 :    ABI_COMMENT("Removing inversion and improper rotations from initial space group because of PAW + SOC")
     729                 :             :    ! MMignolet: PAW can be used with inversion, however it results in seg faults in the dmft code. To enable when this is fixed...
     730                 :         239 :    use_inversion=0
     731                 :             :  end if
     732                 :             : 
     733                 :             :  ! write(std_out,*)' m_symfind%symfind_expert : before call symfind (1) '
     734                 :             : 
     735                 :             :  call symfind(gprimd,msym,natom,nptsym,nspden,nsym,&
     736                 :             :    prtvol,ptsymrel,spinat,symafm,symrel,tnons,tolsym,typat,use_inversion,xred,&
     737                 :        9002 :    chrgat=chrgat,nucdipmom=nucdipmom,ierr=ierr,invardir_red=invardir_red,invaraxial_red=invaraxial_red,invar_z=invar_z)
     738                 :             : 
     739                 :             :   ! write(std_out,*)' m_symfind%symfind_expert : after call symfind (1) '
     740                 :             : 
     741                 :             :   !If the group closure is not obtained, which should be exceptional, try with a larger tolsym (three times larger)
     742         [ +  + ]:        9002 :   if(ierr/=0)then
     743                 :           1 :     ABI_WARNING('Will try to obtain group closure by using a tripled tolsym.')
     744                 :             :     call symfind(gprimd,msym,natom,nptsym,nspden,nsym,&
     745                 :             :       prtvol,ptsymrel,spinat,symafm,symrel,tnons,three*tolsym,typat,use_inversion,xred,&
     746                 :           1 :       chrgat=chrgat,nucdipmom=nucdipmom,ierr=ierr,invardir_red=invardir_red,invaraxial_red=invaraxial_red,invar_z=invar_z)
     747         [ -  + ]:           1 :     ABI_CHECK(ierr==0,"Error in group closure")
     748                 :           1 :     ABI_WARNING('Succeeded to obtain group closure by using a tripled tolsym.')
     749                 :             :   endif
     750                 :             : 
     751                 :             :   ! If the tolerance on symmetries is bigger than 1.e-8, symmetrize tnons for gliding or screw operations,
     752                 :             :   ! symmetrize the atomic positions and recompute the symmetry operations
     753         [ +  + ]:        9002 :   if(tolsym>1.00001e-8)then
     754                 :             : 
     755                 :        8946 :     call symmetrize_tnons(nsym,symrel,tnons,tolsym)
     756   [ -  +  +  -  :       35784 :     ABI_MALLOC(indsym,(4,natom,nsym))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     757   [ -  +  +  -  :       26838 :     ABI_MALLOC(symrec,(3,3,nsym))
          +  -  +  -  -  
                +  +  - ]
     758         [ +  + ]:      299428 :     do isym=1,nsym
     759                 :      299428 :       call mati3inv(symrel(:,:,isym),symrec(:,:,isym))
     760                 :             :     end do
     761                 :        8946 :     call symatm(indsym,natom,nsym,symrec,tnons,tolsym,typat,xred)
     762                 :        8946 :     call symmetrize_xred(natom,nsym,symrel,tnons,xred,indsym=indsym)
     763         [ -  + ]:        8946 :     ABI_FREE(indsym)
     764         [ -  + ]:        8946 :     ABI_FREE(symrec)
     765                 :             : 
     766         [ +  + ]:        8946 :     if(print_comment_tolsym==1)then
     767                 :             :       write(msg,'(a,es12.3,18a)')&
     768                 :        1370 :         'The tolerance on symmetries =',tolsym,' is bigger than 1.0e-8.',ch10,&
     769                 :        1370 :         'In order to avoid spurious effects, the atomic coordinates have been',ch10,&
     770                 :        1370 :         'symmetrized before storing them in the dataset internal variable.',ch10,&
     771                 :        1370 :         'So, do not be surprised by the fact that your input variables (xcart, xred, ...)',ch10,&
     772                 :        1370 :         'do not correspond exactly to the ones echoed by ABINIT, the latter being used to do the calculations.',ch10,&
     773                 :        1370 :         'This is not a problem per se.',ch10,&
     774                 :        1370 :         'Still, in order to avoid this symmetrization (e.g. for specific debugging/development),',&
     775                 :        1370 :         ' decrease tolsym to 1.0e-8 or lower,',ch10,&
     776                 :        1370 :         'or (much preferred) use input primitive vectors that are accurate to better than 1.0e-8.',ch10,&
     777                 :        2740 :         'This message will only be printed once, even if there are other datasets where tolsym is bigger than 1.0e-8.'
     778                 :        1370 :       ABI_COMMENT(msg)
     779                 :        1370 :       print_comment_tolsym=0
     780                 :             :     endif
     781                 :             : 
     782                 :             : !write(std_out,*)' m_symfind%symfind_expert : before call symfind (3) '
     783                 :             : 
     784                 :             :     call symfind(gprimd,msym,natom,nptsym,nspden,nsym,&
     785                 :             :       prtvol,ptsymrel,spinat,symafm,symrel,tnons,tolsym,typat,use_inversion,xred,&
     786                 :        8946 :       chrgat=chrgat,nucdipmom=nucdipmom,invardir_red=invardir_red,invaraxial_red=invaraxial_red,invar_z=invar_z)
     787                 :             : 
     788                 :             : ! write(std_out,*)' m_symfind%symfind_expert : after call symfind (3) '
     789                 :             : 
     790                 :             :     !Needs one more resymmetrization, for the tnons
     791   [ -  +  +  -  :       26838 :     ABI_MALLOC(tnons_new,(3,nsym))
          +  -  +  -  -  
                +  -  + ]
     792                 :             : 
     793                 :             :     call symmetrize_xred(natom,nsym,symrel,tnons,xred,&
     794                 :        8946 :       fixed_mismatch=fixed_mismatch,mismatch_fft_tnons=mismatch_fft_tnons,tnons_new=tnons_new,tolsym=tolsym)
     795   [ +  +  +  + ]:     1170874 :     tnons(:,1:nsym)=tnons_new(:,:)
     796         [ -  + ]:       26838 :     ABI_FREE(tnons_new)
     797                 :             :   end if ! tolsym >1.00001e-8
     798                 :             : 
     799                 :             : ! write(std_out,*)' m_symfind%symfind_expert : exit '
     800                 :             : 
     801                 :        9002 : end subroutine symfind_expert
     802                 :             : !!***
     803                 :             : 
     804                 :             : !!****f* m_symfind/symanal
     805                 :             : !! NAME
     806                 :             : !! symanal
     807                 :             : !!
     808                 :             : !! FUNCTION
     809                 :             : !! Find the space group, Bravais lattice, including Shubnikov characteristics
     810                 :             : !! from the list of symmetries (including magnetic characteristics), and lattice parameters
     811                 :             : !! Warning: the recognition of the space group might not yet work for the
     812                 :             : !! Shubnikov group of type IV
     813                 :             : !!
     814                 :             : !! INPUTS
     815                 :             : !! chkprim= if 1 then stop if the cell is not primitive
     816                 :             : !! msym=default maximal number of symmetries
     817                 :             : !! nsym=actual number of symmetries
     818                 :             : !! rprimd(3,3)=dimensional primitive translations for real space (bohr)
     819                 :             : !! symafm(1:msym)=(anti)ferromagnetic part of symmetry operations
     820                 :             : !! symrel(3,3,1:msym)=symmetry operations in real space in terms
     821                 :             : !!  of primitive translations
     822                 :             : !! tnons(3,1:msym)=nonsymmorphic translations for symmetry operations
     823                 :             : !! tolsym=tolerance for the symmetry operations
     824                 :             : !! [verbose]= if true, will list the symmetry operation labels
     825                 :             : !!
     826                 :             : !! OUTPUT
     827                 :             : !! bravais(11)=characteristics of Bravais lattice (see symlatt.F90)
     828                 :             : !! genafm(3)=magnetic translation generator (in case of Shubnikov group type IV)
     829                 :             : !! ptgroupma = magnetic point group number
     830                 :             : !! spgroup=symmetry space group
     831                 :             : !!
     832                 :             : !! SOURCE
     833                 :             : 
     834                 :       12028 : subroutine symanal(bravais,chkprim,genafm,msym,nsym,ptgroupma,rprimd,spgroup,symafm,symrel,tnons,tolsym, &
     835                 :             :                    verbose) ! optional
     836                 :             : 
     837                 :             : !Arguments ------------------------------------
     838                 :             : !scalars
     839                 :             :  integer,intent(in) :: chkprim,msym,nsym
     840                 :             :  integer,intent(out) :: ptgroupma,spgroup
     841                 :             :  real(dp),intent(in) :: tolsym
     842                 :             :  logical,optional,intent(in) :: verbose
     843                 :             : !arrays
     844                 :             :  integer,intent(out) :: bravais(11)
     845                 :             :  integer,intent(in) :: symafm(msym),symrel(3,3,msym)
     846                 :             :  real(dp),intent(in) :: rprimd(3,3), tnons(3,msym)
     847                 :             :  real(dp),intent(out) :: genafm(3)
     848                 :             : 
     849                 :             : !Local variables-------------------------------
     850                 :             : !scalars
     851                 :             :  integer, parameter :: maxsym=192
     852                 :             : ! In this routine, maxsym is used either to determine the ptsymrel from the rprimd (routine symlatt),
     853                 :             : ! so, it might be up to 192 = 4*48 for FCC, and also to define the maximum number of symmetry operation labels,
     854                 :             : ! but only in case the cell is primitive, which gives the same upper bound. Thus in this routine, msym might
     855                 :             : ! be equal to nsym.
     856                 :             :  integer :: iholohedry_nomagn,isym,isym_nomagn,multi, nptsym,nsym_nomagn,shubnikov
     857                 :             :  logical :: verbose_
     858                 :             :  character(len=5) :: ptgroup,ptgroupha
     859                 :             :  character(len=500) :: msg
     860                 :             : !arrays
     861                 :             :  integer :: identity(3,3)
     862                 :       12028 :  integer,allocatable :: ptsymrel(:,:,:),symrel_nomagn(:,:,:)
     863                 :       12028 :  real(dp),allocatable :: tnons_nomagn(:,:)
     864                 :             :  character(len=128) :: labels(maxsym)
     865                 :             : ! *************************************************************************
     866                 :             : 
     867                 :             : !write(std_out,*)' symanal : enter'
     868                 :             : !write(std_out,*)' symanal : chkprim =',chkprim
     869                 :             : !write(std_out,*)' symanal : nsym=',nsym
     870                 :             : !do isym=1,nsym
     871                 :             : !  write(std_out,*)' symanal : symrel=',symrel(1:3,1:3,isym)
     872                 :             : !enddo
     873                 :             : 
     874                 :       12028 :  verbose_=.false.
     875         [ +  + ]:       12028 :  if (present(verbose)) verbose_=verbose
     876                 :             : 
     877                 :             : !This routine finds the Bravais characteristics, without actually looking at the symmetry operations.
     878         [ -  + ]:       12028 :  ABI_MALLOC(ptsymrel,(3,3,maxsym))
     879                 :       12028 :  call symlatt(bravais,dev_null,maxsym,nptsym,ptsymrel,rprimd,tolsym)
     880         [ -  + ]:       12028 :  ABI_FREE(ptsymrel)
     881                 :             : 
     882                 :             :  ! Check whether the cell is primitive or not.
     883                 :       12028 :  call chkprimit(chkprim,multi,nsym,symafm,symrel)
     884                 :             : 
     885                 :       12028 :  spgroup=0 ; ptgroupma=0 ; genafm(:)=zero
     886                 :             : 
     887         [ +  + ]:       12028 :  if (multi>1) then ! Modify bravais if the cell is not primitive ; no determination of the space group
     888                 :         289 :    bravais(1)=-bravais(1)
     889                 :             :  else
     890                 :             : 
     891                 :             :    ! The cell is primitive, so that the space group can be
     892                 :             :    ! determined. Need to distinguish Fedorov and Shubnikov groups.
     893                 :             :    ! Do not distinguish Shubnikov types I and II.
     894                 :             :    ! Also identify genafm, in case of Shubnikov type IV
     895                 :       11739 :    identity(:,:)=reshape((/1,0,0,0,1,0,0,0,1/),(/3,3/))
     896                 :       11739 :    shubnikov=1
     897         [ +  + ]:      299029 :    do isym=1,nsym
     898         [ +  + ]:      299029 :      if(symafm(isym)==-1)then
     899                 :        5756 :        shubnikov=3
     900   [ +  +  +  +  :       74828 :        if(sum(abs(symrel(:,:,isym)-identity(:,:)))==0)then
                   +  + ]
     901                 :         611 :          shubnikov=4
     902         [ +  + ]:        2444 :          genafm(:)=tnons(:,isym)
     903                 :             :          !write(std_out,*)' isym=',isym
     904                 :             :          !write(std_out,*)' symrel(:,:,isym)',symrel(:,:,isym)
     905                 :             :          !write(std_out,*)' tnons(:,isym)',tnons(:,isym)
     906                 :             :          !write(std_out,*)' symafm(isym)',symafm(isym)
     907                 :             :          exit
     908                 :             :        end if
     909                 :             :      end if
     910                 :             :    end do
     911                 :             : 
     912         [ +  + ]:       11739 :    if(shubnikov/=1)then
     913         [ +  + ]:        1515 :      if(shubnikov==3)write(msg, '(a)' )' Shubnikov space group type III'
     914         [ +  + ]:        1515 :      if(shubnikov==4)write(msg, '(a)' )' Shubnikov space group type IV'
     915                 :        1515 :      call wrtout(std_out,msg)
     916                 :             :    end if
     917                 :             : 
     918         [ +  + ]:       11739 :    if(shubnikov==1 .or. shubnikov==3)then
     919                 :             :      ! Find the correct Bravais characteristics and point group
     920                 :             :      ! Should also be used for Shubnikov groups of type IV ...
     921                 :       11128 :      call symbrav(bravais,msym,nsym,ptgroup,rprimd,symrel,tolsym)
     922                 :             : 
     923                 :             :      ! Find the space group
     924                 :       11128 :      call symspgr(bravais,labels,nsym,spgroup,symrel,tnons,tolsym)
     925                 :             : 
     926         [ +  + ]:       11128 :      if (verbose_) then
     927         [ +  + ]:        2275 :        do isym=1,nsym
     928         [ +  - ]:        2203 :          write(msg,'(a,i3,2a)')' symanal : the symmetry operation no. ',isym,' is ',trim(labels(isym))
     929                 :        2275 :          call wrtout(std_out,msg)
     930                 :             :        enddo
     931                 :             :      endif
     932                 :             : 
     933                 :             :    end if
     934                 :             : 
     935         [ +  + ]:       11128 :    if (shubnikov/=1) then
     936                 :             : 
     937                 :             :      ! Determine nonmagnetic symmetry operations
     938                 :        1515 :      nsym_nomagn=nsym/2
     939   [ -  +  +  -  :        4545 :      ABI_MALLOC(symrel_nomagn,(3,3,nsym_nomagn))
          +  -  +  -  -  
                +  -  + ]
     940   [ -  +  +  -  :        4545 :      ABI_MALLOC(tnons_nomagn,(3,nsym_nomagn))
          +  -  +  -  -  
                +  -  + ]
     941                 :        1515 :      isym_nomagn=0
     942         [ +  + ]:       23791 :      do isym=1,nsym
     943         [ +  + ]:       23791 :        if(symafm(isym)==1)then
     944                 :       11138 :          isym_nomagn=isym_nomagn+1
     945   [ +  +  +  + ]:      144794 :          symrel_nomagn(:,:,isym_nomagn)=symrel(:,:,isym)
     946         [ +  + ]:       44552 :          tnons_nomagn(:,isym_nomagn)=tnons(:,isym)
     947                 :             :        end if
     948                 :             :      end do
     949                 :             : 
     950         [ +  + ]:        1515 :      if (shubnikov==3) then
     951                 :             : 
     952                 :             :        ! write(std_out,*)' symanal : will enter symbrav with halved symmetry set'
     953                 :             :        ! write(std_out,*)' Describe the different symmetry operations (index,symrel,tnons,symafm)'
     954                 :             :        ! do isym=1,nsym_nomagn
     955                 :             :        ! write(std_out,'(i3,2x,9i3,3es12.2,i3)')isym,symrel_nomagn(:,:,isym),tnons_nomagn(:,isym)
     956                 :             :        ! end do
     957                 :             : 
     958                 :             :        ! Find the point group of the halved symmetry set
     959                 :         904 :        call symptgroup(iholohedry_nomagn,nsym_nomagn,ptgroupha,symrel_nomagn)
     960                 :             : 
     961                 :             :        ! Deduce the magnetic point group (ptgroupma) from ptgroup and ptgroupha
     962                 :         904 :        call getptgroupma(ptgroup,ptgroupha,ptgroupma)
     963                 :             : 
     964                 :         611 :      else if(shubnikov==4)then
     965                 :             : 
     966                 :             :        ! Find the Fedorov space group of the halved symmetry set
     967                 :         611 :        call symspgr(bravais,labels,nsym_nomagn,spgroup,symrel_nomagn,tnons_nomagn,tolsym)
     968                 :             : 
     969                 :             :        ! The magnetic translation generator genafm has already been determined
     970                 :             :        ! write(std_out,*)' genafm =',genafm, ' spgroup=',spgroup
     971         [ -  + ]:         611 :        if (verbose_) then
     972                 :           0 :          write(msg, '(a)' )' Select only the non-magnetic symmetry operations '
     973                 :           0 :          call wrtout(std_out,msg)
     974                 :             : 
     975         [ #  # ]:           0 :          do isym=1,nsym
     976         [ #  # ]:           0 :            if(symafm(isym)==1)then
     977                 :           0 :              isym_nomagn=isym_nomagn+1
     978         [ #  # ]:           0 :              write(msg,'(a,i3,2a)')' symspgr : the symmetry operation no. ',isym,' is ',trim(labels(isym_nomagn))
     979                 :           0 :              call wrtout(std_out,msg)
     980                 :             :            endif
     981                 :             :          enddo
     982                 :             :        endif
     983                 :             : 
     984                 :             :      end if
     985                 :             : 
     986         [ -  + ]:        1515 :      ABI_FREE(symrel_nomagn)
     987         [ -  + ]:        1515 :      ABI_FREE(tnons_nomagn)
     988                 :             :    end if ! Shubnikov groups
     989                 :             : 
     990                 :             :  end if
     991                 :             : 
     992                 :       12028 : end subroutine symanal
     993                 :             : !!***
     994                 :             : 
     995                 :             : !!****f* m_symfind/symbrav
     996                 :             : !! NAME
     997                 :             : !! symbrav
     998                 :             : !!
     999                 :             : !! FUNCTION
    1000                 :             : !! From the list of symmetry operations, and the lattice vectors,
    1001                 :             : !! determine the Bravais information (including the holohedry, the centering,
    1002                 :             : !! the coordinate of the primitive vectors in the conventional vectors),
    1003                 :             : !! as well as the point group.
    1004                 :             : !!
    1005                 :             : !! INPUTS
    1006                 :             : !! msym=dimension of symrel
    1007                 :             : !! nsym=actual number of symmetries
    1008                 :             : !! rprimd(3,3)=dimensional primitive translations for real space (bohr)
    1009                 :             : !! symrel(3,3,msym)=symmetry operations in real space in terms
    1010                 :             : !!                  of primitive translations
    1011                 :             : !! tolsym=tolerance for the symmetries
    1012                 :             : !!
    1013                 :             : !! OUTPUT
    1014                 :             : !! bravais(11): bravais(1)=iholohedry
    1015                 :             : !!              bravais(2)=center
    1016                 :             : !!              bravais(3:11)=coordinates of rprimd in the axes
    1017                 :             : !!              of the conventional bravais lattice (*2 if center/=0)
    1018                 :             : !! ptgroup=symmetry point group
    1019                 :             : !! [axis(3)]=Invariant axis in the conventional vector coordinates
    1020                 :             : !!   Set to (/0,0,0/) if the lattice belongs to the same holohedry as the lattice+atoms (+electric field + ...).
    1021                 :             : !!
    1022                 :             : !! SOURCE
    1023                 :             : 
    1024                 :       11128 : subroutine symbrav(bravais,msym,nsym,ptgroup,rprimd,symrel,tolsym,axis)
    1025                 :             : 
    1026                 :             : !Arguments ------------------------------------
    1027                 :             : !scalars
    1028                 :             :  integer,intent(in) :: msym,nsym
    1029                 :             :  real(dp),intent(in) :: tolsym
    1030                 :             :  character(len=5),intent(out) :: ptgroup
    1031                 :             : !arrays
    1032                 :             :  integer,intent(in) :: symrel(3,3,msym)
    1033                 :             :  integer,optional,intent(out) :: axis(3)
    1034                 :             :  integer,intent(out) :: bravais(11)
    1035                 :             :  real(dp),intent(in) :: rprimd(3,3)
    1036                 :             : 
    1037                 :             : !Local variables-------------------------------
    1038                 :             : !scalars
    1039                 :             :  integer :: iaxis,ii,bravais1now,ideform,iholohedry,invariant,isym
    1040                 :             :  integer :: jaxis,next_stage,nptsym,problem,maxsym
    1041                 :             :  integer, parameter :: naxes_ortho=22, naxes_hexa=7
    1042                 :             :  real(dp) :: norm,scprod
    1043                 :             :  character(len=500) :: msg
    1044                 :             : !arrays
    1045                 :             :  integer :: identity(3,3),axis_trial(3),hexa_axes(3,naxes_hexa),ortho_axes(3,naxes_ortho)
    1046                 :       11128 :  integer,allocatable :: ptsymrel(:,:,:),symrelconv(:,:,:)
    1047                 :             :  real(dp) :: axes(3,3),axis_cart(3),axis_red(3)
    1048                 :             :  real(dp) :: rprimdconv(3,3),rprimdtry(3,3),rprimdnow(3,3)
    1049                 :             :  real(dp) :: rprimdconv_invt(3,3)
    1050                 :             : !**************************************************************************
    1051                 :             : 
    1052                 :             : !DEBUG
    1053                 :             : !write(std_out,*)' symbrav : enter '
    1054                 :             : !call flush(std_out)
    1055                 :             : !ENDDEBUG
    1056                 :             : 
    1057                 :             :  identity(:,:)=0
    1058                 :       11128 :  identity(1,1)=1 ; identity(2,2)=1 ; identity(3,3)=1
    1059                 :             : 
    1060                 :       11128 :  ortho_axes(:,:)=0
    1061                 :       11128 :  ortho_axes(1,1)=1
    1062                 :       11128 :  ortho_axes(2,2)=1
    1063                 :       11128 :  ortho_axes(3,3)=1
    1064         [ +  + ]:       44512 :  ortho_axes(:,4)=(/0,1,1/)
    1065         [ +  + ]:       44512 :  ortho_axes(:,5)=(/1,0,1/)
    1066         [ +  + ]:       44512 :  ortho_axes(:,6)=(/1,1,0/)
    1067         [ +  + ]:       44512 :  ortho_axes(:,7)=(/0,1,-1/)
    1068         [ +  + ]:       44512 :  ortho_axes(:,8)=(/-1,0,1/)
    1069         [ +  + ]:       44512 :  ortho_axes(:,9)=(/1,-1,0/)
    1070         [ +  + ]:       44512 :  ortho_axes(:,10)=(/0,1,2/)
    1071         [ +  + ]:       44512 :  ortho_axes(:,11)=(/2,0,1/)
    1072         [ +  + ]:       44512 :  ortho_axes(:,12)=(/1,2,0/)
    1073         [ +  + ]:       44512 :  ortho_axes(:,13)=(/1,1,1/)
    1074         [ +  + ]:       44512 :  ortho_axes(:,14)=(/-1,1,1/)
    1075         [ +  + ]:       44512 :  ortho_axes(:,15)=(/1,-1,1/)
    1076         [ +  + ]:       44512 :  ortho_axes(:,16)=(/1,1,-1/)
    1077         [ +  + ]:       44512 :  ortho_axes(:,17)=(/2,1,1/)
    1078         [ +  + ]:       44512 :  ortho_axes(:,18)=(/1,2,1/)
    1079         [ +  + ]:       44512 :  ortho_axes(:,19)=(/1,1,2/)
    1080         [ +  + ]:       44512 :  ortho_axes(:,20)=(/2,1,-1/)
    1081         [ +  + ]:       44512 :  ortho_axes(:,21)=(/-1,2,1/)
    1082         [ +  + ]:       44512 :  ortho_axes(:,22)=(/1,-1,2/)
    1083                 :             : 
    1084                 :       11128 :  hexa_axes(:,:)=0
    1085                 :       11128 :  hexa_axes(1,1)=1
    1086                 :       11128 :  hexa_axes(2,2)=1
    1087                 :       11128 :  hexa_axes(3,3)=1
    1088         [ +  + ]:       44512 :  hexa_axes(:,4)=(/1,-1,0/)
    1089         [ +  + ]:       44512 :  hexa_axes(:,5)=(/2,1,0/)
    1090         [ +  + ]:       44512 :  hexa_axes(:,6)=(/1,1,0/)
    1091         [ +  + ]:       44512 :  hexa_axes(:,7)=(/1,2,0/)
    1092                 :             : 
    1093                 :             : !Determine the point group from the list of symmetry operations.
    1094                 :             : !Also determine the holohedry, up to one undeterminacy : hR versus hP
    1095                 :       11128 :  call symptgroup(iholohedry,nsym,ptgroup,symrel)
    1096                 :             : 
    1097                 :             : !DEBUG
    1098                 :             : !write(std_out,*)' symbrav, after symptgroup: nsym=',nsym
    1099                 :             : !call flush(std_out)
    1100                 :             : !write(std_out,*)' symbrav: symrel='
    1101                 :             : !do isym=1,nsym
    1102                 :             : !  write(std_out,'(9i4)')symrel(:,:,isym)
    1103                 :             : !enddo
    1104                 :             : !write(std_out,*)' symbrav: iholohedry=',iholohedry
    1105                 :             : !call flush(std_out)
    1106                 :             : !ENDDEBUG
    1107                 :             : 
    1108                 :             : !Loop over trial deformations
    1109                 :             : !This is needed in case the Bravais lattice determination from the lattice vectors
    1110                 :             : !has a higher holohedry than the real one, in which the symmetry
    1111                 :             : !operations for the atoms (or electric field, etc) are taken into account
    1112                 :       11128 :  iaxis=0
    1113                 :       11128 :  invariant=0
    1114                 :       11128 :  next_stage=0
    1115                 :       11128 :  rprimdnow(:,:)=rprimd(:,:)
    1116                 :       11128 :  rprimdtry(:,:)=rprimd(:,:)
    1117   [ -  +  +  -  :       33384 :  ABI_MALLOC(symrelconv,(3,3,nsym))
          +  -  +  -  -  
                +  +  - ]
    1118                 :             : 
    1119                 :             : !At most will have to try naxes_ortho*5 deformations (naxes_ortho axes, five stages)
    1120                 :             : !First, test whether the current recognition of Bravais lattice is problematic (iholohedry differs from bravais(1)).
    1121                 :             : !Then, if there is a problem, test different deformations of rprimd, one after the other.
    1122                 :             : !For each try, there is a new rprimdtry from the different set of deformation, that is generated later in the loop
    1123                 :             : !Also bravais1now and rprimdnow might changed (and progressively lowered).
    1124                 :             : !The latter change induces at most 5 stages for the computation (cubic->tetragonal->orthorhombic->monoclinic->triclinic).
    1125                 :             : !After an upgrade of bravais1now and rprimdnow, one has to restart the full set of deformations.
    1126                 :             : !Not sure that this procedure resolves all cases, but seems to work on >40000 inaccurate POSCAR files.
    1127         [ +  - ]:       15626 :  do ideform=1,naxes_ortho*5
    1128                 :             : 
    1129                 :       15626 :    maxsym=max(192,msym)
    1130   [ -  +  +  -  :       46878 :    ABI_MALLOC(ptsymrel,(3,3,maxsym))
          +  -  -  +  -  
                      + ]
    1131                 :       15626 :    call symlatt(bravais,std_out,maxsym,nptsym,ptsymrel,rprimdtry,tolsym)
    1132         [ -  + ]:       15626 :    ABI_FREE(ptsymrel)
    1133                 :             : 
    1134                 :             : !DEBUG
    1135                 :             : !write(std_out,*)' symbrav: inside loop with ideform,iaxis=',ideform,iaxis
    1136                 :             : !write(std_out,'(a,9f12.6)')' rprimdtry=',rprimdtry(:,:)
    1137                 :             : !write(std_out,'(a,2i4)')' bravais(1:2)=',bravais(1:2)
    1138                 :             : !call flush(std_out)
    1139                 :             : !ENDDEBUG
    1140                 :             : 
    1141                 :             : 
    1142                 :             : !  Examine the agreement with bravais(1)
    1143                 :             : !  Warning : might change Bravais lattice hR to hP, if hexagonal axes
    1144                 :       15626 :    problem=0
    1145                 :       23617 :    select case (bravais(1))
    1146                 :             :    case (7)
    1147         [ +  + ]:        7991 :      if(iholohedry<6)problem=1
    1148         [ -  + ]:        7991 :      if(iholohedry==6)problem=2
    1149                 :             :    case (6)
    1150         [ +  + ]:         669 :      if(iholohedry<4)problem=1
    1151         [ -  + ]:         669 :      if(iholohedry==7 .or. iholohedry==4)problem=2
    1152                 :             : !      Here, change hR into hP
    1153         [ +  + ]:         669 :      if(iholohedry==5)iholohedry=6
    1154                 :             :    case (5)
    1155         [ +  + ]:         806 :      if(iholohedry<4)problem=1
    1156         [ -  + ]:         806 :      if(iholohedry==7 .or. iholohedry==6 .or. iholohedry==4)problem=2
    1157                 :             :    case (4)
    1158         [ +  + ]:        2042 :      if(iholohedry<4)problem=1
    1159         [ -  + ]:        2042 :      if(iholohedry>4)problem=2
    1160                 :             :    case (3)
    1161         [ +  + ]:         898 :      if(iholohedry<3)problem=1
    1162         [ -  + ]:         898 :      if(iholohedry>3)problem=2
    1163                 :             :    case (2)
    1164         [ +  + ]:        1775 :      if(iholohedry<2)problem=1
    1165         [ -  + ]:        1775 :      if(iholohedry>2)problem=2
    1166                 :             :    case (1)
    1167   [ +  +  +  +  :       15626 :      if(iholohedry>1)problem=2
          +  +  +  -  -  
                      + ]
    1168                 :             :    end select
    1169                 :             : 
    1170                 :             : !  This is the usual situation, in which the lattice belong to the same holohedry
    1171                 :             : !  as the lattice+atoms (+electric field + ...)
    1172         [ +  + ]:       15626 :    if(problem==0)exit
    1173                 :             : 
    1174         [ -  + ]:        4498 :    if(problem==2)then
    1175         [ #  # ]:           0 :      if(iaxis==0)then
    1176                 :             :        write(msg, '(3a,i3,3a,i3,7a)' )&
    1177                 :           0 :         'The Bravais lattice determined only from the primitive',ch10,&
    1178                 :           0 :         'vectors (rprim or angdeg), bravais(1)=',bravais(1),', is not compatible',ch10,&
    1179                 :           0 :         'with the real one, iholohedry=',iholohedry,', obtained by taking into',ch10,&
    1180                 :           0 :         'account the symmetry operations. This might be due to an insufficient',ch10,&
    1181                 :           0 :         'number of digits in the specification of rprim (at least 10),',ch10,&
    1182                 :           0 :         'or to an erroneous rprim or angdeg. If this is not the case, then ...'
    1183                 :           0 :        ABI_BUG(msg)
    1184                 :             :      end if
    1185         [ #  # ]:           0 :      if(iaxis==1)then
    1186                 :             :        write(msg, '(3a,3i3,2a,i3,2a,i3)' )&
    1187                 :           0 :        'Could not succeed to determine the bravais lattice',ch10,&
    1188                 :           0 :        'problem,iaxis,invariant=',problem,iaxis,invariant,ch10,&
    1189                 :           0 :        'bravais(1)=',bravais(1),ch10,&
    1190                 :           0 :        'iholohedry=',iholohedry
    1191                 :           0 :        ABI_BUG(msg)
    1192                 :             :      end if
    1193                 :             : !    Try to increase tolsym to find the Bravais lattice.
    1194                 :             :      maxsym=max(192,msym)
    1195   [ #  #  #  #  :           0 :      ABI_MALLOC(ptsymrel,(3,3,maxsym))
             #  #  #  # ]
    1196                 :             : !DEBUG
    1197                 :             : !    write(6,*)' symbrav : will call symlatt, 3*tolsym=',3*tolsym
    1198                 :             : !ENDDEBUG
    1199                 :           0 :      call symlatt(bravais,std_out,maxsym,nptsym,ptsymrel,rprimdtry,3*tolsym)
    1200         [ #  # ]:           0 :      ABI_FREE(ptsymrel)
    1201         [ #  # ]:           0 :      if(bravais(1)==iholohedry)then
    1202                 :             : !      Succeeded
    1203                 :             :        exit
    1204                 :             :      else
    1205                 :             :        write(msg, '(3a,3i3,2a,i3,2a,i3)' )&
    1206                 :           0 :        'Could not succeed to determine the bravais lattice, even after considering a larger tolsym',ch10,&
    1207                 :           0 :        'problem,iaxis,invariant=',problem,iaxis,invariant,ch10,&
    1208                 :           0 :        'bravais(1)=',bravais(1),ch10,&
    1209                 :           0 :        'iholohedry=',iholohedry
    1210                 :           0 :        ABI_BUG(msg)
    1211                 :             :      end if
    1212                 :             :    end if
    1213                 :             : 
    1214         [ +  - ]:        4498 :    if(problem==1)then  ! One is left with the problem=1 case, basically iholohedry is lower than bravais(1)
    1215         [ +  + ]:        4498 :      if(iaxis==0)then
    1216                 :             :        write(msg, '(a,a,a,i3,a,a,a,i3,a,a,a)' )&
    1217                 :        2934 :        'The Bravais lattice determined only from the primitive',ch10,&
    1218                 :        2934 :        'vectors, bravais(1)=',bravais(1),', is more symmetric',ch10,&
    1219                 :        2934 :        'than the real one, iholohedry=',iholohedry,', obtained by taking into',ch10,&
    1220                 :        5868 :        'account the atomic positions. Start deforming the primitive vector set.'
    1221                 :        2934 :        ABI_COMMENT(msg)
    1222                 :             :        next_stage=1
    1223                 :             :      else if(iaxis/=0)then
    1224         [ +  + ]:        1564 :        if(bravais(1)<bravais1now)then
    1225                 :             :          write(msg, '(3a,i3,3a,i3,2a)' )&
    1226                 :        1349 :          'The Bravais lattice determined from modified primitive',ch10,&
    1227                 :        1349 :          'vectors, bravais(1)=',bravais(1),', has a lower symmetry than before,',ch10,&
    1228                 :        1349 :          'but is still more symmetric than the real one, iholohedry=',iholohedry,ch10,&
    1229                 :        2698 :          'obtained by taking into account the atomic positions.'
    1230                 :        1349 :          ABI_COMMENT(msg)
    1231                 :             :          next_stage=1
    1232         [ -  + ]:         215 :        else if(iaxis==1)then
    1233                 :             :          write(msg, '(3a,3i3,2a,i3,2a,i3)' )&
    1234                 :           0 :          'Could not succeed to determine the bravais lattice',ch10,&
    1235                 :           0 :          'problem,iaxis,invariant=',problem,iaxis,invariant,ch10,&
    1236                 :           0 :          'bravais(1)=',bravais(1),ch10,&
    1237                 :           0 :          'iholohedry=',iholohedry
    1238                 :           0 :          ABI_BUG(msg)
    1239                 :             :        end if
    1240                 :             :      end if
    1241                 :             :    end if ! problem==1
    1242                 :             : 
    1243                 :             : !  One is here when problem=1 (iholohedry < bravais(1)) and either
    1244                 :             : !  - iaxis=0 (no deformation has been tried yet),
    1245                 :             : !  - some deformation iaxis has been tried giving bravais(1), but iholohedry < bravais(1) < bravais1now
    1246                 :             : !  - some deformation iaxis has been tried giving bravais(1), but iholohedry < bravais(1) = bravais1now and iaxis/=1 .
    1247                 :             : !  Also, note that next_stage is still 0 when bravais(1)=bravais1now .
    1248                 :             : !  The loop has been ended (so, the search failed) when bravais(1)=bravais1now and iaxis==1.
    1249                 :             : 
    1250                 :             :    if(next_stage==1)then
    1251                 :        4283 :      bravais1now=bravais(1)
    1252                 :        4283 :      rprimdnow(:,:)=rprimdtry(:,:)
    1253                 :             : !    Generate the symmetry operations in the conventional vector coordinates
    1254         [ +  + ]:       17132 :      rprimdconv(:,1)=bravais(3:5)
    1255         [ +  + ]:       17132 :      rprimdconv(:,2)=bravais(6:8)
    1256         [ +  + ]:       17132 :      rprimdconv(:,3)=bravais(9:11)
    1257                 :        4283 :      axes(:,:)=zero
    1258                 :        4283 :      axes(1,1)=one ; axes(2,2)=one ; axes(3,3)=one
    1259   [ +  +  +  +  :      211269 :      symrelconv(:,:,1:nsym)=symrel(:,:,1:nsym)
                   +  + ]
    1260                 :        4283 :      call symrelrot(nsym,rprimdconv,axes,symrelconv,tolsym)
    1261         [ +  + ]:        4283 :      if(bravais(1)/=6)then
    1262                 :        4266 :        iaxis=naxes_ortho+1
    1263                 :             :      else
    1264                 :          17 :        iaxis=naxes_hexa+1
    1265                 :             :      end if
    1266                 :             :      next_stage=0
    1267                 :             : !DEBUG
    1268                 :             : !    write(std_out,*)' symbrav: next stage, bravais(1), bravais(2) and symrelconv'
    1269                 :             : !    write(std_out,'(a,2i4)')' bravais(1:2)=',bravais(1:2)
    1270                 :             : !    write(std_out,'(a,9f12.6)')' rprimdconv=',rprimdconv(:,:)
    1271                 :             : !    do isym=1,nsym
    1272                 :             : !      write(std_out,'(9i4)')symrelconv(:,:,isym)
    1273                 :             : !    enddo
    1274                 :             : !    call flush(std_out)
    1275                 :             : !ENDDEBUG
    1276                 :             :    end if
    1277                 :             : 
    1278                 :             : !  Go to the next iaxis that will be left invariant
    1279                 :        4498 :    iaxis=iaxis-1
    1280         [ +  - ]:       25008 :    do jaxis=iaxis,1,-1
    1281         [ +  + ]:       25008 :      if(bravais(1)/=6)then
    1282         [ +  + ]:       99956 :        axis_trial(:)=ortho_axes(:,jaxis)
    1283                 :             :      else
    1284         [ +  + ]:          76 :        axis_trial(:)=hexa_axes(:,jaxis)
    1285                 :             :      end if
    1286                 :             : !    DEBUG
    1287                 :             : !    write(std_out,*)' symbrav : ixaxis, trial jaxis=',iaxis,jaxis
    1288                 :             : !    write(std_out,*)' axis_trial=',axis_trial
    1289                 :             : !    ENDDEBUG
    1290                 :       25008 :      invariant=1
    1291                 :             : !    Examine whether all symmetry operations leave the axis invariant (might be reversed, though)
    1292         [ +  + ]:      225362 :      do isym=1,nsym
    1293   [ -  +  +  +  :     1803186 :        if(sum(abs(matmul(symrelconv(:,:,isym),axis_trial)+(-axis_trial(:))))/=0 .and. &
             +  +  +  + ]
    1294   [ +  +  +  +  :     7037398 :        sum(abs(matmul(symrelconv(:,:,isym),axis_trial)+axis_trial(:)))/=0 )invariant=0
          +  +  +  +  +  
          +  +  +  +  -  
                   +  - ]
    1295                 :             :      end do
    1296         [ +  + ]:       25008 :      if(invariant==1)then
    1297                 :        4498 :        iaxis=jaxis
    1298                 :             : !DEBUG
    1299                 :             : !      write(msg, '(2a,i3)' )ch10,' symbrav : found invariant axis, jaxis=',jaxis
    1300                 :             : !      call wrtout(std_out,msg)
    1301                 :             : !ENDDEBUG
    1302                 :        4498 :        exit
    1303                 :             :      end if
    1304                 :             :    end do
    1305                 :             : 
    1306         [ -  + ]:        4498 :    if(invariant==0)then
    1307                 :             : !    Not a single axis was invariant with respect to all operations ?!
    1308                 :             : !    do isym=1,nsym; write(std_out, '(a,10i4)' )' isym,symrelconv=',isym,symrelconv(:,:,isym); enddo
    1309                 :             :      write(msg, '(3a,3i3,2a,i3,2a,i3)' )&
    1310                 :           0 :      'Could not succeed to determine the bravais lattice (not a single invariant)',ch10,&
    1311                 :           0 :      'problem,iaxis,invariant=',problem,iaxis,invariant,ch10,&
    1312                 :           0 :      'bravais(1)=',bravais(1),ch10,&
    1313                 :           0 :      'iholohedry=',iholohedry
    1314                 :           0 :      ABI_BUG(msg)
    1315                 :             :    end if
    1316                 :             : 
    1317                 :        4498 :    call matr3inv(rprimdconv,rprimdconv_invt)
    1318                 :             :    axis_red(:)=axis_trial(1)*rprimdconv_invt(1,:)+ &
    1319                 :             : &   axis_trial(2)*rprimdconv_invt(2,:)+ &
    1320         [ +  + ]:       17992 : &   axis_trial(3)*rprimdconv_invt(3,:)
    1321                 :             :    axis_cart(:)=axis_red(1)*rprimdnow(:,1)+ &
    1322                 :             : &   axis_red(2)*rprimdnow(:,2)+ &
    1323         [ +  + ]:       17992 : &   axis_red(3)*rprimdnow(:,3)
    1324         [ +  + ]:       17992 :    norm=sum(axis_cart(:)**2)
    1325                 :             : !DEBUG
    1326                 :             : !  write(6,*)' axis_trial =',axis_trial
    1327                 :             : !  write(6,*)' axis_red =',axis_red
    1328                 :             : !  write(6,*)' axis_cart =',axis_cart
    1329                 :             : !  write(6,*)' rprimdnow=',rprimdnow
    1330                 :             : !ENDDEBUG
    1331                 :             : !  Expand by a uniform, quite arbitrary, dilatation, along the invariant axis
    1332                 :             : !  Note : make these dilatation different, according to ideform
    1333                 :             : !  XG 20151221  : Still, the interplay between the size of the deformation and the tolsym is not easy to address.
    1334                 :             : !  Indeed the deformation must be sufficiently large to be perceived by symlatt as a real breaking of the
    1335                 :             : !  symmetry of the lattice. In order to deal with all the small values od tolsym, it has been set at a minimum of tol3,
    1336                 :             : !  but it must also be larger than tolsym. Moreover, for some axis choice, the deformation is not aligned with the axis, decreasing
    1337                 :             : !  the effective deformation length. An additional factor of three is thus included, actually increased to six just to be sure...
    1338         [ +  + ]:       44746 :    do ii=1,3
    1339                 :       13494 :      scprod=axis_cart(1)*rprimdnow(1,ii)+axis_cart(2)*rprimdnow(2,ii)+axis_cart(3)*rprimdnow(3,ii)
    1340         [ +  + ]:       58474 :      rprimdtry(:,ii)=rprimdnow(:,ii)+ideform*(max(tol3,six*tolsym)-tol6)*scprod/norm*axis_cart(:)
    1341                 :             :    end do
    1342                 :             : 
    1343                 :             : !DEBUG
    1344                 :             : !  write(6,*)' rprimdtry=',rprimdtry
    1345                 :             : !ENDDEBUG
    1346                 :             : 
    1347                 :             :  end do ! ideform
    1348                 :             : 
    1349         [ -  + ]:       11128 :  if(bravais(1)/=iholohedry)then
    1350                 :             :    write(msg, '(3a,3i3,2a,i3,2a,i3)' )&
    1351                 :           0 :    'Despite efforts, Could not succeed to determine the bravais lattice :',ch10,&
    1352                 :           0 :    'bravais(1)=',bravais(1),ch10,&
    1353                 :           0 :    'iholohedry=',iholohedry
    1354                 :           0 :    ABI_BUG(msg)
    1355                 :             :  end if
    1356                 :             : 
    1357         [ -  + ]:       11128 :  ABI_FREE(symrelconv)
    1358                 :             : 
    1359         [ -  + ]:       11128 :  if (PRESENT(axis)) then  ! Return symmetry axis.
    1360                 :           0 :    axis=(/0,0,0/)
    1361         [ #  # ]:           0 :    if (iaxis/=0) then
    1362         [ #  # ]:           0 :      if(bravais(1)/=6)then
    1363         [ #  # ]:           0 :        axis=ortho_axes(:,iaxis)
    1364                 :             :      else
    1365         [ #  # ]:           0 :        axis=hexa_axes(:,iaxis)
    1366                 :             :      end if
    1367                 :             :    end if
    1368                 :             :  end if
    1369                 :             : 
    1370                 :             : !DEBUG
    1371                 :             : !write(std_out,'(a)')' symbrav : exit '
    1372                 :             : !ENDDEBUG
    1373                 :             : 
    1374                 :       11128 : end subroutine symbrav
    1375                 :             : !!***
    1376                 :             : 
    1377                 :             : !!****f* m_symfind/symspgr
    1378                 :             : !! NAME
    1379                 :             : !! symspgr
    1380                 :             : !!
    1381                 :             : !! FUNCTION
    1382                 :             : !! Find the type of each symmetry operation (calling symcharac):
    1383                 :             : !!   proper symmetries 1,2,2_1,3,3_1,3_2,4,4_1,4_2,4_3,6,6_1,...6_5
    1384                 :             : !!   improper symmetries -1,m,a,b,c,d,n,g,-3,-4,-6 ,
    1385                 :             : !! Then, build an array with the number of such operations.
    1386                 :             : !! Then, call symlist to identify the space group.
    1387                 :             : !!
    1388                 :             : !! INPUTS
    1389                 :             : !! bravais(11): bravais(1)=iholohedry
    1390                 :             : !!              bravais(2)=center
    1391                 :             : !!              bravais(3:11)=coordinates of rprimd in the axes
    1392                 :             : !!              of the conventional bravais lattice (*2 if center/=0)
    1393                 :             : !! nsym=actual number of symmetries
    1394                 :             : !! symrel(3,3,nsym)= nsym symmetry operations in real space in terms
    1395                 :             : !!   of primitive translations
    1396                 :             : !! tnons(3,nsym)=nonsymmorphic translations for each symmetry (would
    1397                 :             : !!   be 0 0 0 each for a symmorphic space group)
    1398                 :             : !!
    1399                 :             : !! OUTPUT
    1400                 :             : !! labels(maxsym=192)= labels of the symmetry operations
    1401                 :             : !! spgroup=symmetry space group number
    1402                 :             : !!
    1403                 :             : !! NOTES
    1404                 :             : !! It is assumed that the symmetry operations will be entered in the
    1405                 :             : !! symrel tnons arrays, for the PRIMITIVE cell. The matrix of transformation
    1406                 :             : !! from the primitive cell to the conventional cell is described
    1407                 :             : !! in the array "bravais" (see symlatt.F90).
    1408                 :             : !! The present routine first make the transformation from the
    1409                 :             : !! primitive coordinates to the conventional ones, then eventually
    1410                 :             : !! generate additional symmetries, taking into account the
    1411                 :             : !! centering translations.
    1412                 :             : !! Then, the order and determinant of each symmetry operation
    1413                 :             : !! is determined.
    1414                 :             : !!
    1415                 :             : !! For proper symmetries (rotations), the
    1416                 :             : !! associated translation is also determined.
    1417                 :             : !! However, left or right handed screw rotations are
    1418                 :             : !! not (presently) distinguished, and will be attributed equally
    1419                 :             : !! to left or right.
    1420                 :             : !!
    1421                 :             : !! For the detailed description of the labelling of the axes, see symaxes.f and symplanes.f
    1422                 :             : !!
    1423                 :             : !! SOURCE
    1424                 :             : 
    1425                 :       11739 : subroutine symspgr(bravais,labels,nsym,spgroup,symrel,tnons,tolsym)
    1426                 :             : 
    1427                 :             :  use m_numeric_tools, only : OPERATOR(.x.)
    1428                 :             : 
    1429                 :             : !Arguments ------------------------------------
    1430                 :             : !scalars
    1431                 :             :  integer,intent(in) :: nsym
    1432                 :             :  integer,intent(out) :: spgroup
    1433                 :             :  real(dp),intent(in) :: tolsym
    1434                 :             : !arrays
    1435                 :             :  integer,intent(in) :: bravais(11),symrel(3,3,nsym)
    1436                 :             :  real(dp),intent(in) :: tnons(3,nsym)
    1437                 :             :  character(len=128),intent(out) :: labels(192) ! 192 = maxsym
    1438                 :             : 
    1439                 :             : !Local variables-------------------------------
    1440                 :             : !scalars
    1441                 :             : ! logical,parameter :: verbose=.FALSE.
    1442                 :             :  integer :: additional_info,brvltt,center,direction=0,found,iholohedry,ii
    1443                 :             :  integer :: ishift,isym,jj,nshift,nsymconv,spgaxor,spgorig,sporder
    1444                 :             :  character(len=1) :: brvsb
    1445                 :             :  character(len=15) :: intsb,ptintsb,ptschsb,schsb
    1446                 :             :  character(len=35) :: intsbl
    1447                 :             :  character(len=500) :: msg
    1448                 :             : !arrays
    1449                 :             :  integer :: ivec1(3), ivec2(3)
    1450                 :             :  integer :: n_axes(31),n_axest(31),prime(5),test_direction(3),symrel_uni(3,3)
    1451                 :             :  integer :: uniaxis(3),uniaxis_try(3)
    1452                 :       11739 :  integer,allocatable :: determinant(:),symrelconv(:,:,:),t_axes(:)
    1453                 :             :  real(dp) :: axes(3,3),rprimdconv(3,3),vect(3,3)
    1454                 :       11739 :  real(dp),allocatable :: shift(:,:),tnonsconv(:,:)
    1455                 :             : !**************************************************************************
    1456                 :             : 
    1457                 :             :  DBG_ENTER("COLL")
    1458                 :             : 
    1459                 :             : !Initialize brvltt, from bravais(2) and bravais(1)
    1460                 :       11739 :  center=bravais(2)
    1461                 :       11739 :  iholohedry=bravais(1)
    1462                 :       11739 :  brvltt=1
    1463         [ +  + ]:       11739 :  if(center==-1)brvltt=2  ! Inner centering
    1464         [ +  + ]:       11739 :  if(center==-3)brvltt=3  ! Face centering
    1465         [ +  + ]:       11739 :  if(center==1)brvltt=5  ! A-Face centering
    1466         [ +  + ]:       11739 :  if(center==2)brvltt=6  ! B-Face centering
    1467         [ +  + ]:       11739 :  if(center==3)brvltt=4  ! C-Face centering
    1468         [ +  + ]:       11739 :  if(iholohedry==5)brvltt=7  ! Rhombohedral
    1469                 :             : 
    1470                 :             : !Produce the symmetry operations, in the axis of the conventional cell
    1471                 :       11739 :  nsymconv=nsym
    1472         [ +  + ]:       11739 :  if(center/=0)nsymconv=2*nsymconv
    1473         [ +  + ]:       11739 :  if(center==-3)nsymconv=4*nsym
    1474   [ -  +  +  -  :       35217 :  ABI_MALLOC(symrelconv,(3,3,nsymconv))
          +  -  +  -  -  
                +  -  + ]
    1475   [ -  +  +  -  :       35217 :  ABI_MALLOC(tnonsconv,(3,nsymconv))
          +  -  +  -  -  
                +  -  + ]
    1476                 :             : 
    1477                 :             : !Produce symrel and tnons in conventional axes,
    1478                 :             : !name them symrelconv and tnonsconv
    1479         [ +  + ]:       46956 :  rprimdconv(:,1)=bravais(3:5)
    1480         [ +  + ]:       46956 :  rprimdconv(:,2)=bravais(6:8)
    1481         [ +  + ]:       46956 :  rprimdconv(:,3)=bravais(9:11)
    1482                 :             : 
    1483   [ +  +  +  +  :       79803 :  if(center/=0)rprimdconv(:,:)=rprimdconv(:,:)*half
                   +  + ]
    1484                 :             : 
    1485                 :       11739 :  axes(:,:)=zero
    1486                 :       11739 :  axes(1,1)=one ; axes(2,2)=one ; axes(3,3)=one
    1487   [ +  +  +  +  :     3764852 :  symrelconv(:,:,1:nsym)=symrel(:,:,1:nsym)
                   +  + ]
    1488                 :             : !Note that the number of symmetry operations is still nsym
    1489                 :       11739 :  call symrelrot(nsym,rprimdconv,axes,symrelconv,tolsym)
    1490                 :             : 
    1491                 :       11739 :  call xred2xcart(nsym,rprimdconv,tnonsconv,tnons)
    1492                 :             : !Gives the associated translation, with components in the interval ]-0.5,0.5] .
    1493   [ +  +  +  + ]:     1166543 :  tnonsconv(:,1:nsym)=tnonsconv(:,1:nsym)-nint(tnonsconv(:,1:nsym)-tol6)
    1494                 :             : 
    1495                 :             : !If the Bravais lattice is centered, duplicate or quadruplicate
    1496                 :             : !the number of symmetry operations, using the Bravais lattice shifts
    1497                 :       11739 :  nshift=1
    1498         [ +  + ]:       11739 :  if(center/=0)nshift=2
    1499         [ +  + ]:       11739 :  if(center==-3)nshift=4
    1500   [ -  +  +  -  :       23478 :  ABI_MALLOC(shift,(3,nshift))
             -  +  -  + ]
    1501         [ +  + ]:       46956 :  shift(:,1)=zero
    1502         [ +  + ]:       11739 :  if(center/=0 .and. center/=-3)then
    1503         [ +  + ]:        5188 :    shift(:,2)=half
    1504         [ +  + ]:        1297 :    if(center==1)shift(1,2)=zero
    1505         [ +  + ]:        1297 :    if(center==2)shift(2,2)=zero
    1506         [ +  + ]:        1297 :    if(center==3)shift(3,2)=zero
    1507         [ +  + ]:       10442 :  else if(center==-3)then
    1508         [ +  + ]:       17500 :    shift(:,2)=half ; shift(1,2)=zero
    1509         [ +  + ]:       17500 :    shift(:,3)=half ; shift(2,3)=zero
    1510         [ +  + ]:       17500 :    shift(:,4)=half ; shift(3,4)=zero
    1511                 :             :  end if ! center/=0 or -3
    1512         [ +  + ]:       11739 :  if(nshift/=1)then
    1513         [ +  + ]:       20094 :    do ishift=2,nshift
    1514   [ +  -  +  +  :    14844718 :      symrelconv(:,:,(ishift-1)*nsym+1:ishift*nsym)=symrelconv(:,:,1:nsym)
          +  +  +  +  +  
             +  +  +  +  
                      + ]
    1515         [ +  + ]:      590490 :      do isym=1,nsym
    1516         [ +  + ]:     2296006 :        tnonsconv(:,(ishift-1)*nsym+isym)=tnonsconv(:,isym)+shift(:,ishift)
    1517                 :             :      end do
    1518                 :             :    end do ! ishift
    1519                 :             :  end if ! nshift/=1
    1520                 :             : 
    1521                 :             : !At this stage, all the symmetry operations are available,
    1522                 :             : !expressed in the conventional axis, and also include
    1523                 :             : !the Bravais lattive translations, and associated operations...
    1524                 :             : 
    1525                 :       11739 :  n_axes(:)=0
    1526                 :             : 
    1527   [ -  +  +  -  :       35217 :  ABI_MALLOC(determinant,(nsymconv))
          +  -  +  -  -  
                +  -  + ]
    1528                 :             : 
    1529                 :             : !Get the determinant
    1530                 :       11739 :  call symdet(determinant,nsymconv,symrelconv)
    1531                 :             : 
    1532                 :             : !Get the order of each the symmetry operation, as well as the maximal order
    1533                 :             : !Also, examine whether each symmetry operation is the inversion, or a root of the inversion (like -3)
    1534                 :             : !Decide which kind of point symmetry operation it is
    1535                 :             : !Finally assign tnonsconv order and decide the space symmetry operation
    1536                 :             : 
    1537   [ -  +  +  -  :       23478 :  ABI_MALLOC(t_axes,(nsymconv))
             -  +  -  + ]
    1538                 :             : 
    1539         [ +  + ]:      870836 :  do isym=1,nsymconv
    1540                 :             : 
    1541                 :             : !  Note : nsymconv might be bigger than 192, but only for non-primitive cells, in which case labels will not be echoed anywhere.
    1542                 :             : !  192 is the fixed dimension of labels, so this avoids possible memory problems.
    1543                 :             :    call symcharac(center, determinant(isym), iholohedry, isym, labels(mod(isym-1,192)+1), &
    1544                 :      859097 :    symrelconv(:,:,isym), tnonsconv(:,isym), t_axes(isym))
    1545         [ -  + ]:      859097 :    if (t_axes(isym) == -1) then
    1546                 :           0 :      write(msg, '(a,a,i3,a,3(a,3i4,a),a,3es22.12,a,a,3es22.12)' )ch10,&
    1547                 :           0 :      ' symspgr: problem with isym=',isym,ch10,&
    1548                 :           0 :      '  symrelconv(:,1,isym)=',symrelconv(:,1,isym),ch10,&
    1549                 :           0 :      '  symrelconv(:,2,isym)=',symrelconv(:,2,isym),ch10,&
    1550                 :           0 :      '  symrelconv(:,3,isym)=',symrelconv(:,3,isym),ch10,&
    1551                 :           0 :      '  tnonsconv(:,isym)=',tnonsconv(:,isym)
    1552                 :           0 :      call wrtout(std_out,msg)
    1553                 :           0 :      write(msg, '(a,i0,2a)' )'The space symmetry operation number',isym,ch10,'is not a (translated) root of unity'
    1554                 :           0 :      ABI_BUG(msg)
    1555         [ -  + ]:      859097 :    else if (t_axes(isym) == -2) then
    1556                 :           0 :      write(msg, '(a,i0,a)' )'The symmetry operation number ',isym,' is not a root of unity'
    1557                 :           0 :      ABI_BUG(msg)
    1558                 :             :    end if
    1559                 :             : 
    1560                 :      870836 :    n_axes(t_axes(isym))=n_axes(t_axes(isym))+1
    1561                 :             :  end do ! isym=1,nsymconv
    1562                 :             : 
    1563   [ +  +  -  + ]:      375648 :  if (sum(n_axes)-nsymconv/=0) then
    1564                 :             :    write(msg, '(7a)' )&
    1565                 :           0 :    'Not all the symmetries have been recognized. ',ch10,&
    1566                 :           0 :    'This might be due either to an error in the input file',ch10,&
    1567                 :           0 :    'or to a BUG in ABINIT',ch10,&
    1568                 :           0 :    'Please contact the ABINIT group.'
    1569                 :           0 :    ABI_WARNING(msg)
    1570                 :             :  end if
    1571                 :             : 
    1572                 :             :  !write(std_out,*)' symspgr : brvltt,nsymconv=',brvltt,nsymconv
    1573                 :             :  !write(std_out,*)' n_axes(1:10)=',n_axes(1:10)
    1574                 :             :  !write(std_out,*)' n_axes(11:20)=',n_axes(11:20)
    1575                 :             :  !write(std_out,*)' n_axes(21:31)=',n_axes(21:31)
    1576                 :             : 
    1577                 :             : !Treat cases in which the space group cannot be identified on the
    1578                 :             : !basis of n_axes one need additional information
    1579         [ +  + ]:       11739 :  if(brvltt==1)then
    1580                 :             : !  If the bravais lattice is primitive
    1581         [ +  + ]:        5255 :    if(nsymconv==4)then
    1582                 :         309 :      n_axest=(/0,0,0,0,0,0,0,1,1,0,  0,0,0,0,0,2,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0/)
    1583   [ +  +  +  + ]:        9888 :      if(sum((n_axes-n_axest)**2)==0)then    ! Spgroup 27 (Pcc2) or 32 (Pba2)
    1584                 :          16 :        write(std_out,*)' symspgr: 27 or 32'
    1585                 :          16 :        additional_info=2
    1586                 :             : !      Select binary axis
    1587         [ +  + ]:          80 :        do isym=1,nsymconv
    1588         [ +  + ]:          80 :          if(t_axes(isym)==8)then
    1589                 :             : !          Find direction of binary axis
    1590         [ +  - ]:          16 :            if(symrelconv(1,1,isym)==1)direction=1
    1591         [ +  - ]:          16 :            if(symrelconv(2,2,isym)==1)direction=2
    1592         [ +  - ]:          16 :            if(symrelconv(3,3,isym)==1)direction=3
    1593                 :             :          end if
    1594                 :             :        end do
    1595                 :             : !      Examine the projection of the translation vector of the a, b or c mirror planes onto the binary axis
    1596         [ +  + ]:          80 :        do isym=1,nsymconv
    1597         [ +  + ]:          80 :          if(t_axes(isym)==16)then
    1598         [ +  + ]:          32 :            if(abs(tnonsconv(direction,isym))>tol8)additional_info=1
    1599                 :             :          end if
    1600                 :             :        end do
    1601                 :             :      end if
    1602         [ +  + ]:        4946 :    else if(nsymconv==8)then
    1603                 :         881 :      n_axest=(/0,0,0,0,1,0,0,1,1,0,  0,0,0,0,1,2,0,0,0,2,  0,0,0,0,0,0,0,0,0,0,0/)
    1604   [ +  +  +  + ]:       28192 :      if(sum((n_axes-n_axest)**2)==0)then    ! Spgroup 55 (Pbam) or 57 (Pbcm)
    1605                 :          26 :        write(std_out,*)' symspgr: 55 or 57'
    1606                 :          26 :        additional_info=1
    1607                 :             : !      Select mirror plane m
    1608         [ +  + ]:         234 :        do isym=1,nsymconv
    1609         [ +  + ]:         234 :          if(t_axes(isym)==15)then
    1610                 :             : !          Find direction of mirror plane
    1611         [ -  + ]:          26 :            if(symrelconv(1,1,isym)==-1)direction=1
    1612         [ -  + ]:          26 :            if(symrelconv(2,2,isym)==-1)direction=2
    1613         [ +  - ]:          26 :            if(symrelconv(3,3,isym)==-1)direction=3
    1614                 :             :          end if
    1615                 :             :        end do
    1616                 :             : !      Examine the projection of the translation vector of the a, b, or c mirror planes
    1617                 :             : !      onto the binary axis
    1618         [ +  + ]:         234 :        do isym=1,nsymconv
    1619         [ +  + ]:         234 :          if(t_axes(isym)==16)then
    1620         [ +  + ]:          52 :            if(abs(tnonsconv(direction,isym))>tol8)additional_info=2
    1621                 :             :          end if
    1622                 :             :        end do
    1623                 :             :      end if
    1624                 :         881 :      n_axest=(/0,0,0,0,1,0,0,1,1,0,  0,0,0,0,0,2,0,1,0,2,  0,0,0,0,0,0,0,0,0,0,0/)
    1625   [ +  +  +  + ]:       28192 :      if(sum((n_axes-n_axest)**2)==0)then    ! Spgroup 56 (Pccn) or 60 (Pbcn)
    1626                 :          26 :        write(std_out,*)' symspgr: 56 or 60'
    1627                 :          26 :        additional_info=1
    1628                 :             : !      Select mirror plane n
    1629         [ +  + ]:         234 :        do isym=1,nsymconv
    1630         [ +  + ]:         234 :          if(t_axes(isym)==18)then
    1631                 :             : !          Find direction of mirror plane
    1632         [ -  + ]:          26 :            if(symrelconv(1,1,isym)==-1)direction=1
    1633         [ -  + ]:          26 :            if(symrelconv(2,2,isym)==-1)direction=2
    1634         [ +  - ]:          26 :            if(symrelconv(3,3,isym)==-1)direction=3
    1635                 :             :          end if
    1636                 :             :        end do
    1637                 :             : !      Examine the projection of the translation vector of the a, b, or c mirror planes
    1638                 :             : !      onto the binary axis
    1639         [ +  + ]:         234 :        do isym=1,nsymconv
    1640         [ +  + ]:         234 :          if(t_axes(isym)==16)then
    1641         [ +  + ]:          52 :            if(abs(tnonsconv(direction,isym))<tol8)additional_info=2
    1642                 :             :          end if
    1643                 :             :        end do
    1644                 :             :      end if
    1645                 :             :    end if
    1646         [ +  + ]:        6484 :  else if(brvltt==2)then
    1647                 :             : !  In the few next lines, use additional_info as a flag
    1648                 :         698 :    additional_info=0
    1649                 :             : !  If the bravais lattice is inner-centered
    1650         [ +  + ]:         698 :    if(nsymconv==8)then
    1651                 :             : !    Test spgroup 23 (I222) or 24 (I2_{1}2_{1}2_{1})
    1652                 :         105 :      n_axest=(/0,0,0,0,0,0,1,1,3,0,  0,0,0,0,0,0,0,0,0,3,  0,0,0,0,0,0,0,0,0,0,0/)
    1653   [ +  +  +  + ]:        3360 :      if(sum((n_axes-n_axest)**2)==0) additional_info=1
    1654         [ +  + ]:         593 :    else if(nsymconv==24)then
    1655                 :             : !    Test spgroup 197 (I23) or 199 (I2_{1}3)
    1656                 :           2 :      n_axest=(/0,0,0,0,0,0,1,1,3,16, 0,0,0,0,0,0,0,0,0,3,  0,0,0,0,0,0,0,0,0,0,0/)
    1657   [ +  +  +  - ]:          64 :      if(sum((n_axes-n_axest)**2)==0) additional_info=1
    1658                 :             :    end if
    1659         [ +  + ]:         698 :    if(additional_info==1)then
    1660                 :           8 :      write(std_out,*)' symspgr: (23 or 24) or (197 or 199)'
    1661                 :             : !    Select the three binary axes (they might be 2 or 2_1 !)
    1662                 :           8 :      test_direction(:)=0
    1663         [ +  + ]:         104 :      do isym=1,nsymconv
    1664         [ +  + ]:         104 :        if(t_axes(isym)==20)then
    1665                 :             : !        Find direction of axis
    1666         [ +  + ]:          96 :          do direction=1,3
    1667         [ +  + ]:          96 :            if(symrelconv(direction,direction,isym)==1)then
    1668                 :          24 :              test_direction(direction)=1
    1669         [ -  + ]:          24 :              if(abs(tnonsconv(direction,isym))<tol8)then
    1670         [ #  # ]:           0 :                vect(:,direction)=tnonsconv(:,isym)
    1671                 :             :              else
    1672         [ +  + ]:          96 :                vect(:,direction)=tnonsconv(:,isym)+half
    1673                 :             :              end if
    1674         [ +  + ]:          96 :              vect(:,direction)=vect(:,direction)-nint(vect(:,direction)-tol8)
    1675                 :          24 :              vect(direction,direction)=zero
    1676                 :             :            end if
    1677                 :             :          end do ! direction=1,3
    1678                 :             :        end if ! if binary axis
    1679                 :             :      end do ! isym
    1680   [ +  -  -  +  :           8 :      if(test_direction(1)/=1 .or. test_direction(2)/=1 .and. test_direction(3)/=1)then
                   -  - ]
    1681                 :             :        write(msg, '(5a,3i4)' )&
    1682                 :           0 :        'For space groups 23, 24, 197 or 197, the three binary axes',ch10,&
    1683                 :           0 :        'are not equally partitioned along the x, y and z directions',ch10,&
    1684                 :           0 :        'test_direction(1:3)=',test_direction(:)
    1685                 :           0 :        ABI_BUG(msg)
    1686                 :             :      end if
    1687                 :           8 :      additional_info=1
    1688   [ +  +  +  -  :           8 :      if(abs(vect(1,2)-vect(1,3))>tol8 .or. abs(vect(2,1)-vect(2,3))>tol8 .or. &
                   -  + ]
    1689                 :           4 :         abs(vect(3,1)-vect(3,2))>tol8) additional_info=2
    1690                 :             :    end if ! additional information are needed
    1691                 :             :  end if ! brvltt==1
    1692                 :             : 
    1693         [ +  + ]:       11739 :  if (brvltt==0 .or. brvltt==1) then ! Primitive
    1694                 :        5255 :    call symlist_prim(additional_info,nsymconv,n_axes,spgroup)
    1695         [ +  + ]:        6484 :  else if(brvltt==2)then
    1696                 :         698 :    call symlist_bcc(additional_info,nsymconv,n_axes,spgroup)
    1697         [ +  + ]:        5786 :  else if(brvltt==3)then
    1698                 :        4375 :    call symlist_fcc(nsymconv,n_axes,spgroup)
    1699                 :             :  else
    1700                 :        1411 :    call symlist_others(brvltt,nsymconv,n_axes,spgroup)
    1701                 :             :  end if
    1702                 :             : 
    1703         [ +  + ]:       11739 :  if(spgroup==0) then
    1704                 :             :    write(msg, '(5a)' )&
    1705                 :          17 :    'Could not find the space group.',ch10,&
    1706                 :          17 :    'This often happens when the user selects a restricted set of symmetries ',ch10,&
    1707                 :          34 :    'in the input file, instead of letting the code automatically find symmetries.'
    1708                 :          17 :    ABI_WARNING(msg)
    1709                 :             :  end if
    1710                 :             : 
    1711                 :       11739 :  spgorig=1 ; spgaxor=1
    1712                 :       11739 :  call spgdata(brvsb,intsb,intsbl,ptintsb,ptschsb,schsb,spgaxor,spgroup,sporder,spgorig)
    1713                 :             : 
    1714         [ +  + ]:       11739 :  if(spgroup/=0)then
    1715                 :       11722 :    write(msg, '(a,i4,2x,a,a,a,a,a)' ) ' symspgr: spgroup=',spgroup,trim(brvsb),trim(intsb),'   (=',trim(schsb),')'
    1716                 :       11722 :    call wrtout(std_out,msg)
    1717                 :             :  end if
    1718                 :             : 
    1719         [ +  + ]:       11739 :  if(bravais(1)==7)then
    1720                 :        5622 :    write(msg, '(a)' ) ' symspgr: optical characteristics = isotropic '
    1721                 :        5622 :    call wrtout(std_out,msg)
    1722         [ +  + ]:        6117 :  else if(bravais(1)==4 .or. bravais(1)==5 .or. bravais(1)==6)then
    1723                 :        3060 :    write(msg, '(a)' ) ' symspgr: optical characteristics = uniaxial '
    1724                 :        3060 :    call wrtout(std_out,msg)
    1725                 :             :    ! Identify the first symmetry operation that is order 3, 4 or 6
    1726                 :        3060 :    found=0
    1727         [ +  + ]:       16596 :    do isym=1,nsym
    1728   [ +  +  +  + ]:      232019 :      if( minval( abs( t_axes(isym)-(/10,12,14,22,23,24,25,26,27,28,29,30,31/) ))==0) then
    1729                 :             :        ! Proper rotations
    1730                 :             :        found=1 ; exit
    1731                 :             : 
    1732   [ +  +  +  + ]:       58124 :      else if( minval( abs( t_axes(isym)-(/1,2,3/) ))==0) then
    1733                 :             :        ! Improper symmetry operations
    1734                 :         995 :        found=-1 ; exit
    1735                 :             :      end if
    1736                 :             :    end do
    1737         [ +  + ]:        3060 :    if(found==-1 .or. found==1)then
    1738   [ +  +  +  + ]:       39455 :      symrel_uni=symrel(:,:,isym)
    1739   [ +  +  +  +  :       14975 :      if(found==-1)symrel_uni=-symrel_uni
                   +  + ]
    1740                 :             :      ! Now, symrel_uni is a rotation of order 3, 4, 6, for which the axis must be identified
    1741                 :             :      ! It is actually the only eigenvector with eigenvalue 1. It can be found by cross products
    1742                 :             :      ! Subtract the unit matrix.
    1743         [ +  + ]:       12140 :      do ii=1,3
    1744                 :       12140 :        symrel_uni(ii,ii)=symrel_uni(ii,ii)-1
    1745                 :             :      end do
    1746                 :        3650 :      found=0
    1747         [ -  + ]:        3650 :      do ii=1,3
    1748         [ +  + ]:        3650 :        jj=ii+1 ; if(jj==4)jj=1
    1749                 :             :        ! Cross product
    1750   [ +  +  +  + ]:       25550 :        ivec1 = symrel_uni(ii,:); ivec2 = symrel_uni(jj,:)
    1751                 :        3650 :        uniaxis = ivec1 .x. ivec2
    1752   [ +  +  +  + ]:       14600 :        if(sum(uniaxis**2)/=0)then
    1753                 :             :          found=1 ; exit
    1754                 :             :        end if
    1755                 :             :      end do
    1756         [ +  - ]:        3035 :      if(found==1)then
    1757                 :             :        ! Try to reduce the length, by an integer factor (try only primes 2, 3, 5, 7, 11)
    1758                 :        3035 :        prime=(/2,3,5,7,11/)
    1759                 :        3035 :        ii=1
    1760         [ +  + ]:       19780 :        do while (ii<6)
    1761         [ +  + ]:       66980 :          uniaxis_try=uniaxis/prime(ii)
    1762   [ +  +  +  + ]:       70015 :          if(sum(abs(uniaxis_try*prime(ii)-uniaxis))==0)then
    1763                 :        1570 :            uniaxis=uniaxis_try
    1764                 :             :          else
    1765                 :       15175 :            ii=ii+1
    1766                 :             :          end if
    1767                 :             :        end do
    1768                 :        3035 :        write(msg, '(a,3i4)' ) ' Optical axis (in reduced coordinates, real space ) :',uniaxis
    1769                 :             :      end if
    1770                 :             :    end if
    1771                 :             :    if(found==0)then
    1772                 :          25 :      write(msg, '(a)' ) ' However, the axis has not been found. Sorry for this.'
    1773                 :             :    end if
    1774                 :        3060 :    call wrtout(std_out,msg)
    1775                 :             :  end if
    1776                 :             : 
    1777         [ -  + ]:       11739 :  ABI_FREE(determinant)
    1778         [ -  + ]:       11739 :  ABI_FREE(shift)
    1779         [ -  + ]:       11739 :  ABI_FREE(symrelconv)
    1780         [ -  + ]:       11739 :  ABI_FREE(tnonsconv)
    1781         [ -  + ]:       11739 :  ABI_FREE(t_axes)
    1782                 :             : 
    1783                 :             :  DBG_EXIT("COLL")
    1784                 :             : 
    1785                 :       11739 : end subroutine symspgr
    1786                 :             : !!***
    1787                 :             : 
    1788                 :             : !!****f* m_symfind/symlatt
    1789                 :             : !! NAME
    1790                 :             : !! symlatt
    1791                 :             : !!
    1792                 :             : !! FUNCTION
    1793                 :             : !! From the unit cell vectors (rprimd) and the corresponding metric tensor,
    1794                 :             : !! find the Bravais lattice and its symmetry operations (ptsymrel).
    1795                 :             : !! 1) Find the shortest possible primitive vectors for the lattice
    1796                 :             : !! 2) Determines the holohedral group of the lattice, and the
    1797                 :             : !!    axes to be used for the conventional cell
    1798                 :             : !!    (this is a delicate part, in which the centering of the
    1799                 :             : !!    reduced cell must be taken into account)
    1800                 :             : !!    The idea is to determine the basis vectors of the conventional
    1801                 :             : !!    cell from the reduced cell basis vectors.
    1802                 :             : !! 3) Generate the symmetry operations of the holohedral group
    1803                 :             : !!
    1804                 :             : !! INPUTS
    1805                 :             : !! iout=unit number of output file
    1806                 :             : !! msym=default maximal number of symmetries. WARNING : cannot be simply set to nsym, because
    1807                 :             : !!   the number of symmetries found here will likely be bigger than sym !
    1808                 :             : !! rprimd(3,3)=dimensional primitive translations for real space (bohr)
    1809                 :             : !! tolsym=tolerance for the symmetries
    1810                 :             : !!
    1811                 :             : !! OUTPUT
    1812                 :             : !!  bravais(11): bravais(1)=iholohedry
    1813                 :             : !!               bravais(2)=center
    1814                 :             : !!               bravais(3:11)=coordinates of rprim in the axes
    1815                 :             : !!               of the conventional bravais lattice (*2 if center/=0)
    1816                 :             : !! nptsym=number of point symmetries of the Bravais lattice
    1817                 :             : !! ptsymrel(3,3,1:msym)= nptsym point-symmetry operations
    1818                 :             : !! of the Bravais lattice in real space in terms of primitive translations.
    1819                 :             : !!
    1820                 :             : !! NOTES
    1821                 :             : !! WARNING: bravais(1) might be given a negative value in another
    1822                 :             : !! routine, if the cell is non-primitive.
    1823                 :             : !! The holohedral groups are numbered as follows
    1824                 :             : !! (see international tables for crystallography (1983), p. 13)
    1825                 :             : !! iholohedry=1   triclinic      1bar
    1826                 :             : !! iholohedry=2   monoclinic     2/m
    1827                 :             : !! iholohedry=3   orthorhombic   mmm
    1828                 :             : !! iholohedry=4   tetragonal     4/mmm
    1829                 :             : !! iholohedry=5   trigonal       3bar m
    1830                 :             : !! iholohedry=6   hexagonal      6/mmm
    1831                 :             : !! iholohedry=7   cubic          m3bar m
    1832                 :             : !! Centering
    1833                 :             : !! center=0        no centering
    1834                 :             : !! center=-1       body-centered
    1835                 :             : !! center=-3       face-centered
    1836                 :             : !! center=1        A-face centered
    1837                 :             : !! center=2        B-face centered
    1838                 :             : !! center=3        C-face centered
    1839                 :             : !!
    1840                 :             : !! SOURCE
    1841                 :             : 
    1842                 :       40278 : subroutine symlatt(bravais,iout,msym,nptsym,ptsymrel,rprimd,tolsym)
    1843                 :             : 
    1844                 :             : !Arguments ------------------------------------
    1845                 :             : !scalars
    1846                 :             :  integer,intent(in) :: iout,msym
    1847                 :             :  integer,intent(out) :: nptsym
    1848                 :             :  real(dp),intent(in) :: tolsym
    1849                 :             : !arrays
    1850                 :             :  integer,intent(out) :: bravais(11),ptsymrel(3,3,msym)
    1851                 :             :  real(dp),intent(in) :: rprimd(3,3)
    1852                 :             : 
    1853                 :             : !Local variables-------------------------------
    1854                 :             : !scalars
    1855                 :             :  integer,parameter :: mgen=4
    1856                 :             :  integer :: center,fact,found,foundc,ia,iaxis1,iaxis2
    1857                 :             :  integer :: isign1,isign2,ib,icase,igen,iholohedry,ii,index,isym
    1858                 :             :  integer :: itrial,jj,jsym,ngen=0,orthogonal,sign12,sign13,sign23,sumsign
    1859                 :             :  real(dp) :: determinant,norm2a,norm2b,norm2c,norm2trial,reduceda,reducedb,sca
    1860                 :             :  real(dp) :: scalarprod,scb,trace,trace_best,val
    1861                 :             :  character(len=500) :: msg
    1862                 :             : !arrays
    1863                 :             :  integer,parameter :: list_holo(7)=(/7,6,4,3,5,2,1/)
    1864                 :             :  integer :: ang90(3),equal(3),gen(3,3,mgen),gen2xy(3,3),gen2y(3,3),gen2z(3,3)
    1865                 :             :  integer :: gen3(3,3),gen6(3,3),icoord(3,3),identity(3,3),nvecta(3),nvectb(3)
    1866                 :             :  integer :: order(mgen)
    1867                 :             :  real(dp) :: axes(3,3),axesinvt(3,3),axes_best(3,3),axes_try(3,3)
    1868                 :             :  real(dp) :: cell_base(3,3),coord(3,3),metmin(3,3)
    1869                 :             :  real(dp) :: minim(3,3),scprods(3,3),vecta(3),vectb(3),vectc(3),vin1(3),vin2(3),vext(3)
    1870                 :             : !**************************************************************************
    1871                 :             : 
    1872                 :             : !DEBUG
    1873                 :             : !write(std_out,'(a,es14.6)') ' m_symfind%symlatt : enter, tolsym= ',tolsym
    1874                 :             : !call flush(std_out)
    1875                 :             : !ENDDEBUG
    1876                 :             : 
    1877                 :       40278 :  identity(:,:)=0 ; identity(1,1)=1 ; identity(2,2)=1 ; identity(3,3)=1
    1878                 :       40278 :  nvecta(1)=2 ; nvectb(1)=3
    1879                 :       40278 :  nvecta(2)=1 ; nvectb(2)=3
    1880                 :       40278 :  nvecta(3)=1 ; nvectb(3)=2
    1881                 :             : 
    1882                 :             : !--------------------------------------------------------------------------
    1883                 :             : !Reduce the input vectors to a set of minimal vectors
    1884                 :       40278 :  call smallprim(metmin,minim,rprimd)
    1885                 :             : 
    1886                 :             : !DEBUG
    1887                 :             : !write(std_out,*)' symlatt : minim(:,1)=',minim(:,1)
    1888                 :             : !write(std_out,*)' symlatt : minim(:,2)=',minim(:,2)
    1889                 :             : !write(std_out,*)' symlatt : minim(:,3)=',minim(:,3)
    1890                 :             : !call flush(std_out)
    1891                 :             : !ENDDEBUG
    1892                 :             : 
    1893                 :             : !--------------------------------------------------------------------------
    1894                 :             : !Examine the angles and vector lengths
    1895                 :       40278 :  ang90(:)=0
    1896         [ +  + ]:       40278 :  if(metmin(1,2)**2<tolsym**2*metmin(1,1)*metmin(2,2))ang90(3)=1
    1897         [ +  + ]:       40278 :  if(metmin(1,3)**2<tolsym**2*metmin(1,1)*metmin(3,3))ang90(2)=1
    1898         [ +  + ]:       40278 :  if(metmin(2,3)**2<tolsym**2*metmin(2,2)*metmin(3,3))ang90(1)=1
    1899                 :       40278 :  equal(:)=0
    1900         [ +  + ]:       40278 :  if(abs(metmin(1,1)-metmin(2,2))<tolsym*half*(metmin(1,1)+metmin(2,2)))equal(3)=1
    1901         [ +  + ]:       40278 :  if(abs(metmin(1,1)-metmin(3,3))<tolsym*half*(metmin(1,1)+metmin(3,3)))equal(2)=1
    1902         [ +  + ]:       40278 :  if(abs(metmin(2,2)-metmin(3,3))<tolsym*half*(metmin(2,2)+metmin(3,3)))equal(1)=1
    1903                 :             : 
    1904                 :             : !DEBUG
    1905                 :             : !write(std_out,*)' ang90=',ang90(:)
    1906                 :             : !write(std_out,*)' equal=',equal(:)
    1907                 :             : !call flush(std_out)
    1908                 :             : !ENDDEBUG
    1909                 :             : 
    1910                 :             : !-----------------------------------------------------------------------
    1911                 :             : !Identification of the centering
    1912                 :             : 
    1913                 :       40278 :  foundc=0
    1914                 :             : !Default values
    1915                 :       40278 :  fact=1 ; center=0
    1916                 :       40278 :  cell_base(:,:)=minim(:,:)
    1917                 :             : 
    1918                 :             : !Examine each holohedral group
    1919                 :             : !This search is ordered : should not be happy with tetragonal,
    1920                 :             : !while there is FCC ...
    1921         [ +  + ]:      126813 :  do index=1,6
    1922                 :             : 
    1923                 :             : !  If the holohedry is already found, exit
    1924         [ +  + ]:      123013 :    if(foundc==1)exit
    1925                 :             : 
    1926                 :             : !  Initialize the target holohedry
    1927                 :       86535 :    iholohedry=list_holo(index)
    1928                 :             : 
    1929                 :             : !  DEBUG
    1930                 :             : !  write(std_out,*)
    1931                 :             : !  write(std_out,*)' symlatt : trial holohedry',iholohedry
    1932                 :             : !  ENDDEBUG
    1933                 :             : 
    1934                 :       86535 :    orthogonal=0
    1935   [ +  +  +  + ]:       86535 :    if(iholohedry==7 .or. iholohedry==4 .or. iholohedry==3)orthogonal=1
    1936                 :             : 
    1937                 :             : !  Now, will examine different working hypothesis.
    1938                 :             : !  The set of these hypothesis is thought to cover all possible cases ...
    1939                 :             : 
    1940                 :             : !  Working hypothesis : the basis is orthogonal
    1941   [ +  +  +  + ]:       86535 :    if(ang90(1)+ang90(2)+ang90(3)==3 .and. orthogonal==1)then
    1942                 :       21486 :      fact=1 ; center=0
    1943                 :       21486 :      cell_base(:,:)=minim(:,:)
    1944                 :             : !    Checks that the basis vectors are OK for the target holohedry
    1945                 :       21486 :      call holocell(cell_base,0,foundc,iholohedry,tolsym)
    1946                 :             :    end if
    1947                 :             : 
    1948                 :             : !  Select one trial direction
    1949         [ +  + ]:      303739 :    do itrial=1,3
    1950                 :             : 
    1951                 :             : !    If the holohedry is already found, exit
    1952         [ +  + ]:      211869 :      if(foundc==1)exit
    1953                 :             : 
    1954                 :      176926 :      ia=nvecta(itrial) ; ib=nvectb(itrial)
    1955                 :             : 
    1956                 :             : !    This is in case of hexagonal holohedry
    1957   [ +  -  +  +  :      176926 :      if(foundc==0 .and. iholohedry==6 .and. ang90(ia)==1 .and. ang90(ib)==1 .and. equal(itrial)==1 )then
          +  +  +  +  +  
                      + ]
    1958                 :        7406 :        reduceda=metmin(ib,ia)/metmin(ia,ia)
    1959                 :        7406 :        fact=1 ; center=0
    1960         [ +  + ]:        7406 :        if(abs(reduceda+0.5d0)<tolsym)then
    1961         [ +  + ]:        8520 :          cell_base(:,1)=minim(:,ia)
    1962         [ +  + ]:        8520 :          cell_base(:,2)=minim(:,ib)
    1963         [ +  + ]:        8520 :          cell_base(:,3)=minim(:,itrial)
    1964                 :             : !DEBUG
    1965                 :             : !      write(std_out,*)' cell_base(:,1)=',cell_base(:,1)
    1966                 :             : !      write(std_out,*)' cell_base(:,2)=',cell_base(:,2)
    1967                 :             : !      write(std_out,*)' cell_base(:,3)=',cell_base(:,3)
    1968                 :             : !ENDDEBUG
    1969                 :             : !        Checks that the basis vectors are OK for the target holohedry
    1970                 :        2130 :          call holocell(cell_base,0,foundc,iholohedry,tolsym)
    1971         [ +  + ]:        5276 :        else if(abs(reduceda-0.5d0)<tolsym)then
    1972         [ +  + ]:         276 :          cell_base(:,1)=minim(:,ia)
    1973         [ +  + ]:         276 :          cell_base(:,2)=minim(:,ib)-minim(:,ia)
    1974         [ +  + ]:         276 :          cell_base(:,3)=minim(:,itrial)
    1975                 :             : !        Checks that the basis vectors are OK for the target holohedry
    1976                 :          69 :          call holocell(cell_base,0,foundc,iholohedry,tolsym)
    1977                 :             :        end if
    1978                 :             :      end if
    1979                 :             : 
    1980                 :             : !    Working hypothesis : the conventional cell is orthogonal,
    1981                 :             : !    and the two other vectors are axes of the conventional cell
    1982   [ +  +  +  +  :      176926 :      if(foundc==0 .and. orthogonal==1 .and. ang90(itrial)==1)then
                   +  + ]
    1983                 :             : 
    1984                 :             : !      Compute the reduced coordinate of trial vector in the basis
    1985                 :             : !      of the two other vectors
    1986                 :       37612 :        reduceda=metmin(itrial,ia)/metmin(ia,ia)
    1987                 :       37612 :        reducedb=metmin(itrial,ib)/metmin(ib,ib)
    1988         [ +  + ]:      150448 :        cell_base(:,ia)=minim(:,ia)
    1989         [ +  + ]:      150448 :        cell_base(:,ib)=minim(:,ib)
    1990   [ +  +  +  +  :       37612 :        if( (abs(abs(reduceda)-0.5d0)<tolsym .and. abs(reducedb)<tolsym ) .or. &
                   +  + ]
    1991         [ +  + ]:       37612 : &       ( abs(reduceda)<tolsym .and. abs(abs(reducedb)-0.5d0)<tolsym)       )then
    1992         [ +  + ]:        4602 :          if(abs(abs(reduceda)-0.5d0)<tolsym)center=ib
    1993         [ +  + ]:        4602 :          if(abs(abs(reducedb)-0.5d0)<tolsym)center=ia
    1994                 :        4602 :          fact=2
    1995                 :             :          cell_base(:,itrial)= &
    1996         [ +  + ]:       18408 : &         (minim(:,itrial)-reduceda*minim(:,ia)-reducedb*minim(:,ib) )*2.0d0
    1997                 :        4602 :          call holocell(cell_base,0,foundc,iholohedry,tolsym)
    1998   [ +  +  +  + ]:       33010 :        else if( abs(abs(reduceda)-0.5d0)<tolsym .and.&
    1999                 :             : &         abs(abs(reducedb)-0.5d0)<tolsym       ) then
    2000                 :         553 :          fact=2 ; center=-1
    2001                 :             :          cell_base(:,itrial)= &
    2002         [ +  + ]:        2212 : &         (minim(:,itrial)-reduceda*minim(:,ia)-reducedb*minim(:,ib) )*2.0d0
    2003                 :         553 :          call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2004                 :             :        end if
    2005                 :             :      end if
    2006                 :             : 
    2007                 :             : !    Working hypothesis : the conventional cell is orthogonal, and
    2008                 :             : !    the trial vector is one of the future axes, and the face perpendicular to it is centered
    2009                 :             :      if(foundc==0 .and. iholohedry==3 .and. &
    2010   [ +  +  +  +  :      176926 : &     ang90(ia)==1 .and. ang90(ib)==1 .and. equal(itrial)==1 )then
          +  +  +  +  +  
                      + ]
    2011                 :         460 :        fact=2 ; center=itrial
    2012         [ +  + ]:        1840 :        cell_base(:,ia)=minim(:,ia)+minim(:,ib)
    2013         [ +  + ]:        1840 :        cell_base(:,ib)=minim(:,ia)-minim(:,ib)
    2014         [ +  + ]:        1840 :        cell_base(:,itrial)=minim(:,itrial)
    2015                 :             : !      Checks that the basis vectors are OK for the target holohedry
    2016                 :         460 :        call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2017                 :             :      end if
    2018                 :             : 
    2019                 :             : !    DEBUG
    2020                 :             : !    write(std_out,*)' after test_b, foundc=',foundc
    2021                 :             : !    ENDDEBUG
    2022                 :             : 
    2023                 :             : !    Working hypothesis : the conventional cell is orthogonal, and
    2024                 :             : !    the trial vector is one of the future axes
    2025   [ +  +  +  + ]:      176926 :      if(foundc==0 .and. orthogonal==1)then
    2026                 :             : !      Compute the projection of the two other vectors on the trial vector
    2027                 :      107035 :        reduceda=metmin(itrial,ia)/metmin(itrial,itrial)
    2028                 :      107035 :        reducedb=metmin(itrial,ib)/metmin(itrial,itrial)
    2029                 :             : !      If both projections are half-integer, one might have found an axis
    2030   [ +  +  +  + ]:      107035 :        if( abs(abs(reduceda)-0.5d0)<tolsym .and.&
    2031                 :             : &       abs(abs(reducedb)-0.5d0)<tolsym       ) then
    2032         [ +  + ]:       96608 :          vecta(:)=minim(:,ia)-reduceda*minim(:,itrial)
    2033         [ +  + ]:       96608 :          vectb(:)=minim(:,ib)-reducedb*minim(:,itrial)
    2034                 :       24152 :          norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2
    2035                 :       24152 :          norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2
    2036                 :       24152 :          scalarprod=vecta(1)*vectb(1)+vecta(2)*vectb(2)+vecta(3)*vectb(3)
    2037                 :             : !        Note the order of selection : body-centered is prefered
    2038                 :             : !        over face centered, which is correct for the tetragonal case
    2039         [ +  + ]:       24152 :          if(abs(norm2a-norm2b)<tolsym*half*(norm2a+norm2b))then
    2040                 :             : !          The lattice is body centered
    2041                 :       17279 :            fact=2 ; center=-1
    2042         [ +  + ]:       69116 :            cell_base(:,ia)=vecta(:)+vectb(:)
    2043         [ +  + ]:       69116 :            cell_base(:,ib)=vecta(:)-vectb(:)
    2044         [ +  + ]:       69116 :            cell_base(:,itrial)=minim(:,itrial)
    2045                 :       17279 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2046         [ +  - ]:        6873 :          else if(abs(scalarprod)<tolsym*half*(norm2a+norm2b))then
    2047                 :             : !          The lattice is face centered
    2048                 :           0 :            fact=2 ; center=-3
    2049         [ #  # ]:           0 :            cell_base(:,ia)=2.0d0*vecta(:)
    2050         [ #  # ]:           0 :            cell_base(:,ib)=2.0d0*vectb(:)
    2051         [ #  # ]:           0 :            cell_base(:,itrial)=minim(:,itrial)
    2052                 :           0 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2053                 :             :          end if
    2054                 :             :        end if
    2055                 :             :      end if
    2056                 :             : 
    2057                 :             : !    DEBUG
    2058                 :             : !    write(std_out,*)' after test_c, foundc=',foundc
    2059                 :             : !    ENDDEBUG
    2060                 :             : 
    2061                 :             : !    Working hypothesis : the conventional cell is orthogonal,
    2062                 :             : !    and body centered with no basis vector being an axis,
    2063                 :             : !    in which case the basis vectors must be equal (even for orthorhombic)
    2064                 :             :      if(foundc==0 .and. orthogonal==1 .and. &
    2065   [ +  +  +  +  :      176926 : &     equal(1)==1 .and. equal(2)==1 .and. equal(3)==1 )then
          +  +  +  +  +  
                      - ]
    2066                 :             : !      Compute the combination of the two other vectors
    2067         [ +  + ]:       93436 :        vecta(:)=minim(:,ia)+minim(:,ib)
    2068         [ +  + ]:       93436 :        vectb(:)=minim(:,ia)-minim(:,ib)
    2069                 :       23359 :        norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2
    2070                 :       23359 :        norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2
    2071                 :             : !      Project the trial vector on the first of the two vectors
    2072                 :             :        reduceda=( minim(1,itrial)*vecta(1)+       &
    2073                 :             : &       minim(2,itrial)*vecta(2)+       &
    2074                 :       23359 : &       minim(3,itrial)*vecta(3) )/norm2a
    2075                 :             :        reducedb=( minim(1,itrial)*vectb(1)+       &
    2076                 :             : &       minim(2,itrial)*vectb(2)+       &
    2077                 :       23359 : &       minim(3,itrial)*vectb(3) )/norm2b
    2078         [ +  + ]:       23359 :        if( abs(abs(reduceda)-0.5d0)<tolsym )then
    2079                 :             : !        The first vector is an axis
    2080                 :        3653 :          fact=2 ; center=-1
    2081         [ +  + ]:       14612 :          cell_base(:,ia)=vecta(:)
    2082         [ +  + ]:       14612 :          vecta(:)=minim(:,itrial)-reduceda*vecta(:)
    2083         [ +  + ]:       14612 :          vectb(:)=0.5d0*vectb(:)
    2084         [ +  + ]:       14612 :          cell_base(:,ib)=vecta(:)+vectb(:)
    2085         [ +  + ]:       14612 :          cell_base(:,itrial)=vecta(:)-vectb(:)
    2086                 :        3653 :          call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2087         [ +  + ]:       19706 :        else if( abs(abs(reducedb)-0.5d0)<tolsym )then
    2088                 :             : !        The second vector is an axis
    2089                 :          84 :          fact=2 ; center=-1
    2090         [ +  + ]:         336 :          cell_base(:,ib)=vectb(:)
    2091         [ +  + ]:         336 :          vectb(:)=minim(:,itrial)-reducedb*vectb(:)
    2092         [ +  + ]:         336 :          vecta(:)=0.5d0*vecta(:)
    2093         [ +  + ]:         336 :          cell_base(:,ia)=vectb(:)+vecta(:)
    2094         [ +  + ]:         336 :          cell_base(:,itrial)=vectb(:)-vecta(:)
    2095                 :          84 :          call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2096                 :             :        end if
    2097                 :             :      end if
    2098                 :             : 
    2099                 :             : !    Working hypothesis : the conventional cell is orthogonal,
    2100                 :             : !    and face centered, in the case where two minimal vectors are equal
    2101   [ +  +  +  +  :      176926 :      if(foundc==0 .and. orthogonal==1 .and. equal(itrial)==1 ) then
                   +  + ]
    2102                 :             : !      Compute the combination of these two vectors
    2103         [ +  + ]:      157048 :        vecta(:)=minim(:,ia)+minim(:,ib)
    2104         [ +  + ]:      157048 :        vectb(:)=minim(:,ia)-minim(:,ib)
    2105                 :       39262 :        norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2
    2106                 :       39262 :        norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2
    2107                 :             : !      Project the trial vector on the two vectors
    2108                 :             :        reduceda=( minim(1,itrial)*vecta(1)+       &
    2109                 :             : &       minim(2,itrial)*vecta(2)+       &
    2110                 :       39262 : &       minim(3,itrial)*vecta(3) )/norm2a
    2111                 :             :        reducedb=( minim(1,itrial)*vectb(1)+       &
    2112                 :             : &       minim(2,itrial)*vectb(2)+       &
    2113                 :       39262 : &       minim(3,itrial)*vectb(3) )/norm2b
    2114   [ +  +  +  +  :       39262 :        if( (abs(abs(reduceda)-0.5d0)<tolsym .and. abs(reducedb)<tolsym ) .or. &
                   +  + ]
    2115         [ +  + ]:       39262 : &       ( abs(reduceda)<tolsym .and. abs(abs(reducedb)-0.5d0)<tolsym)       )then
    2116                 :         978 :          fact=2 ; center=-3
    2117                 :             :          cell_base(:,itrial)= &
    2118         [ +  + ]:        3912 : &         (minim(:,itrial)-reduceda*vecta(:)-reducedb*vectb(:) )*2.0d0
    2119         [ +  + ]:        3912 :          cell_base(:,ia)=vecta(:)
    2120         [ +  + ]:        3912 :          cell_base(:,ib)=vectb(:)
    2121                 :         978 :          call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2122                 :             :        end if
    2123                 :             :      end if
    2124                 :             : 
    2125                 :             : !    Working hypothesis : the conventional cell is orthogonal,
    2126                 :             : !    face centered, but no two vectors are on the same "square"
    2127   [ +  +  +  + ]:      176926 :      if(foundc==0 .and. orthogonal==1)then
    2128                 :             : !      Compute the combination of these two vectors
    2129         [ +  + ]:      419860 :        vecta(:)=minim(:,ia)+minim(:,ib)
    2130         [ +  + ]:      419860 :        vectb(:)=minim(:,ia)-minim(:,ib)
    2131                 :      104965 :        norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2
    2132                 :      104965 :        norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2
    2133                 :             : !      The trial vector length must be equal to one of these lengths
    2134         [ +  + ]:      104965 :        if(abs(metmin(itrial,itrial)-norm2a)<tolsym*norm2a)then
    2135                 :        1211 :          fact=2 ; center=-3
    2136         [ +  + ]:        4844 :          cell_base(:,ia)=vecta(:)+minim(:,itrial)
    2137         [ +  + ]:        4844 :          cell_base(:,ib)=vecta(:)-minim(:,itrial)
    2138                 :             : !        Project vectb perpendicular to cell_base(:,ia) and cell_base(:,ib)
    2139                 :        1211 :          norm2a=cell_base(1,ia)**2+cell_base(2,ia)**2+cell_base(3,ia)**2
    2140                 :        1211 :          norm2b=cell_base(1,ib)**2+cell_base(2,ib)**2+cell_base(3,ib)**2
    2141                 :             :          reduceda=( cell_base(1,ia)*vectb(1)+       &
    2142                 :             : &         cell_base(2,ia)*vectb(2)+       &
    2143                 :        1211 : &         cell_base(3,ia)*vectb(3) )/norm2a
    2144                 :             :          reducedb=( cell_base(1,ib)*vectb(1)+       &
    2145                 :             : &         cell_base(2,ib)*vectb(2)+       &
    2146                 :        1211 : &         cell_base(3,ib)*vectb(3) )/norm2b
    2147   [ +  +  +  - ]:        1211 :          if( abs(abs(reduceda)-0.5d0)<tolsym .and.         &
    2148                 :             : &         abs(abs(reducedb)-0.5d0)<tolsym      )then
    2149         [ #  # ]:           0 :            cell_base(:,itrial)=vectb(:)-reduceda*cell_base(:,ia)-reducedb*cell_base(:,ib)
    2150                 :           0 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2151                 :             :          end if
    2152         [ +  + ]:      103754 :        else if(abs(metmin(itrial,itrial)-norm2b)<tolsym*norm2b)then
    2153                 :       17405 :          fact=2 ; center=-3
    2154         [ +  + ]:       69620 :          cell_base(:,ia)=vectb(:)+minim(:,itrial)
    2155         [ +  + ]:       69620 :          cell_base(:,ib)=vectb(:)-minim(:,itrial)
    2156                 :             : !        Project vecta perpendicular to cell_base(:,ia) and cell_base(:,ib)
    2157                 :       17405 :          norm2a=cell_base(1,ia)**2+cell_base(2,ia)**2+cell_base(3,ia)**2
    2158                 :       17405 :          norm2b=cell_base(1,ib)**2+cell_base(2,ib)**2+cell_base(3,ib)**2
    2159                 :             :          reduceda=( cell_base(1,ia)*vecta(1)+       &
    2160                 :             : &         cell_base(2,ia)*vecta(2)+       &
    2161                 :       17405 : &         cell_base(3,ia)*vecta(3) )/norm2a
    2162                 :             :          reducedb=( cell_base(1,ib)*vecta(1)+       &
    2163                 :             : &         cell_base(2,ib)*vecta(2)+       &
    2164                 :       17405 : &         cell_base(3,ib)*vecta(3) )/norm2b
    2165   [ +  +  +  + ]:       17405 :          if( abs(abs(reduceda)-0.5d0)<tolsym .and.         &
    2166                 :             : &         abs(abs(reducedb)-0.5d0)<tolsym      )then
    2167         [ +  + ]:       66572 :            cell_base(:,itrial)=vecta(:)-reduceda*cell_base(:,ia)-reducedb*cell_base(:,ib)
    2168                 :       16643 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2169                 :             :          end if
    2170                 :             :        end if
    2171                 :             :      end if
    2172                 :             : 
    2173                 :             : !    Working hypothesis : the cell is rhombohedral, and
    2174                 :             : !    the three minimal vectors have same length and same absolute scalar product
    2175                 :             :      if(foundc==0 .and. iholohedry==5 .and. &
    2176   [ +  +  +  +  :      176926 : &     equal(1)==1 .and. equal(2)==1 .and. equal(3)==1 )then
          +  +  +  +  +  
                      - ]
    2177         [ +  + ]:         347 :        if( abs(abs(metmin(1,2))-abs(metmin(1,3)))<tolsym*metmin(1,1) .and.     &
    2178         [ +  - ]:         347 : &       abs(abs(metmin(1,2))-abs(metmin(2,3)))<tolsym*metmin(2,2)      )then
    2179                 :         323 :          fact=1 ; center=0
    2180                 :         323 :          cell_base(:,:)=minim(:,:)
    2181                 :             : !        One might have to change the sign of one of the vectors
    2182                 :         323 :          sign12=1 ; sign13=1 ; sign23=1
    2183         [ +  + ]:         323 :          if(metmin(1,2)<0.0d0)sign12=-1
    2184         [ +  + ]:         323 :          if(metmin(1,3)<0.0d0)sign13=-1
    2185         [ +  + ]:         323 :          if(metmin(2,3)<0.0d0)sign23=-1
    2186                 :         323 :          sumsign=sign12+sign13+sign23
    2187         [ +  + ]:         323 :          if(sumsign==-1)then
    2188   [ -  +  -  - ]:          50 :            if(sign12==1)cell_base(:,3)=-cell_base(:,3)
    2189   [ -  +  -  - ]:          50 :            if(sign13==1)cell_base(:,2)=-cell_base(:,2)
    2190   [ +  -  +  + ]:         200 :            if(sign23==1)cell_base(:,1)=-cell_base(:,1)
    2191         [ +  + ]:         273 :          else if(sumsign==1)then
    2192   [ -  +  -  - ]:           4 :            if(sign12==-1)cell_base(:,3)=-cell_base(:,3)
    2193   [ -  +  -  - ]:           4 :            if(sign13==-1)cell_base(:,2)=-cell_base(:,2)
    2194   [ +  -  +  + ]:          16 :            if(sign23==-1)cell_base(:,1)=-cell_base(:,1)
    2195                 :             :          end if
    2196                 :         323 :          call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2197                 :             :        end if
    2198                 :             :      end if
    2199                 :             : 
    2200                 :             : !    DEBUG
    2201                 :             : !    write(std_out,*)' after test_3a, foundc=',foundc
    2202                 :             : !    write(std_out,*)' after test_3a, itrial=',itrial
    2203                 :             : !    write(std_out,*)' after test_3a, equal(:)=',equal(:)
    2204                 :             : !    ENDDEBUG
    2205                 :             : 
    2206                 :             : !    Working hypothesis : the cell is rhombohedral, one vector
    2207                 :             : !    is parallel to the trigonal axis
    2208   [ +  +  +  +  :      176926 :      if(foundc==0 .and. iholohedry==5 .and. equal(itrial)==1 )then
                   +  + ]
    2209   [ +  +  +  + ]:       20888 :        vecta(:)=minim(:,ia) ; vectb(:)=minim(:,ib)
    2210                 :        2984 :        norm2trial=minim(1,itrial)**2+minim(2,itrial)**2+minim(3,itrial)**2
    2211                 :             :        reduceda=( minim(1,itrial)*vecta(1)+       &
    2212                 :             : &       minim(2,itrial)*vecta(2)+       &
    2213                 :        2984 : &       minim(3,itrial)*vecta(3) )/norm2trial
    2214                 :             :        reducedb=( minim(1,itrial)*vectb(1)+       &
    2215                 :             : &       minim(2,itrial)*vectb(2)+       &
    2216                 :        2984 : &       minim(3,itrial)*vectb(3) )/norm2trial
    2217                 :             : !      DEBUG
    2218                 :             : !      write(std_out,*)' reduceda,reducedb=',reduceda,reducedb
    2219                 :             : !      ENDDEBUG
    2220   [ +  +  -  + ]:        2984 :        if(abs(abs(reduceda)-1.0d0/3.0d0)<tolsym .and.      &
    2221                 :             : &       abs(abs(reducedb)-1.0d0/3.0d0)<tolsym      ) then
    2222                 :             : !        Possibly change of sign to make positive the scalar product with
    2223                 :             : !        the vector parallel to the trigonal axis
    2224   [ +  +  +  + ]:          82 :          if(reduceda<zero)vecta(:)=-vecta(:)
    2225   [ +  +  +  + ]:         130 :          if(reducedb<zero)vectb(:)=-vectb(:)
    2226                 :             : !        Projection on the orthogonal plane
    2227         [ +  + ]:         148 :          vecta(:)=vecta(:)-abs(reduceda)*cell_base(:,itrial)
    2228         [ +  + ]:         148 :          vectb(:)=vectb(:)-abs(reducedb)*cell_base(:,itrial)
    2229                 :             : !        These two vectors should have an angle of 120 degrees
    2230                 :          37 :          norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2
    2231                 :          37 :          scalarprod=vecta(1)*vectb(1)+vecta(2)*vectb(2)+vecta(3)*vectb(3)
    2232                 :             : !        DEBUG
    2233                 :             : !        write(std_out,*)' norm2a,scalarprod=',norm2a,scalarprod
    2234                 :             : !        ENDDEBUG
    2235         [ +  + ]:          37 :          if(abs(two*scalarprod+norm2a)<tolsym*norm2a)then
    2236                 :          12 :            fact=1 ; center=0
    2237   [ -  +  -  - ]:          12 :            if(scalarprod>0.0d0)vectb(:)=-vectb(:)
    2238                 :             : !          Now vecta and vectb have an angle of 120 degrees
    2239         [ +  + ]:          48 :            cell_base(:,1)=cell_base(:,itrial)/3.0d0+vecta(:)
    2240         [ +  + ]:          48 :            cell_base(:,2)=cell_base(:,itrial)/3.0d0+vectb(:)
    2241         [ +  + ]:          48 :            cell_base(:,3)=cell_base(:,itrial)/3.0d0-vecta(:)-vectb(:)
    2242                 :             : !          DEBUG
    2243                 :             : !          write(std_out,*)' cell_base(:,1)=',cell_base(:,1)
    2244                 :             : !          write(std_out,*)' cell_base(:,2)=',cell_base(:,2)
    2245                 :             : !          write(std_out,*)' cell_base(:,3)=',cell_base(:,3)
    2246                 :             : !          ENDDEBUG
    2247                 :          12 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2248                 :             :          end if
    2249                 :             :        end if
    2250                 :             :      end if
    2251                 :             : 
    2252                 :             : !    Working hypothesis : the cell is rhombohedral, one vector
    2253                 :             : !    is in the plane perpendicular to the trigonal axis
    2254   [ +  +  +  +  :      176926 :      if(foundc==0 .and. iholohedry==5 .and. equal(itrial)==1 ) then
                   +  + ]
    2255         [ +  + ]:       11888 :        vecta(:)=minim(:,ia)+minim(:,ib)
    2256         [ +  + ]:       11888 :        vectb(:)=minim(:,ia)-minim(:,ib)
    2257                 :        2972 :        norm2trial=cell_base(1,itrial)**2+cell_base(2,itrial)**2+cell_base(3,itrial)**2
    2258                 :        2972 :        norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2
    2259                 :        2972 :        norm2b=vecta(1)**2+vecta(2)**2+vecta(3)**2
    2260                 :             :        reduceda=( cell_base(1,itrial)*vecta(1)+       &
    2261                 :             : &       cell_base(2,itrial)*vecta(2)+       &
    2262                 :        2972 : &       cell_base(3,itrial)*vecta(3) )/norm2trial
    2263                 :             :        reducedb=( cell_base(1,itrial)*vectb(1)+       &
    2264                 :             : &       cell_base(2,itrial)*vectb(2)+       &
    2265                 :        2972 : &       cell_base(3,itrial)*vectb(3) )/norm2trial
    2266   [ +  +  -  + ]:        2972 :        if(abs(norm2trial-norm2a)<tolsym*norm2a .and. &
    2267                 :             : &       abs(abs(2*reduceda)-norm2trial)<tolsym*norm2trial    )then
    2268                 :           0 :          fact=1 ; center=0
    2269         [ #  # ]:           0 :          cell_base(:,1)=minim(:,ia)
    2270         [ #  # ]:           0 :          cell_base(:,2)=-minim(:,ib)
    2271         [ #  # ]:           0 :          cell_base(:,3)=-minim(:,ib)+2*reduceda*minim(:,itrial)
    2272                 :           0 :          call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2273   [ +  +  -  + ]:        2972 :        else if (abs(norm2trial-norm2b)<tolsym*norm2b .and. &
    2274                 :             : &         abs(abs(2*reducedb)-norm2trial)<tolsym*norm2trial    )then
    2275                 :           0 :          fact=1 ; center=0
    2276         [ #  # ]:           0 :          cell_base(:,1)=minim(:,ia)
    2277         [ #  # ]:           0 :          cell_base(:,2)=minim(:,ib)
    2278         [ #  # ]:           0 :          cell_base(:,3)=minim(:,ib)+2*reducedb*minim(:,itrial)
    2279                 :           0 :          call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2280                 :             :        end if
    2281                 :             :      end if
    2282                 :             : 
    2283                 :             : !    Working hypothesis : the cell is rhombohedral, two vectors
    2284                 :             : !    are in the plane perpendicular to the trigonal axis
    2285   [ +  +  +  +  :      176926 :      if(foundc==0 .and. iholohedry==5 .and. equal(itrial)==1 ) then
                   +  + ]
    2286   [ +  +  +  + ]:       20804 :        vecta(:)=minim(:,ia) ; vectb(:)=minim(:,ib)
    2287                 :        2972 :        norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2
    2288                 :        2972 :        norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2
    2289                 :        2972 :        scalarprod=vecta(1)*vectb(1)+vecta(2)*vectb(2)+vecta(3)*vectb(3)
    2290         [ +  + ]:        2972 :        if(abs(abs(2*scalarprod)-norm2a)<tolsym*norm2a)then
    2291                 :             : !        This is in order to have 120 angle between vecta and vectb
    2292   [ +  +  +  + ]:        1957 :          if(scalarprod>0.0d0)vectb(:)=-vectb(:)
    2293                 :             :          reduceda=( cell_base(1,itrial)*vecta(1)+        &
    2294                 :             : &         cell_base(2,itrial)*vecta(2)+        &
    2295                 :        1246 : &         cell_base(3,itrial)*vecta(3) )/norm2a
    2296                 :             :          reducedb=( cell_base(1,itrial)*vectb(1)+        &
    2297                 :             : &         cell_base(2,itrial)*vectb(2)+        &
    2298                 :        1246 : &         cell_base(3,itrial)*vectb(3) )/norm2b
    2299                 :        1246 :          fact=1 ; center=0
    2300         [ +  + ]:        4984 :          cell_base(:,1)=minim(:,itrial)
    2301   [ +  +  +  + ]:        1246 :          if(abs(reduceda-0.5d0)<tolsym .and. abs(reducedb)<tolsym )then
    2302         [ +  + ]:         900 :            cell_base(:,2)=minim(:,itrial)-vecta(:)
    2303         [ +  + ]:         900 :            cell_base(:,3)=minim(:,itrial)-vecta(:)-vectb(:)
    2304                 :         225 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2305   [ +  +  +  - ]:        1021 :          else if(abs(reduceda-0.5d0)<tolsym.and. abs(reducedb+0.5d0)<tolsym )then
    2306         [ +  + ]:          24 :            cell_base(:,2)=minim(:,itrial)-vecta(:)
    2307         [ +  + ]:          24 :            cell_base(:,3)=minim(:,itrial)+vectb(:)
    2308                 :           6 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2309   [ -  +  -  - ]:        1015 :          else if(abs(reduceda)<tolsym .and. abs(reducedb+0.5d0)<tolsym )then
    2310         [ #  # ]:           0 :            cell_base(:,2)=minim(:,itrial)+vectb(:)
    2311         [ #  # ]:           0 :            cell_base(:,3)=minim(:,itrial)+vecta(:)+vectb(:)
    2312                 :           0 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2313   [ +  -  +  + ]:        1015 :          else if(abs(reduceda+0.5d0)<tolsym .and. abs(reducedb)<tolsym)then
    2314         [ +  + ]:          24 :            cell_base(:,2)=minim(:,itrial)+vecta(:)
    2315         [ +  + ]:          24 :            cell_base(:,3)=minim(:,itrial)+vecta(:)+vectb(:)
    2316                 :           6 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2317   [ +  -  +  - ]:        1009 :          else if(abs(reduceda+0.5d0)<tolsym .and. abs(reducedb-0.5d0)<tolsym)then
    2318         [ +  + ]:        4036 :            cell_base(:,2)=minim(:,itrial)+vecta(:)
    2319         [ +  + ]:        4036 :            cell_base(:,3)=minim(:,itrial)-vectb(:)
    2320                 :        1009 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2321   [ #  #  #  # ]:           0 :          else if(abs(reduceda)<tolsym .and. abs(reducedb-0.5d0)<tolsym )then
    2322         [ #  # ]:           0 :            cell_base(:,2)=minim(:,itrial)-vectb(:)
    2323         [ #  # ]:           0 :            cell_base(:,3)=minim(:,itrial)-vecta(:)-vectb(:)
    2324                 :           0 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2325                 :             :          end if
    2326                 :             :        end if
    2327                 :             :      end if
    2328                 :             : 
    2329                 :             : !    Working hypothesis : monoclinic holohedry, primitive. Then, two angles are 90 degrees
    2330                 :             :      if(foundc==0 .and. iholohedry==2 .and. &
    2331   [ +  +  +  +  :      176926 : &     ang90(ia)==1 .and. ang90(ib)==1 ) then
             +  +  +  + ]
    2332                 :         297 :        fact=1 ; center=0
    2333         [ +  + ]:        1188 :        cell_base(:,1)=minim(:,ia)
    2334         [ +  + ]:        1188 :        cell_base(:,2)=minim(:,itrial)
    2335         [ +  + ]:        1188 :        cell_base(:,3)=minim(:,ib)
    2336                 :             : !      Checks that the basis vectors are OK for the target holohedry
    2337                 :         297 :        call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2338                 :             :      end if
    2339                 :             : 
    2340                 :             : !    Monoclinic holohedry, one-face-centered cell
    2341                 :             : !    Working hypothesis, two vectors have equal length.
    2342         [ +  + ]:     1061556 :      do icase=1,5
    2343   [ +  +  +  +  :     1061556 :        if(foundc==0 .and. iholohedry==2 .and. equal(itrial)==1 ) then
                   +  + ]
    2344         [ +  + ]:       15492 :          vecta(:)=cell_base(:,ia)+cell_base(:,ib)
    2345         [ +  + ]:       15492 :          vectb(:)=cell_base(:,ia)-cell_base(:,ib)
    2346                 :        3873 :          norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2
    2347                 :        3873 :          norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2
    2348                 :             : !        The minim(:,trial) vector belongs to the
    2349                 :             : !        plane parallel to the cell_base(:,ia),cell_base(:,ib) plane
    2350                 :             : !        In that plane, must try minim(:,itrial),
    2351                 :             : !        as well as the 4 different combinations of
    2352                 :             : !        minim(:,itrial) with the vectors in the plane
    2353   [ +  +  +  + ]:        7170 :          if(icase==1)vectc(:)=minim(:,itrial)
    2354   [ +  +  +  + ]:        5964 :          if(icase==2)vectc(:)=minim(:,itrial)+cell_base(:,ia)
    2355   [ +  +  +  + ]:        5958 :          if(icase==3)vectc(:)=minim(:,itrial)+cell_base(:,ib)
    2356   [ +  +  +  + ]:        5946 :          if(icase==4)vectc(:)=minim(:,itrial)-cell_base(:,ia)
    2357   [ +  +  +  + ]:        5946 :          if(icase==5)vectc(:)=minim(:,itrial)-cell_base(:,ib)
    2358                 :        3873 :          norm2c=vectc(1)**2+vectc(2)**2+vectc(3)**2
    2359                 :             :          sca=vectc(1)*vecta(1)+&
    2360                 :             : &         vectc(2)*vecta(2)+&
    2361                 :        3873 : &         vectc(3)*vecta(3)
    2362                 :             :          scb=vectc(1)*vectb(1)+&
    2363                 :             : &         vectc(2)*vectb(2)+&
    2364                 :        3873 : &         vectc(3)*vectb(3)
    2365                 :             : !        DEBUG
    2366                 :             : !        write(std_out,*)' symlatt : test iholohedry=2, sca,scb=',sca,scb
    2367                 :             : !        ENDDEBUG
    2368   [ +  +  +  + ]:        3873 :          if(abs(sca)<tolsym*sqrt(norm2c*norm2a) .or. abs(scb)<tolsym*sqrt(norm2c*norm2b))then
    2369                 :         408 :            fact=2 ; center=3
    2370                 :             : !          The itrial direction is centered
    2371         [ +  + ]:        1632 :            cell_base(:,3)=vectc(:)
    2372         [ +  + ]:         408 :            if(abs(sca)<tolsym*sqrt(norm2c*norm2a))then
    2373         [ +  + ]:         560 :              cell_base(:,2)=vecta(:)
    2374         [ +  + ]:         560 :              cell_base(:,1)=vectb(:)
    2375                 :         140 :              call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2376         [ -  + ]:         268 :            else if(abs(scb)<tolsym*sqrt(norm2c*norm2b))then
    2377         [ +  + ]:        1072 :              cell_base(:,2)=vectb(:)
    2378         [ +  + ]:        1072 :              cell_base(:,1)=vecta(:)
    2379                 :         268 :              call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2380                 :             :            end if
    2381                 :             :          end if
    2382                 :             :        end if
    2383                 :             :      end do ! icase=1,5
    2384                 :             : 
    2385                 :             : !    Monoclinic holohedry, one-face-centered cell, but non equivalent.
    2386                 :             : !    This case, one pair of vectors is orthogonal
    2387   [ +  +  +  +  :      176926 :      if(foundc==0 .and. iholohedry==2 .and. ang90(itrial)==1) then
                   +  + ]
    2388         [ +  + ]:        4704 :        vecta(:)=minim(:,ia)
    2389         [ +  + ]:        4704 :        vectb(:)=minim(:,ib)
    2390                 :        1176 :        norm2a=vecta(1)**2+vecta(2)**2+vecta(3)**2
    2391                 :        1176 :        norm2b=vectb(1)**2+vectb(2)**2+vectb(3)**2
    2392                 :             : !      Project the trial vector on the two vectors
    2393                 :             :        reduceda=( minim(1,itrial)*vecta(1)+       &
    2394                 :             : &       minim(2,itrial)*vecta(2)+       &
    2395                 :        1176 : &       minim(3,itrial)*vecta(3) )/norm2a
    2396                 :             :        reducedb=( minim(1,itrial)*vectb(1)+       &
    2397                 :             : &       minim(2,itrial)*vectb(2)+       &
    2398                 :        1176 : &       minim(3,itrial)*vectb(3) )/norm2b
    2399   [ +  +  +  + ]:        1176 :        if(abs(abs(reduceda)-0.5d0)<tolsym .or. abs(abs(reducedb)-0.5d0)<tolsym) then
    2400                 :         759 :          fact=2 ; center=3
    2401         [ +  + ]:         759 :          if(abs(abs(reduceda)-0.5d0)<tolsym)then
    2402         [ +  + ]:          20 :            cell_base(:,2)=vecta(:)
    2403         [ +  + ]:          20 :            cell_base(:,3)=vectb(:)
    2404         [ +  + ]:          20 :            cell_base(:,1)=2*(minim(:,itrial)-reduceda*vecta(:))
    2405                 :           5 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2406         [ -  + ]:         754 :          else if(abs(abs(reducedb)-0.5d0)<tolsym)then
    2407         [ +  + ]:        3016 :            cell_base(:,2)=vectb(:)
    2408         [ +  + ]:        3016 :            cell_base(:,3)=vecta(:)
    2409         [ +  + ]:        3016 :            cell_base(:,1)=2*(minim(:,itrial)-reducedb*vectb(:))
    2410                 :         754 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2411                 :             :          end if
    2412                 :             :        end if
    2413                 :             :      end if
    2414                 :             : 
    2415                 :             : !    Monoclinic holohedry, one-face-centered cell, but non equivalent.
    2416                 :             : !    This case, no pair of vectors is orthogonal, no pair of vector of equal lentgh
    2417   [ +  +  +  + ]:      263461 :      if(foundc==0 .and. iholohedry==2)then
    2418                 :             : !      Try to find a vector that belongs to the mediator plane, or the binary vector.
    2419                 :             : !      There must be one such vector, if centered monoclinic and no pair of vectors of equal length,
    2420                 :             : !      either among the three vectors, or among one of their differences or sums.
    2421                 :             : !      And there must be, among the two other vectors, one vector whose projection
    2422                 :             : !      on this vector is half the length of this vector.
    2423         [ +  + ]:       29696 :        vecta(:)=minim(:,ia)
    2424         [ +  + ]:       29696 :        vectb(:)=minim(:,ib)
    2425                 :             : !      Try the different possibilities for the vector on which the projection will be half ...
    2426         [ +  + ]:       32759 :        do ii=1,5
    2427   [ +  +  +  + ]:       50388 :          if(ii==1)vectc(:)=minim(:,itrial)
    2428   [ +  +  +  + ]:       48129 :          if(ii==2)vectc(:)=minim(:,itrial)+vecta(:)
    2429   [ +  +  +  + ]:       42174 :          if(ii==3)vectc(:)=minim(:,itrial)-vecta(:)
    2430   [ +  +  +  + ]:       42174 :          if(ii==4)vectc(:)=minim(:,itrial)+vectb(:)
    2431   [ +  +  +  + ]:       42063 :          if(ii==5)vectc(:)=minim(:,itrial)-vectb(:)
    2432                 :       28116 :          norm2trial=vectc(1)**2+vectc(2)**2+vectc(3)**2
    2433                 :             : !        Project the two vectors on the trial vector
    2434                 :       28116 :          reduceda=( vectc(1)*vecta(1)+vectc(2)*vecta(2)+vectc(3)*vecta(3) )/norm2trial
    2435                 :       28116 :          reducedb=( vectc(1)*vectb(1)+vectc(2)*vectb(2)+vectc(3)*vectb(3) )/norm2trial
    2436                 :       28116 :          found=0
    2437         [ +  + ]:       28116 :          if(abs(abs(reduceda)-0.5d0)<tolsym)then
    2438                 :        2055 :            vin1(:)=vectc(:)
    2439         [ +  + ]:        8220 :            vin2(:)=2.0d0*(vecta(:)-reduceda*vectc(:))
    2440                 :        2055 :            vext(:)=vectb(:)
    2441                 :             :            found=1
    2442         [ +  + ]:       26061 :          else if(abs(abs(reducedb)-0.5d0)<tolsym)then
    2443                 :         726 :            vin1(:)=vectc(:)
    2444         [ +  + ]:        2904 :            vin2(:)=2.0d0*(vectb(:)-reduceda*vectc(:))
    2445                 :         726 :            vext(:)=vecta(:)
    2446                 :             :            found=1
    2447                 :             :          end if
    2448                 :        4643 :          if(found==1)exit
    2449                 :             :        end do
    2450                 :             : !      Now, vin1 and vin2 are perpendicular to each other, and in the plane that contains the binary vector.
    2451                 :             : !      One of them must be the binary vector if any.
    2452                 :             : !      On the other hand, vext is out-of-plane. Might belong to the mediator plane or not.
    2453                 :             : !      If C monoclinc, then the projection of this vext on the binary vector will be either 0 or +1/2 or -1/2.
    2454                 :             : !      The binary axis must be stored in cell_base(:,2) for conventional C-cell
    2455         [ +  + ]:        7424 :        if(found==1)then
    2456                 :        2781 :          found=0
    2457                 :             : 
    2458                 :             : !        Test vin1 being the binary axis
    2459                 :        2781 :          norm2trial=vin1(1)**2+vin1(2)**2+vin1(3)**2
    2460                 :        2781 :          reduceda=(vext(1)*vin1(1)+vext(2)*vin1(2)+vext(3)*vin1(3))/norm2trial
    2461         [ +  + ]:        2781 :          if(abs(reduceda)<tolsym)then  ! vin1 is the binary axis and vext is in the mediator plane
    2462                 :        5060 :            found=1
    2463         [ +  + ]:        5060 :            cell_base(:,1)=vin2(:)
    2464         [ +  + ]:        5060 :            cell_base(:,2)=vin1(:)
    2465         [ +  + ]:        5060 :            cell_base(:,3)=vext(:)
    2466         [ +  + ]:        1516 :          else if(abs(abs(reduceda)-0.5d0)<tolsym)then  ! vin1 is the binary axis and vext has +1/2 or -1/2 as projection
    2467                 :         144 :            found=1
    2468         [ +  + ]:         144 :            cell_base(:,1)=vin2(:)
    2469         [ +  + ]:         144 :            cell_base(:,2)=vin1(:)
    2470         [ +  + ]:         144 :            cell_base(:,3)=vext(:)-reduceda*vin1(:)+vin2(:)*half
    2471                 :             :          else
    2472                 :             : !          Test vin2 being the binary axis
    2473                 :        1480 :            norm2trial=vin2(1)**2+vin2(2)**2+vin2(3)**2
    2474                 :        1480 :            reduceda=(vext(1)*vin2(1)+vext(2)*vin2(2)+vext(3)*vin2(3))/norm2trial
    2475         [ +  + ]:        1480 :            if(abs(reduceda)<tolsym)then  ! vin2 is the binary axis and vext is in the mediator plane
    2476                 :         328 :              found=1
    2477         [ +  + ]:         328 :              cell_base(:,1)=vin1(:)
    2478         [ +  + ]:         328 :              cell_base(:,2)=vin2(:)
    2479         [ +  + ]:         328 :              cell_base(:,3)=vext(:)
    2480         [ -  + ]:        1398 :            else if(abs(abs(reduceda)-0.5d0)<tolsym)then  ! vin2 is the binary axis and vext has +1/2 or -1/2 as projection
    2481                 :           0 :              found=1
    2482         [ #  # ]:           0 :              cell_base(:,1)=vin1(:)
    2483         [ #  # ]:           0 :              cell_base(:,2)=vin2(:)
    2484         [ #  # ]:           0 :              cell_base(:,3)=vext(:)-reduceda*vin2(:)+vin1(:)*half
    2485                 :             :            end if
    2486                 :             :          end if
    2487                 :             : 
    2488                 :             :          if(found==1)then
    2489                 :        1383 :            fact=2 ; center=3
    2490                 :        1383 :            call holocell(cell_base,0,foundc,iholohedry,tolsym)
    2491                 :             :          end if
    2492                 :             :        end if
    2493                 :             :      end if
    2494                 :             : 
    2495                 :             :    end do ! Do-loop on three different directions
    2496                 :             :  end do !  Do-loop on different target holohedries
    2497                 :             : 
    2498         [ +  + ]:       40278 :  if(foundc==0)then
    2499                 :        1649 :    iholohedry=1 ; fact=1 ; center=0
    2500                 :        1649 :    cell_base(:,:)=minim(:,:)
    2501                 :             :  end if
    2502                 :             : 
    2503                 :             : !DEBUG
    2504                 :             : !write(std_out,*)' symlatt : done with centering tests, foundc=',foundc
    2505                 :             : !write(std_out,*)'  center=',center
    2506                 :             : !write(std_out,*)'  iholohedry=',iholohedry
    2507                 :             : !call flush(std_out)
    2508                 :             : !ENDDEBUG
    2509                 :             : 
    2510                 :             : !--------------------------------------------------------------------------
    2511                 :             : !Final check on the Bravais lattice, using the basis vectors
    2512                 :             : 
    2513                 :             : !Recompute the metric tensor
    2514         [ +  + ]:       40278 :  if(foundc==1)then
    2515         [ +  + ]:      154516 :    do ii=1,3
    2516                 :             :      metmin(:,ii)=cell_base(1,:)*cell_base(1,ii)+&
    2517                 :             : &     cell_base(2,:)*cell_base(2,ii)+&
    2518         [ +  + ]:      502177 : &     cell_base(3,:)*cell_base(3,ii)
    2519                 :             :    end do
    2520                 :             :  end if
    2521                 :             : 
    2522                 :             : !Examine the angles and vector lengths
    2523                 :       40278 :  ang90(:)=0
    2524         [ +  + ]:       40278 :  if(metmin(1,2)**2<tolsym**2*metmin(1,1)*metmin(2,2))ang90(3)=1
    2525         [ +  + ]:       40278 :  if(metmin(1,3)**2<tolsym**2*metmin(1,1)*metmin(3,3))ang90(2)=1
    2526         [ +  + ]:       40278 :  if(metmin(2,3)**2<tolsym**2*metmin(2,2)*metmin(3,3))ang90(1)=1
    2527                 :       40278 :  equal(:)=0
    2528         [ +  + ]:       40278 :  if(abs(metmin(1,1)-metmin(2,2))<tolsym*half*(metmin(1,1)+metmin(2,2)))equal(3)=1
    2529         [ +  + ]:       40278 :  if(abs(metmin(1,1)-metmin(3,3))<tolsym*half*(metmin(1,1)+metmin(3,3)))equal(2)=1
    2530         [ +  + ]:       40278 :  if(abs(metmin(2,2)-metmin(3,3))<tolsym*half*(metmin(2,2)+metmin(3,3)))equal(1)=1
    2531                 :             : 
    2532                 :             : !DEBUG
    2533                 :             : !write(std_out,*)' symlatt : recompute the  metric tensor '
    2534                 :             : !write(std_out,*)'  ang90=',ang90
    2535                 :             : !write(std_out,*)'  equal=',equal
    2536                 :             : !call flush(std_out)
    2537                 :             : !ENDDEBUG
    2538                 :             : 
    2539                 :             : !The axes will be aligned with the previously determined
    2540                 :             : !basis vectors, EXCEPT for the tetragonal cell, see later
    2541                 :       40278 :  axes(:,:)=cell_base(:,:)
    2542                 :             : 
    2543                 :       40278 :  found=0
    2544                 :             : !Check orthogonal conventional cells
    2545         [ +  + ]:       40278 :  if(ang90(1)+ang90(2)+ang90(3)==3)then
    2546                 :             : 
    2547                 :             : !  Cubic system
    2548         [ +  + ]:       32701 :    if(equal(1)+equal(2)+equal(3)==3)then
    2549                 :             : !    However, one-face centered is not admitted
    2550   [ +  +  +  - ]:       24669 :      if(center==0 .or. center==-1 .or. center==-3)then
    2551                 :       16739 :        iholohedry=7 ; found=1
    2552         [ +  + ]:        7930 :        if(center==0)then
    2553                 :        6739 :          write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is cP (primitive cubic)'
    2554         [ +  + ]:       17930 :        else if(center==-1)then
    2555                 :        1191 :          write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is cI (body-centered cubic)'
    2556                 :             :        else if(center==-3)then
    2557                 :       16739 :          write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is cF (face-centered cubic)'
    2558                 :             :        end if
    2559                 :             :      end if
    2560                 :             :    end if
    2561                 :             : 
    2562                 :             : !  Tetragonal system
    2563   [ +  +  +  +  :        8032 :    if(found==0 .and. &
                   +  + ]
    2564                 :             : &   (equal(1)==1 .or. equal(2)==1 .or. equal(3)==1) )then
    2565                 :             : !    However, one-face centered or face-centered is not admitted
    2566         [ +  + ]:        5431 :      if(center==0 .or. center==-1)then
    2567                 :        5353 :        iholohedry=4 ; found=1
    2568         [ +  + ]:        5353 :        if(equal(1)==1)then
    2569   [ +  +  +  +  :       24560 :          axes(:,3)=cell_base(:,1) ; axes(:,1)=cell_base(:,2) ; axes(:,2)=cell_base(:,3)
                   +  + ]
    2570         [ +  + ]:        2897 :        else if(equal(2)==1)then
    2571   [ +  +  +  +  :        1260 :          axes(:,3)=cell_base(:,2) ; axes(:,2)=cell_base(:,1) ; axes(:,1)=cell_base(:,3)
                   +  + ]
    2572         [ +  - ]:        2771 :        else if(equal(3)==1)then
    2573                 :        2771 :          axes(:,:)=cell_base(:,:)
    2574                 :             :        end if
    2575         [ +  + ]:        5353 :        if(center==0)then
    2576                 :        4747 :          write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is tP (primitive tetragonal)'
    2577                 :             :        else if(center==-1)then
    2578                 :         606 :          write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is tI (body-centered tetragonal)'
    2579                 :             :        end if
    2580                 :             :      end if
    2581                 :             :    end if
    2582                 :             : 
    2583                 :             : !  Orthorhombic system
    2584                 :             :    if(found==0)then
    2585                 :        2679 :      iholohedry=3 ; found=1
    2586                 :        2679 :      axes(:,:)=cell_base(:,:)
    2587         [ +  + ]:        2679 :      if(center==0)then
    2588                 :        1751 :        write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is oP (primitive orthorhombic)'
    2589         [ +  + ]:         928 :      else if(center==-1)then
    2590                 :         302 :        write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is oI (body-centered orthorhombic)'
    2591         [ +  + ]:         626 :      else if(center==1 .or. center==2 .or. center==3)then
    2592                 :         526 :        write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is oC (one-face-centered orthorhombic)'
    2593         [ +  - ]:         100 :      else if(center==-3)then
    2594                 :         100 :        write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is oF (face-centered orthorhombic)'
    2595                 :             :      end if
    2596                 :             :    end if
    2597                 :             : 
    2598                 :             :  else
    2599                 :             : 
    2600                 :             : !  Hexagonal system
    2601   [ +  +  +  +  :        7577 :    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
             +  -  +  - ]
    2602                 :        2196 :      iholohedry=6 ; found=1
    2603                 :        2196 :      write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is hP (primitive hexagonal)'
    2604                 :             :    end if
    2605                 :             : 
    2606                 :             : !  Rhombohedral system
    2607                 :             :    if(found==0 .and. equal(1)+equal(2)+equal(3)==3 .and.       &
    2608   [ +  +  +  -  :        5381 : &   abs(metmin(2,1)-metmin(3,2))<tolsym*metmin(2,2)             .and.       &
                   +  - ]
    2609                 :             : &   abs(metmin(2,1)-metmin(3,1))<tolsym*metmin(1,1) )then
    2610                 :        1581 :      iholohedry=5 ; found=1
    2611                 :        1581 :      write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is hR (rhombohedral)'
    2612                 :             :    end if
    2613                 :             : 
    2614                 :             : !  Monoclinic system
    2615         [ +  + ]:        3800 :    if(found==0 .and. ang90(1)+ang90(2)+ang90(3)==2 )then
    2616                 :        2151 :      iholohedry=2 ; found=1
    2617         [ +  + ]:        2151 :      if(center==0)then
    2618                 :         297 :        write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is mP (primitive monoclinic)'
    2619         [ +  - ]:        1854 :      else if(center==3)then
    2620                 :        1854 :        write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is mC (one-face-centered monoclinic)'
    2621                 :             :      end if
    2622                 :             :    end if
    2623                 :             : 
    2624                 :             : !  Triclinic system
    2625                 :             :    if(found==0)then
    2626                 :        1649 :      iholohedry=1 ; found=1
    2627                 :        1649 :      write(msg,'(a,a)')ch10,' symlatt: the Bravais lattice is aP (primitive triclinic)'
    2628                 :             :    end if
    2629                 :             : 
    2630                 :             :  end if
    2631                 :             : 
    2632                 :       40278 :  call wrtout(iout,msg)
    2633                 :             : 
    2634                 :             : !DEBUG
    2635                 :             : !write(std_out,*)' symlatt : after checking conventional orthogonal cell '
    2636                 :             : !call flush(std_out)
    2637                 :             : !ENDDEBUG
    2638                 :             : 
    2639                 :             : !--------------------------------------------------------------------------
    2640                 :             : !Make sure that axes form a right-handed coordinate system
    2641                 :             : !(Note : this should be done in the body of the routine,
    2642                 :             : !by making changes that leave the sign of the mixed product of the three
    2643                 :             : !vectors invariant)
    2644                 :             :  determinant=axes(1,1)*axes(2,2)*axes(3,3) &
    2645                 :             : & +axes(1,2)*axes(2,3)*axes(3,1) &
    2646                 :             : & +axes(1,3)*axes(3,2)*axes(2,1) &
    2647                 :             : & -axes(1,1)*axes(3,2)*axes(2,3) &
    2648                 :             : & -axes(1,3)*axes(2,2)*axes(3,1) &
    2649                 :       40278 : & -axes(1,2)*axes(2,1)*axes(3,3)
    2650         [ +  + ]:       40278 :  if(determinant<zero)then
    2651   [ +  +  +  + ]:       71162 :    axes(:,:)=-axes(:,:)
    2652                 :             :  end if
    2653                 :             : 
    2654                 :             : !DEBUG
    2655                 :             : !write(std_out,'(a,i4)')' symlatt : before itrial do loop, iholohedry= ',iholohedry
    2656                 :             : !write(std_out,'(a,3es14.6,a,3es14.6,a,3es14.6)')' rprimd=',&
    2657                 :             : !&  rprimd(:,1),ch10,rprimd(:,2),ch10,rprimd(:,3)
    2658                 :             : !call flush(std_out)
    2659                 :             : !ENDDEBUG
    2660                 :             : 
    2661                 :             : !--------------------------------------------------------------------------
    2662                 :             : !Prefer symmetry axes on the same side as the primitive axes,
    2663                 :             : !when the changes are allowed
    2664         [ +  - ]:       63878 :  do itrial=1,100
    2665                 :             : 
    2666                 :             : !  DEBUG
    2667                 :             : !  write(std_out,'(a)')' '
    2668                 :             : !  write(std_out,'(a,i5)')' symlatt : itrial do loop, itrial= ',itrial
    2669                 :             : !  write(std_out,'(a,3es14.6,a,3es14.6,a,3es14.6)')' axes  =',&
    2670                 :             : !  &  axes(:,1),ch10,axes(:,2),ch10,axes(:,3)
    2671                 :             : !  call flush(std_out)
    2672                 :             : !  ENDDEBUG
    2673                 :             : 
    2674         [ +  + ]:      255512 :    do ia=1,3
    2675                 :             :      scprods(ia,:)=axes(1,ia)*rprimd(1,:)+&
    2676                 :             : &     axes(2,ia)*rprimd(2,:)+&
    2677         [ +  + ]:      766536 : &     axes(3,ia)*rprimd(3,:)
    2678         [ +  + ]:      766536 :      norm2trial=sum(axes(:,ia)**2)
    2679         [ +  + ]:      830414 :      scprods(ia,:)=scprods(ia,:)/sqrt(norm2trial)
    2680                 :             :    end do
    2681         [ +  + ]:      255512 :    do ia=1,3
    2682         [ +  + ]:      766536 :      norm2trial=sum(rprimd(:,ia)**2)
    2683         [ +  + ]:      830414 :      scprods(:,ia)=scprods(:,ia)/sqrt(norm2trial)
    2684                 :             :    end do
    2685                 :             : 
    2686                 :             : !DEBUG
    2687                 :             : !  write(std_out,'(a,3f12.6)')' diagonal scalar products ',scprods(1,1),scprods(2,2),scprods(3,3)
    2688                 :             : !  call flush(std_out)
    2689                 :             : !ENDDEBUG
    2690                 :             : 
    2691                 :             : !  One should now try all the generators of the
    2692                 :             : !  proper rotations of each Bravais lattice, coupled with change of
    2693                 :             : !  signs of each vector. This is not done systematically in what follows ...
    2694                 :             : !  Here, the third axis is left unchanged
    2695         [ +  + ]:       63878 :    if(iholohedry/=5)then
    2696   [ +  +  +  + ]:       59476 :      if(scprods(1,1)<-tolsym .and. scprods(2,2)<-tolsym)then
    2697   [ +  +  +  + ]:       16450 :        axes(:,1)=-axes(:,1) ; axes(:,2)=-axes(:,2)
    2698                 :             :        cycle
    2699                 :             :      end if
    2700                 :             :    end if
    2701                 :             : !  The first (or second) axis is left unchanged
    2702         [ +  + ]:       61528 :    if(iholohedry/=5 .and. iholohedry/=6)then
    2703   [ +  +  +  + ]:       54930 :      if(scprods(2,2)<-tolsym .and. scprods(3,3)<-tolsym)then
    2704   [ +  +  +  + ]:        9093 :        axes(:,2)=-axes(:,2) ; axes(:,3)=-axes(:,3)
    2705                 :             :        cycle
    2706                 :             :      end if
    2707   [ +  +  +  + ]:       53631 :      if(scprods(1,1)<-tolsym .and. scprods(3,3)<-tolsym)then
    2708   [ +  +  +  + ]:        3318 :        axes(:,1)=-axes(:,1) ; axes(:,3)=-axes(:,3)
    2709                 :             :        cycle
    2710                 :             :      end if
    2711                 :             :    end if
    2712                 :             : !  Permutation of the three axis
    2713         [ +  + ]:       59755 :    if(iholohedry==5 .or. iholohedry==7)then
    2714                 :       45727 :      trace=scprods(1,1)+scprods(2,2)+scprods(3,3)
    2715         [ +  + ]:       45727 :      if(trace+tolsym< scprods(1,2)+scprods(2,3)+scprods(3,1))then
    2716   [ +  +  +  + ]:        3591 :        vecta(:)=axes(:,1) ; axes(:,1)=axes(:,3)
    2717   [ +  +  +  + ]:        3591 :        axes(:,3)=axes(:,2); axes(:,2)=vecta(:)
    2718                 :             :        cycle
    2719                 :             :      end if
    2720         [ +  + ]:       45214 :      if(trace+tolsym < scprods(1,3)+scprods(2,1)+scprods(3,2))then
    2721   [ +  +  +  + ]:      123648 :        vecta(:)=axes(:,1) ; axes(:,1)=axes(:,2)
    2722   [ +  +  +  + ]:      123648 :        axes(:,2)=axes(:,3); axes(:,3)=vecta(:)
    2723                 :             :        cycle
    2724                 :             :      end if
    2725                 :             : !    This case is observed when the three new vectors
    2726                 :             : !    are pointing opposite to the three original vectors
    2727                 :             : !    One takes their opposite, then switch two of them, then process
    2728                 :             : !    them again in the loop
    2729   [ +  +  +  +  :      358150 :      if(sum(scprods(:,:))<-tolsym)then
                   +  + ]
    2730         [ +  + ]:        5200 :        axes(:,1)=-axes(:,1)
    2731         [ +  + ]:        5200 :        vecta(:)=-axes(:,2)
    2732         [ +  + ]:        5200 :        axes(:,2)=-axes(:,3)
    2733         [ +  + ]:        5200 :        axes(:,3)=vecta(:)
    2734                 :             :        cycle
    2735                 :             :      end if
    2736                 :             :    end if
    2737                 :             : 
    2738                 :             : !  Actually, for iholohedry==7, can test specifically all possibilities
    2739                 :             : !  and take the best one.
    2740                 :             : !  Not activated, because changing the order of symmetries in many tests !
    2741                 :             :    if(iholohedry==7 .and. .false.)then
    2742                 :             : !  if(iholohedry==7)then
    2743                 :             : 
    2744                 :             : !DEBUG
    2745                 :             : !write(std_out,'(a,a)')ch10,' enter search of all possibilities for iholohedry==7 '
    2746                 :             : !write(std_out,'(a,3es14.6,a,3es14.6,a,3es14.6)')' axes  =',&
    2747                 :             : !&  axes(:,1),ch10,axes(:,2),ch10,axes(:,3)
    2748                 :             : !call flush(std_out)
    2749                 :             : !ENDDEBUG
    2750                 :             : 
    2751                 :             :      do iaxis1=1,3
    2752                 :             :        axes_try(:,1)=axes(:,iaxis1)
    2753                 :             :        do iaxis2=1,2
    2754                 :             :          if(iaxis1==1)axes_try(:,2)=axes(:,1+iaxis2)
    2755                 :             :          if(iaxis1==2)axes_try(:,2)=axes(:,2*iaxis2-1)
    2756                 :             :          if(iaxis1==3)axes_try(:,2)=axes(:,iaxis2)
    2757                 :             :          if(iaxis2==1)axes_try(:,3)=axes(:,3)
    2758                 :             :          if(iaxis2==2)axes_try(:,3)=axes(:,1)
    2759                 :             :          if(iaxis1==1.and.iaxis2==2)axes_try(:,3)=axes(:,2)
    2760                 :             :          if(iaxis1==3.and.iaxis2==1)axes_try(:,3)=axes(:,2)
    2761                 :             :          do isign1=1,-1,-2
    2762                 :             :            axes_try(:,1)=-axes_try(:,1)
    2763                 :             :            do isign2=1,-1,-2
    2764                 :             :              axes_try(:,2)=-axes_try(:,2)
    2765                 :             :              determinant=axes_try(1,1)*axes_try(2,2)*axes_try(3,3) &
    2766                 :             : &                       +axes_try(1,2)*axes_try(2,3)*axes_try(3,1) &
    2767                 :             : &                       +axes_try(1,3)*axes_try(3,2)*axes_try(2,1) &
    2768                 :             : &                       -axes_try(1,1)*axes_try(3,2)*axes_try(2,3) &
    2769                 :             : &                       -axes_try(1,3)*axes_try(2,2)*axes_try(3,1) &
    2770                 :             : &                       -axes_try(1,2)*axes_try(2,1)*axes_try(3,3)
    2771                 :             :              if(determinant<zero)axes_try(:,3)=-axes_try(:,3)
    2772                 :             :              do ia=1,3
    2773                 :             :                scprods(ia,:)=axes_try(1,ia)*rprimd(1,:)+&
    2774                 :             : &                            axes_try(2,ia)*rprimd(2,:)+&
    2775                 :             : &                            axes_try(3,ia)*rprimd(3,:)
    2776                 :             :                norm2trial=sum(axes_try(:,ia)**2)
    2777                 :             :                scprods(ia,:)=scprods(ia,:)/sqrt(norm2trial)
    2778                 :             :              end do
    2779                 :             :              do ia=1,3
    2780                 :             :                norm2trial=sum(rprimd(:,ia)**2)
    2781                 :             :                scprods(:,ia)=scprods(:,ia)/sqrt(norm2trial)
    2782                 :             :              end do
    2783                 :             :              trace=scprods(1,1)+scprods(2,2)+scprods(3,3)
    2784                 :             :              if(iaxis1==1.and.iaxis2==1.and.isign1==1.and.isign2==1)then
    2785                 :             :                trace_best=trace
    2786                 :             :                axes_best=axes_try
    2787                 :             :              else if (trace>trace_best+tolsym)then
    2788                 :             :                trace_best=trace
    2789                 :             :                axes_best=axes_try
    2790                 :             :              endif
    2791                 :             :            enddo ! isign2
    2792                 :             :          enddo ! isign1
    2793                 :             :        enddo ! iaxes2
    2794                 :             :      enddo ! iaxes1
    2795                 :             :      axes=axes_best
    2796                 :             :    endif ! iholohedry=7
    2797                 :           0 :    exit
    2798                 :             :  end do
    2799                 :             : 
    2800                 :             : !--------------------------------------------------------------------------
    2801                 :             : 
    2802                 :             : !DEBUG
    2803                 :             : !write(std_out,'(a,a)')ch10,' after order/sign optimization do-loop '
    2804                 :             : !write(std_out,'(a,3es14.6,a,3es14.6,a,3es14.6)')' rprimd=',&
    2805                 :             : !&  rprimd(:,1),ch10,rprimd(:,2),ch10,rprimd(:,3)
    2806                 :             : !write(std_out,'(a,3es14.6,a,3es14.6,a,3es14.6)')' axes  =',&
    2807                 :             : !&  axes(:,1),ch10,axes(:,2),ch10,axes(:,3)
    2808                 :             : !call flush(std_out)
    2809                 :             : !ENDDEBUG
    2810                 :             : 
    2811                 :             : !Compute the coordinates of rprimd in the system defined by axes(:,:)
    2812                 :       40278 :  call matr3inv(axes,axesinvt)
    2813         [ +  + ]:      161112 :  do ii=1,3
    2814                 :             :    coord(:,ii)=rprimd(1,ii)*axesinvt(1,:)+ &
    2815                 :             : &   rprimd(2,ii)*axesinvt(2,:)+ &
    2816         [ +  + ]:      523614 : &   rprimd(3,ii)*axesinvt(3,:)
    2817                 :             :  end do
    2818                 :             : 
    2819                 :             : !Check that the coordinates are integers, or half-integer in
    2820                 :             : !the case there is a centering, and generate integer coordinates
    2821         [ +  + ]:      161112 :  do ii=1,3
    2822         [ +  + ]:      523614 :    do jj=1,3
    2823                 :      362502 :      val=coord(ii,jj)*fact
    2824         [ -  + ]:      362502 :      if(abs(val-nint(val))>fact*two*tolsym)then
    2825                 :             :        write(msg,'(4a,a,3es18.10,a,a,3es18.10,a,a,3es18.10,a,a,i4)')&
    2826                 :           0 :        'One of the coordinates of rprimd in axes is non-integer,',ch10,&
    2827                 :           0 :        'or non-half-integer (if centering), within 2*tolsym.',ch10,&
    2828                 :           0 :        'coord=',coord(:,1),ch10,&
    2829                 :           0 :        '      ',coord(:,2),ch10,&
    2830                 :           0 :        '      ',coord(:,3),ch10,&
    2831                 :           0 :        'fact=',fact
    2832                 :           0 :        ABI_BUG(msg)
    2833                 :             :      end if
    2834                 :      483336 :      icoord(ii,jj)=nint(val)
    2835                 :             :    end do
    2836                 :             :  end do
    2837                 :             : 
    2838                 :             : !Store the bravais lattice characteristics
    2839                 :       40278 :  bravais(1)=iholohedry
    2840                 :       40278 :  bravais(2)=center
    2841         [ +  + ]:      161112 :  bravais(3:5)=icoord(1:3,1)
    2842         [ +  + ]:      161112 :  bravais(6:8)=icoord(1:3,2)
    2843         [ +  + ]:      161112 :  bravais(9:11)=icoord(1:3,3)
    2844                 :             : 
    2845                 :             : !--------------------------------------------------------------------------
    2846                 :             : !Initialize the set of symmetries
    2847                 :             : !Bravais lattices are always invariant under identity and inversion
    2848                 :             : 
    2849                 :             : !Identity and inversion
    2850   [ +  +  +  +  :     1006950 :  ptsymrel(:,:,1)=identity(:,:) ; ptsymrel(:,:,2)=-identity(:,:)
             +  +  +  + ]
    2851                 :       40278 :  nptsym=2
    2852                 :             : 
    2853                 :             : !Keep this for IFCv70 compiler
    2854                 :             :  if(nptsym/=2)then
    2855                 :             :    write(msg,'(a,a,a,a)')ch10,&
    2856                 :             :    ' symlatt : BUG -',ch10,&
    2857                 :             :    '  Crazy error, compiler bug '
    2858                 :             :    call wrtout(std_out,msg)
    2859                 :             :  end if
    2860                 :             : 
    2861                 :             : !--------------------------------------------------------------------------
    2862                 :             : !Initialize some generators
    2863                 :             : !gen6 is defined in a coordinated system with gamma=120 degrees
    2864                 :       40278 :  gen6(:,:)=0  ; gen6(3,3)=1  ; gen6(1,1)=1  ; gen6(1,2)=-1 ; gen6(2,1)=1
    2865                 :       40278 :  gen3(:,:)=0  ; gen3(1,2)=1  ; gen3(2,3)=1  ; gen3(3,1)=1
    2866                 :       40278 :  gen2xy(:,:)=0 ; gen2xy(2,1)=1 ; gen2xy(1,2)=1; gen2xy(3,3)=1
    2867                 :       40278 :  gen2y(:,:)=0 ; gen2y(1,1)=-1; gen2y(2,2)=1 ; gen2y(3,3)=-1
    2868                 :       40278 :  gen2z(:,:)=0 ; gen2z(1,1)=-1; gen2z(2,2)=-1; gen2z(3,3)=1
    2869                 :             : 
    2870                 :             : !--------------------------------------------------------------------------
    2871                 :             : 
    2872                 :             : !Define the generators for each holohedry (inversion is already included)
    2873         [ +  + ]:       40278 :  if(iholohedry==6)then
    2874                 :        2196 :    ngen=2
    2875   [ +  +  +  + ]:       28548 :    gen(:,:,1)=gen2xy(:,:) ; order(1)=2
    2876   [ +  +  +  + ]:       28548 :    gen(:,:,2)=gen6(:,:)   ; order(2)=6
    2877         [ +  + ]:       38082 :  else if(iholohedry==5)then
    2878                 :        1581 :    ngen=2
    2879   [ +  +  +  + ]:       20553 :    gen(:,:,1)=gen2xy(:,:) ; order(1)=2
    2880   [ +  +  +  + ]:       20553 :    gen(:,:,2)=gen3(:,:)   ; order(2)=3
    2881                 :             :  else
    2882   [ +  +  +  + ]:      474513 :    gen(:,:,1)=gen2y(:,:)  ; order(1)=2
    2883   [ +  +  +  + ]:      474513 :    gen(:,:,2)=gen2z(:,:)  ; order(2)=2
    2884   [ +  +  +  + ]:      474513 :    gen(:,:,3)=gen2xy(:,:) ; order(3)=2
    2885   [ +  +  +  + ]:      474513 :    gen(:,:,4)=gen3(:,:)   ; order(4)=3
    2886         [ +  + ]:       36501 :    if(iholohedry<=4)ngen=iholohedry-1
    2887         [ +  + ]:       36501 :    if(iholohedry==7)ngen=4
    2888                 :             :  end if
    2889                 :             : 
    2890                 :             : !Build the point symmetry operations from generators, in the reduced system
    2891                 :             : !of coordinates defined by axes(:,:)
    2892         [ +  + ]:       40278 :  if(ngen/=0)then
    2893         [ +  + ]:      168427 :    do igen=1,ngen
    2894         [ +  + ]:     1424012 :      do isym=1+nptsym,order(igen)*nptsym
    2895                 :     1294214 :        jsym=isym-nptsym
    2896         [ +  + ]:     5306654 :        do ii=1,3
    2897                 :             :          ptsymrel(:,ii,isym)=gen(:,1,igen)*ptsymrel(1,ii,jsym)+ &
    2898                 :             : &         gen(:,2,igen)*ptsymrel(2,ii,jsym)+ &
    2899         [ +  + ]:    16824782 : &         gen(:,3,igen)*ptsymrel(3,ii,jsym)
    2900                 :             :        end do
    2901                 :             :      end do
    2902                 :      168427 :      nptsym=order(igen)*nptsym
    2903                 :             : 
    2904                 :             :    end do
    2905                 :             :  end if
    2906                 :             : 
    2907                 :             : !--------------------------------------------------------------------------
    2908                 :             : 
    2909                 :             : !Transform symmetry matrices in the system defined by rprimd
    2910                 :       40278 :  call symrelrot(nptsym,axes,rprimd,ptsymrel,tolsym)
    2911                 :             : 
    2912                 :             : !DEBUG
    2913                 :             : !write(std_out,'(a)') ' symlatt : exit '
    2914                 :             : !call flush(std_out)
    2915                 :             : !stop
    2916                 :             : !ENDDEBUG
    2917                 :             : 
    2918                 :       40278 : end subroutine symlatt
    2919                 :             : !!***
    2920                 :             : 
    2921         [ -  + ]:      200354 : end module m_symfind
    2922                 :             : !!***
        

Generated by: LCOV version 2.3-1