LCOV - code coverage report
Current view: top level - src/80_tdep - m_tdep_latt.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 77.8 % 194 151
Test Date: 2026-11-09 11:14:24 Functions: 66.7 % 3 2
Branches: 85.7 % 259 222

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_tdep_latt
       2                 :             : !! NAME
       3                 :             : !!  m_tdep_latt
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  This module contains the TDEP Lattice data type, which describes the
       7                 :             : !!  lattice of the unitcell and of the supercell, and the routines building it.
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !! Copyright (C) 2011-2026 ABINIT group (GA,FB,JB)
      11                 :             : !! This file is distributed under the terms of the
      12                 :             : !! GNU General Public License, see ~abinit/COPYING
      13                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      14                 :             : !!
      15                 :             : !! SOURCE
      16                 :             : 
      17                 :             : #if defined HAVE_CONFIG_H
      18                 :             : #include "config.h"
      19                 :             : #endif
      20                 :             : 
      21                 :             : #include "abi_common.h"
      22                 :             : 
      23                 :             : module m_tdep_latt
      24                 :             : 
      25                 :             :  use defs_basis
      26                 :             :  use m_abicore
      27                 :             :  use m_errors
      28                 :             :  use m_xmpi
      29                 :             : 
      30                 :             :  use m_matrix,           only : matr3inv, mat33det
      31                 :             :  use m_geometry,         only : metric
      32                 :             :  use m_tdep_dataset,     only : atdep_dataset_type, MPI_enreg_type
      33                 :             : 
      34                 :             :  implicit none
      35                 :             : !!***
      36                 :             : 
      37                 :             : !!****t* m_tdep_latt/Lattice_type
      38                 :             : !! NAME
      39                 :             : !! Lattice_type
      40                 :             : !!
      41                 :             : !! FUNCTION
      42                 :             : !!  Holds the primitive vectors of the unitcell and of the supercell
      43                 :             : !!  (in various forms: transposed, inverted, dimensioned or not), the
      44                 :             : !!  lattice parameters, the Bravais lattice and the supercell multiplicity.
      45                 :             : !!
      46                 :             : !! SOURCE
      47                 :             : 
      48                 :             :   type Lattice_type
      49                 :             : 
      50                 :             :     double precision :: acell_unitcell(3)
      51                 :             :     ! Lattice parameters of the unitcell (bohr)
      52                 :             : 
      53                 :             :     double precision :: angle_alpha
      54                 :             :     ! Angle (in degrees) defining the lattice, for some Bravais lattices
      55                 :             : 
      56                 :             :     integer :: brav
      57                 :             :     ! Bravais lattice, with the convention of m_dynmat:
      58                 :             :     ! 1=simple, 2=face-centered, 3=body-centered, 4=hexagonal
      59                 :             : 
      60                 :             :     integer :: bravais(11)
      61                 :             :     ! Bravais lattice (bravais(1): holohedry) and centering (bravais(2)), see symlatt
      62                 :             : 
      63                 :             :     integer :: line
      64                 :             :     ! How the lattice parameters multiply rprim (see tdep_make_latt):
      65                 :             :     ! 0=line or column, 1=line only, 2=column only, 3=neither
      66                 :             : 
      67                 :             :     double precision :: metmin        (3,3)
      68                 :             :     ! Currently unused
      69                 :             : 
      70                 :             :     double precision :: minim         (3,3)
      71                 :             :     ! Currently unused
      72                 :             : 
      73                 :             :     double precision :: multiplicity  (3,3)
      74                 :             :     ! Supercell scaling matrix
      75                 :             : 
      76                 :             :     double precision :: multiplicitym1(3,3)
      77                 :             :     ! Inverse of multiplicity
      78                 :             : 
      79                 :             :     double precision :: gmet          (3,3)
      80                 :             :     ! Reciprocal space metric of the unitcell (bohr^-2), computed from rprimdt
      81                 :             : 
      82                 :             :     double precision :: rmet          (3,3)
      83                 :             :     ! Real space metric of the unitcell (bohr^2), computed from rprimdt
      84                 :             : 
      85                 :             :     double precision :: gprimd        (3,3)
      86                 :             :     ! Dimensioned reciprocal primitive vectors of the unitcell (bohr^-1),
      87                 :             :     ! computed from rprimdt
      88                 :             : 
      89                 :             :     double precision :: gprim         (3,3)
      90                 :             :     ! Inverse of rprim (dimensionless reciprocal primitive vectors of the unitcell)
      91                 :             : 
      92                 :             :     double precision :: gprimt        (3,3)
      93                 :             :     ! Transpose of gprim
      94                 :             : 
      95                 :             :     double precision :: rprim         (3,3)
      96                 :             :     ! Dimensionless primitive vectors of the unitcell
      97                 :             : 
      98                 :             :     double precision :: rprimt        (3,3)
      99                 :             :     ! Transpose of rprim
     100                 :             : 
     101                 :             :     double precision :: rprimm1       (3,3)
     102                 :             :     ! Inverse of rprim
     103                 :             : 
     104                 :             :     double precision :: rprimd        (3,3)
     105                 :             :     ! Dimensioned primitive vectors of the unitcell (bohr)
     106                 :             : 
     107                 :             :     double precision :: rprimdm1      (3,3)
     108                 :             :     ! Inverse of rprimd
     109                 :             : 
     110                 :             :     double precision :: rprimdt       (3,3)
     111                 :             :     ! Transpose of rprimd
     112                 :             : 
     113                 :             :     double precision :: rprimdtm1     (3,3)
     114                 :             :     ! Inverse of rprimdt
     115                 :             : 
     116                 :             :     double precision :: rprimd_md     (3,3)
     117                 :             :     ! Dimensioned primitive vectors of the supercell (bohr),
     118                 :             :     ! recomputed from rprim, acell_unitcell and multiplicity
     119                 :             : 
     120                 :             :   end type Lattice_type
     121                 :             : !!***
     122                 :             : 
     123                 :             :   public :: tdep_make_inbox
     124                 :             :   public :: tdep_make_latt
     125                 :             : 
     126                 :             : contains
     127                 :             : 
     128                 :             : !=====================================================================================================
     129                 :             : 
     130                 :             : !!****f* ABINIT/m_tdep_latt/tdep_make_inbox
     131                 :             : !! NAME
     132                 :             : !!  tdep_make_inbox
     133                 :             : !!
     134                 :             : !! FUNCTION
     135                 :             : !!  Wrap a set of vectors in reduced coordinates into [-0.5,0.5[, by removing
     136                 :             : !!  from each component the nearest integer (a small tolerance is used to
     137                 :             : !!  choose between the two boundaries). If temp is present, the integer shifts
     138                 :             : !!  are computed from tab but applied to temp, and tab is left unchanged.
     139                 :             : !!
     140                 :             : !! INPUTS
     141                 :             : !!  natom = Number of vectors.
     142                 :             : !!  tol = Tolerance used when rounding to the nearest integer.
     143                 :             : !!
     144                 :             : !! OUTPUT
     145                 :             : !!
     146                 :             : !! SIDE EFFECTS
     147                 :             : !!  tab(3,natom) = Vectors in reduced coordinates. Wrapped on exit,
     148                 :             : !!                 if temp is not present.
     149                 :             : !!  temp(3,natom) = (optional) Vectors in reduced coordinates, shifted on exit
     150                 :             : !!                  by the integer shifts computed from tab.
     151                 :             : !!
     152                 :             : !! SOURCE
     153                 :             : 
     154                 :    23145431 : subroutine tdep_make_inbox(tab,natom,tol,&
     155                 :             : &                          temp) !Optional
     156                 :             : 
     157                 :             :   integer :: natom,ii,jj,iatom
     158                 :             :   double precision :: tol
     159                 :             :   double precision :: tab(3,natom) !Input (and ouput if temp is not present)
     160                 :             :   double precision,optional :: temp(3,natom) !Input/Output (if present)
     161                 :             : 
     162                 :             :   !GA: One could make use of function wrap2_pmhalf
     163                 :             : 
     164         [ +  + ]:    46290862 :   do iatom=1,natom
     165         [ +  + ]:   115727155 :     do ii=1,3
     166         [ +  + ]:    69436293 :       if (tab(ii,iatom).lt.0.d0) then
     167                 :    19739163 :         jj=int(tab(ii,iatom)-0.5+tol)
     168         [ +  - ]:    49697130 :       else if (tab(ii,iatom).ge.0.d0) then
     169                 :    49697130 :         jj=int(tab(ii,iatom)+0.5+tol)
     170                 :             :       end if
     171         [ +  + ]:    92581724 :       if (present(temp)) then
     172                 :    69118575 :         temp(ii,iatom)=temp(ii,iatom)-real(jj)
     173                 :             :       else
     174                 :      317718 :         tab(ii,iatom)=tab(ii,iatom)-real(jj)
     175                 :             :       end if
     176                 :             :     end do
     177                 :             :   end do
     178                 :             : 
     179                 :    23145431 : end subroutine tdep_make_inbox
     180                 :             : !!***
     181                 :             : 
     182                 :             : !=====================================================================================================
     183                 :             : 
     184                 :             : !!****f* ABINIT/m_tdep_latt/tdep_make_latt
     185                 :             : !! NAME
     186                 :             : !!  tdep_make_latt
     187                 :             : !!
     188                 :             : !! FUNCTION
     189                 :             : !!  Initialize the Lattice object. The dimensionless primitive vectors of
     190                 :             : !!  the unitcell (rprim) are built from the Bravais lattice (Invar%bravais)
     191                 :             : !!  and, if needed, the angle Invar%angle_alpha. The lattice parameters
     192                 :             : !!  (acell_unitcell) and the rotation matrix R are then deduced from the
     193                 :             : !!  primitive vectors of the supercell given in input (Invar%rprimd_md),
     194                 :             : !!  which are related to rprim by:
     195                 :             : !!      rprimd_md = R * A * multiplicity * rprim
     196                 :             : !!  where A is the diagonal matrix containing acell_unitcell.
     197                 :             : !!  The input supercell vectors are rotated accordingly, and checked against
     198                 :             : !!  the ones recomputed from rprim, acell_unitcell and multiplicity.
     199                 :             : !!  Finally, the dimensioned primitive vectors of the unitcell, their
     200                 :             : !!  transpose and inverse, and the metrics are computed.
     201                 :             : !!
     202                 :             : !! OUTPUT
     203                 :             : !!  Lattice = Lattice object, initialized.
     204                 :             : !!  rotation_cart(3,3) = Rotation matrix, in cartesian coordinates, applied to
     205                 :             : !!                       the input supercell primitive vectors (the cartesian
     206                 :             : !!                       forces must be rotated accordingly, see
     207                 :             : !!                       tdep_sampling_rotate).
     208                 :             : !!
     209                 :             : !! SIDE EFFECTS
     210                 :             : !!  Invar = Input object containing the input variables.
     211                 :             : !!          On exit, Invar%rprimd_md is rotated.
     212                 :             : !!
     213                 :             : !! SOURCE
     214                 :             : 
     215                 :          46 :  subroutine tdep_make_latt(Invar,Lattice,rotation_cart)
     216                 :             : 
     217                 :             :   type(Lattice_type),intent(out) :: Lattice
     218                 :             :   type(atdep_dataset_type),intent(inout) :: Invar
     219                 :             :   double precision, intent(out) :: rotation_cart(3,3)
     220                 :             : 
     221                 :             :   integer :: brav,ii,jj,line
     222                 :             :   double precision :: acell_unitcell(3),multiplicity(3,3),multiplicitym1(3,3)
     223                 :             :   double precision :: rprimd(3,3),rprimdt(3,3),rprimd_md(3,3),rprimdm1(3,3)
     224                 :             :   double precision :: rprim(3,3),rprimm1(3,3),rprimt(3,3),rprimdtm1(3,3)
     225                 :             :   double precision :: rprimd_unitcell(3,3)
     226                 :             :   double precision :: rprimd_tmp(3,3), rprimdm1_tmp(3,3)
     227                 :             :   double precision :: RAmat(3,3),Amat2(3,3),Rmat(3,3)
     228                 :             :   double precision :: rotation(3,3)
     229                 :             :   double precision :: xi,hh
     230                 :             :   double precision :: ucvol
     231                 :             :   character(len=500) :: msg
     232                 :             : 
     233                 :             : ! For bravais(1):
     234                 :             : ! The holohedral groups are numbered as follows
     235                 :             : ! (see international tables for crystallography (1983), p. 13)
     236                 :             : ! iholohedry=1   triclinic      1bar
     237                 :             : ! iholohedry=2   monoclinic     2/m
     238                 :             : ! iholohedry=3   orthorhombic   mmm
     239                 :             : ! iholohedry=4   tetragonal     4/mmm
     240                 :             : ! iholohedry=5   trigonal       3bar m
     241                 :             : ! iholohedry=6   hexagonal      6/mmm
     242                 :             : ! iholohedry=7   cubic          m3bar m
     243                 :             : 
     244                 :             : ! For bravais(2):
     245                 :             : ! Centering
     246                 :             : ! center=0        no centering
     247                 :             : ! center=-1       body-centered
     248                 :             : ! center=-3       face-centered
     249                 :             : ! center=1        A-face centered
     250                 :             : ! center=2        B-face centered
     251                 :             : ! center=3        C-face centered
     252                 :             : 
     253                 :             : ! Correspondency between brav and bravais: brav=1-S.C., 2-F.C., 3-B.C., 4-Hex.)
     254                 :             : 
     255                 :             : ! Initialize some local variables
     256                 :          46 :   acell_unitcell(:)=zero; multiplicity(:,:)=zero; multiplicitym1(:,:)=zero
     257                 :          46 :   rprimd(:,:)=zero; rprimdm1(:,:)=zero; rprimdt(:,:)=zero; rprimd_md(:,:)=zero
     258                 :          46 :   rprim(:,:)=zero; rprimm1(:,:)=zero; rprimt(:,:)=zero; rprimdtm1(:,:)=zero
     259                 :          46 :   rprimd_unitcell(:,:)=zero; RAmat(:,:)=zero; Amat2(:,:)=zero; Rmat(:,:)=zero
     260                 :             : 
     261                 :             : 
     262                 :             : ! ---------------------------------------------------------------------------- !
     263                 :             : ! Here, rprim defines a Primitive Lattice and NOT a Conventional lattice
     264                 :             : ! The lattice parameters have to multiply rprim on:
     265                 :             : ! 0/ line or column         --> line 0
     266                 :             : !                               Cubic, Fcc, Bcc, Ortho, Tetra, Rhombo, Hexa
     267                 :             : ! 1/ line only              --> line=1 (see rprim using acell in ABINIT) :
     268                 :             : !                               Mono, Tri
     269                 :             : ! 2/ column only            --> line=2 (see rprim using scalecart in ABINIT) :
     270                 :             : !                               Bct, Face-centered-Ortho, Body-centered-Ortho, C-centered-Ortho
     271                 :             : ! 3/ neither line or column --> line=3 (rprim has to be directly dimensioned in ABINIT) :
     272                 :             : !                               C-centered-Mono
     273                 :             : ! ---------------------------------------------------------------------------- !
     274                 :          46 :   line=0
     275                 :             : ! For monoclinic: bravais(1)=2
     276   [ +  +  -  -  :          46 :   if (Invar%bravais(1).eq.2.and.Invar%bravais(2).eq.0) then !monoclinic
          +  -  +  +  +  
             +  +  +  - ]
     277                 :           1 :     brav=1
     278                 :           1 :     line=1
     279                 :           1 :     rprim(1,1)= 1.0d0                             ; rprim(1,2)= 0.0d0 ; rprim(1,3)= 0.0d0
     280                 :           1 :     rprim(2,1)= 0.0d0                             ; rprim(2,2)= 1.0d0 ; rprim(2,3)= 0.0d0
     281                 :           1 :     rprim(3,1)= dcos(Invar%angle_alpha*pi/180.d0) ; rprim(3,2)= 0.0d0 ; rprim(3,3)= dsin(Invar%angle_alpha*pi/180.d0)
     282                 :             : ! For orthorhombic: bravais(1)=3
     283                 :             :   else if (Invar%bravais(1).eq.3.and.Invar%bravais(2).eq.0) then !orthorhombic
     284                 :           2 :     brav=1
     285                 :           2 :     line=0
     286                 :           2 :     rprim(1,1)=1.0d0 ; rprim(1,2)=0.0d0 ; rprim(1,3)=0.0d0
     287                 :           2 :     rprim(2,1)=0.0d0 ; rprim(2,2)=1.0d0 ; rprim(2,3)=0.0d0
     288                 :           2 :     rprim(3,1)=0.0d0 ; rprim(3,2)=0.0d0 ; rprim(3,3)=1.0d0
     289                 :             :   else if (Invar%bravais(1).eq.3.and.Invar%bravais(2).eq.-3) then !face centered orthorhombic
     290                 :           0 :     brav=1
     291                 :           0 :     line=2
     292                 :           0 :     rprim(1,1)=0.0d0 ; rprim(1,2)=0.5d0 ; rprim(1,3)=0.5d0
     293                 :           0 :     rprim(2,1)=0.5d0 ; rprim(2,2)=0.0d0 ; rprim(2,3)=0.5d0
     294                 :           0 :     rprim(3,1)=0.5d0 ; rprim(3,2)=0.5d0 ; rprim(3,3)=0.0d0
     295                 :             :   else if (Invar%bravais(1).eq.3.and.Invar%bravais(2).eq.-1) then !body centered orthorhombic
     296                 :           0 :     brav=1
     297                 :           0 :     line=2
     298                 :           0 :     rprim(1,1)=-0.5d0 ; rprim(1,2)= 0.5d0 ; rprim(1,3)= 0.5d0
     299                 :           0 :     rprim(2,1)= 0.5d0 ; rprim(2,2)=-0.5d0 ; rprim(2,3)= 0.5d0
     300                 :           0 :     rprim(3,1)= 0.5d0 ; rprim(3,2)= 0.5d0 ; rprim(3,3)=-0.5d0
     301                 :             :   else if (Invar%bravais(1).eq.3.and.Invar%bravais(2).eq.3) then !orthorombic C-face centered
     302                 :           7 :     brav=1
     303                 :           7 :     line=2
     304                 :           7 :     rprim(1,1)= 0.5d0 ; rprim(1,2)=-0.5d0 ; rprim(1,3)=0.0d0
     305                 :           7 :     rprim(2,1)= 0.5d0 ; rprim(2,2)= 0.5d0 ; rprim(2,3)=0.0d0
     306                 :           7 :     rprim(3,1)= 0.0d0 ; rprim(3,2)= 0.0d0 ; rprim(3,3)=1.0d0
     307                 :             : ! For tetragonal: bravais(1)=4
     308                 :             :   else if (Invar%bravais(1).eq.4.and.Invar%bravais(2).eq.0) then !tetragonal
     309                 :           0 :     brav=1
     310                 :           0 :     line=2
     311                 :           0 :     rprim(1,1)=1.0d0 ; rprim(1,2)=0.0d0 ; rprim(1,3)=0.0d0
     312                 :           0 :     rprim(2,1)=0.0d0 ; rprim(2,2)=1.0d0 ; rprim(2,3)=0.0d0
     313                 :           0 :     rprim(3,1)=0.0d0 ; rprim(3,2)=0.0d0 ; rprim(3,3)=1.0d0
     314                 :             :   else if (Invar%bravais(1).eq.4.and.Invar%bravais(2).eq.-1) then !body centered tetragonal
     315                 :           2 :     brav=3
     316                 :           2 :     line=2
     317                 :           2 :     rprim(1,1)=-0.5d0 ; rprim(1,2)= 0.5d0 ; rprim(1,3)= 0.5d0
     318                 :           2 :     rprim(2,1)= 0.5d0 ; rprim(2,2)=-0.5d0 ; rprim(2,3)= 0.5d0
     319                 :           2 :     rprim(3,1)= 0.5d0 ; rprim(3,2)= 0.5d0 ; rprim(3,3)=-0.5d0
     320                 :             : ! For trigonal: bravais(1)=5
     321                 :             :   else if (Invar%bravais(1).eq.5.and.Invar%bravais(2).eq.0) then !rhombo
     322                 :           3 :     brav=1
     323                 :           3 :     line=0
     324                 :           3 :     xi=dsin(Invar%angle_alpha*pi/180.d0/2d0)
     325                 :           3 :     hh=dsqrt(1d0-4d0/3d0*xi**2)
     326                 :           3 :     rprim(1,1)=xi    ; rprim(1,2)=-xi/dsqrt(3d0)    ; rprim(1,3)= hh
     327                 :           3 :     rprim(2,1)= 0.d0 ; rprim(2,2)=2d0*xi/dsqrt(3d0) ; rprim(2,3)= hh
     328                 :           3 :     rprim(3,1)=-xi   ; rprim(3,2)=-xi/dsqrt(3d0)    ; rprim(3,3)= hh
     329                 :             : !  double precision :: AA,BB,CC,DD
     330                 :             : !    AA=dcos(Invar%angle_alpha*pi/180.d0/2d0)
     331                 :             : !    BB=dsin(Invar%angle_alpha*pi/180.d0/2d0)
     332                 :             : !    CC=dcos(Invar%angle_alpha*pi/180.d0)
     333                 :             : !    DD=dsqrt(1-CC**2/AA**2)
     334                 :             : !    rprim(1,1)= AA   ; rprim(1,2)= AA  ; rprim(1,3)= CC/AA
     335                 :             : !    rprim(2,1)=-BB   ; rprim(2,2)= BB  ; rprim(2,3)= 0.d0
     336                 :             : !    rprim(3,1)= 0.d0 ; rprim(3,2)= 0.d0; rprim(3,3)= DD
     337                 :             : !    rprim(1,1)= AA    ; rprim(1,2)= -BB ; rprim(1,3)= 0.d0
     338                 :             : !    rprim(2,1)= AA    ; rprim(2,2)=  BB ; rprim(2,3)= 0.d0
     339                 :             : !    rprim(3,1)= CC/AA ; rprim(3,2)= 0.d0; rprim(3,3)= DD
     340                 :             : ! For hexagonal: bravais(1)=6
     341                 :             :   else if (Invar%bravais(1).eq.6.and.Invar%bravais(2).eq.0) then !hexagonal
     342                 :           5 :     brav=4
     343                 :           5 :     line=0
     344                 :             : ! The following definition of the hcp is fixed in m_dynmat (chkrp9)
     345                 :           5 :     rprim(1,1)= 1.0d0 ; rprim(1,2)= 0.0d0            ; rprim(1,3)= 0.0d0
     346                 :           5 :     rprim(2,1)=-0.5d0 ; rprim(2,2)= dsqrt(3.d0)/2.d0 ; rprim(2,3)= 0.0d0
     347                 :           5 :     rprim(3,1)= 0.0d0 ; rprim(3,2)= 0.0d0            ; rprim(3,3)= 1.0d0
     348                 :             : ! For cubic: bravais(1)=7
     349                 :             :   else if (Invar%bravais(1).eq.7.and.Invar%bravais(2).eq.0) then !simple cubic
     350                 :           6 :     brav=1
     351                 :           6 :     line=0
     352                 :           6 :     rprim(1,1)=1.0d0 ; rprim(1,2)=0.0d0 ; rprim(1,3)=0.0d0
     353                 :           6 :     rprim(2,1)=0.0d0 ; rprim(2,2)=1.0d0 ; rprim(2,3)=0.0d0
     354                 :           6 :     rprim(3,1)=0.0d0 ; rprim(3,2)=0.0d0 ; rprim(3,3)=1.0d0
     355                 :             :   else if (Invar%bravais(1).eq.7.and.Invar%bravais(2).eq.-3) then !face centered cubic
     356                 :          16 :     brav=2
     357                 :          16 :     line=0
     358                 :          16 :     rprim(1,1)=0.0d0 ; rprim(1,2)=0.5d0 ; rprim(1,3)=0.5d0
     359                 :          16 :     rprim(2,1)=0.5d0 ; rprim(2,2)=0.0d0 ; rprim(2,3)=0.5d0
     360                 :          16 :     rprim(3,1)=0.5d0 ; rprim(3,2)=0.5d0 ; rprim(3,3)=0.0d0
     361                 :             :   else if (Invar%bravais(1).eq.7.and.Invar%bravais(2).eq.-1) then !body centered cubic
     362                 :           4 :     brav=3
     363                 :           4 :     line=0
     364                 :           4 :     rprim(1,1)=-0.5d0 ; rprim(1,2)= 0.5d0 ; rprim(1,3)= 0.5d0
     365                 :           4 :     rprim(2,1)= 0.5d0 ; rprim(2,2)=-0.5d0 ; rprim(2,3)= 0.5d0
     366                 :           4 :     rprim(3,1)= 0.5d0 ; rprim(3,2)= 0.5d0 ; rprim(3,3)=-0.5d0
     367                 :             :   else
     368                 :           0 :     ABI_ERROR('THIS BRAVAIS IS NOT DEFINED')
     369                 :             :   end if
     370                 :             : 
     371                 :             : ! ---------------------------------------------------------------------------- !
     372                 :             : 
     373                 :             : ! Define inverse of the multiplicity
     374   [ +  +  +  + ]:         598 :   multiplicity = Invar%multiplicity
     375                 :          46 :   call matr3inv(multiplicity,multiplicitym1)
     376   [ +  +  +  +  :        1150 :   multiplicitym1 = TRANSPOSE(multiplicitym1)
             +  +  +  + ]
     377                 :             : 
     378                 :             : ! Compute gprim and (transpose of gprim) gprimt
     379                 :          46 :   call matr3inv(rprim, Lattice%gprimt)
     380   [ +  +  +  +  :        1150 :   Lattice%gprim = TRANSPOSE(Lattice%gprimt)
             +  +  +  + ]
     381                 :             : ! GA: This is a weird convention, and is different from the rest of abinit.
     382                 :             : !     See for example how the DDB has to be initialized with Lattice.
     383                 :             : 
     384                 :             : ! Define transpose and inverse of rprim
     385   [ +  +  +  + ]:         598 :   rprimt = TRANSPOSE(rprim)
     386                 :          46 :   call matr3inv(rprimt, rprimm1)
     387                 :             : 
     388                 :             : ! Compute acell_unitcell and a rotation matrix, given that
     389                 :             : ! the supercell rprimd is related to the unitcell rprim according to
     390                 :             : !     rprimd  = R * A * multiplicity * rprim
     391                 :             : ! where R is unitary and A is a diagonal matrix containing acell.
     392   [ +  +  +  +  :        3634 :   RAmat = MATMUL(MATMUL(Invar%rprimd_md, rprimm1), multiplicitym1)
          +  +  +  +  +  
                +  +  + ]
     393                 :             : 
     394                 :             : ! This matrix should be diagonal
     395   [ +  +  +  +  :        1840 :   Amat2 = MATMUL(TRANSPOSE(RAmat), RAmat)
                   +  + ]
     396         [ +  + ]:         184 :   do ii=1,3
     397                 :         184 :     acell_unitcell(ii) = sqrt(Amat2(ii,ii))
     398                 :             :   end do
     399         [ +  + ]:         184 :   do ii=1,3
     400         [ +  + ]:         598 :     do jj=1,3
     401                 :         552 :       Rmat(ii,jj) = RAmat(ii,jj) / acell_unitcell(jj)
     402                 :             :     end do
     403                 :             :   end do
     404   [ +  +  +  + ]:         598 :   rotation = TRANSPOSE(Rmat)
     405                 :             : 
     406                 :             : ! Compute rotation matrix in cartesian coordinates
     407                 :          46 :   call matr3inv(Invar%rprimd_md, rprimdm1_tmp)
     408   [ +  +  +  +  :        1150 :   rprimdm1_tmp = TRANSPOSE(rprimdm1_tmp)
             +  +  +  + ]
     409   [ +  +  +  +  :        1840 :   rotation_cart = MATMUL(rotation, Invar%rprimd_md)
                   +  + ]
     410   [ +  +  +  +  :        1840 :   rotation_cart = MATMUL(rprimdm1_tmp, rotation_cart)
                   +  + ]
     411   [ +  +  +  +  :        1150 :   rotation_cart = TRANSPOSE(rotation_cart)
             +  +  +  + ]
     412                 :             : 
     413                 :             :   ! Perform some checks
     414         [ -  + ]:          46 :   if ((mat33det(rotation) - 1) .gt. tol8) then
     415   [ #  #  #  #  :           0 :      rprimd_tmp = MATMUL(multiplicitym1, Invar%rprimd_md)
                   #  # ]
     416                 :             :      write(msg, '(6a,3(3f16.10,1x,a),2a,3(3f16.10,1x,a))')&
     417                 :           0 :       'The input primitive vectors cannot be aligned',ch10,&
     418                 :           0 :       'with the expected primitive vectors through rotation.',ch10,&
     419                 :           0 :       'Input unitcell primitive vectors:',ch10,&
     420                 :           0 :       (rprimd_tmp(1,jj),jj=1,3),ch10,&
     421                 :           0 :       (rprimd_tmp(2,jj),jj=1,3),ch10,&
     422                 :           0 :       (rprimd_tmp(3,jj),jj=1,3),ch10,&
     423                 :           0 :       'Expected primitive vectors:',ch10,&
     424                 :           0 :       (rprim(1,jj),jj=1,3),ch10,&
     425                 :           0 :       (rprim(2,jj),jj=1,3),ch10,&
     426                 :           0 :       (rprim(3,jj),jj=1,3),ch10
     427                 :           0 :     ABI_ERROR(msg)
     428                 :             :   end if
     429                 :             : 
     430                 :             : ! Apply rotation to rprim_md
     431   [ +  +  +  +  :        2944 :   Invar%rprimd_md = MATMUL(rotation, Invar%rprimd_md)
          +  +  +  +  +  
             +  +  +  +  
                      + ]
     432                 :             : 
     433                 :             : ! ---------------------------------------------------------------------------- !
     434                 :             : 
     435                 :             : ! Recompute dimensioned primitive vectors
     436   [ +  +  +  +  :        1840 :   rprimd_md = MATMUL(multiplicity, rprim)
                   +  + ]
     437         [ +  + ]:          46 :   if (line==0.or.line==1) then
     438         [ +  + ]:         148 :     do ii=1,3
     439         [ +  + ]:         481 :       do jj=1,3
     440                 :         444 :         rprimd_md(ii,jj) = acell_unitcell(ii) * rprimd_md(ii,jj)
     441                 :             :       end do
     442                 :             :     end do
     443                 :             :   else if (line==2) then
     444         [ +  + ]:          36 :     do ii=1,3
     445         [ +  + ]:         117 :       do jj=1,3
     446                 :         108 :         rprimd_md(ii,jj) = acell_unitcell(jj) * rprimd_md(ii,jj)
     447                 :             :       end do
     448                 :             :     end do
     449                 :             :   end if
     450                 :             : 
     451                 :             : ! Echo some (re)computed quantities
     452                 :          46 :   write(ab_out,*) ' '
     453                 :          46 :   write(ab_out,*) '#############################################################################'
     454                 :          46 :   write(ab_out,*) '########################## Computed quantities ##############################'
     455                 :          46 :   write(ab_out,*) '#############################################################################'
     456                 :             : 
     457                 :             : ! Check the off-diagonal elements
     458         [ +  + ]:         184 :   do ii=1,3
     459                 :         184 :     write(std_out,'(a,1x,3(f16.10,1x))') 'The rprimd_md (computed)=',(rprimd_md(ii,jj),jj=1,3)
     460                 :             :   end do
     461                 :             :   if((abs(rprimd_md(1,2)-Invar%rprimd_md(1,2)).gt.tol5).or.(abs(rprimd_md(1,3)-Invar%rprimd_md(1,3)).gt.tol5).or.&
     462                 :             : &    (abs(rprimd_md(2,1)-Invar%rprimd_md(2,1)).gt.tol5).or.(abs(rprimd_md(3,1)-Invar%rprimd_md(3,1)).gt.tol5).or.&
     463                 :             : &    (abs(rprimd_md(2,3)-Invar%rprimd_md(2,3)).gt.tol5).or.(abs(rprimd_md(3,2)-Invar%rprimd_md(3,2)).gt.tol5).or.&
     464   [ -  +  -  +  :          46 : &    (abs(rprimd_md(1,1)-Invar%rprimd_md(1,1)).gt.tol5).or.(abs(rprimd_md(2,2)-Invar%rprimd_md(2,2)).gt.tol5).or.&
          -  +  -  +  -  
          +  -  +  -  +  
             -  +  -  + ]
     465                 :             : &    (abs(rprimd_md(3,3)-Invar%rprimd_md(3,3)).gt.tol5)) then
     466         [ #  # ]:           0 :     do ii=1,3
     467                 :           0 :       write(std_out,'(a,1x,3(f16.10,1x))') 'The rprimd (from the input file or NetCDF file) is=',&
     468   [ #  #  #  # ]:           0 : &                                             (Invar%rprimd_md(ii,jj),jj=1,3)
     469                 :             :     end do
     470         [ #  # ]:           0 :     do ii=1,3
     471                 :           0 :       write(std_out,'(a,1x,3(f16.10,1x))') 'However, using multiplicity (from the input file)=',&
     472                 :           0 : &                                             (multiplicity(ii,jj),jj=1,3)
     473                 :             :     end do
     474         [ #  # ]:           0 :     do ii=1,3
     475                 :           0 :       write(std_out,'(a,1x,3(f16.10,1x))') 'rprim (from the aTDEP code)=',(rprim(ii,jj),jj=1,3)
     476                 :             :     end do
     477                 :           0 :     write(std_out,'(a,1x,3(f16.10,1x))') 'and acell (from the calculation)=',(acell_unitcell(ii),ii=1,3)
     478                 :           0 :     ABI_ERROR(' RPRIMD IS NOT RELATED TO RPRIM AND MULTIPLICITY. MODIFY YOUR RPRIMD.')
     479                 :             :   end if
     480                 :             : 
     481                 :             : ! Check the diagonal elements
     482         [ +  + ]:          46 :   if ((Invar%bravais(1).eq.2).and.(Invar%bravais(2).eq.0)) then !monoclinic
     483   [ +  -  -  + ]:           1 :     if ((acell_unitcell(1).gt.acell_unitcell(3)).or.&
     484                 :             : &       (acell_unitcell(2).gt.acell_unitcell(3))) then
     485                 :           0 :       ABI_ERROR('You must set a,b <= c in the conventional lattice')
     486                 :             :     end if
     487         [ +  + ]:          45 :   else if ((Invar%bravais(1).eq.3).and.(Invar%bravais(2).eq.3)) then !C face centered orthorombique
     488         [ -  + ]:           7 :     if (acell_unitcell(1).ge.acell_unitcell(2)) then
     489                 :           0 :       ABI_ERROR('You must set a < b in the conventional lattice')
     490                 :             :     end if
     491         [ +  + ]:          38 :   else if (Invar%bravais(1).eq.6) then !hexagonal
     492         [ -  + ]:           5 :     if(abs(acell_unitcell(1)-acell_unitcell(2)).gt.tol8) then
     493                 :           0 :       ABI_ERROR(' STOP: THE PRECISION ON THE LATTICE PARAMETERS IS NOT SUFFICIENT')
     494                 :             :     end if
     495                 :           5 :     acell_unitcell(2)=acell_unitcell(1)
     496         [ +  + ]:          33 :   else if (Invar%bravais(1).eq.7) then !cubic
     497   [ +  -  -  + ]:          26 :     if((abs(acell_unitcell(1)-acell_unitcell(2)).gt.tol8).or.&
     498                 :             : &      (abs(acell_unitcell(2)-acell_unitcell(3)).gt.tol8)) then
     499                 :           0 :       ABI_ERROR('THE PRECISION ON THE LATTICE PARAMETERS IS NOT SUFFICIENT')
     500                 :             :     end if
     501                 :          26 :     acell_unitcell(2)=acell_unitcell(1)
     502                 :          26 :     acell_unitcell(3)=acell_unitcell(1)
     503                 :             :   end if
     504                 :          46 :   write(ab_out,'(a,1x,3(f16.10,1x))') ' acell_unitcell=',acell_unitcell(:)
     505                 :             : 
     506                 :             : ! Recompute rprimd_md with the symmetrized acell,
     507                 :             : ! in order to have a precision higher than 1.d-8.
     508   [ +  +  +  +  :        1840 :   rprimd_md = MATMUL(multiplicity, rprim)
                   +  + ]
     509         [ +  + ]:          46 :   if (line==0.or.line==1) then
     510         [ +  + ]:         148 :     do ii=1,3
     511         [ +  + ]:         481 :       do jj=1,3
     512                 :         444 :         rprimd_md(ii,jj) = acell_unitcell(ii) * rprimd_md(ii,jj)
     513                 :             :       end do
     514                 :             :     end do
     515                 :             :   else if (line==2) then
     516         [ +  + ]:          36 :     do ii=1,3
     517         [ +  + ]:         117 :       do jj=1,3
     518                 :         108 :         rprimd_md(ii,jj) = acell_unitcell(jj) * rprimd_md(ii,jj)
     519                 :             :       end do
     520                 :             :     end do
     521                 :             :   end if
     522         [ +  + ]:         184 :   do ii=1,3
     523                 :         184 :     write(ab_out,'(a,1x,3(f16.10,1x))') ' rprimd_md=',(rprimd_md(ii,jj),jj=1,3)
     524                 :             :   end do
     525                 :             : 
     526                 :             : ! Define the rprimd with respect to the acell_unitcell, according to the value of "line"
     527         [ +  + ]:          46 :   if (line==2) then
     528                 :           9 :     rprimd(1,1)=rprim(1,1)*acell_unitcell(1) ; rprimd(1,2)=rprim(1,2)*acell_unitcell(2) ; rprimd(1,3)=rprim(1,3)*acell_unitcell(3)
     529                 :           9 :     rprimd(2,1)=rprim(2,1)*acell_unitcell(1) ; rprimd(2,2)=rprim(2,2)*acell_unitcell(2) ; rprimd(2,3)=rprim(2,3)*acell_unitcell(3)
     530                 :           9 :     rprimd(3,1)=rprim(3,1)*acell_unitcell(1) ; rprimd(3,2)=rprim(3,2)*acell_unitcell(2) ; rprimd(3,3)=rprim(3,3)*acell_unitcell(3)
     531                 :             :   else if (line==0.or.line==1) then
     532                 :          37 :     rprimd(1,1)=rprim(1,1)*acell_unitcell(1) ; rprimd(1,2)=rprim(1,2)*acell_unitcell(1) ; rprimd(1,3)=rprim(1,3)*acell_unitcell(1)
     533                 :          37 :     rprimd(2,1)=rprim(2,1)*acell_unitcell(2) ; rprimd(2,2)=rprim(2,2)*acell_unitcell(2) ; rprimd(2,3)=rprim(2,3)*acell_unitcell(2)
     534                 :          37 :     rprimd(3,1)=rprim(3,1)*acell_unitcell(3) ; rprimd(3,2)=rprim(3,2)*acell_unitcell(3) ; rprimd(3,3)=rprim(3,3)*acell_unitcell(3)
     535                 :             :   end if
     536                 :             : 
     537                 :             : ! Define transpose and inverse of rprimd
     538   [ +  +  +  + ]:         598 :   rprimdt = TRANSPOSE(rprimd)
     539                 :             : 
     540                 :             :   ! Compute gmet, rmet, gprimd
     541                 :             :   ! ucvol is discarded here: it is recomputed from Lattice%rprimd and stored
     542                 :             :   ! in Model%ucvol, once the Model object is available (see tdep_model_init).
     543                 :          46 :   call metric(Lattice%gmet,Lattice%gprimd,std_out,Lattice%rmet,rprimdt,ucvol)
     544                 :             : 
     545                 :          46 :   call matr3inv(rprimd, rprimdtm1)
     546                 :          46 :   call matr3inv(rprimdt, rprimdm1)
     547                 :             : 
     548                 :             : ! Store all these values in the 'Lattice' datatype
     549         [ +  + ]:         184 :   Lattice%acell_unitcell(:)  =acell_unitcell(:)
     550                 :          46 :   Lattice%angle_alpha        =Invar%angle_alpha
     551                 :          46 :   Lattice%brav               =brav
     552         [ +  + ]:         552 :   Lattice%bravais(:)         =Invar%bravais(:)
     553                 :          46 :   Lattice%line               =line
     554   [ +  +  +  + ]:         598 :   Lattice%multiplicity  (:,:)=multiplicity(:,:)
     555   [ +  +  +  + ]:         598 :   Lattice%multiplicitym1(:,:)=multiplicitym1(:,:)
     556   [ +  +  +  + ]:         598 :   Lattice%rprim         (:,:)=rprim         (:,:)
     557   [ +  +  +  + ]:         598 :   Lattice%rprimt        (:,:)=rprimt        (:,:)
     558   [ +  +  +  + ]:         598 :   Lattice%rprimm1       (:,:)=rprimm1       (:,:)
     559   [ +  +  +  + ]:         598 :   Lattice%rprimd        (:,:)=rprimd        (:,:)
     560   [ +  +  +  + ]:         598 :   Lattice%rprimdm1      (:,:)=rprimdm1      (:,:)
     561   [ +  +  +  + ]:         598 :   Lattice%rprimdt       (:,:)=rprimdt       (:,:)
     562   [ +  +  +  + ]:         598 :   Lattice%rprimdtm1     (:,:)=rprimdtm1     (:,:)
     563   [ +  +  +  + ]:         598 :   Lattice%rprimd_md     (:,:)=rprimd_md     (:,:)
     564                 :             : 
     565                 :          46 :  end subroutine tdep_make_latt
     566                 :             : !!***
     567                 :             : 
     568                 :             : !=====================================================================================================
     569                 :             : 
     570                 :           0 : end module m_tdep_latt
     571                 :             : !!***
        

Generated by: LCOV version 2.3-1