TABLE OF CONTENTS


ABINIT/ingeo [ Functions ]

[ Top ] [ Functions ]

NAME

 ingeo

FUNCTION

 Initialize geometry variables for the ABINIT code.
 1) set up unit cell : acell, rprim and rprimd ; deduce Bravais lattice
 2) (removed)
 3) Set up the number of atoms (natrd) in the primitive set, to be read.
 4) Read the type of each atom in the primitive set
 5) Read coordinates for each atom in the primitive set
 6) Eventually read the symmetries
 7) Checks whether the geometry builder must be used,
    and call it if needed. Call eventually the symmetry builder and analyser
    Make the adequate transfers if the geometry
    builder is not needed.
 8) Initialize the fixing of atoms,
    the initial velocities, and the initial atomic spin

COPYRIGHT

 Copyright (C) 1998-2018 ABINIT group (XG, RC)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .
 For the initials of contributors, see ~abinit/doc/developers/contributors.txt .

INPUTS

 berryopt == 4/14: electric field is on; berryopt = 6/7/16/17: electric displacement field is on
 iimage= index of the current image
 iout=unit number of output file
 jdtset=number of the dataset looked for
 lenstr=actual length of the string
 msym=default maximal number of symmetries
 natom=number of atoms
 nimage=number of images
 npsp=number of pseudopotentials (needed for the dimension of znucl)
 nspden=number of spin-density components
 nsppol=number of independent spin polarizations
 ntypat=number of type of atoms
 nzchempot=defines the use of a spatially-varying chemical potential along z
 pawspnorb=1 when spin-orbit is activated within PAW
 ratsph(1:ntypat)=radius of the atomic sphere
 string*(*)=character string containing all the input data, used
  only if choice=1 or 3. Initialized previously in instrng.

OUTPUT

 acell(3)=length of primitive vectors
 amu(ntypat)=mass of each atomic type
 bravais(11)=characteristics of Bravais lattice (see symlatt.F90)
 genafm(3)=magnetic translation generator (in case of Shubnikov group type IV)
 iatfix(3,natom)=indices for atoms fixed along some (or all) directions
 jellslab=not zero if jellslab keyword is activated
 slabzbeg, slabzend= the z coordinates of beginning / end of the jellium slab
 mixalch(npspalch,ntypalch)=alchemical mixing factors
 nsym=actual number of symmetries
 nucdipmom(3,natom)=nuclear magnetic dipole moment of each atom in atomic units
 ptgroupma = magnetic point group number
 rprim(3,3)=dimensionless real space primitive translations
 spgroup=symmetry space group
 spinat(3,natom)=initial spin of each atom, in unit of hbar/2.
 symafm(1:msym)=(anti)ferromagnetic part of symmetry operations
 symmorphi=if 0, only allows symmorphic symmetry operations
 symrel(3,3,1:msym)=symmetry operations in real space in terms
  of primitive translations
 tnons(3,1:msym)=nonsymmorphic translations for symmetry operations
 tolsym=tolerance for the symmetry operations
 typat(natom)=type integer for each atom in cell
 vel(3,natom)=initial velocity of atoms in bohr/atomic time units
 vel_cell(3,3)=initial velocity of cell parameters in bohr/atomic time units
 xred(3,natom)=reduced dimensionless atomic coordinates
 znucl(1:npsp)=nuclear number of atom as specified in psp file

SIDE EFFECTS

NOTES

 the parameters ntypat and natom have already been read in indims,
 and were used to dimension the arrays needed here.

TODO

 The dtset datastructure should NOT be an argument of this routine ... !

 MG: I completely agree. Abinit developers must learn that Fortran does not allow for aliasing!

PARENTS

      invars1

CHILDREN

      atomdata_from_znucl,chkorthsy,fillcell,gensymshub,gensymshub4
      gensymspgr,ingeo_img,ingeobld,intagm,mati3inv,metric,mkradim,mkrdim
      randomcellpos,symanal,symatm,symfind,symlatt,symmetrize_rprimd
      symmetrize_xred,symrelrot,wrtout,xcart2xred,xred2xcart

