Branch data Line data Source code
1 : : !!****m* ABINIT/m_kpts
2 : : !! NAME
3 : : !! m_kpts
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !! COPYRIGHT
8 : : !! Copyright (C) 2008-2026 ABINIT group (XG, MG, MJV, DRH, DCA, JCC, MM)
9 : : !! This file is distributed under the terms of the
10 : : !! GNU General Public License, see ~abinit/COPYING
11 : : !! or http://www.gnu.org/copyleft/gpl.txt .
12 : : !!
13 : : !! SOURCE
14 : :
15 : : #if defined HAVE_CONFIG_H
16 : : #include "config.h"
17 : : #endif
18 : :
19 : : #include "abi_common.h"
20 : :
21 : : module m_kpts
22 : :
23 : : use defs_basis
24 : : use m_errors
25 : : use m_abicore
26 : : use m_crystal
27 : : use m_sort
28 : : use m_krank
29 : : use m_htetra
30 : : use m_xmpi
31 : :
32 : : use m_time, only : timab, cwtime, cwtime_report
33 : : use m_copy, only : alloc_copy
34 : : use m_numeric_tools, only : wrap2_zero_one, interpol3d_0d
35 : : use m_matrix, only : mati3inv, mati3det, matr3inv
36 : : use m_symtk, only : smallprim
37 : : use m_fstrings, only : sjoin, itoa, ftoa, ltoa, ktoa
38 : : use m_numeric_tools, only : wrap2_pmhalf
39 : : use m_geometry, only : metric
40 : : use m_symkpt, only : symkpt, symkpt_new
41 : :
42 : : implicit none
43 : :
44 : : private
45 : :
46 : : public :: kpts_timrev_from_kptopt ! Returns the value of timrev from kptopt
47 : : public :: kpts_ibz_from_kptrlatt ! Determines the IBZ, the weights and the BZ from kptrlatt
48 : : public :: tetra_from_kptrlatt ! Create an instance of htetra_t from kptrlatt and shiftk
49 : : public :: symkchk ! Checks that the set of k points has the full space group symmetry, modulo time reversal if appropriate.
50 : : public :: kpts_sort ! order list of k-points according to the norm.
51 : : public :: kpts_pack_in_stars ! Pack k-points in stars.
52 : : public :: kpts_map ! Compute symmetry table.
53 : : public :: kpts_map_print ! Print the symmetry table bz2ibz to a list of units with header.
54 : : public :: listkk ! Find correspondence between two set of k-points.
55 : : public :: getkgrid ! Compute the grid of k points in the irreducible Brillouin zone.
56 : : public :: smpbz ! Generate a set of special k (or q) points which samples in a homogeneous way the BZ
57 : : public :: testkgrid ! Test different grids of k points.
58 : : public :: kptrlatt_from_ngkpt ! Insert ngkpt in kptrlatt matrix
59 : : public :: kptrlatt_from_brav_ngqpt ! Build the kptrlatt reproducing a legacy brav==2/3/4 mesh via smpbz's general algorithm
60 : : public :: kptrlatt_ncells ! Exact number of k/q points smpbz's general algorithm produces for a given kptrlatt/nshiftk
61 : : public :: qmesh_from_brav_ngqpt ! Translate the historical (brav, ngqpt, shifts) q-mesh specification into (kptrlatt, shifts)
62 : : public :: kptrlatt_merge_shifts ! Supercell matrix (Born-von Karman box) of a q-mesh with several shifts
63 : :
64 : : !FIXME: Deprecated
65 : : public :: get_full_kgrid ! Create full grid of kpoints and find equivalent irred ones.
66 : : public :: mknormpath
67 : : private :: get_kpt_fullbz ! Create full grid of kpoints from kptrlatt and shiftk
68 : : !!***
69 : :
70 : : #if 0
71 : : type, public :: kinds_t
72 : : integer :: ibz_idx
73 : : integer :: isym
74 : : integer :: trev
75 : : integer :: g0(3)
76 : : logical :: is_irred
77 : : contains
78 : : end type kinds_t
79 : : !!***
80 : :
81 : : type, public :: kmap_t
82 : : integer :: nkpt = -1
83 : : integer :: kptopt = -1
84 : : integer :: ierr = -1
85 : : !character(len=500) :: err_msg
86 : : character(len=20) :: mode
87 : : real(dp) :: dksqmax
88 : : real(dp) :: qpt(3) = zero
89 : : type(kinds_t),allocatable :: inds(:)
90 : : contains
91 : : procedure :: free => kmap_free
92 : : end type kmap_t
93 : : !!***
94 : : #endif
95 : :
96 : : !----------------------------------------------------------------------
97 : :
98 : : !!****t* m_kpts/bzlint_t
99 : : !! NAME
100 : : !! bzlint_t
101 : : !!
102 : : !! FUNCTION
103 : : !! Linear interpolator for functions defined in the BZ.
104 : : !!
105 : : !! To interpolate initial data defined on a ngkpt(3) k-mesh.
106 : : !! if the values of shape (ndat, nkpt) are known on nkpt k-points `kpts(3,nkpt)
107 : : !! belonging to the ngkpt mesh, use the following calls:
108 : : !!
109 : : !! Example:
110 : : !! type(bzlint_t) :: bzlint
111 : : !! call bzlint%init(ngkpt, ndat, nkpt, kpts, values)
112 : : !!
113 : : !! ! Now we can (linearly) interpolate at arbitrary kpoints
114 : : !! allocate(results, (ndat)
115 : : !! do ik=1,nk_interp(interp_kpt, results)
116 : : !! call bzlint%free(results)
117 : : !! end do
118 : : !!
119 : : !! call bzlint%free() ! Free memory
120 : : !!
121 : : !! To handle complex data, use real(dp) pointers associated to complex(dp) arrays as in:
122 : : !!
123 : : !! use, intrinsic :: iso_c_binding
124 : : !! complex(dp),allocatable,target :: cvalues(:)
125 : : !! real(dp), ABI_CONTIGUOUS pointer :: rpt_d2(:,:)
126 : : !!
127 : : !! allocate(cvalues(ndat, nkpt))
128 : : !! ! fill cvalues...
129 : : !!
130 : : !! call c_f_pointer(c_loc(cvalues), rpt_d2, [2*ndat, nkpt])
131 : : !! call bzlint%init(ngkpt, 2*ndat, nkpt, kpts, rpt_d2)
132 : : !!
133 : : !! SOURCE
134 : :
135 : : type, public :: bzlint_t
136 : : integer :: nx, ny, nz, ndat
137 : : integer :: ngkpt(3)
138 : : real(dp),allocatable :: vals_grid(:,:,:,:)
139 : : contains
140 : : procedure :: init => bzlint_init
141 : : procedure :: interp => bzlint_interp
142 : : procedure :: free => bzlint_free
143 : : end type bzlint_t
144 : : !!***
145 : :
146 : : !----------------------------------------------------------------------
147 : :
148 : : contains !============================================================
149 : : !!***
150 : :
151 : : !!****f* m_kpts/kpts_timrev_from_kptopt
152 : : !! NAME
153 : : !! kpts_timrev_from_kptopt
154 : : !!
155 : : !! FUNCTION
156 : : !! Returns the value of timrev from kptopt
157 : : !! 1 if the use of time-reversal is allowed; 0 otherwise
158 : : !!
159 : : !! INPUTS
160 : : !! kptopt=option for the generation of k points
161 : : !! (defines whether spatial symmetries and/or time-reversal can be used)
162 : : !!
163 : : !! SOURCE
164 : :
165 : 91115 : integer pure function kpts_timrev_from_kptopt(kptopt) result(timrev)
166 : :
167 : : !Arguments ------------------------------------
168 : : integer,intent(in) :: kptopt
169 : : ! *********************************************************************
170 : :
171 [ + + - + ]: 91115 : timrev = 1; if (any(kptopt == [3, 4])) timrev = 0
172 : :
173 : 4070 : end function kpts_timrev_from_kptopt
174 : : !!***
175 : :
176 : : !!****f* m_kpts/kpts_ibz_from_kptrlatt
177 : : !! NAME
178 : : !! kpts_ibz_from_kptrlatt
179 : : !!
180 : : !! FUNCTION
181 : : !! Determines the irreducible wedge, the corresponding weights and the list
182 : : !! of k-points in the Brillouin Zone starting from kptrlatt and the set shifts.
183 : : !!
184 : : !! INPUTS
185 : : !! cryst<crystal_t> = crystalline structure with info on symmetries and time-reversal.
186 : : !! kptopt=option for the generation of k points (defines whether spatial symmetries and/or time-reversal can be used)
187 : : !! kptrlatt(3,3)=integer coordinates of the primitive vectors of the
188 : : !! lattice reciprocal to the k point lattice to be generated here
189 : : !! If diagonal, the three values are the Monkhorst-Pack usual values, in case of simple cubic.
190 : : !! nshiftk= number of shift vectors in the repeated cell
191 : : !! shiftk(3,nshiftk) = vectors that will be used to determine the shifts from (0. 0. 0.).
192 : : !!
193 : : !! OUTPUT
194 : : !! nkibz,nkbz = Number of points in IBZ and BZ, respectively.
195 : : !! The following arrays are allocated and returned by the routine:
196 : : !! kibz(3,nkibz) = k-points in the IBZ.
197 : : !! wtk(nkibz) = weights of the k-points in the IBZ (normalized to one).
198 : : !! kbz(3,nkbz) = k-points in the BZ.
199 : : !! [new_kptrlatt] = New value of kptrlatt returned by getkgrid
200 : : !! [new_shiftk(3,new_nshiftk)] = New set of shifts returned by getkgrid
201 : : !! [bz2ibz(6,nkbz)]=Mapping BZ --> IBZ
202 : : !!
203 : : !! SOURCE
204 : :
205 : 535 : subroutine kpts_ibz_from_kptrlatt(cryst, kptrlatt, kptopt, nshiftk, shiftk, & ! in
206 : : nkibz, kibz, wtk, nkbz, kbz, & ! out
207 : : new_kptrlatt, new_shiftk, bz2ibz) ! out Optional
208 : :
209 : : !Arguments ------------------------------------
210 : : !scalars
211 : : integer,intent(in) :: nshiftk,kptopt
212 : : integer,intent(out) :: nkibz,nkbz
213 : : type(crystal_t),intent(in) :: cryst
214 : : !arrays
215 : : integer,intent(in) :: kptrlatt(3,3)
216 : : integer,optional,allocatable,intent(out) :: bz2ibz(:,:)
217 : : integer,optional,intent(out) :: new_kptrlatt(3,3)
218 : : real(dp),intent(in) :: shiftk(3,nshiftk)
219 : : real(dp),allocatable,intent(out) :: wtk(:),kibz(:,:),kbz(:,:)
220 : : real(dp),optional,allocatable,intent(out) :: new_shiftk(:,:)
221 : :
222 : : !Local variables-------------------------------
223 : : !scalars
224 : : integer,parameter :: iout0 = 0, chksymbreak0 = 0, iscf2 = 2
225 : : integer :: my_nshiftk
226 : : real(dp) :: kptrlen
227 : : !arrays
228 : : integer,parameter :: vacuum0(3) = [0, 0, 0]
229 : : integer :: my_kptrlatt(3,3)
230 : 535 : integer,allocatable :: indkpt(:),bz2ibz_smap(:,:)
231 : : real(dp) :: my_shiftk(3,MAX_NSHIFTK)
232 : : ! *********************************************************************
233 : :
234 : : ! Copy kptrlatt and shifts because getkgrid can change them
235 : : ! Be careful as getkgrid expects shiftk(3,MAX_NSHIFTK).
236 [ - + ]: 535 : ABI_CHECK_IRANGE(nshiftk, 1, MAX_NSHIFTK, "Invalid value of nshiftk")
237 [ + + + + ]: 2675 : my_nshiftk = nshiftk; my_shiftk = zero; my_shiftk(:,1:nshiftk) = shiftk
238 : 535 : my_kptrlatt = kptrlatt
239 : :
240 : : call getkgrid_low(chksymbreak0,iout0,iscf2,kibz,kptopt,my_kptrlatt,kptrlen,&
241 : : cryst%nsym,-1,nkibz,my_nshiftk,cryst%nsym,cryst%rprimd,my_shiftk,cryst%symafm,&
242 [ - + - + : 535 : cryst%symrel,vacuum0,wtk,indkpt,bz2ibz_smap,fullbz=kbz)
- + ]
243 : :
244 [ + + ]: 535 : if (present(bz2ibz)) then
245 [ - + ]: 335 : ABI_MOVE_ALLOC(bz2ibz_smap, bz2ibz)
246 : : else
247 [ + - ]: 200 : ABI_SFREE(bz2ibz_smap)
248 : : endif
249 [ + + ]: 535 : ABI_SFREE(indkpt)
250 : :
251 : 535 : nkbz = size(kbz, dim=2)
252 : :
253 : : ! Optionally, return new shifts and new_kptrlatt
254 [ + + ]: 535 : if (present(new_shiftk)) then
255 [ - + + - : 834 : ABI_MALLOC(new_shiftk, (3, my_nshiftk))
+ - + - -
+ - + -
+ ]
256 [ - + + + : 1668 : new_shiftk = my_shiftk(:, 1:my_nshiftk)
+ + ]
257 : : end if
258 [ + + ]: 535 : if (present(new_kptrlatt)) new_kptrlatt = my_kptrlatt
259 : :
260 : : DBG_CHECK(abs(sum(wtk) - one) < tol10, "sum(wtk) != one")
261 : :
262 [ - + - + ]: 535 : end subroutine kpts_ibz_from_kptrlatt
263 : : !!***
264 : :
265 : : !----------------------------------------------------------------------
266 : :
267 : : !!****f* m_kpts/tetra_from_kptrlatt
268 : : !! NAME
269 : : !! tetra_from_kptrlatt
270 : : !!
271 : : !! FUNCTION
272 : : !! Helper function to to create an instance and htetra from kptrlatt and shiftk
273 : : !!
274 : : !! INPUTS
275 : : !! cryst<cryst_t>=Crystalline structure.
276 : : !! kptopt=Option for the k-point generation.
277 : : !! kptrlatt(3,3)=k-point lattice specification
278 : : !! nshiftk= number of shift vectors.
279 : : !! shiftk(3,nshiftk)=shift vectors for k point generation
280 : : !! nkibz=Number of points in the IBZ
281 : : !! kibz(3,nkibz)=Reduced coordinates of the k-points in the IBZ.
282 : : !! comm= MPI communicator
283 : : !!
284 : : !! OUTPUT
285 : : !! tetra<htetra_t>=Tetrahedron object, fully initialized if ierr == 0.
286 : : !! msg=Error message if ierr /= 0
287 : : !! ierr=Exit status
288 : : !!
289 : : !! SOURCE
290 : :
291 : 81 : type(htetra_t) function tetra_from_kptrlatt( &
292 : 81 : cryst, kptopt, kptrlatt, nshiftk, shiftk, nkibz, kibz, comm, msg, ierr) result (htetra)
293 : :
294 : : !Arguments ------------------------------------
295 : : !scalars
296 : : integer,intent(in) :: kptopt,nshiftk,nkibz,comm
297 : : integer,intent(out) :: ierr
298 : : character(len=*),intent(out) :: msg
299 : : type(crystal_t),intent(in) :: cryst
300 : : !arrays
301 : : integer,intent(in) :: kptrlatt(3,3)
302 : : real(dp),intent(in) :: shiftk(3,nshiftk),kibz(3,nkibz)
303 : :
304 : : !Local variables-------------------------------
305 : : !scalars
306 : : integer :: nkfull,my_nkibz,new_nshiftk
307 : : character(len=80) :: errorstring
308 : : !arrays
309 : : integer :: new_kptrlatt(3,3)
310 : 81 : integer,allocatable :: indkk(:)
311 : 81 : integer,allocatable :: bz2ibz(:,:)
312 : : real(dp) :: rlatt(3,3),klatt(3,3)
313 : 81 : real(dp),allocatable :: kfull(:,:),my_kibz(:,:),my_wtk(:),new_shiftk(:,:)
314 : : ! *************************************************************************
315 : :
316 : 81 : ierr = 0
317 : :
318 : : ! Refuse only 1 kpoint: the algorithms are no longer valid. DOH!
319 : 81 : if (nkibz == 1) then
320 [ # # # # ]: 0 : msg = 'You need at least 2 kpoints to use the tetrahedron method.'
321 : 0 : ierr = 1; goto 10
322 : : end if
323 [ + - + - : 81 : if (all(kptrlatt == 0)) then
- + - + ]
324 [ # # # # ]: 0 : msg = 'Cannot generate tetrahedron because input kptrlatt == 0.'
325 : 0 : ierr = 1; goto 10
326 : : end if
327 [ - + ]: 81 : if (kptopt <= 0) then
328 [ # # # # ]: 0 : msg = sjoin("Cannot generate tetrahedron because input kptopt:", itoa(kptopt))
329 : 0 : ierr = 1; goto 10
330 : : end if
331 : :
332 : : call kpts_ibz_from_kptrlatt(cryst, kptrlatt, kptopt, nshiftk, shiftk, &
333 : 81 : my_nkibz, my_kibz, my_wtk, nkfull, kfull, new_kptrlatt=new_kptrlatt, new_shiftk=new_shiftk, bz2ibz=bz2ibz)
334 : :
335 [ - + ]: 81 : ABI_FREE(my_wtk)
336 : 81 : new_nshiftk = size(new_shiftk, dim=2)
337 : :
338 [ + - + - : 81 : if (my_nkibz /= nkibz .or. all(my_kibz /= kibz) ) then
- + + - -
+ ]
339 [ # # # # ]: 0 : msg = sjoin("Input nkibz:", itoa(nkibz), "does not agree with computed value:", itoa(my_nkibz))
340 : 0 : ierr = 1; goto 10
341 : : end if
342 : :
343 : : ! Do not support new_nshiftk > 1: lattice must be decomposed into boxes
344 : : ! and this is not always possible (I think) with bizarre shifts
345 : : ! normally at this point we have incorporated everything into
346 : : ! new_kptrlatt, and only 1 shift is needed (in particular for MP grids).
347 [ - + ]: 81 : if (new_nshiftk > 1) then
348 : : write(msg, "(9a)") &
349 : 0 : 'Cannot create tetrahedron object...',ch10, &
350 : 0 : 'Only simple lattices are supported. Action: use nshiftk=1.',ch10, &
351 [ # # # # ]: 0 : 'new_shiftk: ', trim(ltoa(reshape(new_shiftk, [3*new_nshiftk]))),ch10, &
352 [ # # ]: 0 : 'new_kptrlatt: ', trim(ltoa(reshape(new_kptrlatt, [9])))
353 : 0 : ierr = 2; goto 10
354 : : end if
355 : :
356 [ + + + + ]: 1053 : rlatt = new_kptrlatt; call matr3inv(rlatt, klatt)
357 : :
358 [ - + + - : 243 : ABI_MALLOC(indkk, (nkfull))
+ - + - -
+ - + ]
359 [ + + ]: 164424 : indkk(:) = bz2ibz(1, :)
360 [ + - ]: 81 : ABI_SFREE(bz2ibz)
361 : :
362 : 81 : call htetra%init(indkk, cryst%gprimd, klatt, kfull, nkfull, my_kibz, my_nkibz, ierr, errorstring, comm)
363 [ + - - - : 81 : if (ierr /= 0) msg = errorstring
- - ]
364 : :
365 : : 10 continue
366 : :
367 [ + - ]: 81 : ABI_SFREE(my_kibz)
368 [ + - ]: 81 : ABI_SFREE(indkk)
369 [ + - ]: 81 : ABI_SFREE(kfull)
370 [ + - ]: 81 : ABI_SFREE(new_shiftk)
371 : :
372 [ - + - + : 162 : end function tetra_from_kptrlatt
- + - + -
+ - + ]
373 : : !!***
374 : :
375 : : !!****f* m_kpts/symkchk
376 : : !! NAME
377 : : !! symkchk
378 : : !!
379 : : !! FUNCTION
380 : : !! Checks that the set of k points chosen for a response function
381 : : !! calculation has the full space group symmetry, modulo time reversal if appropriate.
382 : : !! Returns ierr/=0 with error message if not satisfied
383 : : !! Currently used only when strain perturbation is treated. Based on symkpt.
384 : : !!
385 : : !! INPUTS
386 : : !! kptns(3,nkpt)= k vectors in reciprocal space
387 : : !! nkpt = number of k-points whose weights are wtk
388 : : !! nsym=number of space group symmetries
389 : : !! symrec(3,3,nsym)=3x3 matrices of the group symmetries (reciprocal space)
390 : : !! timrev: if 1, the time reversal operation has to be taken into account
391 : : !! if 0, no time reversal symmetry.
392 : : !!
393 : : !! OUTPUT
394 : : !! msg=Error message if ierr /= 0
395 : : !!
396 : : !! TODO
397 : : !! This version should scale badly with the number of k-points. Replace loops with listkk
398 : : !!
399 : : !! SOURCE
400 : :
401 : 37 : integer function symkchk(kptns,nkpt,nsym,symrec,timrev,errmsg) result(ierr)
402 : :
403 : : !Arguments -------------------------------
404 : : !scalars
405 : : integer,intent(in) :: nkpt,nsym,timrev
406 : : character(len=*),intent(out) :: errmsg
407 : : !arrays
408 : : integer,intent(in) :: symrec(3,3,nsym)
409 : : real(dp),intent(in) :: kptns(3,nkpt)
410 : :
411 : : !Local variables -------------------------
412 : : !scalars
413 : : integer :: identi,ii,ikpt,ikpt2,imatch,isym,jj,tident
414 : : real(dp) :: difk,reduce
415 : : character(len=500) :: msg
416 : : !arrays
417 : : real(dp) :: ksym(3)
418 : : ! *********************************************************************
419 : :
420 : 37 : ierr = 0
421 : :
422 : 37 : if(timrev/=1 .and. timrev/=0)then
423 : : write(errmsg, '(3a,i0,a)' )&
424 : 0 : 'timrev should be 0 or 1, while',ch10,&
425 : 0 : 'it is equal to ',timrev,'.'
426 : 0 : ierr = 1; return
427 : : end if
428 : :
429 [ + + ]: 37 : if(nsym/=1)then
430 : : ! Find the identity symmetry operation
431 [ + - ]: 36 : do isym=1,nsym
432 : : tident=1
433 [ + + ]: 144 : do jj=1,3
434 [ - + ]: 108 : if(symrec(jj,jj,isym)/=1)tident=0
435 [ + + ]: 468 : do ii=1,3
436 [ + + + - ]: 756 : if( ii/=jj .and.symrec(ii,jj,isym)/=0)tident=0
437 : : end do
438 : : end do
439 [ + - ]: 36 : if(tident==1)then
440 : 36 : identi=isym
441 : 36 : call wrtout(std_out,sjoin(' symkchk: found identity with number:', itoa(identi)))
442 : 36 : exit
443 : : end if
444 : : end do
445 [ - + ]: 36 : if(tident==0)then
446 [ # # # # ]: 0 : errmsg = 'Did not found the identity operation.'
447 : 0 : ierr = 1; return
448 : : end if
449 : : end if
450 : :
451 : : !Here begins the serious business
452 : : !The length sorting, etc. of symkpt have been dropped because the
453 : : !computational cost is estimated to be negligible.
454 : :
455 [ + + + - ]: 37 : if(nsym>1 .or. timrev==1)then
456 : :
457 : : ! Outer loop over kpts
458 [ + + ]: 5672 : do ikpt=1,nkpt-1
459 : :
460 : : ! Loop on the symmetries
461 : : ! For each k-point and each symmetry transformation, a matching
462 : : ! k-point must be found, modulo time reversal if appropriate
463 [ + + ]: 231509 : do isym=1,nsym
464 : :
465 : : ! Get the symmetric of the vector
466 [ + + ]: 903348 : do ii=1,3
467 : : ksym(ii)= kptns(1,ikpt)*symrec(ii,1,isym)&
468 : : & +kptns(2,ikpt)*symrec(ii,2,isym)&
469 : 903348 : & +kptns(3,ikpt)*symrec(ii,3,isym)
470 : : end do
471 : :
472 : : ! Second loop k-points
473 [ + - ]: 133743336 : do ikpt2=1,nkpt
474 : :
475 : : ! Test for match of symmetric and any vector (including original)
476 : : imatch=1
477 [ + + ]: 534973344 : do ii=1,3
478 : 401230008 : difk= ksym(ii)-kptns(ii,ikpt2)
479 : 401230008 : reduce=difk-anint(difk)
480 [ + + ]: 534973344 : if(abs(reduce)>tol8)imatch=0
481 : : end do
482 [ + + ]: 133743336 : if(imatch==1)exit
483 : :
484 : : ! Test for match with time reversal
485 [ + - ]: 133855570 : if(timrev==1)then
486 : : imatch=1
487 [ + + ]: 534518932 : do ii=1,3
488 : 400889199 : difk= ksym(ii)+kptns(ii,ikpt2)
489 : 400889199 : reduce=difk-anint(difk)
490 [ + + ]: 534518932 : if(abs(reduce)>tol8)imatch=0
491 : : end do
492 [ + + ]: 133629733 : if(imatch==1)exit
493 : : end if
494 : :
495 : : end do ! End secondary loop over k-points
496 [ - + ]: 231472 : if (imatch/=1) then
497 : : write(errmsg, '(a,a,a,i0,a,i0,a,a,a,a)' )&
498 : 0 : 'k-point set must have full space-group symmetry',ch10,&
499 : 0 : 'there is no match for kpt: ',ikpt,' transformed by symmetry: ',isym,ch10,&
500 : 0 : 'Action: change kptopt to 2 or 3 and/or change or use shiftk',ch10,&
501 : 0 : 'shiftk = 0 0 0 is always a safe choice.'
502 : 0 : ierr = 2; return
503 : : end if
504 : :
505 : : end do ! End loop on isym
506 : : end do ! End primary loop over k-points
507 : :
508 : 37 : write(msg,'(a)')' symkchk : k-point set has full space-group symmetry.'
509 [ + + ]: 111 : call wrtout([std_out, ab_out], msg)
510 : : end if
511 : :
512 [ - + ]: 37 : end function symkchk
513 : : !!***
514 : :
515 : : !!****f* m_kpts/kpts_sort
516 : : !! NAME
517 : : !! kpts_sort
518 : : !!
519 : : !! FUNCTION
520 : : !! Order list of k-points according to their norm.
521 : : !!
522 : : !! SOURCE
523 : :
524 : 0 : subroutine kpts_sort(gprimd, nkpt, kpts)
525 : :
526 : : !Arguments ------------------------------------
527 : : !scalars
528 : : integer,intent(in) :: nkpt
529 : : !arrays
530 : : real(dp),intent(in) :: gprimd(3, 3)
531 : : real(dp),intent(inout) :: kpts(3, nkpt)
532 : :
533 : : !Local variables-------------------------------
534 : : !scalars
535 : : integer :: ikpt
536 : : !arrays
537 : 0 : integer,allocatable :: iperm(:)
538 : 0 : real(dp),allocatable :: knorm2(:), kpts_ord(:,:)
539 : : ! *************************************************************************
540 : :
541 [ # # # # : 0 : ABI_MALLOC(knorm2, (nkpt))
# # # # #
# # # ]
542 [ # # ]: 0 : do ikpt=1,nkpt
543 [ # # # # : 0 : knorm2(ikpt) = dot_product(kpts(:,ikpt), matmul(gprimd, kpts(:, ikpt)))
# # ]
544 : : end do
545 : :
546 [ # # # # : 0 : ABI_MALLOC(iperm, (nkpt))
# # # # #
# # # ]
547 [ # # # # : 0 : iperm = [(ikpt, ikpt=1, nkpt)]
# # # # #
# # # # #
# # ]
548 : 0 : call sort_dp(nkpt, knorm2, iperm, tol12)
549 [ # # ]: 0 : ABI_FREE(knorm2)
550 : :
551 [ # # # # : 0 : ABI_MALLOC(kpts_ord, (3, nkpt))
# # # # #
# # # ]
552 [ # # ]: 0 : do ikpt=1,nkpt
553 [ # # ]: 0 : kpts_ord(:, ikpt) = kpts(:, iperm(ikpt))
554 : : end do
555 [ # # # # ]: 0 : kpts = kpts_ord
556 : :
557 [ # # ]: 0 : ABI_FREE(iperm)
558 [ # # ]: 0 : ABI_FREE(kpts_ord)
559 : :
560 : 0 : end subroutine kpts_sort
561 : : !!***
562 : :
563 : : !!****f* m_kpts/kpts_pack_in_stars
564 : : !! NAME
565 : : !! kpts_pack_in_stars
566 : : !!
567 : : !! FUNCTION
568 : : !! Pack k-points in stars using kmap symmetry table.
569 : : !! Rearrange kpts as well as kmap.
570 : : !!
571 : : !! SOURCE
572 : :
573 : 8 : subroutine kpts_pack_in_stars(nkpt, kpts, kmap)
574 : :
575 : : !Arguments ------------------------------------
576 : : !scalars
577 : : integer,intent(in) :: nkpt
578 : : !arrays
579 : : real(dp),intent(inout) :: kpts(3, nkpt)
580 : : integer,intent(inout) :: kmap(6, nkpt)
581 : :
582 : : !Local variables-------------------------------
583 : : !scalars
584 : : integer :: ikpt, seen_ibz, ik_start, ik0, nkibz
585 : : integer :: ik_ibz, isym_k, trev_k, tsign, g0_k(3)
586 : : logical :: isirr_k
587 : : !arrays
588 : 8 : integer,allocatable :: iperm(:), ibz_ids(:), kmap_ord(:,:), star_pos(:,:)
589 : : real(dp) :: swap_kpt(3), swap_kmap(6)
590 : 8 : real(dp),allocatable :: kpts_ord(:,:)
591 : : ! *************************************************************************
592 : :
593 : : ! Order according to ik_ibz index
594 [ - + + - : 24 : ABI_MALLOC(ibz_ids, (nkpt))
+ - + - -
+ - + ]
595 [ - + + - : 16 : ABI_MALLOC(iperm, (nkpt))
- + - + ]
596 [ - + + + ]: 2573 : ibz_ids = kmap(1, :)
597 [ + - + + : 7695 : iperm = [(ikpt, ikpt=1, nkpt)]
+ - + + +
- - + - -
+ + ]
598 : :
599 : 8 : call sort_int(nkpt, ibz_ids, iperm)
600 [ - + ]: 8 : ABI_FREE(ibz_ids)
601 : :
602 : : ! Rearrange items in _ord arrays.
603 [ - + + - : 24 : ABI_MALLOC(kpts_ord, (3, nkpt))
+ - + - -
+ - + ]
604 [ - + + - : 24 : ABI_MALLOC(kmap_ord, (6, nkpt))
+ - + - -
+ + - ]
605 [ + + ]: 2565 : do ikpt=1,nkpt
606 [ + + ]: 10228 : kpts_ord(:, ikpt) = kpts(:, iperm(ikpt))
607 [ + + ]: 17907 : kmap_ord(:, ikpt) = kmap(:, iperm(ikpt))
608 : : end do
609 : :
610 : : ! We want each star group to start with the point in the IBZ so an extra shuffle is needed.
611 : : ! star_pos stores the beginning of the star group and the position of the base k0 for each star.
612 [ + + ]: 2565 : nkibz = maxval(kmap(1,:))
613 [ - + + - : 423 : ABI_ICALLOC(star_pos, (2, nkibz))
+ - + - -
+ - + + +
+ + ]
614 : :
615 : : seen_ibz = -1
616 [ + + ]: 2565 : do ikpt=1,nkpt
617 : 2557 : ik_ibz = kmap_ord(1, ikpt); isym_k = kmap_ord(2, ikpt)
618 [ + + ]: 10228 : trev_k = kmap_ord(6, ikpt); g0_k = kmap_ord(3:5, ikpt)
619 [ + + + + : 8601 : isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
+ + - + ]
620 : 2557 : tsign = 1; if (trev_k == 1) tsign = -1
621 [ + + ]: 2557 : if (ik_ibz /= seen_ibz) then
622 : 133 : star_pos(1, ik_ibz) = ikpt
623 : 133 : seen_ibz = ik_ibz
624 : : end if
625 [ + + ]: 2565 : if (isirr_k) star_pos(2, ik_ibz) = ikpt
626 : : end do
627 : :
628 : : ! Now put ik0 in the ik_start slot if needed.
629 [ + + ]: 141 : do ik_ibz=1, nkibz
630 : 133 : ik_start = star_pos(1, ik_ibz)
631 : 133 : ik0 = star_pos(2, ik_ibz)
632 [ + + ]: 133 : if (ik_start == ik0) cycle
633 : :
634 [ + + ]: 408 : swap_kpt = kpts_ord(:, ik_start)
635 [ + + ]: 714 : swap_kmap = kmap_ord(:, ik_start)
636 : :
637 [ + + ]: 408 : kpts_ord(:, ik_start) = kpts_ord(:, ik0)
638 [ + + ]: 714 : kmap_ord(:, ik_start) = kmap_ord(:, ik0)
639 [ + + ]: 408 : kpts_ord(:, ik0) = swap_kpt
640 [ + + ]: 753 : kmap_ord(:, ik0) = swap_kmap
641 : : end do
642 : :
643 [ + + + + ]: 10236 : kpts = kpts_ord
644 [ + + + + ]: 17907 : kmap = kmap_ord
645 : :
646 [ - + ]: 8 : ABI_FREE(star_pos)
647 [ - + ]: 8 : ABI_FREE(iperm)
648 [ - + ]: 8 : ABI_FREE(kpts_ord)
649 [ - + ]: 8 : ABI_FREE(kmap_ord)
650 : :
651 : 8 : end subroutine kpts_pack_in_stars
652 : : !!***
653 : :
654 : : !!****f* m_kpts/kpts_map
655 : : !! NAME
656 : : !! kpts_map
657 : : !!
658 : : !! FUNCTION
659 : : !! Compute symmetry table.
660 : : !!
661 : : !! INPUTS
662 : : !!
663 : : !! OUTPUT
664 : : !!
665 : : !! SOURCE
666 : :
667 : 87045 : integer function kpts_map(mode, kptopt, cryst, krank, nkpt2, kpt2, map, &
668 : : qpt, dksqmax_tol) result(ierr) ! optional
669 : :
670 : : !Arguments ------------------------------------
671 : : !scalars
672 : : character(len=*),intent(in) :: mode
673 : : integer,intent(in) :: kptopt, nkpt2
674 : : class(crystal_t),intent(in) :: cryst
675 : : class(krank_t),intent(inout) :: krank
676 : : real(dp),optional,intent(in) :: dksqmax_tol
677 : : !arrays
678 : : real(dp),intent(in) :: kpt2(3, nkpt2)
679 : : real(dp),optional,intent(in) :: qpt(3)
680 : : integer,intent(out) :: map(6, nkpt2)
681 : :
682 : : !Local variables-------------------------------
683 : : !scalars
684 : : real(dp) :: dksqmax, my_tol
685 : : integer :: timrev, nsym
686 : : !arrays
687 : : real(dp) :: my_qpt(3)
688 : : ! *************************************************************************
689 : :
690 [ + + ]: 87045 : my_qpt = zero; if (present(qpt)) my_qpt = qpt
691 : 87045 : timrev = kpts_timrev_from_kptopt(kptopt)
692 : : ! if no spatial symm. set nsym to 1 to suppress the use of spatial symm.
693 : : ! the first symm. is always the identity
694 [ - + ]: 87045 : if (kptopt==2 .or. kptopt==3) then
695 : 0 : nsym = 1
696 : : else
697 : 87045 : nsym = cryst%nsym
698 : : end if
699 : :
700 : 86232 : select case (mode)
701 : : case ("symrel")
702 : : ! Note symrel and use_symrec = .False.
703 : : ! These are the conventions for the symmetrization of the wavefunctions used in cgtk_rotate.
704 : : call krank%get_mapping(nkpt2, kpt2, dksqmax, cryst%gmet, map, &
705 : 86232 : nsym, cryst%symafm, cryst%symrel, timrev, use_symrec=.False., qpt=my_qpt)
706 : :
707 : : case ("symrec")
708 : : ! Note symrec and use_symrec = .True.
709 : : ! These are the conventions for the symmetrization of the DVDB as well as the conventions
710 : : ! used in several BZ routines.
711 : : ! In principle one should always use this convention but then the symmetrization of the
712 : : ! wavefunctions should be rewritten almost completely.
713 : :
714 : : call krank%get_mapping(nkpt2, kpt2, dksqmax, cryst%gmet, map, &
715 : 813 : nsym, cryst%symafm, cryst%symrec, timrev, use_symrec=.True., qpt=my_qpt)
716 : :
717 : : case default
718 [ + + - ]: 87045 : ABI_ERROR(sjoin("Invalid mode:", mode))
719 : : end select
720 : :
721 [ - + ]: 87045 : my_tol = tol12; if (present(dksqmax_tol)) my_tol = dksqmax_tol
722 : :
723 [ + + ]: 87045 : ierr = merge(1, 0, dksqmax > my_tol)
724 : : !if (ierr /= 0) call wrtout(std_out, sjoin(" CRITICAL WARNING: dksqmax ", ftoa(dksqmax), " > ", ftoa(my_tol)))
725 : :
726 : : #if 0
727 : : !if (present(pack_in_stars)) then
728 : : ! if (pack_in_stars)
729 : : ! call kpts_pack_in_stars(nkpt2, kpt2, kmap)
730 : : ! end if
731 : : !end if
732 : :
733 : :
734 : : kmap%nkpt = nkpt2
735 : : kmap%kptopt = kptopt
736 : : kmap%ierr = ierr
737 : : kmap%dksqmax = dksqmax
738 : : kmap%mode = trim(mode)
739 : : kmap%qpt = qpt
740 : : ABI_MALLOC(kmap%inds, (nkpt2))
741 : : do ii=1,nkpt2
742 : : kmap(ii)%ibz_idx = indkk_kq(1, ii)
743 : : kmap(ii)%isym = indkk_kq(2, ii)
744 : : kmap(ii)%trev = indkk_kq(6, ii)
745 : : kmap(ii)%g0 = indkk_kq(3:5, ii)
746 : : kmap(ii)%is_irred = (kmap(ii)%isym == 1 .and. kmap(ii)%trev == 0 .and. all(kmap%g0 == 0))
747 : : end do
748 : :
749 : : !ABI_FREE(kmap%inds)
750 : : #endif
751 : :
752 : 87045 : end function kpts_map
753 : : !!***
754 : :
755 : : !!****f* m_kpts/kpts_map_print
756 : : !! NAME
757 : : !! kpts_map_print
758 : : !!
759 : : !! FUNCTION
760 : : !! Print the symmetry table bz2ibz associated to the BZ bz and the IBZ ibz
761 : : !! to a list of units with header. Mode corresponds to the value passed to kpts_map
762 : : !! If prtvol is 0, max 20 entries are printed. Use prtvol > 0 to print all k-points.
763 : : !!
764 : : !! SOURCE
765 : :
766 [ # # # # : 0 : subroutine kpts_map_print(units, header, mode, bz, ibz, bz2ibz, prtvol)
# # # # ]
767 : :
768 : : !Arguments ------------------------------------
769 : : !scalars
770 : : character(len=*),intent(in) :: header, mode
771 : : integer,intent(in) :: prtvol, units(:), bz2ibz(:,:)
772 : : real(dp),intent(in) :: bz(:,:), ibz(:,:)
773 : :
774 : : !Local variables-------------------------------
775 : : !scalars
776 : : integer :: ik_ibz, ik_bz, isym_k, trev_k, g0_k(3)
777 : : logical :: isirr_k
778 : : character(len=5000) :: msg
779 : : ! *************************************************************************
780 : :
781 [ # # ]: 0 : call wrtout(units, " "//trim(header))
782 : 0 : select case (mode)
783 : : case ("symrec")
784 : : call wrtout(units, &
785 : 0 : " Legend: bz = TS(ibz) + g0 where isym is the index of the symrec operation S and itim is 1 if TR is used.")
786 : : case ("symrel")
787 : : call wrtout(units, &
788 : 0 : " Legend: bz = TS^t(ibz) + g0 where isym is the index of the symrel operation S and itim is 1 if TR is used.")
789 : : case default
790 [ # # # ]: 0 : ABI_ERROR(sjoin("Invalid mode:", mode))
791 : : end select
792 : :
793 : : ! yes, I'm a barbarian but Fortran string formatting is a pain.
794 : 0 : msg = " BZ IBZ ibz isym itim g0"
795 : 0 : call wrtout(units, msg)
796 : :
797 [ # # ]: 0 : do ik_bz=1,size(bz2ibz, dim=2)
798 [ # # # # ]: 0 : if (prtvol == 0 .and. ik_bz > 20) then
799 : 0 : call wrtout(units, "prtvol = 0, max 20 points are written"); exit
800 : : end if
801 : 0 : ik_ibz = bz2ibz(1, ik_bz); isym_k = bz2ibz(2, ik_bz)
802 [ # # ]: 0 : trev_k = bz2ibz(6, ik_bz); g0_k = bz2ibz(3:5, ik_bz)
803 : : isirr_k = (isym_k == 1 .and. trev_k == 0 .and. all(g0_k == 0))
804 : : write(msg, '(i6, 2x, 2(a,2x), 3(i4,2x), a)' ) &
805 [ # # # # : 0 : ik_bz, trim(ktoa(bz(:, ik_bz))), trim(ktoa(ibz(:,ik_ibz))), ik_ibz, isym_k, trev_k, trim(ltoa(g0_k))
# # # # #
# # # # #
# # # # #
# # # ]
806 : 0 : call wrtout(units, msg)
807 : : end do
808 : :
809 : 0 : call wrtout(units, ch10)
810 : :
811 : 0 : end subroutine kpts_map_print
812 : : !!***
813 : :
814 : : !!****f* m_kpts/listkk
815 : : !! NAME
816 : : !! listkk
817 : : !!
818 : : !! FUNCTION
819 : : !! Given a list of nkpt1 initial k points kptns1 and a list of nkpt2
820 : : !! final k points kptns2, associates each final kpt with a "closest"
821 : : !! initial k point (or symmetric thereof, also taking possible umklapp)
822 : : !! as determined by a metric gmet, that commutes with the symmetry operations.
823 : : !! The algorithm does not scale as nkpt1 times nkpt2, thanks
824 : : !! to the ordering of the kptns1 and kptns2 vectors according to their
825 : : !! lengths, and comparison first between vectors of similar lengths.
826 : : !! Returns indirect indexing list indkk.
827 : : !!
828 : : !! INPUTS
829 : : !! gmet(3,3)=reciprocal space metric (bohr^-2)
830 : : !! kptns1(3,nkpt1)=list of initial k points (reduced coordinates)
831 : : !! kptns2(3,nkpt2)=list of final k points
832 : : !! nkpt1=number of initial k points
833 : : !! nkpt2=number of final k points
834 : : !! nsym=number of symmetry elements in space group
835 : : !! sppoldbl=if 1, no spin-polarisation doubling
836 : : !! if 2, spin-polarisation doubling using symafm
837 : : !! symafm(nsym)=(anti)ferromagnetic part of symmetry operations
838 : : !! symmat(3,3,nsym)=symmetry operations (symrel or symrec, depending on value of use_symrec
839 : : !! timrev=1 if the use of time-reversal is allowed; 0 otherwise
840 : : !! comm=MPI communicator.
841 : : !! [use_symrec]: if present and true, symmat assumed to be symrec, otherwise assumed to be symrel (default)
842 : : !!
843 : : !! OUTPUT
844 : : !! dksqmax=maximal value of the norm**2 of the difference between
845 : : !! a kpt2 vector and the closest k-point found from the kptns1 set, using symmetries.
846 : : !! indkk(nkpt2*sppoldbl,6)=describe k point number of kpt1 that allows to
847 : : !! generate wavefunctions closest to given kpt2
848 : : !! if sppoldbl=2, use symafm to generate spin down wfs from spin up wfs
849 : : !!
850 : : !! indkk(:,1)=k point number of kptns1
851 : : !! indkk(:,2)=symmetry operation to be applied to kpt1, to give kpt1a
852 : : !! (if 0, means no symmetry operation, equivalent to identity )
853 : : !! indkk(:,3:5)=shift in reciprocal space to be given to kpt1a,
854 : : !! to give kpt1b, that is the closest to kpt2.
855 : : !! indkk(:,6)=1 if time-reversal was used to generate kpt1a from kpt1, 0 otherwise
856 : : !!
857 : : !! NOTES
858 : : !! The tolerances tol12 and tol8 aims at giving a machine-independent ordering.
859 : : !! (this trick is used in bonds.f, listkk.f, prtrhomxmn.f and rsiaf9.f)
860 : : !! The tolerance tol12 is used for each component of the k vectors,
861 : : !! and for the length of the vectors while the tolerance tol8 is used for
862 : : !! the comparison of the squared lengths of the separate vectors.
863 : : !!
864 : : !! SOURCE
865 : :
866 : 4756 : subroutine listkk(dksqmax, gmet, indkk, kptns1, kptns2, nkpt1, nkpt2, nsym, sppoldbl, symafm, symmat, timrev, comm, &
867 : : use_symrec) ! optional
868 : :
869 : : !Arguments ------------------------------------
870 : : !scalars
871 : : integer,intent(in) :: nkpt1,nkpt2,nsym,sppoldbl,timrev,comm
872 : : real(dp),intent(out) :: dksqmax
873 : : logical,optional,intent(in) :: use_symrec
874 : : !arrays
875 : : integer,intent(in) :: symafm(nsym),symmat(3,3,nsym)
876 : : integer,intent(out) :: indkk(nkpt2*sppoldbl,6)
877 : : real(dp),intent(in) :: gmet(3,3),kptns1(3,nkpt1),kptns2(3,nkpt2)
878 : :
879 : : !Local variables-------------------------------
880 : : !scalars
881 : : integer,parameter :: usesym=1, limit=1
882 : : integer :: nprocs, my_rank, ierr, isk_start, isk_stop
883 : : integer :: l3,ig1,ig2,ig3,ii,ikpg1,ikpt1,ikpt2,ikpt2_done, isk
884 : : integer :: ilarger,ismaller,itrial
885 : : integer :: isppol,isym,itimrev,jkpt1,jsym,jtime
886 : : integer :: nsym_used,timrev_used
887 : : real(dp) :: dksq,dksqmn,lk2,llarger,ldiff,lsmaller,ltrial,min_l
888 : : !real(dp) :: cpu,wall,gflops
889 : : character(len=500) :: msg
890 : : !arrays
891 : : integer :: dkint(3),jdkint(3),k1int(3),k2int(3)
892 : 4756 : integer, allocatable :: isort(:), tmp_indkk(:,:)
893 : : real(dp) :: tsec(2)
894 : : real(dp) :: dk(3),kpg1(3),kpt1a(3),k1(3),k2(3)
895 : : !real(dp) :: kasq,ka(3)
896 : 4756 : real(dp),allocatable :: lkpg1(:),lkpg1_sorted(:)
897 : : ! *************************************************************************
898 : :
899 : 4756 : call timab(1091, 1, tsec)
900 : : !call cwtime(cpu, wall, gflops, "start")
901 : :
902 : 4756 : my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
903 : :
904 [ - + ]: 4756 : if (sppoldbl<1 .or. sppoldbl>2) then
905 : 0 : write(msg, '(a,i0,a)' )'The value of sppoldbl is: ',sppoldbl,', but it should be either 1 or 2.'
906 : 0 : ABI_BUG(msg)
907 : : end if
908 : :
909 : : ! When usesym=0, the old way of converting the wavefunctions (without using the symmetries), is recovered.
910 : 4756 : nsym_used=nsym
911 : 4756 : timrev_used=timrev
912 : : if(usesym==0)nsym_used=1
913 : : if(usesym==0)timrev_used=0
914 : :
915 : : ! Precompute the length of the kpt1 vectors, also taking into account possible umklapp vectors
916 : 4756 : l3 = (2*limit+1)**3
917 [ - + + - : 2903322 : ABI_CALLOC(lkpg1, (l3*nkpt1))
+ - + - -
+ - + +
+ ]
918 [ - + + - : 2898566 : ABI_CALLOC(lkpg1_sorted, (l3*nkpt1))
- + - + +
+ ]
919 [ - + + - : 14268 : ABI_MALLOC(isort, (l3*nkpt1))
+ - + - -
+ - + ]
920 [ + + ]: 2893810 : isort = 0
921 : :
922 : 4756 : call xmpi_split_work(nkpt1, comm, isk_start, isk_stop)
923 : : !write(std_out,*)' List of kpt1 vectors'; write(std_out,*)' Length of the kpt1 vectors:'
924 : :
925 : : !$OMP PARALLEL DO PRIVATE(k1, k1int, kpg1, ikpg1)
926 [ + + ]: 110110 : do ikpt1=isk_start,isk_stop
927 [ + + ]: 421416 : k1(:) = kptns1(:,ikpt1) !; write(std_out,*)ikpt1,k1(:)
928 [ + + ]: 421416 : k1int(:) = nint(k1(:) + tol12)
929 [ + + ]: 421416 : k1(:) = k1(:) - k1int(:)
930 [ + + ]: 426172 : do ig3=-limit,limit
931 : 316062 : kpg1(3) = k1(3) + ig3
932 [ + + ]: 1369602 : do ig2=-limit,limit
933 : 948186 : kpg1(2) = k1(2) + ig2
934 [ + + ]: 4108806 : do ig1=-limit,limit
935 : 2844558 : kpg1(1) = k1(1) + ig1
936 : :
937 : 2844558 : ikpg1 = ig1 + limit + 1 + (2*limit+1)*(ig2+limit) + (2*limit+1)**2*(ig3+limit) + l3*(ikpt1-1)
938 : : ! Compute the norm of the vector (also taking into account possible umklapp)
939 : : lkpg1(ikpg1) = sqrt(gmet(1,1)*kpg1(1)**2+gmet(2,2)*kpg1(2)**2 + &
940 : : gmet(3,3)*kpg1(3)**2+two*(gmet(2,1)*kpg1(2)*kpg1(1) + &
941 : 2844558 : gmet(3,2)*kpg1(3)*kpg1(2)+gmet(3,1)*kpg1(3)*kpg1(1)))
942 : 2844558 : lkpg1_sorted(ikpg1) = lkpg1(ikpg1)
943 : 3792744 : isort(ikpg1) = ikpg1
944 : : !write(std_out,*)' ikpt1,ig1,ig2,ig3,lkpg1=',ikpt1,ig1,ig2,ig3,lkpg1(ikpg1)
945 : : end do
946 : : end do
947 : : end do
948 : : end do
949 : :
950 [ + + ]: 4756 : if (nprocs > 1) then
951 : 84 : call xmpi_sum(lkpg1_sorted, comm, ierr)
952 : 84 : call xmpi_sum(lkpg1, comm, ierr)
953 : 84 : call xmpi_sum(isort, comm, ierr)
954 : : end if
955 : : !call cwtime_report(" listkk_loop1", cpu, wall, gflops)
956 : :
957 : 4756 : call sort_dp(l3*nkpt1, lkpg1_sorted, isort, tol12)
958 : : ! From "precompute" to "sort_dp" represents more than 50% of the overall wall time for large meshes.
959 : : !call cwtime_report(" listkk_sort", cpu, wall, gflops)
960 : :
961 : : !write(std_out,*)' listkk : output list of kpt1 for checking purposes '
962 : : !write(std_out,*)' ii,ikpt1,isort(ii)-l3*(ikpt1-1),lkpg1_sorted(ii),lkpg1(isort(ii)) '
963 : : !do ii=1,l3*nkpt1
964 : : ! ikpt1=(isort(ii)-1)/l3+1
965 : : ! write(std_out,*)ii,ikpt1,isort(ii)-l3*(ikpt1-1),lkpg1_sorted(ii),lkpg1(isort(ii))
966 : : !enddo
967 : :
968 : 4756 : dksqmax = zero
969 [ + + + + ]: 2059768 : indkk = 0
970 : : ! TODO: Should change API to use this shape.
971 : : ! workspace array for improved memory access.
972 [ - + + - : 14268 : ABI_MALLOC(tmp_indkk, (6, nkpt2*sppoldbl))
+ - + - -
+ - + ]
973 [ + + + + ]: 2368978 : tmp_indkk = 0
974 : :
975 : : ! Split loop in contiguous blocks
976 : 4756 : call xmpi_split_work(sppoldbl * nkpt2, comm, isk_start, isk_stop)
977 : :
978 [ + + ]: 9512 : do isppol=1,sppoldbl
979 [ + + ]: 347258 : do ikpt2=1,nkpt2
980 : 337746 : isk = ikpt2 + (isppol-1)*nkpt2
981 [ + + + + ]: 337746 : if (isk < isk_start .or. isk > isk_stop) cycle
982 : :
983 : 319474 : ikpt2_done=0
984 : : ! Precompute the length of the kpt2 vector, with the Umklapp vector such that it is the closest to the Gamma point
985 [ + + ]: 1277896 : k2(:)=kptns2(:,ikpt2)
986 [ + + ]: 1277896 : k2int(:)=nint(k2(:)+tol12)
987 [ + + ]: 1277896 : k2(:)=k2(:)-k2int(:)
988 : : lk2=sqrt(gmet(1,1)*k2(1)**2+gmet(2,2)*k2(2)**2+&
989 : : gmet(3,3)*k2(3)**2+two*(gmet(2,1)*k2(2)*k2(1)+&
990 : 319474 : gmet(3,2)*k2(3)*k2(2)+gmet(3,1)*k2(3)*k2(1)))
991 : : ! write(std_out, '(a,i4,7es16.6)' )' listkk : ikpt2,kptns2(:,ikpt2),k2(:),lk2=',ikpt2,kptns2(:,ikpt2),k2(:),lk2
992 : :
993 : : ! Find the kpt1 vector whose length is the most similar to the length of lk2 up to a tolerance.
994 : : ! Use a bisection algorithm.
995 : 319474 : ismaller=0; lsmaller=zero
996 : 319474 : ilarger=l3*nkpt1+1; llarger=huge(one)
997 : :
998 : : ! This loop should never reach l3*nkpt1, since this is a bisection algorithm
999 [ + - ]: 2677419 : do ii=1,l3*nkpt1
1000 [ + + - + ]: 2677419 : if((ilarger-ismaller)<2 .or. (llarger-lsmaller)<2*tol12)exit
1001 : 2357945 : itrial=(ilarger+ismaller)/2 ; ltrial=lkpg1_sorted(itrial)
1002 [ + + ]: 2677419 : if((ltrial-lk2)>tol12)then
1003 : : ilarger=itrial ; llarger=ltrial
1004 [ + + ]: 673032 : else if((ltrial-lk2)<-tol12)then
1005 : : ismaller=itrial ; lsmaller=ltrial
1006 : : else
1007 : 316852 : ismaller=itrial ; lsmaller=ltrial
1008 : 316852 : ilarger=itrial ; llarger=ltrial
1009 : : end if
1010 : : end do
1011 : 319474 : itrial=ismaller
1012 [ + + ]: 319474 : if(abs(llarger-lk2)<abs(lsmaller-lk2)-tol12)itrial=ilarger
1013 [ + + ]: 319474 : if(itrial==0)itrial=ilarger
1014 : 319474 : ismaller=itrial ; ilarger=itrial
1015 : : !write(std_out,*)' listkk : starting search at itrial=',itrial
1016 : :
1017 : 319474 : dksqmn=huge(one)
1018 : :
1019 : : ! The ii index is dummy. This avoids an infinite loop.
1020 [ + + ]: 1775885 : do ii=1,l3*nkpt1
1021 : : ! If the difference in length between the trial vector and the target vector is bigger
1022 : : ! than the already achieved distance, the search is finished ...
1023 : 1775884 : ldiff = abs(lkpg1_sorted(itrial) - lk2)
1024 : : ! write(std_out,*)' listkk : ii,itrial,lkpg1_sorted(itrial),lk2,ldiff,&
1025 : : ! dksqmn=',ii,itrial,lkpg1_sorted(itrial),lk2,ldiff,dksqmn
1026 : :
1027 [ + + ]: 1775884 : if (ldiff**2 > dksqmn+tol8) exit
1028 : :
1029 : : ! If this k-point has already been examined in a previous batch, skip it
1030 : : ! First, compute the minimum of the difference of length of the sets of
1031 : : ! associated vectors thanks to Umklapp vectors with the target vector
1032 : 1550489 : ikpt1 = (isort(itrial)-1) /l3 + 1
1033 [ + - - + : 44964181 : min_l = minval(abs(lkpg1((ikpt1-1)*l3+1:(ikpt1-1)*l3+l3)-lk2))
- - + + ]
1034 : :
1035 : : ! Then compare with the current ldiff
1036 : : ! write(std_out,*)' listkk : ikpt1,min_l,ldiff=',ikpt1,min_l,ldiff
1037 [ + + ]: 1550489 : if (min_l > ldiff-tol12) then
1038 : :
1039 : : ! Now, will examine the trial vector, and the symmetric ones
1040 : : ! MG FIXME: Here there's a possible problem with the order of symmetries because
1041 : : ! in symkpt, time-reversal is the innermost loop. This can create inconsistencies in the symmetry tables.
1042 : : ! Besides, one should use symrel^{-1 T} to keep the correspondence between isym -> R or S
1043 [ + + ]: 4024320 : do itimrev=0,timrev_used
1044 [ + + ]: 65612918 : do isym=1,nsym_used
1045 : :
1046 : : ! Select magnetic characteristic of symmetries
1047 [ + - + + ]: 63075624 : if (isppol == 1 .and. symafm(isym) == -1) cycle
1048 [ - + - - ]: 63057224 : if (isppol == 2 .and. symafm(isym) == 1) cycle
1049 : :
1050 : : ! Compute symmetric point to kpt1
1051 : : if (usesym==1) then
1052 : : ! original code only used transpose(symrel)
1053 [ + + ]: 63057224 : if (present(use_symrec)) then
1054 [ + + ]: 60085787 : if (use_symrec) then
1055 [ + + + + : 82845425 : kpt1a(:) = MATMUL(symmat(:,:,isym),kptns1(:,ikpt1))
+ + + + ]
1056 : : else
1057 [ + + + + : 1419299250 : kpt1a(:) = MATMUL(TRANSPOSE(symmat(:,:,isym)),kptns1(:,ikpt1))
+ + + + ]
1058 : : end if
1059 : : else
1060 [ + + + + : 74285925 : kpt1a(:) = MATMUL(TRANSPOSE(symmat(:,:,isym)),kptns1(:,ikpt1))
+ + + + ]
1061 : : end if
1062 [ + + ]: 252228896 : kpt1a(:)=(1-2*itimrev)*kpt1a(:)
1063 : : else
1064 : : kpt1a(:)=kptns1(:,ikpt1)
1065 : : end if
1066 : :
1067 : : ! Compute difference with respect to kpt2, modulo a lattice vector
1068 [ + + ]: 252228896 : dk(:)=kptns2(:,ikpt2)-kpt1a(:)
1069 : : if (usesym==1) then
1070 : : ! The tolerance insure similar behaviour on different platforms
1071 : : ! XG120418: Actually, *assumes* that the closest point will have reduced
1072 : : ! coordinates differing by less than 1/2. There might be elongated cells where this is not correct ...
1073 [ + + ]: 252228896 : dkint(:)=nint(dk(:)+tol12)
1074 [ + + ]: 252228896 : dk(:)=dk(:)-dkint(:)
1075 : : else
1076 : : dkint(:)=0
1077 : : end if
1078 : :
1079 : : ! Compute norm of the difference vector, and update kpt1 if better.
1080 : : dksq=gmet(1,1)*dk(1)**2+gmet(2,2)*dk(2)**2+ &
1081 : : gmet(3,3)*dk(3)**2+two*(gmet(2,1)*dk(2)*dk(1)+ &
1082 : 63057224 : gmet(3,2)*dk(3)*dk(2)+gmet(3,1)*dk(3)*dk(1))
1083 : :
1084 [ + + ]: 63057224 : if (dksq < dksqmn+tol8) then
1085 : : ! If exactly the right point (without using symmetries neither umklapp vector), will exit the search
1086 : : ! Note that in this condition, each coordinate is tested separately, without squaring.
1087 : : ! So, it is a much stronger condition than dksqmn < tol12
1088 [ + + + + ]: 15208312 : if (sum(abs(kptns2(:,ikpt2)-kptns1(:,ikpt1)))<3*tol12) ikpt2_done = 1
1089 : :
1090 : : ! Update in three cases: either if succeeded to have exactly the vector, or the distance is better,
1091 : : ! or the distance is only slightly worsened so select the lowest itimrev, isym or ikpt1,
1092 : : ! in order to respect previous ordering
1093 : : if (ikpt2_done==1 .or. &
1094 [ + - + + : 3708000 : dksq+tol12<dksqmn .or. &
+ - + + +
+ + + +
+ ]
1095 : : ( abs(dksq-dksqmn)<tol12 .and. &
1096 : : ((itimrev<jtime) .or. &
1097 : : (itimrev==jtime .and. isym<jsym) .or. &
1098 : : (itimrev==jtime .and. isym==jsym .and. ikpt1<jkpt1))))then
1099 : :
1100 : 1342813 : dksqmn = dksq
1101 : 1342813 : jkpt1 = ikpt1
1102 : 1342813 : jsym = isym
1103 : 1342813 : jtime = itimrev
1104 : 1342813 : jdkint(:) = dkint(:)
1105 : :
1106 : : !if (ikpt2_done == 1) then
1107 : : ! write(std_out,*)'Succeeded to lower dskmn,ikpt2_done=',dksqmn,ikpt2_done
1108 : : ! write(std_out,*)' ikpt1,ikpt2=',ikpt1, ikpt2
1109 : : ! write(std_out,*)' ikpt1,isym,dkint(:),itimrev=',ikpt1,isym,dkint(:),itimrev
1110 : : ! ka(:) = kpt1a(:) + dkint(:)
1111 : : ! kasq=gmet(1,1)*ka(1)**2+gmet(2,2)*ka(2)**2+&
1112 : : ! gmet(3,3)*ka(3)**2+two*(gmet(2,1)*ka(2)*ka(1)+&
1113 : : ! gmet(3,2)*ka(3)*ka(2)+gmet(3,1)*ka(3)*ka(1))
1114 : : ! write(std_out,*)' k1 = ',kpt1a(:)
1115 : : ! write(std_out,*)' dkint = ',dkint(:)
1116 : : ! write(std_out,*)' Actual k1 = ',ka(:)
1117 : : ! write(std_out,*)' k2 = ',kptns2(:,ikpt2)
1118 : : ! write(std_out,*)' Actual k1sq = ',kasq
1119 : : !end if
1120 : : end if
1121 : : end if
1122 : :
1123 [ + + ]: 65594518 : if (ikpt2_done==1) exit
1124 : : end do ! isym
1125 [ + + ]: 4024320 : if (ikpt2_done==1) exit
1126 : : end do ! itimrev
1127 [ + + ]: 1487026 : if (ikpt2_done==1) exit
1128 : : end if
1129 : :
1130 : : ! Update the interval that has been explored
1131 : 1456411 : if (itrial < ismaller) ismaller = itrial
1132 : 1456411 : if (itrial > ilarger) ilarger = itrial
1133 : :
1134 : : ! Select the next index to be tried (preferably the smaller indices, but this is a bit arbitrary).
1135 : : ! write(std_out,*)' before choosing the next index :'
1136 : : ! write(std_out,*)' ismaller,itrial,ilarger=',ismaller,itrial,ilarger
1137 : : ! write(std_out,*)' lkpg1_sorted(ismaller-1),lk2,lkpg1_sorted(ilarger+1)=',&
1138 : : ! lkpg1_sorted(ismaller-1),lk2,lkpg1_sorted(ilarger+1)
1139 : :
1140 [ + + + - ]: 1456411 : if (ismaller>1 .and. ilarger<l3*nkpt1) then
1141 [ + + ]: 1446557 : if (abs(lkpg1_sorted(ismaller-1)-lk2) < abs(lkpg1_sorted(ilarger+1)-lk2)+tol12) then
1142 : : itrial = ismaller-1
1143 : : else
1144 : 760427 : itrial = ilarger+1
1145 : : end if
1146 : : end if
1147 [ + + + + ]: 1456411 : if (ismaller==1 .and. ilarger<l3*nkpt1) itrial = ilarger+1
1148 [ + + - + ]: 1775885 : if (ismaller>1 .and. ilarger==l3*nkpt1) itrial = ismaller-1
1149 : : !if(ismaller==1 .and. ilarger==l3*nkpt1), we are done with the loop !
1150 : : end do ! ikpt1
1151 : :
1152 : : ! Store indices (lots of cache miss here)
1153 : : !indkk(isk, 1) = jkpt1
1154 : : !indkk(isk, 2) = jsym
1155 : : !indkk(isk, 3:5) = jdkint(:)
1156 : : !indkk(isk, 6) = jtime
1157 : :
1158 : 319474 : tmp_indkk(1, isk) = jkpt1
1159 : 319474 : tmp_indkk(2, isk) = jsym
1160 [ + + ]: 1277896 : tmp_indkk(3:5, isk) = jdkint(:)
1161 : 319474 : tmp_indkk(6, isk) = jtime
1162 : :
1163 : 319474 : dksqmax = max(dksqmax, dksqmn)
1164 : :
1165 [ + - ]: 324230 : if (dksqmn < -tol12) then
1166 : 0 : write(msg, '(a,es16.6)' )'The minimum square of dk has negative norm: dksqmn= ',dksqmn
1167 : 0 : ABI_BUG(msg)
1168 : : end if
1169 : :
1170 : : ! DEBUG SECTION
1171 : : !if (dksqmn > tol5) then
1172 : : ! if (present(use_symrec)) then
1173 : : ! if (use_symrec) then
1174 : : ! kpt1a(:) = MATMUL(symmat(:,:,jsym),kptns1(:,jkpt1))
1175 : : ! else
1176 : : ! kpt1a(:) = MATMUL(TRANSPOSE(symmat(:,:,jsym)),kptns1(:,jkpt1))
1177 : : ! end if
1178 : : ! else
1179 : : ! kpt1a(:) = MATMUL(TRANSPOSE(symmat(:,:,jsym)),kptns1(:,jkpt1))
1180 : : ! end if
1181 : : ! kpt1a(:)=(1-2*jtime)*kpt1a(:)
1182 : : ! print *, "Cannot find k2: ", k2(:)
1183 : : ! print *, "Rotated TS(k1): ", kpt1a(:)
1184 : : ! print *, "with k1: ", kptns1(:, jkpt1)
1185 : : ! print *, "dksqmn: ", dksqmn
1186 : : !end if
1187 : : !END DEBUG
1188 : :
1189 : : !write(std_out,'(a,i6,i2,2x,i6,5i3,es24.14)' )' listkk: ikpt2,isppol,indkk(isk,:)=',ikpt2,isppol,indkk(isk,:),dksqmn
1190 : : end do ! ikpt2
1191 : : end do ! isppol
1192 : :
1193 [ - + ]: 4756 : ABI_FREE(isort)
1194 [ - + ]: 4756 : ABI_FREE(lkpg1)
1195 [ - + ]: 4756 : ABI_FREE(lkpg1_sorted)
1196 : :
1197 [ + + + + ]: 2059768 : indkk = transpose(tmp_indkk)
1198 [ - + ]: 4756 : ABI_FREE(tmp_indkk)
1199 [ + + ]: 4756 : if (nprocs > 1) then
1200 : 84 : call xmpi_sum(indkk, comm, ierr)
1201 : 84 : dksqmn = dksqmax
1202 : 84 : call xmpi_max(dksqmn, dksqmax, comm, ierr)
1203 : : end if
1204 : :
1205 : 4756 : call timab(1091, 2, tsec)
1206 : : !call cwtime_report(" listkk_end", cpu, wall, gflops)
1207 : :
1208 : 4756 : end subroutine listkk
1209 : : !!***
1210 : :
1211 : : !!****f* m_kpts/getkgrid
1212 : : !! NAME
1213 : : !! getkgrid
1214 : : !!
1215 : : !! FUNCTION
1216 : : !! Compute the grid of k points in the irreducible Brillouin zone.
1217 : : !! Note that nkpt (and nkpthf) can be computed by calling this routine with nkpt=0, provided that kptopt/=0.
1218 : : !! If downsampling is present, also compute a downsampled k grid.
1219 : : !!
1220 : : !! INPUTS
1221 : : !! chksymbreak= if 1, will check whether the k point grid is symmetric (for kptopt=1,2 and 4), and stop if not.
1222 : : !! iout=unit number for echoed output . 0 if no output is wished.
1223 : : !! iscf= ( <= 0 =>non-SCF), >0 => SCF) MG: FIXME I don't understand why we have to pass the value iscf.
1224 : : !! kptopt=option for the generation of k points. defines whether spatial symmetries and/or time-reversal can be used)
1225 : : !! msym=default maximal number of symmetries
1226 : : !! nsym=number of symmetries
1227 : : !! rprimd(3,3)=dimensional real space primitive translations (bohr)
1228 : : !! symafm(nsym)=(anti)ferromagnetic part of symmetry operations
1229 : : !! symrel(3,3,nsym)=symmetry operations in real space in terms of primitive translations
1230 : : !! vacuum(3)=for each direction, 0 if no vacuum, 1 if vacuum
1231 : : !! [downsampling(3) = input variable that governs the downsampling]
1232 : : !!
1233 : : !! OUTPUT
1234 : : !! kptrlen=length of the smallest real space supercell vector associated with the lattice of k points.
1235 : : !! nkpt_computed=number of k-points in the IBZ computed in the present routine
1236 : : !! If nkpt/=0 the following are also output:
1237 : : !! kpt(3,nkpt)=reduced coordinates of k points.
1238 : : !! wtk(nkpt)=weight assigned to each k point.
1239 : : !! [fullbz(3,nkpt_fullbz)]=k-points generated in the full Brillouin zone.
1240 : : !! In output: allocated array with the list of k-points in the BZ.
1241 : : !! [kpthf(3,nkpthf)]=k-points generated in the full Brillouin zone, possibly downsampled (for Fock).
1242 : : !!
1243 : : !! NOTES
1244 : : !! msym not needed since nsym is the last index.
1245 : : !!
1246 : : !! SIDE EFFECTS
1247 : : !! Input/Output
1248 : : !! nkpt=number of k points (might be zero, see output description)
1249 : : !! kptrlatt(3,3)=k-point lattice specification
1250 : : !! nshiftk=actual number of k-point shifts in shiftk
1251 : : !! shiftk(3,MAX_NSHIFTK)=shift vectors for k point generation
1252 : : !! [nkpthf] = number of k points in the full BZ, for the Fock operator.
1253 : : !!
1254 : : !! SOURCE
1255 : :
1256 : 19850 : subroutine getkgrid(chksymbreak,iout,iscf,kpt,kptopt,kptrlatt,kptrlen,&
1257 : 19850 : & msym,nkpt,nkpt_computed,nshiftk,nsym,rprimd,shiftk,symafm,symrel,vacuum,wtk,&
1258 [ + + + - : 9925 : & fullbz,nkpthf,kpthf,downsampling) ! optional
- + ]
1259 : :
1260 : : !Arguments ------------------------------------
1261 : : !scalars
1262 : : integer,intent(in) :: chksymbreak,iout,iscf,kptopt,msym,nkpt,nsym
1263 : : integer,intent(inout),optional :: nkpthf
1264 : : integer,intent(inout) :: nshiftk
1265 : : integer,intent(inout) :: nkpt_computed !vz_i
1266 : : real(dp),intent(out) :: kptrlen
1267 : : !arrays
1268 : : integer,intent(in) :: symafm(msym),symrel(3,3,msym),vacuum(3)
1269 : : integer,optional,intent(in) :: downsampling(3)
1270 : : integer,intent(inout) :: kptrlatt(3,3)
1271 : 9925 : integer,allocatable :: indkpt(:)
1272 : 9925 : integer,allocatable :: bz2ibz_smap(:,:)
1273 : : real(dp),intent(in) :: rprimd(3,3)
1274 : : real(dp),intent(inout) :: shiftk(3,MAX_NSHIFTK)
1275 : : real(dp),intent(inout) :: kpt(3,nkpt) !vz_i
1276 : : real(dp),intent(inout) :: wtk(nkpt)
1277 : : real(dp),optional,allocatable,intent(out) :: fullbz(:,:)
1278 : : real(dp),optional,intent(out) :: kpthf(:,:)
1279 : :
1280 : : !Local variables-------------------------------
1281 : 9925 : real(dp),allocatable :: kpt_tmp(:,:), wtk_tmp(:)
1282 : :
1283 : : call getkgrid_low(chksymbreak,iout,iscf,kpt_tmp,kptopt,kptrlatt,kptrlen,&
1284 : : msym,nkpt,nkpt_computed,nshiftk,nsym,rprimd,shiftk,symafm,symrel,vacuum,wtk_tmp,indkpt,bz2ibz_smap,&
1285 [ + + + + : 12541 : fullbz,nkpthf,kpthf,downsampling)
- + ]
1286 : :
1287 [ + + ]: 9924 : if (nkpt > 0) then
1288 [ + + + + ]: 473280 : kpt(:,1:nkpt) = kpt_tmp(:,1:nkpt)
1289 [ + + ]: 121404 : wtk(1:nkpt) = wtk_tmp(1:nkpt)
1290 : : end if
1291 : :
1292 [ + - ]: 9924 : ABI_SFREE(kpt_tmp)
1293 [ + - ]: 9924 : ABI_SFREE(wtk_tmp)
1294 [ + + ]: 9924 : ABI_SFREE(indkpt)
1295 [ + - ]: 9924 : ABI_SFREE(bz2ibz_smap)
1296 : :
1297 [ - + - + : 9924 : end subroutine getkgrid
- + - + ]
1298 : : !!***
1299 : :
1300 : : !!****f* m_kpts/getkgrid_low
1301 : : !! NAME
1302 : : !! getkgrid_low
1303 : : !!
1304 : : !! FUNCTION
1305 : : !! Compute the grid of k points in the irreducible Brillouin zone.
1306 : : !! Note that nkpt (and nkpthf) can be computed by calling this routine with nkpt=0, provided that kptopt/=0.
1307 : : !! If downsampling is present, also compute a downsampled k grid.
1308 : : !!
1309 : : !! INPUTS
1310 : : !! chksymbreak= if 1, will check whether the k point grid is symmetric (for kptopt=1,2 and 4), and stop if not.
1311 : : !! iout=unit number for echoed output . 0 if no output is wished.
1312 : : !! iscf= ( <= 0 =>non-SCF), >0 => SCF) MG: FIXME I don't understand why we have to pass the value iscf.
1313 : : !! kptopt=option for the generation of k points (defines whether spatial symmetries and/or time-reversal can be used)
1314 : : !! msym=default maximal number of symmetries
1315 : : !! nsym=number of symmetries
1316 : : !! rprimd(3,3)=dimensional real space primitive translations (bohr)
1317 : : !! symafm(nsym)=(anti)ferromagnetic part of symmetry operations
1318 : : !! symrel(3,3,nsym)=symmetry operations in real space in terms of primitive translations
1319 : : !! vacuum(3)=for each direction, 0 if no vacuum, 1 if vacuum
1320 : : !! [downsampling(3) = input variable that governs the downsampling]
1321 : : !!
1322 : : !! OUTPUT
1323 : : !! kptrlen=length of the smallest real space supercell vector associated with the lattice of k points.
1324 : : !! nkpt_computed=number of k-points in the IBZ computed in the present routine
1325 : : !! If nkpt/=0 the following are also output:
1326 : : !! kpt(3,nkpt)=reduced coordinates of k points.
1327 : : !! wtk(nkpt)=weight assigned to each k point.
1328 : : !! bz2ibz_smap(nkbz, 6)= Mapping BZ --> IBZ.
1329 : : !! [fullbz(3,nkpt_fullbz)]=k-points generated in the full Brillouin zone.
1330 : : !! In output: allocated array with the list of k-points in the BZ.
1331 : : !! [kpthf(3,nkpthf)]=k-points generated in the full Brillouin zone, possibly downsampled (for Fock).
1332 : : !!
1333 : : !! NOTES
1334 : : !! msym not needed since nsym is the last index.
1335 : : !!
1336 : : !! SIDE EFFECTS
1337 : : !! Input/Output
1338 : : !! nkpt=number of k points (might be zero, see output description)
1339 : : !! kptrlatt(3,3)=k-point lattice specification
1340 : : !! nshiftk=actual number of k-point shifts in shiftk
1341 : : !! shiftk(3,MAX_NSHIFTK)=shift vectors for k point generation
1342 : : !! [nkpthf] = number of k points in the full BZ, for the Fock operator.
1343 : : !!
1344 : : !! SOURCE
1345 : :
1346 : 10460 : subroutine getkgrid_low(chksymbreak,iout,iscf,kpt,kptopt,kptrlatt,kptrlen,&
1347 : 10460 : & msym,nkpt,nkpt_computed,nshiftk,nsym,rprimd,shiftk,symafm,symrel,vacuum,wtk,indkpt,bz2ibz_smap,&
1348 [ + + + - : 10460 : & fullbz,nkpthf,kpthf,downsampling) ! optional
- + ]
1349 : :
1350 : : !Arguments ------------------------------------
1351 : : !scalars
1352 : : integer,intent(in) :: chksymbreak,iout,iscf,kptopt,msym,nkpt,nsym
1353 : : integer,intent(inout),optional :: nkpthf
1354 : : integer,intent(inout) :: nshiftk
1355 : : integer,intent(inout) :: nkpt_computed !vz_i
1356 : : real(dp),intent(out) :: kptrlen
1357 : : !arrays
1358 : : integer,intent(in) :: symafm(msym),symrel(3,3,msym),vacuum(3)
1359 : : integer,optional,intent(in) :: downsampling(3)
1360 : : integer,intent(inout) :: kptrlatt(3,3)
1361 : : real(dp),intent(in) :: rprimd(3,3)
1362 : : real(dp),intent(inout) :: shiftk(3,MAX_NSHIFTK)
1363 : : integer,allocatable,intent(out) :: indkpt(:)
1364 : : integer,allocatable,intent(out) :: bz2ibz_smap(:,:)
1365 : : real(dp),allocatable,intent(out) :: kpt(:,:) !vz_i
1366 : : real(dp),allocatable,intent(out) :: wtk(:)
1367 : : real(dp),optional,allocatable,intent(out) :: fullbz(:,:)
1368 : : real(dp),optional,intent(out) :: kpthf(:,:)
1369 : :
1370 : : !Local variables-------------------------------
1371 : : !scalars
1372 : : integer, parameter :: max_number_of_prime=47
1373 : : integer :: decreased,found,ii,ikpt,iprime,ishiftk,isym,jshiftk,kshiftk,mkpt,mult
1374 : : integer :: nkpthf_computed,nkpt_fullbz,nkptlatt,nshiftk2,nsym_used,option
1375 : : integer :: test_prime,timrev
1376 : : integer :: nkpt_use
1377 : : real(dp) :: length2,ucvol,ucvol_super
1378 : : character(len=500) :: msg
1379 : : !arrays
1380 : : integer, parameter :: prime_factor(max_number_of_prime)=(/2,3,5,7,9, 11,13,17,19,23,&
1381 : : & 29,31,37,41,43, 47,53,59,61,67,&
1382 : : & 71,73,79,83,89, 97,101,103,107,109,&
1383 : : & 113,127,131,137,139, 149,151,157,163,167,&
1384 : : & 173,179,181,191,193, 197,199/)
1385 : : integer :: kptrlatt2(3,3)
1386 : 10460 : integer,allocatable :: belong_chain(:),generator(:),number_in_chain(:)
1387 : 10460 : integer,allocatable :: repetition_factor(:),symrec(:,:,:)
1388 : : ! real(dp) :: cart(3,3)
1389 : : real(dp) :: dijk(3),delta_dmult(3),dmult(3),fact_vacuum(3),gmet(3,3)
1390 : : real(dp) :: gmet_super(3,3),gprimd(3,3),gprimd_super(3,3),klatt2(3,3)
1391 : : real(dp) :: klatt3(3,3),kptrlattr(3,3),ktransf(3,3),ktransf_invt(3,3)
1392 : : real(dp) :: metmin(3,3),minim(3,3),rmet(3,3),rmet_super(3,3),rprimd_super(3,3)
1393 : 10460 : real(dp),allocatable :: deltak(:,:),kpt_fullbz(:,:),shiftk2(:,:),shiftk3(:,:),spkpt(:,:),wtk_folded(:),wtk_fullbz(:)
1394 : : ! *************************************************************************
1395 : :
1396 : 10460 : call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
1397 : :
1398 : : !call cwtime(cpu, wall, gflops, "start")
1399 [ + + ]: 10460 : if (kptopt==1.or.kptopt==4) then
1400 : : ! Cannot use antiferromagnetic symmetry operations to decrease the number of k points
1401 : : !XG20191123: now, antiferromagnetic symmetry operations can be used to decrease the number of k points for kptopt==4
1402 : 7659 : nsym_used=0
1403 [ + + ]: 247394 : do isym=1,nsym
1404 [ + + + + ]: 247394 : if(symafm(isym)==1 .or. kptopt==4)nsym_used=nsym_used+1
1405 : : end do
1406 [ - + + - : 22977 : ABI_MALLOC(symrec,(3,3,nsym_used))
+ - + - -
+ - + ]
1407 : 7659 : nsym_used=0
1408 [ + + ]: 247394 : do isym=1,nsym ! Get the symmetry matrices in terms of reciprocal basis
1409 [ + + + + ]: 247394 : if(symafm(isym)==1 .or. kptopt==4)then
1410 : 238163 : nsym_used=nsym_used+1
1411 : 238163 : call mati3inv(symrel(:,:,isym),symrec(:,:,nsym_used))
1412 : : end if
1413 : : end do
1414 [ + + ]: 2801 : else if (kptopt==2) then
1415 : : !Use only the time-reversal
1416 : 756 : nsym_used=1
1417 [ - + ]: 756 : ABI_MALLOC(symrec,(3,3,1))
1418 [ + + + + ]: 9828 : symrec(1:3,1:3,1)=0
1419 [ + + ]: 3024 : do ii=1,3
1420 : 3024 : symrec(ii,ii,1)=1
1421 : : end do
1422 : : end if
1423 : :
1424 : 10460 : kptrlatt2(:,:)=kptrlatt(:,:)
1425 : 10460 : nshiftk2=nshiftk
1426 [ - + ]: 10460 : ABI_MALLOC(shiftk2,(3,MAX_NSHIFTK))
1427 [ - + ]: 10460 : ABI_MALLOC(shiftk3,(3,MAX_NSHIFTK))
1428 [ + + + + ]: 8796860 : shiftk2(:,:)=shiftk(:,:)
1429 : :
1430 : : !Find a primitive k point lattice, if possible, by decreasing the number of shifts.
1431 [ + + ]: 10460 : if(nshiftk2/=1)then
1432 : :
1433 : : do
1434 : : ! Loop to be repeated if there has been a successful reduction of nshiftk2
1435 [ - + + - : 16998 : ABI_MALLOC(deltak,(3,nshiftk2))
+ - + - -
+ - + ]
1436 [ - + + - : 16998 : ABI_MALLOC(repetition_factor,(nshiftk2))
+ - + - -
+ - + ]
1437 [ - + + - : 11332 : ABI_MALLOC(generator,(nshiftk2))
- + - + ]
1438 [ - + + - : 11332 : ABI_MALLOC(belong_chain,(nshiftk2))
- + - + ]
1439 [ - + + - : 11332 : ABI_MALLOC(number_in_chain,(nshiftk2))
- + - + ]
1440 : :
1441 : 5666 : decreased=0
1442 [ + + ]: 22606 : deltak(1,1:nshiftk2)=shiftk2(1,1:nshiftk2)-shiftk2(1,1)
1443 [ + + ]: 22606 : deltak(2,1:nshiftk2)=shiftk2(2,1:nshiftk2)-shiftk2(2,1)
1444 [ + + ]: 22606 : deltak(3,1:nshiftk2)=shiftk2(3,1:nshiftk2)-shiftk2(3,1)
1445 [ + + + + : 73426 : deltak(:,:)=deltak(:,:)-floor(deltak(:,:)+tol8)
+ + ]
1446 : :
1447 : : ! Identify for each shift, the smallest repetition prime factor that yields a reciprocal lattice vector.
1448 [ + + ]: 22606 : repetition_factor(:)=0
1449 : 5666 : repetition_factor(1)=1
1450 [ + + ]: 16940 : do ishiftk=2,nshiftk2
1451 [ + + ]: 19776 : do iprime=1,max_number_of_prime
1452 : 14050 : test_prime=prime_factor(iprime)
1453 [ + + ]: 56200 : dmult(:)=test_prime*deltak(:,ishiftk)
1454 [ + + + + ]: 56260 : if(sum(abs( dmult(:)-nint(dmult(:)) ))<tol8)then
1455 : 11214 : repetition_factor(ishiftk)=test_prime
1456 : 11214 : exit
1457 : : end if
1458 : : end do
1459 : : end do
1460 : :
1461 : : ! Initialize the selection of tentative generators
1462 [ + + ]: 22606 : generator(:)=1
1463 [ + + ]: 22606 : do ishiftk=1,nshiftk2
1464 [ + + ]: 22606 : if(repetition_factor(ishiftk)==0 .or. repetition_factor(ishiftk)==1)generator(ishiftk)=0
1465 : : end do
1466 : :
1467 : : ! Try different shifts as generators, by order of increasing repetition factor,
1468 : : ! provided they are equal or bigger than 2
1469 [ - + ]: 5668 : do iprime=1,max_number_of_prime
1470 [ + + ]: 5724 : do ishiftk=2,nshiftk2
1471 : : ! Note that ishiftk=1 is never a generator. It is the reference starting point.
1472 [ + + + + ]: 5722 : if(generator(ishiftk)==1 .and. repetition_factor(ishiftk)==prime_factor(iprime))then
1473 : : ! Test the generator : is it indeed closed ?
1474 [ + + ]: 5666 : if(prime_factor(iprime)/=2)then
1475 [ + + ]: 4 : do mult=2,prime_factor(iprime)-1
1476 [ + + ]: 8 : dmult(:)=mult*deltak(:,ishiftk)
1477 : 6 : found=0
1478 [ + - ]: 6 : do jshiftk=1,nshiftk2
1479 [ + + ]: 24 : delta_dmult(:)=deltak(:,jshiftk)-dmult(:)
1480 [ + + + + ]: 24 : if(sum(abs(delta_dmult(:)-nint(delta_dmult(:)) ))<tol8)then
1481 : : found=1
1482 : : exit
1483 : : end if
1484 : : end do
1485 [ + - ]: 4 : if(found==0)exit
1486 : : end do
1487 [ - + ]: 2 : if(found==0)generator(ishiftk)=0
1488 : : end if
1489 [ + - ]: 5666 : if(generator(ishiftk)==0)cycle
1490 : : else
1491 : : cycle
1492 : : end if
1493 : : ! Now, test whether all k points can be found in all possible chains
1494 [ + + ]: 22606 : belong_chain(:)=0
1495 [ + + ]: 22606 : do jshiftk=1,nshiftk2
1496 : : ! Initialize a chain starting from a k point not yet in a chain
1497 [ + + ]: 22606 : if(belong_chain(jshiftk)==0)then
1498 [ + + ]: 37149 : number_in_chain(:)=0 ! Not a member of the chain (yet)
1499 : 8469 : number_in_chain(jshiftk)=1 ! The first point in chain
1500 [ + + ]: 16940 : do mult=1,prime_factor(iprime)-1
1501 [ + + ]: 33884 : dmult(:)=mult*deltak(:,ishiftk)
1502 : 8471 : found=0
1503 [ + - ]: 8717 : do kshiftk=jshiftk+1,nshiftk2
1504 [ + + ]: 34868 : delta_dmult(:)=deltak(:,kshiftk)-deltak(:,jshiftk)-dmult(:)
1505 [ + + + + ]: 34868 : if(sum(abs(delta_dmult(:)-nint(delta_dmult(:)) ))<tol8)then
1506 : 8471 : found=1
1507 : 8471 : number_in_chain(kshiftk)=mult+1
1508 : : exit
1509 : : end if
1510 : : end do
1511 : 8469 : if(found==0)then
1512 : 0 : generator(ishiftk)=0
1513 : 0 : exit
1514 : : end if
1515 : : end do
1516 [ - + ]: 8469 : if(generator(ishiftk)==1)then
1517 : : ! Store the chain
1518 [ + + ]: 37149 : do kshiftk=1,nshiftk2
1519 [ + + ]: 37149 : if(number_in_chain(kshiftk)/=0)belong_chain(kshiftk)=number_in_chain(kshiftk)
1520 : : end do
1521 : : else
1522 : : exit
1523 : : end if
1524 : : end if
1525 : : end do
1526 : :
1527 [ + - ]: 5666 : if(generator(ishiftk)==0)cycle
1528 : :
1529 : : ! For the generator based on ishiftk, all the k points have been found to belong to one chain.
1530 : : ! All the initializing k points in the different chains have belong_chain(:)=1 .
1531 : : ! They must be kept, and the others thrown away.
1532 : 5666 : ktransf(:,:)=0.0_dp
1533 : 5666 : ktransf(1,1)=1.0_dp
1534 : 5666 : ktransf(2,2)=1.0_dp
1535 : 5666 : ktransf(3,3)=1.0_dp
1536 : : ! Replace one of the unit vectors by the shift vector deltak(:,ishiftk).
1537 : : ! However, must pay attention not to make linear combinations.
1538 : : ! Also, choose positive sign for first-non-zero value.
1539 [ + + ]: 5666 : if(abs(deltak(1,ishiftk)-nint(deltak(1,ishiftk)))>tol8)then
1540 [ + - + + ]: 11596 : if(deltak(1,ishiftk)>0)ktransf(:,1)= deltak(:,ishiftk)
1541 [ - + - - ]: 2899 : if(deltak(1,ishiftk)<0)ktransf(:,1)=-deltak(:,ishiftk)
1542 [ + - ]: 2767 : else if(abs(deltak(2,ishiftk)-nint(deltak(2,ishiftk)))>tol8)then
1543 [ + - + + ]: 11068 : if(deltak(2,ishiftk)>0)ktransf(:,2)= deltak(:,ishiftk)
1544 [ - + - - ]: 2767 : if(deltak(2,ishiftk)<0)ktransf(:,2)=-deltak(:,ishiftk)
1545 [ # # ]: 0 : else if(abs(deltak(3,ishiftk)-nint(deltak(3,ishiftk)))>tol8)then
1546 [ # # # # ]: 0 : if(deltak(3,ishiftk)>0)ktransf(:,3)= deltak(:,ishiftk)
1547 [ # # # # ]: 0 : if(deltak(3,ishiftk)<0)ktransf(:,3)=-deltak(:,ishiftk)
1548 : : end if
1549 : : ! Copy the integers to real(dp)
1550 [ + + + + ]: 73658 : kptrlattr(:,:)=kptrlatt2(:,:)
1551 : : ! Go to reciprocal space
1552 : 5666 : call matr3inv(kptrlattr,klatt2)
1553 : : ! Make the transformation
1554 [ + + ]: 22664 : do ii=1,3
1555 [ + + ]: 73658 : klatt3(:,ii)=ktransf(1,ii)*klatt2(:,1)+ktransf(2,ii)*klatt2(:,2)+ktransf(3,ii)*klatt2(:,3)
1556 : : end do
1557 : : ! Back to real space
1558 : 5666 : call matr3inv(klatt3,kptrlattr)
1559 : : ! real(dp) to integer
1560 [ + + + + ]: 73658 : kptrlatt2(:,:)=nint(kptrlattr(:,:))
1561 : : ! Prepare the transformation of the shifts
1562 : 5666 : call matr3inv(ktransf,ktransf_invt)
1563 : 5666 : decreased=1
1564 : 5666 : kshiftk=0
1565 [ + + ]: 22606 : do jshiftk=1,nshiftk2
1566 [ + + ]: 22606 : if(belong_chain(jshiftk)==1)then
1567 : 8469 : kshiftk=kshiftk+1
1568 : : ! Place the shift with index jshiftk in place of the one in kshiftk,
1569 : : ! also transform the shift from the old to the new coordinate system
1570 : : shiftk3(:,kshiftk)=ktransf_invt(1,:)*shiftk2(1,jshiftk)+&
1571 : : & ktransf_invt(2,:)*shiftk2(2,jshiftk)+&
1572 [ + + ]: 33876 : & ktransf_invt(3,:)*shiftk2(3,jshiftk)
1573 : : end if
1574 : : end do
1575 : 5666 : nshiftk2=nshiftk2/prime_factor(iprime)
1576 [ + + + + : 39542 : shiftk2(:,1:nshiftk2)=shiftk3(:,1:nshiftk2)-floor(shiftk3(:,1:nshiftk2)+tol8)
+ + ]
1577 [ - + ]: 5666 : if(kshiftk/=nshiftk2)then
1578 : 0 : ABI_BUG('The search for a primitive k point lattice contains a bug.')
1579 : : end if
1580 : :
1581 : : ! If this trial shift was successful, must exit the loop on trial ishiftk,
1582 : : ! and reinitialize the global loop
1583 : 2 : if(decreased==1)exit
1584 : : end do ! ishiftk
1585 : 0 : if(decreased==1)exit
1586 : : end do ! iprime
1587 : :
1588 [ - + ]: 5666 : ABI_FREE(belong_chain)
1589 [ - + ]: 5666 : ABI_FREE(deltak)
1590 [ - + ]: 5666 : ABI_FREE(number_in_chain)
1591 : 5666 : ABI_FREE(repetition_factor)
1592 [ - + ]: 5666 : ABI_FREE(generator)
1593 : :
1594 [ + + ]: 5666 : if(decreased==0 .or. nshiftk2==1)exit
1595 : :
1596 : : end do ! Infinite loop
1597 : :
1598 : : end if ! End nshiftk being 1 or larger
1599 : :
1600 : : !Impose shiftk coordinates to be in [0,1[
1601 [ + + ]: 20920 : do ishiftk=1,nshiftk2
1602 [ + + ]: 52300 : do ii=1,3
1603 [ + + ]: 31380 : if(shiftk2(ii,ishiftk)>one-tol8) shiftk2(ii,ishiftk)=shiftk2(ii,ishiftk)-1.0_dp
1604 [ + + ]: 41840 : if(shiftk2(ii,ishiftk)<-tol8) shiftk2(ii,ishiftk)=shiftk2(ii,ishiftk)+1.0_dp
1605 : : end do
1606 : : end do
1607 : :
1608 : : !Compute the number of k points in the G-space unit cell
1609 : : nkptlatt=kptrlatt2(1,1)*kptrlatt2(2,2)*kptrlatt2(3,3) &
1610 : : & +kptrlatt2(1,2)*kptrlatt2(2,3)*kptrlatt2(3,1) &
1611 : : & +kptrlatt2(1,3)*kptrlatt2(2,1)*kptrlatt2(3,2) &
1612 : : & -kptrlatt2(1,2)*kptrlatt2(2,1)*kptrlatt2(3,3) &
1613 : : & -kptrlatt2(1,3)*kptrlatt2(2,2)*kptrlatt2(3,1) &
1614 : 10460 : & -kptrlatt2(1,1)*kptrlatt2(2,3)*kptrlatt2(3,2)
1615 : :
1616 : : !Check whether the number of k points is positive, otherwise, change the handedness of kptrlatt2
1617 [ + + ]: 10460 : if(nkptlatt<=0)then
1618 : : ! write(std_out,*)' getkgrid : nkptlatt is negative !'
1619 [ + + ]: 100 : kptrlatt2(:,3)=-kptrlatt2(:,3)
1620 : 25 : nkptlatt=-nkptlatt
1621 [ + + ]: 50 : do ishiftk=1,nshiftk2
1622 : 50 : shiftk2(3,ishiftk)=-shiftk2(3,ishiftk)
1623 : : end do
1624 : : end if
1625 : :
1626 : : !Determine the smallest supercell R-vector whose contribution
1627 : : !is not taken correctly into account in the k point integration.
1628 : : !Increase enormously the size of the cell when vacuum is present.
1629 [ + + ]: 41840 : fact_vacuum(:)=1
1630 [ + + ]: 10460 : if(vacuum(1)==1)fact_vacuum(1)=1000.0_dp
1631 [ + + ]: 10460 : if(vacuum(2)==1)fact_vacuum(2)=1000.0_dp
1632 [ + + ]: 10460 : if(vacuum(3)==1)fact_vacuum(3)=1000.0_dp
1633 [ + + ]: 41840 : do ii=1,3
1634 : : rprimd_super(:,ii)=fact_vacuum(1)*rprimd(:,1)*kptrlatt2(1,ii)+&
1635 : : & fact_vacuum(2)*rprimd(:,2)*kptrlatt2(2,ii)+&
1636 [ + + ]: 135980 : & fact_vacuum(3)*rprimd(:,3)*kptrlatt2(3,ii)
1637 : : end do
1638 : :
1639 : 10460 : call metric(gmet_super,gprimd_super,-1,rmet_super,rprimd_super,ucvol_super)
1640 : 10460 : call smallprim(metmin,minim,rprimd_super)
1641 : 10460 : length2=min(metmin(1,1),metmin(2,2),metmin(3,3))
1642 : 10460 : kptrlen=sqrt(length2)
1643 : :
1644 : : !write(msg,'(a,es16.6)' )' getkgrid : length of smallest supercell vector (bohr)=',kptrlen
1645 : : !call wrtout(std_out,msg)
1646 : : ! If the number of shifts has been decreased, determine the set of kptrlatt2 vectors
1647 : : ! with minimal length (without using fact_vacuum)
1648 : : ! It is worth to determine the minimal set of vectors so that the kptrlatt that is output
1649 : : ! does not seem screwy, although correct but surprising.
1650 [ + + ]: 10460 : if(nshiftk/=nshiftk2)then
1651 [ + + ]: 11572 : do ii=1,3
1652 [ + + ]: 37609 : rprimd_super(:,ii)=rprimd(:,1)*kptrlatt2(1,ii)+rprimd(:,2)*kptrlatt2(2,ii)+rprimd(:,3)*kptrlatt2(3,ii)
1653 : : end do
1654 : 2893 : call metric(gmet_super,gprimd_super,-1,rmet_super,rprimd_super,ucvol_super)
1655 : : ! Shift vectors in cartesian coordinates (reciprocal space)
1656 [ + + ]: 5786 : do ishiftk=1,nshiftk2
1657 : : shiftk3(:,ishiftk)=gprimd_super(:,1)*shiftk2(1,ishiftk)+&
1658 : : & gprimd_super(:,2)*shiftk2(2,ishiftk)+&
1659 [ + + ]: 14465 : & gprimd_super(:,3)*shiftk2(3,ishiftk)
1660 : : end do
1661 : 2893 : call smallprim(metmin,minim,rprimd_super)
1662 : 2893 : call metric(gmet_super,gprimd_super,-1,rmet_super,minim,ucvol_super)
1663 : : ! This is the new kptrlatt2
1664 [ + + ]: 11572 : do ii=1,3
1665 : : dijk(:)=gprimd(1,:)*minim(1,ii)+&
1666 : : & gprimd(2,:)*minim(2,ii)+&
1667 [ + + ]: 34716 : & gprimd(3,:)*minim(3,ii)
1668 [ + + ]: 37609 : kptrlatt2(:,ii)=nint(dijk(:))
1669 : : end do
1670 : : ! Shifts in the new set of kptrlatt vectors
1671 [ + + ]: 5786 : do ishiftk=1,nshiftk2
1672 : : shiftk2(:,ishiftk)=minim(1,:)*shiftk3(1,ishiftk)+&
1673 : : & minim(2,:)*shiftk3(2,ishiftk)+&
1674 [ + + ]: 14465 : & minim(3,:)*shiftk3(3,ishiftk)
1675 : : end do
1676 : : end if
1677 : :
1678 : 10460 : mkpt=nkptlatt*nshiftk2
1679 : :
1680 [ - + + - : 31380 : ABI_MALLOC(spkpt,(3,mkpt))
+ - + - -
+ - + ]
1681 : 10460 : option=0
1682 [ + + ]: 10460 : if(iout/=0)option=1
1683 : :
1684 : : !call cwtime_report(' shifts', cpu, wall, gflops)
1685 : :
1686 [ + + ]: 10460 : if (present(downsampling))then
1687 : 7309 : call smpbz(iout,kptrlatt2,mkpt,nkpthf_computed,nshiftk2,option,shiftk2,spkpt,downsampling=downsampling)
1688 [ + - + + ]: 7309 : if (present(kpthf) .and. nkpthf/=0) then
1689 : : ! Returns list of k-points in the Full BZ, possibly downsampled for Fock
1690 [ + + + + ]: 3020549 : kpthf = spkpt(:,1:nkpthf)
1691 : : end if
1692 : 7309 : nkpthf=nkpthf_computed
1693 : : end if
1694 : :
1695 : 10460 : call smpbz(iout,kptrlatt2,mkpt,nkpt_fullbz,nshiftk2,option,shiftk2,spkpt)
1696 : : !call cwtime_report(' smpbz', cpu, wall, gflops)
1697 : :
1698 [ + + ]: 10460 : if(kptopt==1 .or. kptopt==2 .or. kptopt==4)then
1699 : :
1700 [ - + + - : 25245 : ABI_MALLOC(indkpt,(nkpt_fullbz))
+ - + - -
+ - + -
+ ]
1701 [ - + + - : 25245 : ABI_MALLOC(kpt_fullbz,(3,nkpt_fullbz))
+ - + - -
+ - + ]
1702 [ - + + - : 25245 : ABI_MALLOC(bz2ibz_smap, (6, nkpt_fullbz))
+ - + - -
+ - + -
+ ]
1703 : : #if 1
1704 [ - + + - : 25245 : ABI_MALLOC(wtk_fullbz,(nkpt_fullbz))
+ - + - -
+ - + ]
1705 [ - + + - : 16830 : ABI_MALLOC(wtk_folded,(nkpt_fullbz))
- + - + ]
1706 : :
1707 [ + + + + ]: 19327623 : kpt_fullbz(:,:)=spkpt(:,1:nkpt_fullbz)
1708 [ + + ]: 4838217 : wtk_fullbz(1:nkpt_fullbz)=1.0_dp/dble(nkpt_fullbz)
1709 : :
1710 [ + + ]: 8415 : timrev=1;if (kptopt==4) timrev=0
1711 : :
1712 [ + + ]: 4838217 : indkpt = 0
1713 : : call symkpt(chksymbreak,gmet,indkpt,iout,kpt_fullbz,nkpt_fullbz,&
1714 : 8415 : & nkpt_computed,nsym_used,symrec,timrev,wtk_fullbz,wtk_folded,bz2ibz_smap,xmpi_comm_self)
1715 : :
1716 [ - + ]: 8415 : ABI_FREE(symrec)
1717 [ - + ]: 8415 : ABI_FREE(wtk_fullbz)
1718 : :
1719 : : !do ikpt=1,nkpt_fullbz
1720 : : ! write(*,*) ikpt, indkpt(ikpt), bz2ibz_smap(1,ikpt), indkpt(bz2ibz_smap(1,ikpt))
1721 : : !end do
1722 : : #else
1723 : : kpt_fullbz(:,:)=spkpt(:,1:nkpt_fullbz)
1724 : :
1725 : : timrev=1;if (kptopt==4) timrev=0
1726 : :
1727 : : call symkpt_new(chksymbreak,gmet,indkpt,iout,kpt_fullbz,nkpt_fullbz,&
1728 : : & nkpt_computed,nsym_used,symrec,timrev,bz2ibz_smap,xmpi_comm_self)
1729 : :
1730 : : ABI_FREE(symrec)
1731 : : ABI_CALLOC(wtk_folded,(nkpt_fullbz))
1732 : : do ii=1,nkpt_fullbz
1733 : : ikpt = indkpt(bz2ibz_smap(1,ii))
1734 : : wtk_folded(ikpt) = wtk_folded(ikpt) + one
1735 : : end do
1736 : : wtk_folded = wtk_folded / nkpt_fullbz
1737 : : #endif
1738 : :
1739 [ - + ]: 2045 : else if(kptopt==3)then
1740 [ - + + - : 688117 : ABI_ICALLOC(bz2ibz_smap, (6, nkpt_fullbz))
+ - + - -
+ - + - +
+ + + + ]
1741 [ + - + + : 196897 : bz2ibz_smap(1,:) = [(ii,ii=1,nkpt_fullbz)]
+ + ]
1742 [ + + ]: 99471 : bz2ibz_smap(2,:) = 1 !isym
1743 : 2045 : nkpt_computed=nkpt_fullbz
1744 : : end if
1745 : : !call cwtime_report(' symkpt', cpu, wall, gflops)
1746 : :
1747 : : !The number of k points has been computed from kptopt, kptrlatt, nshiftk, shiftk,
1748 : : !and the eventual symmetries, it is presently called nkpt_computed.
1749 : 10460 : nkpt_use = nkpt
1750 [ + + ]: 10460 : if (nkpt<0) nkpt_use = nkpt_computed
1751 : :
1752 : : !Check that the argument nkpt is coherent with nkpt_computed, if nkpt/=0.
1753 [ + + + + ]: 10460 : if(nkpt_use/=nkpt_computed .and. nkpt/=0)then
1754 : : write(msg, '(a,i0,5a,i0,7a)') &
1755 : 1 : 'The argument nkpt = ',nkpt_use,', does not match',ch10,&
1756 : 1 : 'the number of k points generated by kptopt, kptrlatt, shiftk,',ch10,&
1757 : 1 : 'and the eventual symmetries, that is, nkpt= ',nkpt_computed,'.',ch10,&
1758 : 1 : 'However, note that it might be due to the user,',ch10,&
1759 : 1 : 'if nkpt is explicitly defined in the input file.',ch10,&
1760 : 2 : 'In this case, please check your input file.'
1761 : 1 : ABI_BUG(msg)
1762 : : end if
1763 : :
1764 [ + + + - : 31377 : ABI_MALLOC(kpt,(3,nkpt_use))
+ - + + -
+ - + -
+ ]
1765 [ + + + - : 31377 : ABI_MALLOC(wtk,(nkpt_use))
+ - + + -
+ - + -
+ ]
1766 : :
1767 [ + + ]: 10459 : if(kptopt==1 .or. kptopt==2 .or. kptopt==4)then
1768 : :
1769 [ + + ]: 8414 : if(nkpt_use/=0)then
1770 [ + + ]: 219148 : do ikpt=1,nkpt_use
1771 [ + + ]: 862428 : kpt(:,ikpt)=kpt_fullbz(:,indkpt(ikpt))
1772 [ + + + - : 219148 : if(iscf>=0 .or. iscf==-3 .or. iscf==-1.or.iscf==-2)wtk(ikpt)=wtk_folded(indkpt(ikpt))
+ - ]
1773 : : end do
1774 : : end if
1775 : :
1776 [ + + ]: 8414 : if (present(fullbz)) then
1777 : : ! Returns list of k-points in the Full BZ.
1778 [ - + ]: 544 : ABI_MOVE_ALLOC(kpt_fullbz,fullbz)
1779 : : else
1780 [ - + ]: 7870 : ABI_FREE(kpt_fullbz)
1781 : : end if
1782 : :
1783 [ - + ]: 8414 : ABI_FREE(wtk_folded)
1784 : :
1785 [ + - ]: 2045 : else if(kptopt==3)then
1786 : :
1787 [ + + ]: 2045 : if(nkpt_use/=0)then
1788 [ + + + + ]: 225090 : kpt(:,1:nkpt_use)=spkpt(:,1:nkpt_use)
1789 [ + + + - : 56846 : if(iscf>1 .or. iscf==-3 .or. iscf==-1.or.iscf==-2)wtk(1:nkpt_use)=1.0_dp/dble(nkpt_use)
+ + + + ]
1790 : : end if
1791 : :
1792 [ + + ]: 2045 : if (present(fullbz)) then
1793 : : ! Returns list of k-points in the Full BZ.
1794 [ - + + - : 39 : ABI_MALLOC(fullbz,(3,nkpt_fullbz))
+ - + - -
+ - + -
+ ]
1795 [ - + + + : 3610 : fullbz = spkpt(:,1:nkpt_fullbz)
+ + ]
1796 : : end if
1797 : :
1798 : : end if
1799 : :
1800 [ - + ]: 10459 : ABI_FREE(spkpt)
1801 : 10459 : kptrlatt(:,:)=kptrlatt2(:,:)
1802 : 10459 : nshiftk=nshiftk2
1803 [ + + + + ]: 52295 : shiftk(:,1:nshiftk)=shiftk2(:,1:nshiftk)
1804 [ - + ]: 10459 : ABI_FREE(shiftk2)
1805 [ - + ]: 10459 : ABI_FREE(shiftk3)
1806 : :
1807 [ - + - + : 20919 : end subroutine getkgrid_low
- + ]
1808 : : !!***
1809 : :
1810 : : !!****f* m_kpts/get_full_kgrid
1811 : : !! NAME
1812 : : !! get_full_kgrid
1813 : : !!
1814 : : !! FUNCTION
1815 : : !! Create full grid of kpoints and find equivalent
1816 : : !! irred ones. Duplicates work in getkgrid, but need all outputs of kpt_fullbz, and indkpt
1817 : : !!
1818 : : !! INPUTS
1819 : : !! kpt(3,nkpt)=irreducible kpoints
1820 : : !! kptrlatt(3,3)=lattice vectors for full kpoint grid
1821 : : !! nkpt=number of irreducible kpoints
1822 : : !! nkpt_fullbz=number of kpoints in full brillouin zone
1823 : : !! nshiftk=number of kpoint grid shifts
1824 : : !! nsym=number of symmetries
1825 : : !! shiftk(3,nshiftk)=kpoint shifts
1826 : : !! symrel(3,3,nsym)=symmetry matrices in real space
1827 : : !!
1828 : : !! OUTPUT
1829 : : !! indkpt(nkpt_fullbz)=non-symmetrized indices of the k-points (see symkpt.f)
1830 : : !! kpt_fullbz(3,nkpt_fullbz)=kpoints in full brillouin zone
1831 : : !!
1832 : : !! NOTES
1833 : : !! MG: The present implementation always assumes kptopt==1 !!!!
1834 : : !!
1835 : : !! TODO: This routine should be removed
1836 : : !!
1837 : : !! SOURCE
1838 : :
1839 : 0 : subroutine get_full_kgrid(indkpt,kpt,kpt_fullbz,kptrlatt,nkpt,nkpt_fullbz,nshiftk,nsym,shiftk,symrel)
1840 : :
1841 : : !Arguments ------------------------------------
1842 : : !scalars
1843 : : integer,intent(in) :: nkpt,nkpt_fullbz,nshiftk,nsym
1844 : : !arrays
1845 : : integer,intent(in) :: kptrlatt(3,3),symrel(3,3,nsym)
1846 : : integer,intent(out) :: indkpt(nkpt_fullbz)
1847 : : real(dp),intent(in) :: kpt(3,nkpt),shiftk(3,nshiftk)
1848 : : real(dp),intent(out) :: kpt_fullbz(3,nkpt_fullbz)
1849 : :
1850 : : !Local variables-------------------------------
1851 : : !scalars
1852 : : integer :: ikpt,isym,itim,timrev
1853 : : integer :: symrankkpt
1854 : : character(len=500) :: msg
1855 : 0 : type(krank_t) :: krank
1856 : : !arrays
1857 : 0 : integer :: inv_symrel(3,3,nsym)
1858 : : real(dp) :: k2(3)
1859 : : ! *********************************************************************
1860 : :
1861 : : !Invert symrels => gives symrels for kpoints
1862 : :
1863 [ # # ]: 0 : do isym=1,nsym
1864 : 0 : call mati3inv (symrel(:,:,isym),inv_symrel(:,:,isym))
1865 : : end do
1866 : :
1867 : 0 : call get_kpt_fullbz(kpt_fullbz,kptrlatt,nkpt_fullbz,nshiftk,shiftk)
1868 : :
1869 : : ! make full k-point rank arrays
1870 : 0 : call krank%init(nkpt, kpt)
1871 : :
1872 : : !find equivalence to irred kpoints in kpt
1873 [ # # ]: 0 : indkpt(:) = 0
1874 : 0 : timrev=1 ! includes the time inversion symmetry
1875 [ # # ]: 0 : do ikpt=1,nkpt_fullbz
1876 [ # # ]: 0 : do isym=1,nsym
1877 [ # # ]: 0 : do itim=1,(1-2*timrev),-2
1878 : :
1879 : : k2(:) = itim*(inv_symrel(:,1,isym)*kpt_fullbz(1,ikpt) + &
1880 : : inv_symrel(:,2,isym)*kpt_fullbz(2,ikpt) + &
1881 [ # # ]: 0 : inv_symrel(:,3,isym)*kpt_fullbz(3,ikpt))
1882 : :
1883 : 0 : symrankkpt = krank%get_rank(k2)
1884 [ # # ]: 0 : if (krank%invrank(symrankkpt) /= -1) indkpt(ikpt) = krank%invrank(symrankkpt)
1885 : :
1886 : : end do ! loop time reversal symmetry
1887 : : end do ! loop sym ops
1888 : :
1889 [ # # ]: 0 : if (indkpt(ikpt) == 0) then
1890 : 0 : write(msg,'(a,i0)')' indkpt(ikpt) is still 0: no irred kpoint is equiv to ikpt ',ikpt
1891 : 0 : ABI_BUG(msg)
1892 : : end if
1893 : : end do ! loop full kpts
1894 : :
1895 : 0 : call krank%free()
1896 : :
1897 [ # # # # : 0 : end subroutine get_full_kgrid
# # ]
1898 : : !!***
1899 : :
1900 : : !!****f* m_kpts/get_kpt_fullbz
1901 : : !! NAME
1902 : : !! get_kpt_fullbz
1903 : : !!
1904 : : !! FUNCTION
1905 : : !! Create full grid of kpoints from kptrlatt and shiftk
1906 : : !!
1907 : : !! INPUTS
1908 : : !! kptrlatt(3,3)=lattice vectors for full kpoint grid
1909 : : !! nkpt_fullbz=number of kpoints in full brillouin zone
1910 : : !! nshiftk=number of kpoint grid shifts
1911 : : !! shiftk(3,nshiftk)=kpoint shifts
1912 : : !!
1913 : : !! OUTPUT
1914 : : !! kpt_fullbz(3,nkpt_fullbz)=kpoints in full brillouin zone
1915 : : !!
1916 : : !! SOURCE
1917 : :
1918 : 0 : subroutine get_kpt_fullbz(kpt_fullbz,kptrlatt,nkpt_fullbz,nshiftk,shiftk)
1919 : :
1920 : : !Arguments ------------------------------------
1921 : : !scalars
1922 : : integer,intent(in) :: nkpt_fullbz,nshiftk
1923 : : !arrays
1924 : : integer,intent(in) :: kptrlatt(3,3)
1925 : : real(dp),intent(in) :: shiftk(3,nshiftk)
1926 : : real(dp),intent(out) :: kpt_fullbz(3,nkpt_fullbz)
1927 : :
1928 : : !Local variables-------------------------------
1929 : : !scalars
1930 : : integer, parameter :: max_number_of_prime=47
1931 : : integer :: det,ii,ikshft,iprim,jj,kk,nn
1932 : : character(len=500) :: msg
1933 : : !arrays
1934 : : integer :: boundmax(3),boundmin(3),common_factor(3)
1935 : : integer, parameter :: prime_factor(max_number_of_prime)=(/2,3,5,7,9, 11,13,17,19,23,&
1936 : : & 29,31,37,41,43, 47,53,59,61,67,&
1937 : : & 71,73,79,83,89, 97,101,103,107,109,&
1938 : : & 113,127,131,137,139, 149,151,157,163,167,&
1939 : : & 173,179,181,191,193, 197,199/)
1940 : : real(dp) :: k1(3),k2(3),klatt(3,3),rlatt(3,3),shift(3),test_rlatt(3,3)
1941 : : ! *********************************************************************
1942 : :
1943 : : !Identify first factors that can be used to rescale the three kptrlatt vectors
1944 : : !Only test a large set of prime factors, though ...
1945 [ # # ]: 0 : do jj=1,3
1946 : 0 : common_factor(jj)=1
1947 [ # # ]: 0 : rlatt(:,jj)=kptrlatt(:,jj)
1948 [ # # ]: 0 : do iprim=1,max_number_of_prime
1949 [ # # ]: 0 : test_rlatt(:,jj)=rlatt(:,jj)/dble(prime_factor(iprim))
1950 : : ! If one of the components is lower than 1 in absolute value, then it is not worth to continue the search.
1951 [ # # # # : 0 : if(minval(abs(abs(test_rlatt(:,jj))-half))<half-tol8)exit
# # # # ]
1952 : 0 : do
1953 [ # # # # ]: 0 : if(sum(abs(test_rlatt(:,jj)-nint(test_rlatt(:,jj)) ))<tol8)then
1954 : 0 : common_factor(jj)=prime_factor(iprim)*common_factor(jj)
1955 [ # # ]: 0 : rlatt(:,jj)=rlatt(:,jj)/dble(prime_factor(iprim))
1956 [ # # ]: 0 : test_rlatt(:,jj)=test_rlatt(:,jj)/dble(prime_factor(iprim))
1957 : : else
1958 : : exit
1959 : : end if
1960 : : end do
1961 : : end do
1962 : : end do
1963 : 0 : call mati3det(kptrlatt,det)
1964 : 0 : det=det/(common_factor(1)*common_factor(2)*common_factor(3))
1965 : :
1966 [ # # # # ]: 0 : rlatt(:,:)=kptrlatt(:,:)
1967 : 0 : call matr3inv(rlatt,klatt)
1968 : : !Now, klatt contains the three primitive vectors of the k lattice,
1969 : : !in reduced coordinates. One builds all k vectors that
1970 : : !are contained in the first Brillouin zone, with coordinates
1971 : : !in the interval [0,1[ . First generate boundaries of a big box.
1972 : : !In order to generate all possible vectors in the reciprocal space,
1973 : : !one must consider all multiples of the primitive ones, until a vector with only integers is found.
1974 : : !The maximum bound is the scale of the corresponding kptrlatt vector, times the determinant of kptrlatt. Also consider negative vectors.
1975 : : !On this basis, compute the bounds.
1976 [ # # ]: 0 : do jj=1,3
1977 : : ! To accommodate the shifts, boundmin starts from -1
1978 : : ! Well, this is not a complete solution ...
1979 : 0 : boundmin(jj)=-1-common_factor(jj)*abs(det)
1980 : 0 : boundmax(jj)=common_factor(jj)*abs(det)
1981 : : end do
1982 : :
1983 : 0 : nn=1
1984 [ # # ]: 0 : do kk=boundmin(3),boundmax(3)
1985 [ # # ]: 0 : do jj=boundmin(2),boundmax(2)
1986 [ # # ]: 0 : do ii=boundmin(1),boundmax(1)
1987 [ # # ]: 0 : do ikshft=1,nshiftk
1988 : :
1989 : : ! Coordinates of the trial k point with respect to the k primitive lattice
1990 : 0 : k1(1)=ii+shiftk(1,ikshft)
1991 : 0 : k1(2)=jj+shiftk(2,ikshft)
1992 : 0 : k1(3)=kk+shiftk(3,ikshft)
1993 : :
1994 : : ! Reduced coordinates of the trial k point
1995 [ # # ]: 0 : k2(:)=k1(1)*klatt(:,1)+k1(2)*klatt(:,2)+k1(3)*klatt(:,3)
1996 : :
1997 : : ! Eliminate the point if outside [0,1[
1998 [ # # # # ]: 0 : if(k2(1)<-tol10)cycle ; if(k2(1)>one-tol10)cycle
1999 [ # # # # ]: 0 : if(k2(2)<-tol10)cycle ; if(k2(2)>one-tol10)cycle
2000 [ # # # # ]: 0 : if(k2(3)<-tol10)cycle ; if(k2(3)>one-tol10)cycle
2001 : :
2002 : : ! Wrap the trial values in the interval ]-1/2,1/2] .
2003 : 0 : call wrap2_pmhalf(k2(1),k1(1),shift(1))
2004 : 0 : call wrap2_pmhalf(k2(2),k1(2),shift(2))
2005 : 0 : call wrap2_pmhalf(k2(3),k1(3),shift(3))
2006 [ # # ]: 0 : if(nn > nkpt_fullbz) then
2007 : 0 : write (msg,'(a,i0)')' nkpt_fullbz mis-estimated, exceed nn=',nn
2008 : 0 : ABI_BUG(msg)
2009 : : end if
2010 [ # # ]: 0 : kpt_fullbz(:,nn)=k1(:)
2011 : 0 : nn=nn+1
2012 : : end do
2013 : : end do
2014 : : end do
2015 : : end do
2016 : 0 : nn = nn-1
2017 : :
2018 [ # # ]: 0 : if (nn /= nkpt_fullbz) then
2019 : 0 : write (msg,'(2(a,i0),a,a)')' nkpt_fullbz= ',nkpt_fullbz,' underestimated nn=',nn,&
2020 : 0 : & ch10, "Perhaps your k grid or shifts do not correspond to the symmetry?"
2021 : 0 : ABI_BUG(msg)
2022 : : end if
2023 : :
2024 : 0 : end subroutine get_kpt_fullbz
2025 : : !!***
2026 : :
2027 : : !!****f* m_kpts/smpbz
2028 : : !! NAME
2029 : : !! smpbz
2030 : : !!
2031 : : !! FUNCTION
2032 : : !! Generate a set of special k (or q) points which samples in a homogeneous way
2033 : : !! the entire Brillouin zone of an arbitrary lattice, specified by kptrlatt
2034 : : !! (the matrix of the k/q point lattice reciprocal to the requested sampling
2035 : : !! lattice). This is the general Monkhorst-Pack algorithm: any Bravais
2036 : : !! lattice, including face-centered cubic, body-centered lattice and
2037 : : !! hexagonal ones, is handled by feeding it the appropriate (possibly
2038 : : !! non-diagonal) kptrlatt -- see kptrlatt_from_brav_ngqpt for a helper that
2039 : : !! builds kptrlatt from the historical (brav, ngqpt) input convention.
2040 : : !! If kptrlatt is diagonal, the algorithm used here reduces to the usual
2041 : : !! Monkhorst-Pack set of k points.
2042 : : !!
2043 : : !! INPUTS
2044 : : !! downsampling(3) [optional]
2045 : : !! Three integer numbers, describing the downsampling of the k grid
2046 : : !! If present, in any case, only the first shiftk is taken into account
2047 : : !! The absolute value of one number gives, for the corresponding k-coordinate, the factor of decrease of the sampling
2048 : : !! If zero, only one point is used to sample along this direction
2049 : : !! The sign has also a meaning :
2050 : : !! - if three numbers are negative, perform a face-centered sampling
2051 : : !! - if two numbers are negative, perform a body-centered sampling
2052 : : !! - if one number is negative, perform a face-centered sampling for the two-dimensional lattice of the other directions
2053 : : !! - if one number is zero and at least one number is negative, perform face-centered sampling for the non-zero directions.
2054 : : !! iout = unit number for output
2055 : : !! kptrlatt(3,3)=integer coordinates of the primitive vectors of the
2056 : : !! lattice reciprocal to the k point lattice to be generated here
2057 : : !! If diagonal, the three values are the Monkhorst-Pack usual values, in case of simple cubic.
2058 : : !! mkpt = maximum number of k points
2059 : : !! nshiftk= number of shift vectors in the repeated cell
2060 : : !! option= Flag defining what will be printed of iout: 0 for k points, anything else for q points.
2061 : : !! Also, for q points, if the Gamma point is present, place it first in the list.
2062 : : !! shiftk(3,nshiftk) = vectors that will be used to determine the shifts from (0. 0. 0.).
2063 : : !! prtout=write info to the output and log files.
2064 : : !!
2065 : : !! OUTPUT
2066 : : !! nkpt = number of k points
2067 : : !! spkpt(3,mkpt) = the nkpt first values contain the special k points
2068 : : !! obtained by the Monkhorst & Pack method, in reduced coordinates.
2069 : : !! These vectors have to be multiplied by the reciprocal basis vectors
2070 : : !! gprimd(3,3) (in cartesian coordinates) to obtain the special k points
2071 : : !! set in cartesian coordinates.
2072 : : !!
2073 : : !! NOTES
2074 : : !! also allows for more than one vector in repeated cell.
2075 : : !! References :
2076 : : !! H.J. Monkhorst and J.D. Pack, Phys. Rev. B 13, 5188 (1976) [[cite:Monkhorst1976]]
2077 : : !! J.D. Pack and H.J. Monkhorst, Phys. Rev. B 16, 1748 (1977) [[cite:Pack1977]]
2078 : : !! A.H. MacDonald, Phys. Rev. B 18, 5897 (1978) [[cite:MacDonald1978]]
2079 : : !! R.A. Evarestov and V.P. Smirnov, Phys. Stat. Sol. (b) 119, 9 (1983) [[cite:Evarestov1983]]
2080 : : !!
2081 : : !! SOURCE
2082 : :
2083 : 18129 : subroutine smpbz(iout,kptrlatt,mkpt,nkpt,nshiftk,option,shiftk,spkpt,downsampling,prtout)
2084 : :
2085 : : !Arguments -------------------------------
2086 : : !scalars
2087 : : integer,intent(in) :: iout,mkpt,nshiftk,option
2088 : : integer,intent(out) :: nkpt
2089 : : logical, optional, intent(in) :: prtout
2090 : : !arrays
2091 : : integer,intent(in) :: kptrlatt(3,3)
2092 : : integer,optional,intent(in) :: downsampling(3)
2093 : : real(dp),intent(in) :: shiftk(3,nshiftk)
2094 : : real(dp),intent(out) :: spkpt(3,mkpt)
2095 : :
2096 : : !Local variables -------------------------
2097 : : !scalars
2098 : : integer,parameter :: prtvol=0
2099 : : integer :: dividedown,ii,ikshft,jj,kk,nkpout,nkptlatt,nn,proddown
2100 : : logical :: prtout_
2101 : : real(dp) :: shift
2102 : : character(len=500) :: msg
2103 : : !arrays
2104 : : integer :: ads(3),boundmax(3),boundmin(3),cds(3),coord(3)
2105 : 18129 : integer, allocatable :: found1(:,:),found2(:,:),found3(:,:)
2106 : : real(dp) :: k1(3),k2(3),klatt(3,3),rlatt(3,3)
2107 : : ! *********************************************************************
2108 : :
2109 : : !write(std_out,*)' smpbz : iout,mkpt,nkpt,option=',iout,mkpt,nkpt,option
2110 : : !write(std_out,*)' smpbz : kptrlatt(:,:)=',kptrlatt(:,:)
2111 : : !write(std_out,*)' smpbz : nshiftk=',nshiftk
2112 : : !write(std_out,*)' smpbz : shiftk(:,:)=',shiftk(:,:)
2113 : : !write(std_out,*)' smpbz : downsampling(:)=',downsampling(:)
2114 : :
2115 : 18129 : prtout_ = .true.
2116 [ + + ]: 18129 : if (present(prtout)) then
2117 : 201 : prtout_ = prtout
2118 : : end if
2119 : :
2120 [ + + ]: 18129 : if (option/=0) then
2121 [ + + ]: 382 : if (prtout_) call wrtout(iout,' Homogeneous q point set in the B.Z. ')
2122 : : end if
2123 : :
2124 : : !Just in case the user wants the grid downsampled to the Gamma point, checks that it is present, and possibly exits
2125 [ + + ]: 18129 : if(present(downsampling))then
2126 [ + + + + ]: 29236 : if(sum(abs(downsampling(:)))==0)then
2127 [ + - ]: 18 : do ikshft=1,nshiftk
2128 [ + + + - ]: 72 : if(sum(abs(shiftk(:,ikshft)))>tol12)cycle
2129 : 18 : nkpt=1
2130 [ + + ]: 72 : spkpt(:,1)=zero
2131 : 0 : return
2132 : : end do
2133 : : end if
2134 : : end if
2135 : :
2136 : : ! Compute the number of k points in the G-space unit cell
2137 : : ! (will be multiplied by nshiftk later).
2138 : : nkptlatt=kptrlatt(1,1)*kptrlatt(2,2)*kptrlatt(3,3) &
2139 : : & +kptrlatt(1,2)*kptrlatt(2,3)*kptrlatt(3,1) &
2140 : : & +kptrlatt(1,3)*kptrlatt(2,1)*kptrlatt(3,2) &
2141 : : & -kptrlatt(1,2)*kptrlatt(2,1)*kptrlatt(3,3) &
2142 : : & -kptrlatt(1,3)*kptrlatt(2,2)*kptrlatt(3,1) &
2143 : 18111 : & -kptrlatt(1,1)*kptrlatt(2,3)*kptrlatt(3,2)
2144 : :
2145 [ + + ]: 18111 : if(present(downsampling))then
2146 [ + + + - : 7291 : if(.not.(downsampling(1)==1 .and. downsampling(2)==1 .and. downsampling(3)==1))then
- + ]
2147 [ - + ]: 150 : if(nshiftk>1)then
2148 : : write(msg, '(a,3i4,2a,i4,4a)' )&
2149 : 0 : & 'Real downsampling is activated, with downsampling(1:3)=',downsampling(1:3),ch10,&
2150 : 0 : & 'However, nshiftk must be 1 in this case, while the input nshiftk=',nshiftk,ch10,&
2151 : 0 : & 'Action: either choose not to downsample the k point grid (e.g. fockdownsampling=1),',ch10,&
2152 : 0 : & 'or set nshiftk=1.'
2153 : 0 : ABI_ERROR(msg)
2154 : : end if
2155 : 150 : proddown=downsampling(1)*downsampling(2)*downsampling(3)
2156 [ + - ]: 150 : if(proddown/=0)then
2157 : 150 : dividedown=abs(proddown)
2158 [ + + + + ]: 600 : if(minval(downsampling(:))<0)then ! If there is at least one negative number
2159 : 42 : dividedown=dividedown*2
2160 [ + + ]: 42 : if(proddown>0)dividedown=dividedown*2 ! If there are two negative numbers
2161 : : end if
2162 : : end if
2163 [ + - ]: 150 : if(mod(nkptlatt,dividedown)==0)then
2164 : 150 : nkptlatt=nkptlatt/dividedown
2165 : : else
2166 : : write(msg, '(a,3i4,2a,i4,4a)' )&
2167 : 0 : & 'The requested downsampling, with downsampling(1:3)=',downsampling(1:3),ch10,&
2168 : 0 : & 'is not compatible with kptrlatt=',ch10,&
2169 : 0 : & kptrlatt(:,:),ch10,&
2170 : 0 : & 'that gives nkptlatt=',nkptlatt,ch10,&
2171 : 0 : & 'Action: either choose not to downsample the k point grid (e.g. fockdownsampling=1),',ch10,&
2172 : 0 : & 'or modify your k-point grid and/or your downsampling in order for them to be compatible.'
2173 : 0 : ABI_ERROR(msg)
2174 : : end if
2175 : : end if
2176 : : end if
2177 : :
2178 : : ! Simple Lattice
2179 : : if (prtvol > 0) call wrtout(std_out,' Simple Lattice Grid ')
2180 [ - + ]: 18111 : if (mkpt<nkptlatt*nshiftk) then
2181 : : write(msg, '(a,a,a,i8,a,a,a,a,a)' )&
2182 : 0 : & 'The value of mkpt is not large enough. It should be',ch10,&
2183 : 0 : & 'at least',nkptlatt*nshiftk,',',ch10,&
2184 : 0 : & 'Action: set mkpt to that value in the main routine,',ch10,&
2185 : 0 : & 'and recompile the code.'
2186 : 0 : ABI_BUG(msg)
2187 : : end if
2188 : :
2189 : : ! Build primitive vectors of the k lattice
2190 [ + + + + ]: 235443 : rlatt(:,:)=kptrlatt(:,:)
2191 : 18111 : call matr3inv(rlatt,klatt)
2192 : :
2193 : : ! write(std_out,*)' First primitive vector of the k lattice :',klatt(:,1)
2194 : : ! write(std_out,*)' Second primitive vector of the k lattice :',klatt(:,2)
2195 : : ! write(std_out,*)' Third primitive vector of the k lattice :',klatt(:,3)
2196 : :
2197 : : ! Now, klatt contains the three primitive vectors of the k lattice,
2198 : : ! in reduced coordinates. One builds all k vectors that
2199 : : ! are contained in the first Brillouin zone, with coordinates
2200 : : ! in the interval [0,1[ . First generate boundaries of a big box.
2201 : :
2202 [ + + ]: 72444 : do jj=1,3
2203 : :
2204 : : ! Mathematically, one has to find the coordinates of the corners of a
2205 : : ! rectangular paralleliped with integer coordinates, that multiplies the klatt primitive cell and allows
2206 : : ! it to incorporate completely the [0,1]^3 box. Then take the minimum and maximum
2207 : : ! of these coordinates, and round them negatively and positively to the next integer.
2208 : : ! This can be done easily using kptrlatt, considering each coordinate in turn
2209 : : ! and boils down to enlarging the boundaries for jj by the value of kptrlatt(:,jj),
2210 : : ! acting on boundmin or boundmax depending on the sign of kptrlatt(:,jj).
2211 : : ! XG171020 The coding before 171020 was correct, despite being very simple.
2212 : 54333 : boundmin(jj)=0 ; boundmax(jj)=0
2213 [ + + ]: 217332 : do ii=1,3
2214 [ + + ]: 162999 : if(kptrlatt(ii,jj)<0)boundmin(jj)=boundmin(jj)+kptrlatt(ii,jj)
2215 [ + + ]: 217332 : if(kptrlatt(ii,jj)>0)boundmax(jj)=boundmax(jj)+kptrlatt(ii,jj)
2216 : : end do
2217 : :
2218 : : ! To accommodate the shifts, boundmin and boundmax don't start from 0, but are enlarged by one
2219 : : ! positively and/or negatively.
2220 : : ! XG171020 Coding in v8.6.0 and before was not correct. This one is even simpler actually.
2221 [ + - - + : 163038 : boundmin(jj)=boundmin(jj)-ceiling(maxval(shiftk(jj,:))+tol14)
- - + + +
+ ]
2222 [ + - - + : 181149 : boundmax(jj)=boundmax(jj)-floor(minval(shiftk(jj,:))-tol14)
- - + + +
+ ]
2223 : :
2224 : : end do
2225 : :
2226 [ + + ]: 18111 : if(present(downsampling))then
2227 [ - + + - : 29164 : ABI_MALLOC(found1,(boundmin(2):boundmax(2),boundmin(3):boundmax(3)))
- + + - +
- + - - +
- + ]
2228 [ - + + - : 29164 : ABI_MALLOC(found2,(boundmin(1):boundmax(1),boundmin(3):boundmax(3)))
- + + - +
- + - - +
- + ]
2229 [ - + + - : 29164 : ABI_MALLOC(found3,(boundmin(1):boundmax(1),boundmin(2):boundmax(2)))
- + + - +
- + - - +
- + ]
2230 [ + + + + : 1997047 : found1=0 ; found2=0 ; found3=0
+ + + + +
+ + + ]
2231 : : end if
2232 : :
2233 : 18111 : nn=1
2234 [ + + ]: 165041 : do kk=boundmin(3),boundmax(3)
2235 : 146930 : coord(3)=kk
2236 [ + + ]: 1847466 : do jj=boundmin(2),boundmax(2)
2237 : 1682425 : coord(2)=jj
2238 [ + + ]: 29455295 : do ii=boundmin(1),boundmax(1)
2239 : 27625940 : coord(1)=ii
2240 : :
2241 : : ! Here, apply the downsampling : skip some of the trials
2242 [ + + ]: 27625940 : if(present(downsampling))then
2243 : :
2244 [ - + - - ]: 9350492 : if(downsampling(1)==0 .and. found1(coord(2),coord(3))==1)cycle
2245 [ - + - - ]: 9350492 : if(downsampling(2)==0 .and. found2(coord(1),coord(3))==1)cycle
2246 [ - + - - ]: 9350492 : if(downsampling(3)==0 .and. found3(coord(1),coord(2))==1)cycle
2247 : :
2248 [ + + ]: 37401968 : ads(:)=abs(downsampling(:))
2249 [ + - + + ]: 9350492 : if(ads(1)>0 .and. mod(coord(1),ads(1))/=0)cycle
2250 [ + - + + ]: 9301160 : if(ads(2)>0 .and. mod(coord(2),ads(2))/=0)cycle
2251 [ + - + + ]: 9279392 : if(ads(3)>0 .and. mod(coord(3),ads(2))/=0)cycle
2252 [ + + ]: 37079136 : cds(:)=coord(:)/ads(:)
2253 [ + + + + ]: 37079136 : if(minval(downsampling(:))<0)then ! If there is at least one negative number
2254 : :
2255 [ + - ]: 1134 : if(downsampling(1)*downsampling(2)*downsampling(3)/=0)then ! If there is no zero number
2256 : : ! Face-centered case
2257 [ + - + + : 1134 : if(downsampling(1)<0 .and. downsampling(2)<0 .and. downsampling(3)<0)then ! All three are negative
+ + ]
2258 [ + + + + ]: 1512 : if(mod(sum(cds(:)),2)/=0)cycle
2259 : : ! One-face-centered case
2260 [ + + ]: 756 : else if(downsampling(1)*downsampling(2)*downsampling(3)<0)then ! Only one is negative
2261 [ + - + + ]: 378 : if(downsampling(1)<0 .and. mod(cds(2)+cds(3),2)/=0)cycle
2262 [ - + - - ]: 210 : if(downsampling(2)<0 .and. mod(cds(1)+cds(3),2)/=0)cycle
2263 [ - + - - ]: 210 : if(downsampling(3)<0 .and. mod(cds(1)+cds(2),2)/=0)cycle
2264 : : ! Body-centered case ! What is left : two are negative
2265 : : else
2266 : : ! Either all are zero, or all are one, so skip when sum is 1 or 2.
2267 [ + + + + : 2646 : if(sum(mod(cds(:),2))==1 .or. sum(mod(cds(:),2))==2)cycle
+ + ]
2268 : : end if
2269 : : else
2270 [ # # # # ]: 0 : if(downsampling(1)==0 .and. mod(cds(2)+cds(3),2)/=0)cycle
2271 [ # # # # ]: 0 : if(downsampling(2)==0 .and. mod(cds(1)+cds(3),2)/=0)cycle
2272 [ # # # # ]: 0 : if(downsampling(3)==0 .and. mod(cds(1)+cds(2),2)/=0)cycle
2273 : : end if
2274 : : end if
2275 : : end if
2276 : :
2277 [ + + ]: 56775212 : do ikshft=1,nshiftk
2278 : :
2279 : : ! Only the first shiftk is taken into account if downsampling
2280 : : ! if(.false.)then
2281 [ + + ]: 27548157 : if(present(downsampling))then
2282 [ + + + - : 9269182 : if(.not.(downsampling(1)==1 .and. downsampling(2)==1 .and. downsampling(3)==1))then
- + ]
2283 [ - + ]: 6996 : if(ikshft>1)cycle
2284 : : end if
2285 : : end if
2286 : :
2287 : : ! Coordinates of the trial k point with respect to the k primitive lattice
2288 : 27548157 : k1(1)=ii+shiftk(1,ikshft)
2289 : 27548157 : k1(2)=jj+shiftk(2,ikshft)
2290 : 27548157 : k1(3)=kk+shiftk(3,ikshft)
2291 : : ! Reduced coordinates of the trial k point
2292 [ + + ]: 110192628 : k2(:)=k1(1)*klatt(:,1)+k1(2)*klatt(:,2)+k1(3)*klatt(:,3)
2293 : : ! Eliminate the point if outside [0,1[
2294 [ + + + + ]: 27548157 : if(k2(1)<-tol10)cycle ; if(k2(1)>one-tol10)cycle
2295 [ + + + + ]: 16123704 : if(k2(2)<-tol10)cycle ; if(k2(2)>one-tol10)cycle
2296 [ + + + + ]: 10397403 : if(k2(3)<-tol10)cycle ; if(k2(3)>one-tol10)cycle
2297 : : ! Wrap the trial values in the interval ]-1/2,1/2] .
2298 : 6513870 : call wrap2_pmhalf(k2(1),k1(1),shift)
2299 : 6513870 : call wrap2_pmhalf(k2(2),k1(2),shift)
2300 : 6513870 : call wrap2_pmhalf(k2(3),k1(3),shift)
2301 [ + + ]: 26055480 : spkpt(:,nn)=k1(:)
2302 : 6513870 : nn=nn+1
2303 : :
2304 [ + + ]: 34139810 : if(present(downsampling))then
2305 : 1490138 : found1(coord(2),coord(3))=1
2306 : 1490138 : found2(coord(1),coord(3))=1
2307 : 1490138 : found3(coord(1),coord(2))=1
2308 : : end if
2309 : :
2310 : : end do
2311 : : end do
2312 : : end do
2313 : : end do
2314 : 18111 : nkpt=nn-1
2315 : :
2316 [ + + ]: 18111 : if(present(downsampling))then
2317 [ - + ]: 7291 : ABI_FREE(found1)
2318 [ - + ]: 7291 : ABI_FREE(found2)
2319 [ - + ]: 7291 : ABI_FREE(found3)
2320 : : end if
2321 : :
2322 [ - + ]: 18111 : if(nkpt/=nkptlatt*nshiftk)then
2323 : : write(msg, '(a,i0,3a,i0,a)' )&
2324 : 0 : 'The number of k points ',nkpt,' is not equal to',ch10,&
2325 : 0 : 'nkptlatt*nshiftk which is ',nkptlatt*nshiftk,'.'
2326 : 0 : ABI_BUG(msg)
2327 : : end if
2328 : :
2329 : :
2330 [ + + ]: 18111 : if (option/=0) then
2331 : : ! Put the Gamma point first
2332 [ + + ]: 382 : if(nkpt>1)then
2333 [ + + ]: 19070 : do ii=1,nkpt
2334 [ + + + + ]: 76238 : if(sum(abs(spkpt(:,ii)))<tol8)then
2335 [ + + ]: 1376 : spkpt(:,ii)=spkpt(:,1)
2336 [ + + ]: 1376 : spkpt(:,1)=zero
2337 : : exit
2338 : : end if
2339 : : end do
2340 : : end if
2341 : :
2342 [ + + ]: 382 : if (prtout_) then
2343 : 377 : write(msg,'(a,i8)')' Grid q points : ',nkpt
2344 : 377 : call wrtout(iout,msg)
2345 : 377 : nkpout=nkpt
2346 [ + + ]: 377 : if(nkpt>80)then
2347 : 65 : call wrtout(iout,' greater than 80, so only write 20 of them ')
2348 : 65 : nkpout=20
2349 : : end if
2350 [ + + ]: 9651 : do ii=1,nkpout
2351 : 9274 : write(msg, '(1x,i2,a2,3es16.8)' )ii,') ',spkpt(1,ii),spkpt(2,ii),spkpt(3,ii)
2352 : 9651 : call wrtout(iout,msg)
2353 : : end do
2354 : : end if
2355 : : end if
2356 : :
2357 [ - + - + : 18111 : end subroutine smpbz
- + ]
2358 : : !!***
2359 : :
2360 : : !!****f* m_kpts/testkgrid
2361 : : !! NAME
2362 : : !! testkgrid
2363 : : !!
2364 : : !! FUNCTION
2365 : : !! Test different grids of k points. The algorithm used is based on the idea of testing different
2366 : : !! one-dimensional sets of possible k point grids. It is not exhaustive (other families could be included),
2367 : : !! but should do a respectable job in all cases. The Monkhorst-Pack set of grids (defined with respect to
2368 : : !! symmetry axes, and not primitive axes) is always tested.
2369 : : !!
2370 : : !! INPUTS
2371 : : !! bravais(11): bravais(1)=iholohedry
2372 : : !! bravais(2)=center
2373 : : !! bravais(3:11)=coordinates of rprim in the axes of the conventional bravais lattice (*2 if center/=0)
2374 : : !! iout=unit number for echoed output
2375 : : !! msym=default maximal number of symmetries
2376 : : !! nsym=number of symmetries
2377 : : !! prtkpt=if non-zero, will write the characteristics of k grids, then stop
2378 : : !! rprimd(3,3)=dimensional real space primitive translations (bohr)
2379 : : !! symafm(nsym)=(anti)ferromagnetic part of symmetry operations
2380 : : !! symrel(3,3,nsym)=symmetry operations in real space in terms of primitive translations
2381 : : !! vacuum(3)=for each direction, 0 if no vacuum, 1 if vacuum
2382 : : !!
2383 : : !! OUTPUT
2384 : : !! kptrlatt(3,3)=k-point lattice specification
2385 : : !! nshiftk=number of k-point shifts in shiftk (always 1 from this routine)
2386 : : !! shiftk(3,MAX_NSHIFTK)=shift vectors for k point generation
2387 : : !!
2388 : : !! SIDE EFFECTS
2389 : : !! kptrlen=length of the smallest real space supercell vector associated with the lattice of k points.
2390 : : !!
2391 : : !! NOTES
2392 : : !! Note that nkpt can be computed by calling this routine with input value nkpt=0
2393 : : !! Note that kptopt is always =1 in this routine.
2394 : : !!
2395 : : !! SOURCE
2396 : :
2397 : 197 : subroutine testkgrid(bravais,iout,kptrlatt,kptrlen,msym,nshiftk,nsym,prtkpt,rprimd,shiftk,symafm,symrel,vacuum)
2398 : :
2399 : : !Arguments ------------------------------------
2400 : : !scalars
2401 : : integer,intent(in) :: iout,msym,nsym,prtkpt
2402 : : integer,intent(out) :: nshiftk
2403 : : real(dp),intent(inout) :: kptrlen
2404 : : !arrays
2405 : : integer,intent(in) :: bravais(11),symafm(msym),symrel(3,3,msym),vacuum(3)
2406 : : integer,intent(out) :: kptrlatt(3,3)
2407 : : real(dp),intent(in) :: rprimd(3,3)
2408 : : real(dp),intent(inout) :: shiftk(3,MAX_NSHIFTK) !vz_i
2409 : :
2410 : : !Local variables-------------------------------
2411 : : !scalars
2412 : : integer,parameter :: kptopt=1,mkpt_list=100000
2413 : : integer :: ang90,center,dirvacuum,equal,igrid,igrid_current,iholohedry,ii,init_mult,iscale,iscf
2414 : : integer :: iset,mult1,mult2,mult3,ndims,nkpt,nkpt_current,nkpt_trial,nset
2415 : : real(dp) :: buffer_scale,determinant,fact,factor,kptrlen_current,kptrlen_max,kptrlen_target
2416 : : real(dp) :: kptrlen_trial,length1,length2,length3,length_axis1,length_axis2
2417 : : real(dp) :: length_axis3,merit_factor,mult1h,mult2h,mult3h,reduceda,reducedb
2418 : : real(dp) :: sca,scb,scc,surface,ucvol
2419 : : character(len=500) :: msg
2420 : : !arrays
2421 : : integer :: kptrlatt_current(3,3),kptrlatt_trial(3,3)
2422 : 197 : integer,allocatable :: grid_list(:)
2423 : : real(dp) :: axes(3,3),gmet(3,3),gprimd(3,3),matrix1(3,3),matrix2(3,3)
2424 : : real(dp) :: metmin(3,3),minim(3,3),r2d(3,3),rmet(3,3),rsuper(3,3)
2425 : : real(dp) :: shiftk_current(3,MAX_NSHIFTK),shiftk_trial(3,MAX_NSHIFTK)
2426 : 197 : real(dp),allocatable :: kpt(:,:),kptrlen_list(:),wtk(:)
2427 : : ! *************************************************************************
2428 : :
2429 : 197 : kptrlen_target=kptrlen
2430 : :
2431 : : !The vacuum array must be made of 0 or 1
2432 [ + + ]: 788 : do ii=1,3
2433 [ - + ]: 788 : if(vacuum(ii)/=0 .and. vacuum(ii)/=1)then
2434 : : write(msg,'(a,a,a,i1,a,i3,a,a)')&
2435 : 0 : & 'The values of vacuum must be 0 or 1.',ch10,&
2436 : 0 : & 'However, the input vacuum(',ii,') is',vacuum(ii),ch10,&
2437 : 0 : & 'Action: correct vacuum in your input file.'
2438 : 0 : ABI_ERROR(msg)
2439 : : end if
2440 : : end do
2441 : :
2442 : : !Specific preparation for 2-dimensional system
2443 [ + + + + ]: 788 : if(sum(vacuum(:))==1)then
2444 : :
2445 : : ! Make the non-active vector orthogonal to the active vectors,
2446 : : ! and take it along the z direction
2447 [ + + ]: 8 : if(vacuum(1)==1)then
2448 : 2 : r2d(1,3)=rprimd(2,2)*rprimd(3,3)-rprimd(3,2)*rprimd(2,3)
2449 : 2 : r2d(2,3)=rprimd(3,2)*rprimd(1,3)-rprimd(1,2)*rprimd(3,3)
2450 : 2 : r2d(3,3)=rprimd(1,2)*rprimd(2,3)-rprimd(2,2)*rprimd(1,3)
2451 [ + + ]: 8 : r2d(:,1)=rprimd(:,2)
2452 [ + + ]: 8 : r2d(:,2)=rprimd(:,3)
2453 : : dirvacuum=1
2454 [ - + ]: 6 : else if(vacuum(2)==1)then
2455 : 0 : r2d(1,3)=rprimd(2,3)*rprimd(3,1)-rprimd(3,3)*rprimd(2,1)
2456 : 0 : r2d(2,3)=rprimd(3,3)*rprimd(1,1)-rprimd(1,3)*rprimd(3,1)
2457 : 0 : r2d(3,3)=rprimd(1,3)*rprimd(2,1)-rprimd(2,3)*rprimd(1,1)
2458 [ # # ]: 0 : r2d(:,1)=rprimd(:,3)
2459 [ # # ]: 0 : r2d(:,2)=rprimd(:,1)
2460 : : dirvacuum=2
2461 [ + - ]: 6 : else if(vacuum(3)==1)then
2462 : 6 : r2d(1,3)=rprimd(2,1)*rprimd(3,2)-rprimd(3,1)*rprimd(2,2)
2463 : 6 : r2d(2,3)=rprimd(3,1)*rprimd(1,2)-rprimd(1,1)*rprimd(3,2)
2464 : 6 : r2d(3,3)=rprimd(1,1)*rprimd(2,2)-rprimd(2,1)*rprimd(1,2)
2465 [ + + ]: 24 : r2d(:,1)=rprimd(:,1)
2466 [ + + ]: 24 : r2d(:,2)=rprimd(:,2)
2467 : : dirvacuum=3
2468 : : end if
2469 [ + + ]: 32 : surface=sqrt(sum(r2d(:,3)**2))
2470 : : ! Identify the 2-D Bravais lattice
2471 : : ! DEBUG
2472 : : ! write(std_out,*)' r2d=',r2d(:,:)
2473 : : ! ENDDEBUG
2474 : 8 : call metric(gmet,gprimd,-1,rmet,r2d,ucvol)
2475 : 8 : call smallprim(metmin,minim,r2d)
2476 : : ! DEBUG
2477 : : ! write(std_out,*)' minim=',minim(:,:)
2478 : : ! ENDDEBUG
2479 : 8 : ang90=0 ; equal=0 ; center=0
2480 : 8 : axes(:,:)=minim(:,:)
2481 [ + + ]: 8 : if(abs(metmin(1,2))<tol8)ang90=1
2482 [ + + ]: 8 : if(abs(metmin(1,1)-metmin(2,2))<tol8)equal=1
2483 [ + + ]: 8 : if(ang90==1)then
2484 : : if(equal==1)iholohedry=4
2485 [ + + ]: 5 : if(equal==0)iholohedry=2
2486 [ + + ]: 3 : else if(equal==1)then
2487 : 2 : reduceda=metmin(1,2)/metmin(1,1)
2488 [ + + ]: 2 : if(abs(reduceda+0.5_dp)<tol8)then
2489 : : iholohedry=3
2490 [ - + ]: 1 : else if(abs(reduceda-0.5_dp)<tol8)then
2491 : 0 : iholohedry=3
2492 : : ! Use conventional axes
2493 [ # # ]: 0 : axes(:,2)=minim(:,2)-minim(:,1)
2494 : : else
2495 : 4 : iholohedry=2 ; center=1
2496 [ + + ]: 4 : axes(:,1)=minim(:,1)+minim(:,2)
2497 [ + + ]: 4 : axes(:,2)=minim(:,2)-minim(:,1)
2498 : : end if
2499 : : else
2500 : 1 : reduceda=metmin(1,2)/metmin(1,1)
2501 : 1 : reducedb=metmin(1,2)/metmin(2,2)
2502 [ - + ]: 1 : if(abs(reduceda+0.5_dp)<tol8)then
2503 : 0 : iholohedry=2 ; center=1
2504 [ # # ]: 0 : axes(:,2)=2.0_dp*minim(:,2)+minim(:,1)
2505 [ - + ]: 1 : else if(abs(reduceda-0.5_dp)<tol8)then
2506 : 0 : iholohedry=2 ; center=1
2507 [ # # ]: 0 : axes(:,2)=2.0_dp*minim(:,2)-minim(:,1)
2508 [ - + ]: 1 : else if(abs(reducedb+0.5_dp)<tol8)then
2509 : 0 : iholohedry=2 ; center=1
2510 [ # # ]: 0 : axes(:,1)=2.0_dp*minim(:,1)+minim(:,2)
2511 [ - + ]: 1 : else if(abs(reducedb-0.5_dp)<tol8)then
2512 : 0 : iholohedry=2 ; center=1
2513 [ # # ]: 0 : axes(:,1)=2.0_dp*minim(:,1)-minim(:,2)
2514 : : else
2515 : : iholohedry=1
2516 : : end if
2517 : : end if
2518 : : ! Make sure that axes form a right-handed coordinate system
2519 : : determinant=axes(1,1)*axes(2,2)*axes(3,3) &
2520 : : & +axes(1,2)*axes(2,3)*axes(3,1) &
2521 : : & +axes(1,3)*axes(3,2)*axes(2,1) &
2522 : : & -axes(1,1)*axes(3,2)*axes(2,3) &
2523 : : & -axes(1,3)*axes(2,2)*axes(3,1) &
2524 : 8 : & -axes(1,2)*axes(2,1)*axes(3,3)
2525 [ - + ]: 8 : if(determinant<zero)then
2526 [ # # ]: 0 : axes(:,1)=-axes(:,1)
2527 : : end if
2528 : : ! Prefer symmetry axes on the same side as the primitive axes
2529 [ + + ]: 32 : sca=DOT_PRODUCT(axes(:,1), r2d(:,1))
2530 [ + + ]: 32 : scb=DOT_PRODUCT(axes(:,2), r2d(:,2))
2531 : : scc=DOT_PRODUCT(axes(:,3), rprimd(:,dirvacuum))
2532 [ - + - - ]: 8 : if(sca<-tol8 .and. scb<-tol8)then
2533 [ # # ]: 0 : axes(:,1)=-axes(:,1) ; sca=-sca
2534 [ - - ]: 8 : axes(:,2)=-axes(:,2) ; scb=-scb
2535 : : end if
2536 : : ! Doing this might change the angle between vectors, so that
2537 : : ! the cell is not conventional anymore
2538 : : ! if(sca<-tol8 .and. scc<-tol8)then
2539 : : ! axes(:,1)=-axes(:,1) ; sca=-sca
2540 : : ! axes(:,3)=-axes(:,3) ; scc=-scc
2541 : : ! end if
2542 : : ! if(scb<-tol8 .and. scc<-tol8)then
2543 : : ! axes(:,2)=-axes(:,2) ; scb=-scb
2544 : : ! axes(:,3)=-axes(:,3) ; scc=-scc
2545 : : ! end if
2546 [ + + + + : 32 : length_axis1=NORM2(axes(:,1))
+ - ]
2547 [ + + + + : 32 : length_axis2=NORM2(axes(:,2))
+ + ]
2548 : :
2549 : : ! DEBUG
2550 : : ! write(std_out,*)' testkgrid: iholohedry, center =',iholohedry,center
2551 : : ! write(std_out,*)' testkgrid: axis 1=',axes(:,1)
2552 : : ! write(std_out,*)' testkgrid: axis 2=',axes(:,2)
2553 : : ! write(std_out,*)' testkgrid: axis 3=',axes(:,3)
2554 : : ! write(std_out,*)' testkgrid: length_axis=',length_axis1,length_axis2
2555 : : ! ENDDEBUG
2556 : :
2557 : : ! End special treatment of 2-D case
2558 : : end if
2559 : :
2560 : : !3-dimensional system
2561 [ + + + + ]: 788 : if(sum(vacuum(:))==0)then
2562 : 83 : iholohedry=bravais(1)
2563 : 83 : center=bravais(2)
2564 : 83 : fact=1.0_dp
2565 [ + + ]: 83 : if(center/=0)fact=0.5_dp
2566 [ + + ]: 332 : matrix1(:,1)=bravais(3:5)*fact
2567 [ + + ]: 332 : matrix1(:,2)=bravais(6:8)*fact
2568 [ + + ]: 332 : matrix1(:,3)=bravais(9:11)*fact
2569 : 83 : call matr3inv(matrix1,matrix2)
2570 [ + + ]: 332 : do ii=1,3
2571 [ + + ]: 1079 : axes(:,ii)=rprimd(:,1)*matrix2(ii,1)+rprimd(:,2)*matrix2(ii,2)+rprimd(:,3)*matrix2(ii,3)
2572 : : end do
2573 [ + + + + : 332 : length_axis1 = NORM2(axes(:,1))
+ + ]
2574 [ + + + + : 332 : length_axis2 = NORM2(axes(:,2))
+ + ]
2575 [ + + + + : 332 : length_axis3 = NORM2(axes(:,3))
+ + ]
2576 : : ! DEBUG
2577 : : ! write(std_out,*)' testkgrid: axes=',axes(:,:)
2578 : : ! write(std_out,*)' length_axis=',length_axis1,length_axis2,length_axis3
2579 : : ! ENDDEBUG
2580 : : end if
2581 : :
2582 : : !This routine examine only primitive k lattices.
2583 : 197 : nshiftk=1
2584 : :
2585 : : !If prtkpt/=0, will examine more grids than strictly needed
2586 : 197 : buffer_scale=one
2587 [ + + ]: 197 : if(prtkpt/=0)buffer_scale=two
2588 : :
2589 [ + + ]: 197 : if(prtkpt/=0)then
2590 : 13 : write(msg,'(a,a,a,a,a,a,a,a)' )ch10,&
2591 : 13 : ' testkgrid : will perform the analysis of a series of k-grids.',ch10,&
2592 : 13 : ' Note that kptopt=1 in this analysis, irrespective of its input value.',ch10,ch10,&
2593 : 26 : ' Grid# kptrlatt shiftk kptrlen nkpt iset',ch10
2594 : 13 : call wrtout(std_out,msg)
2595 : 13 : call wrtout(iout,msg)
2596 [ - + ]: 13 : ABI_MALLOC(grid_list,(mkpt_list))
2597 [ - + ]: 13 : ABI_MALLOC(kptrlen_list,(mkpt_list))
2598 [ + + ]: 1300013 : grid_list(:)=0
2599 [ + + ]: 1300013 : kptrlen_list(:)=0.0_dp
2600 : : end if
2601 : :
2602 [ + + + + ]: 788 : if(sum(vacuum(:))==3)then
2603 : :
2604 : 102 : kptrlatt(:,:)=0
2605 : 102 : kptrlatt(1,1)=1
2606 : 102 : kptrlatt(2,2)=1
2607 : 102 : kptrlatt(3,3)=1
2608 [ + + ]: 408 : shiftk(:,1)=0.0_dp
2609 : 102 : kptrlen=1000.0_dp
2610 : 102 : nkpt_current=1
2611 : 102 : igrid_current=1
2612 : :
2613 [ - + ]: 102 : if(prtkpt/=0)then
2614 : : write(msg,&
2615 : : & '(a,3i4,a,es14.4,a,es14.4,i8,i6,a,a,3i4,a,es14.4,a,a,3i4,a,es14.4,a)' )&
2616 : 0 : & ' 1 ',kptrlatt(:,1),' ',shiftk(1,1),' ',kptrlen,1,1,ch10,&
2617 : 0 : & ' ',kptrlatt(:,2),' ',shiftk(2,1),ch10,&
2618 : 0 : & ' ',kptrlatt(:,3),' ',shiftk(3,1),ch10
2619 : 0 : call wrtout(std_out,msg)
2620 : 0 : call wrtout(iout,msg)
2621 : : ! The unit cell volume is fake
2622 : 0 : ucvol=kptrlen**3
2623 : : end if
2624 : :
2625 : : else
2626 : :
2627 : 95 : nkpt=0 ; nkpt_current=0 ; iscf=1 ; iset=1
2628 : 95 : kptrlen_current=0.0_dp
2629 : 95 : mult1=0 ; mult2=0 ; mult3=0 ; init_mult=1
2630 [ - + ]: 95 : ABI_MALLOC(kpt,(3,nkpt))
2631 [ - + ]: 95 : ABI_MALLOC(wtk,(nkpt))
2632 : 95 : call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
2633 : :
2634 : : ! Loop on different grids, the upper limit is only to avoid an infinite loop
2635 [ + - ]: 2054 : do igrid=1,1000
2636 : :
2637 : 2054 : kptrlatt_trial(:,:)=0
2638 : 2054 : kptrlatt_trial(1,1)=1
2639 : 2054 : kptrlatt_trial(2,2)=1
2640 : 2054 : kptrlatt_trial(3,3)=1
2641 [ + + ]: 8216 : shiftk_trial(:,1)=0.0_dp
2642 : :
2643 : : ! 1-dimensional system
2644 [ + + + + ]: 8216 : if(sum(vacuum(:))==2)then
2645 [ + - ]: 6 : if(vacuum(1)==0)then
2646 : 6 : kptrlatt_trial(1,1)=2*igrid ; shiftk_trial(1,1)=0.5_dp
2647 [ # # ]: 0 : else if(vacuum(2)==0)then
2648 : 0 : kptrlatt_trial(2,2)=2*igrid ; shiftk_trial(2,1)=0.5_dp
2649 [ # # ]: 0 : else if(vacuum(3)==0)then
2650 : 0 : kptrlatt_trial(3,3)=2*igrid ; shiftk_trial(3,1)=0.5_dp
2651 : : end if
2652 : : end if
2653 : :
2654 : : ! 2-dimensional system
2655 [ + + + + ]: 8216 : if(sum(vacuum(:))==1)then
2656 : :
2657 : : ! Treat hexagonal holohedries separately
2658 [ + + ]: 342 : if(iholohedry==3)then
2659 : :
2660 : : ! write(std_out,*)' testkgrid: 2D, hexagonal'
2661 : :
2662 : 44 : mult1=mult1+1
2663 : 44 : nset=4
2664 [ + + ]: 44 : if(iset==1)then
2665 [ + + ]: 56 : rsuper(:,1)=axes(:,1)*mult1
2666 [ + + ]: 56 : rsuper(:,2)=axes(:,2)*mult1
2667 [ + + ]: 56 : shiftk_trial(:,1)=0.0_dp
2668 [ + + ]: 30 : else if(iset==2)then
2669 [ + + ]: 32 : rsuper(:,1)=(axes(:,1)-axes(:,2)) *mult1
2670 [ + + ]: 32 : rsuper(:,2)=(axes(:,1)+2*axes(:,2))*mult1
2671 : 8 : shiftk_trial(1,1)=1.0_dp/3.0_dp
2672 : 8 : shiftk_trial(2,1)=1.0_dp/3.0_dp
2673 [ + + ]: 22 : else if(iset==3)then
2674 [ + + ]: 32 : rsuper(:,1)=(axes(:,1)-axes(:,2)) *mult1
2675 [ + + ]: 32 : rsuper(:,2)=(axes(:,1)+2*axes(:,2))*mult1
2676 [ + + ]: 32 : shiftk_trial(:,1)=0.0_dp
2677 [ - + ]: 14 : else if(iset==4)then
2678 [ + + ]: 56 : rsuper(:,1)=axes(:,1)*mult1
2679 [ + + ]: 56 : rsuper(:,2)=axes(:,2)*mult1
2680 : 14 : shiftk_trial(1,1)=0.5_dp
2681 : 14 : shiftk_trial(2,1)=0.5_dp
2682 : : end if
2683 : :
2684 : : else
2685 : : ! Now treat all other holohedries
2686 : 298 : length1=length_axis1*mult1
2687 : 298 : length2=length_axis2*mult2
2688 : : ! write(std_out,*)' testkgrid: (2d) length=',length1,length2
2689 [ + + ]: 298 : if(abs(length1-length2)<tol8)then
2690 : 103 : mult1=mult1+1
2691 : 103 : mult2=mult2+1
2692 [ + + ]: 195 : else if(length1>length2)then
2693 : 85 : mult2=mult2+1
2694 [ + - ]: 110 : else if(length2>length1)then
2695 : 110 : mult1=mult1+1
2696 : : end if
2697 : 298 : nset=4
2698 : : ! iset==5 and 6 are allowed only for centered lattice
2699 [ + + ]: 298 : if(center==1)nset=6
2700 [ + + ]: 298 : if(iset==1 .or. iset==2)then
2701 [ + + ]: 640 : rsuper(:,1)=axes(:,1)*mult1
2702 [ + + ]: 640 : rsuper(:,2)=axes(:,2)*mult2
2703 [ + + ]: 138 : else if(iset==3 .or. iset==4)then
2704 [ + + ]: 460 : rsuper(:,1)=axes(:,1)*mult1-axes(:,2)*mult2
2705 [ + + ]: 460 : rsuper(:,2)=axes(:,1)*mult1+axes(:,2)*mult2
2706 [ + - ]: 23 : else if(iset==5 .or. iset==6)then
2707 [ + + ]: 92 : rsuper(:,1)=axes(:,1)*(mult1-0.5_dp)-axes(:,2)*(mult2-0.5_dp)
2708 [ + + ]: 92 : rsuper(:,2)=axes(:,1)*(mult1-0.5_dp)+axes(:,2)*(mult2-0.5_dp)
2709 : : end if
2710 : : ! This was the easiest way to code all even mult1 and mult2 pairs:
2711 : : ! make separate series for this possibility.
2712 [ + + ]: 298 : if(iset==2 .or. iset==4 .or. iset==6)then
2713 [ + + ]: 404 : rsuper(:,1)=2.0_dp*rsuper(:,1)
2714 [ + + ]: 404 : rsuper(:,2)=2.0_dp*rsuper(:,2)
2715 : : end if
2716 : 298 : shiftk_trial(1,1)=0.5_dp
2717 : 298 : shiftk_trial(2,1)=0.5_dp
2718 : :
2719 : : end if
2720 : :
2721 : : ! Put back the inactive direction
2722 [ + + ]: 342 : if(dirvacuum==1)then
2723 [ + + ]: 56 : rsuper(:,3)=rsuper(:,1)
2724 : 14 : shiftk_trial(3,1)=shiftk_trial(1,1)
2725 [ + + ]: 56 : rsuper(:,1)=rprimd(:,1)
2726 : 14 : shiftk_trial(1,1)=0.0_dp
2727 [ - + ]: 328 : else if(dirvacuum==2)then
2728 [ # # ]: 0 : rsuper(:,3)=rsuper(:,1)
2729 : 0 : shiftk_trial(3,1)=shiftk_trial(1,1)
2730 [ # # ]: 0 : rsuper(:,1)=rsuper(:,2)
2731 : 0 : shiftk_trial(1,1)=shiftk_trial(2,1)
2732 [ # # ]: 0 : rsuper(:,2)=rprimd(:,2)
2733 : 0 : shiftk_trial(2,1)=0.0_dp
2734 : : else if(dirvacuum==3)then
2735 [ + + ]: 1312 : rsuper(:,3)=rprimd(:,3)
2736 : 328 : shiftk_trial(3,1)=0.0_dp
2737 : : end if
2738 : :
2739 : : ! The supercell and the corresponding shift have been generated !
2740 : : ! Convert cartesian coordinates into kptrlatt_trial
2741 [ + + ]: 1368 : do ii=1,3
2742 : : kptrlatt_trial(:,ii)=nint( gprimd(1,:)*rsuper(1,ii)+&
2743 : : & gprimd(2,:)*rsuper(2,ii)+&
2744 [ + + ]: 4446 : & gprimd(3,:)*rsuper(3,ii) )
2745 : : end do
2746 : :
2747 : : ! End of 2-dimensional system
2748 : : end if
2749 : :
2750 : : ! 3-dimensional system
2751 [ + + + + ]: 8216 : if(sum(vacuum(:))==0)then
2752 : : ! Treat hexagonal holohedries separately
2753 [ + + ]: 1706 : if(iholohedry==6)then
2754 : 108 : length1=length_axis1*mult1
2755 : 108 : length3=length_axis3*mult3
2756 : : ! write(std_out,*)' testkgrid: (hex) lengths=',length1,length2
2757 [ + + ]: 108 : if(abs(length1-length3)<tol8)then
2758 : 20 : mult1=mult1+1
2759 : 20 : mult3=mult3+1
2760 [ + + ]: 88 : else if(length1>length3)then
2761 : 44 : mult3=mult3+1
2762 [ + - ]: 44 : else if(length3>length1)then
2763 : 44 : mult1=mult1+1
2764 : : end if
2765 : 108 : nset=4
2766 [ + + ]: 108 : if(iset==1)then
2767 [ + + ]: 100 : rsuper(:,1)=axes(:,1)*mult1
2768 [ + + ]: 100 : rsuper(:,2)=axes(:,2)*mult1
2769 [ + + ]: 100 : rsuper(:,3)=axes(:,3)*mult3
2770 [ + + ]: 100 : shiftk_trial(:,1)=0.0_dp
2771 : 25 : shiftk_trial(3,1)=0.5_dp
2772 [ + + ]: 83 : else if(iset==2)then
2773 [ + + ]: 116 : rsuper(:,1)=(axes(:,1)-axes(:,2)) *mult1
2774 [ + + ]: 116 : rsuper(:,2)=(axes(:,1)+2*axes(:,2))*mult1
2775 [ + + ]: 116 : rsuper(:,3)=axes(:,3)*mult3
2776 : 29 : shiftk_trial(1,1)=1.0_dp/3.0_dp
2777 : 29 : shiftk_trial(2,1)=1.0_dp/3.0_dp
2778 : 29 : shiftk_trial(3,1)=0.5_dp
2779 [ + + ]: 54 : else if(iset==3)then
2780 [ + + ]: 116 : rsuper(:,1)=(axes(:,1)-axes(:,2)) *mult1
2781 [ + + ]: 116 : rsuper(:,2)=(axes(:,1)+2*axes(:,2))*mult1
2782 [ + + ]: 116 : rsuper(:,3)=axes(:,3)*mult3
2783 [ + + ]: 116 : shiftk_trial(:,1)=0.0_dp
2784 : 29 : shiftk_trial(3,1)=0.5_dp
2785 [ - + ]: 25 : else if(iset==4)then
2786 [ + + ]: 100 : rsuper(:,1)=axes(:,1)*mult1
2787 [ + + ]: 100 : rsuper(:,2)=axes(:,2)*mult1
2788 [ + + ]: 100 : rsuper(:,3)=axes(:,3)*mult3
2789 [ + + ]: 100 : shiftk_trial(:,1)=0.5_dp
2790 : : end if
2791 : :
2792 : : else
2793 : : ! Now treat all other holohedries
2794 : 1598 : length1=length_axis1*mult1
2795 : 1598 : length2=length_axis2*mult2
2796 : 1598 : length3=length_axis3*mult3
2797 : : ! write(std_out,*)' testkgrid: length=',length1,length2,length3
2798 [ + + + + ]: 1598 : if(length2>length1+tol8 .and. length3>length1+tol8)then
2799 : 100 : mult1=mult1+1
2800 [ + + + + ]: 1498 : else if(length1>length2+tol8 .and. length3>length2+tol8)then
2801 : 154 : mult2=mult2+1
2802 [ + + + + ]: 1344 : else if(length1>length3+tol8 .and. length2>length3+tol8)then
2803 : 352 : mult3=mult3+1
2804 : : else if(abs(length2-length3)<tol8 .and. &
2805 [ + + + + : 992 : & abs(length1-length3)<tol8 .and. &
+ - ]
2806 : : & abs(length1-length2)<tol8 )then
2807 : 807 : mult1=mult1+1 ; mult2=mult2+1 ; mult3=mult3+1
2808 [ + + ]: 185 : else if(abs(length1-length2)<tol8)then
2809 : 151 : mult1=mult1+1 ; mult2=mult2+1
2810 [ - + ]: 34 : else if(abs(length1-length3)<tol8)then
2811 : 0 : mult1=mult1+1 ; mult3=mult3+1
2812 [ + - ]: 34 : else if(abs(length2-length3)<tol8)then
2813 : 34 : mult2=mult2+1 ; mult3=mult3+1
2814 : : end if
2815 : 1598 : nset=6
2816 [ + + ]: 1598 : if(center==-1 .or. center==-3)nset=8
2817 [ + + ]: 1598 : if(iset==1 .or. iset==2)then
2818 : : ! Simple lattice of k points
2819 [ + + ]: 2080 : rsuper(:,1)=axes(:,1)*mult1
2820 [ + + ]: 2080 : rsuper(:,2)=axes(:,2)*mult2
2821 [ + + ]: 2080 : rsuper(:,3)=axes(:,3)*mult3
2822 [ + + ]: 2080 : shiftk_trial(:,1)=0.5_dp
2823 [ + + ]: 1078 : else if(iset==3 .or. iset==4)then
2824 : : ! FCC lattice of k points = BCC lattice in real space
2825 [ + + ]: 1848 : rsuper(:,1)=-axes(:,1)*mult1+axes(:,2)*mult2+axes(:,3)*mult3
2826 [ + + ]: 1848 : rsuper(:,2)= axes(:,1)*mult1-axes(:,2)*mult2+axes(:,3)*mult3
2827 [ + + ]: 1848 : rsuper(:,3)= axes(:,1)*mult1+axes(:,2)*mult2-axes(:,3)*mult3
2828 [ + + ]: 1848 : shiftk_trial(:,1)=0.5_dp
2829 [ + + ]: 616 : else if(iset==5 .or. iset==6)then
2830 : : ! BCC lattice of k points = FCC lattice in real space
2831 [ + + ]: 2028 : rsuper(:,1)= axes(:,2)*mult2+axes(:,3)*mult3
2832 [ + + ]: 2028 : rsuper(:,2)= axes(:,1)*mult1 +axes(:,3)*mult3
2833 [ + + ]: 2028 : rsuper(:,3)= axes(:,1)*mult1+axes(:,2)*mult2
2834 : : ! The BCC lattice has no empty site with full symmetry
2835 [ + + ]: 2028 : shiftk_trial(:,1)=0.0_dp
2836 [ + - ]: 109 : else if(iset==7 .or. iset==8)then
2837 : : ! iset==7 and 8 are allowed only for centered lattice
2838 : 109 : mult1h=mult1-0.5_dp
2839 : 109 : mult2h=mult2-0.5_dp
2840 : 109 : mult3h=mult3-0.5_dp
2841 [ + + ]: 109 : if(center==-1)then
2842 : : ! FCC lattice of k points = BCC lattice in real space
2843 [ + + ]: 352 : rsuper(:,1)=-axes(:,1)*mult1h+axes(:,2)*mult2h+axes(:,3)*mult3h
2844 [ + + ]: 352 : rsuper(:,2)= axes(:,1)*mult1h-axes(:,2)*mult2h+axes(:,3)*mult3h
2845 [ + + ]: 352 : rsuper(:,3)= axes(:,1)*mult1h+axes(:,2)*mult2h-axes(:,3)*mult3h
2846 [ + + ]: 352 : shiftk_trial(:,1)=0.5_dp
2847 [ + - ]: 21 : else if(center==-3)then
2848 : : ! BCC lattice of k points = FCC lattice in real space
2849 [ + + ]: 84 : rsuper(:,1)= axes(:,2)*mult2h+axes(:,3)*mult3h
2850 [ + + ]: 84 : rsuper(:,2)= axes(:,1)*mult1h +axes(:,3)*mult3h
2851 [ + + ]: 84 : rsuper(:,3)= axes(:,1)*mult1h+axes(:,2)*mult2h
2852 : : ! The BCC lattice has no empty site with full symmetry
2853 [ + + ]: 84 : shiftk_trial(:,1)=0.0_dp
2854 : : end if
2855 : : end if
2856 : : ! This was the easiest way to code all even mult1, mult2, mult3 triplets:
2857 : : ! make separate series for this possibility.
2858 [ + + ]: 1598 : if(2*(iset/2)==iset)then
2859 [ + + ]: 2864 : rsuper(:,1)=2.0_dp*rsuper(:,1)
2860 [ + + ]: 2864 : rsuper(:,2)=2.0_dp*rsuper(:,2)
2861 [ + + ]: 2864 : rsuper(:,3)=2.0_dp*rsuper(:,3)
2862 : : end if
2863 : : end if
2864 : :
2865 : : ! write(std_out,*)' testkgrid: gprimd=',gprimd(:,:)
2866 : : ! write(std_out,*)' testkgrid: rsuper=',rsuper(:,:)
2867 : : ! write(std_out,*)' testkgrid: iset =',iset
2868 : :
2869 : : ! The supercell and the corresponding shift have been generated!
2870 : : ! Convert cartesian coordinates into kptrlatt_trial
2871 [ + + ]: 6824 : do ii=1,3
2872 : : kptrlatt_trial(:,ii)=nint( gprimd(1,:)*rsuper(1,ii)+&
2873 : : & gprimd(2,:)*rsuper(2,ii)+&
2874 [ + + ]: 22178 : & gprimd(3,:)*rsuper(3,ii) )
2875 : : end do
2876 : :
2877 : : ! End of 3-dimensional system
2878 : : end if
2879 : :
2880 : : ! write(std_out,*)' testkgrid: before getkgrid'
2881 : : ! write(std_out,*)' testkgrid: rprimd=',rprimd(:,:)
2882 : : ! write(std_out,*)' testkgrid: kptrlatt_trial=',kptrlatt_trial(:,:)
2883 : :
2884 : : call getkgrid(0,0,iscf,kpt,&
2885 : : & kptopt,kptrlatt_trial,kptrlen_trial,&
2886 : : & msym,nkpt,nkpt_trial,nshiftk,nsym,rprimd,&
2887 : 2054 : & shiftk_trial,symafm,symrel,vacuum,wtk)
2888 : :
2889 : : ! write(std_out,*)' testkgrid: after getkgrid'
2890 : :
2891 : : ! In case one does not need the full list of grids, will take a shortcut, and go to one of the last grids of the series,
2892 : : ! that generates a kptrlen_trial that is just below kptrlen.
2893 [ + + + + : 2054 : if(prtkpt==0 .and. init_mult==1 .and. kptrlen_trial<(half-tol8)*kptrlen )then
+ + ]
2894 : 274 : iscale=int((one-tol8)*kptrlen/kptrlen_trial)
2895 : 274 : mult1=mult1*iscale
2896 : 274 : mult2=mult2*iscale
2897 : 274 : mult3=mult3*iscale
2898 : 274 : init_mult=0
2899 : : ! write(std_out,*)' testkgrid: iscale=',iscale
2900 [ + + + + ]: 3562 : kptrlatt_trial(:,:)=kptrlatt_trial(:,:)*iscale
2901 : : call getkgrid(0,0,iscf,kpt,&
2902 : : & kptopt,kptrlatt_trial,kptrlen_trial,&
2903 : : & msym,nkpt,nkpt_trial,nshiftk,nsym,rprimd,&
2904 : 274 : & shiftk_trial,symafm,symrel,vacuum,wtk)
2905 : : end if
2906 : :
2907 : : if( (kptrlen_trial+tol8>kptrlen*(1.0_dp+tol8) .and. nkpt_current==0) .or. &
2908 [ + + + + : 2054 : & (kptrlen_trial+tol8>kptrlen*(1.0_dp+tol8) .and. nkpt_trial<nkpt_current) .or. &
+ + + + +
+ ]
2909 : : & (nkpt_trial==nkpt_current .and. kptrlen_trial>kptrlen_current*(1.0_dp+tol8)))then
2910 : :
2911 : 181 : kptrlatt_current(:,:)=kptrlatt_trial(:,:)
2912 : 181 : nkpt_current=nkpt_trial
2913 : 181 : shiftk_current(:,:)=shiftk_trial(:,:)
2914 : 181 : kptrlen_current=kptrlen_trial
2915 : 181 : igrid_current=igrid
2916 : : end if
2917 : :
2918 [ + + ]: 2054 : if(prtkpt/=0)then
2919 : : write(msg,'(i5,a,3i4,a,es14.4,a,es14.4,i8,i6,a,a,3i4,a,es14.4,a,a,3i4,a,es14.4,a)' )&
2920 : 788 : & igrid,' ',kptrlatt_trial(:,1),' ',shiftk_trial(1,1),&
2921 : 788 : & ' ',kptrlen_trial,nkpt_trial,iset,ch10,&
2922 : 788 : & ' ',kptrlatt_trial(:,2),' ',shiftk_trial(2,1),ch10,&
2923 : 1576 : & ' ',kptrlatt_trial(:,3),' ',shiftk_trial(3,1),ch10
2924 : 788 : call wrtout(std_out,msg)
2925 : 788 : call wrtout(iout,msg)
2926 : :
2927 : : ! Keep track of this grid, if it is worth
2928 [ + + ]: 788 : if(kptrlen_trial > kptrlen_list(nkpt_trial)*(1.0_dp+tol8))then
2929 : 512 : grid_list(nkpt_trial)=igrid
2930 : 512 : kptrlen_list(nkpt_trial)=kptrlen_trial
2931 : : end if
2932 : : end if
2933 : :
2934 : : ! Treat 1-D case
2935 [ + + + + : 8216 : if( sum(vacuum(:))==2 .and. kptrlen_trial>buffer_scale*(1.0_dp+tol8)*kptrlen )exit
+ + ]
2936 : :
2937 : : ! Treat 2-D case or 3-D case
2938 [ + + + + : 8295 : if( sum(vacuum(:))<=1 .and. kptrlen_trial>buffer_scale*(1.0_dp+tol8)*kptrlen )then
+ + ]
2939 : : ! The present set of sets of k points is finished:
2940 : : ! either it was the last, or one has to go to the next one
2941 [ + + ]: 564 : if(iset==nset)exit
2942 : 473 : iset=iset+1
2943 : 473 : mult1=0 ; mult2=0 ; mult3=0 ; init_mult=1
2944 : : end if
2945 : :
2946 : : end do ! igrid=1,1000
2947 : :
2948 [ - + ]: 95 : ABI_FREE(kpt)
2949 [ - + ]: 95 : ABI_FREE(wtk)
2950 : :
2951 : 95 : kptrlatt(:,:)=kptrlatt_current(:,:)
2952 : 95 : shiftk(:,:)=shiftk_current(:,:)
2953 : 95 : kptrlen=kptrlen_current
2954 : :
2955 : : end if ! test on the number of dimensions
2956 : :
2957 [ + + ]: 197 : if(prtkpt/=0)then
2958 : :
2959 : : ! sqrt(1/2) comes from the FCC packing, the best one
2960 : 13 : factor=sqrt(0.5_dp)/ucvol/dble(nsym)
2961 : 13 : ndims=3
2962 [ + + + + ]: 52 : if(sum(vacuum(:))/=0)then
2963 [ + + + - ]: 24 : if(sum(vacuum(:))==1)then
2964 : : ! sqrt(3/4) comes from the hex packing, the best one
2965 : : ! one multiplies by 2 because nsym is likely twice the number
2966 : : ! of symmetries that can be effectively used in 2D
2967 : 6 : ndims=2 ; factor=sqrt(0.75_dp)/surface/dble(nsym)*2
2968 : 6 : write(msg,'(2a)' )ch10,' Note that the system is bi-dimensional.'
2969 [ # # # # ]: 0 : else if(sum(vacuum(:))==2)then
2970 : 0 : ndims=1 ; factor=1/ucvol
2971 : 0 : write(msg,'(2a)' )ch10,' Note that the system is uni-dimensional.'
2972 [ # # # # ]: 0 : else if(sum(vacuum(:))==3)then
2973 : 0 : ndims=0
2974 : 0 : write(msg,'(2a)' )ch10,' Note that the system is zero-dimensional.'
2975 : : end if
2976 : 6 : call wrtout(std_out,msg)
2977 : 6 : call wrtout(iout,msg)
2978 : : end if
2979 : :
2980 : : ! The asymptotic value of the merit factor is determined
2981 : : ! by the set of symmetries: in 3D, if it includes the
2982 : : ! inversion symmetry, the limit will be 1, if not, it
2983 : : ! will be two. In 2D, if it includes the inversion symmetry
2984 : : ! and an operation that maps z on -z, it will tend to one,
2985 : : ! while if only one of these operations is present,
2986 : : ! it will tend to two, and if none is present, it will tend to four.
2987 : 13 : write(msg,'(11a)' )ch10,&
2988 : 13 : & ' List of best grids, ordered by nkpt.',ch10,&
2989 : 13 : & ' (stop at a value of kptrlen 20% larger than the target value).',ch10,&
2990 : 13 : & ' (the merit factor will tend to one or two in 3 dimensions)',ch10,&
2991 : 13 : & ' (and to one, two or four in 2 dimensions)',ch10,ch10,&
2992 : 26 : & ' nkpt kptrlen grid# merit_factor'
2993 : 13 : call wrtout(std_out,msg)
2994 : 13 : call wrtout(iout,msg)
2995 : :
2996 : 13 : kptrlen_max=0.0_dp
2997 [ + - ]: 347 : do ii=1,mkpt_list
2998 [ + + ]: 347 : if(kptrlen_list(ii)>kptrlen_max*(1.0_dp+tol8))then
2999 : 126 : kptrlen_max=kptrlen_list(ii)
3000 : 126 : merit_factor=kptrlen_max**ndims/dble(ii)*factor
3001 : 126 : write(msg, '(i6,es14.4,i6,f12.4)' )ii,kptrlen_max,grid_list(ii),merit_factor
3002 : 126 : call wrtout(std_out,msg)
3003 : 126 : call wrtout(iout,msg)
3004 : : end if
3005 [ + + ]: 347 : if(kptrlen_max>1.2_dp*(1.0_dp-tol8)*kptrlen_target)exit
3006 : : end do
3007 : :
3008 : 13 : write(msg,'(a,a,es14.4,a,a,i6,a,a,a,es14.4,a,i6)' )ch10,&
3009 : 13 : & ' For target kptrlen=',kptrlen_target,',',&
3010 : 13 : & ' the selected grid is number',igrid_current,',',ch10,&
3011 : 26 : & ' giving kptrlen=',kptrlen_current,' with nkpt=',nkpt_current
3012 : 13 : call wrtout(std_out,msg)
3013 : 13 : call wrtout(iout,msg)
3014 : :
3015 : 13 : write(msg,'(a,a,a,a)' )ch10,&
3016 : 13 : & ' testkgrid : stop after analysis of a series of k-grids.',ch10,&
3017 : 26 : & ' For usual production runs, set prtkpt back to 0 (the default).'
3018 : 13 : call wrtout(std_out,msg, do_flush=.True.)
3019 : 13 : call wrtout(iout,msg, do_flush=.True.)
3020 : :
3021 : 13 : call abi_abort('PERS', exit_status=0, print_config=.false.)
3022 : : end if
3023 : :
3024 [ - + - + ]: 184 : end subroutine testkgrid
3025 : : !!***
3026 : :
3027 : : !!****f* m_kpts/mknormpath
3028 : : !! NAME
3029 : : !! mknormpath
3030 : : !!
3031 : : !! FUNCTION
3032 : : !! Please do not use this routine, use make_normpath instead.
3033 : : !! mknormpath should be removed
3034 : : !!
3035 : : !! This simple routine generates a normalized path that can be used to plot a band
3036 : : !! structures in an easy way. For normalized path we mean a path where the number
3037 : : !! of division on each segment is proportional to the length of the segment itself.
3038 : : !! To generate the above mentioned path, the subroutine must be called twice.
3039 : : !! The first call reports the total number of divisions in the normalized path, dimension
3040 : : !! that is required to correctly allocate the array.
3041 : : !! The second call calculates the reduced coordinates of the circuit.
3042 : : !!
3043 : : !! INPUTS
3044 : : !! nbounds=number of points defining the path
3045 : : !! ndiv_small=number of points to be used to sample the smallest
3046 : : !! segment defined by bounds(:,1:nbounds)
3047 : : !! bounds(3,nbounds)=points defining the path
3048 : : !! gmet(3,3)=metric
3049 : : !!
3050 : : !! OUTPUT
3051 : : !! ndiv(nbounds-1)= number of divisions for each segment
3052 : : !! npt_tot=total number of points sampled along the circuit
3053 : : !! path(3,npt_tot)= normalized path in reciprocal space
3054 : : !!
3055 : : !! TODO
3056 : : !! Do not use this routine, it is obsolete and should be replaced by make_path in m_bz_mesh.
3057 : : !!
3058 : : !! SOURCE
3059 : :
3060 : 70 : subroutine mknormpath(nbounds,bounds,gmet,ndiv_small,ndiv,npt_tot,path)
3061 : :
3062 : : !Arguments ------------------------------------
3063 : : !scalars
3064 : : integer,intent(in) :: nbounds,ndiv_small
3065 : : integer,intent(inout) :: npt_tot
3066 : : !arrays
3067 : : integer,intent(inout) :: ndiv(nbounds-1)
3068 : : real(dp),intent(in) :: bounds(3,nbounds),gmet(3,3)
3069 : : real(dp),intent(out),optional :: path(3,npt_tot)
3070 : :
3071 : : !Local variables-------------------------------
3072 : : !scalars
3073 : : integer :: idx,ii,jp
3074 : : real(dp) :: fct
3075 : : character(len=500) :: msg
3076 : : !arrays
3077 : 140 : real(dp) :: dd(3),lng(nbounds-1)
3078 : : ! *************************************************************************
3079 : :
3080 [ - + ]: 70 : if (ndiv_small<=0) then
3081 : : write(msg,'(3a,i0)')&
3082 : 0 : 'The argument ndiv_small should be a positive number,',ch10,&
3083 : 0 : 'however, ndiv_small=',ndiv_small
3084 : 0 : ABI_ERROR(msg)
3085 : : end if
3086 : :
3087 [ + + ]: 586 : do ii=1,nbounds-1
3088 [ + + ]: 2064 : dd(:)=bounds(:,ii+1)-bounds(:,ii)
3089 : : lng(ii)= sqrt( dd(1)*gmet(1,1)*dd(1)+ &
3090 : : & dd(2)*gmet(2,2)*dd(2)+ &
3091 : : & dd(3)*gmet(3,3)*dd(3)+ &
3092 : : & 2.0d0*(dd(1)*gmet(1,2)*dd(2)+ &
3093 : : & dd(1)*gmet(1,3)*dd(3)+ &
3094 : : & dd(2)*gmet(2,3)*dd(3)) &
3095 : 586 : & )
3096 : : end do
3097 : 70 : write(std_out,*)lng
3098 [ + - - + : 656 : fct=minval(lng)
- - + + ]
3099 : :
3100 : : ! Avoid division by zero if k(:,i+1)=k(:,i)
3101 [ - + ]: 70 : if (abs(fct)<tol6) then
3102 : : write(msg,'(3a)')&
3103 : 0 : 'found two consecutive points in the path which are equal',ch10,&
3104 : 0 : 'This is not allowed, please modify the path in your input file'
3105 : 0 : ABI_ERROR(msg)
3106 : : end if
3107 : :
3108 : 70 : fct=fct/ndiv_small
3109 [ + + ]: 586 : ndiv(:)=nint(lng(:)/fct)
3110 : : ! The 1 stand for the first point
3111 [ + + ]: 586 : npt_tot=sum(ndiv)+1
3112 : :
3113 [ + - ]: 70 : if (.not.present(path)) then
3114 : 70 : write(msg,'(2a,i0)')ch10,' mknormpath : total number of points on the path: ',npt_tot
3115 : 70 : call wrtout(std_out,msg)
3116 : 70 : write(msg,'(2a)')ch10,' Number of divisions for each segment of the normalized path: '
3117 : 70 : call wrtout(std_out,msg)
3118 [ + + ]: 586 : do ii=1,nbounds-1
3119 : : write(msg,'(2(3f8.5,a),i5,a)')&
3120 : 516 : bounds(:,ii),' ==> ',bounds(:,ii+1),' ( ndiv: ',ndiv(ii),' )'
3121 : 586 : call wrtout(std_out,msg)
3122 : : end do
3123 : 70 : write(msg,'(a)')ch10
3124 : 70 : call wrtout(std_out,msg)
3125 : : else
3126 : 0 : write(msg,'(2a)')ch10,' Normalized Path: '
3127 : 0 : call wrtout(std_out,msg)
3128 : 0 : idx=1
3129 [ # # ]: 0 : do ii=1,nbounds-1
3130 [ # # ]: 0 : do jp=1,ndiv(ii)
3131 [ # # ]: 0 : path(:,idx)=bounds(:,ii)+(jp-1)*(path(:,ii+1)-path(:,ii))/ndiv(ii)
3132 : 0 : write(msg,'(i4,4x,3(f8.5,1x))')idx,path(:,idx)
3133 : 0 : call wrtout(std_out,msg)
3134 : 0 : idx=idx+1
3135 : : end do
3136 : : end do
3137 : : end if
3138 : :
3139 : 70 : end subroutine mknormpath
3140 : : !!***
3141 : :
3142 : : !!****f* m_kpts/bzlint_init
3143 : : !! NAME
3144 : : !! bzlint_init
3145 : : !!
3146 : : !! FUNCTION
3147 : : !!
3148 : : !! INPUTS
3149 : : !!
3150 : : !! OUTPUT
3151 : : !!
3152 : : !! SOURCE
3153 : :
3154 : 0 : subroutine bzlint_init(self, ngkpt, ndat, nkpt, kpts, values)
3155 : :
3156 : : !Arguments ------------------------------------
3157 : : class(bzlint_t),intent(inout) :: self
3158 : : integer,intent(in) :: ngkpt(3), ndat, nkpt
3159 : : real(dp),intent(in) :: kpts(3,nkpt), values(ndat, nkpt)
3160 : :
3161 : : !Local variables-------------------------------
3162 : : integer :: ik, ix, iy, iz, inds(3)
3163 : : real(dp) :: kpt_wrap(3), shift(3)
3164 : : ! *********************************************************************
3165 : :
3166 [ # # ]: 0 : self%ngkpt = ngkpt; self%ndat = ndat
3167 : : ! The mesh is closed i.e. periodic images are included.
3168 : 0 : self%nx = ngkpt(1); self%ny = ngkpt(2); self%nz = ngkpt(3)
3169 [ # # # # : 0 : ABI_CALLOC(self%vals_grid, (self%nx, self%ny, self%nz, ndat))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
3170 : :
3171 : : ! Insert values in the grid.
3172 [ # # ]: 0 : do ik=1,nkpt
3173 [ # # ]: 0 : call wrap2_zero_one(kpts(:,ik), kpt_wrap, shift)
3174 [ # # ]: 0 : inds = nint(kpt_wrap * self%ngkpt)
3175 : : ! here we need to shift the indices by 1 (since Fortran people like to count starting from 1 (: )
3176 : 0 : ix = inds(1) + 1; iy = inds(2) + 1; iz = inds(3) + 1
3177 [ # # ]: 0 : self%vals_grid(ix,iy,iz,:) = values(:, ik)
3178 : : end do
3179 : :
3180 : 0 : end subroutine bzlint_init
3181 : : !!***
3182 : :
3183 : : !!****f* m_kpts/bzlint_interp
3184 : : !! NAME
3185 : : !! bzlint_interp
3186 : : !!
3187 : : !! FUNCTION
3188 : : !! Interpolate values at kpt
3189 : : !!
3190 : : !! SOURCE
3191 : :
3192 : 0 : subroutine bzlint_interp(self, kpt, results)
3193 : :
3194 : : !Arguments ------------------------------------
3195 : : class(bzlint_t),intent(in) :: self
3196 : : real(dp),intent(in) :: kpt(3)
3197 : : real(dp),intent(out) :: results(self%ndat)
3198 : :
3199 : : !Local variables-------------------------------
3200 : : integer :: idat
3201 : : real(dp) :: kpt_wrap(3), shift(3)
3202 : : ! *********************************************************************
3203 : :
3204 [ # # ]: 0 : call wrap2_zero_one(kpt, kpt_wrap, shift)
3205 [ # # ]: 0 : do idat=1,self%ndat
3206 : 0 : results(idat) = interpol3d_0d(kpt_wrap, self%nx, self%ny, self%nz, self%vals_grid(:,:,:,idat))
3207 : : end do
3208 : :
3209 : 0 : end subroutine bzlint_interp
3210 : : !!***
3211 : :
3212 : : !!****f* m_kpts/bzlint_free
3213 : : !! NAME
3214 : : !! bzlint_free
3215 : : !!
3216 : : !! FUNCTION
3217 : : !! Free dynamic memory
3218 : : !!
3219 : : !! SOURCE
3220 : :
3221 : 0 : subroutine bzlint_free(self)
3222 : :
3223 : : !Arguments ------------------------------------
3224 : : class(bzlint_t),intent(inout) :: self
3225 : : ! *********************************************************************
3226 : :
3227 [ # # ]: 0 : ABI_SFREE(self%vals_grid)
3228 : :
3229 : 0 : end subroutine bzlint_free
3230 : : !!***
3231 : :
3232 : : !!****f* m_kpts/kptrlatt_from_ngkpt
3233 : : !! NAME
3234 : : !! kptrlatt_from_ngkpt
3235 : : !!
3236 : : !! FUNCTION
3237 : : !! Insert ngkpt in kptrlatt 3x3 array
3238 : : !!
3239 : : !! SOURCE
3240 : :
3241 : 4 : pure subroutine kptrlatt_from_ngkpt(ngkpt, kptrlatt)
3242 : :
3243 : : !Arguments ------------------------------------
3244 : : integer,intent(in) :: ngkpt(3)
3245 : : integer,intent(out) :: kptrlatt(3,3)
3246 : :
3247 : : !Local variables-------------------------------
3248 : : integer :: ii
3249 : : !************************************************************************
3250 : :
3251 : 4 : kptrlatt = 0
3252 [ + + ]: 16 : do ii=1,3
3253 : 16 : kptrlatt(ii,ii) = ngkpt(ii)
3254 : : end do
3255 : :
3256 : 4 : end subroutine kptrlatt_from_ngkpt
3257 : : !!***
3258 : :
3259 : : !----------------------------------------------------------------------
3260 : :
3261 : : !!****f* m_kpts/kptrlatt_from_brav_ngqpt
3262 : : !! NAME
3263 : : !! kptrlatt_from_brav_ngqpt
3264 : : !!
3265 : : !! FUNCTION
3266 : : !! Build the kptrlatt matrix that reproduces, via smpbz's general
3267 : : !! (brav==1) Monkhorst-Pack enumeration, the same q/k-point set that
3268 : : !! smpbz's brav==2/3/4 branches produce directly. This lets any caller
3269 : : !! use brav==1 unconditionally (smpbz's brav==2/3/4 branches are legacy,
3270 : : !! hard-coded shortcuts for diagonal, cubic-equal ngqpt -- the general
3271 : : !! branch already handles any Bravais lattice, provided the caller feeds
3272 : : !! it the right kptrlatt; see getkgrid_low, which already always calls
3273 : : !! smpbz with brav=1 for exactly this reason).
3274 : : !!
3275 : : !! The brav==2 (FCC) and brav==3 (BCC) formulas below were derived and
3276 : : !! verified numerically (not just algebraically): a standalone replica of
3277 : : !! both smpbz branches was checked to produce the identical set of
3278 : : !! q-points (not just the same count) for several (ngqpt, shiftk)
3279 : : !! combinations, using the standard half-integer shift (0.5,0.5,0.5) that
3280 : : !! every actual anaddb/a-TDEP brav==2/3/4 input uses. They are not
3281 : : !! verified to reproduce brav==2/3's legacy output for shiftk=(0,0,0):
3282 : : !! that edge case depends on hard-coded epsilon tie-breaking for points
3283 : : !! sitting exactly on the Wigner-Seitz boundary in the legacy algorithm,
3284 : : !! which is not reproduced here.
3285 : : !!
3286 : : !! The FCC/BCC "conventional cell doubling" construction (half=ngqpt(1)/2)
3287 : : !! requires ngqpt(1) even and >=2: it has no non-degenerate integer
3288 : : !! representation for ngqpt(1)<2 (only possible value: 1). Callers must
3289 : : !! route that case to kpts_degenerate_fcc_bcc instead (see there for why:
3290 : : !! in short, no integer kptrlatt can both have determinant 1 -- needed for
3291 : : !! a single output point -- and encode FCC/BCC periodicity, which requires
3292 : : !! determinant >=4). This function must not be called with ngqpt(1)<2 and
3293 : : !! abs(brav) in {2,3}.
3294 : : !!
3295 : : !! INPUTS
3296 : : !! brav = 1 or -1 -> simple lattice; 2 -> face-centered cubic;
3297 : : !! 3 -> body-centered lattice; 4 -> hexagonal lattice (D6h)
3298 : : !! ngqpt(3) = Monkhorst-Pack-like divisions, as historically passed to
3299 : : !! smpbz's former brav==2/3/4 branches (must be equal, and even, for
3300 : : !! brav==2/3).
3301 : : !!
3302 : : !! OUTPUT
3303 : : !! kptrlatt(3,3) = integer matrix to feed to smpbz (now always brav==1).
3304 : : !!
3305 : : !! SOURCE
3306 : :
3307 [ - + ]: 224 : pure function kptrlatt_from_brav_ngqpt(brav, ngqpt) result(kptrlatt)
3308 : :
3309 : : !Arguments ------------------------------------
3310 : : integer,intent(in) :: brav
3311 : : integer,intent(in) :: ngqpt(3)
3312 : : integer :: kptrlatt(3,3)
3313 : :
3314 : : !Local variables-------------------------------
3315 : : integer :: half
3316 : :
3317 : : ! *********************************************************************
3318 : :
3319 : 241 : select case (abs(brav))
3320 : : case (2)
3321 : 17 : half = ngqpt(1) / 2
3322 [ + + ]: 170 : kptrlatt = reshape([-half, half, half, half, -half, half, half, half, -half], [3,3])
3323 : : case (3)
3324 : 0 : half = ngqpt(1) / 2
3325 [ # # ]: 0 : kptrlatt = reshape([0, half, half, half, 0, half, half, half, 0], [3,3])
3326 : : case default
3327 : : ! brav==1 or brav==4: plain diagonal Monkhorst-Pack grid.
3328 [ + + + + ]: 2691 : kptrlatt = 0
3329 [ + + - ]: 431 : kptrlatt(1,1) = ngqpt(1); kptrlatt(2,2) = ngqpt(2); kptrlatt(3,3) = ngqpt(3)
3330 : : end select
3331 : :
3332 : 224 : end function kptrlatt_from_brav_ngqpt
3333 : : !!***
3334 : :
3335 : : !----------------------------------------------------------------------
3336 : :
3337 : : !!****f* m_kpts/kpts_degenerate_fcc_bcc
3338 : : !! NAME
3339 : : !! kpts_degenerate_fcc_bcc
3340 : : !!
3341 : : !! FUNCTION
3342 : : !! Handle the one q-mesh density that smpbz's general Monkhorst-Pack
3343 : : !! algorithm cannot represent for FCC (brav==2) or BCC (brav==3):
3344 : : !! ngqpt(1)<2 (only possible value: 1), where the caller compensates the
3345 : : !! too-coarse conventional-cell density via nshiftk (nshiftk=2 or 4, the
3346 : : !! only other values ABINIT's input parser allows). There is no integer
3347 : : !! kptrlatt reproducing this case: the smallest non-degenerate FCC/BCC-
3348 : : !! shaped kptrlatt already has determinant 4 (FCC) or 8 (BCC) -- i.e.
3349 : : !! samples that many conventional-cell points -- so a mesh producing a
3350 : : !! single point can never be expressed as (kptrlatt, shiftk) fed to the
3351 : : !! general algorithm, for ANY kptrlatt: getting down to 1 output point
3352 : : !! with nshiftk=1 needs determinant 1 (unimodular, i.e. no folding at all,
3353 : : !! which cannot simultaneously encode FCC/BCC periodicity), and feeding
3354 : : !! nshiftk>1 unchanged to the general algorithm just enumerates nshiftk
3355 : : !! raw, undeduplicated points instead of reducing them through that
3356 : : !! periodicity. Verified numerically that this is not merely a missing
3357 : : !! formula: unlike the "just fall back to a plain diagonal grid" idea
3358 : : !! (which is safe for every other purpose in this module), the plain
3359 : : !! diagonal grid genuinely computes at a spurious, physically-redundant
3360 : : !! extra q-point that DDB test fixtures built around the legacy answer do
3361 : : !! not contain data for -- so this must reproduce the legacy answer
3362 : : !! exactly, not just "some valid answer".
3363 : : !!
3364 : : !! Since ngqpt is 1 in every direction here, the (ii,jj,kk) loop the
3365 : : !! legacy brav==2/3 algorithm used is trivial (always visits (1,1,1)), so
3366 : : !! only the per-shift Wigner-Seitz-like reduction below is needed -- a
3367 : : !! handful of lines, not smpbz's former legacy machinery, and reachable
3368 : : !! only for this one narrow, structural precondition.
3369 : : !!
3370 : : !! INPUTS
3371 : : !! brav = 2 (face-centered) or 3 (body-centered)
3372 : : !! iout, option, prtout = as in smpbz (option/=0 prints the point list,
3373 : : !! same format smpbz itself uses, so callers see identical output
3374 : : !! whether they are routed through smpbz or through this routine).
3375 : : !! nshiftk, shiftk(3,nshiftk) = as in smpbz
3376 : : !!
3377 : : !! OUTPUT
3378 : : !! nkpt = number of surviving q-points (<=nshiftk)
3379 : : !! spkpt(3,nshiftk) = the nkpt first columns hold the surviving q-points
3380 : : !!
3381 : : !! SOURCE
3382 : :
3383 : 1 : subroutine kpts_degenerate_fcc_bcc(brav, iout, nshiftk, shiftk, option, nkpt, spkpt, prtout)
3384 : :
3385 : : !Arguments ------------------------------------
3386 : : integer,intent(in) :: brav, iout, nshiftk, option
3387 : : integer,intent(out) :: nkpt
3388 : : logical,optional,intent(in) :: prtout
3389 : : real(dp),intent(in) :: shiftk(3,nshiftk)
3390 : : real(dp),intent(out) :: spkpt(3,nshiftk)
3391 : :
3392 : : !Local variables-------------------------------
3393 : : integer :: ii, ikshft
3394 : : logical :: prtout_
3395 : : real(dp) :: shift
3396 : : real(dp) :: k2(3), kcar(3), ktest(3)
3397 : : character(len=500) :: msg
3398 : :
3399 : : ! *********************************************************************
3400 : :
3401 : 1 : prtout_ = .true.
3402 [ - + ]: 1 : if (present(prtout)) prtout_ = prtout
3403 : :
3404 [ - + ]: 1 : if (option/=0) then
3405 [ # # ]: 0 : if (prtout_) call wrtout(iout,' Homogeneous q point set in the B.Z. ')
3406 : : end if
3407 : :
3408 : 1 : nkpt = 0
3409 [ + + ]: 3 : do ikshft=1,nshiftk
3410 : 2 : call wrap2_pmhalf(shiftk(1,ikshft),k2(1),shift)
3411 : 2 : call wrap2_pmhalf(shiftk(2,ikshft),k2(2),shift)
3412 : 2 : call wrap2_pmhalf(shiftk(3,ikshft),k2(3),shift)
3413 : 2 : ktest(1)=2*k2(1)-1.0d-10
3414 : 2 : ktest(2)=2*k2(2)-2.0d-10
3415 : 2 : ktest(3)=2*k2(3)-5.0d-10
3416 : :
3417 [ + - ]: 2 : if (abs(brav) == 2) then
3418 : : ! Test whether it is inside the FCC BZ.
3419 [ + + + + ]: 8 : if (sum(abs(ktest)) >= 1.5_dp) cycle
3420 : : else
3421 : : ! Test whether it is inside the BCC BZ.
3422 [ # # ]: 0 : if (abs(ktest(1))+abs(ktest(2)) >= one) cycle
3423 [ # # ]: 0 : if (abs(ktest(1))+abs(ktest(3)) >= one) cycle
3424 [ # # ]: 0 : if (abs(ktest(2))+abs(ktest(3)) >= one) cycle
3425 : : end if
3426 : :
3427 : 1 : kcar(1)=ktest(1)+1.0d-10
3428 : 1 : kcar(2)=ktest(2)+2.0d-10
3429 : 1 : kcar(3)=ktest(3)+5.0d-10
3430 : 1 : nkpt = nkpt+1
3431 [ + - ]: 2 : if (abs(brav) == 2) then
3432 : 1 : spkpt(1,nkpt) = 0.5_dp*kcar(2)+0.5_dp*kcar(3)
3433 : 1 : spkpt(2,nkpt) = 0.5_dp*kcar(1)+0.5_dp*kcar(3)
3434 : 1 : spkpt(3,nkpt) = 0.5_dp*kcar(1)+0.5_dp*kcar(2)
3435 : : else
3436 : 0 : spkpt(1,nkpt) = -0.5_dp*kcar(1)+0.5_dp*kcar(2)+0.5_dp*kcar(3)
3437 : 0 : spkpt(2,nkpt) = 0.5_dp*kcar(1)-0.5_dp*kcar(2)+0.5_dp*kcar(3)
3438 : 0 : spkpt(3,nkpt) = 0.5_dp*kcar(1)+0.5_dp*kcar(2)-0.5_dp*kcar(3)
3439 : : end if
3440 : : end do
3441 : :
3442 [ - + ]: 1 : if (option/=0) then
3443 : : ! Put the Gamma point first
3444 [ # # ]: 0 : if (nkpt>1) then
3445 [ # # ]: 0 : do ii=1,nkpt
3446 [ # # # # ]: 0 : if (sum(abs(spkpt(:,ii)))<tol8) then
3447 [ # # ]: 0 : spkpt(:,ii)=spkpt(:,1)
3448 [ # # ]: 0 : spkpt(:,1)=zero
3449 : : exit
3450 : : end if
3451 : : end do
3452 : : end if
3453 : :
3454 [ # # ]: 0 : if (prtout_) then
3455 : 0 : write(msg,'(a,i8)')' Grid q points : ',nkpt
3456 : 0 : call wrtout(iout,msg)
3457 [ # # ]: 0 : do ii=1,nkpt
3458 : 0 : write(msg, '(1x,i2,a2,3es16.8)' )ii,') ',spkpt(1,ii),spkpt(2,ii),spkpt(3,ii)
3459 : 0 : call wrtout(iout,msg)
3460 : : end do
3461 : : end if
3462 : : end if
3463 : :
3464 : 1 : end subroutine kpts_degenerate_fcc_bcc
3465 : : !!***
3466 : :
3467 : : !----------------------------------------------------------------------
3468 : :
3469 : : !!****f* m_kpts/qmesh_from_brav_ngqpt
3470 : : !! NAME
3471 : : !! qmesh_from_brav_ngqpt
3472 : : !!
3473 : : !! FUNCTION
3474 : : !! Translate the historical anaddb-style q-mesh specification (brav, ngqpt,
3475 : : !! nshiftk, shiftk) into a brav-independent one (kptrlatt, nshiftk_out,
3476 : : !! shiftk_out) that smpbz, ifc_init and the like can consume directly.
3477 : : !! Everything is delegated to kptrlatt_from_brav_ngqpt, except the FCC/BCC
3478 : : !! case ngqpt(1)<2, which has no integer kptrlatt: it is reduced to
3479 : : !! kptrlatt=identity plus the (one or few) q points that survive
3480 : : !! kpts_degenerate_fcc_bcc, used as shifts.
3481 : : !!
3482 : : !! INPUTS
3483 : : !! brav, ngqpt(3), nshiftk, shiftk(3,nshiftk)= historical specification.
3484 : : !!
3485 : : !! OUTPUT
3486 : : !! kptrlatt(3,3), nshiftk_out<=nshiftk, shiftk_out(3,nshiftk)=first nshiftk_out columns are used.
3487 : : !!
3488 : : !! SOURCE
3489 : :
3490 : 225 : subroutine qmesh_from_brav_ngqpt(brav, ngqpt, nshiftk, shiftk, kptrlatt, nshiftk_out, shiftk_out)
3491 : :
3492 : : !Arguments ------------------------------------
3493 : : integer,intent(in) :: brav, ngqpt(3), nshiftk
3494 : : real(dp),intent(in) :: shiftk(3,nshiftk)
3495 : : integer,intent(out) :: kptrlatt(3,3), nshiftk_out
3496 : : real(dp),intent(out) :: shiftk_out(3,nshiftk)
3497 : :
3498 : : !Local variables-------------------------------
3499 : : integer :: ii
3500 : 225 : real(dp) :: pts(3,nshiftk)
3501 : : character(len=500) :: msg
3502 : :
3503 : : ! *********************************************************************
3504 : :
3505 [ + + + + ]: 1181 : shiftk_out = zero
3506 [ + + + + ]: 225 : if (abs(brav) >= 2 .and. abs(brav) <= 3 .and. ngqpt(1) < 2) then
3507 : 1 : call kpts_degenerate_fcc_bcc(brav, 0, nshiftk, shiftk, 0, nshiftk_out, pts)
3508 [ - + ]: 1 : if (nshiftk_out == 0) then
3509 : 0 : write(msg,'(a,i0,a,3(i0,1x),a,i0,3a)') 'brav=',brav,', ngqpt=',ngqpt,', nshiftk=',nshiftk,&
3510 : 0 : ' selects no q point.',ch10,'Action: increase ngqpt, or use nshiftk=2 (or 4) with ngqpt=1.'
3511 : 0 : ABI_ERROR(msg)
3512 : : end if
3513 : 1 : kptrlatt = 0
3514 [ + + ]: 4 : do ii=1,3
3515 : 4 : kptrlatt(ii,ii) = 1
3516 : : end do
3517 [ + + + + ]: 5 : shiftk_out(:,1:nshiftk_out) = pts(:,1:nshiftk_out)
3518 : : else
3519 : 224 : kptrlatt = kptrlatt_from_brav_ngqpt(brav, ngqpt)
3520 : 224 : nshiftk_out = nshiftk
3521 [ + + + + ]: 1172 : shiftk_out = shiftk
3522 : : end if
3523 : :
3524 : 225 : end subroutine qmesh_from_brav_ngqpt
3525 : : !!***
3526 : :
3527 : : !----------------------------------------------------------------------
3528 : :
3529 : : !!****f* m_kpts/kptrlatt_merge_shifts
3530 : : !! NAME
3531 : : !! kptrlatt_merge_shifts
3532 : : !!
3533 : : !! FUNCTION
3534 : : !! The q-points generated by (kptrlatt, nshiftk, shiftk) are the union of
3535 : : !! nshiftk cosets of the lattice L dual to the supercell lattice S generated
3536 : : !! by the columns of kptrlatt. When this union is itself one coset of a finer
3537 : : !! lattice L', return the matrix of the coarser supercell S' dual to L'
3538 : : !! (columns = primitive vectors of S', in units of the unit cell vectors),
3539 : : !! which is the Born-von Karman box that Fourier-transforms these q-points
3540 : : !! to real space without aliasing. S' is the sublattice {K m: m.(s_j-s_1) integer}.
3541 : : !!
3542 : : !! It is an error if the union is not a single coset (nshiftk shifts must
3543 : : !! generate a group of exactly nshiftk elements modulo L).
3544 : : !!
3545 : : !! INPUTS
3546 : : !! kptrlatt(3,3), nshiftk, shiftk(3,nshiftk)
3547 : : !!
3548 : : !! OUTPUT
3549 : : !! sc_kptrlatt(3,3)= merged matrix, columns being the supercell vectors.
3550 : : !!
3551 : : !! SOURCE
3552 : :
3553 : 201 : subroutine kptrlatt_merge_shifts(kptrlatt, nshiftk, shiftk, sc_kptrlatt)
3554 : :
3555 : : !Arguments ------------------------------------
3556 : : integer,intent(in) :: kptrlatt(3,3), nshiftk
3557 : : real(dp),intent(in) :: shiftk(3,nshiftk)
3558 : : integer,intent(out) :: sc_kptrlatt(3,3)
3559 : :
3560 : : !Local variables-------------------------------
3561 : : integer :: dd, ii, jj, ic, m1, m2, m3, qq, nin, ncosets, mm(3), bas(3,3), ww(3), tmp(3)
3562 : 201 : integer,allocatable :: aa(:,:)
3563 : : logical :: ok
3564 : : character(len=2000) :: msg
3565 : : character(len=200) :: line
3566 : :
3567 : : ! *********************************************************************
3568 : :
3569 [ + + ]: 201 : if (nshiftk == 1) then
3570 : 196 : sc_kptrlatt = kptrlatt
3571 : : return
3572 : : end if
3573 : :
3574 : : ! Common denominator dd such that dd*(s_j - s_1) is integer.
3575 [ - + + - : 15 : ABI_MALLOC(aa,(3,nshiftk))
+ - + - -
+ - + ]
3576 : 5 : ok = .false.
3577 [ + - ]: 10 : do dd=1,12
3578 : 10 : ok = .true.
3579 [ + + ]: 36 : do jj=2,nshiftk
3580 [ + + + + : 79 : if (any(abs(dd*(shiftk(:,jj)-shiftk(:,1)) - nint(dd*(shiftk(:,jj)-shiftk(:,1)))) > tol6)) ok = .false.
+ + ]
3581 : : end do
3582 [ + + ]: 10 : if (ok) exit
3583 : : end do
3584 [ - + ]: 5 : if (.not. ok) then
3585 : 0 : ABI_ERROR("The q-point shifts are not rational with a small denominator, cannot build a supercell for them.")
3586 : : end if
3587 [ + + ]: 18 : do jj=2,nshiftk
3588 [ + + ]: 57 : aa(:,jj) = nint(dd*(shiftk(:,jj)-shiftk(:,1)))
3589 : : end do
3590 : :
3591 : : ! Lattice M' = {m in Z^3: m.aa_j = 0 mod dd for all j}, contains dd*Z^3.
3592 : : ! Build a basis of M' (columns of bas, with zeros above the diagonal) by adding its vectors
3593 : : ! in [0,dd)^3 one by one, and count them: M'/dd*Z^3 has nin elements, so the shifts
3594 : : ! generate ncosets = dd**3/nin cosets of the q-mesh, which must also be det(bas).
3595 : 5 : bas = zero
3596 [ + + ]: 20 : do ii=1,3
3597 : 20 : bas(ii,ii) = dd
3598 : : end do
3599 : 5 : nin = 0
3600 [ + + ]: 15 : do m3=0,dd-1
3601 [ + + ]: 35 : do m2=0,dd-1
3602 [ + + ]: 70 : do m1=0,dd-1
3603 [ + + ]: 160 : mm = [m1,m2,m3]
3604 : 40 : ok = .true.
3605 [ + + ]: 144 : do jj=2,nshiftk
3606 [ + + + + ]: 456 : if (modulo(sum(mm*aa(:,jj)), dd) /= 0) ok = .false.
3607 : : end do
3608 [ + + ]: 40 : if (.not. ok) cycle
3609 : 12 : nin = nin + 1
3610 : : ! Add mm to the lattice spanned by bas with the Euclidean algorithm, column by column.
3611 : 12 : ww = mm
3612 [ + + ]: 68 : do ic=1,3
3613 [ + + ]: 55 : do while (ww(ic) /= 0)
3614 : 19 : qq = bas(ic,ic) / ww(ic)
3615 [ + + ]: 76 : tmp = bas(:,ic) - qq*ww
3616 [ + + ]: 76 : bas(:,ic) = ww
3617 : 19 : ww = tmp
3618 : : end do
3619 [ + + + + ]: 106 : if (bas(ic,ic) < 0) bas(:,ic) = -bas(:,ic)
3620 : : end do
3621 : : end do
3622 : : end do
3623 : : end do
3624 [ - + ]: 5 : ABI_FREE(aa)
3625 : :
3626 : 5 : ncosets = dd**3 / nin
3627 [ + - - + ]: 5 : if (ncosets /= nshiftk .or. kptrlatt_ncells(bas, 1) /= ncosets) then
3628 : 0 : write(msg,'(a,i0,a,i0,a,i0,2a)') 'The ',nshiftk,' q-point shifts generate ',ncosets,&
3629 : 0 : ' cosets of the q-mesh (lattice basis determinant: ',kptrlatt_ncells(bas, 1),&
3630 : 0 : '), so their union is not a single shifted mesh.',ch10
3631 [ # # ]: 0 : do jj=1,nshiftk
3632 : 0 : write(line,'(a,i0,a,3es16.8)') ' shift ',jj,':',shiftk(:,jj)
3633 [ # # ]: 0 : msg = trim(msg)//trim(line)//ch10
3634 : : end do
3635 : 0 : write(line,'(a,i0,a,9(1x,i0))') ' denominator: ',dd,', basis:',bas
3636 : : msg = trim(msg)//trim(line)//ch10//&
3637 [ # # ]: 0 : 'Action: choose shifts that form a group modulo the q-mesh (e.g. 0 and 1/2 along the same direction).'
3638 : 0 : ABI_ERROR(msg)
3639 : : end if
3640 : :
3641 [ + + + + : 200 : sc_kptrlatt = matmul(kptrlatt, bas)
+ + ]
3642 : :
3643 : : end subroutine kptrlatt_merge_shifts
3644 : : !!***
3645 : :
3646 : : !----------------------------------------------------------------------
3647 : :
3648 : : !!****f* m_kpts/kptrlatt_ncells
3649 : : !! NAME
3650 : : !! kptrlatt_ncells
3651 : : !!
3652 : : !! FUNCTION
3653 : : !! Exact number of k/q points smpbz's general (brav==1) algorithm
3654 : : !! produces for a given kptrlatt and number of shifts: |det(kptrlatt)| *
3655 : : !! nshiftk. This is not an upper bound, it is the exact count (smpbz
3656 : : !! itself checks this internally: `if (nkpt/=nkptlatt*nshiftk)
3657 : : !! ABI_BUG(...)`), so callers can size their output array from it
3658 : : !! directly, replacing brav-dependent /2, /4 guesses.
3659 : : !!
3660 : : !! SOURCE
3661 : :
3662 : 286 : pure function kptrlatt_ncells(kptrlatt, nshiftk) result(ncells)
3663 : :
3664 : : !Arguments ------------------------------------
3665 : : integer,intent(in) :: kptrlatt(3,3), nshiftk
3666 : : integer :: ncells
3667 : :
3668 : : ! *********************************************************************
3669 : :
3670 : : ncells = abs( &
3671 : : kptrlatt(1,1)*kptrlatt(2,2)*kptrlatt(3,3) &
3672 : : +kptrlatt(1,2)*kptrlatt(2,3)*kptrlatt(3,1) &
3673 : : +kptrlatt(1,3)*kptrlatt(2,1)*kptrlatt(3,2) &
3674 : : -kptrlatt(1,2)*kptrlatt(2,1)*kptrlatt(3,3) &
3675 : : -kptrlatt(1,3)*kptrlatt(2,2)*kptrlatt(3,1) &
3676 : : -kptrlatt(1,1)*kptrlatt(2,3)*kptrlatt(3,2) &
3677 : 286 : ) * nshiftk
3678 : :
3679 : 286 : end function kptrlatt_ncells
3680 : : !!***
3681 : :
3682 [ # # # # : 0 : end module m_kpts
# # # # #
# # # ]
3683 : : !!***
|