1!--------------------------------------------------------------------------------------------------!
2!   CP2K: A general program to perform molecular dynamics simulations                              !
3!   Copyright (C) 2000 - 2019  CP2K developers group                                               !
4!--------------------------------------------------------------------------------------------------!
5
6! **************************************************************************************************
7!> \brief Types and basic routines needed for a kpoint calculation
8!> \par History
9!>       2014.07 created [JGH]
10!>       2014.11 unified k-point and gamma-point code [Ole Schuett]
11!> \author JGH
12! **************************************************************************************************
13MODULE kpoint_types
14   USE cp_blacs_env,                    ONLY: cp_blacs_env_release,&
15                                              cp_blacs_env_type
16   USE cp_fm_types,                     ONLY: cp_fm_p_type,&
17                                              cp_fm_release
18   USE cp_log_handling,                 ONLY: cp_get_default_logger,&
19                                              cp_logger_type
20   USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
21                                              cp_print_key_unit_nr
22   USE cp_para_env,                     ONLY: cp_cart_release,&
23                                              cp_para_env_release
24   USE cp_para_types,                   ONLY: cp_para_cart_type,&
25                                              cp_para_env_type
26   USE input_cp2k_kpoints,              ONLY: use_complex_wfn,&
27                                              use_real_wfn
28   USE input_section_types,             ONLY: section_vals_get,&
29                                              section_vals_type,&
30                                              section_vals_val_get
31   USE kinds,                           ONLY: default_string_length,&
32                                              dp
33   USE mathconstants,                   ONLY: twopi
34   USE physcon,                         ONLY: angstrom
35   USE qs_matrix_pools,                 ONLY: mpools_release,&
36                                              qs_matrix_pools_type
37   USE qs_mo_types,                     ONLY: deallocate_mo_set,&
38                                              mo_set_p_type
39   USE qs_neighbor_list_types,          ONLY: neighbor_list_set_p_type
40   USE string_utilities,                ONLY: uppercase
41#include "./base/base_uses.f90"
42
43   IMPLICIT NONE
44
45   PRIVATE
46
47   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'kpoint_types'
48
49   PUBLIC :: kpoint_type
50   PUBLIC :: kpoint_create, kpoint_release, get_kpoint_info
51   PUBLIC :: read_kpoint_section, write_kpoint_info
52   PUBLIC :: kpoint_env_type, kpoint_env_p_type
53   PUBLIC :: kpoint_env_create, get_kpoint_env
54   PUBLIC :: kpoint_sym_type
55   PUBLIC :: kpoint_sym_create
56
57! **************************************************************************************************
58!> \brief Keeps information about a specific k-point
59!> \param nkpoint   the kpoint index
60!> \param wkp       weight of this kpoint
61!> \param xkp       kpoint coordinates in units of b-vector
62!> \param is_local  if this kpoint is calculated on a single thread
63!> \param mos       associated MOs (r/i,spin)
64!> \param pmat      associated density matrix (r/i,spin)
65!> \param wmat      associated energy weighted density matrix (r/i,spin)
66!> \author JGH
67! **************************************************************************************************
68   TYPE kpoint_env_type
69      INTEGER                                           :: nkpoint
70      REAL(KIND=dp)                                     :: wkp
71      REAL(KIND=dp), DIMENSION(3)                       :: xkp
72      LOGICAL                                           :: is_local
73      TYPE(mo_set_p_type), DIMENSION(:, :), POINTER     :: mos
74      TYPE(cp_fm_p_type), DIMENSION(:, :), POINTER      :: pmat
75      TYPE(cp_fm_p_type), DIMENSION(:, :), POINTER      :: wmat
76   END TYPE kpoint_env_type
77
78   TYPE kpoint_env_p_type
79      TYPE(kpoint_env_type), POINTER                    :: kpoint_env
80   END TYPE kpoint_env_p_type
81
82! **************************************************************************************************
83!> \brief Keeps symmetry information about a specific k-point
84!> \param apply_symmetry ...
85!> \param nwght     kpoint multiplicity
86!> \param xkp       kpoint coordinates
87!> \param rot       rotation matrices
88!> \param f0        atom permutation
89!> \author JGH
90! **************************************************************************************************
91   TYPE kpoint_sym_type
92      LOGICAL                                           :: apply_symmetry
93      INTEGER                                           :: nwght
94      REAL(KIND=dp), DIMENSION(:, :), POINTER           :: xkp
95      REAL(KIND=dp), DIMENSION(:, :, :), POINTER        :: rot
96      INTEGER, DIMENSION(:, :), POINTER                 :: f0
97   END TYPE kpoint_sym_type
98
99   TYPE kpoint_sym_p_type
100      TYPE(kpoint_sym_type), POINTER                    :: kpoint_sym
101   END TYPE kpoint_sym_p_type
102
103! **************************************************************************************************
104!> \brief Contains information about kpoints
105!> \par History
106!>       2014.07 created [JGH]
107!> \param kp_scheme           [input] Type of kpoint grid
108!> \param nkp_grid            [input] Grid points
109!> \param kp_shift            [input] Shift of the grid
110!> \param use_real_wfn        [input] real/complex wfn
111!> \param symmetry            [input] use symmetry (atoms) to reduce kpoints
112!> \param full_grid           [input] don't reduce kpoints at all
113!> \param verbose             [input] more output information
114!> \param eps_geo             [input] accuracy of atom symmetry detection
115!> \param parallel_group_size [input] kpoint group size
116!> \param nkp     number of kpoints
117!> \param xkp     kpoint coordinates
118!> \param wkp     kpoint weights
119!> \param para_env 'global' parallel environment
120!> \param cart 2d distribution of the processors for the kpoints,
121!>        a column work together on the same kpoint
122!> \param para_env_full the global para env that contains all the kpoints,
123!>        this is just the cart as para_env
124!> \param para_env_kp parallel environment of the kpoint calculation
125!> \param para_env_inter_kp parallel environment between kpoints
126!> \param iogrp  this kpoint group has the IO processor
127!> \param nkp_groups   number of kpoint groups
128!> \param kp_dist      kpoints distribution on groups
129!> \param kp_range     kpoints distribution for local processor
130!> \param blacs_env    BLACS env for the kpoint group
131!> \param opmats       Operator matrices
132!> \param kp_env       Information for each kpoint
133!> \param mpools       FM matrix pools for kpoint groups
134!> \author JGH
135! **************************************************************************************************
136   TYPE kpoint_type
137      CHARACTER(LEN=default_string_length)    :: kp_scheme
138      INTEGER, DIMENSION(3)                   :: nkp_grid
139      REAL(KIND=dp), DIMENSION(3)             :: kp_shift
140      LOGICAL                                 :: use_real_wfn
141      LOGICAL                                 :: symmetry
142      LOGICAL                                 :: full_grid
143      LOGICAL                                 :: verbose
144      REAL(KIND=dp)                           :: eps_geo
145      INTEGER                                 :: parallel_group_size
146      INTEGER                                 :: nkp
147      REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp => Null()
148      REAL(KIND=dp), DIMENSION(:), POINTER    :: wkp => Null()
149      ! parallel environment
150      TYPE(cp_para_env_type), POINTER         :: para_env => Null()
151      TYPE(cp_blacs_env_type), POINTER        :: blacs_env_all => Null()
152      TYPE(cp_para_cart_type), POINTER        :: cart => Null()
153      TYPE(cp_para_env_type), POINTER         :: para_env_full => Null(), &
154                                                 para_env_kp => Null(), &
155                                                 para_env_inter_kp => Null()
156      LOGICAL                                 :: iogrp
157      INTEGER                                 :: nkp_groups
158      INTEGER, DIMENSION(:, :), POINTER       :: kp_dist => Null()
159      INTEGER, DIMENSION(2)                   :: kp_range
160      TYPE(cp_blacs_env_type), POINTER        :: blacs_env => Null()
161      INTEGER, DIMENSION(:, :, :), POINTER    :: cell_to_index => Null()
162      INTEGER, DIMENSION(:, :), POINTER       :: index_to_cell => Null()
163      TYPE(neighbor_list_set_p_type), &
164         DIMENSION(:), POINTER                :: sab_nl => Null()
165      ! environment
166      TYPE(kpoint_env_p_type), DIMENSION(:), &
167         POINTER                              :: kp_env => Null()
168      TYPE(kpoint_sym_p_type), DIMENSION(:), &
169         POINTER                              :: kp_sym => Null()
170      TYPE(qs_matrix_pools_type), POINTER     :: mpools => Null()
171   END TYPE kpoint_type
172
173! **************************************************************************************************
174
175CONTAINS
176
177! **************************************************************************************************
178!> \brief Create a kpoint environment
179!> \param kpoint  All the kpoint information
180!> \author JGH
181! **************************************************************************************************
182   SUBROUTINE kpoint_create(kpoint)
183      TYPE(kpoint_type), POINTER                         :: kpoint
184
185      CHARACTER(LEN=*), PARAMETER :: routineN = 'kpoint_create', routineP = moduleN//':'//routineN
186
187      CPASSERT(.NOT. ASSOCIATED(kpoint))
188
189      ALLOCATE (kpoint)
190
191      kpoint%kp_scheme = ""
192      kpoint%nkp_grid = 0
193      kpoint%kp_shift = 0.0_dp
194      kpoint%symmetry = .FALSE.
195      kpoint%verbose = .FALSE.
196      kpoint%full_grid = .FALSE.
197      kpoint%use_real_wfn = .FALSE.
198      kpoint%eps_geo = 1.0e-6_dp
199      kpoint%parallel_group_size = -1
200
201      kpoint%nkp = 0
202
203      NULLIFY (kpoint%xkp, kpoint%wkp)
204      NULLIFY (kpoint%kp_dist)
205
206      NULLIFY (kpoint%para_env)
207      NULLIFY (kpoint%blacs_env_all)
208      NULLIFY (kpoint%cart)
209      NULLIFY (kpoint%para_env_full, kpoint%para_env_kp, kpoint%para_env_inter_kp)
210      NULLIFY (kpoint%blacs_env)
211      kpoint%nkp_groups = 0
212      kpoint%iogrp = .FALSE.
213      kpoint%kp_range = 0
214
215      NULLIFY (kpoint%kp_env)
216      NULLIFY (kpoint%mpools)
217
218      ALLOCATE (kpoint%cell_to_index(0:0, 0:0, 0:0))
219      kpoint%cell_to_index(:, :, :) = 1
220
221      ALLOCATE (kpoint%index_to_cell(0:0, 0:0))
222      kpoint%index_to_cell(:, :) = 0
223
224   END SUBROUTINE kpoint_create
225
226! **************************************************************************************************
227!> \brief  Release a kpoint environment, deallocate all data
228!> \param kpoint  The kpoint environment
229!> \author JGH
230! **************************************************************************************************
231   SUBROUTINE kpoint_release(kpoint)
232      TYPE(kpoint_type), POINTER                         :: kpoint
233
234      CHARACTER(LEN=*), PARAMETER :: routineN = 'kpoint_release', routineP = moduleN//':'//routineN
235
236      INTEGER                                            :: ik
237
238      IF (ASSOCIATED(kpoint)) THEN
239
240         IF (ASSOCIATED(kpoint%xkp)) THEN
241            DEALLOCATE (kpoint%xkp)
242         END IF
243         IF (ASSOCIATED(kpoint%wkp)) THEN
244            DEALLOCATE (kpoint%wkp)
245         END IF
246         IF (ASSOCIATED(kpoint%kp_dist)) THEN
247            DEALLOCATE (kpoint%kp_dist)
248         ENDIF
249
250         CALL mpools_release(kpoint%mpools)
251         CALL cp_blacs_env_release(kpoint%blacs_env)
252         CALL cp_blacs_env_release(kpoint%blacs_env_all)
253
254         CALL cp_cart_release(kpoint%cart)
255         CALL cp_para_env_release(kpoint%para_env)
256         CALL cp_para_env_release(kpoint%para_env_full)
257         CALL cp_para_env_release(kpoint%para_env_kp)
258         CALL cp_para_env_release(kpoint%para_env_inter_kp)
259
260         IF (ASSOCIATED(kpoint%cell_to_index)) DEALLOCATE (kpoint%cell_to_index)
261         IF (ASSOCIATED(kpoint%index_to_cell)) DEALLOCATE (kpoint%index_to_cell)
262
263         IF (ASSOCIATED(kpoint%kp_env)) THEN
264            DO ik = 1, SIZE(kpoint%kp_env)
265               CALL kpoint_env_release(kpoint%kp_env(ik)%kpoint_env)
266            END DO
267            DEALLOCATE (kpoint%kp_env)
268         END IF
269
270         IF (ASSOCIATED(kpoint%kp_sym)) THEN
271            DO ik = 1, SIZE(kpoint%kp_sym)
272               CALL kpoint_sym_release(kpoint%kp_sym(ik)%kpoint_sym)
273            END DO
274            DEALLOCATE (kpoint%kp_sym)
275         END IF
276
277         DEALLOCATE (kpoint)
278
279      END IF
280
281   END SUBROUTINE kpoint_release
282
283! **************************************************************************************************
284!> \brief Retrieve information from a kpoint environment
285!> \param kpoint        The kpoint environment
286!> \param kp_scheme     Type of kpoint grid
287!> \param nkp_grid      Grid points
288!> \param kp_shift      Shift of the grid
289!> \param symmetry      use symmetry (atoms) to reduce kpoints
290!> \param verbose       more output information
291!> \param full_grid     don't reduce kpoints at all
292!> \param use_real_wfn  real/complex wfn
293!> \param eps_geo       accuracy of atom symmetry detection
294!> \param parallel_group_size kpoint group size
295!> \param kp_range      kpoints distribution for local processor
296!> \param nkp           number of kpoints
297!> \param xkp           kpoint coordinates in units of b-vector
298!> \param wkp           kpoint weights
299!> \param para_env      'global' parallel environment
300!> \param blacs_env_all BLACS env for the total environment
301!> \param cart          2d distribution of the processors for the kpoints,
302!>        a column work together on the same kpoint
303!> \param para_env_full the global para env that contains all the kpoints,
304!>        this is just the cart as para_env
305!> \param para_env_kp   parallel environment of the kpoint calculation
306!> \param para_env_inter_kp   parallel environment between kpoints
307!> \param blacs_env     BLACS env for the kpoint group
308!> \param kp_env        Information for each kpoint
309!> \param mpools        FM matrix pools for kpoint groups
310!> \param iogrp         this kpoint group has the IO processor
311!> \param nkp_groups    number of kpoint groups
312!> \param kp_dist       kpoints distribution on groups
313!> \param cell_to_index given a cell triple, returns the real space index
314!> \param sab_nl        neighbourlist that defines real space matrices
315!> \author JGH
316! **************************************************************************************************
317   SUBROUTINE get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, &
318                              full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, &
319                              para_env, blacs_env_all, cart, para_env_full, para_env_kp, para_env_inter_kp, blacs_env, &
320                              kp_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, sab_nl)
321      TYPE(kpoint_type), POINTER                         :: kpoint
322      CHARACTER(LEN=*), OPTIONAL                         :: kp_scheme
323      INTEGER, DIMENSION(3), OPTIONAL                    :: nkp_grid
324      REAL(KIND=dp), DIMENSION(3), OPTIONAL              :: kp_shift
325      LOGICAL, OPTIONAL                                  :: symmetry, verbose, full_grid, &
326                                                            use_real_wfn
327      REAL(KIND=dp), OPTIONAL                            :: eps_geo
328      INTEGER, OPTIONAL                                  :: parallel_group_size
329      INTEGER, DIMENSION(2), OPTIONAL                    :: kp_range
330      INTEGER, OPTIONAL                                  :: nkp
331      REAL(KIND=dp), DIMENSION(:, :), OPTIONAL, POINTER  :: xkp
332      REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER     :: wkp
333      TYPE(cp_para_env_type), OPTIONAL, POINTER          :: para_env
334      TYPE(cp_blacs_env_type), OPTIONAL, POINTER         :: blacs_env_all
335      TYPE(cp_para_cart_type), OPTIONAL, POINTER         :: cart
336      TYPE(cp_para_env_type), OPTIONAL, POINTER          :: para_env_full, para_env_kp, &
337                                                            para_env_inter_kp
338      TYPE(cp_blacs_env_type), OPTIONAL, POINTER         :: blacs_env
339      TYPE(kpoint_env_p_type), DIMENSION(:), OPTIONAL, &
340         POINTER                                         :: kp_env
341      TYPE(qs_matrix_pools_type), OPTIONAL, POINTER      :: mpools
342      LOGICAL, OPTIONAL                                  :: iogrp
343      INTEGER, OPTIONAL                                  :: nkp_groups
344      INTEGER, DIMENSION(:, :), OPTIONAL, POINTER        :: kp_dist
345      INTEGER, DIMENSION(:, :, :), OPTIONAL, POINTER     :: cell_to_index
346      TYPE(neighbor_list_set_p_type), DIMENSION(:), &
347         OPTIONAL, POINTER                               :: sab_nl
348
349      CHARACTER(LEN=*), PARAMETER :: routineN = 'get_kpoint_info', &
350         routineP = moduleN//':'//routineN
351
352      CPASSERT(ASSOCIATED(kpoint))
353
354      IF (PRESENT(kp_scheme)) kp_scheme = kpoint%kp_scheme
355      IF (PRESENT(nkp_grid)) nkp_grid = kpoint%nkp_grid
356      IF (PRESENT(kp_shift)) kp_shift = kpoint%kp_shift
357      IF (PRESENT(symmetry)) symmetry = kpoint%symmetry
358      IF (PRESENT(verbose)) verbose = kpoint%verbose
359      IF (PRESENT(full_grid)) full_grid = kpoint%full_grid
360      IF (PRESENT(use_real_wfn)) use_real_wfn = kpoint%use_real_wfn
361      IF (PRESENT(eps_geo)) eps_geo = kpoint%eps_geo
362      IF (PRESENT(parallel_group_size)) parallel_group_size = kpoint%parallel_group_size
363
364      IF (PRESENT(nkp)) nkp = kpoint%nkp
365      IF (PRESENT(wkp)) wkp => kpoint%wkp
366      IF (PRESENT(xkp)) xkp => kpoint%xkp
367
368      IF (PRESENT(para_env)) para_env => kpoint%para_env
369      IF (PRESENT(cart)) cart => kpoint%cart
370      IF (PRESENT(para_env_full)) para_env_full => kpoint%para_env_full
371      IF (PRESENT(para_env_kp)) para_env_kp => kpoint%para_env_kp
372      IF (PRESENT(para_env_inter_kp)) para_env_inter_kp => kpoint%para_env_inter_kp
373      IF (PRESENT(blacs_env_all)) blacs_env_all => kpoint%blacs_env_all
374      IF (PRESENT(blacs_env)) blacs_env => kpoint%blacs_env
375
376      IF (PRESENT(iogrp)) iogrp = kpoint%iogrp
377      IF (PRESENT(kp_range)) kp_range = kpoint%kp_range
378      IF (PRESENT(nkp_groups)) nkp_groups = kpoint%nkp_groups
379      IF (PRESENT(kp_dist)) kp_dist => kpoint%kp_dist
380
381      IF (PRESENT(kp_env)) kp_env => kpoint%kp_env
382      IF (PRESENT(mpools)) mpools => kpoint%mpools
383
384      IF (PRESENT(cell_to_index)) cell_to_index => kpoint%cell_to_index
385      IF (PRESENT(sab_nl)) sab_nl => kpoint%sab_nl
386
387   END SUBROUTINE get_kpoint_info
388
389! **************************************************************************************************
390!> \brief Set information in a kpoint environment
391!> \param kpoint        The kpoint environment
392!> \param kp_scheme     Type of kpoint grid
393!> \param nkp_grid      Grid points
394!> \param kp_shift      Shift of the grid
395!> \param symmetry      use symmetry (atoms) to reduce kpoints
396!> \param verbose       more output information
397!> \param full_grid     don't reduce kpoints at all
398!> \param use_real_wfn  real/complex wfn
399!> \param eps_geo       accuracy of atom symmetry detection
400!> \param parallel_group_size kpoint group size
401!> \param kp_range      kpoints distribution for local processor
402!> \param nkp           number of kpoints
403!> \param xkp           kpoint coordinates
404!> \param wkp           kpoint weights
405!> \param para_env      'global' parallel environment
406!> \param blacs_env_all BLACS env for the total environment
407!> \param cart          2d distribution of the processors for the kpoints,
408!>        a column work together on the same kpoint
409!> \param para_env_full the global para env that contains all the kpoints,
410!>        this is just the cart as para_env
411!> \param para_env_kp   parallel environment of the kpoint calculation
412!> \param para_env_inter_kp   parallel environment between kpoints
413!> \param blacs_env     BLACS env for the kpoint group
414!> \param kp_env        Information for each kpoint
415!> \param mpools        FM matrix pools for kpoint groups
416!> \param iogrp         this kpoint group has the IO processor
417!> \param nkp_groups    number of kpoint groups
418!> \param kp_dist       kpoints distribution on groups
419!> \param cell_to_index given a cell triple, returns the real space index
420!> \param sab_nl        neighbourlist that defines real space matrices
421!> \author JGH
422! **************************************************************************************************
423   SUBROUTINE set_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, &
424                              full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, &
425                              para_env, blacs_env_all, cart, para_env_full, para_env_kp, para_env_inter_kp, blacs_env, &
426                              kp_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, sab_nl)
427      TYPE(kpoint_type), POINTER                         :: kpoint
428      CHARACTER(LEN=*), OPTIONAL                         :: kp_scheme
429      INTEGER, DIMENSION(3), OPTIONAL                    :: nkp_grid
430      REAL(KIND=dp), DIMENSION(3), OPTIONAL              :: kp_shift
431      LOGICAL, OPTIONAL                                  :: symmetry, verbose, full_grid, &
432                                                            use_real_wfn
433      REAL(KIND=dp), OPTIONAL                            :: eps_geo
434      INTEGER, OPTIONAL                                  :: parallel_group_size
435      INTEGER, DIMENSION(2), OPTIONAL                    :: kp_range
436      INTEGER, OPTIONAL                                  :: nkp
437      REAL(KIND=dp), DIMENSION(:, :), OPTIONAL, POINTER  :: xkp
438      REAL(KIND=dp), DIMENSION(:), OPTIONAL, POINTER     :: wkp
439      TYPE(cp_para_env_type), OPTIONAL, POINTER          :: para_env
440      TYPE(cp_blacs_env_type), OPTIONAL, POINTER         :: blacs_env_all
441      TYPE(cp_para_cart_type), OPTIONAL, POINTER         :: cart
442      TYPE(cp_para_env_type), OPTIONAL, POINTER          :: para_env_full, para_env_kp, &
443                                                            para_env_inter_kp
444      TYPE(cp_blacs_env_type), OPTIONAL, POINTER         :: blacs_env
445      TYPE(kpoint_env_p_type), DIMENSION(:), OPTIONAL, &
446         POINTER                                         :: kp_env
447      TYPE(qs_matrix_pools_type), OPTIONAL, POINTER      :: mpools
448      LOGICAL, OPTIONAL                                  :: iogrp
449      INTEGER, OPTIONAL                                  :: nkp_groups
450      INTEGER, DIMENSION(:, :), OPTIONAL, POINTER        :: kp_dist
451      INTEGER, DIMENSION(:, :, :), OPTIONAL, POINTER     :: cell_to_index
452      TYPE(neighbor_list_set_p_type), DIMENSION(:), &
453         OPTIONAL, POINTER                               :: sab_nl
454
455      CHARACTER(LEN=*), PARAMETER :: routineN = 'set_kpoint_info', &
456         routineP = moduleN//':'//routineN
457
458      CPASSERT(ASSOCIATED(kpoint))
459
460      IF (PRESENT(kp_scheme)) kpoint%kp_scheme = kp_scheme
461      IF (PRESENT(nkp_grid)) kpoint%nkp_grid = nkp_grid
462      IF (PRESENT(kp_shift)) kpoint%kp_shift = kp_shift
463      IF (PRESENT(symmetry)) kpoint%symmetry = symmetry
464      IF (PRESENT(verbose)) kpoint%verbose = verbose
465      IF (PRESENT(full_grid)) kpoint%full_grid = full_grid
466      IF (PRESENT(use_real_wfn)) kpoint%use_real_wfn = use_real_wfn
467      IF (PRESENT(eps_geo)) kpoint%eps_geo = eps_geo
468      IF (PRESENT(parallel_group_size)) kpoint%parallel_group_size = parallel_group_size
469
470      IF (PRESENT(nkp)) kpoint%nkp = nkp
471      IF (PRESENT(wkp)) kpoint%wkp => wkp
472      IF (PRESENT(xkp)) kpoint%xkp => xkp
473
474      IF (PRESENT(para_env)) kpoint%para_env => para_env
475      IF (PRESENT(cart)) kpoint%cart => cart
476      IF (PRESENT(para_env_full)) kpoint%para_env_full => para_env_full
477      IF (PRESENT(para_env_kp)) kpoint%para_env_kp => para_env_kp
478      IF (PRESENT(para_env_inter_kp)) kpoint%para_env_inter_kp => para_env_inter_kp
479      IF (PRESENT(blacs_env_all)) kpoint%blacs_env_all => blacs_env_all
480      IF (PRESENT(blacs_env)) kpoint%blacs_env => blacs_env
481
482      IF (PRESENT(iogrp)) kpoint%iogrp = iogrp
483      IF (PRESENT(kp_range)) kpoint%kp_range = kp_range
484      IF (PRESENT(nkp_groups)) kpoint%nkp_groups = nkp_groups
485      IF (PRESENT(kp_dist)) kpoint%kp_dist => kp_dist
486
487      IF (PRESENT(kp_env)) kpoint%kp_env => kp_env
488      IF (PRESENT(mpools)) kpoint%mpools => mpools
489      IF (PRESENT(sab_nl)) kpoint%sab_nl => sab_nl
490
491      IF (PRESENT(cell_to_index)) THEN
492         IF (ASSOCIATED(kpoint%cell_to_index)) DEALLOCATE (kpoint%cell_to_index)
493         kpoint%cell_to_index => cell_to_index
494      ENDIF
495
496   END SUBROUTINE set_kpoint_info
497
498! **************************************************************************************************
499!> \brief Read the kpoint input section
500!> \param kpoint  The kpoint environment
501!> \param kpoint_section The input section
502!> \param a_vec ...
503!> \author JGH
504! **************************************************************************************************
505   SUBROUTINE read_kpoint_section(kpoint, kpoint_section, a_vec)
506      TYPE(kpoint_type), POINTER                         :: kpoint
507      TYPE(section_vals_type), POINTER                   :: kpoint_section
508      REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: a_vec
509
510      CHARACTER(len=*), PARAMETER :: routineN = 'read_kpoint_section', &
511         routineP = moduleN//':'//routineN
512
513      CHARACTER(LEN=default_string_length)               :: ustr
514      CHARACTER(LEN=default_string_length), &
515         DIMENSION(:), POINTER                           :: tmpstringlist
516      INTEGER                                            :: i, n_rep, nval, wfntype
517      LOGICAL                                            :: available
518      REAL(KIND=dp)                                      :: ff
519      REAL(KIND=dp), DIMENSION(:), POINTER               :: reallist
520
521      CPASSERT(ASSOCIATED(kpoint))
522
523      CALL section_vals_get(kpoint_section, explicit=available)
524
525      IF (available) THEN
526         CALL section_vals_val_get(kpoint_section, "SCHEME", c_vals=tmpstringlist)
527         nval = SIZE(tmpstringlist)
528         CPASSERT(nval >= 1)
529         kpoint%kp_scheme = tmpstringlist(1)
530         CALL uppercase(kpoint%kp_scheme)
531
532         ! SCHEME [None, Gamma, Monkhorst-Pack, MacDonald, General]
533         SELECT CASE (kpoint%kp_scheme)
534         CASE ("NONE")
535            ! do nothing
536         CASE ("GAMMA")
537            ! do nothing
538         CASE ("MONKHORST-PACK")
539            CPASSERT(nval >= 4)
540            DO i = 2, 4
541               READ (tmpstringlist(i), *) kpoint%nkp_grid(i - 1)
542            END DO
543         CASE ("MACDONALD")
544            CPASSERT(nval >= 7)
545            DO i = 2, 4
546               READ (tmpstringlist(i), *) kpoint%nkp_grid(i - 1)
547            END DO
548            DO i = 5, 7
549               READ (tmpstringlist(i), *) kpoint%kp_shift(i - 4)
550            END DO
551         CASE ("GENERAL")
552            CALL section_vals_val_get(kpoint_section, "UNITS", c_val=ustr)
553            CALL uppercase(ustr)
554            CALL section_vals_val_get(kpoint_section, "KPOINT", n_rep_val=n_rep)
555            kpoint%nkp = n_rep
556            ALLOCATE (kpoint%xkp(3, n_rep), kpoint%wkp(n_rep))
557            DO i = 1, n_rep
558               CALL section_vals_val_get(kpoint_section, "KPOINT", i_rep_val=i, &
559                                         r_vals=reallist)
560               nval = SIZE(reallist)
561               CPASSERT(nval >= 4)
562               SELECT CASE (ustr)
563               CASE ("B_VECTOR")
564                  kpoint%xkp(1:3, i) = reallist(1:3)
565               CASE ("CART_ANGSTROM")
566                  kpoint%xkp(1:3, i) = (reallist(1)*a_vec(1, 1:3) + &
567                                        reallist(2)*a_vec(2, 1:3) + &
568                                        reallist(3)*a_vec(3, 1:3))/twopi*angstrom
569               CASE ("CART_BOHR")
570                  kpoint%xkp(1:3, i) = (reallist(1)*a_vec(1, 1:3) + &
571                                        reallist(2)*a_vec(2, 1:3) + &
572                                        reallist(3)*a_vec(3, 1:3))/twopi
573               CASE DEFAULT
574                  CPABORT("Unknown Unit for kpoint definition")
575               END SELECT
576               kpoint%wkp(i) = reallist(4)
577            END DO
578            ff = 1.0_dp/SUM(kpoint%wkp(:))
579            kpoint%wkp(:) = ff*kpoint%wkp(:)
580         CASE DEFAULT
581            CPABORT("")
582         END SELECT
583
584         CALL section_vals_val_get(kpoint_section, "SYMMETRY", l_val=kpoint%symmetry)
585         CALL section_vals_val_get(kpoint_section, "WAVEFUNCTIONS", i_val=wfntype)
586         CALL section_vals_val_get(kpoint_section, "VERBOSE", l_val=kpoint%verbose)
587         CALL section_vals_val_get(kpoint_section, "FULL_GRID", l_val=kpoint%full_grid)
588         CALL section_vals_val_get(kpoint_section, "EPS_GEO", r_val=kpoint%eps_geo)
589         CALL section_vals_val_get(kpoint_section, "PARALLEL_GROUP_SIZE", &
590                                   i_val=kpoint%parallel_group_size)
591         SELECT CASE (wfntype)
592         CASE (use_real_wfn)
593            kpoint%use_real_wfn = .TRUE.
594         CASE (use_complex_wfn)
595            kpoint%use_real_wfn = .FALSE.
596         CASE DEFAULT
597            CPABORT("")
598         END SELECT
599
600      ELSE
601         kpoint%kp_scheme = "NONE"
602      END IF
603
604   END SUBROUTINE read_kpoint_section
605
606! **************************************************************************************************
607!> \brief Write information on the kpoints to output
608!> \param kpoint  The kpoint environment
609!> \param dft_section  DFT section information
610!> \author JGH
611! **************************************************************************************************
612   SUBROUTINE write_kpoint_info(kpoint, dft_section)
613      TYPE(kpoint_type), POINTER                         :: kpoint
614      TYPE(section_vals_type), POINTER                   :: dft_section
615
616      CHARACTER(len=*), PARAMETER :: routineN = 'write_kpoint_info', &
617         routineP = moduleN//':'//routineN
618
619      INTEGER                                            :: i, punit
620      TYPE(cp_logger_type), POINTER                      :: logger
621
622      CPASSERT(ASSOCIATED(kpoint))
623
624      NULLIFY (logger)
625      logger => cp_get_default_logger()
626
627      punit = cp_print_key_unit_nr(logger, dft_section, "PRINT%KPOINTS", extension=".Log")
628      IF (punit > 0) THEN
629
630         IF (kpoint%kp_scheme /= "NONE") THEN
631            WRITE (punit, '(/," ",79("*"),/,T37,A,/," ",79("*"))') "Kpoints"
632         END IF
633         SELECT CASE (kpoint%kp_scheme)
634         CASE ("NONE")
635            ! be silent
636         CASE ("GAMMA")
637            WRITE (punit, '(A,T57,A)') ' BRILLOUIN|', ' Gamma-point calculation'
638         CASE ("MONKHORST-PACK")
639            WRITE (punit, '(A,T61,A20)') ' BRILLOUIN| K-point scheme ', '      Monkhorst-Pack'
640            WRITE (punit, '(A,T66,3I5)') ' BRILLOUIN| K-Point grid', kpoint%nkp_grid
641            WRITE (punit, '(A,T66,G15.6)') ' BRILLOUIN| Accuracy in Symmetry determination', kpoint%eps_geo
642         CASE ("MACDONALD")
643            WRITE (punit, '(A,T71,A10)') ' BRILLOUIN| K-point scheme ', ' MacDonald'
644            WRITE (punit, '(A,T66,3I5)') ' BRILLOUIN| K-Point grid', kpoint%nkp_grid
645            WRITE (punit, '(A,T51,3F10.4)') ' BRILLOUIN| K-Point shift', kpoint%kp_shift
646            WRITE (punit, '(A,T66,G15.6)') ' BRILLOUIN| Accuracy in Symmetry determination', kpoint%eps_geo
647         CASE ("GENERAL")
648            WRITE (punit, '(A,T71,A10)') ' BRILLOUIN| K-point scheme ', '   General'
649         CASE DEFAULT
650            CPABORT("")
651         END SELECT
652         IF (kpoint%kp_scheme /= "NONE") THEN
653            IF (kpoint%symmetry) THEN
654               WRITE (punit, '(A,T76,A)') ' BRILLOUIN| K-Point point group symmetrization', '   ON'
655            ELSE
656               WRITE (punit, '(A,T76,A)') ' BRILLOUIN| K-Point point group symmetrization', '  OFF'
657            END IF
658            IF (kpoint%use_real_wfn) THEN
659               WRITE (punit, '(A,T76,A)') ' BRILLOUIN| Wavefunction type', ' REAL'
660            ELSE
661               WRITE (punit, '(A,T73,A)') ' BRILLOUIN| Wavefunction type', ' COMPLEX'
662            END IF
663            IF (kpoint%full_grid) THEN
664               WRITE (punit, '(A,T76,A)') ' BRILLOUIN| Use full k-point grid     '
665            END IF
666            IF (kpoint%kp_scheme /= "GAMMA") THEN
667               WRITE (punit, '(A,T71,I10)') ' BRILLOUIN| List of Kpoints [2 Pi/Bohr]', kpoint%nkp
668               WRITE (punit, '(A,T30,A,T48,A,T63,A,T78,A)') &
669                  ' BRILLOUIN| Number ', 'Weight', 'X', 'Y', 'Z'
670               DO i = 1, kpoint%nkp
671                  WRITE (punit, '(A,I5,3X,4F15.5)') ' BRILLOUIN| ', i, kpoint%wkp(i), &
672                     kpoint%xkp(1, i), kpoint%xkp(2, i), kpoint%xkp(3, i)
673               END DO
674            END IF
675            WRITE (punit, '(" ",79("*"))')
676         END IF
677
678      END IF
679      CALL cp_print_key_finished_output(punit, logger, dft_section, "PRINT%KPOINTS")
680
681   END SUBROUTINE write_kpoint_info
682
683! **************************************************************************************************
684!> \brief Create a single kpoint environment
685!> \param kp_env  Single kpoint environment
686!> \author JGH
687! **************************************************************************************************
688   SUBROUTINE kpoint_env_create(kp_env)
689      TYPE(kpoint_env_type), POINTER                     :: kp_env
690
691      CHARACTER(LEN=*), PARAMETER :: routineN = 'kpoint_env_create', &
692         routineP = moduleN//':'//routineN
693
694      CPASSERT(.NOT. ASSOCIATED(kp_env))
695
696      ALLOCATE (kp_env)
697
698      kp_env%nkpoint = 0
699      kp_env%wkp = 0.0_dp
700      kp_env%xkp = 0.0_dp
701      kp_env%is_local = .FALSE.
702
703      NULLIFY (kp_env%mos)
704      NULLIFY (kp_env%pmat)
705      NULLIFY (kp_env%wmat)
706
707   END SUBROUTINE kpoint_env_create
708
709! **************************************************************************************************
710!> \brief Release a single kpoint environment
711!> \param kp_env  Single kpoint environment
712!> \author JGH
713! **************************************************************************************************
714   SUBROUTINE kpoint_env_release(kp_env)
715      TYPE(kpoint_env_type), POINTER                     :: kp_env
716
717      CHARACTER(LEN=*), PARAMETER :: routineN = 'kpoint_env_release', &
718         routineP = moduleN//':'//routineN
719
720      INTEGER                                            :: ic, is
721
722      IF (ASSOCIATED(kp_env)) THEN
723
724         IF (ASSOCIATED(kp_env%mos)) THEN
725            DO is = 1, SIZE(kp_env%mos, 2)
726               DO ic = 1, SIZE(kp_env%mos, 1)
727                  CALL deallocate_mo_set(kp_env%mos(ic, is)%mo_set)
728               END DO
729            END DO
730            DEALLOCATE (kp_env%mos)
731         END IF
732
733         IF (ASSOCIATED(kp_env%pmat)) THEN
734            DO is = 1, SIZE(kp_env%pmat, 2)
735               DO ic = 1, SIZE(kp_env%pmat, 1)
736                  CALL cp_fm_release(kp_env%pmat(ic, is)%matrix)
737               END DO
738            END DO
739            DEALLOCATE (kp_env%pmat)
740         END IF
741
742         IF (ASSOCIATED(kp_env%wmat)) THEN
743            DO is = 1, SIZE(kp_env%wmat, 2)
744               DO ic = 1, SIZE(kp_env%wmat, 1)
745                  CALL cp_fm_release(kp_env%wmat(ic, is)%matrix)
746               END DO
747            END DO
748            DEALLOCATE (kp_env%wmat)
749         END IF
750
751         DEALLOCATE (kp_env)
752
753      END IF
754
755   END SUBROUTINE kpoint_env_release
756
757! **************************************************************************************************
758!> \brief Get information from a single kpoint environment
759!> \param kpoint_env Single kpoint environment
760!> \param nkpoint    Index of kpoint
761!> \param wkp        Weight of kpoint
762!> \param xkp        Coordinates of kpoint
763!> \param is_local   Is this kpoint local (single cpu group)
764!> \param mos        MOs of this kpoint
765!> \author JGH
766! **************************************************************************************************
767   SUBROUTINE get_kpoint_env(kpoint_env, nkpoint, wkp, xkp, is_local, mos)
768      TYPE(kpoint_env_type), POINTER                     :: kpoint_env
769      INTEGER, OPTIONAL                                  :: nkpoint
770      REAL(KIND=dp), OPTIONAL                            :: wkp
771      REAL(KIND=dp), DIMENSION(3), OPTIONAL              :: xkp
772      LOGICAL, OPTIONAL                                  :: is_local
773      TYPE(mo_set_p_type), DIMENSION(:, :), OPTIONAL, &
774         POINTER                                         :: mos
775
776      CHARACTER(LEN=*), PARAMETER :: routineN = 'get_kpoint_env', routineP = moduleN//':'//routineN
777
778      CPASSERT(ASSOCIATED(kpoint_env))
779
780      IF (PRESENT(nkpoint)) nkpoint = kpoint_env%nkpoint
781      IF (PRESENT(wkp)) wkp = kpoint_env%wkp
782      IF (PRESENT(xkp)) xkp = kpoint_env%xkp
783      IF (PRESENT(is_local)) is_local = kpoint_env%is_local
784      IF (PRESENT(mos)) mos => kpoint_env%mos
785
786   END SUBROUTINE get_kpoint_env
787
788! **************************************************************************************************
789!> \brief Create a single kpoint symmetry environment
790!> \param kp_sym  ...
791!> \author JGH
792! **************************************************************************************************
793   SUBROUTINE kpoint_sym_create(kp_sym)
794      TYPE(kpoint_sym_type), POINTER                     :: kp_sym
795
796      CHARACTER(LEN=*), PARAMETER :: routineN = 'kpoint_sym_create', &
797         routineP = moduleN//':'//routineN
798
799      CPASSERT(.NOT. ASSOCIATED(kp_sym))
800
801      ALLOCATE (kp_sym)
802
803      kp_sym%nwght = 0
804      kp_sym%apply_symmetry = .FALSE.
805
806      NULLIFY (kp_sym%rot)
807      NULLIFY (kp_sym%xkp)
808      NULLIFY (kp_sym%f0)
809
810   END SUBROUTINE kpoint_sym_create
811
812! **************************************************************************************************
813!> \brief Release a single kpoint symmetry environment
814!> \param kp_sym  ...
815!> \author JGH
816! **************************************************************************************************
817   SUBROUTINE kpoint_sym_release(kp_sym)
818      TYPE(kpoint_sym_type), POINTER                     :: kp_sym
819
820      CHARACTER(LEN=*), PARAMETER :: routineN = 'kpoint_sym_release', &
821         routineP = moduleN//':'//routineN
822
823      IF (ASSOCIATED(kp_sym)) THEN
824
825         IF (ASSOCIATED(kp_sym%rot)) THEN
826            DEALLOCATE (kp_sym%rot)
827         END IF
828         IF (ASSOCIATED(kp_sym%xkp)) THEN
829            DEALLOCATE (kp_sym%xkp)
830         END IF
831         IF (ASSOCIATED(kp_sym%f0)) THEN
832            DEALLOCATE (kp_sym%f0)
833         END IF
834
835         DEALLOCATE (kp_sym)
836
837      END IF
838
839   END SUBROUTINE kpoint_sym_release
840
841! **************************************************************************************************
842
843END MODULE kpoint_types
844