SOURCE

  97 #if defined HAVE_CONFIG_H
  98 #include "config.h"
  99 #endif
 100 
 101 #include "abi_common.h"
 102 
 103 subroutine ingeo (acell,amu,dtset,bravais,&
 104 & genafm,iatfix,icoulomb,iimage,iout,jdtset,jellslab,lenstr,mixalch,&
 105 & msym,natom,nimage,npsp,npspalch,nspden,nsppol,nsym,ntypalch,ntypat,&
 106 & nucdipmom,nzchempot,pawspnorb,&
 107 & ptgroupma,ratsph,rprim,slabzbeg,slabzend,spgroup,spinat,string,symafm,&
 108 & symmorphi,symrel,tnons,tolsym,typat,vel,vel_cell,xred,znucl)
 109 
 110  use defs_basis
 111  use defs_abitypes
 112  use m_ingeo_img
 113  use m_profiling_abi
 114  use m_errors
 115  use m_atomdata
 116 
 117  use m_geometry, only : mkradim, mkrdim, xcart2xred, xred2xcart, randomcellpos, metric
 118  use m_parser,   only : intagm
 119 
 120 !This section has been created automatically by the script Abilint (TD).
 121 !Do not modify the following lines by hand.
 122 #undef ABI_FUNC
 123 #define ABI_FUNC 'ingeo'
 124  use interfaces_14_hidewrite
 125  use interfaces_32_util
 126  use interfaces_41_geometry
 127  use interfaces_57_iovars, except_this_one => ingeo
 128 !End of the abilint section
 129 
 130  implicit none
 131 
 132 !Arguments ------------------------------------
 133 !scalars
 134  integer,intent(in) :: iimage,iout,jdtset,lenstr,msym
 135  integer,intent(in) :: nimage,npsp,npspalch,nspden,nsppol
 136  integer,intent(in) :: ntypalch,ntypat,nzchempot,pawspnorb
 137  integer,intent(inout) :: natom,symmorphi
 138  integer,intent(out) :: icoulomb,jellslab,ptgroupma,spgroup !vz_i
 139  integer,intent(inout) :: nsym !vz_i
 140  real(dp),intent(out) :: slabzbeg,slabzend,tolsym
 141  character(len=*),intent(in) :: string
 142 !arrays
 143  integer,intent(out) :: bravais(11),iatfix(3,natom) !vz_i
 144  integer,intent(inout) :: symafm(msym) !vz_i
 145  integer,intent(inout) :: symrel(3,3,msym) !vz_i
 146  integer,intent(out) :: typat(natom)
 147  real(dp),intent(inout) :: nucdipmom(3,natom)
 148  real(dp),intent(in) :: ratsph(ntypat)
 149  real(dp),intent(inout) :: spinat(3,natom)
 150  real(dp),intent(out) :: acell(3),amu(ntypat),genafm(3),mixalch(npspalch,ntypalch)
 151  real(dp),intent(inout) :: rprim(3,3),tnons(3,msym) !vz_i
 152  real(dp),intent(out) :: vel(3,natom),vel_cell(3,3),xred(3,natom)
 153  real(dp),intent(in) :: znucl(npsp)
 154  type(dataset_type),intent(in) :: dtset
 155 
 156 !Local variables-------------------------------
 157  character(len=*), parameter :: format01110 ="(1x,a6,1x,(t9,8i8) )"
 158  character(len=*), parameter :: format01160 ="(1x,a6,1x,1p,(t9,3g18.10)) "
 159 !scalars
 160  integer :: bckbrvltt,brvltt,chkprim,iatom,idir,iexit,ii,ipsp,irreducible,isym,itypat
 161  integer :: jsym,marr,mu,natfix,natrd,nobj,noncoll
 162  integer :: nptsym,nsym_now,ntyppure,random_atpos,shubnikov,spgaxor,spgorig
 163  integer :: spgroupma,tacell,tangdeg,tgenafm,tnatrd,tread,trprim,tscalecart,tspgroupma
 164  integer :: txangst,txcart,txred,txrandom,use_inversion
 165  real(dp) :: amu_default,a2,aa,cc,cosang,ucvol,sumalch
 166  character(len=500) :: message
 167  type(atomdata_t) :: atom
 168 !arrays
 169  integer,allocatable :: ptsymrel(:,:,:),typat_read(:),symrec(:,:,:),indsym(:,:,:)
 170  integer,allocatable :: intarr(:)
 171  real(dp) :: angdeg(3), field_xred(3),gmet(3,3),gprimd(3,3),rmet(3,3),rcm(3)
 172  real(dp) :: rprimd(3,3),rprimd_new(3,3),scalecart(3)
 173 !real(dp) :: tsec(2)
 174  real(dp),allocatable :: mass_psp(:)
 175  real(dp),allocatable :: tnons_cart(:,:),xangst_read(:,:)
 176  real(dp),allocatable :: xcart(:,:),xcart_read(:,:),xred_read(:,:),dprarr(:)
 177 
 178 ! *************************************************************************
 179 
 180  marr=max(12,3*natom,9*msym)
 181  ABI_ALLOCATE(intarr,(marr))
 182  ABI_ALLOCATE(dprarr,(marr))
 183 
 184 !1) set up unit cell : acell, rprim and rprimd ---------------------
 185 
 186  acell(1:3)=one
 187  call intagm(dprarr,intarr,jdtset,marr,3,string(1:lenstr),'acell',tacell,'LEN')
 188  if(tacell==1) acell(1:3)=dprarr(1:3)
 189  call ingeo_img(acell,iimage,jdtset,lenstr,nimage,3,string,"acell",tacell,'LEN')
 190 
 191  scalecart(1:3)=one
 192  call intagm(dprarr,intarr,jdtset,marr,3,string(1:lenstr),'scalecart',tscalecart,'LEN')
 193  if(tscalecart==1) scalecart(1:3)=dprarr(1:3)
 194  call ingeo_img(scalecart,iimage,jdtset,lenstr,nimage,3,string,"scalecart",tscalecart,'LEN')
 195 
 196 !Check that input length scales acell(3) are > 0
 197  do mu=1,3
 198    if(acell(mu)<=zero) then
 199      write(message, '(a,i0,a, 1p,e14.6,a,a,a,a)' )&
 200 &     'Length scale ',mu,' is input as acell=',acell(mu),ch10,&
 201 &     'However, length scales must be > 0 ==> stop',ch10,&
 202 &     'Action: correct acell in input file.'
 203      MSG_ERROR(message)
 204    end if
 205  end do
 206 
 207 !Initialize rprim, or read the angles
 208  tread=0
 209  call intagm(dprarr,intarr,jdtset,marr,9,string(1:lenstr),'rprim',trprim,'DPR')
 210  if(trprim==1)rprim(:,:)=reshape( dprarr(1:9) , (/3,3/) )
 211  call ingeo_img(rprim,iimage,jdtset,lenstr,nimage,3,3,string,"rprim",trprim,'DPR')
 212 
 213 !If none of the rprim were read ...
 214  if(trprim==0)then
 215    call intagm(dprarr,intarr,jdtset,marr,3,string(1:lenstr),'angdeg',tangdeg,'DPR')
 216    angdeg(:)=dprarr(1:3)
 217    call ingeo_img(angdeg,iimage,jdtset,lenstr,nimage,3,string,"angdeg",tangdeg,'DPR')
 218 
 219    if(tangdeg==1)then
 220      call wrtout(std_out,' ingeo : use angdeg to generate rprim.',"COLL")
 221 
 222 !    Check that input angles are positive
 223      do mu=1,3
 224        if(angdeg(mu)<=0.0_dp) then
 225          write(message, '(a,i0,a,1p,e14.6,a,a,a,a)' )&
 226 &         'Angle number ',mu,' is input as angdeg=',angdeg(mu),ch10,&
 227 &         'However, angles must be > 0 ==> stop',ch10,&
 228 &         'Action: correct angdeg in input file.'
 229          MSG_ERROR(message)
 230        end if
 231      end do
 232 
 233 !    Check that the sum of angles is smaller than 360 degrees
 234      if(angdeg(1)+angdeg(2)+angdeg(3)>=360.0_dp) then
 235        write(message, '(a,a,a,es14.4,a,a,a)' )&
 236 &       'The sum of input angles (angdeg(1:3)) must be lower than 360 degrees',ch10,&
 237 &       'while it is ',angdeg(1)+angdeg(2)+angdeg(3),'.',ch10,&
 238 &       'Action: correct angdeg in input file.'
 239        MSG_ERROR(message)
 240      end if
 241 
 242      if( abs(angdeg(1)-angdeg(2))<tol12 .and. &
 243 &     abs(angdeg(2)-angdeg(3))<tol12 .and. &
 244 &     abs(angdeg(1)-90._dp)+abs(angdeg(2)-90._dp)+abs(angdeg(3)-90._dp)>tol12 )then
 245 !      Treat the case of equal angles (except all right angles):
 246 !      generates trigonal symmetry wrt third axis
 247        cosang=cos(pi*angdeg(1)/180.0_dp)
 248        a2=2.0_dp/3.0_dp*(1.0_dp-cosang)
 249        aa=sqrt(a2)
 250        cc=sqrt(1.0_dp-a2)
 251        rprim(1,1)=aa        ; rprim(2,1)=0.0_dp                 ; rprim(3,1)=cc
 252        rprim(1,2)=-0.5_dp*aa ; rprim(2,2)= sqrt(3.0_dp)*0.5_dp*aa ; rprim(3,2)=cc
 253        rprim(1,3)=-0.5_dp*aa ; rprim(2,3)=-sqrt(3.0_dp)*0.5_dp*aa ; rprim(3,3)=cc
 254 !      DEBUG
 255 !      write(std_out,*)' ingeo : angdeg=',angdeg(1:3)
 256 !      write(std_out,*)' ingeo : aa,cc=',aa,cc
 257 !      ENDDEBUG
 258      else
 259 !      Treat all the other cases
 260        rprim(:,:)=0.0_dp
 261        rprim(1,1)=1.0_dp
 262        rprim(1,2)=cos(pi*angdeg(3)/180.0_dp)
 263        rprim(2,2)=sin(pi*angdeg(3)/180.0_dp)
 264        rprim(1,3)=cos(pi*angdeg(2)/180.0_dp)
 265        rprim(2,3)=(cos(pi*angdeg(1)/180.0_dp)-rprim(1,2)*rprim(1,3))/rprim(2,2)
 266        rprim(3,3)=sqrt(1.0_dp-rprim(1,3)**2-rprim(2,3)**2)
 267      end if
 268 
 269    end if
 270 !  No problem if neither rprim nor angdeg are defined : use default rprim
 271  end if
 272 
 273 !Rescale rprim using scalecart (and set scalecart to one)
 274  rprim(:,1)=scalecart(:)*rprim(:,1)
 275  rprim(:,2)=scalecart(:)*rprim(:,2)
 276  rprim(:,3)=scalecart(:)*rprim(:,3)
 277  scalecart(:)=one
 278 
 279 !Compute different matrices in real and reciprocal space, also checks whether ucvol is positive.
 280  call mkrdim(acell,rprim,rprimd)
 281  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
 282 
 283  tolsym=tol8
 284  call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'tolsym',tread,'DPR')
 285  if(tread==1) tolsym=dprarr(1)
 286 
 287 !Find a tentative Bravais lattice and its point symmetries (might not use them)
 288 !Note that the Bravais lattice might not be the correct one yet (because the
 289 !actual atomic locations might lower the symattry obtained from the lattice parameters only)
 290  ABI_ALLOCATE(ptsymrel,(3,3,msym))
 291  call symlatt(bravais,msym,nptsym,ptsymrel,rprimd,tolsym)
 292 
 293 !3) Possibly, initialize a jellium slab
 294  jellslab=0
 295  call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'jellslab',tread,'INT')
 296  if(tread==1) jellslab=intarr(1)
 297 
 298  slabzbeg=zero
 299  slabzend=zero
 300  if(jellslab/=0)then
 301    call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'slabzbeg',tread,'DPR')
 302    if(tread==1) slabzbeg=dprarr(1)
 303 
 304    call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'slabzend',tread,'DPR')
 305    if(tread==1) slabzend=dprarr(1)
 306  end if
 307 
 308 !4) Set up the number of atoms in the primitive set, to be read.
 309 
 310 !This is the default
 311  natrd=natom
 312 
 313  call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'natrd',tnatrd,'INT')
 314  if(tnatrd==1) natrd=intarr(1)
 315 
 316  if(natrd<1 .or. natrd>natom)then
 317    write(message, '(3a,i0,a,i0,2a,a)' )&
 318 &   'The number of atoms to be read (natrd) must be positive and not bigger than natom.',ch10,&
 319 &   'This is not the case : natrd=',natrd,', natom=',natom,ch10,&
 320 &   'Action: correct natrd or natom in your input file.'
 321    MSG_ERROR(message)
 322  end if
 323 
 324 
 325 !5) Read the type and initial spin of each atom in the primitive set--------
 326 
 327 !Check for the use of the old name of this variable
 328  call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'type',tread,'INT')
 329  if(tread==1) then
 330    write(message,'(a,a,a)')&
 331 &   'The use of the "type" input variable is forbidden since version 4.1 .',ch10,&
 332 &   'Action: replace "type" by "typat".'
 333    MSG_ERROR(message)
 334  end if
 335 
 336  ABI_ALLOCATE(typat_read,(natrd))
 337  typat_read(1)=1
 338 
 339  call intagm(dprarr,intarr,jdtset,marr,natrd,string(1:lenstr),'typat',tread,'INT')
 340 
 341 !If not read, try the XYZ data
 342  if(tread==0)then
 343    call intagm(dprarr,intarr,jdtset,marr,natrd,string(1:lenstr),'_typat',tread,'INT')
 344  end if
 345  if(tread==1) typat_read(1:natrd)=intarr(1:natrd)
 346 
 347  do iatom=1,natrd
 348    if(typat_read(iatom)<1 .or. typat_read(iatom)>ntypat )then
 349      write(message,'(a,i0,a,i0,a,a,a,i0,a,a,a)')&
 350 &     'The input type of atom number ',iatom,' is equal to ',typat_read(iatom),',',ch10,&
 351 &     'while it should be between 1 and ntypat= ',ntypat,'.',ch10,&
 352 &     'Action: change either the variable typat or the variable ntypat.'
 353      MSG_ERROR(message)
 354    end if
 355  end do
 356 
 357 !6) Read coordinates for each atom in the primitive set--------
 358 
 359  ABI_ALLOCATE(xangst_read,(3,natrd))
 360  ABI_ALLOCATE(xcart_read,(3,natrd))
 361  ABI_ALLOCATE(xred_read,(3,natrd))
 362 
 363  random_atpos=0
 364  call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'random_atpos',txrandom,'INT')
 365  if(txrandom==1) random_atpos=intarr(1)
 366  if (random_atpos < 0 .or. random_atpos > 5) then
 367    write(message,'(a,a,a)')&
 368 &   'Random positions is a variable defined between 0 and 5. Error in the input file. ',ch10,&
 369 &   'Action: define one of these in your input file.'
 370    MSG_ERROR(message)
 371  end if
 372 !if(nimage/=1 .and. iimage/=1)then
 373 !FIXME : should this be called outside the above end if?
 374  call randomcellpos(natom,npsp,ntypat,random_atpos,ratsph,rprim,rprimd,typat_read,xred_read(:,1:natrd),znucl,acell)
 375 !This should not be printed if randomcellpos did nothing - it contains garbage. Spurious output anyway
 376 !end if
 377 
 378  call intagm(dprarr,intarr,jdtset,marr,3*natrd,string(1:lenstr),'xred',txred,'DPR')
 379  if(txred==1 .and. txrandom == 0) xred_read(:,1:natrd) = reshape( dprarr(1:3*natrd) , (/3,natrd/) )
 380  call ingeo_img(xred_read,iimage,jdtset,lenstr,nimage,3,natrd,string,"xred",txred,'DPR')
 381 
 382  call intagm(dprarr,intarr,jdtset,marr,3*natrd,string(1:lenstr),'xangst',txangst,'DPR')
 383  if(txangst==1 .and. txrandom==0) xangst_read(:,1:natrd) = reshape( dprarr(1:3*natrd) , (/3,natrd/) )
 384  call ingeo_img(xangst_read,iimage,jdtset,lenstr,nimage,3,natrd,string,"xangst",txangst,'DPR')
 385 
 386  call intagm(dprarr,intarr,jdtset,marr,3*natrd,string(1:lenstr),'xcart',txcart,'LEN')
 387  if(txcart==1 .and. txrandom==0)xcart_read(:,1:natrd) = reshape( dprarr(1:3*natrd) , (/3,natrd/) )
 388  call ingeo_img(xcart_read,iimage,jdtset,lenstr,nimage,3,natrd,string,"xcart",txcart,'LEN')
 389 
 390 !Might initialize xred from XYZ file
 391  if(txred+txcart+txangst+txrandom==0)then
 392    call intagm(dprarr,intarr,jdtset,marr,3*natrd,string(1:lenstr),'_xred',txred,'DPR')
 393    if(txred==1 .and. txrandom==0) xred_read(:,1:natrd) = reshape( dprarr(1:3*natrd) , (/3,natrd/) )
 394 
 395    call intagm(dprarr,intarr,jdtset,marr,3*natrd,string(1:lenstr),'_xangst',txangst,'DPR')
 396    if(txangst==1 .and. txrandom==0) xangst_read(:,1:natrd) = reshape( dprarr(1:3*natrd) , (/3,natrd/) )
 397  end if
 398 
 399  if (txred+txcart+txangst+txrandom==0) then
 400    write(message, '(a,a,a)' )&
 401 &   'Neither xred nor xangst nor xcart are present in input file. ',ch10,&
 402 &   'Action: define one of these in your input file.'
 403    MSG_ERROR(message)
 404  end if
 405 
 406  if (txred==1)   write(message, '(a)' ) '  xred   is defined in input file'
 407  if (txangst==1) write(message, '(a)' ) '  xangst is defined in input file'
 408  if (txcart ==1) write(message, '(a)' ) '  xcart  is defined in input file'
 409  if (txrandom ==1) write(message, '(a)' ) '  xred  as random positions in the unit cell'
 410  if (txrandom ==1) write(message, '(a)' ) '  xcart  are defined from a random distribution '
 411  call wrtout(std_out,message,'COLL')
 412 
 413  if (txred+txcart+txangst+txrandom>1)then
 414    write(message, '(3a)' )&
 415 &   'Too many input channels for atomic positions are defined.',ch10,&
 416 &   'Action: choose to define only one of these.'
 417    MSG_ERROR(message)
 418  end if
 419 
 420  if(txred==1 .or. txrandom /=0 )then
 421    call wrtout(std_out,' ingeo : takes atomic coordinates from input array xred ','COLL')
 422    call xred2xcart(natrd,rprimd,xcart_read,xred_read)
 423  else
 424    if(txangst==1)then
 425      call wrtout(std_out,' ingeo : takes atomic coordinates from input array xangst','COLL')
 426      xcart_read(:,:)=xangst_read(:,:)/Bohr_Ang
 427    else
 428      call wrtout(std_out,' ingeo : takes atomic coordinates from input array xcart','COLL')
 429    end if
 430    txred=1
 431  end if
 432 !At this stage, the cartesian coordinates are known, for the atoms whose coordinates where read.
 433 
 434 !Here, allocate the variable that will contain the completed
 435 !sets of xcart, after the use of the geometry builder or the symmetry builder
 436  ABI_ALLOCATE(xcart,(3,natom))
 437 
 438 !7) Eventually read the symmetries
 439 
 440 !Take care of the symmetries
 441  call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'nsym',tread,'INT')
 442 
 443  if(tread==1) nsym=intarr(1)
 444 
 445 !Check that nsym is not negative
 446  if (nsym<0) then
 447    write(message, '(a,i0,a,a,a,a)' )&
 448 &   'Input nsym must be positive or 0, but was ',nsym,ch10,&
 449 &   'This is not allowed.',ch10,&
 450 &   'Action: correct nsym in your input file.'
 451    MSG_ERROR(message)
 452  end if
 453 !Check that nsym is not bigger than msym
 454  if (nsym>msym) then
 455    write(message, '(a,i0,a,i0,a,a,a,a,a)' )&
 456 &   'Input nsym=',nsym,' exceeds msym=',msym,'.',ch10,&
 457 &   'This is not allowed.',ch10,&
 458 &   'Action: correct nsym in your input file.'
 459    MSG_ERROR(message)
 460  end if
 461 
 462 !Read symmorphi
 463  call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'symmorphi',tread,'INT')
 464  if(tread==1) symmorphi=intarr(1)
 465 
 466 !Now, read the symmetry operations
 467  if(nsym>0)then
 468    call intagm(dprarr,intarr,jdtset,marr,9*nsym,string(1:lenstr),'symrel',tread,'INT')
 469    if(nsym>1 .and. tread==0)then
 470      write(message,'(3a)')&
 471 &     'When nsym>1, symrel must be defined in the input file.',ch10,&
 472 &     'Action : either change nsym, or define symrel in your input file.'
 473      MSG_ERROR(message)
 474    end if
 475    if(tread==1) symrel(:,:,1:nsym)=reshape( intarr(1:9*nsym) , (/3,3,nsym/) )
 476 
 477 !  Take care of tnons
 478    tnons(:,1:nsym)=zero
 479    call intagm(dprarr,intarr,jdtset,marr,3*nsym,string(1:lenstr),'tnons',tread,'DPR')
 480    if(tread==1) tnons(:,1:nsym)=reshape( dprarr(1:3*nsym) , (/3,nsym/) )
 481 
 482    if(symmorphi==0)then
 483      do isym=1,nsym
 484        if(sum(tnons(:,isym)**2)>tol6)then
 485          write(message, '(5a,i0,a,3f8.4,3a)' )&
 486 &         'When symmorph/=1, the vectors of translation (tnons)',ch10,&
 487 &         'a symmetry operation must vanish.',ch10,&
 488 &         'However, for the symmetry operation number ',isym,', tnons =',tnons(:,isym),'.',ch10,&
 489 &         'Action : either change your list of allowed symmetry operations, or use the symmetry finder (nsym=0).'
 490          MSG_ERROR(message)
 491        end if
 492      end do
 493    end if
 494 
 495 !  Take care of symafm
 496    call intagm(dprarr,intarr,jdtset,marr,nsym,string(1:lenstr),'symafm',tread,'INT')
 497    if(tread==1) symafm(1:nsym)=intarr(1:nsym)
 498 
 499  end if
 500 
 501 
 502 !8) Checks whether the geometry builder must be used, and call it if needed.
 503 !Call the symmetry builder and analyzer if needed.
 504 
 505 !At this stage, nsym might still contain the default 0, msym contains the default dtset%maxnsym.
 506 !The cartesian coordinates of the atoms of the primitive set are contained in xcart_read.
 507 
 508  nobj=0
 509  call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'nobj',tread,'INT')
 510  if(tread==1) nobj=intarr(1)
 511 
 512 !If there are objects, chkprim will not be used immediately
 513 !But, if there are no objects, but a space group, it will be used directly.
 514  chkprim=1
 515  call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'chkprim',tread,'INT')
 516  if(tread==1) chkprim=intarr(1)
 517 
 518  if(nobj/=0)then
 519 
 520 !  Spinat is read for each atom, from 1 to natom
 521    call intagm(dprarr,intarr,jdtset,marr,3*natom,string(1:lenstr),'spinat',tread,'DPR')
 522    if(tread==1) then
 523      spinat(1:3,1:natom) = reshape( dprarr(1:3*natom) , (/3,natom/) )
 524    else if (nspden==4.or.(nspden==2.and.nsppol==1)) then
 525      write(message, '(5a)' )&
 526 &     'When nspden=4 or (nspden==2 and nsppol==1), the input variable spinat must be',ch10,&
 527 &     'defined in the input file, which is apparently not the case.',ch10,&
 528 &     'Action: define spinat or use nspden=1 in your input file.'
 529      MSG_ERROR(message)
 530    end if
 531 
 532 !  nucdipmom is read for each atom, from 1 to natom
 533    call intagm(dprarr,intarr,jdtset,marr,3*natom,string(1:lenstr),'nucdipmom',tread,'DPR')
 534    if(tread==1) then
 535      nucdipmom(1:3,1:natom) = reshape( dprarr(1:3*natom) , (/3,natom/) )
 536    end if
 537 
 538 !  Will use the geometry builder
 539    if(tnatrd/=1 .and. nobj/=0)then
 540      write(message, '(a,a,a,i0,a,a,a,a,a)' )&
 541 &     'The number of atoms to be read (natrd) must be initialized',ch10,&
 542 &     'in the input file, when nobj= ',nobj,'.',ch10,&
 543 &     'This is not the case.',ch10,&
 544 &     'Action: initialize natrd in your input file.'
 545      MSG_ERROR(message)
 546    end if
 547 
 548    if(jellslab/=0)then
 549      write(message, '(a,i0,3a)' )&
 550 &     'A jellium slab cannot be used when nobj= ',nobj,'.',ch10,&
 551 &     'Action: change one of the input variables jellslab or nobj in your input file.'
 552      MSG_ERROR(message)
 553    end if
 554 
 555    call ingeobld (iout,jdtset,lenstr,natrd,natom,nobj,string,typat,typat_read,xcart,xcart_read)
 556 
 557 !  Finalize the computation of coordinates : produce xred.
 558    call xcart2xred(natom,rprimd,xcart,xred)
 559 
 560  else ! nobj==0
 561 
 562 !  Spinat is read for each irreducible atom, from 1 to natrd
 563    call intagm(dprarr,intarr,jdtset,marr,3*natrd,string(1:lenstr),'spinat',tread,'DPR')
 564    if(tread==1)spinat(1:3,1:natrd) = reshape( dprarr(1:3*natrd) , (/3,natrd/) )
 565 
 566 !  nucdipmom is read for each irreducible atom, from 1 to natrd
 567    call intagm(dprarr,intarr,jdtset,marr,3*natrd,string(1:lenstr),'nucdipmom',tread,'DPR')
 568    if(tread==1)nucdipmom(1:3,1:natrd) = reshape( dprarr(1:3*natrd) , (/3,natrd/) )
 569 
 570 !  Get xred
 571    call xcart2xred(natrd,rprimd,xcart_read,xred)
 572 
 573    spgroup=0
 574    call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'spgroup',tread,'INT')
 575    if(tread==1) spgroup=intarr(1)
 576 
 577    if(spgroup/=0 .or. nsym/=0)then
 578 
 579      if(jellslab/=0 .and. nsym/=1 .and. spgroup/=1)then
 580        write(message, '(5a)' )&
 581 &       'For the time being, a jellium slab can only be used',ch10,&
 582 &       'either with the symmetry finder (nsym=0) or with the space group 1 (nsym=1)',ch10,&
 583 &       'Action: change one of the input variables jellslab or nsym or spgroup in your input file.'
 584        MSG_ERROR(message)
 585      end if
 586 
 587      if(nzchempot/=0 .and. nsym/=1 .and. spgroup/=1)then
 588        write(message, '(5a)' )&
 589 &       'For the time being, a spatially-varying chemical potential can only be used',ch10,&
 590 &       'either with the symmetry finder (nsym=0) or with the space group 1 (nsym=1)',ch10,&
 591 &       'Action: change one of the input variables nzchempot or nsym or spgroup in your input file.'
 592        MSG_ERROR(message)
 593      end if
 594 
 595      typat(1:natrd)=typat_read(1:natrd)
 596 
 597      if(spgroup/=0 .and. nsym/=0)then
 598        write(message, '(a,i0,a,a,i0,a,a,a,a,a,a,a,a)' )&
 599 &       'The spatial group number spgroup= ',spgroup,ch10,&
 600 &       'is specified, as well as the number of symmetries nsym= ',nsym,ch10,&
 601 &       'This is not allowed, as you can define the symmetries',ch10,&
 602 &       'either using spgroup OR using nsym, but not both.',ch10,&
 603 &       'Action: modify your input file',ch10,&
 604 &       '(either set spgroup to 0, or nsym to 0)'
 605        MSG_ERROR(message)
 606      end if
 607 
 608      brvltt=0
 609 
 610      if(spgroup/=0)then
 611 
 612 !      Will generate the spatial group using spgroup
 613 !      Assign default values
 614        spgaxor=1
 615        spgorig=1
 616        call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'brvltt',tread,'INT')
 617        if(tread==1) brvltt=intarr(1)
 618        call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'spgaxor',tread,'INT')
 619        if(tread==1) spgaxor=intarr(1)
 620        call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'spgorig',tread,'INT')
 621        if(tread==1) spgorig=intarr(1)
 622 
 623 !      Treat the case of magnetic groups
 624        call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'spgroupma',tspgroupma,'INT')
 625        if(tspgroupma==1) spgroupma=intarr(1)
 626        call intagm(dprarr,intarr,jdtset,marr,3,string(1:lenstr),'genafm',tgenafm,'DPR')
 627        if(tgenafm==1) genafm(1:3)=dprarr(1:3)
 628        if(tspgroupma/=0 .and. tgenafm/=0)then
 629          write(message, '(a,i0,a,a,3es9.2,a,a,a,a,a,a,a,a)' )&
 630 &         'The spatial group number spgroupma= ',spgroupma,ch10,&
 631 &         'is specified, as well as the antiferromagnetic generator genafm=',genafm(1:3),ch10,&
 632 &         'This is not allowed, as you can define the magnetic space group',ch10,&
 633 &         'either using spgroupma OR using genafm, but not both.',ch10,&
 634 &         'Action: modify your input file',ch10,&
 635 &         '(either define spgroupma or genafm)'
 636          MSG_ERROR(message)
 637        end if
 638 
 639 !      TODO : all the symmetry generation operations should be in one big routine
 640 
 641 !      If spgroupma is defined, check whether it is consistent
 642 !      with spgroup, determine the Shubnikov type,
 643 !      and, for type IV, find the corresponding genafm
 644        shubnikov=1
 645        if(tspgroupma==1)then
 646          call gensymshub(genafm,spgroup,spgroupma,shubnikov)
 647        else if(tgenafm==1)then
 648          shubnikov=4
 649        end if
 650 
 651 !      Generate the spatial group of symmetries in a conventional cell
 652 !      In case of Shubnikov space group type IV, only generate the
 653 !      Fedorov (non-magnetic) group. For Shubnikov type III space group,
 654 !      the magnetic part is generated here.
 655        bckbrvltt=brvltt
 656        if(brvltt==-1)brvltt=0
 657        call gensymspgr(brvltt,msym,nsym,shubnikov,spgaxor,spgorig,spgroup,spgroupma,symafm,symrel,tnons)
 658 
 659 !      For shubnikov type IV groups,
 660 !      double the space group, using the antiferromagnetic translation generator
 661        if(shubnikov==4)then
 662          call gensymshub4(genafm,msym,nsym,symafm,symrel,tnons)
 663        end if
 664 
 665 !      DEBUG
 666 !      write(std_out,*)' after gensymshub4, nsym =',nsym
 667 !      write(std_out,*)' Describe the different symmetry operations (index,symrel,tnons,symafm)'
 668 !      do ii=1,nsym
 669 !      write(std_out,'(i3,2x,9i3,3es12.2,i3)')ii,symrel(:,:,ii),tnons(:,ii),symafm(ii)
 670 !      end do
 671 !      ENDDEBUG
 672 
 673 !      If brvltt was -1 at input, one should now change the conventional cell
 674 !      to a primitive one, if brvltt/=1
 675        if(bckbrvltt==-1 .and. brvltt/=1)then
 676 !        Will work with rprim only
 677          rprim(:,:)=rprimd(:,:)
 678          rprimd_new(:,:)=rprimd(:,:)
 679          acell(:)=1.0_dp
 680          select case(brvltt)
 681          case(5)
 682            rprimd_new(:,2)=(rprim(:,2)+rprim(:,3))*0.5_dp
 683            rprimd_new(:,3)=(rprim(:,3)-rprim(:,2))*0.5_dp
 684          case(6)
 685            rprimd_new(:,1)=(rprim(:,1)+rprim(:,3))*0.5_dp
 686            rprimd_new(:,3)=(rprim(:,3)-rprim(:,1))*0.5_dp
 687          case(4)
 688            rprimd_new(:,1)=(rprim(:,1)+rprim(:,2))*0.5_dp
 689            rprimd_new(:,2)=(rprim(:,2)-rprim(:,1))*0.5_dp
 690          case(3)
 691            rprimd_new(:,1)=(rprim(:,2)+rprim(:,3))*0.5_dp
 692            rprimd_new(:,2)=(rprim(:,1)+rprim(:,3))*0.5_dp
 693            rprimd_new(:,3)=(rprim(:,1)+rprim(:,2))*0.5_dp
 694          case(2)
 695            rprimd_new(:,1)=(-rprim(:,1)+rprim(:,2)+rprim(:,3))*0.5_dp
 696            rprimd_new(:,2)=( rprim(:,1)-rprim(:,2)+rprim(:,3))*0.5_dp
 697            rprimd_new(:,3)=( rprim(:,1)+rprim(:,2)-rprim(:,3))*0.5_dp
 698          case(7)
 699            rprimd_new(:,1)=( rprim(:,1)*2.0_dp+rprim(:,2)+rprim(:,3))/3.0_dp
 700            rprimd_new(:,2)=(-rprim(:,1)      +rprim(:,2)+rprim(:,3))/3.0_dp
 701            rprimd_new(:,3)=(-rprim(:,1)-rprim(:,2)*2.0_dp+rprim(:,3))/3.0_dp
 702          end select
 703          call symrelrot(nsym,rprimd,rprimd_new,symrel,tolsym)
 704 !        Produce xred in the new system of coordinates
 705          call xred2xcart(natrd,rprimd,xcart,xred)
 706          call xcart2xred(natrd,rprimd_new,xcart,xred)
 707 !        Produce tnons in the new system of coordinates
 708          ABI_ALLOCATE(tnons_cart,(3,nsym))
 709          call xred2xcart(nsym,rprimd,tnons_cart,tnons)
 710          call xcart2xred(nsym,rprimd_new,tnons_cart,tnons)
 711          ABI_DEALLOCATE(tnons_cart)
 712 
 713 !        DEBUG
 714 !        write(std_out,*)' after change of coordinates, nsym =',nsym
 715 !        write(std_out,*)' Describe the different symmetry operations (index,symrel,tnons,symafm)'
 716 !        do ii=1,nsym
 717 !        write(std_out,'(i3,2x,9i3,3es12.2,i3)')ii,symrel(:,:,ii),tnons(:,ii),symafm(ii)
 718 !        end do
 719 !        ENDDEBUG
 720 
 721 !        Prune the symmetry operations : suppress those with
 722 !        exactly the same point and magnetic part
 723          nsym_now=1
 724          do isym=2,nsym
 725            irreducible=1
 726            do jsym=1,nsym_now
 727              if(sum(abs(symrel(:,:,isym)-symrel(:,:,jsym)))==0 .and. symafm(isym)==symafm(jsym)) then
 728                irreducible=0
 729                exit
 730              end if
 731            end do
 732            if(irreducible==1)then
 733              nsym_now=nsym_now+1
 734              symrel(:,:,nsym_now)=symrel(:,:,isym)
 735              tnons(:,nsym_now)=tnons(:,isym)
 736              symafm(nsym_now)=symafm(isym)
 737            end if
 738          end do
 739          nsym=nsym_now
 740 !        Translate tnons in the ]-0.5,0.5] interval
 741          tnons(:,1:nsym)=tnons(:,1:nsym)-nint(tnons(:,1:nsym)-1.0d-8)
 742 
 743 !        DEBUG
 744 !        write(std_out,*)' after reduction, nsym =',nsym
 745 !        write(std_out,*)' Describe the different symmetry operations (index,symrel,tnons,symafm)'
 746 !        do ii=1,nsym
 747 !        write(std_out,'(i3,2x,9i3,3es12.2,i3)')ii,symrel(:,:,ii),tnons(:,ii),symafm(ii)
 748 !        end do
 749 !        ENDDEBUG
 750 
 751 !        Now that symrel, tnons and xred are expressed in the primitive
 752 !        axis system, update the geometric quantities
 753          rprimd(:,:)=rprimd_new(:,:)
 754          rprim(:,:)=rprimd_new(:,:)
 755          call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
 756          call symlatt(bravais,msym,nptsym,ptsymrel,rprimd,tolsym)
 757        end if
 758 
 759      end if
 760 
 761      if(natom/=natrd)then
 762 !      Generate the full set of atoms from its knowledge in the irreducible part.
 763        call fillcell(natom,natrd,nsym,nucdipmom,spinat,symafm,symrel,tnons,tolsym,typat,xred)
 764      end if
 765 
 766 !    Check whether the symmetry operations are consistent with the lattice vectors
 767      iexit=0
 768 
 769      call chkorthsy(gprimd,iexit,nsym,rmet,rprimd,symrel)
 770 
 771    else ! spgroup==0 and nsym==0
 772 
 773 !    Here, spgroup==0 as well as nsym==0, so must generate
 774 !    the spatial group of symmetry. However, all the atom
 775 !    positions must be known, so the number
 776 !    of atoms to be read must equal the total number of atoms.
 777      if(natrd/=natom)then
 778 
 779        write(message, '(a,i0,a,a,i0,a,a,a,a,a,a,a,a,a)' )&
 780 &       'The number of atoms to be read (natrd)= ',natrd,ch10,&
 781 &       'differs from the total number of atoms (natom)= ',natom,ch10,&
 782 &       'while spgroup=0 and nsym=0.',&
 783 &       'This is not allowed, since the information needed to',ch10,&
 784 &       'generate the missing atomic coordinates is not available.',ch10,&
 785 &       'Action: modify your input file',ch10,&
 786 &       '(either natrd, or natom, or spgroup, or nsym)'
 787        MSG_ERROR(message)
 788      else
 789 
 790        typat(:)=typat_read(:)
 791 !      Find the symmetry operations : nsym, symafm, symrel and tnons.
 792 !      Use nptsym and ptsymrel, as determined by symlatt
 793        noncoll=0;if (nspden==4) noncoll=1
 794        use_inversion=1;if (dtset%usepaw == 1 .and. (nspden==4.or.pawspnorb>0)) use_inversion=0
 795 
 796 !      Get field in reduced coordinates (reduced e/d field)
 797 
 798        field_xred(:)=zero
 799        if (dtset%berryopt ==4) then
 800          do ii=1,3
 801            field_xred(ii)=dot_product(dtset%efield(:),gprimd(:,ii))
 802          end do
 803        else if (dtset%berryopt == 6 ) then
 804          do ii=1,3
 805            field_xred(ii)=dot_product(dtset%dfield(:),gprimd(:,ii))
 806            field_xred(ii)=field_xred(ii)+ dot_product(dtset%efield(:),gprimd(:,ii)) ! note: symmetry broken by D and E
 807          end do
 808        else if (dtset%berryopt == 14) then
 809          do ii=1,3
 810            field_xred(ii)=dot_product(dtset%red_efieldbar(:),gmet(:,ii))
 811          end do
 812        else if (dtset%berryopt == 16) then
 813          do ii=1,3
 814            field_xred(ii)=dtset%red_dfield(ii)+dtset%red_efield(ii)  ! symmetry broken by reduced d and e
 815          end do
 816        else if (dtset%berryopt == 17) then
 817          do ii=1,3
 818            field_xred(ii)=dot_product(dtset%red_efieldbar(:),gmet(:,ii))
 819            if(dtset%jfielddir(ii)==2) field_xred(ii)=dtset%red_dfield(ii)
 820          end do
 821        end if
 822 
 823 
 824        call symfind(dtset%berryopt,field_xred,gprimd,jellslab,msym,natom,noncoll,nptsym,nsym,&
 825 &       nzchempot,ptsymrel,spinat,symafm,symrel,tnons,tolsym,typat,use_inversion,xred,nucdipmom)
 826 
 827 !      If the tolerance on symmetries is bigger than 1.e-8, symmetrize the atomic positions
 828        if(tolsym>1.00001e-8)then
 829          ABI_ALLOCATE(indsym,(4,natom,nsym))
 830          ABI_ALLOCATE(symrec,(3,3,nsym))
 831          do isym=1,nsym
 832            call mati3inv(symrel(:,:,isym),symrec(:,:,isym))
 833          end do
 834          call symatm(indsym,natom,nsym,symrec,tnons,tolsym,typat,xred)
 835          call symmetrize_xred(indsym,natom,nsym,symrel,tnons,xred)
 836          ABI_DEALLOCATE(indsym)
 837          ABI_DEALLOCATE(symrec)
 838 
 839          write(message,'(a,es14.6,10a)')&
 840 &         'The tolerance on symmetries =',tolsym,ch10,&
 841 &         'is bigger than the usual tolerance, i.e. 1.0e-8 .',ch10,&
 842 &         'In order to avoid spurious effect, the atomic coordinates have been',ch10,&
 843 &         'symmetrized before storing them in the dataset internal variable.',ch10,&
 844 &         'So, do not be surprised by the fact that your input variables (xcart, xred, ...)',ch10,&
 845 &         'do not correspond to the ones echoed by ABINIT, the latter being used to do the calculations.'
 846          MSG_WARNING(message)
 847        end if
 848 
 849      end if
 850 
 851    end if
 852 
 853 !  Finalize the computation of coordinates : produce xcart
 854    call xred2xcart(natom,rprimd,xcart,xred)
 855 
 856  end if ! check of existence of an object
 857 
 858  ABI_DEALLOCATE(ptsymrel)
 859  ABI_DEALLOCATE(xangst_read)
 860  ABI_DEALLOCATE(xcart_read)
 861  ABI_DEALLOCATE(xcart)
 862  ABI_DEALLOCATE(xred_read)
 863  ABI_DEALLOCATE(typat_read)
 864 
 865 !Correct the default nsym value, if a symmetry group has not been generated.
 866  if(nsym==0)nsym=1
 867 
 868 !--------------------------------------------------------------------------------------------------------
 869 
 870  icoulomb=0
 871  call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'icoulomb',tread,'INT')
 872  if(tread==1)icoulomb=intarr(1)
 873 
 874 !calculate the center of the atomic system such as to put the
 875 !atoms in the middle of the simulation box for the free BC case.
 876  if (icoulomb == 1) then
 877    rcm(:)=zero
 878    do iatom=1,natom
 879      rcm(:)=rcm(:)+xred(:,iatom)
 880    end do
 881    rcm(:)=rcm(:)/real(natom,dp)-half
 882    do iatom=1,natom
 883      xred(:,iatom)=xred(:,iatom)-rcm(:)
 884    end do
 885 !  Also modify the tnons
 886    do isym=1,nsym
 887      tnons(:,isym)=matmul(symrel(:,:,isym),rcm(:))-rcm(:)+tnons(:,isym)
 888    end do
 889 
 890    message = ' Because icoulomb is 1, the average center of coordinates of the system has been translated to (0.5,0.5,0.5) '
 891    MSG_WARNING(message)
 892  end if
 893 
 894 !========================================================================================================
 895 !
 896 !At this stage, the cell parameters and atomic coordinates are known, as well as the symmetry operations
 897 !There has been a preliminary analysis of the holohedry (not definitive, though ...)
 898 !
 899 !========================================================================================================
 900 
 901 !Here, determine correctly the Bravais lattice and other space group or shubnikov group characteristics
 902  call symanal(bravais,chkprim,genafm,msym,nsym,ptgroupma,rprimd,spgroup,symafm,symrel,tnons,tolsym)
 903 
 904 !If the tolerance on symmetries is bigger than 1.e-8, symmetrize the rprimd. Keep xred fixed.
 905  if(tolsym>1.00001e-8)then
 906 !  Check whether the symmetry operations are consistent with the lattice vectors
 907    iexit=1
 908 
 909    call chkorthsy(gprimd,iexit,nsym,rmet,rprimd,symrel)
 910    if(iexit==-1)then
 911      call symmetrize_rprimd(bravais,nsym,rprimd,symrel,tolsym)
 912      call mkradim(acell,rprim,rprimd)
 913      write(message,'(a,es14.6,10a)')&
 914 &     'The tolerance on symmetries =',tolsym,ch10,&
 915 &     'is bigger than the usual tolerance, i.e. 1.0e-8 .',ch10,&
 916 &     'In order to avoid spurious effect, the primitive vectors have been',ch10,&
 917 &     'symmetrized before storing them in the dataset internal variable.',ch10,&
 918 &     'So, do not be surprised by the fact that your input variables (acell, rprim, xcart, xred, ...)',ch10,&
 919 &     'do not correspond to the ones echoed by ABINIT, the latter being used to do the calculations.'
 920      MSG_WARNING(message)
 921    end if
 922 
 923  end if
 924 
 925  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
 926  angdeg(1)=180.0_dp/pi * acos(rmet(2,3)/sqrt(rmet(2,2)*rmet(3,3)))
 927  angdeg(2)=180.0_dp/pi * acos(rmet(1,3)/sqrt(rmet(1,1)*rmet(3,3)))
 928  angdeg(3)=180.0_dp/pi * acos(rmet(1,2)/sqrt(rmet(1,1)*rmet(2,2)))
 929  write(std_out,'(a,3f14.8)') ' ingeo : angdeg(1:3)=',angdeg(1:3)
 930 
 931 !--------------------------------------------------------------------------------------
 932 
 933 !Finally prune the set of symmetry in case non-symmorphic operations must be excluded
 934  if(symmorphi==0)then
 935    jsym=0
 936    do isym=1,nsym
 937      if(sum(tnons(:,isym)**2)<tol6)then
 938        jsym=jsym+1
 939 !      This symmetry operation is non-symmorphic, and can be kept
 940        if(isym/=jsym)then
 941          symrel(:,:,jsym)=symrel(:,:,isym)
 942          tnons(:,jsym)=tnons(:,isym)
 943          symafm(jsym)=symafm(isym)
 944        end if
 945      end if
 946    end do
 947    nsym=jsym
 948  end if
 949 
 950 
 951 !DEBUG
 952 !call symmultsg(nsym,symafm,symrel,tnons)
 953 !ENDDEBUG
 954 
 955 !9) initialize the list of fixed atoms, and initial velocities -----------------
 956 !Note : these inputs do not influence the previous generation of
 957 !symmetry operations. This might be changed in the future
 958 
 959 !idir=0 is for iatfix , idir=1 is for iatfixx,
 960 !idir=2 is for iatfixy, idir=3 is for iatfixz
 961  iatfix(:,:)=0
 962 
 963  do idir=0,3
 964 
 965    if(idir==0)then
 966      call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'natfix',tread,'INT')
 967    else if(idir==1)then
 968      call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'natfixx',tread,'INT')
 969    else if(idir==2)then
 970      call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'natfixy',tread,'INT')
 971    else if(idir==3)then
 972      call intagm(dprarr,intarr,jdtset,marr,1,string(1:lenstr),'natfixz',tread,'INT')
 973    end if
 974 
 975 !  Use natfix also for natfixx,natfixy,natfixz
 976    natfix=0
 977    if(tread==1) natfix=intarr(1)
 978 
 979 
 980 !  Checks the validity of natfix
 981    if (natfix<0 .or. natfix>natom) then
 982      write(message, '(a,a,a,i0,a,i4,a,a,a)' )&
 983 &     'The input variables natfix, natfixx, natfixy and natfixz must be',ch10,&
 984 &     'between 0 and natom (= ',natom,'), while one of them is ',natfix,'.',ch10,&
 985 &     'Action: correct that occurence in your input file.'
 986      MSG_ERROR(message)
 987    end if
 988 
 989 !  Read iatfix
 990    if(idir==0)then
 991      call intagm(dprarr,intarr,jdtset,marr,natfix,string(1:lenstr),'iatfix',tread,'INT')
 992    else if(idir==1)then
 993      call intagm(dprarr,intarr,jdtset,marr,natfix,string(1:lenstr),'iatfixx',tread,'INT')
 994    else if(idir==2)then
 995      call intagm(dprarr,intarr,jdtset,marr,natfix,string(1:lenstr),'iatfixy',tread,'INT')
 996    else if(idir==3)then
 997      call intagm(dprarr,intarr,jdtset,marr,natfix,string(1:lenstr),'iatfixz',tread,'INT')
 998    end if
 999 
