LCOV - code coverage report
Current view: top level - src - cryssym.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 176 279 63.1 %
Date: 2024-11-21 06:45:46 Functions: 7 11 63.6 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief K-points and crystal symmetry routines
      10             : !> \author jgh
      11             : ! **************************************************************************************************
      12             : MODULE cryssym
      13             : 
      14             :    USE bibliography,                    ONLY: Togo2018,&
      15             :                                               cite_reference
      16             :    USE kinds,                           ONLY: dp
      17             :    USE kpsym,                           ONLY: group1s,&
      18             :                                               k290s
      19             :    USE spglib_f08,                      ONLY: spg_get_international,&
      20             :                                               spg_get_major_version,&
      21             :                                               spg_get_micro_version,&
      22             :                                               spg_get_minor_version,&
      23             :                                               spg_get_multiplicity,&
      24             :                                               spg_get_pointgroup,&
      25             :                                               spg_get_schoenflies,&
      26             :                                               spg_get_symmetry
      27             :    USE string_utilities,                ONLY: strip_control_codes
      28             : #include "./base/base_uses.f90"
      29             : 
      30             :    IMPLICIT NONE
      31             :    PRIVATE
      32             :    PUBLIC :: csym_type, release_csym_type, print_crys_symmetry, print_kp_symmetry
      33             :    PUBLIC :: crys_sym_gen, kpoint_gen
      34             : 
      35             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cryssym'
      36             : 
      37             : ! **************************************************************************************************
      38             : !> \brief CSM type
      39             : !> \par   Content:
      40             : !>
      41             : ! **************************************************************************************************
      42             :    TYPE csym_type
      43             :       LOGICAL                                     :: symlib = .FALSE.
      44             :       LOGICAL                                     :: fullgrid = .FALSE.
      45             :       INTEGER                                     :: plevel = 0
      46             :       INTEGER                                     :: punit = -1
      47             :       INTEGER                                     :: istriz = -1
      48             :       REAL(KIND=dp)                               :: delta = 1.0e-8_dp
      49             :       REAL(KIND=dp), DIMENSION(3, 3)              :: hmat = 0.0_dp
      50             :       ! KPOINTS
      51             :       REAL(KIND=dp), DIMENSION(3)                 :: wvk0 = 0.0_dp
      52             :       INTEGER, DIMENSION(3)                       :: mesh = 0
      53             :       INTEGER                                     :: nkpoint = 0
      54             :       INTEGER                                     :: nat = 0
      55             :       INTEGER, DIMENSION(:), ALLOCATABLE          :: atype
      56             :       REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: scoord
      57             :       REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: xkpoint
      58             :       REAL(KIND=dp), DIMENSION(:), ALLOCATABLE    :: wkpoint
      59             :       REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: kpmesh
      60             :       INTEGER, DIMENSION(:, :), ALLOCATABLE       :: kplink
      61             :       INTEGER, DIMENSION(:), ALLOCATABLE          :: kpop
      62             :       !SPGLIB
      63             :       CHARACTER(len=11)                           :: international_symbol = ""
      64             :       CHARACTER(len=6)                            :: pointgroup_symbol = ""
      65             :       CHARACTER(len=10)                           :: schoenflies = ""
      66             :       INTEGER                                     :: n_operations = 0
      67             :       INTEGER, DIMENSION(:, :, :), ALLOCATABLE    :: rotations
      68             :       REAL(KIND=dp), DIMENSION(:, :), ALLOCATABLE :: translations
      69             :       !K290
      70             :       REAL(KIND=dp), DIMENSION(3, 3, 48)          :: rt = 0.0_dp
      71             :       REAL(KIND=dp), DIMENSION(3, 48)             :: vt = 0.0_dp
      72             :       INTEGER, ALLOCATABLE, DIMENSION(:, :)       :: f0
      73             :       INTEGER                                     :: nrtot = 0
      74             :       INTEGER, DIMENSION(48)                      :: ibrot = 1
      75             :    END TYPE csym_type
      76             : 
      77             : CONTAINS
      78             : 
      79             : ! **************************************************************************************************
      80             : !> \brief Release the CSYM type
      81             : !> \param csym  The CSYM type
      82             : ! **************************************************************************************************
      83         435 :    SUBROUTINE release_csym_type(csym)
      84             :       TYPE(csym_type)                                    :: csym
      85             : 
      86         435 :       IF (ALLOCATED(csym%rotations)) THEN
      87         434 :          DEALLOCATE (csym%rotations)
      88             :       END IF
      89         435 :       IF (ALLOCATED(csym%translations)) THEN
      90         434 :          DEALLOCATE (csym%translations)
      91             :       END IF
      92         435 :       IF (ALLOCATED(csym%atype)) THEN
      93         435 :          DEALLOCATE (csym%atype)
      94             :       END IF
      95         435 :       IF (ALLOCATED(csym%scoord)) THEN
      96         435 :          DEALLOCATE (csym%scoord)
      97             :       END IF
      98         435 :       IF (ALLOCATED(csym%xkpoint)) THEN
      99         142 :          DEALLOCATE (csym%xkpoint)
     100             :       END IF
     101         435 :       IF (ALLOCATED(csym%wkpoint)) THEN
     102         142 :          DEALLOCATE (csym%wkpoint)
     103             :       END IF
     104         435 :       IF (ALLOCATED(csym%kpmesh)) THEN
     105         142 :          DEALLOCATE (csym%kpmesh)
     106             :       END IF
     107         435 :       IF (ALLOCATED(csym%kplink)) THEN
     108         142 :          DEALLOCATE (csym%kplink)
     109             :       END IF
     110         435 :       IF (ALLOCATED(csym%kpop)) THEN
     111         142 :          DEALLOCATE (csym%kpop)
     112             :       END IF
     113         435 :       IF (ALLOCATED(csym%f0)) THEN
     114           0 :          DEALLOCATE (csym%f0)
     115             :       END IF
     116             : 
     117         435 :    END SUBROUTINE release_csym_type
     118             : 
     119             : ! **************************************************************************************************
     120             : !> \brief ...
     121             : !> \param csym ...
     122             : !> \param scoor ...
     123             : !> \param types ...
     124             : !> \param hmat ...
     125             : !> \param delta ...
     126             : !> \param iounit ...
     127             : ! **************************************************************************************************
     128         435 :    SUBROUTINE crys_sym_gen(csym, scoor, types, hmat, delta, iounit)
     129             :       TYPE(csym_type)                                    :: csym
     130             :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: scoor
     131             :       INTEGER, DIMENSION(:), INTENT(IN)                  :: types
     132             :       REAL(KIND=dp), INTENT(IN)                          :: hmat(3, 3)
     133             :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: delta
     134             :       INTEGER, INTENT(IN), OPTIONAL                      :: iounit
     135             : 
     136             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'crys_sym_gen'
     137             : 
     138             :       INTEGER                                            :: handle, ierr, major, micro, minor, nat, &
     139             :                                                             nop, tra_mat(3, 3)
     140             :       LOGICAL                                            :: spglib
     141             : 
     142         435 :       CALL timeset(routineN, handle)
     143             : 
     144             :       !..total number of atoms
     145         435 :       nat = SIZE(scoor, 2)
     146         435 :       csym%nat = nat
     147             : 
     148             :       ! output unit
     149         435 :       IF (PRESENT(iounit)) THEN
     150         435 :          csym%punit = iounit
     151             :       ELSE
     152           0 :          csym%punit = -1
     153             :       END IF
     154             : 
     155             :       ! accuracy for symmetry
     156         435 :       IF (PRESENT(delta)) THEN
     157         435 :          csym%delta = delta
     158             :       ELSE
     159           0 :          csym%delta = 1.e-6_dp
     160             :       END IF
     161             : 
     162             :       !..set cell values
     163        5655 :       csym%hmat = hmat
     164             : 
     165             :       ! atom types
     166        1305 :       ALLOCATE (csym%atype(nat))
     167        5760 :       csym%atype(1:nat) = types(1:nat)
     168             : 
     169             :       ! scaled coordinates
     170        1305 :       ALLOCATE (csym%scoord(3, nat))
     171       21735 :       csym%scoord(1:3, 1:nat) = scoor(1:3, 1:nat)
     172             : 
     173         435 :       csym%n_operations = 0
     174             : 
     175             :       !..try spglib
     176         435 :       major = spg_get_major_version()
     177         435 :       minor = spg_get_minor_version()
     178         435 :       micro = spg_get_micro_version()
     179         435 :       IF (major == 0) THEN
     180           0 :          CALL cp_warn(__LOCATION__, "Symmetry library SPGLIB not available")
     181           0 :          spglib = .FALSE.
     182             :       ELSE
     183         435 :          spglib = .TRUE.
     184         435 :          CALL cite_reference(Togo2018)
     185         435 :          ierr = spg_get_international(csym%international_symbol, TRANSPOSE(hmat), scoor, types, nat, delta)
     186         435 :          IF (ierr == 0) THEN
     187           1 :             CALL cp_warn(__LOCATION__, "Symmetry Library SPGLIB failed")
     188           1 :             spglib = .FALSE.
     189             :          ELSE
     190         434 :             nop = spg_get_multiplicity(TRANSPOSE(hmat), scoor, types, nat, delta)
     191        2170 :             ALLOCATE (csym%rotations(3, 3, nop), csym%translations(3, nop))
     192         434 :             csym%n_operations = nop
     193             :             ierr = spg_get_symmetry(csym%rotations, csym%translations, nop, &
     194         434 :                                     TRANSPOSE(hmat), scoor, types, nat, delta)
     195             :             ! Schoenflies Symbol
     196         434 :             csym%schoenflies = ' '
     197         434 :             ierr = spg_get_schoenflies(csym%schoenflies, TRANSPOSE(hmat), scoor, types, nat, delta)
     198             :             ! Point Group
     199         434 :             csym%pointgroup_symbol = ' '
     200         434 :             tra_mat = 0
     201             :             ierr = spg_get_pointgroup(csym%pointgroup_symbol, tra_mat, &
     202         434 :                                       csym%rotations, csym%n_operations)
     203             : 
     204         434 :             CALL strip_control_codes(csym%international_symbol)
     205         434 :             CALL strip_control_codes(csym%schoenflies)
     206         434 :             CALL strip_control_codes(csym%pointgroup_symbol)
     207             :          END IF
     208             :       END IF
     209         435 :       csym%symlib = spglib
     210             : 
     211         435 :       CALL timestop(handle)
     212             : 
     213         435 :    END SUBROUTINE crys_sym_gen
     214             : 
     215             : ! **************************************************************************************************
     216             : !> \brief ...
     217             : !> \param csym ...
     218             : !> \param nk ...
     219             : !> \param symm ...
     220             : !> \param shift ...
     221             : !> \param full_grid ...
     222             : ! **************************************************************************************************
     223         142 :    SUBROUTINE kpoint_gen(csym, nk, symm, shift, full_grid)
     224             :       TYPE(csym_type)                                    :: csym
     225             :       INTEGER, INTENT(IN)                                :: nk(3)
     226             :       LOGICAL, INTENT(IN), OPTIONAL                      :: symm
     227             :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: shift(3)
     228             :       LOGICAL, INTENT(IN), OPTIONAL                      :: full_grid
     229             : 
     230             :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'kpoint_gen'
     231             : 
     232             :       INTEGER                                            :: handle, i, ik, j, nkp, nkpts
     233         142 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: kpop, xptr
     234             :       LOGICAL                                            :: fullmesh
     235         142 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: wkp
     236         142 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: xkp
     237             : 
     238         142 :       CALL timeset(routineN, handle)
     239             : 
     240         142 :       IF (PRESENT(shift)) THEN
     241         568 :          csym%wvk0 = shift
     242             :       ELSE
     243           0 :          csym%wvk0 = 0.0_dp
     244             :       END IF
     245             : 
     246         142 :       csym%istriz = -1
     247         142 :       IF (PRESENT(symm)) THEN
     248         142 :          IF (symm) csym%istriz = 1
     249             :       END IF
     250             : 
     251         142 :       IF (PRESENT(full_grid)) THEN
     252         142 :          fullmesh = full_grid
     253             :       ELSE
     254             :          fullmesh = .FALSE.
     255             :       END IF
     256         142 :       csym%fullgrid = fullmesh
     257             : 
     258         142 :       csym%nkpoint = 0
     259         568 :       csym%mesh(1:3) = nk(1:3)
     260             : 
     261         142 :       nkpts = nk(1)*nk(2)*nk(3)
     262         994 :       ALLOCATE (xkp(3, nkpts), wkp(nkpts), kpop(nkpts))
     263             :       ! kp: link
     264         426 :       ALLOCATE (csym%kplink(2, nkpts))
     265        9460 :       csym%kplink = 0
     266             : 
     267             :       ! go through all the options
     268         142 :       IF (csym%symlib) THEN
     269             :          ! symmetry library is available
     270         142 :          IF (fullmesh) THEN
     271             :             ! full mesh requested
     272          60 :             CALL full_grid_gen(nk, xkp, wkp, shift)
     273          60 :             IF (csym%istriz == 1) THEN
     274             :                ! use inversion symmetry
     275          48 :                CALL inversion_symm(xkp, wkp, csym%kplink(1, :))
     276             :             ELSE
     277             :                ! full kpoint mesh is used
     278             :             END IF
     279          82 :          ELSE IF (csym%istriz /= 1) THEN
     280             :             ! use inversion symmetry
     281          82 :             CALL full_grid_gen(nk, xkp, wkp, shift)
     282          82 :             CALL inversion_symm(xkp, wkp, csym%kplink(1, :))
     283             :          ELSE
     284             :             ! use symmetry library to reduce k-points
     285           0 :             IF (SUM(ABS(csym%wvk0)) /= 0.0_dp) THEN
     286             :                CALL cp_abort(__LOCATION__, "MacDonald shifted k-point meshes are only "// &
     287           0 :                              "possible without symmetrization.")
     288             :             END IF
     289             : 
     290           0 :             CALL full_grid_gen(nk, xkp, wkp, shift)
     291           0 :             CALL kp_symmetry(csym, xkp, wkp, kpop)
     292             : 
     293             :          END IF
     294             :       ELSE
     295             :          ! no symmetry library is available
     296           0 :          CALL full_grid_gen(nk, xkp, wkp, shift)
     297           0 :          IF (csym%istriz /= 1 .AND. fullmesh) THEN
     298             :             ! full kpoint mesh is used
     299           0 :             DO i = 1, nkpts
     300           0 :                csym%kplink(1, i) = i
     301             :             END DO
     302             :          ELSE
     303             :             ! use inversion symmetry
     304           0 :             CALL inversion_symm(xkp, wkp, csym%kplink(1, :))
     305             :          END IF
     306             :       END IF
     307             :       ! count kpoints
     308         142 :       nkp = 0
     309        3248 :       DO i = 1, nkpts
     310        3248 :          IF (wkp(i) > 0.0_dp) nkp = nkp + 1
     311             :       END DO
     312             : 
     313             :       ! store reduced kpoint set
     314         142 :       csym%nkpoint = nkp
     315         710 :       ALLOCATE (csym%xkpoint(3, nkp), csym%wkpoint(nkp))
     316         426 :       ALLOCATE (xptr(nkp))
     317        3248 :       j = 0
     318        3248 :       DO ik = 1, nkpts
     319        3248 :          IF (wkp(ik) > 0.0_dp) THEN
     320        1608 :             j = j + 1
     321        1608 :             csym%wkpoint(j) = wkp(ik)
     322        6432 :             csym%xkpoint(1:3, j) = xkp(1:3, ik)
     323        1608 :             xptr(j) = ik
     324             :          END IF
     325             :       END DO
     326         142 :       CPASSERT(j == nkp)
     327             : 
     328             :       ! kp: mesh
     329         284 :       ALLOCATE (csym%kpmesh(3, nkpts))
     330       12566 :       csym%kpmesh(1:3, 1:nkpts) = xkp(1:3, 1:nkpts)
     331             : 
     332             :       ! kp: link
     333        3248 :       DO ik = 1, nkpts
     334        3106 :          i = csym%kplink(1, ik)
     335       73574 :          DO j = 1, nkp
     336       73432 :             IF (i == xptr(j)) THEN
     337        3030 :                csym%kplink(2, ik) = j
     338        3030 :                EXIT
     339             :             END IF
     340             :          END DO
     341             :       END DO
     342         142 :       DEALLOCATE (xptr)
     343             : 
     344             :       ! kp: operations
     345         284 :       ALLOCATE (csym%kpop(nkpts))
     346         142 :       IF (csym%symlib .AND. csym%istriz == 1 .AND. .NOT. fullmesh) THEN
     347             :          ! atomic symmetry operations possible
     348           0 :          csym%kpop(1:nkpts) = kpop(1:nkpts)
     349           0 :          DO ik = 1, nkpts
     350           0 :             CPASSERT(csym%kpop(ik) /= 0)
     351             :          END DO
     352             :       ELSE
     353             :          ! only time reversal symmetry
     354        3248 :          DO ik = 1, nkpts
     355        3248 :             IF (wkp(ik) > 0.0_dp) THEN
     356        1608 :                csym%kpop(ik) = 1
     357             :             ELSE
     358        1498 :                csym%kpop(ik) = 2
     359             :             END IF
     360             :          END DO
     361             :       END IF
     362             : 
     363         142 :       DEALLOCATE (xkp, wkp, kpop)
     364             : 
     365         142 :       CALL timestop(handle)
     366             : 
     367         142 :    END SUBROUTINE kpoint_gen
     368             : 
     369             : ! **************************************************************************************************
     370             : !> \brief ...
     371             : !> \param csym ...
     372             : !> \param xkp ...
     373             : !> \param wkp ...
     374             : !> \param kpop ...
     375             : ! **************************************************************************************************
     376           0 :    SUBROUTINE kp_symmetry(csym, xkp, wkp, kpop)
     377             :       TYPE(csym_type)                                    :: csym
     378             :       REAL(KIND=dp), DIMENSION(:, :)                     :: xkp
     379             :       REAL(KIND=dp), DIMENSION(:)                        :: wkp
     380             :       INTEGER, DIMENSION(:)                              :: kpop
     381             : 
     382             :       INTEGER                                            :: i, ihc, ihg, ik, indpg, iou, iq1, iq2, &
     383             :                                                             iq3, istriz, isy, itoj, j, kr, li, lr, &
     384             :                                                             nat, nc, nhash, nkm, nkp, nkpoint, &
     385             :                                                             nsp, ntvec
     386           0 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: includ, isc, list, lwght, ty
     387           0 :       INTEGER, ALLOCATABLE, DIMENSION(:, :)              :: f0, lrot
     388             :       INTEGER, DIMENSION(48)                             :: ib
     389             :       REAL(KIND=dp)                                      :: alat
     390           0 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: rlist, rx, tvec, wvkl, xkapa
     391             :       REAL(KIND=dp), DIMENSION(3)                        :: a1, a2, a3, b1, b2, b3, origin, rr, wvk0
     392             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: hmat, strain
     393             :       REAL(KIND=dp), DIMENSION(3, 3, 48)                 :: r
     394             :       REAL(KIND=dp), DIMENSION(3, 48)                    :: vt
     395             : 
     396           0 :       iou = csym%punit
     397           0 :       hmat = csym%hmat
     398           0 :       nat = csym%nat
     399           0 :       iq1 = csym%mesh(1)
     400           0 :       iq2 = csym%mesh(2)
     401           0 :       iq3 = csym%mesh(3)
     402             :       nkpoint = 10*iq1*iq2*iq3
     403           0 :       nkpoint = 2*MAX(iq1, iq2, iq3)**3
     404           0 :       wvk0 = csym%wvk0
     405           0 :       istriz = csym%istriz
     406           0 :       a1(1:3) = hmat(1:3, 1)
     407           0 :       a2(1:3) = hmat(1:3, 2)
     408           0 :       a3(1:3) = hmat(1:3, 3)
     409           0 :       alat = hmat(1, 1)
     410           0 :       strain = 0.0_dp
     411           0 :       ALLOCATE (xkapa(3, nat), rx(3, nat), tvec(3, 200), ty(nat), isc(nat), f0(49, nat))
     412           0 :       ty(1:nat) = csym%atype(1:nat)
     413           0 :       nsp = MAXVAL(ty)
     414           0 :       DO i = 1, nat
     415           0 :          xkapa(1:3, i) = MATMUL(hmat, csym%scoord(1:3, i))
     416             :       END DO
     417           0 :       nhash = 1000
     418           0 :       ALLOCATE (wvkl(3, nkpoint), rlist(3, nkpoint), includ(nkpoint), list(nhash + nkpoint))
     419           0 :       ALLOCATE (lrot(48, nkpoint), lwght(nkpoint))
     420             : 
     421           0 :       IF (iou > 0) THEN
     422             :          WRITE (iou, '(/,(T2,A79))') &
     423           0 :             "*******************************************************************************", &
     424           0 :             "**                      Special K-Point Generation by K290                   **", &
     425           0 :             "*******************************************************************************"
     426             :       END IF
     427             : 
     428             :       CALL K290s(iou, nat, nkpoint, nsp, iq1, iq2, iq3, istriz, &
     429             :                  a1, a2, a3, alat, strain, xkapa, rx, tvec, &
     430             :                  ty, isc, f0, ntvec, wvk0, wvkl, lwght, lrot, &
     431           0 :                  nhash, includ, list, rlist, csym%delta)
     432             : 
     433             :       CALL GROUP1s(0, a1, a2, a3, nat, ty, xkapa, b1, b2, b3, &
     434             :                    ihg, ihc, isy, li, nc, indpg, ib, ntvec, &
     435           0 :                    vt, f0, r, tvec, origin, rx, isc, csym%delta)
     436             : 
     437           0 :       IF (iou > 0) THEN
     438             :          WRITE (iou, '((T2,A79))') &
     439           0 :             "*******************************************************************************", &
     440           0 :             "**                              Finished K290                                **", &
     441           0 :             "*******************************************************************************"
     442             :       END IF
     443             : 
     444           0 :       csym%rt = r
     445           0 :       csym%vt = vt
     446           0 :       csym%nrtot = nc
     447           0 :       ALLOCATE (csym%f0(nat, nc))
     448           0 :       DO i = 1, nc
     449           0 :          csym%f0(1:nat, i) = f0(i, 1:nat)
     450             :       END DO
     451           0 :       csym%ibrot = 0
     452           0 :       csym%ibrot(1:nc) = ib(1:nc)
     453             : 
     454           0 :       kpop = 0
     455           0 :       nkm = iq1*iq2*iq3
     456           0 :       nkp = 0
     457           0 :       DO i = 1, nkm
     458           0 :          IF (lwght(i) == 0) EXIT
     459           0 :          nkp = nkp + 1
     460             :       END DO
     461           0 :       wkp = 0
     462             :       ik = 0
     463           0 :       DO i = 1, nkp
     464           0 :          DO j = 1, nkm
     465           0 :             wvk0(1:3) = xkp(1:3, j) - wvkl(1:3, i)
     466           0 :             IF (ALL(ABS(wvk0(1:3)) < 1.e-12_dp)) THEN
     467           0 :                wkp(j) = lwght(i)
     468           0 :                itoj = j
     469           0 :                EXIT
     470             :             END IF
     471             :          END DO
     472           0 :          DO lr = 1, lwght(i)
     473           0 :             kr = lrot(lr, i)
     474           0 :             rr(1:3) = kp_apply_operation(wvkl(1:3, i), r(1:3, 1:3, ABS(kr)))
     475           0 :             IF (kr < 0) rr(1:3) = -rr(1:3)
     476           0 :             DO j = 1, nkm
     477           0 :                wvk0(1:3) = xkp(1:3, j) - rr(1:3)
     478           0 :                IF (ALL(ABS(wvk0(1:3)) < 1.e-12_dp)) THEN
     479           0 :                   csym%kplink(1, j) = itoj
     480           0 :                   kpop(j) = kr
     481           0 :                   EXIT
     482             :                END IF
     483             :             END DO
     484             :          END DO
     485             :       END DO
     486           0 :       DEALLOCATE (xkapa, rx, tvec, ty, isc, f0)
     487           0 :       DEALLOCATE (wvkl, rlist, includ, list)
     488           0 :       DEALLOCATE (lrot, lwght)
     489             : 
     490           0 :    END SUBROUTINE kp_symmetry
     491             : ! **************************************************************************************************
     492             : !> \brief ...
     493             : !> \param nk ...
     494             : !> \param xkp ...
     495             : !> \param wkp ...
     496             : !> \param shift ...
     497             : ! **************************************************************************************************
     498         142 :    SUBROUTINE full_grid_gen(nk, xkp, wkp, shift)
     499             :       INTEGER, INTENT(IN)                                :: nk(3)
     500             :       REAL(KIND=dp), DIMENSION(:, :)                     :: xkp
     501             :       REAL(KIND=dp), DIMENSION(:)                        :: wkp
     502             :       REAL(KIND=dp), INTENT(IN)                          :: shift(3)
     503             : 
     504             :       INTEGER                                            :: i, ix, iy, iz
     505             :       REAL(KIND=dp)                                      :: kpt_latt(3)
     506             : 
     507        3248 :       wkp = 0.0_dp
     508         142 :       i = 0
     509         494 :       DO ix = 1, nk(1)
     510        1488 :          DO iy = 1, nk(2)
     511        4452 :             DO iz = 1, nk(3)
     512        3106 :                i = i + 1
     513        3106 :                kpt_latt(1) = REAL(2*ix - nk(1) - 1, KIND=dp)/(2._dp*REAL(nk(1), KIND=dp))
     514        3106 :                kpt_latt(2) = REAL(2*iy - nk(2) - 1, KIND=dp)/(2._dp*REAL(nk(2), KIND=dp))
     515        3106 :                kpt_latt(3) = REAL(2*iz - nk(3) - 1, KIND=dp)/(2._dp*REAL(nk(3), KIND=dp))
     516       12424 :                xkp(1:3, i) = kpt_latt(1:3)
     517        4100 :                wkp(i) = 1.0_dp
     518             :             END DO
     519             :          END DO
     520             :       END DO
     521        3248 :       DO i = 1, nk(1)*nk(2)*nk(3)
     522       12566 :          xkp(1:3, i) = xkp(1:3, i) + shift(1:3)
     523             :       END DO
     524             : 
     525         142 :    END SUBROUTINE full_grid_gen
     526             : 
     527             : ! **************************************************************************************************
     528             : !> \brief ...
     529             : !> \param xkp ...
     530             : !> \param wkp ...
     531             : !> \param link ...
     532             : ! **************************************************************************************************
     533         130 :    SUBROUTINE inversion_symm(xkp, wkp, link)
     534             :       REAL(KIND=dp), DIMENSION(:, :)                     :: xkp
     535             :       REAL(KIND=dp), DIMENSION(:)                        :: wkp
     536             :       INTEGER, DIMENSION(:)                              :: link
     537             : 
     538             :       INTEGER                                            :: i, j, nkpts
     539             : 
     540         130 :       nkpts = SIZE(wkp, 1)
     541             : 
     542        3160 :       link(:) = 0
     543        3160 :       DO i = 1, nkpts
     544        3030 :          IF (link(i) == 0) link(i) = i
     545      107768 :          DO j = i + 1, nkpts
     546      106106 :             IF (wkp(j) == 0) CYCLE
     547       92268 :             IF (ALL(xkp(:, i) == -xkp(:, j))) THEN
     548        1498 :                wkp(i) = wkp(i) + wkp(j)
     549        1498 :                wkp(j) = 0.0_dp
     550        1498 :                link(j) = i
     551        1498 :                EXIT
     552             :             END IF
     553             :          END DO
     554             :       END DO
     555             : 
     556         130 :    END SUBROUTINE inversion_symm
     557             : 
     558             : ! **************************************************************************************************
     559             : !> \brief ...
     560             : !> \param x ...
     561             : !> \param r ...
     562             : !> \return ...
     563             : ! **************************************************************************************************
     564           0 :    FUNCTION kp_apply_operation(x, r) RESULT(y)
     565             :       REAL(KIND=dp), INTENT(IN)                          :: x(3), r(3, 3)
     566             :       REAL(KIND=dp)                                      :: y(3)
     567             : 
     568           0 :       y(1) = r(1, 1)*x(1) + r(1, 2)*x(2) + r(1, 3)*x(3)
     569           0 :       y(2) = r(2, 1)*x(1) + r(2, 2)*x(2) + r(2, 3)*x(3)
     570           0 :       y(3) = r(3, 1)*x(1) + r(3, 2)*x(2) + r(3, 3)*x(3)
     571             : 
     572           0 :    END FUNCTION kp_apply_operation
     573             : 
     574             : ! **************************************************************************************************
     575             : !> \brief ...
     576             : !> \param csym ...
     577             : ! **************************************************************************************************
     578         341 :    SUBROUTINE print_crys_symmetry(csym)
     579             :       TYPE(csym_type)                                    :: csym
     580             : 
     581             :       INTEGER                                            :: i, iunit, j, plevel
     582             : 
     583         341 :       iunit = csym%punit
     584         341 :       IF (iunit >= 0) THEN
     585         296 :          plevel = csym%plevel
     586         296 :          WRITE (iunit, "(/,T2,A)") "Crystal Symmetry Information"
     587         296 :          IF (csym%symlib) THEN
     588         295 :             WRITE (iunit, '(A,T71,A10)') "       International Symbol: ", ADJUSTR(TRIM(csym%international_symbol))
     589         295 :             WRITE (iunit, '(A,T71,A10)') "       Point Group Symbol: ", ADJUSTR(TRIM(csym%pointgroup_symbol))
     590         295 :             WRITE (iunit, '(A,T71,A10)') "       Schoenflies Symbol: ", ADJUSTR(TRIM(csym%schoenflies))
     591             :             !
     592         295 :             WRITE (iunit, '(A,T71,I10)') "       Number of Symmetry Operations: ", csym%n_operations
     593         295 :             IF (plevel > 0) THEN
     594           0 :                DO i = 1, csym%n_operations
     595             :                   WRITE (iunit, '(A,i4,T51,3I10,/,T51,3I10,/,T51,3I10)') &
     596           0 :                      "           Rotation #: ", i, (csym%rotations(j, :, i), j=1, 3)
     597           0 :                   WRITE (iunit, '(T36,3F15.7)') csym%translations(:, i)
     598             :                END DO
     599             :             END IF
     600             :          ELSE
     601           1 :             WRITE (iunit, "(T2,A)") "SPGLIB for Crystal Symmetry Information determination is not availale"
     602             :          END IF
     603             :       END IF
     604             : 
     605         341 :    END SUBROUTINE print_crys_symmetry
     606             : 
     607             : ! **************************************************************************************************
     608             : !> \brief ...
     609             : !> \param csym ...
     610             : ! **************************************************************************************************
     611          48 :    SUBROUTINE print_kp_symmetry(csym)
     612             :       TYPE(csym_type), INTENT(IN)                        :: csym
     613             : 
     614             :       INTEGER                                            :: i, iunit, nat, plevel
     615             : 
     616          48 :       iunit = csym%punit
     617          48 :       IF (iunit >= 0) THEN
     618           3 :          plevel = csym%plevel
     619           3 :          WRITE (iunit, "(/,T2,A)") "K-point Symmetry Information"
     620           3 :          WRITE (iunit, '(A,T67,I14)') "       Number of Special K-points: ", csym%nkpoint
     621           3 :          WRITE (iunit, '(T19,A,T74,A)') " Wavevector Basis ", " Weight"
     622         175 :          DO i = 1, csym%nkpoint
     623         175 :             WRITE (iunit, '(T2,i10,3F10.5,T71,I10)') i, csym%xkpoint(1:3, i), NINT(csym%wkpoint(i))
     624             :          END DO
     625           3 :          WRITE (iunit, '(/,A,T63,3I6)') "       K-point Mesh: ", csym%mesh(1), csym%mesh(2), csym%mesh(3)
     626           3 :          WRITE (iunit, '(T19,A,T54,A)') " Wavevector Basis ", " Special Points    Rotation"
     627         347 :          DO i = 1, csym%mesh(1)*csym%mesh(2)*csym%mesh(3)
     628         344 :             WRITE (iunit, '(T2,i10,3F10.5,T45,3I12)') i, csym%kpmesh(1:3, i), &
     629         691 :                csym%kplink(1:2, i), csym%kpop(i)
     630             :          END DO
     631           3 :          IF (csym%nrtot > 0) THEN
     632           0 :             WRITE (iunit, '(/,A)') "       Atom Transformation Table"
     633           0 :             nat = SIZE(csym%f0, 1)
     634           0 :             DO i = 1, csym%nrtot
     635           0 :                WRITE (iunit, '(T10,A,I3,(T21,12I5))') " Rot=", csym%ibrot(i), csym%f0(1:nat, i)
     636             :             END DO
     637             :          END IF
     638             :       END IF
     639             : 
     640          48 :    END SUBROUTINE print_kp_symmetry
     641             : 
     642           0 : END MODULE cryssym

Generated by: LCOV version 1.15