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

Generated by: LCOV version 2.0-1