1000 !  If some iatfix was read, natfix must vanish
1001    if (natfix==0 .and. tread==1)then
1002      write(message, '(a,i1,5a)' )&
1003 &     'For direction ',idir,' the corresponding natfix is zero,',ch10,&
1004 &     'while iatfix specifies some atoms to be fixed.',ch10,&
1005 &     'Action: either specify a non-zero natfix(x,y,z) or suppress iatfix(x,y,z).'
1006      MSG_ERROR(message)
1007    end if
1008 
1009 !  If natfix is non-zero, iatfix must be defined
1010    if (natfix>0 .and. tread==0)then
1011      write(message, '(a,i1,3a,i0,3a)' )&
1012 &     'For direction ',idir,' no iatfix has been specified,',ch10,&
1013 &     'while natfix specifies that some atoms to be fixed, natfix= ',natfix,'.',ch10,&
1014 &     'Action: either set natfix(x,y,z) to zero or define iatfix(x,y,z).'
1015      MSG_ERROR(message)
1016    end if
1017 
1018    if(tread==1)then
1019      do ii=1,natfix
1020 !      Checks the validity of the input iatfix
1021        if (intarr(ii)<1 .or. intarr(ii)>natom) then
1022          write(message, '(a,a,a,i0,a,a,a)' )&
1023 &         'The input variables iatfix, iatfixx, iatfixy and iatfixz must be',ch10,&
1024 &         'between 1 and natom, while one of them is ',intarr(ii),'.',ch10,&
1025 &         'Action: correct that occurence in your input file.'
1026          MSG_ERROR(message)
1027        end if
1028 !      Finally set the value of the internal iatfix array
1029        do iatom=1,natom
1030          if(intarr(ii)==iatom)then
1031            if(idir==0)iatfix(1:3,iatom)=1
1032            if(idir/=0)iatfix(idir,iatom)=1
1033          end if
1034        end do
1035      end do
1036    end if
1037 
1038  end do
1039 
1040  vel(:,:)=zero
1041  call intagm(dprarr,intarr,jdtset,marr,3*natom,string(1:lenstr),'vel',tread,'DPR')
1042  if(tread==1)vel(:,:)=reshape( dprarr(1:3*natom) , (/3,natom/) )
1043  call ingeo_img(vel,iimage,jdtset,lenstr,nimage,3,natom,string,"vel",tread,'DPR')
1044 
1045  vel_cell(:,:)=zero
1046  call intagm(dprarr,intarr,jdtset,marr,3*3,string(1:lenstr),'vel_cell',tread,'DPR')
1047  if(tread==1)vel_cell(:,:)=reshape( dprarr(1:9) , (/3,3/) )
1048 
1049 !mixalch
1050  if(ntypalch>0)then
1051    call intagm(dprarr,intarr,jdtset,marr,npspalch*ntypalch,string(1:lenstr),'mixalch',tread,'DPR')
1052    if(tread==1) mixalch(1:npspalch,1:ntypalch)=&
1053 &   reshape(dprarr(1:npspalch*ntypalch),(/npspalch,ntypalch/))
1054    do itypat=1,ntypalch
1055      sumalch=sum(mixalch(1:npspalch,itypat))
1056      if(abs(sumalch-one)>tol10)then
1057        write(message, '(a,i0,2a,f8.2,4a)' )&
1058 &       'For the alchemical atom number ',itypat,ch10,&
1059 &       'the sum of the pseudopotential coefficients is',sumalch,ch10,&
1060 &       'while it should be one.',ch10,&
1061 &       'Action : check the content of the input variable mixalch.'
1062        MSG_ERROR(message)
1063      end if
1064    end do
1065    call ingeo_img(mixalch,iimage,jdtset,lenstr,nimage,npspalch,ntypalch,string,"mixalch",tread,'DPR')
1066  end if
1067 
1068 !amu (needs mixalch to be initialized ...)
1069 !Find the default mass
1070  ABI_ALLOCATE(mass_psp,(npsp))
1071  do ipsp=1,npsp
1072    call atomdata_from_znucl(atom,znucl(ipsp))
1073    amu_default = atom%amu
1074    mass_psp(ipsp)=amu_default
1075  end do
1076 !When the pseudo-atom is pure, simple copy
1077  ntyppure=ntypat-ntypalch
1078  if(ntyppure>0)then
1079    amu(1:ntyppure)=mass_psp(1:ntyppure)
1080  end if
1081 !When the pseudo-atom is alchemical, must make mixing
1082  if(ntypalch>0)then
1083    do itypat=ntyppure+1,ntypat
1084      amu(itypat)=zero
1085      do ipsp=ntyppure+1,npsp
1086        amu(itypat)=amu(itypat)+mixalch(ipsp-ntyppure,itypat-ntyppure)*mass_psp(ipsp)
1087      end do
1088    end do
1089  end if
1090  ABI_DEALLOCATE(mass_psp)
1091 
1092  call intagm(dprarr,intarr,jdtset,marr,ntypat,string(1:lenstr),'amu',tread,'DPR')
1093  if(tread==1)amu(:)=dprarr(1:ntypat)
1094  call ingeo_img(amu,iimage,jdtset,lenstr,nimage,ntypat,string,"amu",tread,'DPR')
1095 
1096 
1097  ABI_DEALLOCATE(intarr)
1098  ABI_DEALLOCATE(dprarr)
1099 
1100 end subroutine ingeo