LCOV - code coverage report
Current view: top level - src - qs_band_structure.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:06f838d) Lines: 91.8 % 195 179
Test Date: 2026-06-05 07:04:50 Functions: 100.0 % 4 4

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Calculation of band structures
      10              : !> \par History
      11              : !>       2015.06 created [JGH]
      12              : !> \author JGH
      13              : ! **************************************************************************************************
      14              : MODULE qs_band_structure
      15              :    USE cell_types,                      ONLY: cell_type
      16              :    USE cp_blacs_env,                    ONLY: cp_blacs_env_type
      17              :    USE cp_control_types,                ONLY: dft_control_type
      18              :    USE cp_dbcsr_api,                    ONLY: dbcsr_p_type
      19              :    USE cp_files,                        ONLY: close_file,&
      20              :                                               open_file
      21              :    USE cp_log_handling,                 ONLY: cp_logger_get_default_io_unit
      22              :    USE cp_parser_methods,               ONLY: read_float_object
      23              :    USE input_section_types,             ONLY: section_vals_get,&
      24              :                                               section_vals_get_subs_vals,&
      25              :                                               section_vals_type,&
      26              :                                               section_vals_val_get
      27              :    USE kinds,                           ONLY: default_string_length,&
      28              :                                               dp,&
      29              :                                               max_line_length
      30              :    USE kpoint_methods,                  ONLY: kpoint_env_initialize,&
      31              :                                               kpoint_init_cell_index,&
      32              :                                               kpoint_initialize_mo_set,&
      33              :                                               kpoint_initialize_mos
      34              :    USE kpoint_types,                    ONLY: get_kpoint_info,&
      35              :                                               kpoint_create,&
      36              :                                               kpoint_env_type,&
      37              :                                               kpoint_release,&
      38              :                                               kpoint_sym_create,&
      39              :                                               kpoint_type
      40              :    USE machine,                         ONLY: m_walltime
      41              :    USE mathconstants,                   ONLY: twopi
      42              :    USE message_passing,                 ONLY: mp_para_env_type
      43              :    USE physcon,                         ONLY: angstrom,&
      44              :                                               evolt
      45              :    USE qs_environment_types,            ONLY: get_qs_env,&
      46              :                                               qs_env_release,&
      47              :                                               qs_environment_type
      48              :    USE qs_gamma2kp,                     ONLY: create_kp_from_gamma
      49              :    USE qs_mo_types,                     ONLY: get_mo_set
      50              :    USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
      51              :    USE qs_scf_diagonalization,          ONLY: do_general_diag_kp
      52              :    USE qs_scf_types,                    ONLY: qs_scf_env_type
      53              :    USE scf_control_types,               ONLY: scf_control_type
      54              :    USE string_utilities,                ONLY: uppercase
      55              : #include "./base/base_uses.f90"
      56              : 
      57              :    IMPLICIT NONE
      58              : 
      59              :    PRIVATE
      60              : 
      61              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_band_structure'
      62              : 
      63              :    PUBLIC :: calculate_band_structure, calculate_kp_orbitals, calculate_kpoints_for_bs
      64              : 
      65              : ! **************************************************************************************************
      66              : 
      67              : CONTAINS
      68              : 
      69              : ! **************************************************************************************************
      70              : !> \brief Main routine for band structure calculation
      71              : !> \param qs_env ...
      72              : !> \author JGH
      73              : ! **************************************************************************************************
      74        51410 :    SUBROUTINE calculate_band_structure(qs_env)
      75              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      76              : 
      77              :       LOGICAL                                            :: do_kpoints, explicit
      78              :       TYPE(section_vals_type), POINTER                   :: bs_input
      79              : 
      80        25705 :       bs_input => section_vals_get_subs_vals(qs_env%input, "DFT%PRINT%BAND_STRUCTURE")
      81        25705 :       CALL section_vals_get(bs_input, explicit=explicit)
      82        25705 :       IF (explicit) THEN
      83            8 :          CALL get_qs_env(qs_env, do_kpoints=do_kpoints)
      84            8 :          IF (do_kpoints) THEN
      85            6 :             CALL do_calculate_band_structure(qs_env)
      86              :          ELSE
      87              :             BLOCK
      88              :                TYPE(qs_environment_type), POINTER :: qs_env_kp
      89            2 :                CALL create_kp_from_gamma(qs_env, qs_env_kp)
      90            2 :                CALL do_calculate_band_structure(qs_env_kp)
      91            2 :                CALL qs_env_release(qs_env_kp)
      92            2 :                DEALLOCATE (qs_env_kp)
      93              :             END BLOCK
      94              :          END IF
      95              :       END IF
      96              : 
      97        25705 :    END SUBROUTINE calculate_band_structure
      98              : 
      99              : ! **************************************************************************************************
     100              : !> \brief band structure calculation
     101              : !> \param qs_env ...
     102              : !> \author JGH
     103              : ! **************************************************************************************************
     104           16 :    SUBROUTINE do_calculate_band_structure(qs_env)
     105              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     106              : 
     107              :       CHARACTER(LEN=default_string_length)               :: filename, ustr
     108              :       CHARACTER(LEN=default_string_length), &
     109            8 :          DIMENSION(:), POINTER                           :: spname, strptr
     110              :       CHARACTER(LEN=max_line_length)                     :: error_message
     111              :       INTEGER                                            :: bs_data_unit, i, i_rep, ik, ikk, ikpgr, &
     112              :                                                             imo, ip, ispin, n_ptr, n_rep, nadd, &
     113              :                                                             nkp, nmo, npline, npoints, nspins, &
     114              :                                                             unit_nr
     115              :       INTEGER, DIMENSION(2)                              :: kp_range
     116              :       LOGICAL                                            :: explicit, io_default, my_kpgrp
     117              :       REAL(KIND=dp)                                      :: t1, t2
     118              :       REAL(KIND=dp), DIMENSION(3)                        :: kpptr
     119              :       REAL(KIND=dp), DIMENSION(3, 3)                     :: cart_hmat
     120            8 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: eigenvalues, eigval, occnum, &
     121            8 :                                                             occupation_numbers, wkp
     122            8 :       REAL(kind=dp), DIMENSION(:, :), POINTER            :: kpgeneral, kspecial, xkp
     123              :       TYPE(cell_type), POINTER                           :: cell
     124              :       TYPE(dft_control_type), POINTER                    :: dft_control
     125              :       TYPE(kpoint_env_type), POINTER                     :: kp
     126              :       TYPE(kpoint_type), POINTER                         :: kpoint
     127              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     128              :       TYPE(section_vals_type), POINTER                   :: bs_input, kpset
     129              : 
     130           16 :       bs_input => section_vals_get_subs_vals(qs_env%input, "DFT%PRINT%BAND_STRUCTURE")
     131            8 :       CALL section_vals_get(bs_input, explicit=explicit)
     132            8 :       IF (explicit) THEN
     133            8 :          CALL section_vals_val_get(bs_input, "FILE_NAME", c_val=filename)
     134            8 :          CALL section_vals_val_get(bs_input, "ADDED_MOS", i_val=nadd)
     135            8 :          unit_nr = cp_logger_get_default_io_unit()
     136            8 :          CALL get_qs_env(qs_env=qs_env, para_env=para_env)
     137            8 :          CALL get_qs_env(qs_env, cell=cell)
     138          104 :          cart_hmat(:, :) = cell%hmat(:, :)
     139            8 :          IF (cell%input_cell_canonicalized) cart_hmat(:, :) = cell%input_hmat(:, :)
     140            8 :          kpset => section_vals_get_subs_vals(bs_input, "KPOINT_SET")
     141            8 :          CALL section_vals_get(kpset, n_repetition=n_rep)
     142            8 :          IF (unit_nr > 0) THEN
     143            4 :             WRITE (unit_nr, FMT="(/,T2,A)") "KPOINTS| Band Structure Calculation"
     144            4 :             WRITE (unit_nr, FMT="(T2,A,T71,I10)") "KPOINTS| Number of k-point sets", n_rep
     145            4 :             IF (nadd /= 0) THEN
     146            1 :                WRITE (unit_nr, FMT="(T2,A,T71,I10)") "KPOINTS| Number of added MOs/bands", nadd
     147              :             END IF
     148              :          END IF
     149            8 :          IF (filename == "") THEN
     150              :             ! use standard output file
     151            2 :             bs_data_unit = unit_nr
     152            2 :             io_default = .TRUE.
     153              :          ELSE
     154            6 :             io_default = .FALSE.
     155            6 :             IF (para_env%is_source()) THEN
     156              :                CALL open_file(filename, unit_number=bs_data_unit, file_status="UNKNOWN", file_action="WRITE", &
     157            3 :                               file_position="APPEND")
     158              :             ELSE
     159            3 :                bs_data_unit = -1
     160              :             END IF
     161              :          END IF
     162           18 :          DO i_rep = 1, n_rep
     163           10 :             t1 = m_walltime()
     164           10 :             CALL section_vals_val_get(kpset, "NPOINTS", i_rep_section=i_rep, i_val=npline)
     165           10 :             CALL section_vals_val_get(kpset, "UNITS", i_rep_section=i_rep, c_val=ustr)
     166           10 :             CALL uppercase(ustr)
     167           10 :             CALL section_vals_val_get(kpset, "SPECIAL_POINT", i_rep_section=i_rep, n_rep_val=n_ptr)
     168           30 :             ALLOCATE (kspecial(3, n_ptr))
     169           30 :             ALLOCATE (spname(n_ptr))
     170           30 :             DO ip = 1, n_ptr
     171           20 :                CALL section_vals_val_get(kpset, "SPECIAL_POINT", i_rep_section=i_rep, i_rep_val=ip, c_vals=strptr)
     172           20 :                IF (SIZE(strptr(:), 1) == 4) THEN
     173            6 :                   spname(ip) = strptr(1)
     174           24 :                   DO i = 1, 3
     175           18 :                      CALL read_float_object(strptr(i + 1), kpptr(i), error_message)
     176           24 :                      IF (LEN_TRIM(error_message) > 0) CPABORT(TRIM(error_message))
     177              :                   END DO
     178           14 :                ELSE IF (SIZE(strptr(:), 1) == 3) THEN
     179           14 :                   spname(ip) = "not specified"
     180           56 :                   DO i = 1, 3
     181           42 :                      CALL read_float_object(strptr(i), kpptr(i), error_message)
     182           56 :                      IF (LEN_TRIM(error_message) > 0) CPABORT(TRIM(error_message))
     183              :                   END DO
     184              :                ELSE
     185            0 :                   CPABORT("Input SPECIAL_POINT invalid")
     186              :                END IF
     187           10 :                SELECT CASE (ustr)
     188              :                CASE ("B_VECTOR")
     189           48 :                   kspecial(1:3, ip) = kpptr(1:3)
     190              :                CASE ("CART_ANGSTROM")
     191              :                   kspecial(1:3, ip) = (kpptr(1)*cart_hmat(1, 1:3) + &
     192              :                                        kpptr(2)*cart_hmat(2, 1:3) + &
     193            0 :                                        kpptr(3)*cart_hmat(3, 1:3))/twopi*angstrom
     194              :                CASE ("CART_BOHR")
     195              :                   kspecial(1:3, ip) = (kpptr(1)*cart_hmat(1, 1:3) + &
     196              :                                        kpptr(2)*cart_hmat(2, 1:3) + &
     197           32 :                                        kpptr(3)*cart_hmat(3, 1:3))/twopi
     198              :                CASE DEFAULT
     199           20 :                   CPABORT("Unknown unit <"//TRIM(ustr)//"> specified for k-point definition")
     200              :                END SELECT
     201              :             END DO
     202           10 :             npoints = (n_ptr - 1)*npline + 1
     203           10 :             CPASSERT(npoints >= 1)
     204              : 
     205              :             ! Initialize environment and calculate MOs
     206           30 :             ALLOCATE (kpgeneral(3, npoints))
     207           70 :             kpgeneral(1:3, 1) = kspecial(1:3, 1)
     208           10 :             ikk = 1
     209           20 :             DO ik = 2, n_ptr
     210          100 :                DO ip = 1, npline
     211           80 :                   ikk = ikk + 1
     212              :                   kpgeneral(1:3, ikk) = kspecial(1:3, ik - 1) + &
     213              :                                         REAL(ip, KIND=dp)/REAL(npline, KIND=dp)* &
     214          570 :                                         (kspecial(1:3, ik) - kspecial(1:3, ik - 1))
     215              :                END DO
     216              :             END DO
     217           10 :             NULLIFY (kpoint)
     218           10 :             CALL calculate_kp_orbitals(qs_env, kpoint, "GENERAL", nadd, kpgeneral=kpgeneral)
     219           10 :             DEALLOCATE (kpgeneral)
     220              : 
     221           10 :             CALL get_qs_env(qs_env, dft_control=dft_control)
     222           10 :             nspins = dft_control%nspins
     223           10 :             kp => kpoint%kp_env(1)%kpoint_env
     224           10 :             CALL get_mo_set(kp%mos(1, 1), nmo=nmo)
     225           40 :             ALLOCATE (eigval(nmo), occnum(nmo))
     226           10 :             CALL get_kpoint_info(kpoint, nkp=nkp, kp_range=kp_range, xkp=xkp, wkp=wkp)
     227              : 
     228           10 :             IF (unit_nr > 0) THEN
     229              :                WRITE (UNIT=unit_nr, FMT="(T2,A,I4,T71,I10)") &
     230            5 :                   "KPOINTS| Number of k-points in set ", i_rep, npoints
     231              :                WRITE (UNIT=unit_nr, FMT="(T2,A)") &
     232            5 :                   "KPOINTS| In units of b-vector [2pi/Bohr]"
     233           15 :                DO ip = 1, n_ptr
     234              :                   WRITE (UNIT=unit_nr, FMT="(T2,A,I5,1X,A11,3(1X,F12.6))") &
     235           45 :                      "KPOINTS| Special point ", ip, ADJUSTL(TRIM(spname(ip))), kspecial(1:3, ip)
     236              :                END DO
     237              :             END IF
     238           10 :             IF (bs_data_unit > 0 .AND. (bs_data_unit /= unit_nr)) THEN
     239              :                WRITE (UNIT=bs_data_unit, FMT="(4(A,I0),A)") &
     240            4 :                   "# Set ", i_rep, ": ", n_ptr, " special points, ", npoints, " k-points, ", nmo, " bands"
     241           13 :                DO ip = 1, n_ptr
     242              :                   WRITE (UNIT=bs_data_unit, FMT="(A,I0,T20,T24,3(1X,F14.8),2X,A)") &
     243           40 :                      "#  Special point ", ip, kspecial(1:3, ip), ADJUSTL(TRIM(spname(ip)))
     244              :                END DO
     245              :             END IF
     246              : 
     247          100 :             DO ik = 1, nkp
     248           90 :                my_kpgrp = (ik >= kp_range(1) .AND. ik <= kp_range(2))
     249          190 :                DO ispin = 1, nspins
     250           90 :                   IF (my_kpgrp) THEN
     251           90 :                      ikpgr = ik - kp_range(1) + 1
     252           90 :                      kp => kpoint%kp_env(ikpgr)%kpoint_env
     253           90 :                      CALL get_mo_set(kp%mos(1, ispin), eigenvalues=eigenvalues, occupation_numbers=occupation_numbers)
     254         3370 :                      eigval(1:nmo) = eigenvalues(1:nmo)
     255         3370 :                      occnum(1:nmo) = occupation_numbers(1:nmo)
     256              :                   ELSE
     257            0 :                      eigval(1:nmo) = 0.0_dp
     258            0 :                      occnum(1:nmo) = 0.0_dp
     259              :                   END IF
     260         3370 :                   CALL kpoint%para_env_inter_kp%sum(eigval)
     261         3370 :                   CALL kpoint%para_env_inter_kp%sum(occnum)
     262          180 :                   IF (bs_data_unit > 0) THEN
     263              :                      WRITE (UNIT=bs_data_unit, FMT="(A,I0,T15,A,I0,A,T24,3(1X,F14.8),3X,F14.8)") &
     264          180 :                         "#  Point ", ik, "  Spin ", ispin, ":", xkp(1:3, ik), wkp(ik)
     265              :                      WRITE (UNIT=bs_data_unit, FMT="(A)") &
     266           45 :                         "#   Band    Energy [eV]     Occupation"
     267          865 :                      DO imo = 1, nmo
     268              :                         WRITE (UNIT=bs_data_unit, FMT="(T2,I7,2(1X,F14.8))") &
     269          865 :                            imo, eigval(imo)*evolt, occnum(imo)
     270              :                      END DO
     271              :                   END IF
     272              :                END DO
     273              :             END DO
     274              : 
     275           10 :             DEALLOCATE (kspecial, spname)
     276           10 :             DEALLOCATE (eigval, occnum)
     277           10 :             CALL kpoint_release(kpoint)
     278           10 :             t2 = m_walltime()
     279           48 :             IF (unit_nr > 0) THEN
     280            5 :                WRITE (UNIT=unit_nr, FMT="(T2,A,T67,F14.3)") "KPOINTS| Time for k-point line ", t2 - t1
     281              :             END IF
     282              : 
     283              :          END DO
     284              : 
     285              :          ! Close output files
     286            8 :          IF (.NOT. io_default) THEN
     287            6 :             IF (para_env%is_source()) CALL close_file(bs_data_unit)
     288              :          END IF
     289              : 
     290              :       END IF
     291              : 
     292            8 :    END SUBROUTINE do_calculate_band_structure
     293              : 
     294              : ! **************************************************************************************************
     295              : !> \brief diagonalize KS matrices at a set of kpoints
     296              : !> \param qs_env ...
     297              : !> \param kpoint ...
     298              : !> \param scheme ...
     299              : !> \param nadd ...
     300              : !> \param mp_grid ...
     301              : !> \param kpgeneral ...
     302              : !> \param group_size_ext ...
     303              : !> \param kp_shift ...
     304              : !> \param gamma_centered ...
     305              : !> \author JGH
     306              : ! **************************************************************************************************
     307           10 :    SUBROUTINE calculate_kp_orbitals(qs_env, kpoint, scheme, nadd, mp_grid, kpgeneral, group_size_ext, &
     308              :                                     kp_shift, gamma_centered)
     309              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     310              :       TYPE(kpoint_type), POINTER                         :: kpoint
     311              :       CHARACTER(LEN=*), INTENT(IN)                       :: scheme
     312              :       INTEGER, INTENT(IN)                                :: nadd
     313              :       INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL        :: mp_grid
     314              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
     315              :          OPTIONAL                                        :: kpgeneral
     316              :       INTEGER, INTENT(IN), OPTIONAL                      :: group_size_ext
     317              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN), OPTIONAL  :: kp_shift
     318              :       LOGICAL, INTENT(IN), OPTIONAL                      :: gamma_centered
     319              : 
     320              :       LOGICAL                                            :: diis_step
     321              :       TYPE(cp_blacs_env_type), POINTER                   :: blacs_env
     322           10 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks, matrix_s
     323              :       TYPE(dft_control_type), POINTER                    :: dft_control
     324              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     325              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     326           10 :          POINTER                                         :: sab_nl
     327              :       TYPE(qs_scf_env_type), POINTER                     :: scf_env
     328              :       TYPE(scf_control_type), POINTER                    :: scf_control
     329              : 
     330              :       CALL calculate_kpoints_for_bs(kpoint, scheme, group_size_ext, mp_grid, kpgeneral, &
     331           10 :                                     kp_shift, gamma_centered)
     332              : 
     333           10 :       CALL get_qs_env(qs_env=qs_env, para_env=para_env, blacs_env=blacs_env)
     334           10 :       CALL kpoint_env_initialize(kpoint, para_env, blacs_env)
     335              : 
     336           10 :       CALL kpoint_initialize_mos(kpoint, qs_env%mos, nadd)
     337           10 :       CALL kpoint_initialize_mo_set(kpoint)
     338              : 
     339           10 :       CALL get_qs_env(qs_env, sab_kp=sab_nl, dft_control=dft_control)
     340           10 :       CALL kpoint_init_cell_index(kpoint, sab_nl, para_env, dft_control%nimages)
     341              : 
     342              :       CALL get_qs_env(qs_env, matrix_ks_kp=matrix_ks, matrix_s_kp=matrix_s, &
     343           10 :                       scf_env=scf_env, scf_control=scf_control)
     344           10 :       CALL do_general_diag_kp(matrix_ks, matrix_s, kpoint, scf_env, scf_control, .FALSE., diis_step)
     345              : 
     346           10 :    END SUBROUTINE calculate_kp_orbitals
     347              : 
     348              : ! **************************************************************************************************
     349              : !> \brief ...
     350              : !> \param kpoint ...
     351              : !> \param scheme ...
     352              : !> \param group_size_ext ...
     353              : !> \param mp_grid ...
     354              : !> \param kpgeneral ...
     355              : !> \param kp_shift ...
     356              : !> \param gamma_centered ...
     357              : ! **************************************************************************************************
     358           42 :    SUBROUTINE calculate_kpoints_for_bs(kpoint, scheme, group_size_ext, mp_grid, kpgeneral, &
     359              :                                        kp_shift, gamma_centered)
     360              : 
     361              :       TYPE(kpoint_type), POINTER                         :: kpoint
     362              :       CHARACTER(LEN=*), INTENT(IN)                       :: scheme
     363              :       INTEGER, INTENT(IN), OPTIONAL                      :: group_size_ext
     364              :       INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL        :: mp_grid
     365              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN), &
     366              :          OPTIONAL                                        :: kpgeneral
     367              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN), OPTIONAL  :: kp_shift
     368              :       LOGICAL, INTENT(IN), OPTIONAL                      :: gamma_centered
     369              : 
     370              :       INTEGER                                            :: i, idim, ix, iy, iz, npoints
     371              :       INTEGER, DIMENSION(3)                              :: ik
     372              :       LOGICAL                                            :: gamma_mesh
     373              :       REAL(KIND=dp), DIMENSION(3)                        :: kpt_latt, shift
     374              : 
     375           58 :       CPASSERT(.NOT. ASSOCIATED(kpoint))
     376              : 
     377           58 :       CALL kpoint_create(kpoint)
     378              : 
     379           58 :       IF (PRESENT(kp_shift)) THEN
     380            0 :          shift = kp_shift
     381              :       ELSE
     382           58 :          shift = 0.0_dp
     383              :       END IF
     384           58 :       IF (PRESENT(gamma_centered)) THEN
     385            0 :          gamma_mesh = gamma_centered
     386              :       ELSE
     387              :          gamma_mesh = .FALSE.
     388              :       END IF
     389              : 
     390           58 :       kpoint%kp_scheme = scheme
     391           58 :       kpoint%symmetry = .FALSE.
     392           58 :       kpoint%verbose = .FALSE.
     393           58 :       kpoint%full_grid = .FALSE.
     394           58 :       kpoint%use_real_wfn = .FALSE.
     395           58 :       kpoint%gamma_centered = gamma_mesh
     396          232 :       kpoint%kp_shift = shift
     397           58 :       kpoint%eps_geo = 1.e-6_dp
     398           58 :       IF (PRESENT(group_size_ext)) THEN
     399           48 :          kpoint%parallel_group_size = group_size_ext
     400              :       ELSE
     401           10 :          kpoint%parallel_group_size = -1
     402              :       END IF
     403            0 :       SELECT CASE (scheme)
     404              :       CASE ("GAMMA")
     405            0 :          kpoint%nkp = 1
     406            0 :          ALLOCATE (kpoint%xkp(3, 1), kpoint%wkp(1))
     407            0 :          kpoint%xkp(1:3, 1) = 0.0_dp
     408            0 :          kpoint%wkp(1) = 1.0_dp
     409            0 :          kpoint%symmetry = .TRUE.
     410            0 :          ALLOCATE (kpoint%kp_sym(1))
     411            0 :          NULLIFY (kpoint%kp_sym(1)%kpoint_sym)
     412            0 :          CALL kpoint_sym_create(kpoint%kp_sym(1)%kpoint_sym)
     413              :       CASE ("MONKHORST-PACK", "MACDONALD")
     414           16 :          CPASSERT(PRESENT(mp_grid))
     415           16 :          npoints = mp_grid(1)*mp_grid(2)*mp_grid(3)
     416           64 :          kpoint%nkp_grid(1:3) = mp_grid(1:3)
     417           16 :          kpoint%full_grid = .TRUE.
     418           16 :          kpoint%nkp = npoints
     419           80 :          ALLOCATE (kpoint%xkp(3, npoints), kpoint%wkp(npoints))
     420           32 :          kpoint%wkp(:) = 1._dp/REAL(npoints, KIND=dp)
     421              :          i = 0
     422           32 :          DO ix = 1, mp_grid(1)
     423           48 :             DO iy = 1, mp_grid(2)
     424           48 :                DO iz = 1, mp_grid(3)
     425           16 :                   i = i + 1
     426           64 :                   ik = [ix, iy, iz]
     427           64 :                   DO idim = 1, 3
     428           64 :                      IF (gamma_mesh .AND. MOD(mp_grid(idim), 2) == 0) THEN
     429              :                         kpt_latt(idim) = REAL(2*ik(idim) - mp_grid(idim), KIND=dp)/ &
     430            0 :                                          (2._dp*REAL(mp_grid(idim), KIND=dp))
     431              :                      ELSE
     432              :                         kpt_latt(idim) = REAL(2*ik(idim) - mp_grid(idim) - 1, KIND=dp)/ &
     433           48 :                                          (2._dp*REAL(mp_grid(idim), KIND=dp))
     434              :                      END IF
     435              :                   END DO
     436           80 :                   kpoint%xkp(1:3, i) = kpt_latt(1:3) + shift(1:3)
     437              :                END DO
     438              :             END DO
     439              :          END DO
     440              :          ! default: no symmetry settings
     441           64 :          ALLOCATE (kpoint%kp_sym(kpoint%nkp))
     442           32 :          DO i = 1, kpoint%nkp
     443           16 :             NULLIFY (kpoint%kp_sym(i)%kpoint_sym)
     444           32 :             CALL kpoint_sym_create(kpoint%kp_sym(i)%kpoint_sym)
     445              :          END DO
     446              :       CASE ("GENERAL")
     447           42 :          CPASSERT(PRESENT(kpgeneral))
     448           42 :          npoints = SIZE(kpgeneral, 2)
     449           42 :          kpoint%nkp = npoints
     450          210 :          ALLOCATE (kpoint%xkp(3, npoints), kpoint%wkp(npoints))
     451          372 :          kpoint%wkp(:) = 1._dp/REAL(npoints, KIND=dp)
     452         1362 :          kpoint%xkp(1:3, 1:npoints) = kpgeneral(1:3, 1:npoints)
     453              :          ! default: no symmetry settings
     454          456 :          ALLOCATE (kpoint%kp_sym(kpoint%nkp))
     455          372 :          DO i = 1, kpoint%nkp
     456          330 :             NULLIFY (kpoint%kp_sym(i)%kpoint_sym)
     457          372 :             CALL kpoint_sym_create(kpoint%kp_sym(i)%kpoint_sym)
     458              :          END DO
     459              :       CASE DEFAULT
     460           58 :          CPABORT("Unknown kpoint scheme requested")
     461              :       END SELECT
     462              : 
     463           58 :    END SUBROUTINE calculate_kpoints_for_bs
     464              : 
     465              : END MODULE qs_band_structure
        

Generated by: LCOV version 2.0-1