LCOV - code coverage report
Current view: top level - src/41_geometry - m_crystal.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 85.0 % 662 563
Test Date: 2026-11-09 23:40:40 Functions: 80.0 % 35 28
Branches: 57.1 % 1680 959

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_crystal
       2                 :             : !! NAME
       3                 :             : !! m_crystal
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !! Module containing the definition of the crystal_t data type and methods used to handle it.
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2008-2026 ABINIT group (MG, YP, MJV, GA)
      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_crystal
      23                 :             : 
      24                 :             :  use, intrinsic :: iso_c_binding
      25                 :             :  use defs_basis
      26                 :             :  use m_errors
      27                 :             :  use m_abicore
      28                 :             :  use m_atomdata
      29                 :             :  use m_xmpi
      30                 :             :  use m_nctk
      31                 :             :  use netcdf
      32                 :             : 
      33                 :             :  use m_io_tools,       only : file_exists
      34                 :             :  use m_numeric_tools,  only : set2unit
      35                 :             :  use m_hide_lapack,    only : matrginv
      36                 :             :  use m_fstrings,       only : int2char10, sjoin, yesno, itoa, strcat
      37                 :             :  use m_matrix,         only : mati3inv
      38                 :             :  use m_symtk,          only : sg_multable, symatm, print_symmetries
      39                 :             :  use m_spgdata,        only : spgdata
      40                 :             :  use m_geometry,       only : metric, xred2xcart, xcart2xred, remove_inversion, getspinrot, symredcart, normv
      41                 :             :  use m_io_tools,       only : open_file
      42                 :             :  use m_pptools,        only : write_xsf
      43                 :             : 
      44                 :             :  implicit none
      45                 :             : 
      46                 :             :  private
      47                 :             : !!***
      48                 :             : 
      49                 :             : !----------------------------------------------------------------------
      50                 :             : 
      51                 :             : !!****t* m_crystal/crystal_t
      52                 :             : !! NAME
      53                 :             : !! crystal_t
      54                 :             : !!
      55                 :             : !! FUNCTION
      56                 :             : !! Structure defining the unit cell (geometry, atomic positions and symmetry operations in real and reciprocal space)
      57                 :             : !!
      58                 :             : !! SOURCE
      59                 :             : 
      60                 :             :  type,public :: crystal_t
      61                 :             : 
      62                 :             : !scalars
      63                 :             :   !integer :: point_group                    ! Point group
      64                 :             :   !integer :: bravais,crystsys               ! Bravais lattice, Crystal system
      65                 :             :   !integer :: nptsym                         ! No of point symmetries of the Bravais lattice
      66                 :             :   !integer :: bravais(11)                    ! bravais(1)=iholohedry, bravais(2)=center
      67                 :             :                                              ! bravais(3:11)=coordinates of rprim in the axes of the conventional
      68                 :             :                                              ! bravais lattice (*2 if center/=0)
      69                 :             :   !integer,pointer ptsymrel(:,:,:)
      70                 :             :   !ptsymrel(3,3,nptsym)
      71                 :             :   ! nptsym point-symmetry operations of the Bravais lattice in real space in terms of primitive translations.
      72                 :             : 
      73                 :             :   integer :: natom = -1
      74                 :             :   ! Number of atoms
      75                 :             : 
      76                 :             :   integer :: nsym = -1
      77                 :             :   ! Number of symmetry operations
      78                 :             : 
      79                 :             :   integer :: ntypat = -1
      80                 :             :   ! Number of type of atoms
      81                 :             : 
      82                 :             :   integer :: nirredat = -1
      83                 :             :   ! Number of irreducibel atoms
      84                 :             : 
      85                 :             :   integer :: npsp = -1
      86                 :             :   ! No. of pseudopotentials
      87                 :             : 
      88                 :             :   integer :: space_group = -1
      89                 :             :   ! Space group
      90                 :             : 
      91                 :             :   integer :: timrev = -1
      92                 :             :   ! TODO BE CAREFUL here, as the convention used in abinit is different.
      93                 :             :   ! 1 => do not use time-reversal symmetry.
      94                 :             :   ! 2 => take advantage of time-reversal symmetry.
      95                 :             : 
      96                 :             :   real(dp) :: ucvol = zero
      97                 :             :   ! Real space unit cell volume.
      98                 :             : 
      99                 :             :   logical :: use_antiferro
     100                 :             :   ! .TRUE. if AFM symmetries are present and used.
     101                 :             : 
     102                 :             : !arrays
     103                 :             :   real(dp) :: angdeg(3) = zero
     104                 :             :   ! Angles among rprim (degree).
     105                 :             : 
     106                 :             :   real(dp) :: gmet(3,3) = zero
     107                 :             :   ! Reciprocal space metric ($\textrm{bohr}^{-2}$).
     108                 :             : 
     109                 :             :   real(dp) :: gprimd(3,3) = zero
     110                 :             :   ! Dimensional primitive translations for reciprocal space ($\textrm{bohr}^{-1}$)
     111                 :             : 
     112                 :             :   real(dp) :: rmet(3,3) = zero
     113                 :             :   ! Metric in real space.
     114                 :             : 
     115                 :             :   real(dp) :: rprimd(3,3) = zero
     116                 :             :   ! Direct lattice vectors, Bohr units.
     117                 :             : 
     118                 :             :   integer,allocatable :: indsym(:,:,:)
     119                 :             :   ! indsym(4,nsym,natom)
     120                 :             :   ! indirect indexing array for atoms, see symatm.F90.
     121                 :             :   ! $ R^{-1} (xred(:,iat)-\tau) = xred(:,iat_sym) + R_0 $
     122                 :             :   ! * indsym(4,  isym,iat) gives iat_sym in the original unit cell.
     123                 :             :   ! * indsym(1:3,isym,iat) gives the lattice vector $R_0$.
     124                 :             : 
     125                 :             :   integer,allocatable :: symafm(:)
     126                 :             :   ! symafm(nsym)
     127                 :             :   ! (Anti)Ferromagnetic symmetries. +1/-1
     128                 :             : 
     129                 :             :   integer,allocatable :: symrec(:,:,:)
     130                 :             :   ! symrec(3,3,nsym)
     131                 :             :   ! Symmetry operation in reciprocal space (reduced coordinates)
     132                 :             : 
     133                 :             :   integer,allocatable :: symrel(:,:,:)
     134                 :             :   ! symrel(3,3,nsym)
     135                 :             :   ! Symmetry operations in direct space (reduced coordinates).
     136                 :             : 
     137                 :             :   real(dp),allocatable :: symrel_cart(:,:,:)
     138                 :             :   ! symrel_cart(3,3,nsym)
     139                 :             :   ! Symmetry operations in cartesian coordinates (same order as symrel)
     140                 :             : 
     141                 :             :   integer,allocatable :: atindx(:)
     142                 :             :   integer,allocatable :: atindx1(:)
     143                 :             :   ! atindx(natom), atindx1(natom)
     144                 :             :   ! Index tables for atoms useful to treat atoms type after type.
     145                 :             : 
     146                 :             :   integer,allocatable :: typat(:)
     147                 :             :   integer,allocatable :: nattyp(:)
     148                 :             :   ! typat(natom), nattyp(ntypat)
     149                 :             :   ! Type of each natom and number of atoms of each type.
     150                 :             : 
     151                 :             :   integer,allocatable :: irredatindx(:)
     152                 :             :   ! Index of irreducible atoms
     153                 :             : 
     154                 :             :   real(dp),allocatable :: tnons(:,:)
     155                 :             :   ! tnons(3,nsym)
     156                 :             :   ! Fractional translations (reduced coordinates)
     157                 :             : 
     158                 :             :   real(dp),allocatable :: xcart(:,:)
     159                 :             :   ! xcart(3,natom)
     160                 :             :   ! Cartesian coordinates.
     161                 :             : 
     162                 :             :   real(dp),allocatable :: xred(:,:)
     163                 :             :   ! xred(3,natom)
     164                 :             :   ! Reduced coordinates.
     165                 :             : 
     166                 :             :   real(dp),allocatable :: spinrot(:,:)
     167                 :             :   ! spinrot(4,nsym)
     168                 :             :   ! spinor rotation matrices.
     169                 :             : 
     170                 :             :   real(dp),allocatable :: amu(:)
     171                 :             :   !  amu(ntypat)
     172                 :             :   !  mass of the atoms (atomic mass unit)
     173                 :             : 
     174                 :             :   real(dp),allocatable :: zion(:)
     175                 :             :   ! zion(ntypat)
     176                 :             :   ! Charge of the pseudo-ion
     177                 :             :   ! (No of valence electrons needed to screen exactly the pseudopotential).
     178                 :             : 
     179                 :             :   !real(dp),allocatable :: znucltypat(:)
     180                 :             :    ! znucltypat(ntypat)
     181                 :             :    ! The atomic number of each type of atom (might be alchemy wrt psps)
     182                 :             : 
     183                 :             :   real(dp),allocatable :: znucl(:)
     184                 :             :   ! znucl(npsp)
     185                 :             :   ! Nuclear charge for each type of pseudopotential
     186                 :             : 
     187                 :             :   character(len=132),allocatable :: title(:)
     188                 :             :    ! title(ntypat)
     189                 :             :    ! The content of first line read from the psp file
     190                 :             : 
     191                 :             :  contains
     192                 :             : 
     193                 :             :    procedure :: init => crystal_init
     194                 :             :     ! Main Creation method.
     195                 :             : 
     196                 :             :    procedure :: ncwrite => crystal_ncwrite
     197                 :             :    ! Write the object in netcdf format
     198                 :             : 
     199                 :             :    procedure :: ncwrite_path => crystal_ncwrite_path
     200                 :             :    ! Dump the object to netcdf file.
     201                 :             : 
     202                 :             :    procedure :: ncread => crystal_ncread
     203                 :             :    ! Read the object from a netcdf file.
     204                 :             : 
     205                 :             :    procedure :: isymmorphic
     206                 :             :    ! True if space group is symmorphic.
     207                 :             : 
     208                 :             :    procedure :: idx_spatial_inversion
     209                 :             :    ! Return the index of the spatial inversion, 0 if not present.
     210                 :             : 
     211                 :             :    procedure :: isalchemical
     212                 :             :    ! True if we are using alchemical pseudopotentials.
     213                 :             : 
     214                 :             :    procedure :: malloc => crystal_malloc
     215                 :             :    ! Allocate memory.
     216                 :             : 
     217                 :             :    procedure :: free => crystal_free
     218                 :             :    ! Free memory.
     219                 :             : 
     220                 :             :    procedure :: copy => crystal_copy
     221                 :             :    ! Copy object.
     222                 :             : 
     223                 :             :    procedure :: bcast => crystal_bcast
     224                 :             :    ! Master broadcasts data and others allocate their arrays.
     225                 :             : 
     226                 :             :    procedure :: new_without_symmetries => crystal_without_symmetries
     227                 :             :    ! Return new object without symmetries (actually nsym = 1 and identity operation)
     228                 :             : 
     229                 :             :    procedure :: new_trinv_only => crystal_trinv_only
     230                 :             :    ! Return new object without only identity, inversion & TR symmetries (if present)
     231                 :             : 
     232                 :             :    procedure :: get_point_group => crystal_point_group
     233                 :             :    ! Return the symmetries of the point group of the crystal.
     234                 :             : 
     235                 :             :    procedure :: index_atoms => crystal_index_atoms
     236                 :             :    ! Generate index table of atoms.
     237                 :             : 
     238                 :             :    procedure :: compute_sym => crystal_compute_sym
     239                 :             :    ! Compute all symetries and construct tables.
     240                 :             : 
     241                 :             :    procedure :: compute_geometry => crystal_compute_geometry
     242                 :             :    ! Compute the different metrics and the angle between primitive vectors.
     243                 :             : 
     244                 :             :    procedure :: symbol_type
     245                 :             :    ! Return the atomic symbol from the itypat index.
     246                 :             : 
     247                 :             :    procedure :: symbol_iatom
     248                 :             :    ! Return the atomic symbol from the iatom index.
     249                 :             : 
     250                 :             :    procedure :: adata_type
     251                 :             :    ! Return atomic data from the itypat index.
     252                 :             : 
     253                 :             :    procedure :: compare => crystal_compare
     254                 :             :    ! Compare two crystalline structures, write warning messages if they differ, return exit status
     255                 :             : 
     256                 :             :    procedure :: print => crystal_print
     257                 :             :    ! Print dimensions and basic info stored in the object
     258                 :             : 
     259                 :             :    procedure :: print_abivars => crystal_print_abivars
     260                 :             :    ! Print unit cell info in Abinit/abivars format
     261                 :             : 
     262                 :             :    procedure :: symmetrize_cart_vec3 => crystal_symmetrize_cart_vec3
     263                 :             :    ! Symmetrize a 3d cartesian vector
     264                 :             : 
     265                 :             :    procedure :: symmetrize_cart_tens33 => crystal_symmetrize_cart_tens33
     266                 :             :    ! Symmetrize a cartesian 3x3 tensor
     267                 :             : 
     268                 :             :    procedure :: get_redcart_qdirs => get_redcart_qdirs
     269                 :             :    ! Return predefined list of 6 q-versors in reciprocal space reduced coordinates.
     270                 :             : 
     271                 :             :    procedure :: write_xsf_data => crystal_write_xsf_data
     272                 :             :    !  Write array in real space in XSF format
     273                 :             : 
     274                 :             :    procedure :: write_poscar => crystal_write_poscar
     275                 :             :    !  Write the structure in the VASP POSCAR format to a unit.
     276                 :             : 
     277                 :             :  end type crystal_t
     278                 :             : 
     279                 :             :  public :: symbols_crystal         ! Return an array with the atomic symbol: ["Sr","Ru","O1","O2","O3"]
     280                 :             :  public :: prt_cif                 ! Print CIF file.
     281                 :             :  public :: prtposcar               ! output VASP style POSCAR and FORCES files.
     282                 :             : !!***
     283                 :             : 
     284                 :             : CONTAINS  !====================================================================================================
     285                 :             : !!***
     286                 :             : 
     287                 :             : !!****f* m_crystal/crystal_init
     288                 :             : !! NAME
     289                 :             : !!  crystal_init
     290                 :             : !!
     291                 :             : !! FUNCTION
     292                 :             : !!  Initialize a crystal_t data type.
     293                 :             : !!  Ideally the routine should work in two different modes:
     294                 :             : !!  Either the symmetries are directly supplied or the space group
     295                 :             : !!  is determined starting from the definition of the unit cell.
     296                 :             : !!  Only the first method is implemented, the second one should be
     297                 :             : !!  a wrapper for the symmetry finder library. To implement the
     298                 :             : !!  second case I have to add additional entries in the object
     299                 :             : !!  and I have also to pass an object describing the (optional) geometry builder.
     300                 :             : !!
     301                 :             : !! INPUTS
     302                 :             : !!  natom=number of atom
     303                 :             : !!  ntypat=number of type of atoms
     304                 :             : !!  nsym=number of symmetry operations
     305                 :             : !!  rprimd(3,3)=dimensional lattive vector (real space)
     306                 :             : !!  typat(natom)=type of each atom
     307                 :             : !!  xred(3,natom)=reduced coordinates of each atom
     308                 :             : !!  symrel(3,3,nsym) [optional]=symmetry operations in real space
     309                 :             : !!  space_group=Space group (0 if not available)
     310                 :             : !!  tnons(3,nsym) [optional]=fractional Translations
     311                 :             : !!  symafm(nsym) [optional]=  ferromagnetic symmetries
     312                 :             : !!  remove_inv [optional]= if .TRUE. the inversion is removed from the set of symmetries
     313                 :             : !!  timrev ==2 => take advantage of time-reversal symmetry
     314                 :             : !!         ==1 ==> do not use time-reversal symmetry
     315                 :             : !!
     316                 :             : !! OUTPUT
     317                 :             : !!  Cryst<crystal_t>= the object completely initialized.
     318                 :             : !!
     319                 :             : !! TODO
     320                 :             : !!  Add additional entries in the class:
     321                 :             : !!  1) Info on space and point group (generators?).
     322                 :             : !!  2) alchemy
     323                 :             : !!  3) masses and nuclear (pseudo&AE) charge
     324                 :             : !!  4) forces stresses, velocities.
     325                 :             : !!  5) constraints for the relaxation
     326                 :             : !!  6) Likely I will need also info on the electric field and berryopt
     327                 :             : !!
     328                 :             : !! SOURCE
     329                 :             : 
     330                 :       32118 : subroutine crystal_init(cryst,amu,space_group,natom,npsp,ntypat,nsym,rprimd,typat,xred,&
     331                 :       32118 :                         zion,znucl,timrev,use_antiferro,remove_inv,title,&
     332                 :       96354 :                         symrel,tnons,symafm) ! Optional
     333                 :             : 
     334                 :             : !Arguments ------------------------------------
     335                 :             : !scalars
     336                 :             :  class(crystal_t),intent(inout) :: Cryst
     337                 :             :  integer,intent(in) :: natom,ntypat,nsym,timrev,space_group,npsp
     338                 :             :  logical,intent(in) :: remove_inv,use_antiferro
     339                 :             : !arrays
     340                 :             :  integer,intent(in) :: typat(natom)
     341                 :             :  integer,optional,intent(in) :: symrel(3,3,nsym),symafm(nsym)
     342                 :             :  real(dp),intent(in) :: amu(ntypat),xred(3,natom),rprimd(3,3),zion(ntypat),znucl(npsp)
     343                 :             :  real(dp),optional,intent(in) :: tnons(3,nsym)
     344                 :             :  character(len=*),intent(in) :: title(ntypat)
     345                 :             : 
     346                 :             : !Local variables-------------------------------
     347                 :             : !scalars
     348                 :             :  integer :: pinv,nsym_noI
     349                 :             :  !character(len=500) :: msg
     350                 :             : !arrays
     351                 :       32118 :  integer,pointer :: symrel_noI(:,:,:)
     352                 :       32118 :  real(dp),pointer :: tnons_noI(:,:)
     353                 :             : ! *************************************************************************
     354                 :             : 
     355                 :             :  !@crystal_t
     356                 :       32118 :  Cryst%natom = natom
     357                 :       32118 :  Cryst%ntypat = ntypat
     358                 :       32118 :  Cryst%npsp = npsp
     359                 :       32118 :  Cryst%space_group = space_group
     360                 :       32118 :  Cryst%nsym = nsym
     361                 :       32118 :  Cryst%timrev = timrev
     362                 :       32118 :  Cryst%use_antiferro = use_antiferro
     363   [ +  +  +  + ]:      417534 :  Cryst%rprimd = rprimd
     364                 :             : 
     365                 :       32118 :  call Cryst%free()
     366                 :       32118 :  call Cryst%malloc()
     367                 :             : 
     368   [ +  -  -  +  :      108262 :  Cryst%amu   = amu
             -  -  +  + ]
     369   [ +  -  -  +  :      146522 :  Cryst%typat = typat
             -  -  +  + ]
     370   [ +  -  +  -  :      393380 :  Cryst%xred  = xred
          -  +  -  -  +  
                +  +  + ]
     371   [ +  -  -  +  :      108262 :  Cryst%zion  = zion
             -  -  +  + ]
     372   [ +  -  -  +  :      108352 :  Cryst%znucl = znucl
             -  -  +  + ]
     373   [ +  -  -  +  :      108262 :  Cryst%title = title
          -  -  +  +  +  
                      + ]
     374                 :             : 
     375                 :       32118 :  call Cryst%compute_geometry()
     376                 :             : 
     377                 :       32118 :  call Cryst%index_atoms()
     378                 :             : 
     379                 :             :  ! TODO: Make this more elegant
     380   [ +  -  +  - ]:       32118 :  if (PRESENT(symrel).and.PRESENT(tnons).and.PRESENT(symafm)) then
     381         [ +  + ]:       32118 :    if (.not.remove_inv) then
     382                 :             :      ! Just a copy
     383   [ +  -  +  -  :     9750961 :      Cryst%symrel=symrel
          +  -  -  +  -  
          -  +  +  +  +  
                   +  + ]
     384   [ +  -  +  -  :     3044764 :      Cryst%tnons=tnons
          -  +  -  -  +  
                +  +  + ]
     385   [ +  -  -  +  :      809365 :      Cryst%symafm=symafm
             -  -  +  + ]
     386                 :             :    else
     387                 :             :      ! Remove inversion, just to be compatible with old GW implementation
     388                 :             :      ! TODO should be removed!
     389                 :           2 :      call remove_inversion(nsym,symrel,tnons,nsym_noI,symrel_noI,tnons_noI,pinv)
     390                 :           2 :      Cryst%nsym=nsym_noI
     391         [ +  - ]:           2 :      ABI_SFREE(Cryst%symrel)
     392         [ +  - ]:           2 :      ABI_SFREE(Cryst%symrec)
     393         [ +  - ]:           2 :      ABI_SFREE(Cryst%tnons)
     394         [ +  - ]:           2 :      ABI_SFREE(Cryst%symafm)
     395   [ -  +  +  -  :           6 :      ABI_MALLOC(Cryst%symrel,(3,3,nsym_noI))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     396   [ -  +  +  -  :           4 :      ABI_MALLOC(Cryst%symrec,(3,3,nsym_noI))
          -  +  -  +  -  
                      + ]
     397   [ -  +  +  -  :           6 :      ABI_MALLOC(Cryst%tnons,(3,nsym_noI))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     398   [ -  +  +  -  :           6 :      ABI_MALLOC(Cryst%symafm,(nsym_noI))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     399   [ +  -  +  -  :         628 :      Cryst%symrel=symrel_noI
          +  -  -  +  -  
          -  -  -  -  -  
          -  -  +  +  +  
                +  +  + ]
     400   [ +  -  +  -  :         196 :      Cryst%tnons=tnons_noI
          -  +  -  -  -  
          -  -  -  +  +  
                   +  + ]
     401   [ +  +  +  -  :          50 :      if (ANY(symafm==-1)) then
                   -  + ]
     402                 :           0 :        ABI_BUG('Solve the problem with inversion before adding ferromagnetic symmetries')
     403                 :             :      end if
     404         [ +  + ]:          50 :      Cryst%symafm=1
     405         [ -  + ]:           2 :      ABI_FREE(symrel_noI)
     406         [ -  + ]:           4 :      ABI_FREE(tnons_noI)
     407                 :             :    end if
     408                 :             : 
     409                 :             :  else
     410                 :             :    ! Find symmetries symrec,symrel,tnons,symafm
     411                 :             :    ! TODO This should be a wrapper around the abinit library whose usage is not so straightforward
     412                 :           0 :    ABI_BUG('NotImplememented: symrel, symrec and tnons should be specied')
     413                 :             :  end if
     414                 :             : 
     415                 :             :  ! Compute all symetries and construct tables.
     416                 :       32118 :  call Cryst%compute_sym()
     417                 :             : 
     418   [ +  -  +  -  :      128472 : end subroutine crystal_init
                   +  - ]
     419                 :             : !!***
     420                 :             : 
     421                 :             : !----------------------------------------------------------------------
     422                 :             : 
     423                 :             : !!****f* m_crystal/crystal_without_symmetries
     424                 :             : !! NAME
     425                 :             : !!  crystal_without_symmetries
     426                 :             : !!
     427                 :             : !! FUNCTION
     428                 :             : !!  Return new crystal_t object without symmetries (actually nsym = 1 and identity operation)
     429                 :             : !!
     430                 :             : !! INPUTS
     431                 :             : !!
     432                 :             : !! OUTPUT
     433                 :             : !!
     434                 :             : !! SOURCE
     435                 :             : 
     436                 :           0 : type(crystal_t) function crystal_without_symmetries(self) result(new)
     437                 :             : 
     438                 :             : !Arguments ------------------------------------
     439                 :             :  class(crystal_t), intent(in) :: self
     440                 :             : 
     441                 :             : !Local variables-------------------------------
     442                 :             :  integer,parameter :: timrev1 = 1, new_symafm(1) = 1
     443                 :             :  real(dp),parameter :: new_tnons(3,1) = zero
     444                 :             : ! *************************************************************************
     445                 :             : 
     446                 :             :  call new%init(self%amu, 1, self%natom, self%npsp, self%ntypat, 1, self%rprimd, self%typat, &
     447                 :             :   self%xred, self%zion, self%znucl, timrev1, .False., .False., self%title, &
     448                 :           0 :   symrel=identity_3d, tnons=new_tnons, symafm=new_symafm)
     449                 :             : 
     450   [ #  #  #  #  :           0 : end function crystal_without_symmetries
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     451                 :             : !!***
     452                 :             : 
     453                 :             : !----------------------------------------------------------------------
     454                 :             : 
     455                 :             : !!****f* m_crystal/crystal_trinv_only
     456                 :             : !! NAME
     457                 :             : !!  crystal_trinv_only
     458                 :             : !!
     459                 :             : !! FUNCTION
     460                 :             : ! ! Return new crystal_t without only identity, inversion and TR symmetries (if present)
     461                 :             : !!
     462                 :             : !! SOURCE
     463                 :             : 
     464                 :           0 : type(crystal_t) function crystal_trinv_only(self) result(new)
     465                 :             : 
     466                 :             : !Arguments ------------------------------------
     467                 :             :  class(crystal_t), intent(in) :: self
     468                 :             : 
     469                 :             : !Local variables-------------------------------
     470                 :             :  integer,parameter :: timrev2 = 2
     471                 :             :  real(dp),parameter :: new_tnons(3,2) = zero
     472                 :             :  integer :: inv_idx, new_symafm(2), new_symrel(3,3,2)
     473                 :             : ! *************************************************************************
     474                 :             : 
     475                 :           0 :  inv_idx = self%idx_spatial_inversion()
     476         [ #  # ]:           0 :  if (inv_idx == 0) then
     477                 :             :    ! no spatial inversion
     478                 :           0 :    new = self%new_without_symmetries(); new%timrev = timrev2
     479                 :             :  else
     480                 :             :    ! spatial inversion is present
     481   [ #  #  #  #  :           0 :    new_symrel(:,:,1) = identity_3d; new_symrel(:,:,2) = self%symrel(:,:,inv_idx)
             #  #  #  # ]
     482                 :           0 :    new_symafm(1) = 1; new_symafm(2) = self%symafm(inv_idx)
     483                 :             : 
     484                 :             :    call new%init(self%amu, 2, self%natom, self%npsp, self%ntypat, 2, self%rprimd, self%typat, &
     485                 :             :      self%xred, self%zion, self%znucl, timrev2, .False., .False., self%title, &
     486                 :           0 :      symrel=new_symrel, tnons=new_tnons, symafm=new_symafm)
     487                 :             :  endif
     488                 :             : 
     489   [ #  #  #  #  :           0 : end function crystal_trinv_only
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     490                 :             : !!***
     491                 :             : 
     492                 :             : !----------------------------------------------------------------------
     493                 :             : 
     494                 :             : !!****f* m_crystal/crystal_index_atoms
     495                 :             : !! NAME
     496                 :             : !!  crystal_index_atoms
     497                 :             : !!
     498                 :             : !! FUNCTION
     499                 :             : !!  Generate index table of atoms, in order for them to be used type after type.
     500                 :             : !!
     501                 :             : !! SOURCE
     502                 :             : 
     503                 :       32519 : subroutine crystal_index_atoms(Cryst)
     504                 :             : 
     505                 :             : !Arguments ------------------------------------
     506                 :             :  class(crystal_t),intent(inout) :: Cryst
     507                 :             : 
     508                 :             : !Local variables-------------------------------
     509                 :             :  integer :: iat,indx,itypat
     510                 :             : ! *********************************************************************
     511                 :             : 
     512                 :       32519 :  indx=1
     513         [ +  + ]:       77092 :  do itypat=1,Cryst%ntypat
     514                 :       44573 :    Cryst%nattyp(itypat)=0
     515         [ +  + ]:      198853 :    do iat=1,Cryst%natom
     516         [ +  + ]:      166334 :      if (Cryst%typat(iat)==itypat) then
     517                 :       83072 :        Cryst%atindx (iat )=indx
     518                 :       83072 :        Cryst%atindx1(indx)=iat
     519                 :       83072 :        indx=indx+1
     520                 :       83072 :        Cryst%nattyp(itypat)=Cryst%nattyp(itypat)+1
     521                 :             :      end if
     522                 :             :    end do
     523                 :             :  end do
     524                 :             : 
     525                 :       32519 : end subroutine crystal_index_atoms
     526                 :             : !!***
     527                 :             : 
     528                 :             : !----------------------------------------------------------------------
     529                 :             : 
     530                 :             : !!****f* m_crystal/crystal_compute_sym
     531                 :             : !! NAME
     532                 :             : !!  crystal_compute_sym
     533                 :             : !!
     534                 :             : !! FUNCTION
     535                 :             : !!  Get symmetries in cartesian coordinates, construct rotation tables
     536                 :             : !!  for atoms with and without spinor, and construct list of reducible atoms.
     537                 :             : !!
     538                 :             : !! SOURCE
     539                 :             : 
     540                 :       32519 : subroutine crystal_compute_sym(Cryst)
     541                 :             : 
     542                 :             : !Arguments ------------------------------------
     543                 :             :  class(crystal_t),intent(inout) :: Cryst
     544                 :             : 
     545                 :             : !Local variables-------------------------------
     546                 :             : !scalars
     547                 :             :  integer :: iat,indx,isym
     548                 :             :  real(dp) :: tolsym8
     549                 :       32519 :  logical, allocatable :: irredat_tmp(:)
     550                 :             : !arrays
     551                 :             :  integer :: symrec(3,3)
     552                 :             : ! *********************************************************************
     553                 :             : 
     554                 :             :  ! Get symmetries in reciprocal space
     555         [ +  + ]:      787559 :  do isym=1,Cryst%nsym
     556                 :      755040 :    call mati3inv(Cryst%symrel(:,:,isym),symrec)
     557   [ +  +  +  + ]:     9848039 :    Cryst%symrec(:,:,isym)=symrec
     558                 :             :  end do
     559                 :             : 
     560                 :             :  ! Get symmetries in cartesian coordinates
     561         [ +  + ]:      787559 :  do isym =1,Cryst%nsym
     562                 :      755040 :    call symredcart(Cryst%rprimd, Cryst%gprimd, Cryst%symrel_cart(:,:,isym), Cryst%symrel(:,:,isym))
     563                 :             :    ! purify operations in cartesian coordinates.
     564   [ +  +  +  +  :     9848039 :    where (abs(Cryst%symrel_cart(:,:,isym)) < tol14)
                   +  + ]
     565                 :             :      Cryst%symrel_cart(:,:,isym) = zero
     566                 :             :    end where
     567                 :             :  end do
     568                 :             : 
     569                 :             :  ! === Obtain a list of rotated atoms ===
     570                 :             :  ! $ R^{-1} (xred(:,iat)-\tau) = xred(:,iat_sym) + R_0 $
     571                 :             :  ! * indsym(4,  isym,iat) gives iat_sym in the original unit cell.
     572                 :             :  ! * indsym(1:3,isym,iat) gives the lattice vector $R_0$.
     573                 :             :  !
     574                 :       32519 :  tolsym8=tol8
     575                 :       32519 :  call symatm(Cryst%indsym, Cryst%natom, Cryst%nsym, Cryst%symrec, Cryst%tnons, tolsym8, Cryst%typat, Cryst%xred)
     576                 :             : 
     577                 :             :  ! Rotations in spinor space
     578         [ +  + ]:      787559 :  do isym=1,Cryst%nsym
     579                 :      787559 :    call getspinrot(Cryst%rprimd, Cryst%spinrot(:,isym), Cryst%symrel(:,:,isym))
     580                 :             :  end do
     581                 :             : 
     582                 :             :  ! Find list of irreducible atoms by using the indsym
     583   [ -  +  +  -  :       97557 :  ABI_MALLOC(irredat_tmp, (Cryst%natom))
          +  -  +  -  -  
                +  -  + ]
     584         [ +  + ]:      115591 :  irredat_tmp = .TRUE.
     585                 :             : 
     586                 :       32519 :  Cryst%nirredat = 0
     587         [ +  + ]:      115591 :  do iat = 1,Cryst%natom
     588         [ +  + ]:      115591 :    if(irredat_tmp(iat))then
     589                 :       65440 :       Cryst%nirredat = Cryst%nirredat + 1
     590         [ +  + ]:     1040726 :       do isym = 1,Cryst%nsym
     591         [ +  + ]:     1040726 :          if (Cryst%indsym(4,isym,iat) /= iat)then
     592                 :      248971 :            irredat_tmp(Cryst%indsym(4,isym,iat)) = .FALSE.
     593                 :             :          endif
     594                 :             :       enddo
     595                 :             :    endif
     596                 :             :  enddo
     597                 :             : 
     598                 :             :  ! Write indexes of irreducible atoms
     599   [ -  +  +  -  :       97557 :  ABI_MALLOC(Cryst%irredatindx, (Cryst%nirredat))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     600                 :       32519 :  indx = 0
     601         [ +  + ]:      115591 :  do iat = 1,Cryst%natom
     602         [ +  + ]:      115591 :     if (irredat_tmp(iat)) then
     603                 :       65440 :       indx = indx + 1
     604                 :       65440 :       cryst%irredatindx(indx) = iat
     605                 :             :     endif
     606                 :             :  enddo
     607                 :             : 
     608         [ +  - ]:       32519 :  ABI_SFREE(irredat_tmp)
     609                 :             : 
     610                 :       32519 : end subroutine crystal_compute_sym
     611                 :             : !!***
     612                 :             : 
     613                 :             : !----------------------------------------------------------------------
     614                 :             : 
     615                 :             : !!****f* m_crystal/crystal_compute_geometry
     616                 :             : !! NAME
     617                 :             : !!  crystal_compute_geometry
     618                 :             : !!
     619                 :             : !! FUNCTION
     620                 :             : !!  Compute the different metrics and the angle between primitive vectors.
     621                 :             : !!  Also compute cartesian coordinates of atoms.
     622                 :             : !!
     623                 :             : !! SOURCE
     624                 :             : 
     625                 :       32519 : subroutine crystal_compute_geometry(Cryst)
     626                 :             : 
     627                 :             : !Arguments ------------------------------------
     628                 :             :  class(crystal_t),intent(inout) :: Cryst
     629                 :             : ! *********************************************************************
     630                 :             : 
     631                 :       32519 :  call metric(Cryst%gmet,Cryst%gprimd,-1,Cryst%rmet,Cryst%rprimd,Cryst%ucvol)
     632                 :             : 
     633                 :       32519 :  Cryst%angdeg(1)=ACOS(Cryst%rmet(2,3)/SQRT(Cryst%rmet(2,2)*Cryst%rmet(3,3)))/two_pi*360.0d0
     634                 :       32519 :  Cryst%angdeg(2)=ACOS(Cryst%rmet(1,3)/SQRT(Cryst%rmet(1,1)*Cryst%rmet(3,3)))/two_pi*360.0d0
     635                 :       32519 :  Cryst%angdeg(3)=ACOS(Cryst%rmet(1,2)/SQRT(Cryst%rmet(1,1)*Cryst%rmet(2,2)))/two_pi*360.0d0
     636                 :             : 
     637                 :       32519 :  call xred2xcart(Cryst%natom,Cryst%rprimd,Cryst%xcart,Cryst%xred)
     638                 :             : 
     639                 :       32519 : end subroutine crystal_compute_geometry
     640                 :             : !!***
     641                 :             : 
     642                 :             : !----------------------------------------------------------------------
     643                 :             : 
     644                 :             : !!****f* m_crystal/crystal_malloc
     645                 :             : !! NAME
     646                 :             : !!  crystal_malloc
     647                 :             : !!
     648                 :             : !! FUNCTION
     649                 :             : !!  Allocate the dynamic arrays in a crystal_t data type.
     650                 :             : !!
     651                 :             : !! SOURCE
     652                 :             : 
     653                 :       33066 : subroutine crystal_malloc(Cryst)
     654                 :             : 
     655                 :             : !Arguments ------------------------------------
     656                 :             :  class(crystal_t),intent(inout) :: Cryst
     657                 :             : 
     658                 :             : !Local variables-------------------------------
     659                 :             :  integer :: ii
     660                 :             : ! *********************************************************************
     661                 :             : 
     662                 :             : !integer
     663   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%typat,(Cryst%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     664   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%xred,(3,Cryst%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     665   [ -  +  +  -  :       66132 :  ABI_MALLOC(Cryst%xcart,(3,Cryst%natom))
          -  +  -  +  -  
                      + ]
     666   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%zion,(Cryst%ntypat))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     667   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%znucl,(Cryst%npsp))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     668   [ -  +  +  -  :       66132 :  ABI_MALLOC(Cryst%amu, (Cryst%ntypat))
          -  +  -  +  -  
                      + ]
     669                 :             : 
     670   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%symrel,(3,3,Cryst%nsym))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     671   [ -  +  +  -  :       66132 :  ABI_MALLOC(Cryst%symrec,(3,3,Cryst%nsym))
          -  +  -  +  -  
                      + ]
     672   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%tnons,(3,Cryst%nsym))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     673   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%symafm,(Cryst%nsym))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     674   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%symrel_cart, (3, 3, Cryst%nsym))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     675   [ -  +  +  -  :      132264 :  ABI_MALLOC(Cryst%indsym,(4, Cryst%nsym, Cryst%natom))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     676                 :             : 
     677   [ -  +  +  -  :       66132 :  ABI_MALLOC(Cryst%atindx,(Cryst%natom))
          -  +  -  +  -  
                      + ]
     678   [ -  +  +  -  :       66132 :  ABI_MALLOC(Cryst%atindx1,(Cryst%natom))
          -  +  -  +  -  
                      + ]
     679   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%nattyp,(Cryst%ntypat))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     680   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%spinrot, (4, Cryst%nsym))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     681                 :             : 
     682   [ -  +  +  -  :       99198 :  ABI_MALLOC(Cryst%title,(Cryst%ntypat))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     683                 :             : 
     684                 :             :  ! nirredat must first be computed from indsym
     685                 :             :  !ABI_MALLOC(Cryst%irredatindx,(Cryst%nirredat))
     686                 :             : 
     687         [ +  + ]:      117548 :  Cryst%typat = zero
     688   [ +  +  +  + ]:      370994 :  Cryst%xred = zero
     689   [ +  +  +  + ]:      370994 :  Cryst%xcart = zero
     690         [ +  + ]:       78567 :  Cryst%zion = zero
     691         [ +  + ]:       78657 :  Cryst%znucl = zero
     692         [ +  + ]:       78567 :  Cryst%amu = zero
     693   [ +  +  +  +  :    10088306 :  Cryst%symrel = zero
                   +  + ]
     694   [ +  +  +  +  :    10088306 :  Cryst%symrec = zero
                   +  + ]
     695   [ +  +  +  + ]:     3126986 :  Cryst%tnons = zero
     696         [ +  + ]:      806546 :  Cryst%symafm = zero
     697   [ +  +  +  +  :    10088306 :  Cryst%symrel_cart = zero
                   +  + ]
     698   [ +  +  +  +  :     8627518 :  Cryst%indsym = zero
                   +  + ]
     699         [ +  + ]:      117548 :  Cryst%atindx = zero
     700         [ +  + ]:      117548 :  Cryst%atindx1 = zero
     701         [ +  + ]:       78567 :  Cryst%nattyp = zero
     702   [ +  +  +  + ]:     3900466 :  Cryst%spinrot = zero
     703                 :             : 
     704         [ +  + ]:       78567 :  do ii=1,Cryst%ntypat
     705                 :       78567 :    Cryst%title(ii) = ''
     706                 :             :  end do
     707                 :             : 
     708                 :       33066 : end subroutine crystal_malloc
     709                 :             : !!***
     710                 :             : 
     711                 :             : !----------------------------------------------------------------------
     712                 :             : 
     713                 :             : !!****f* m_crystal/crystal_free
     714                 :             : !! NAME
     715                 :             : !!  crystal_free
     716                 :             : !!
     717                 :             : !! FUNCTION
     718                 :             : !!  Free dynamic memory in a crystal_t data type.
     719                 :             : !!
     720                 :             : !! SOURCE
     721                 :             : 
     722                 :       66506 : subroutine crystal_free(Cryst)
     723                 :             : 
     724                 :             : !Arguments ------------------------------------
     725                 :             :  class(crystal_t),intent(inout) :: Cryst
     726                 :             : ! *********************************************************************
     727                 :             : 
     728                 :             : !integer
     729         [ +  + ]:       66506 :  ABI_SFREE(Cryst%indsym)
     730         [ +  + ]:       66506 :  ABI_SFREE(Cryst%symafm)
     731         [ +  + ]:       66506 :  ABI_SFREE(Cryst%symrec)
     732         [ +  + ]:       66506 :  ABI_SFREE(Cryst%symrel)
     733         [ +  + ]:       66506 :  ABI_SFREE(Cryst%symrel_cart)
     734         [ +  + ]:       66506 :  ABI_SFREE(Cryst%atindx)
     735         [ +  + ]:       66506 :  ABI_SFREE(Cryst%atindx1)
     736         [ +  + ]:       66506 :  ABI_SFREE(Cryst%typat)
     737         [ +  + ]:       66506 :  ABI_SFREE(Cryst%nattyp)
     738         [ +  + ]:       66506 :  ABI_SFREE(Cryst%irredatindx)
     739                 :             : 
     740                 :             : !real
     741         [ +  + ]:       66506 :  ABI_SFREE(Cryst%tnons)
     742         [ +  + ]:       66506 :  ABI_SFREE(Cryst%xcart)
     743         [ +  + ]:       66506 :  ABI_SFREE(Cryst%xred)
     744         [ +  + ]:       66506 :  ABI_SFREE(Cryst%zion)
     745         [ +  + ]:       66506 :  ABI_SFREE(Cryst%znucl)
     746         [ +  + ]:       66506 :  ABI_SFREE(Cryst%amu)
     747         [ +  + ]:       66506 :  ABI_SFREE(Cryst%spinrot)
     748                 :             : 
     749                 :             : !character
     750         [ +  + ]:       66506 :  ABI_SFREE(Cryst%title)
     751                 :             : 
     752                 :       66506 : end subroutine crystal_free
     753                 :             : !!***
     754                 :             : 
     755                 :             : !----------------------------------------------------------------------
     756                 :             : 
     757                 :             : !!****f* m_crystal/crystal_copy
     758                 :             : !! NAME
     759                 :             : !!  crystal_copy
     760                 :             : !!
     761                 :             : !! FUNCTION
     762                 :             : !!  Copy the object.
     763                 :             : !!
     764                 :             : !! OUTPUTS
     765                 :             : !!  new = A new crystal instance
     766                 :             : !!
     767                 :             : !! SOURCE
     768                 :             : 
     769         [ +  - ]:         531 : subroutine crystal_copy(Cryst, new)
     770                 :             : 
     771                 :             : !Arguments ------------------------------------
     772                 :             :  class(crystal_t),intent(in) :: Cryst
     773                 :             :  class(crystal_t),intent(out) :: new
     774                 :             : ! *********************************************************************
     775                 :             : 
     776                 :             :  ! Copy dimensions, scalar variables, and static arrays
     777                 :         531 :  new%natom = Cryst%natom
     778                 :         531 :  new%nsym = Cryst%nsym
     779                 :         531 :  new%ntypat = Cryst%ntypat
     780                 :         531 :  new%nirredat = Cryst%nirredat
     781                 :         531 :  new%npsp = Cryst%npsp
     782                 :         531 :  new%space_group = Cryst%space_group
     783                 :         531 :  new%timrev = Cryst%timrev
     784                 :         531 :  new%ucvol = Cryst%ucvol
     785                 :         531 :  new%use_antiferro = Cryst%use_antiferro
     786         [ +  + ]:        2124 :  new%angdeg = Cryst%angdeg
     787   [ +  +  +  + ]:        6903 :  new%gmet = Cryst%gmet
     788   [ +  +  +  + ]:        6903 :  new%gprimd = Cryst%gprimd
     789   [ +  +  +  + ]:        6903 :  new%rmet = Cryst%rmet
     790   [ +  +  +  + ]:        6903 :  new%rprimd = Cryst%rprimd
     791                 :             : 
     792                 :             :  ! Allocate memory
     793                 :         531 :  call new%malloc()
     794         [ +  + ]:         531 :  if (allocated(Cryst%irredatindx)) then
     795   [ -  +  +  -  :        1569 :    ABI_MALLOC(new%irredatindx,(new%nirredat))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     796                 :             :  end if
     797                 :             : 
     798                 :             :  ! Copy dynamic arrays
     799   [ +  -  +  -  :      199210 :  new%indsym = Cryst%indsym
          +  -  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  +  
             +  +  +  + ]
     800   [ +  -  -  +  :       19022 :  new%symafm = Cryst%symafm
          -  -  -  -  -  
                -  +  + ]
     801   [ +  -  +  -  :      234542 :  new%symrec = Cryst%symrec
          +  -  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  +  
             +  +  +  + ]
     802   [ +  -  +  -  :      234542 :  new%symrel = Cryst%symrel
          +  -  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  +  
             +  +  +  + ]
     803   [ +  -  +  -  :      234542 :  new%symrel_cart = Cryst%symrel_cart
          +  -  -  +  -  
          -  -  -  -  -  
          -  -  -  -  -  
          -  -  -  +  +  
             +  +  +  + ]
     804   [ +  -  -  +  :        2400 :  new%atindx = Cryst%atindx
          -  -  -  -  -  
                -  +  + ]
     805   [ +  -  -  +  :        2400 :  new%atindx1 = Cryst%atindx1
          -  -  -  -  -  
                -  +  + ]
     806   [ +  -  -  +  :        2400 :  new%typat = Cryst%typat
          -  -  -  -  -  
                -  +  + ]
     807   [ +  -  -  +  :        1950 :  new%nattyp = Cryst%nattyp
          -  -  -  -  -  
                -  +  + ]
     808   [ +  -  +  -  :       72902 :  new%tnons = Cryst%tnons
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  +  +  +  
                      + ]
     809   [ +  -  +  -  :        6414 :  new%xcart = Cryst%xcart
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  +  +  +  
                      + ]
     810   [ +  -  +  -  :        6414 :  new%xred = Cryst%xred
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  +  +  +  
                      + ]
     811   [ +  -  +  -  :       90862 :  new%spinrot = Cryst%spinrot
          -  +  -  -  -  
          -  -  -  -  -  
          -  -  +  +  +  
                      + ]
     812   [ +  -  -  +  :        1950 :  new%amu = Cryst%amu
          -  -  -  -  -  
                -  +  + ]
     813   [ +  -  -  +  :        1950 :  new%zion = Cryst%zion
          -  -  -  -  -  
                -  +  + ]
     814   [ +  -  -  +  :        1950 :  new%znucl = Cryst%znucl
          -  -  -  -  -  
                -  +  + ]
     815   [ +  -  -  +  :        1950 :  new%title = Cryst%title
          -  -  -  -  -  
                -  +  + ]
     816         [ +  + ]:         531 :  if (allocated(Cryst%irredatindx)) then
     817   [ +  -  -  +  :        2060 :    new%irredatindx = Cryst%irredatindx
          -  -  -  -  -  
                -  +  + ]
     818                 :             :  end if
     819                 :             : 
     820                 :         531 : end subroutine crystal_copy
     821                 :             : !!***
     822                 :             : 
     823                 :             : !----------------------------------------------------------------------
     824                 :             : 
     825                 :             : !!****f* m_crystal/crystal_bcast
     826                 :             : !! NAME
     827                 :             : !!  crystal_bcast
     828                 :             : !!
     829                 :             : !! FUNCTION
     830                 :             : !!  Master broadcasts data and others allocate their arrays.
     831                 :             : !!
     832                 :             : !! SOURCE
     833                 :             : 
     834                 :          24 : subroutine crystal_bcast(Cryst, comm)
     835                 :             : 
     836                 :             : !Arguments ------------------------------------
     837                 :             :  class(crystal_t),intent(inout) :: Cryst
     838                 :             :  integer, intent(in) :: comm
     839                 :             : 
     840                 :             : !Local variables -------------------------
     841                 :             :  integer, parameter :: master=0
     842                 :             :  integer :: ierr
     843                 :             : ! *********************************************************************
     844                 :             : 
     845         [ -  + ]:          24 :  if (xmpi_comm_size(comm) == 1) return
     846                 :             : 
     847                 :             :  DBG_ENTER("COLL")
     848                 :             : 
     849                 :             :  ! Integers
     850                 :          24 :  call xmpi_bcast(Cryst%natom, master, comm, ierr)
     851                 :          24 :  call xmpi_bcast(Cryst%nsym, master, comm, ierr)
     852                 :          24 :  call xmpi_bcast(Cryst%ntypat, master, comm, ierr)
     853                 :          24 :  call xmpi_bcast(Cryst%nirredat, master, comm, ierr)
     854                 :          24 :  call xmpi_bcast(Cryst%npsp, master, comm, ierr)
     855                 :          24 :  call xmpi_bcast(Cryst%space_group, master, comm, ierr)
     856                 :          24 :  call xmpi_bcast(Cryst%timrev, master, comm, ierr)
     857                 :          24 :  call xmpi_bcast(Cryst%use_antiferro, master, comm, ierr)
     858                 :             : 
     859         [ +  + ]:          24 :  if (xmpi_comm_rank(comm) /= master) then
     860                 :          16 :    call Cryst%free()
     861                 :          16 :    call Cryst%malloc()
     862                 :             :  end if
     863                 :             : 
     864                 :             :  ! Floats
     865                 :          24 :  call xmpi_bcast(Cryst%ucvol, master, comm, ierr)
     866                 :             : 
     867                 :             :  ! Arrays
     868                 :          24 :  call xmpi_bcast(Cryst%angdeg, master, comm, ierr)
     869                 :          24 :  call xmpi_bcast(Cryst%gmet, master, comm, ierr)
     870                 :          24 :  call xmpi_bcast(Cryst%gprimd, master, comm, ierr)
     871                 :          24 :  call xmpi_bcast(Cryst%rmet, master, comm, ierr)
     872                 :          24 :  call xmpi_bcast(Cryst%rprimd, master, comm, ierr)
     873                 :          24 :  call xmpi_bcast(Cryst%indsym, master, comm, ierr)
     874                 :          24 :  call xmpi_bcast(Cryst%symafm, master, comm, ierr)
     875                 :          24 :  call xmpi_bcast(Cryst%symrec, master, comm, ierr)
     876                 :          24 :  call xmpi_bcast(Cryst%symrel, master, comm, ierr)
     877                 :          24 :  call xmpi_bcast(Cryst%symrel_cart, master, comm, ierr)
     878                 :          24 :  call xmpi_bcast(Cryst%atindx, master, comm, ierr)
     879                 :          24 :  call xmpi_bcast(Cryst%atindx1, master, comm, ierr)
     880                 :          24 :  call xmpi_bcast(Cryst%typat, master, comm, ierr)
     881                 :          24 :  call xmpi_bcast(Cryst%nattyp, master, comm, ierr)
     882                 :          24 :  call xmpi_bcast(Cryst%tnons, master, comm, ierr)
     883                 :          24 :  call xmpi_bcast(Cryst%xcart, master, comm, ierr)
     884                 :          24 :  call xmpi_bcast(Cryst%xred, master, comm, ierr)
     885                 :          24 :  call xmpi_bcast(Cryst%spinrot, master, comm, ierr)
     886                 :          24 :  call xmpi_bcast(Cryst%amu, master, comm, ierr)
     887                 :          24 :  call xmpi_bcast(Cryst%zion, master, comm, ierr)
     888                 :          24 :  call xmpi_bcast(Cryst%znucl, master, comm, ierr)
     889                 :          24 :  call xmpi_bcast(Cryst%title, master, comm, ierr)
     890                 :             : 
     891                 :             :  ! It is not always allocated on master node,
     892                 :             :  ! and it can be computed afterward on each node.
     893                 :             :  !call xmpi_bcast(Cryst%irredatindx, master, comm, ierr)
     894                 :             : 
     895                 :             :  DBG_EXIT("COLL")
     896                 :             : 
     897                 :             : end subroutine crystal_bcast
     898                 :             : !!***
     899                 :             : 
     900                 :             : !----------------------------------------------------------------------
     901                 :             : 
     902                 :             : !!****f* m_crystal/crystal_compare
     903                 :             : !! NAME
     904                 :             : !!  crystal_compare
     905                 :             : !!
     906                 :             : !! FUNCTION
     907                 :             : !!   Compare two crystalline structures,
     908                 :             : !!   write warning messages to stdout if they differ, return exit status
     909                 :             : !!
     910                 :             : !! INPUTS
     911                 :             : !!  [header]=Optional header message.
     912                 :             : !!
     913                 :             : !! OUTPUT
     914                 :             : !!
     915                 :             : !! SOURCE
     916                 :             : 
     917                 :         262 : integer function crystal_compare(self, other, header) result(ierr)
     918                 :             : 
     919                 :             : !Arguments ------------------------------------
     920                 :             :  class(crystal_t),intent(in) :: self, other
     921                 :             :  character(len=*),optional,intent(in) :: header
     922                 :             : 
     923                 :             : !Local variables-------------------------------
     924                 :             :  !integer :: isym, iat, itypat
     925                 :             : ! *********************************************************************
     926                 :             : 
     927         [ +  + ]:         262 :  if (present(header)) call wrtout(std_out, header)
     928                 :         262 :  ierr = 0
     929                 :             : 
     930                 :             :  ! Test basic dimensions and metadata.
     931         [ -  + ]:         262 :  ABI_CHECK_IEQ_IERR(self%natom, other%natom, "Different natom" , ierr)
     932         [ -  + ]:         262 :  ABI_CHECK_IEQ_IERR(self%ntypat, other%ntypat, "Different ntypat" , ierr)
     933         [ -  + ]:         262 :  ABI_CHECK_IEQ_IERR(self%npsp, other%npsp, "Different npsp" , ierr)
     934         [ -  + ]:         262 :  ABI_CHECK_IEQ_IERR(self%nsym, other%nsym, "Different nsym" , ierr)
     935         [ -  + ]:         262 :  ABI_CHECK_IEQ_IERR(self%timrev, other%timrev, "Different timrev" , ierr)
     936                 :             : 
     937         [ -  + ]:         262 :  if (ierr /= 0) goto 10
     938                 :             :  ! After this point, we know that basic dimensions agree with each other.
     939                 :             :  ! Yes, I use GOTO and I'm proud of that!
     940                 :             : 
     941                 :             :  ! Check direct lattice
     942   [ +  +  +  +  :        3406 :  if (any(abs(self%rprimd - other%rprimd) > tol6)) then
             +  -  -  + ]
     943                 :           0 :    ABI_WARNING("Found critical diffs in rprimd lattice vectors.")
     944                 :           0 :    ierr = ierr + 1
     945                 :             :  end if
     946                 :             : 
     947                 :             :  ! Check Symmetries
     948   [ +  +  +  +  :      147734 :  if (any(self%symrel /= other%symrel)) then
          +  +  +  -  -  
                      + ]
     949                 :           0 :    ABI_WARNING("Found critical diffs in symrel symmetries.")
     950                 :           0 :    ierr = ierr + 1
     951                 :             :  end if
     952   [ +  +  +  +  :       45638 :  if (any(abs(self%tnons - other%tnons) > tol3)) then
             +  -  -  + ]
     953                 :           0 :    ABI_WARNING("Found critical diffs in fractional translations tnons.")
     954                 :           0 :    ierr = ierr + 1
     955                 :             :  end if
     956         [ -  + ]:         262 :  if (self%use_antiferro .neqv. other%use_antiferro) then
     957                 :           0 :    ABI_WARNING("Different values of use_antiferro")
     958                 :           0 :    ierr = ierr + 1
     959                 :             :  end if
     960                 :             : 
     961                 :             :  ! Atoms
     962   [ +  +  +  -  :         766 :  if (any(self%typat /= other%typat)) then
                   -  + ]
     963                 :           0 :    ABI_WARNING("Found critical diffs in typat.")
     964                 :             :    !print *, self%typat; print *, other%typat
     965                 :           0 :    ierr = ierr + 1
     966                 :             :  end if
     967   [ +  +  +  -  :         656 :  if (any(abs(self%zion - other%zion) > tol3)) then
                   -  + ]
     968                 :           0 :    ABI_WARNING("Found critical diffs in zion.")
     969                 :           0 :    ierr = ierr + 1
     970                 :             :  end if
     971   [ +  +  +  -  :         656 :  if (any(abs(self%znucl - other%znucl) > tol3)) then
                   -  + ]
     972                 :           0 :    ABI_WARNING("Found critical diffs in znucl.")
     973                 :           0 :    ierr = ierr + 1
     974                 :             :  end if
     975   [ +  +  +  -  :         656 :  if (any(abs(self%amu - other%amu) > tol3)) then
                   -  + ]
     976                 :           0 :    ABI_WARNING("Found critical diffs in amu.")
     977                 :           0 :    ierr = ierr + 1
     978                 :             :  end if
     979   [ +  +  +  +  :        2278 :  if (any(abs(self%xred - other%xred) > tol6)) then
             +  -  -  + ]
     980                 :           0 :    ABI_WARNING("Found critical diffs in xred.")
     981                 :           0 :    ierr = ierr + 1
     982                 :             :  end if
     983                 :             : 
     984         [ -  + ]:         262 :  if (ierr /= 0) goto 10
     985                 :           0 :  return
     986                 :             : 
     987                 :             :  ! Print structure to aid debugging. Caller will handle exit status.
     988                 :           0 : 10 call wrtout(std_out, " Comparing crystal1 and crystal2 for possible differences before returning ierr /= 0!")
     989                 :           0 :    call self%print(header="crystal1")
     990                 :           0 :    call wrtout(std_out, "")
     991                 :           0 :    call other%print(header="crystal2")
     992                 :           0 :    call wrtout(std_out, "")
     993                 :             : 
     994                 :           0 : end function crystal_compare
     995                 :             : !!***
     996                 :             : 
     997                 :             : !----------------------------------------------------------------------
     998                 :             : 
     999                 :             : !!****f* m_crystal/crystal_print
    1000                 :             : !! NAME
    1001                 :             : !!  crystal_print
    1002                 :             : !!
    1003                 :             : !! FUNCTION
    1004                 :             : !!  Print the content of crystal_t data type
    1005                 :             : !!
    1006                 :             : !! INPUTS
    1007                 :             : !!  Cryst<crystal_t>=The structure.
    1008                 :             : !!  [unit]=Unit number for output. Defaults to std_out
    1009                 :             : !!  [prtvol]=Verbosity level. If prtvol== -1, only lattice parameters are printed. Defaults to 0
    1010                 :             : !!  [mode_paral]=Either "COLL" or "PERS"
    1011                 :             : !!  [header]=String to be printed as header for additional info.
    1012                 :             : !!
    1013                 :             : !! OUTPUT
    1014                 :             : !!  Only printing
    1015                 :             : !!
    1016                 :             : !! SOURCE
    1017                 :             : 
    1018                 :        1243 : subroutine crystal_print(Cryst, header, unit, mode_paral, prtvol)
    1019                 :             : 
    1020                 :             : !Arguments ------------------------------------
    1021                 :             : !scalars
    1022                 :             :  class(crystal_t),intent(in) :: Cryst
    1023                 :             :  integer,optional,intent(in) :: unit, prtvol
    1024                 :             :  character(len=*),optional,intent(in) :: mode_paral
    1025                 :             :  character(len=*),optional,intent(in) :: header
    1026                 :             : 
    1027                 :             : !Local variables-------------------------------
    1028                 :             :  integer :: my_unt,my_prtvol,nu,iatom, isym, ii, nsym, units(1)
    1029                 :             :  character(len=4) :: my_mode
    1030                 :             :  character(len=500) :: msg
    1031                 :             : ! *********************************************************************
    1032                 :             : 
    1033                 :         694 :  my_unt   =std_out; if (PRESENT(unit      )) my_unt   =unit
    1034         [ +  + ]:        1243 :  my_prtvol=0      ; if (PRESENT(prtvol    )) my_prtvol=prtvol
    1035   [ +  +  -  + ]:        1243 :  my_mode  ='COLL' ; if (PRESENT(mode_paral)) my_mode  =mode_paral
    1036                 :             : 
    1037         [ +  + ]:        2486 :  units = [my_unt]
    1038                 :             : 
    1039                 :        1243 :  msg=' ==== Info on the Cryst% object ==== '
    1040   [ +  +  +  -  :        1243 :  if (PRESENT(header)) msg=' ==== '//TRIM(ADJUSTL(header))//' ==== '
                   +  - ]
    1041                 :        1243 :  call wrtout(my_unt, sjoin(ch10, msg), my_mode)
    1042                 :             : 
    1043                 :        1243 :  write(msg,'(a)')' Real(R)+Recip(G) space primitive vectors, cartesian coordinates (Bohr,Bohr^-1):'
    1044                 :        1243 :  call wrtout(my_unt,msg,my_mode)
    1045         [ +  + ]:        4972 :  do nu=1,3
    1046                 :             :    write(msg,'(1x,a,i1,a,3f11.7,2x,a,i1,a,3f11.7)')&
    1047         [ +  + ]:       14916 :     'R(',nu,')=',Cryst%rprimd(:,nu)+tol10, &
    1048         [ +  + ]:       18645 :     'G(',nu,')=',Cryst%gprimd(:,nu)+tol10  ! tol10 is used to be consistent with metric.F90
    1049                 :        4972 :    call wrtout(my_unt,msg,my_mode)
    1050                 :             :  end do
    1051                 :             : 
    1052                 :        1243 :  write(msg,'(a,1p,e15.7,a)')' Unit cell volume ucvol=',Cryst%ucvol+tol10,' bohr^3'
    1053                 :        1243 :  call wrtout(my_unt,msg,my_mode)
    1054                 :             : 
    1055                 :        1243 :  write(msg,'(a,3es16.8,a)')' Angles (23,13,12)=',Cryst%angdeg(1:3),' degrees'
    1056                 :        1243 :  call wrtout(my_unt,msg,my_mode)
    1057                 :             : 
    1058         [ +  + ]:        1243 :  if (Cryst%timrev==1) then
    1059                 :         199 :    msg = ' Time-reversal symmetry is not present '
    1060         [ +  - ]:        1044 :  else if (Cryst%timrev==2) then
    1061                 :        1044 :    msg = ' Time-reversal symmetry is present '
    1062                 :             :  else
    1063                 :           0 :    ABI_BUG(sjoin('Wrong value for timrev:', itoa(cryst%timrev)))
    1064                 :             :  end if
    1065                 :        1243 :  call wrtout(my_unt,msg,my_mode)
    1066         [ +  + ]:        1243 :  if (my_prtvol == -1) return
    1067                 :             : 
    1068         [ -  + ]:        1240 :  if (my_prtvol > 0) then
    1069                 :           0 :    call print_symmetries(units, Cryst%nsym, Cryst%symrel, Cryst%tnons, Cryst%symafm)
    1070         [ #  # ]:           0 :    if (Cryst%use_antiferro) call wrtout(my_unt,' System has magnetic symmetries ',my_mode)
    1071                 :             : 
    1072                 :             :    ! Print indsym using the same format as in symatm
    1073                 :           0 :    nsym = cryst%nsym
    1074         [ #  # ]:           0 :    do iatom=1,cryst%natom
    1075                 :           0 :      write(msg, '(a,i0,a)' )' symatm: atom number ',iatom,' is reached starting at atom'
    1076                 :           0 :      call wrtout(std_out, msg)
    1077         [ #  # ]:           0 :      do ii=1,(nsym-1)/24+1
    1078         [ #  # ]:           0 :        if (cryst%natom<100) then
    1079   [ #  #  #  # ]:           0 :          write(msg, '(1x,24i3)' ) (cryst%indsym(4,isym,iatom),isym=1+(ii-1)*24,min(nsym,ii*24))
    1080                 :             :        else
    1081   [ #  #  #  # ]:           0 :          write(msg, '(1x,24i6)' ) (cryst%indsym(4,isym,iatom),isym=1+(ii-1)*24,min(nsym,ii*24))
    1082                 :             :        end if
    1083                 :           0 :        call wrtout(std_out, msg)
    1084                 :             :      end do
    1085                 :             :    end do
    1086                 :             : 
    1087                 :             :  end if
    1088                 :             : 
    1089                 :        1240 :  call wrtout(my_unt, " Reduced atomic positions [iatom, xred, symbol]:", my_mode)
    1090         [ +  + ]:        4275 :  do iatom=1,cryst%natom
    1091                 :        3035 :    write(msg,"(i5,a,2x,3f11.7,2x,a)")iatom,")",cryst%xred(:,iatom), cryst%symbol_type(cryst%typat(iatom))
    1092                 :        4275 :    call wrtout(my_unt,msg,my_mode)
    1093                 :             :  end do
    1094                 :             : 
    1095         [ +  + ]:        1243 : end subroutine crystal_print
    1096                 :             : !!***
    1097                 :             : 
    1098                 :             : !!****f* m_crystal/crystal_print_abivars
    1099                 :             : !! NAME
    1100                 :             : !!  crystal_print_abivars
    1101                 :             : !!
    1102                 :             : !! FUNCTION
    1103                 :             : !!   Print unit cell info in Abinit/abivars format
    1104                 :             : !!
    1105                 :             : !! INPUTS
    1106                 :             : !!  unit=Output unit
    1107                 :             : !!
    1108                 :             : !! OUTPUT
    1109                 :             : !!  Only printing
    1110                 :             : !!
    1111                 :             : !! SOURCE
    1112                 :             : 
    1113                 :           0 : subroutine crystal_print_abivars(cryst, unit)
    1114                 :             : 
    1115                 :             : !Arguments ------------------------------------
    1116                 :             : !scalars
    1117                 :             :  class(crystal_t),intent(in) :: cryst
    1118                 :             :  integer,intent(in) :: unit
    1119                 :             : 
    1120                 :             : !Local variables-------------------------------
    1121                 :             :  integer :: iatom, ii
    1122                 :             :  !character(len=500) :: fmt
    1123                 :             : ! *********************************************************************
    1124                 :             : 
    1125         [ #  # ]:           0 :  if (unit == dev_null) return
    1126                 :             : 
    1127                 :             :  ! Write variables using standard Abinit input format.
    1128                 :           0 :  write(unit, "(/,/,a)")" # Abinit variables"
    1129                 :           0 :  write(unit, "(a)")" acell 1.0 1.0 1.0"
    1130                 :           0 :  write(unit, "(a)")" rprimd"
    1131         [ #  # ]:           0 :  do ii=1,3
    1132                 :           0 :     write(unit, "(3(f11.7,1x))")cryst%rprimd(:, ii)
    1133                 :             :  end do
    1134                 :           0 :  write(unit, "(a, i0)")" natom ", cryst%natom
    1135                 :           0 :  write(unit, "(a, i0)")" ntypat ", cryst%ntypat
    1136                 :           0 :  write(unit, strcat("(a, ", itoa(cryst%natom), "(i0,1x))")) " typat ", cryst%typat
    1137                 :           0 :  write(unit, strcat("(a, ", itoa(cryst%npsp), "(f5.1,1x))")) " znucl ", cryst%znucl
    1138                 :           0 :  write(unit, "(a)")" xred"
    1139         [ #  # ]:           0 :  do iatom=1,cryst%natom
    1140                 :           0 :    write(unit,"(1x, 3f11.7,2x,2a)")cryst%xred(:,iatom), " # ", cryst%symbol_type(cryst%typat(iatom))
    1141                 :             :  end do
    1142                 :             : 
    1143                 :             :  ! Write variables using the abivars format supported by structure variable.
    1144                 :             :  !write(unit, "(/,/,a)")" # Abivars format (external file with structure variable)"
    1145                 :             :  !write(unit, "(a)")" acell 1.0 1.0 1.0"
    1146                 :             :  !write(unit, "(a)")" rprimd"
    1147                 :             :  !do ii=1,3
    1148                 :             :  !   write(unit, "(1x, 3(f11.7,1x))")cryst%rprimd(:, ii)
    1149                 :             :  !end do
    1150                 :             :  !write(unit, "(a, i0)")" natom ", cryst%natom
    1151                 :             :  !write(unit, "(a)")" xred_symbols"
    1152                 :             :  !do iatom=1,cryst%natom
    1153                 :             :  !  write(unit,"(1x, 3f11.7,2x,a)")cryst%xred(:,iatom), cryst%symbol_type(cryst%typat(iatom))
    1154                 :             :  !end do
    1155                 :             : 
    1156                 :             : end subroutine crystal_print_abivars
    1157                 :             : !!***
    1158                 :             : 
    1159                 :             : !----------------------------------------------------------------------
    1160                 :             : 
    1161                 :             : !!****f* m_crystal/symbols_crystal
    1162                 :             : !!
    1163                 :             : !! NAME
    1164                 :             : !! symbols_crystal
    1165                 :             : !!
    1166                 :             : !! FUNCTION
    1167                 :             : !! Return a array with the symbol of each atoms with indexation e.g.
    1168                 :             : !! ["Sr","Ru","O1","O2","O3"]
    1169                 :             : !!
    1170                 :             : !! INPUTS
    1171                 :             : !! natom = number of atoms
    1172                 :             : !! ntypat = number of typat
    1173                 :             : !! npsp =  number of pseudopotentials
    1174                 :             : !! znucl = Nuclear charge for each type of pseudopotential
    1175                 :             : !!
    1176                 :             : !! OUTPUT
    1177                 :             : !! symbols = array with the symbol of each atoms
    1178                 :             : !!
    1179                 :             : !! SOURCE
    1180                 :             : 
    1181                 :         104 : subroutine symbols_crystal(natom, ntypat, npsp, symbols, typat, znucl)
    1182                 :             : 
    1183                 :             : !Arguments ------------------------------------
    1184                 :             : !scalars
    1185                 :             :  integer,intent(in) :: natom,ntypat,npsp
    1186                 :             : !arrays
    1187                 :             :  real(dp),intent(in):: znucl(npsp)
    1188                 :             :  integer,intent(in) :: typat(natom)
    1189                 :             :  character(len=5),intent(out) :: symbols(natom)
    1190                 :             :  character(len=3) :: powerchar
    1191                 :             : 
    1192                 :             : !Local variables-------------------------------
    1193                 :             : !scalar
    1194                 :             :  integer :: ia,ii,itypat,jj
    1195                 :             : ! *************************************************************************
    1196                 :             : 
    1197                 :             :  ! Fill the symbols array
    1198         [ +  + ]:         624 :  do ia=1,natom
    1199                 :         624 :    symbols(ia) = adjustl(znucl2symbol(znucl(typat(ia))))
    1200                 :             :  end do
    1201                 :         104 :  itypat = 0
    1202         [ +  + ]:         416 :  do itypat =1,ntypat
    1203                 :             :    ii = 0
    1204         [ +  + ]:        1872 :    do ia=1,natom
    1205         [ +  + ]:        1872 :      if(typat(ia)==itypat) then
    1206                 :         520 :        ii = ii + 1
    1207                 :             :      end if
    1208                 :             :    end do
    1209         [ +  + ]:         416 :    if(ii>1)then
    1210                 :         104 :      jj=1
    1211         [ +  + ]:         624 :      do ia=1,natom
    1212         [ +  + ]:         624 :        if(typat(ia)==itypat) then
    1213                 :         312 :          write(powerchar,'(I0)') jj
    1214   [ +  -  +  - ]:         312 :          symbols(ia) = trim(symbols(ia))//trim(powerchar)
    1215                 :         312 :          jj=jj+1
    1216                 :             :        end if
    1217                 :             :      end do
    1218                 :             :    end if
    1219                 :             :  end do
    1220                 :             : 
    1221                 :         104 : end subroutine symbols_crystal
    1222                 :             : !!***
    1223                 :             : 
    1224                 :             : !----------------------------------------------------------------------
    1225                 :             : 
    1226                 :             : !!****f* m_crystal/idx_spatial_inversion
    1227                 :             : !! NAME
    1228                 :             : !!  idx_spatial_inversion
    1229                 :             : !!
    1230                 :             : !! FUNCTION
    1231                 :             : !!  Return the index of the spatial inversion, 0 if not present
    1232                 :             : !!
    1233                 :             : !! SOURCE
    1234                 :             : 
    1235                 :          18 : pure integer function idx_spatial_inversion(Cryst) result(inv_idx)
    1236                 :             : 
    1237                 :             : !Arguments ------------------------------------
    1238                 :             :  class(crystal_t),intent(in) :: Cryst
    1239                 :             : 
    1240                 :             : !Local variables-------------------------------
    1241                 :             :  integer :: isym
    1242                 :             : ! *************************************************************************
    1243                 :             : 
    1244                 :          18 :  inv_idx=0
    1245         [ +  + ]:         427 :  do isym=1,cryst%nsym
    1246   [ +  +  +  +  :         677 :    if (all(cryst%symrel(:,:,isym) == inversion_3d)) then
             +  +  +  + ]
    1247                 :          18 :     inv_idx=isym; return
    1248                 :             :    end if
    1249                 :             :  end do
    1250                 :             : 
    1251                 :             : end function idx_spatial_inversion
    1252                 :             : !!***
    1253                 :             : 
    1254                 :             : !----------------------------------------------------------------------
    1255                 :             : 
    1256                 :             : !!****f* m_crystal/isymmorphic
    1257                 :             : !! NAME
    1258                 :             : !!  isymmorphic
    1259                 :             : !!
    1260                 :             : !! FUNCTION
    1261                 :             : !!  Returns .TRUE. if space group is symmorphic, i.e. all fractional translations are zero.
    1262                 :             : !!
    1263                 :             : !! SOURCE
    1264                 :             : 
    1265                 :       18751 : pure logical function isymmorphic(Cryst) result(ans)
    1266                 :             : 
    1267                 :             : !Arguments ------------------------------------
    1268                 :             :  class(crystal_t),intent(in) :: Cryst
    1269                 :             : ! *************************************************************************
    1270                 :             : 
    1271   [ +  +  +  +  :     1032775 :  ans = ALL(ABS(Cryst%tnons) < tol6)
                   +  + ]
    1272                 :             : 
    1273                 :       18751 : end function isymmorphic
    1274                 :             : !!***
    1275                 :             : 
    1276                 :             : !----------------------------------------------------------------------
    1277                 :             : 
    1278                 :             : !!****f* m_crystal/isalchemical
    1279                 :             : !! NAME
    1280                 :             : !!  isalchemical
    1281                 :             : !!
    1282                 :             : !! FUNCTION
    1283                 :             : !!  Returns .TRUE. if we are using alchemical pseudopotentials
    1284                 :             : !!
    1285                 :             : !! SOURCE
    1286                 :             : 
    1287                 :       18751 : pure logical function isalchemical(Cryst) result(ans)
    1288                 :             : 
    1289                 :             : !Arguments ------------------------------------
    1290                 :             :  class(crystal_t),intent(in) :: Cryst
    1291                 :             : ! *************************************************************************
    1292                 :             : 
    1293                 :       18751 :  ans = (Cryst%npsp /= Cryst%ntypat)
    1294                 :             : 
    1295                 :       18751 : end function isalchemical
    1296                 :             : !!***
    1297                 :             : 
    1298                 :             : !----------------------------------------------------------------------
    1299                 :             : 
    1300                 :             : !!****f* m_crystal/adata_type
    1301                 :             : !! NAME
    1302                 :             : !!  adata_type
    1303                 :             : !!
    1304                 :             : !! FUNCTION
    1305                 :             : !!  Return atomic data from the itypat index
    1306                 :             : !!
    1307                 :             : !! SOURCE
    1308                 :             : 
    1309                 :       18655 : type(atomdata_t) function adata_type(crystal, itypat) result(atom)
    1310                 :             : 
    1311                 :             : !Arguments ------------------------------------
    1312                 :             :  class(crystal_t),intent(in) :: crystal
    1313                 :             :  integer,intent(in) :: itypat
    1314                 :             : ! *************************************************************************
    1315                 :             : 
    1316                 :       18655 :  call atomdata_from_znucl(atom, crystal%znucl(itypat))
    1317                 :             : 
    1318                 :       18655 : end function adata_type
    1319                 :             : !!***
    1320                 :             : 
    1321                 :             : !----------------------------------------------------------------------
    1322                 :             : 
    1323                 :             : !!****f* m_crystal/symbol_type
    1324                 :             : !! NAME
    1325                 :             : !!  symbol_type
    1326                 :             : !!
    1327                 :             : !! FUNCTION
    1328                 :             : !!  Return the atomic symbol from the itypat index
    1329                 :             : !!
    1330                 :             : !! SOURCE
    1331                 :             : 
    1332                 :       18655 : function symbol_type(crystal, itypat) result(symbol)
    1333                 :             : 
    1334                 :             : !Arguments ------------------------------------
    1335                 :             : !scalars
    1336                 :             :  class(crystal_t),intent(in) :: crystal
    1337                 :             :  integer,intent(in) :: itypat
    1338                 :             :  character(len=2) :: symbol
    1339                 :             : 
    1340                 :             : !Local variables-------------------------------
    1341                 :             :  type(atomdata_t) :: atom
    1342                 :             : ! *************************************************************************
    1343                 :             : 
    1344                 :       18655 :  atom = crystal%adata_type(itypat)
    1345                 :       18655 :  symbol = atom%symbol
    1346                 :             : 
    1347                 :       18655 : end function symbol_type
    1348                 :             : !!***
    1349                 :             : 
    1350                 :             : !----------------------------------------------------------------------
    1351                 :             : 
    1352                 :             : !!****f* m_crystal/symbol_iatom
    1353                 :             : !! NAME
    1354                 :             : !!  symbol_iatom
    1355                 :             : !!
    1356                 :             : !! FUNCTION
    1357                 :             : !!  Return the atomic symbol from the iatom index
    1358                 :             : !!
    1359                 :             : !! SOURCE
    1360                 :             : 
    1361                 :       15620 : function symbol_iatom(crystal, iatom) result(symbol)
    1362                 :             : 
    1363                 :             : !Arguments ------------------------------------
    1364                 :             : !scalars
    1365                 :             :  class(crystal_t),intent(in) :: crystal
    1366                 :             :  integer,intent(in) :: iatom
    1367                 :             :  character(len=2) :: symbol
    1368                 :             : ! *************************************************************************
    1369                 :             : 
    1370                 :       15620 :  symbol = crystal%symbol_type(crystal%typat(iatom))
    1371                 :             : 
    1372                 :       15620 : end function symbol_iatom
    1373                 :             : !!***
    1374                 :             : 
    1375                 :             : !----------------------------------------------------------------------
    1376                 :             : 
    1377                 :             : !!****f* m_crystal/crystal_point_group
    1378                 :             : !! NAME
    1379                 :             : !!  crystal_point_group
    1380                 :             : !!
    1381                 :             : !! FUNCTION
    1382                 :             : !!  Return the symmetries of the point group of the crystal.
    1383                 :             : !!
    1384                 :             : !! INPUTS
    1385                 :             : !!  [include_timrev]=If True, time-reversal symmetry is included in the point group unless
    1386                 :             : !!    the system has spatial inversion. Default: False
    1387                 :             : !!
    1388                 :             : !! OUTPUT
    1389                 :             : !!  ptg_nsym=Number of symmetries in the point group
    1390                 :             : !!  ptg_symrel(3,3,ptg_nsym)=Rotations in real space
    1391                 :             : !!  ptg_symrec(3,3,ptg_nsym)=Rotations in reciprocal space
    1392                 :             : !!  has_inversion=True if spatial inversion is present in the point group.
    1393                 :             : !!
    1394                 :             : !! SOURCE
    1395                 :             : 
    1396                 :           7 : subroutine crystal_point_group(cryst, ptg_nsym, ptg_symrel, ptg_symrec, has_inversion, include_timrev)
    1397                 :             : 
    1398                 :             : !Arguments ------------------------------------
    1399                 :             : !scalars
    1400                 :             :  class(crystal_t),intent(in) :: cryst
    1401                 :             :  integer,intent(out) :: ptg_nsym
    1402                 :             :  logical,intent(out) :: has_inversion
    1403                 :             :  logical,optional,intent(in) :: include_timrev
    1404                 :             : !arrays
    1405                 :             :  integer,allocatable,intent(out) :: ptg_symrel(:,:,:),ptg_symrec(:,:,:)
    1406                 :             : 
    1407                 :             : !Local variables-------------------------------
    1408                 :             : !scalars
    1409                 :             :  integer :: isym, search, tmp_nsym, ierr
    1410                 :             :  logical :: found, my_include_timrev, debug
    1411                 :             : !arrays
    1412                 :          14 :  integer :: work_symrel(3,3,cryst%nsym)
    1413                 :           7 :  integer,allocatable :: symafm(:)
    1414                 :             : ! *************************************************************************
    1415                 :             : 
    1416         [ +  - ]:           7 :  my_include_timrev = .False.; if (present(include_timrev)) my_include_timrev = include_timrev
    1417                 :             : 
    1418   [ +  +  +  + ]:          91 :  tmp_nsym = 1; work_symrel(:,:,1) = cryst%symrel(:,:,1)
    1419         [ +  + ]:         336 :  do isym=2,cryst%nsym
    1420         [ +  - ]:         329 :    if (cryst%symafm(isym) == -1) cycle
    1421         [ +  + ]:        8225 :    do search=1,tmp_nsym
    1422   [ +  -  +  +  :       12978 :      found = all(work_symrel(:,:,search) == cryst%symrel(:,:,isym))
                   +  + ]
    1423         [ +  - ]:        8225 :      if (found) exit
    1424                 :             :    end do
    1425         [ +  - ]:         336 :    if (.not. found) then
    1426                 :         329 :      tmp_nsym = tmp_nsym + 1
    1427   [ +  +  +  + ]:        4277 :      work_symrel(:,:,tmp_nsym) = cryst%symrel(:,:,isym)
    1428                 :             :    end if
    1429                 :             :  end do
    1430                 :             : 
    1431                 :           7 :  has_inversion = .False.
    1432         [ +  - ]:          14 :  do isym=1,tmp_nsym
    1433   [ +  +  +  +  :          98 :    if (all(work_symrel(:,:,isym) == inversion_3d) ) then
             +  +  +  + ]
    1434                 :           7 :      has_inversion = .True.; exit
    1435                 :             :    end if
    1436                 :             :  end do
    1437                 :             : 
    1438                 :             :  ! Now we know the symmetries of the point group.
    1439   [ -  +  -  - ]:           7 :  ptg_nsym = tmp_nsym; if (.not. has_inversion .and. my_include_timrev) ptg_nsym = 2 * tmp_nsym
    1440   [ -  +  +  -  :          21 :  ABI_MALLOC(ptg_symrel, (3, 3, ptg_nsym))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1441   [ -  +  +  -  :          14 :  ABI_MALLOC(ptg_symrec, (3, 3, ptg_nsym))
          -  +  -  +  -  
                      + ]
    1442                 :             : 
    1443   [ +  +  +  +  :        4375 :  ptg_symrel(:,:,1:tmp_nsym) = work_symrel(:,:,1:tmp_nsym)
                   +  + ]
    1444         [ +  + ]:         343 :  do isym=1,tmp_nsym
    1445                 :         343 :    call mati3inv(ptg_symrel(:,:,isym), ptg_symrec(:,:,isym))
    1446                 :             :  end do
    1447                 :             : 
    1448   [ -  +  -  - ]:           7 :  if (.not. has_inversion .and. my_include_timrev) then
    1449   [ #  #  #  #  :           0 :    ptg_symrel(:,:,tmp_nsym+1:) = -work_symrel(:,:,1:tmp_nsym)
                   #  # ]
    1450         [ #  # ]:           0 :    do isym=tmp_nsym+1,ptg_nsym
    1451                 :           0 :      call mati3inv(ptg_symrel(:,:,isym), ptg_symrec(:,:,isym))
    1452                 :             :    end do
    1453                 :             :  end if
    1454                 :             : 
    1455                 :           7 :  debug = .False.
    1456                 :             :  if (debug) then
    1457                 :             :    ABI_MALLOC(symafm, (ptg_nsym))
    1458                 :             :    symafm = 1
    1459                 :             :    call sg_multable(ptg_nsym, symafm, ptg_symrel, ierr)
    1460                 :             :    ABI_CHECK(ierr == 0, "point group is not a group! See messages above")
    1461                 :             :    ABI_FREE(symafm)
    1462                 :             :  end if
    1463                 :             : 
    1464                 :           7 : end subroutine crystal_point_group
    1465                 :             : !!***
    1466                 :             : 
    1467                 :             : !----------------------------------------------------------------------
    1468                 :             : 
    1469                 :             : !!****f* m_crystal/crystal_ncwrite
    1470                 :             : !! NAME
    1471                 :             : !! crystal_ncwrite
    1472                 :             : !!
    1473                 :             : !! FUNCTION
    1474                 :             : !! Output system geometry to a file, using the NETCDF file format and ETSF I/O.
    1475                 :             : !! Data are taken from the crystal_t object.
    1476                 :             : !!
    1477                 :             : !! INPUTS
    1478                 :             : !!  cryst<crystal_t>=Object defining the unit cell and its symmetries.
    1479                 :             : !!  ncid=NC file handle.
    1480                 :             : !!
    1481                 :             : !! OUTPUT
    1482                 :             : !!  Only writing
    1483                 :             : !!
    1484                 :             : !! NOTES
    1485                 :             : !!  Alchemy not treated, since crystal should be initialized at the beginning of the run.
    1486                 :             : !!
    1487                 :             : !! SOURCE
    1488                 :             : 
    1489                 :       18751 : integer function crystal_ncwrite(cryst, ncid) result(ncerr)
    1490                 :             : 
    1491                 :             : !Arguments ------------------------------------
    1492                 :             : !scalars
    1493                 :             :  class(crystal_t),intent(in) :: cryst
    1494                 :             :  integer,intent(in) :: ncid
    1495                 :             : 
    1496                 :             : !Local variables-------------------------------
    1497                 :             : !scalars
    1498                 :             :  integer :: itypat
    1499                 :             :  character(len=500) :: msg
    1500                 :             :  character(len=etsfio_charlen) :: symmorphic
    1501                 :             :  type(atomdata_t) :: atom
    1502                 :             : !arrays
    1503                 :       37502 :  character(len=2) :: symbols(cryst%ntypat)
    1504                 :       37502 :  character(len=80) :: psp_desc(cryst%ntypat),symbols_long(cryst%ntypat)
    1505                 :             : ! *************************************************************************
    1506                 :             : 
    1507                 :             :  ! TODO alchemy not treated correctly by ETSF_IO specs.
    1508         [ +  + ]:       18751 :  if (cryst%isalchemical()) then
    1509                 :             :    write(msg,"(3a)")&
    1510                 :          70 :     "Alchemical crystals are not fully supported by the netcdf format",ch10,&
    1511                 :         140 :     "Important parameters (e.g. znucl, symbols) are not written with the correct value"
    1512                 :          70 :    ABI_WARNING(msg)
    1513                 :             :  end if
    1514                 :             : 
    1515                 :       18751 :  symmorphic = yesno(cryst%isymmorphic())
    1516                 :             : 
    1517                 :             :  ! Define dimensions.
    1518                 :             :  ! npsp added in v9.
    1519                 :             :  ncerr = nctk_def_dims(ncid, [ &
    1520                 :             :    nctkdim_t("complex", 2), nctkdim_t("symbol_length", 2),&
    1521                 :             :    nctkdim_t("character_string_length", 80), nctkdim_t("number_of_cartesian_directions", 3),&
    1522                 :             :    nctkdim_t("number_of_reduced_dimensions", 3), nctkdim_t("number_of_vectors", 3),&
    1523                 :             :    nctkdim_t("number_of_atoms", cryst%natom), nctkdim_t("number_of_atom_species", cryst%ntypat),&
    1524                 :             :    nctkdim_t("number_of_atom_pseudopotentials", cryst%npsp),&
    1525         [ +  + ]:      206261 :    nctkdim_t("number_of_symmetry_operations", cryst%nsym)], defmode=.True.)
    1526         [ -  + ]:       18751 :  NCF_CHECK(ncerr)
    1527                 :             : 
    1528                 :             :  ! Define variables
    1529                 :             :  ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: &
    1530         [ +  + ]:       75004 :     "space_group", "time_reversal", "use_antiferromagnetic_symmetries"])
    1531         [ -  + ]:       18751 :  NCF_CHECK(ncerr)
    1532                 :             : 
    1533                 :             :  ncerr = nctk_def_arrays(ncid, [ &
    1534                 :             :   ! Atomic structure and symmetry operations
    1535                 :             :   nctkarr_t("primitive_vectors", "dp", "number_of_cartesian_directions, number_of_vectors"), &
    1536                 :             :   nctkarr_t("reduced_symmetry_matrices", "int", &
    1537                 :             :     "number_of_reduced_dimensions, number_of_reduced_dimensions, number_of_symmetry_operations"), &
    1538                 :             :   nctkarr_t("reduced_symmetry_translations", "dp", "number_of_reduced_dimensions, number_of_symmetry_operations"), &
    1539                 :             :   nctkarr_t("atom_species", "int", "number_of_atoms"), &
    1540                 :             :   nctkarr_t("reduced_atom_positions", "dp", "number_of_reduced_dimensions, number_of_atoms"), &
    1541                 :             :   nctkarr_t("atomic_numbers", "dp", "number_of_atom_species"), &
    1542                 :             :   nctkarr_t("atom_species_names", "char", "character_string_length, number_of_atom_species"), &
    1543                 :             :   nctkarr_t("chemical_symbols", "char", "symbol_length, number_of_atom_species"), &
    1544                 :             :   nctkarr_t('atomic_mass_units', "dp", "number_of_atom_species"), &
    1545                 :             :   ! Atomic information.
    1546                 :             :   nctkarr_t("valence_charges", "dp", "number_of_atom_species"), &  ! NB: This variable is not written if alchemical
    1547                 :             :   nctkarr_t("pseudopotential_types", "char", "character_string_length, number_of_atom_species") &
    1548         [ +  + ]:      225012 :  ])
    1549         [ -  + ]:       18751 :  NCF_CHECK(ncerr)
    1550                 :             : 
    1551                 :             :  ! Some variables require the "symmorphic" attribute.
    1552         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_att(ncid, vid("reduced_symmetry_matrices"), "symmorphic", symmorphic))
    1553         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_att(ncid, vid("reduced_symmetry_translations"), "symmorphic", symmorphic))
    1554                 :             : 
    1555                 :             :  ! At this point we have an ETSF-compliant file. Add additional data for internal use in abinit.
    1556                 :             :  ncerr = nctk_def_arrays(ncid, [ &
    1557                 :             :    nctkarr_t('symafm', "int", "number_of_symmetry_operations"), &
    1558                 :             :    nctkarr_t('symrel_cart', "dp", "three, three, number_of_symmetry_operations"), &
    1559                 :             :    nctkarr_t('indsym', "int", "four, number_of_symmetry_operations, number_of_atoms") &
    1560         [ +  + ]:       75004 :  ])
    1561         [ -  + ]:       18751 :  NCF_CHECK(ncerr)
    1562                 :             : 
    1563                 :             :  ! Set-up atomic symbols.
    1564         [ +  + ]:       42963 :  do itypat=1,cryst%ntypat
    1565                 :       24212 :    call atomdata_from_znucl(atom, cryst%znucl(itypat))
    1566                 :       24212 :    symbols(itypat) = atom%symbol
    1567                 :       24212 :    write(symbols_long(itypat),'(a2,a78)') symbols(itypat),REPEAT(CHAR(0),78)
    1568                 :             :    write(psp_desc(itypat),'(2a)') &
    1569         [ +  + ]:      800703 :      cryst%title(itypat)(1:MIN(80,LEN_TRIM(cryst%title(itypat)))),REPEAT(CHAR(0),MAX(0,80-LEN_TRIM(cryst%title(itypat))))
    1570                 :             :  end do
    1571                 :             : 
    1572                 :             :  ! Write data.
    1573         [ -  + ]:       18751 :  NCF_CHECK(nctk_set_datamode(ncid))
    1574         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("space_group"), cryst%space_group))
    1575         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("primitive_vectors"), cryst%rprimd))
    1576         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("reduced_symmetry_matrices"), cryst%symrel))
    1577         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("reduced_symmetry_translations"), cryst%tnons))
    1578         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("atom_species"), cryst%typat))
    1579         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("reduced_atom_positions"), cryst%xred))
    1580         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("atomic_numbers"), cryst%znucl(1:cryst%ntypat)))
    1581         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("atom_species_names"), symbols_long))
    1582         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("chemical_symbols"), symbols))
    1583         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid('atomic_mass_units'), cryst%amu))
    1584         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("pseudopotential_types"), psp_desc))
    1585         [ +  + ]:       18751 :  if (cryst%npsp == cryst%ntypat) then
    1586         [ -  + ]:       18681 :    NCF_CHECK(nf90_put_var(ncid, vid("valence_charges"), cryst%zion))
    1587                 :             :  end if
    1588                 :             : 
    1589         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("symafm"), cryst%symafm))
    1590         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("symrel_cart"), cryst%symrel_cart))
    1591         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("indsym"), cryst%indsym))
    1592                 :             : 
    1593                 :             : ! Variables pertaining to the symmetry of the wavefunctions.
    1594                 :             : ! Note that these variables will be used in crystal_compare
    1595         [ -  + ]:       18751 :  NCF_CHECK(nf90_put_var(ncid, vid("time_reversal"), cryst%timrev))
    1596                 :             : 
    1597         [ +  + ]:       18751 :  if (cryst%use_antiferro) then
    1598         [ -  + ]:         119 :     NCF_CHECK(nf90_put_var(ncid, vid("use_antiferromagnetic_symmetries"), 1))
    1599                 :             :  else
    1600         [ -  + ]:       18632 :     NCF_CHECK(nf90_put_var(ncid, vid("use_antiferromagnetic_symmetries"), 0))
    1601                 :             :  end if
    1602                 :             : 
    1603                 :             : contains
    1604                 :      356199 :  integer function vid(vname)
    1605                 :             :    character(len=*),intent(in) :: vname
    1606                 :      356199 :    vid = nctk_idname(ncid, vname)
    1607                 :             :  end function vid
    1608                 :             : 
    1609                 :             : end function crystal_ncwrite
    1610                 :             : !!***
    1611                 :             : 
    1612                 :             : !----------------------------------------------------------------------
    1613                 :             : 
    1614                 :             : !!****f* m_crystal/crystal_ncwrite_path
    1615                 :             : !! NAME
    1616                 :             : !! crystal_ncwrite_path
    1617                 :             : !!
    1618                 :             : !! FUNCTION
    1619                 :             : !! Output system geometry to a file, using the NETCDF file format and ETSF I/O.
    1620                 :             : !!
    1621                 :             : !! INPUTS
    1622                 :             : !!  crystal<crystal_t>=Object defining the unit cell and its symmetries.
    1623                 :             : !!  path=filename
    1624                 :             : !!
    1625                 :             : !! OUTPUT
    1626                 :             : !!  Only writing
    1627                 :             : !!
    1628                 :             : !! SOURCE
    1629                 :             : 
    1630                 :           0 : integer function crystal_ncwrite_path(crystal, path) result(ncerr)
    1631                 :             : 
    1632                 :             : !Arguments ------------------------------------
    1633                 :             : !scalars
    1634                 :             :  character(len=*),intent(in) :: path
    1635                 :             :  class(crystal_t),intent(in) :: crystal
    1636                 :             : 
    1637                 :             : !Local variables-------------------------------
    1638                 :             :  integer :: ncid
    1639                 :             : ! *************************************************************************
    1640                 :             : 
    1641                 :           0 :  ncerr = nf90_noerr
    1642         [ #  # ]:           0 :  if (file_exists(path)) then
    1643         [ #  # ]:           0 :    NCF_CHECK(nctk_open_modify(ncid, path, xmpi_comm_self))
    1644                 :             :  else
    1645                 :           0 :    ncerr = nctk_open_create(ncid, path, xmpi_comm_self)
    1646         [ #  # ]:           0 :    NCF_CHECK_MSG(ncerr, sjoin("creating:", path))
    1647                 :             :  end if
    1648                 :             : 
    1649         [ #  # ]:           0 :  NCF_CHECK(crystal_ncwrite(crystal, ncid))
    1650         [ #  # ]:           0 :  NCF_CHECK(nf90_close(ncid))
    1651                 :             : 
    1652                 :           0 : end function crystal_ncwrite_path
    1653                 :             : !!***
    1654                 :             : 
    1655                 :             : !----------------------------------------------------------------------
    1656                 :             : 
    1657                 :             : !!****f* m_crystal/crystal_ncread
    1658                 :             : !! NAME
    1659                 :             : !! crystal_ncread
    1660                 :             : !!
    1661                 :             : !! FUNCTION
    1662                 :             : !! Read the crystal object from a NETCDF file.
    1663                 :             : !!
    1664                 :             : !! INPUTS
    1665                 :             : !!  cryst<crystal_t>=Object defining the unit cell and its symmetries.
    1666                 :             : !!  ncid=NC file handle.
    1667                 :             : !!
    1668                 :             : !! OUTPUT
    1669                 :             : !!  crystal
    1670                 :             : !!
    1671                 :             : !! SOURCE
    1672                 :             : 
    1673                 :         401 : subroutine crystal_ncread(cryst, ncid)
    1674                 :             : 
    1675                 :             : !Arguments ------------------------------------
    1676                 :             : !scalars
    1677                 :             :  class(crystal_t),intent(inout) :: cryst
    1678                 :             :  integer,intent(in) :: ncid
    1679                 :             : 
    1680                 :             : !Local variables ------------------------------------
    1681                 :             :  integer :: use_antiferro
    1682                 :             : ! *************************************************************************
    1683                 :             : 
    1684                 :             :  ! ---------------
    1685                 :             :  ! Read dimensions
    1686                 :             :  ! ---------------
    1687         [ -  + ]:         401 :  NCF_CHECK(nctk_get_dim(ncid, "number_of_atoms", cryst%natom))
    1688         [ -  + ]:         401 :  NCF_CHECK(nctk_get_dim(ncid, "number_of_atom_species", cryst%ntypat))
    1689         [ -  + ]:         401 :  NCF_CHECK(nctk_get_dim(ncid, "number_of_atom_pseudopotentials", cryst%npsp))
    1690         [ -  + ]:         401 :  NCF_CHECK(nctk_get_dim(ncid, "number_of_symmetry_operations", cryst%nsym))
    1691                 :             : 
    1692                 :             :  ! ---------------
    1693                 :             :  ! Allocate memory
    1694                 :             :  ! ---------------
    1695                 :         401 :  call cryst%malloc()
    1696                 :             : 
    1697                 :             :  ! ------------
    1698                 :             :  ! read scalars
    1699                 :             :  ! ------------
    1700         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "space_group"), cryst%space_group))
    1701         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "time_reversal"), cryst%timrev))
    1702         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "use_antiferromagnetic_symmetries"), use_antiferro))
    1703                 :         401 :  cryst%use_antiferro = .False.
    1704         [ -  + ]:         401 :  if (use_antiferro /= 0) cryst%use_antiferro = .True.
    1705                 :             : 
    1706                 :             :  ! -----------
    1707                 :             :  ! read arrays
    1708                 :             :  ! -----------
    1709         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "primitive_vectors"), cryst%rprimd))
    1710         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "reduced_symmetry_matrices"), cryst%symrel))
    1711         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "reduced_symmetry_translations"), cryst%tnons))
    1712         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "atom_species"), cryst%typat))
    1713         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "reduced_atom_positions"), cryst%xred))
    1714         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "atomic_numbers"), cryst%znucl(1:cryst%ntypat)))
    1715         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "atomic_mass_units"), cryst%amu))
    1716         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "symafm"), cryst%symafm))
    1717         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "symrel_cart"), cryst%symrel_cart))
    1718         [ -  + ]:         401 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "indsym"), cryst%indsym))
    1719                 :             : 
    1720         [ +  - ]:         401 :  if (cryst%npsp == cryst%ntypat) then
    1721         [ -  + ]:         401 :    NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "valence_charges"), cryst%zion))
    1722                 :             :  end if
    1723                 :             : 
    1724                 :             :  ! Ignore those
    1725                 :             :  !NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "pseudopotential_types"), psp_desc))
    1726                 :             :  !NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "atom_species_names"), symbols_long))
    1727                 :             :  !NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "chemical_symbols"), symbols))
    1728                 :             : 
    1729                 :             :  ! -----------------------
    1730                 :             :  ! Complete initialization
    1731                 :             :  ! -----------------------
    1732                 :             : 
    1733                 :         401 :  call cryst%compute_geometry()
    1734                 :         401 :  call cryst%index_atoms()
    1735                 :         401 :  call cryst%compute_sym()
    1736                 :             : 
    1737                 :         401 : end subroutine crystal_ncread
    1738                 :             : !!***
    1739                 :             : 
    1740                 :             : !----------------------------------------------------------------------
    1741                 :             : 
    1742                 :             : !!****f* m_crystal/prt_cif
    1743                 :             : !! NAME
    1744                 :             : !! prt_cif
    1745                 :             : !!
    1746                 :             : !! FUNCTION
    1747                 :             : !!   print out CIF format file
    1748                 :             : !!
    1749                 :             : !! INPUTS
    1750                 :             : !!
    1751                 :             : !! OUTPUT
    1752                 :             : !!
    1753                 :             : !! SOURCE
    1754                 :             : 
    1755                 :           4 : subroutine prt_cif(brvltt, ciffname, natom, nsym, ntypat, rprimd, &
    1756                 :           2 :                    spgaxor, spgroup, spgorig, symrel, tnon, typat, xred, znucl)
    1757                 :             : 
    1758                 :             : !Arguments ------------------------------------
    1759                 :             : !scalars
    1760                 :             :  integer,intent(in) :: natom, ntypat, nsym
    1761                 :             :  integer, intent(in) :: brvltt, spgaxor, spgroup, spgorig
    1762                 :             : !arrays
    1763                 :             :  integer, intent(in) :: typat(natom)
    1764                 :             :  integer, intent(in) :: symrel(3,3,nsym)
    1765                 :             :  character(len=*), intent(in) :: ciffname
    1766                 :             :  real(dp), intent(in) :: tnon(3,nsym)
    1767                 :             :  real(dp), intent(in) :: rprimd(3,3)
    1768                 :             :  real(dp), intent(in) :: xred(3,natom)
    1769                 :             :  real(dp), intent(in) :: znucl(ntypat)
    1770                 :             : 
    1771                 :             : !Local variables -------------------------------
    1772                 :             : !scalars
    1773                 :             :  integer :: unitcif, iatom, isym, sporder, itypat, nat_this_type
    1774                 :             :  real(dp) :: ucvol
    1775                 :             :  type(atomdata_t) :: atom
    1776                 :             : !arrays
    1777                 :             :  character(len=80) :: tmpstring
    1778                 :             :  character(len=1) :: brvsb
    1779                 :             :  character(len=15) :: intsb,ptintsb,ptschsb,schsb
    1780                 :             :  character(len=35) :: intsbl
    1781                 :             :  character(len=10) :: str_nat_type
    1782                 :             :  character(len=100) :: chemformula
    1783                 :             :  character(len=500) :: msg
    1784                 :             :  real(dp) :: angle(3), gprimd(3,3), rmet(3,3), gmet(3,3)
    1785                 :             : 
    1786                 :             : !*************************************************************************
    1787                 :             : 
    1788                 :             :  ! open file in append mode xlf and other compilers refuse append mode
    1789         [ -  + ]:           2 :  if (open_file(ciffname,msg,newunit=unitcif) /=0) then
    1790                 :           0 :    ABI_WARNING(msg)
    1791                 :           0 :    return
    1792                 :             :  end if
    1793                 :             : 
    1794                 :             :  ! print title for dataset
    1795                 :           2 :  write (unitcif,'(a)') 'data_set'
    1796                 :             : 
    1797                 :             :  ! print cell parameters a,b,c, angles, volume
    1798                 :           2 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
    1799                 :           2 :  angle(1)=acos(rmet(2,3)/sqrt(rmet(2,2)*rmet(3,3)))/two_pi*360.0_dp
    1800                 :           2 :  angle(2)=acos(rmet(1,3)/sqrt(rmet(1,1)*rmet(3,3)))/two_pi*360.0_dp
    1801                 :           2 :  angle(3)=acos(rmet(1,2)/sqrt(rmet(1,1)*rmet(2,2)))/two_pi*360.0_dp
    1802                 :             : 
    1803                 :           2 :  write (unitcif,'(a,E20.10)') '_cell_length_a                     ', sqrt(rmet(1,1))*Bohr_Ang
    1804                 :           2 :  write (unitcif,'(a,E20.10)') '_cell_length_b                     ', sqrt(rmet(2,2))*Bohr_Ang
    1805                 :           2 :  write (unitcif,'(a,E20.10)') '_cell_length_c                     ', sqrt(rmet(3,3))*Bohr_Ang
    1806                 :           2 :  write (unitcif,'(a,E20.10)') '_cell_angle_alpha                  ', angle(1)
    1807                 :           2 :  write (unitcif,'(a,E20.10)') '_cell_angle_beta                   ', angle(2)
    1808                 :           2 :  write (unitcif,'(a,E20.10)') '_cell_angle_gamma                  ', angle(3)
    1809                 :           2 :  write (unitcif,'(a,E20.10)') '_cell_volume                       ', ucvol*(Bohr_Ang)**3
    1810                 :             : 
    1811                 :             :  ! print reduced positions
    1812                 :           2 :  write (unitcif,'(a)') 'loop_'
    1813                 :           2 :  write (unitcif,'(a,E20.10)') '  _atom_site_label                   '
    1814                 :           2 :  write (unitcif,'(a,E20.10)') '  _atom_site_fract_x                 '
    1815                 :           2 :  write (unitcif,'(a,E20.10)') '  _atom_site_fract_y                 '
    1816                 :           2 :  write (unitcif,'(a,E20.10)') '  _atom_site_fract_z                 '
    1817         [ +  + ]:           5 :  do iatom = 1, natom
    1818                 :           3 :    call atomdata_from_znucl(atom,znucl(typat(iatom)))
    1819                 :           5 :    write (unitcif,'(2a,3E20.10)') '  ', atom%symbol, xred(:,iatom)
    1820                 :             :  end do
    1821                 :             : 
    1822                 :             : !other specs in CIF dictionary which may be useful:
    1823                 :             : !GEOM_BOND GEOM_ANGLE GEOM_TORSION
    1824                 :             : 
    1825                 :             :  ! print chemical composition in simplest form
    1826                 :           2 :  chemformula = "'"
    1827         [ +  + ]:           4 :  do itypat = 1, ntypat
    1828                 :           2 :    nat_this_type = 0
    1829         [ +  + ]:           5 :    do iatom = 1, natom
    1830         [ +  - ]:           5 :      if (typat(iatom) == itypat) nat_this_type = nat_this_type+1
    1831                 :             :    end do
    1832                 :           2 :    call atomdata_from_znucl(atom,znucl(itypat))
    1833                 :           2 :    call int2char10(nat_this_type, str_nat_type)
    1834         [ +  - ]:           6 :    chemformula = trim(chemformula) // atom%symbol // trim(str_nat_type) // "  "
    1835                 :             :  end do
    1836         [ +  - ]:           2 :  chemformula = trim(chemformula) // "'"
    1837                 :           2 :  write (unitcif,'(2a)') '_chemical_formula_analytical              ', chemformula
    1838                 :             : 
    1839                 :             :  !FIXME: check that brvltt is correctly used here - is it equal to bravais(1) in the invars routines?
    1840   [ -  -  -  -  :           2 :  if (brvltt==1) then
             -  -  -  + ]
    1841                 :           0 :    write (unitcif,'(a)') '_symmetry_cell_setting             triclinic'
    1842                 :             :  else if(brvltt==2)then
    1843                 :           0 :    write (unitcif,'(a)') '_symmetry_cell_setting             monoclinic'
    1844                 :             :  else if(brvltt==3)then
    1845                 :           0 :    write (unitcif,'(a)') '_symmetry_cell_setting             orthorhombic'
    1846                 :             :  else if(brvltt==4)then
    1847                 :           0 :    write (unitcif,'(a)') '_symmetry_cell_setting             tetragonal'
    1848                 :             :  else if(brvltt==5)then
    1849                 :           0 :    write (unitcif,'(a)') '_symmetry_cell_setting             rhombohedral'
    1850                 :             :  else if(brvltt==6)then
    1851                 :           0 :    write (unitcif,'(a)') '_symmetry_cell_setting             hexagonal'
    1852                 :             :  else if(brvltt==7)then
    1853                 :           0 :    write (unitcif,'(a)') '_symmetry_cell_setting             cubic'
    1854                 :             :  end if
    1855                 :             : 
    1856                 :           2 :  call spgdata(brvsb,intsb,intsbl,ptintsb,ptschsb,schsb,spgaxor,spgroup,sporder,spgorig)
    1857                 :             : 
    1858                 :             :  ! print symmetry operations
    1859                 :           2 :  write (unitcif,'(a,I6)') "_symmetry_Int_Tables_number          ", spgroup
    1860                 :           2 :  write (unitcif,'(5a)') "_symmetry_space_group_name_H-M        '", brvsb, " ", trim(intsb), "'"
    1861                 :           2 :  write (unitcif,'(a)') ''
    1862                 :           2 :  write (unitcif,'(a)') 'loop_'
    1863                 :           2 :  write (unitcif,'(a)') '  _symmetry_equiv_pos_as_xyz           '
    1864         [ +  + ]:          74 :  do isym = 1, nsym
    1865                 :          72 :    call  symrel2string(symrel(:,:,isym), tnon(:,isym), tmpstring)
    1866                 :          74 :    write (unitcif,'(2a)') '  ', trim(tmpstring)
    1867                 :             :  end do
    1868                 :             : 
    1869                 :           2 :  close(unitcif)
    1870                 :             : 
    1871                 :             : end subroutine prt_cif
    1872                 :             : !!***
    1873                 :             : 
    1874                 :             : !!****f* m_crystal/symrel2string
    1875                 :             : !! NAME
    1876                 :             : !! symrel2string
    1877                 :             : !!
    1878                 :             : !! FUNCTION
    1879                 :             : !!
    1880                 :             : !! INPUTS
    1881                 :             : !!
    1882                 :             : !! OUTPUT
    1883                 :             : !!
    1884                 :             : !! NOTES
    1885                 :             : !!
    1886                 :             : !! SOURCE
    1887                 :             : 
    1888                 :          72 : subroutine symrel2string(symrel1, tnon, string)
    1889                 :             : 
    1890                 :             : !Arguments ------------------------------------
    1891                 :             : !scalars
    1892                 :             :  integer, intent(in) :: symrel1(3,3)
    1893                 :             :  real(dp), intent(in) :: tnon(3)
    1894                 :             :  character(len=80), intent(out) :: string
    1895                 :             : 
    1896                 :             : !Local variables -------------------------
    1897                 :             : !scalars
    1898                 :             :  integer :: i1,i2
    1899                 :             :  character(len=1) :: xyz(3)
    1900                 :             : 
    1901                 :             : ! *********************************************************************
    1902                 :             : 
    1903                 :          72 :  xyz(1) = 'x'
    1904                 :          72 :  xyz(2) = 'y'
    1905                 :          72 :  xyz(3) = 'z'
    1906                 :             : 
    1907                 :          72 :  string = ''
    1908         [ +  + ]:         288 :  do i1=1,3
    1909         [ +  + ]:         216 :    if (abs(tnon(i1)) > tol10) then
    1910                 :             :      ! find fraction 1/n for tnon, otherwise do not know what to print
    1911   [ +  +  +  - ]:          36 :      if (abs(one-two*tnon(i1)) < tol10) string = trim(string)//'1/2'
    1912   [ -  +  -  - ]:          36 :      if (abs(one+two*tnon(i1)) < tol10) string = trim(string)//'-1/2'
    1913                 :             : 
    1914   [ +  +  +  - ]:          36 :      if (abs(one-three*tnon(i1)) < tol10) string = trim(string)//'1/3'
    1915   [ +  +  +  - ]:          36 :      if (abs(one+three*tnon(i1)) < tol10) string = trim(string)//'-1/3'
    1916   [ -  +  -  - ]:          36 :      if (abs(two-three*tnon(i1)) < tol10) string = trim(string)//'2/3'
    1917   [ -  +  -  - ]:          36 :      if (abs(two+three*tnon(i1)) < tol10) string = trim(string)//'-2/3'
    1918                 :             : 
    1919   [ -  +  -  - ]:          36 :      if (abs(one-six*tnon(i1)) < tol10) string = trim(string)//'1/6'
    1920   [ -  +  -  - ]:          36 :      if (abs(one+six*tnon(i1)) < tol10) string = trim(string)//'-1/6'
    1921   [ -  +  -  - ]:          36 :      if (abs(five-six*tnon(i1)) < tol10) string = trim(string)//'5/6'
    1922   [ -  +  -  - ]:          36 :      if (abs(five+six*tnon(i1)) < tol10) string = trim(string)//'-5/6'
    1923                 :             :    end if
    1924         [ +  + ]:         864 :    do i2=1,3
    1925                 :             :      ! FIXME: check if this is correct ordering for symrel(i1,i2) looks ok
    1926   [ +  +  +  - ]:         648 :      if (symrel1(i1,i2) == 1)  string = trim(string)//'+'//xyz(i2)
    1927   [ +  +  +  - ]:         864 :      if (symrel1(i1,i2) == -1) string = trim(string)//'-'//xyz(i2)
    1928                 :             :    end do
    1929   [ +  +  +  - ]:         288 :    if (i1 /= 3) string = trim(string)//','
    1930                 :             :  end do
    1931                 :             : 
    1932                 :          72 : end subroutine symrel2string
    1933                 :             : !!***
    1934                 :             : 
    1935                 :             : !!****f* m_crystal/prtposcar
    1936                 :             : !! NAME
    1937                 :             : !!  prtposcar
    1938                 :             : !!
    1939                 :             : !! FUNCTION
    1940                 :             : !!  output VASP style POSCAR and FORCES files for use with frozen phonon codes, like
    1941                 :             : !!  PHON from Dario Alfe' or frophon
    1942                 :             : !!  IMPORTANT: the order of atoms is fixed such that typat is re-grouped.
    1943                 :             : !!  First typat=1 then typat=2, etc...
    1944                 :             : !!  Only master should call this routine in MPI-mode.
    1945                 :             : !!
    1946                 :             : !! INPUTS
    1947                 :             : !!  fcart = forces on atoms in cartesian coordinates
    1948                 :             : !!  natom = number of atoms
    1949                 :             : !!  ntypat = number of types of atoms
    1950                 :             : !!  rprimd = lattice vectors for the primitive cell
    1951                 :             : !!  typat = type for each of the natom atoms
    1952                 :             : !!  ucvol = unit cell volume
    1953                 :             : !!  xred = reduced positions of the atoms
    1954                 :             : !!  znucl = nuclear charge of each atomic type
    1955                 :             : !!
    1956                 :             : !! OUTPUTS
    1957                 :             : !!   Only files written
    1958                 :             : !!
    1959                 :             : !! SOURCE
    1960                 :             : 
    1961                 :           1 : subroutine prtposcar(fcart, fnameradix, natom, ntypat, rprimd, typat, ucvol, xred, znucl)
    1962                 :             : 
    1963                 :             : !Arguments ------------------------------------
    1964                 :             : !scalars
    1965                 :             :  integer, intent(in) :: natom, ntypat
    1966                 :             :  real(dp), intent(in) :: ucvol
    1967                 :             : !arrays
    1968                 :             :  integer, intent(in) :: typat(natom)
    1969                 :             :  real(dp), intent(in) :: fcart(3,natom)
    1970                 :             :  real(dp), intent(in) :: rprimd(3,3)
    1971                 :             :  real(dp), intent(in) :: xred(3,natom)
    1972                 :             :  real(dp), intent(in) :: znucl(ntypat)
    1973                 :             :  character(len=fnlen), intent(in) :: fnameradix
    1974                 :             : 
    1975                 :             : !Local variables-------------------------------
    1976                 :             : !scalars
    1977                 :             :  integer :: iatom, itypat, iout
    1978                 :             :  character(len=500) :: msg
    1979                 :             : !************************************************************************
    1980                 :             : 
    1981                 :             :  ! Output POSCAR file for positions, atom types etc
    1982         [ -  + ]:           1 :  if (open_file(trim(fnameradix)//"_POSCAR", msg, newunit=iout) /= 0) then
    1983                 :           0 :    ABI_ERROR(msg)
    1984                 :             :  end if
    1985                 :           1 :  call write_poscar_arrays(iout, natom, ntypat, rprimd, typat, ucvol, xred, znucl)
    1986                 :           1 :  close(iout)
    1987                 :             : 
    1988                 :             :  ! output FORCES file for forces in same order as positions above
    1989         [ -  + ]:           1 :  if (open_file(trim(fnameradix)//"_FORCES", msg, newunit=iout) /= 0 ) then
    1990                 :           0 :    ABI_ERROR(msg)
    1991                 :             :  end if
    1992                 :             : 
    1993                 :             :  !ndisplacements
    1994                 :             :  !iatom_displaced displacement_red_coord(3)
    1995                 :             :  !forces_cart_ev_Angstr(3)
    1996                 :             :  !...
    1997                 :             :  !<repeat for other displaced atoms>
    1998                 :           1 :  write(iout,'(I7)') 1
    1999                 :           1 :  write(iout,'(a)') '1 0 0 0        ! TO BE FILLED IN '
    2000         [ +  + ]:           3 :  do itypat=1, ntypat
    2001         [ +  + ]:          21 :    do iatom=1,natom
    2002         [ +  + ]:          18 :      if (typat(iatom) /= itypat) cycle
    2003         [ +  + ]:          47 :      write(iout,'(3(E24.14,1x))') Ha_eV/Bohr_Ang*fcart(:,iatom)
    2004                 :             :    end do
    2005                 :             :  end do
    2006                 :             : 
    2007                 :           1 :  close(iout)
    2008                 :             : 
    2009                 :           1 : end subroutine prtposcar
    2010                 :             : !!***
    2011                 :             : 
    2012                 :             : !----------------------------------------------------------------------
    2013                 :             : 
    2014                 :             : !!****f* m_crystal/write_poscar_arrays
    2015                 :             : !! NAME
    2016                 :             : !!  write_poscar_arrays
    2017                 :             : !!
    2018                 :             : !! FUNCTION
    2019                 :             : !!  Write the structure in the VASP POSCAR format (VASP 5, with the line of atomic symbols) to a unit.
    2020                 :             : !!  Lattice vectors in Angstrom, positions in reduced coordinates (Direct) followed by the element symbol.
    2021                 :             : !!  IMPORTANT: the order of atoms is fixed such that typat is re-grouped.
    2022                 :             : !!  First typat=1 then typat=2, etc...
    2023                 :             : !!
    2024                 :             : !! INPUTS
    2025                 :             : !!  unit = Fortran unit, already opened for formatted output
    2026                 :             : !!  natom = number of atoms
    2027                 :             : !!  ntypat = number of types of atoms
    2028                 :             : !!  rprimd = lattice vectors for the primitive cell
    2029                 :             : !!  typat = type for each of the natom atoms
    2030                 :             : !!  ucvol = unit cell volume
    2031                 :             : !!  xred = reduced positions of the atoms
    2032                 :             : !!  znucl = nuclear charge of each atomic type
    2033                 :             : !!
    2034                 :             : !! SOURCE
    2035                 :             : 
    2036                 :           1 : subroutine write_poscar_arrays(unit, natom, ntypat, rprimd, typat, ucvol, xred, znucl)
    2037                 :             : 
    2038                 :             : !Arguments ------------------------------------
    2039                 :             : !scalars
    2040                 :             :  integer, intent(in) :: unit, natom, ntypat
    2041                 :             :  real(dp), intent(in) :: ucvol
    2042                 :             : !arrays
    2043                 :             :  integer, intent(in) :: typat(natom)
    2044                 :             :  real(dp), intent(in) :: rprimd(3,3)
    2045                 :             :  real(dp), intent(in) :: xred(3,natom)
    2046                 :             :  real(dp), intent(in) :: znucl(ntypat)
    2047                 :             : 
    2048                 :             : !Local variables-------------------------------
    2049                 :             : !scalars
    2050                 :             :  integer :: iatom, itypat
    2051                 :             :  type(atomdata_t) :: atom
    2052                 :             : ! arrays
    2053                 :           1 :  integer :: natoms_this_type(ntypat)
    2054                 :             :  character(len=2) :: symbol
    2055                 :             :  character(len=7) :: natoms_this_type_str
    2056                 :             :  character(len=100) :: chem_formula, natoms_all_types, atomsstring_all_types
    2057                 :             : !************************************************************************
    2058                 :             : 
    2059         [ +  + ]:           3 :  natoms_this_type = 0
    2060         [ +  + ]:           3 :  do itypat=1,ntypat
    2061         [ +  + ]:          21 :    do iatom=1,natom
    2062         [ +  + ]:          20 :      if (typat(iatom) == itypat) natoms_this_type(itypat) = natoms_this_type(itypat) + 1
    2063                 :             :    end do
    2064                 :             :  end do
    2065                 :             : 
    2066                 :           1 :  chem_formula = ""
    2067                 :           1 :  atomsstring_all_types = "  "
    2068         [ +  + ]:           3 :  do itypat=1, ntypat
    2069                 :           2 :    call atomdata_from_znucl(atom, znucl(itypat))
    2070                 :           2 :    symbol = atom%symbol
    2071         [ +  - ]:           2 :    if (natoms_this_type(itypat) < 10) then
    2072                 :           2 :      write(natoms_this_type_str, '(I1)') natoms_this_type(itypat)
    2073         [ #  # ]:           0 :    else if (natoms_this_type(itypat) < 100) then
    2074                 :           0 :      write(natoms_this_type_str, '(I2)') natoms_this_type(itypat)
    2075         [ #  # ]:           0 :    else if (natoms_this_type(itypat) < 1000) then
    2076                 :           0 :      write(natoms_this_type_str, '(I3)') natoms_this_type(itypat)
    2077                 :             :    end if
    2078         [ +  - ]:           2 :    chem_formula = trim(chem_formula) // symbol // trim(natoms_this_type_str)
    2079         [ +  - ]:           5 :    atomsstring_all_types = trim(atomsstring_all_types) // "  " // symbol
    2080                 :             :  end do
    2081                 :             : 
    2082                 :           1 :  write (unit,'(3a,E24.14)') "ABINIT generated POSCAR file. Chemical formula is ",trim(chem_formula), &
    2083                 :           2 :                             "  Volume (AA^3) = ", ucvol*Bohr_Ang*Bohr_Ang*Bohr_Ang
    2084                 :             : 
    2085                 :           1 :  write (unit,'(E10.1)')  1.0_dp
    2086         [ +  + ]:           4 :  write (unit,'(3E24.14,1x)') Bohr_Ang*rprimd(:,1) ! (angstr? bohr?)
    2087         [ +  + ]:           4 :  write (unit,'(3E24.14,1x)') Bohr_Ang*rprimd(:,2)
    2088         [ +  + ]:           4 :  write (unit,'(3E24.14,1x)') Bohr_Ang*rprimd(:,3)
    2089                 :           1 :  write (unit, '(a)') trim(atomsstring_all_types)
    2090                 :             : 
    2091                 :           1 :  natoms_all_types = "   "
    2092         [ +  + ]:           3 :  do itypat=1, ntypat
    2093                 :           2 :    write (natoms_this_type_str, '(I7)') natoms_this_type(itypat)
    2094         [ +  - ]:           3 :    natoms_all_types = trim(natoms_all_types) // "   " // trim(natoms_this_type_str)
    2095                 :             :  end do
    2096                 :             : 
    2097                 :           1 :  write(unit,'(a)') trim(natoms_all_types)
    2098                 :           1 :  write(unit,'(a)') "Direct"
    2099                 :             : 
    2100                 :             :  ! The element symbol after the coordinates is ignored by VASP but used by other readers (e.g. pymatgen, abitk).
    2101         [ +  + ]:           3 :  do itypat=1, ntypat
    2102                 :           2 :    call atomdata_from_znucl(atom, znucl(itypat))
    2103         [ +  + ]:          21 :    do iatom=1,natom
    2104         [ +  + ]:          18 :      if (typat(iatom) /= itypat) cycle
    2105                 :          20 :      write (unit,'(3(E24.14,1x),1x,a)') xred(:,iatom), trim(atom%symbol)
    2106                 :             :    end do
    2107                 :             :  end do
    2108                 :             : 
    2109                 :           1 : end subroutine write_poscar_arrays
    2110                 :             : !!***
    2111                 :             : 
    2112                 :             : !----------------------------------------------------------------------
    2113                 :             : 
    2114                 :             : !!****f* m_crystal/crystal_write_poscar
    2115                 :             : !! NAME
    2116                 :             : !!  crystal_write_poscar
    2117                 :             : !!
    2118                 :             : !! FUNCTION
    2119                 :             : !!  Write the structure in the VASP POSCAR format to a unit, see write_poscar_arrays.
    2120                 :             : !!
    2121                 :             : !! INPUTS
    2122                 :             : !!  unit = Fortran unit, already opened for formatted output
    2123                 :             : !!
    2124                 :             : !! SOURCE
    2125                 :             : 
    2126                 :           0 : subroutine crystal_write_poscar(cryst, unit)
    2127                 :             : 
    2128                 :             : !Arguments ------------------------------------
    2129                 :             :  class(crystal_t),intent(in) :: cryst
    2130                 :             :  integer,intent(in) :: unit
    2131                 :             : !************************************************************************
    2132                 :             : 
    2133                 :           0 :  call write_poscar_arrays(unit, cryst%natom, cryst%ntypat, cryst%rprimd, cryst%typat, cryst%ucvol, cryst%xred, cryst%znucl)
    2134                 :             : 
    2135                 :           0 : end subroutine crystal_write_poscar
    2136                 :             : !!***
    2137                 :             : 
    2138                 :             : !----------------------------------------------------------------------
    2139                 :             : 
    2140                 :             : !!****f* m_crystal/crystal_symmetrize_cart_vec3
    2141                 :             : !! NAME
    2142                 :             : !!  crystal_symmetrize_cart_vec3
    2143                 :             : !!
    2144                 :             : !! FUNCTION
    2145                 :             : !!  Use spatial and time-reversal symmetry (TR) to symmetrize a Cartesian vector of real elements.
    2146                 :             : !!
    2147                 :             : !! INPUTS
    2148                 :             : !!  v(3)=Vector in Cartesian coordinates.
    2149                 :             : !!  time_opt=Prefactor that defines how the vectors transforms under TR. Usually +1 or -1
    2150                 :             : !!      Note that TR is used only if cryst%timrev == 2. time_opt = 0 disables TR for testing purposes.
    2151                 :             : !!
    2152                 :             : !! SOURCE
    2153                 :             : 
    2154         [ -  + ]:        4495 : function crystal_symmetrize_cart_vec3(cryst, v, time_opt) result(vsum)
    2155                 :             : 
    2156                 :             : !Arguments ------------------------------------
    2157                 :             :  class(crystal_t),intent(in) :: cryst
    2158                 :             :  real(dp),intent(in) :: v(3)
    2159                 :             :  integer,intent(in) :: time_opt
    2160                 :             :  real(dp) :: vsum(3)
    2161                 :             : 
    2162                 :             : !Local variables-------------------------------
    2163                 :             :  integer :: isym, itime, nsym_sum
    2164                 :             :  real(dp) :: vsym(3), tsign
    2165                 :             : ! *************************************************************************
    2166                 :             : 
    2167         [ +  + ]:       17980 :  vsum = zero; nsym_sum = 0
    2168         [ +  + ]:       13485 :  do itime=1,cryst%timrev
    2169                 :        8990 :    tsign = 1
    2170         [ +  + ]:        8990 :    if (itime == cryst%timrev) then
    2171         [ -  + ]:        4495 :      if (time_opt == 0) cycle
    2172                 :           0 :      tsign = time_opt
    2173                 :             :    end if
    2174         [ +  + ]:      224750 :    do isym=1, cryst%nsym
    2175                 :      215760 :      nsym_sum = nsym_sum + 1
    2176   [ +  +  +  +  :     5609760 :      vsym = matmul(cryst%symrel_cart(:,:,isym), v) * tsign
          +  -  +  -  +  
                      + ]
    2177         [ +  + ]:      872030 :      vsum = vsum + vsym
    2178                 :             :    end do
    2179                 :             :  end do
    2180         [ +  + ]:       17980 :  vsum = vsum / nsym_sum
    2181                 :             : 
    2182                 :        4495 : end function crystal_symmetrize_cart_vec3
    2183                 :             : !!***
    2184                 :             : 
    2185                 :             : !----------------------------------------------------------------------
    2186                 :             : 
    2187                 :             : !!****f* m_crystal/crystal_symmetrize_cart_tens33
    2188                 :             : !! NAME
    2189                 :             : !!  crystal_symmetrize_cart_tens33
    2190                 :             : !!
    2191                 :             : !! FUNCTION
    2192                 :             : !!  Symmetrize a cartesian 3x3 tensor
    2193                 :             : !!  Use spatial and time-reversal symmetry (TR) to symmetrize a Cartesian 3x3 tensor of real elements.
    2194                 :             : !!
    2195                 :             : !! INPUTS
    2196                 :             : !!  v(3)=Vector in Cartesian coordinates.
    2197                 :             : !!  time_opt=Prefacator that defines how the vectors transforms under TR. Usually +1 or -1
    2198                 :             : !!      Note that TR is used only if cryst%timrev == 2. time_opt = 0 disables TR for testing purposes.
    2199                 :             : !!
    2200                 :             : !! SOURCE
    2201                 :             : 
    2202         [ -  + ]:       62537 : function crystal_symmetrize_cart_tens33(cryst, t, time_opt) result(tsum)
    2203                 :             : 
    2204                 :             : !Arguments ------------------------------------
    2205                 :             :  class(crystal_t),intent(in) :: cryst
    2206                 :             :  real(dp),intent(in) :: t(3,3)
    2207                 :             :  integer,intent(in) :: time_opt
    2208                 :             :  real(dp) :: tsum(3,3)
    2209                 :             : 
    2210                 :             : !Local variables-------------------------------
    2211                 :             :  integer :: isym, itime, nsym_sum
    2212                 :             :  real(dp) :: tsym(3,3), tsign
    2213                 :             : ! *************************************************************************
    2214                 :             : 
    2215   [ +  +  +  + ]:      812981 :  tsum = zero; nsym_sum = 0
    2216                 :             : 
    2217         [ +  + ]:      187611 :  do itime=1,cryst%timrev
    2218                 :      125074 :    tsign = 1
    2219         [ +  + ]:      125074 :    if (itime == cryst%timrev) then
    2220         [ -  + ]:       62537 :      if (time_opt == 0) cycle
    2221                 :           0 :      tsign = time_opt
    2222                 :             :    end if
    2223         [ +  + ]:     1991722 :    do isym=1, cryst%nsym
    2224                 :     1866648 :      nsym_sum = nsym_sum + 1
    2225   [ -  +  +  -  :   324796752 :      tsym = tsign * matmul((cryst%symrel_cart(:,:,isym)), matmul(t, transpose(cryst%symrel_cart(:,:,isym))))
          +  -  +  -  -  
          +  -  +  +  +  
          +  +  +  +  +  
          +  +  +  +  -  
          +  -  +  +  +  
          +  +  -  +  +  
          +  +  +  +  +  
          -  +  -  +  -  
          +  -  +  +  +  
                      + ]
    2226   [ +  +  +  + ]:    24391498 :      tsum = tsum + tsym
    2227                 :             :    end do
    2228                 :             :  end do
    2229                 :             : 
    2230   [ +  +  +  + ]:      812981 :  tsum = tsum / nsym_sum
    2231                 :             : 
    2232                 :       62537 : end function crystal_symmetrize_cart_tens33
    2233                 :             : !!***
    2234                 :             : 
    2235                 :             : !----------------------------------------------------------------------
    2236                 :             : 
    2237                 :             : !!****f* m_crystal/get_recart_qdirs
    2238                 :             : !! NAME
    2239                 :             : !!  get_recart_qdirs
    2240                 :             : !!
    2241                 :             : !! FUNCTION
    2242                 :             : !!  Return predefined list of 6 q-versors in reciprocal space reduced coordinates.
    2243                 :             : !!  First 3 entries are along the recip. space lattice vectors, then along the Cartesian axis x,y,z.
    2244                 :             : !!  The optional qlen argument, can be used to rescale the vectors. Default: 1
    2245                 :             : !!
    2246                 :             : !! INPUTS
    2247                 :             : !!
    2248                 :             : !! SOURCE
    2249                 :             : 
    2250                 :          29 : subroutine get_redcart_qdirs(cryst, nq, qdirs, qlen)
    2251                 :             : 
    2252                 :             : !Arguments ------------------------------------
    2253                 :             :  class(crystal_t),intent(in) :: cryst
    2254                 :             :  integer,intent(out) :: nq
    2255                 :             :  real(dp),allocatable,intent(out) :: qdirs(:,:)
    2256                 :             :  real(dp),optional,intent(in) :: qlen
    2257                 :             : 
    2258                 :             : !Local variables-------------------------------
    2259                 :             :  integer :: iq
    2260                 :             :  real(dp) :: qred2cart(3,3), qcart2red(3,3)
    2261                 :             : ! *************************************************************************
    2262                 :             : 
    2263   [ +  +  +  + ]:         377 :  qred2cart = two_pi * cryst%gprimd
    2264                 :          29 :  qcart2red = qred2cart
    2265                 :          29 :  call matrginv(qcart2red, 3, 3)
    2266                 :             : 
    2267                 :          29 :  nq = 6
    2268   [ -  +  -  + ]:          29 :  ABI_MALLOC(qdirs, (3, nq))
    2269         [ +  + ]:         116 :  qdirs(:,1) = [one, zero, zero]  ! (100)
    2270         [ +  + ]:         116 :  qdirs(:,2) = [zero, one, zero]  ! (010)
    2271         [ +  + ]:         116 :  qdirs(:,3) = [zero, zero, one]  ! (001)
    2272   [ +  +  +  +  :         493 :  qdirs(:,4) = matmul(qcart2red, [one, zero, zero]) ! (x)
                   +  + ]
    2273   [ +  +  +  +  :         493 :  qdirs(:,5) = matmul(qcart2red, [zero, one, zero]) ! (y)
                   +  + ]
    2274   [ +  +  +  +  :         493 :  qdirs(:,6) = matmul(qcart2red, [zero, zero, one]) ! (z)
                   +  + ]
    2275                 :             : 
    2276                 :             :  ! normalization
    2277         [ +  + ]:         203 :  do iq=1,nq
    2278         [ +  + ]:         725 :    qdirs(:,iq) = qdirs(:,iq) / normv(qdirs(:,iq), cryst%gmet, "G")
    2279                 :             :  end do
    2280                 :             : 
    2281   [ -  +  -  -  :          29 :  if (present(qlen)) qdirs = qlen * qdirs
                   -  - ]
    2282                 :             : 
    2283                 :          29 : end subroutine get_redcart_qdirs
    2284                 :             : !!***
    2285                 :             : 
    2286                 :             : !----------------------------------------------------------------------
    2287                 :             : 
    2288                 :             : !!****f* m_crystal/crystal_write_xsf_data
    2289                 :             : !! NAME
    2290                 :             : !!  crystal_write_xsf_data
    2291                 :             : !!
    2292                 :             : !! FUNCTION
    2293                 :             : !!  Write array in real space in XSF format
    2294                 :             : !!
    2295                 :             : !! INPUTS
    2296                 :             : !!  filepath: Path to output file.
    2297                 :             : !!  n1, n2, n3: Dimensions of input array.
    2298                 :             : !!  datagrid(n1,n2,n3)=Array in real space.
    2299                 :             : !!
    2300                 :             : !! SOURCE
    2301                 :             : 
    2302                 :           0 : subroutine crystal_write_xsf_data(cryst, filepath, n1, n2, n3, datagrid)
    2303                 :             : 
    2304                 :             : !Arguments ------------------------------------
    2305                 :             :  class(crystal_t),intent(in) :: cryst
    2306                 :             :  character(len=*),intent(in) :: filepath
    2307                 :             :  integer,intent(in) :: n1, n2, n3
    2308                 :             :  real(dp),intent(in) :: datagrid(n1*n2*n3)
    2309                 :             : 
    2310                 :             : !Local variables-------------------------------
    2311                 :             :  integer,parameter :: realrecip = 0
    2312                 :             :  real(dp),parameter :: origin(3) = zero
    2313                 :             : ! *************************************************************************
    2314                 :             : 
    2315                 :             :  call write_xsf(filepath, n1, n2, n3, datagrid, cryst%rprimd, origin, &
    2316                 :           0 :                 cryst%natom, cryst%ntypat, cryst%typat, cryst%xcart, cryst%znucl, realrecip)
    2317                 :             : 
    2318                 :           0 : end subroutine crystal_write_xsf_data
    2319                 :             : !!***
    2320                 :             : 
    2321   [ +  +  -  -  :     1868241 : end module m_crystal
          +  +  -  +  +  
          -  -  +  -  +  
          +  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  + ]
    2322                 :             : !!***
        

Generated by: LCOV version 2.3-1