30#include "./base/base_uses.f90"
37 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'cryssym'
45 LOGICAL :: symlib = .false.
46 LOGICAL :: fullgrid = .false.
47 LOGICAL :: inversion_only = .false.
48 LOGICAL :: spglib_reduction = .false.
49 LOGICAL :: spglib_backend = .false.
50 LOGICAL :: spglib_requested = .true.
53 INTEGER :: istriz = -1
54 REAL(kind=
dp) :: delta = 1.0e-8_dp
55 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat = 0.0_dp
57 REAL(kind=
dp),
DIMENSION(3) :: wvk0 = 0.0_dp
58 INTEGER,
DIMENSION(3) :: mesh = 0
59 INTEGER :: nkpoint = 0
61 INTEGER,
DIMENSION(:),
ALLOCATABLE :: atype
62 REAL(kind=
dp),
DIMENSION(:, :),
ALLOCATABLE :: scoord
63 REAL(kind=
dp),
DIMENSION(:, :),
ALLOCATABLE :: xkpoint
64 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: wkpoint
65 REAL(kind=
dp),
DIMENSION(:, :),
ALLOCATABLE :: kpmesh
66 INTEGER,
DIMENSION(:, :),
ALLOCATABLE :: kplink
67 INTEGER,
DIMENSION(:),
ALLOCATABLE :: kpop
69 CHARACTER(len=11) :: international_symbol =
""
70 CHARACTER(len=6) :: pointgroup_symbol =
""
71 CHARACTER(len=10) :: schoenflies =
""
72 INTEGER :: n_operations = 0
73 INTEGER,
DIMENSION(:, :, :),
ALLOCATABLE :: rotations
74 REAL(kind=
dp),
DIMENSION(:, :),
ALLOCATABLE :: translations
76 REAL(kind=
dp),
DIMENSION(:, :, :),
ALLOCATABLE :: rt
77 REAL(kind=
dp),
DIMENSION(:, :),
ALLOCATABLE :: vt
78 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: f0
80 INTEGER,
DIMENSION(:),
ALLOCATABLE :: ibrot
92 IF (
ALLOCATED(csym%rotations))
THEN
93 DEALLOCATE (csym%rotations)
95 IF (
ALLOCATED(csym%translations))
THEN
96 DEALLOCATE (csym%translations)
98 IF (
ALLOCATED(csym%atype))
THEN
99 DEALLOCATE (csym%atype)
101 IF (
ALLOCATED(csym%scoord))
THEN
102 DEALLOCATE (csym%scoord)
104 IF (
ALLOCATED(csym%xkpoint))
THEN
105 DEALLOCATE (csym%xkpoint)
107 IF (
ALLOCATED(csym%wkpoint))
THEN
108 DEALLOCATE (csym%wkpoint)
110 IF (
ALLOCATED(csym%kpmesh))
THEN
111 DEALLOCATE (csym%kpmesh)
113 IF (
ALLOCATED(csym%kplink))
THEN
114 DEALLOCATE (csym%kplink)
116 IF (
ALLOCATED(csym%kpop))
THEN
117 DEALLOCATE (csym%kpop)
119 IF (
ALLOCATED(csym%rt))
THEN
122 IF (
ALLOCATED(csym%vt))
THEN
125 IF (
ALLOCATED(csym%f0))
THEN
128 IF (
ALLOCATED(csym%ibrot))
THEN
129 DEALLOCATE (csym%ibrot)
144 SUBROUTINE crys_sym_gen(csym, scoor, types, hmat, delta, iounit, use_spglib)
146 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: scoor
147 INTEGER,
DIMENSION(:),
INTENT(IN) :: types
148 REAL(kind=
dp),
INTENT(IN) :: hmat(3, 3)
149 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: delta
150 INTEGER,
INTENT(IN),
OPTIONAL :: iounit
151 LOGICAL,
INTENT(IN),
OPTIONAL :: use_spglib
153 CHARACTER(LEN=*),
PARAMETER :: routinen =
'crys_sym_gen'
155 INTEGER :: handle, ierr, major, micro, minor, nat, &
157 LOGICAL :: my_use_spglib, spglib
159 CALL timeset(routinen, handle)
166 IF (
PRESENT(iounit))
THEN
173 IF (
PRESENT(delta))
THEN
176 csym%delta = 1.e-6_dp
183 ALLOCATE (csym%atype(nat))
184 csym%atype(1:nat) = types(1:nat)
187 ALLOCATE (csym%scoord(3, nat))
188 csym%scoord(1:3, 1:nat) = scoor(1:3, 1:nat)
190 csym%n_operations = 0
193 my_use_spglib = .true.
194 IF (
PRESENT(use_spglib)) my_use_spglib = use_spglib
195 csym%spglib_requested = my_use_spglib
196 IF (.NOT. my_use_spglib)
THEN
203 CALL cp_warn(__location__,
"Symmetry library SPGLIB not available")
210 CALL cp_warn(__location__,
"Symmetry Library SPGLIB failed")
214 ALLOCATE (csym%rotations(3, 3, nop), csym%translations(3, nop))
215 csym%n_operations = nop
217 transpose(hmat), scoor, types, nat, delta)
219 csym%schoenflies =
' '
222 csym%pointgroup_symbol =
' '
225 csym%rotations, csym%n_operations)
235 CALL timestop(handle)
251 SUBROUTINE kpoint_gen(csym, nk, symm, shift, full_grid, gamma_centered, &
252 inversion_symmetry_only, use_spglib_reduction, use_spglib_backend)
254 INTEGER,
INTENT(IN) :: nk(3)
255 LOGICAL,
INTENT(IN),
OPTIONAL :: symm
256 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: shift(3)
257 LOGICAL,
INTENT(IN),
OPTIONAL :: full_grid, gamma_centered, &
258 inversion_symmetry_only, &
259 use_spglib_reduction, &
262 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_gen'
264 INTEGER :: handle, i, ik, j, nkp, nkpts
265 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kpop, xptr
266 LOGICAL :: fullmesh, gamma_mesh, inversion_only, &
267 spglib_backend, spglib_reduction
268 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: wkp
269 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: xkp
271 CALL timeset(routinen, handle)
273 IF (
PRESENT(shift))
THEN
280 IF (
PRESENT(symm))
THEN
281 IF (symm) csym%istriz = 1
284 IF (
PRESENT(full_grid))
THEN
289 csym%fullgrid = fullmesh
291 IF (
PRESENT(gamma_centered))
THEN
292 gamma_mesh = gamma_centered
297 IF (
PRESENT(inversion_symmetry_only))
THEN
298 inversion_only = inversion_symmetry_only
300 inversion_only = .false.
302 csym%inversion_only = inversion_only
304 IF (
PRESENT(use_spglib_reduction))
THEN
305 spglib_reduction = use_spglib_reduction
307 spglib_reduction = .false.
309 csym%spglib_reduction = spglib_reduction
311 IF (
PRESENT(use_spglib_backend))
THEN
312 spglib_backend = use_spglib_backend
314 spglib_backend = .false.
316 csym%spglib_backend = spglib_backend
318 IF (spglib_backend .AND. .NOT. spglib_reduction)
THEN
319 CALL cp_abort(__location__, &
320 "SYMMETRY_BACKEND SPGLIB requires SYMMETRY_REDUCTION_METHOD SPGLIB")
322 IF (csym%istriz == 1 .AND. .NOT. fullmesh .AND. .NOT. inversion_only .AND. &
323 (spglib_backend .OR. spglib_reduction) .AND. .NOT. csym%symlib)
THEN
324 CALL cp_abort(__location__, &
325 "SPGLIB k-point symmetry was requested, but SPGLIB is not available")
329 csym%mesh(1:3) = nk(1:3)
331 IF (
ALLOCATED(csym%rt))
DEALLOCATE (csym%rt)
332 IF (
ALLOCATED(csym%vt))
DEALLOCATE (csym%vt)
333 IF (
ALLOCATED(csym%ibrot))
DEALLOCATE (csym%ibrot)
334 IF (
ALLOCATED(csym%f0))
DEALLOCATE (csym%f0)
335 ALLOCATE (csym%rt(3, 3, 0), csym%vt(3, 0), csym%ibrot(0), csym%f0(csym%nat, 0))
337 nkpts = nk(1)*nk(2)*nk(3)
338 ALLOCATE (xkp(3, nkpts), wkp(nkpts), kpop(nkpts))
340 ALLOCATE (csym%kplink(2, nkpts))
345 IF (csym%symlib)
THEN
349 CALL full_grid_gen(nk, xkp, wkp, shift, gamma_centered=gamma_mesh)
350 IF (csym%istriz == 1)
THEN
352 CALL inversion_symm(xkp, wkp, csym%kplink(1, :))
356 ELSE IF (csym%istriz /= 1 .OR. inversion_only)
THEN
358 CALL full_grid_gen(nk, xkp, wkp, shift, gamma_centered=gamma_mesh)
359 CALL inversion_symm(xkp, wkp, csym%kplink(1, :))
362 CALL full_grid_gen(nk, xkp, wkp, shift, gamma_centered=gamma_mesh)
363 IF (spglib_backend)
THEN
364 CALL kp_symmetry_spglib(csym, xkp, wkp, kpop)
366 CALL kp_symmetry(csym, xkp, wkp, kpop, use_spglib_reduction=spglib_reduction)
372 CALL full_grid_gen(nk, xkp, wkp, shift, gamma_centered=gamma_mesh)
373 IF (csym%istriz == 1 .AND. .NOT. fullmesh .AND. .NOT. inversion_only)
THEN
375 CALL kp_symmetry(csym, xkp, wkp, kpop, use_spglib_reduction=.false.)
376 ELSE IF (csym%istriz /= 1 .AND. fullmesh)
THEN
379 csym%kplink(1, i) = i
383 CALL inversion_symm(xkp, wkp, csym%kplink(1, :))
389 IF (wkp(i) > 0.0_dp) nkp = nkp + 1
394 ALLOCATE (csym%xkpoint(3, nkp), csym%wkpoint(nkp))
398 IF (wkp(ik) > 0.0_dp)
THEN
400 csym%wkpoint(j) = wkp(ik)
401 csym%xkpoint(1:3, j) = xkp(1:3, ik)
408 ALLOCATE (csym%kpmesh(3, nkpts))
409 csym%kpmesh(1:3, 1:nkpts) = xkp(1:3, 1:nkpts)
413 i = csym%kplink(1, ik)
415 IF (i == xptr(j))
THEN
416 csym%kplink(2, ik) = j
424 ALLOCATE (csym%kpop(nkpts))
425 IF (csym%nrtot > 0 .AND. csym%istriz == 1 .AND. .NOT. fullmesh .AND. &
426 .NOT. inversion_only)
THEN
428 csym%kpop(1:nkpts) = kpop(1:nkpts)
430 cpassert(csym%kpop(ik) /= 0)
435 IF (wkp(ik) > 0.0_dp)
THEN
443 DEALLOCATE (xkp, wkp, kpop)
445 CALL timestop(handle)
461 inversion_symmetry_only, use_spglib_reduction, use_spglib_backend)
463 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: xkp_in
464 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: wkp_in
465 LOGICAL,
INTENT(IN),
OPTIONAL :: symm, full_grid, &
466 inversion_symmetry_only, &
467 use_spglib_reduction, &
470 CHARACTER(LEN=*),
PARAMETER :: routinen =
'kpoint_gen_general'
472 INTEGER :: handle, i, nfull
473 LOGICAL :: atomic_symmetry, fullmesh, &
474 inversion_only, spglib_backend, &
476 REAL(kind=
dp) :: weight_eps
478 CALL timeset(routinen, handle)
481 cpassert(
SIZE(xkp_in, 1) == 3)
482 cpassert(
SIZE(xkp_in, 2) == nfull)
484 atomic_symmetry = .false.
485 IF (
PRESENT(symm)) atomic_symmetry = symm
487 IF (atomic_symmetry) csym%istriz = 1
489 IF (
PRESENT(full_grid)) fullmesh = full_grid
490 inversion_only = .false.
491 IF (
PRESENT(inversion_symmetry_only)) inversion_only = inversion_symmetry_only
492 spglib_reduction = .false.
493 IF (
PRESENT(use_spglib_reduction)) spglib_reduction = use_spglib_reduction
494 spglib_backend = .false.
495 IF (
PRESENT(use_spglib_backend)) spglib_backend = use_spglib_backend
497 csym%fullgrid = fullmesh
498 csym%inversion_only = inversion_only
499 csym%spglib_reduction = spglib_reduction
500 csym%spglib_backend = spglib_backend
504 IF (
ALLOCATED(csym%rt))
DEALLOCATE (csym%rt)
505 IF (
ALLOCATED(csym%vt))
DEALLOCATE (csym%vt)
506 IF (
ALLOCATED(csym%ibrot))
DEALLOCATE (csym%ibrot)
507 IF (
ALLOCATED(csym%f0))
DEALLOCATE (csym%f0)
508 ALLOCATE (csym%rt(3, 3, 0), csym%vt(3, 0), csym%ibrot(0), csym%f0(csym%nat, 0))
509 IF (
ALLOCATED(csym%xkpoint))
DEALLOCATE (csym%xkpoint)
510 IF (
ALLOCATED(csym%wkpoint))
DEALLOCATE (csym%wkpoint)
511 IF (
ALLOCATED(csym%kpmesh))
DEALLOCATE (csym%kpmesh)
512 IF (
ALLOCATED(csym%kplink))
DEALLOCATE (csym%kplink)
513 IF (
ALLOCATED(csym%kpop))
DEALLOCATE (csym%kpop)
515 ALLOCATE (csym%kpmesh(3, nfull), csym%kplink(2, nfull), csym%kpop(nfull))
516 csym%kpmesh(1:3, 1:nfull) = xkp_in(1:3, 1:nfull)
520 IF (.NOT. atomic_symmetry .OR. fullmesh)
THEN
522 ALLOCATE (csym%xkpoint(3, nfull), csym%wkpoint(nfull))
523 csym%xkpoint(1:3, 1:nfull) = xkp_in(1:3, 1:nfull)
524 csym%wkpoint(1:nfull) = wkp_in(1:nfull)
526 csym%kplink(1:2, i) = i
528 ELSE IF (inversion_only)
THEN
529 CALL reduce_general_inversion(csym, xkp_in, wkp_in)
531 weight_eps = max(1.e-12_dp, 10.0_dp*csym%delta)
532 IF (any(abs(wkp_in(1:nfull) - wkp_in(1)) > weight_eps))
THEN
533 CALL cp_abort(__location__, &
534 "KPOINTS%SYMMETRY with SCHEME GENERAL requires equal explicit weights.")
536 IF (spglib_backend)
THEN
537 IF (.NOT. csym%symlib)
THEN
538 CALL cp_abort(__location__, &
539 "SCHEME GENERAL with SYMMETRY_BACKEND SPGLIB requires SPGLIB.")
541 CALL reduce_general_spglib(csym, xkp_in)
542 ELSE IF (spglib_reduction)
THEN
543 IF (.NOT. csym%symlib)
THEN
544 CALL cp_abort(__location__, &
545 "SCHEME GENERAL with SYMMETRY_REDUCTION_METHOD SPGLIB requires SPGLIB.")
547 CALL setup_k290_operations(csym)
548 CALL reduce_general_spglib_k290(csym, xkp_in)
550 CALL setup_k290_operations(csym)
551 CALL reduce_general_k290(csym, xkp_in)
555 CALL timestop(handle)
567 SUBROUTINE kp_symmetry(csym, xkp, wkp, kpop, use_spglib_reduction)
569 REAL(kind=
dp),
DIMENSION(:, :) :: xkp
570 REAL(kind=
dp),
DIMENSION(:) :: wkp
571 INTEGER,
DIMENSION(:) :: kpop
572 LOGICAL,
INTENT(IN),
OPTIONAL :: use_spglib_reduction
574 INTEGER :: i, ihc, ihg, indpg, iou, iq1, iq2, iq3, &
575 istriz, isy, li, nat, nc, nhash, &
576 nkpoint, nrot, nsp, ntvec
577 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: includ, isc,
list, lwght, ty
578 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: f0, lrot
579 INTEGER,
ALLOCATABLE,
DIMENSION(:, :, :) :: srot
580 INTEGER,
DIMENSION(48) :: ib
581 LOGICAL :: spglib_reduction
582 REAL(kind=
dp) :: alat
583 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: rlist, rx, tvec, wvkl, xkapa
584 REAL(kind=
dp),
DIMENSION(3) :: a1, a2, a3, b1, b2, b3, origin, wvk0
585 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat, strain
586 REAL(kind=
dp),
DIMENSION(3, 3, 48) :: r
587 REAL(kind=
dp),
DIMENSION(3, 48) :: vt
595 nkpoint = 10*iq1*iq2*iq3
600 IF (
PRESENT(use_spglib_reduction))
THEN
601 spglib_reduction = use_spglib_reduction
603 spglib_reduction = .false.
605 a1(1:3) = hmat(1:3, 1)
606 a2(1:3) = hmat(1:3, 2)
607 a3(1:3) = hmat(1:3, 3)
610 ALLOCATE (xkapa(3, nat), rx(3, nat), tvec(3, 200), ty(nat), isc(nat), f0(49, nat))
611 ty(1:nat) = csym%atype(1:nat)
614 xkapa(1:3, i) = matmul(hmat, csym%scoord(1:3, i))
617 ALLOCATE (wvkl(3, nkpoint), rlist(3, nkpoint), includ(nkpoint),
list(nhash + nkpoint))
618 ALLOCATE (lrot(48, nkpoint), lwght(nkpoint))
621 WRITE (iou,
'(/,(T2,A79))') &
622 "*******************************************************************************", &
623 "** Special K-Point Generation by K290 **", &
624 "*******************************************************************************"
627 IF (spglib_reduction)
CALL cite_reference(
togo2018)
629 CALL k290s(iou, nat, nkpoint, nsp, iq1, iq2, iq3, istriz, &
630 a1, a2, a3, alat, strain, xkapa, rx, tvec, &
631 ty, isc, f0, ntvec, wvk0, wvkl, lwght, lrot, &
632 nhash, includ,
list, rlist, csym%delta)
634 CALL group1s(0, a1, a2, a3, nat, ty, xkapa, b1, b2, b3, &
635 ihg, ihc, isy, li, nc, indpg, ib, ntvec, &
636 vt, f0, r, tvec, origin, rx, isc, csym%delta)
639 WRITE (iou,
'((T2,A79))') &
640 "*******************************************************************************", &
641 "** Finished K290 **", &
642 "*******************************************************************************"
646 IF (
ALLOCATED(csym%rt))
DEALLOCATE (csym%rt)
647 IF (
ALLOCATED(csym%vt))
DEALLOCATE (csym%vt)
648 IF (
ALLOCATED(csym%ibrot))
DEALLOCATE (csym%ibrot)
649 IF (
ALLOCATED(csym%f0))
DEALLOCATE (csym%f0)
650 ALLOCATE (csym%rt(3, 3, nc), csym%vt(3, nc), csym%ibrot(nc))
651 csym%vt(1:3, 1:nc) = vt(1:3, 1:nc)
652 ALLOCATE (csym%f0(nat, nc))
654 csym%rt(1:3, 1:3, i) = r(1:3, 1:3, ib(i))
655 csym%f0(1:nat, i) = f0(i, 1:nat)
657 csym%ibrot(1:nc) = ib(1:nc)
659 IF (csym%n_operations > nc .AND. .NOT. spglib_reduction)
THEN
660 IF (
ALLOCATED(srot))
DEALLOCATE (srot)
661 ALLOCATE (srot(3, 3, csym%n_operations))
662 CALL setup_spglib_operations(csym, srot, nrot)
663 CALL reduce_spglib_kpoint_mesh(csym, xkp, wkp, kpop, srot, nrot)
665 ELSE IF (spglib_reduction)
THEN
666 ALLOCATE (srot(3, 3, csym%n_operations))
667 CALL setup_spglib_reduction_rotations(csym, srot, nrot)
668 CALL reduce_spglib_kpoint_mesh_k290(csym, xkp, wkp, kpop, srot, nrot, &
669 a1, a2, a3, b1, b2, b3, alat)
672 CALL reduce_kpoint_mesh(csym, xkp, wkp, kpop, nc, ib, r, a1, a2, a3, b1, b2, b3, alat)
674 DEALLOCATE (xkapa, rx, tvec, ty, isc, f0)
675 DEALLOCATE (wvkl, rlist, includ,
list)
676 DEALLOCATE (lrot, lwght)
678 END SUBROUTINE kp_symmetry
687 SUBROUTINE kp_symmetry_spglib(csym, xkp, wkp, kpop)
689 REAL(kind=
dp),
DIMENSION(:, :) :: xkp
690 REAL(kind=
dp),
DIMENSION(:) :: wkp
691 INTEGER,
DIMENSION(:) :: kpop
694 INTEGER,
ALLOCATABLE,
DIMENSION(:, :, :) :: srot
698 WRITE (iou,
'(/,(T2,A79))') &
699 "*******************************************************************************", &
700 "** Special K-Point Generation by SPGLIB **", &
701 "*******************************************************************************"
705 ALLOCATE (srot(3, 3, csym%n_operations))
706 CALL setup_spglib_operations(csym, srot, nrot)
707 CALL reduce_spglib_kpoint_mesh(csym, xkp, wkp, kpop, srot, nrot)
711 WRITE (iou,
'((T2,A79))') &
712 "*******************************************************************************", &
713 "** Finished SPGLIB **", &
714 "*******************************************************************************"
717 END SUBROUTINE kp_symmetry_spglib
723 SUBROUTINE setup_k290_operations(csym)
726 INTEGER :: i, ihc, ihg, indpg, iou, iq1, iq2, iq3, &
727 isy, li, nat, nc, nhash, nkpoint, nsp, &
729 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: includ, isc,
list, lwght, ty
730 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: f0, lrot
731 INTEGER,
DIMENSION(48) :: ib
732 REAL(kind=
dp) :: alat
733 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: rlist, rx, tvec, wvkl, xkapa
734 REAL(kind=
dp),
DIMENSION(3) :: a1, a2, a3, b1, b2, b3, origin, wvk0
735 REAL(kind=
dp),
DIMENSION(3, 3) :: strain
736 REAL(kind=
dp),
DIMENSION(3, 3, 48) :: r
737 REAL(kind=
dp),
DIMENSION(3, 48) :: vt
741 CALL setup_k290_lattice(csym, a1, a2, a3, b1, b2, b3, alat)
742 iq1 = max(1, csym%mesh(1))
743 iq2 = max(1, csym%mesh(2))
744 iq3 = max(1, csym%mesh(3))
745 nkpoint = max(10, 10*iq1*iq2*iq3)
749 ALLOCATE (xkapa(3, nat), rx(3, nat), tvec(3, 200), ty(nat), isc(nat), f0(49, nat))
750 ty(1:nat) = csym%atype(1:nat)
753 xkapa(1:3, i) = matmul(csym%hmat, csym%scoord(1:3, i))
756 ALLOCATE (wvkl(3, nkpoint), rlist(3, nkpoint), includ(nkpoint),
list(nhash + nkpoint))
757 ALLOCATE (lrot(48, nkpoint), lwght(nkpoint))
760 WRITE (iou,
'(/,(T2,A79))') &
761 "*******************************************************************************", &
762 "** Special K-Point Generation by K290 **", &
763 "*******************************************************************************"
767 CALL k290s(iou, nat, nkpoint, nsp, iq1, iq2, iq3, csym%istriz, &
768 a1, a2, a3, alat, strain, xkapa, rx, tvec, &
769 ty, isc, f0, ntvec, wvk0, wvkl, lwght, lrot, &
770 nhash, includ,
list, rlist, csym%delta)
772 CALL group1s(0, a1, a2, a3, nat, ty, xkapa, b1, b2, b3, &
773 ihg, ihc, isy, li, nc, indpg, ib, ntvec, &
774 vt, f0, r, tvec, origin, rx, isc, csym%delta)
777 WRITE (iou,
'((T2,A79))') &
778 "*******************************************************************************", &
779 "** Finished K290 **", &
780 "*******************************************************************************"
784 IF (
ALLOCATED(csym%rt))
DEALLOCATE (csym%rt)
785 IF (
ALLOCATED(csym%vt))
DEALLOCATE (csym%vt)
786 IF (
ALLOCATED(csym%ibrot))
DEALLOCATE (csym%ibrot)
787 IF (
ALLOCATED(csym%f0))
DEALLOCATE (csym%f0)
788 ALLOCATE (csym%rt(3, 3, nc), csym%vt(3, nc), csym%ibrot(nc))
789 csym%vt(1:3, 1:nc) = vt(1:3, 1:nc)
790 ALLOCATE (csym%f0(nat, nc))
792 csym%rt(1:3, 1:3, i) = r(1:3, 1:3, ib(i))
793 csym%f0(1:nat, i) = f0(i, 1:nat)
795 csym%ibrot(1:nc) = ib(1:nc)
797 DEALLOCATE (xkapa, rx, tvec, ty, isc, f0)
798 DEALLOCATE (wvkl, rlist, includ,
list)
799 DEALLOCATE (lrot, lwght)
801 END SUBROUTINE setup_k290_operations
814 SUBROUTINE setup_k290_lattice(csym, a1, a2, a3, b1, b2, b3, alat)
816 REAL(kind=
dp),
DIMENSION(3),
INTENT(OUT) :: a1, a2, a3, b1, b2, b3
817 REAL(kind=
dp),
INTENT(OUT) :: alat
819 REAL(kind=
dp) :: volum
821 a1(1:3) = csym%hmat(1:3, 1)
822 a2(1:3) = csym%hmat(1:3, 2)
823 a3(1:3) = csym%hmat(1:3, 3)
824 alat = csym%hmat(1, 1)
825 volum = a1(1)*a2(2)*a3(3) + a2(1)*a3(2)*a1(3) + &
826 a3(1)*a1(2)*a2(3) - a1(3)*a2(2)*a3(1) - &
827 a2(3)*a3(2)*a1(1) - a3(3)*a1(2)*a2(1)
829 b1(1) = (a2(2)*a3(3) - a2(3)*a3(2))/volum
830 b1(2) = (a2(3)*a3(1) - a2(1)*a3(3))/volum
831 b1(3) = (a2(1)*a3(2) - a2(2)*a3(1))/volum
832 b2(1) = (a3(2)*a1(3) - a3(3)*a1(2))/volum
833 b2(2) = (a3(3)*a1(1) - a3(1)*a1(3))/volum
834 b2(3) = (a3(1)*a1(2) - a3(2)*a1(1))/volum
835 b3(1) = (a1(2)*a2(3) - a1(3)*a2(2))/volum
836 b3(2) = (a1(3)*a2(1) - a1(1)*a2(3))/volum
837 b3(3) = (a1(1)*a2(2) - a1(2)*a2(1))/volum
839 END SUBROUTINE setup_k290_lattice
847 SUBROUTINE setup_spglib_operations(csym, srot, nrot)
849 INTEGER,
DIMENSION(:, :, :),
INTENT(OUT) :: srot
850 INTEGER,
INTENT(OUT) :: nrot
852 INTEGER :: iop, jop, pass
853 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: perm
854 INTEGER,
DIMENSION(3, 3) :: eye, frot, irot
855 LOGICAL :: duplicate, identity, valid, &
858 REAL(kind=
dp),
DIMENSION(3, 3) :: h_inv, rfrac
860 cpassert(csym%symlib)
864 IF (
ALLOCATED(csym%rt))
DEALLOCATE (csym%rt)
865 IF (
ALLOCATED(csym%vt))
DEALLOCATE (csym%vt)
866 IF (
ALLOCATED(csym%ibrot))
DEALLOCATE (csym%ibrot)
867 IF (
ALLOCATED(csym%f0))
DEALLOCATE (csym%f0)
868 ALLOCATE (csym%rt(3, 3, csym%n_operations), csym%vt(3, csym%n_operations))
869 ALLOCATE (csym%ibrot(csym%n_operations), csym%f0(csym%nat, csym%n_operations))
875 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
877 ALLOCATE (perm(csym%nat))
888 DO iop = 1, csym%n_operations
889 irot(1:3, 1:3) = csym%rotations(1:3, 1:3, iop)
890 frot(1:3, 1:3) = transpose(irot(1:3, 1:3))
891 identity = all(frot == eye)
892 zero_translation = all(abs(csym%translations(1:3, iop) - &
893 anint(csym%translations(1:3, iop))) <= eps)
894 IF (pass == 1 .AND. (.NOT. identity .OR. .NOT. zero_translation)) cycle
895 IF (pass == 2 .AND. (identity .OR. .NOT. zero_translation)) cycle
896 IF (pass == 3 .AND. (.NOT. identity .OR. zero_translation)) cycle
897 IF (pass == 4 .AND. (identity .OR. zero_translation)) cycle
901 IF (all(frot == srot(:, :, jop)) .AND. &
902 all(abs(csym%translations(1:3, iop) - csym%vt(1:3, jop) - &
903 anint(csym%translations(1:3, iop) - csym%vt(1:3, jop))) <= eps))
THEN
910 CALL spglib_atom_permutation(csym, frot, csym%translations(:, iop), perm, valid)
911 IF (.NOT. valid) cycle
915 srot(1:3, 1:3, nrot) = frot(1:3, 1:3)
916 rfrac(1:3, 1:3) = real(frot(1:3, 1:3), kind=
dp)
917 csym%rt(1:3, 1:3, nrot) = matmul(csym%hmat, matmul(rfrac, h_inv))
918 csym%vt(1:3, nrot) = csym%translations(1:3, iop)
919 csym%ibrot(nrot) = nrot
920 csym%f0(1:csym%nat, nrot) = perm(1:csym%nat)
926 IF (nrot == 0)
CALL cp_abort(__location__,
"SPGLIB did not return usable symmetry operations")
928 END SUBROUTINE setup_spglib_operations
936 SUBROUTINE setup_spglib_reduction_rotations(csym, srot, nrot)
938 INTEGER,
DIMENSION(:, :, :),
INTENT(OUT) :: srot
939 INTEGER,
INTENT(OUT) :: nrot
941 INTEGER :: iop, jop, pass
942 INTEGER,
DIMENSION(3, 3) :: eye, frot, irot
943 LOGICAL :: duplicate, identity
945 cpassert(csym%symlib)
956 DO iop = 1, csym%n_operations
957 irot(1:3, 1:3) = csym%rotations(1:3, 1:3, iop)
958 frot(1:3, 1:3) = transpose(irot(1:3, 1:3))
959 identity = all(frot == eye)
960 IF (pass == 1 .AND. .NOT. identity) cycle
961 IF (pass == 2 .AND. identity) cycle
965 IF (all(frot == srot(:, :, jop)))
THEN
973 srot(1:3, 1:3, nrot) = frot(1:3, 1:3)
977 IF (nrot == 0)
CALL cp_abort(__location__,
"SPGLIB did not return usable symmetry rotations")
979 END SUBROUTINE setup_spglib_reduction_rotations
989 SUBROUTINE spglib_atom_permutation(csym, rot, trans, perm, valid)
991 INTEGER,
DIMENSION(3, 3),
INTENT(IN) :: rot
992 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: trans
993 INTEGER,
DIMENSION(:),
INTENT(OUT) :: perm
994 LOGICAL,
INTENT(OUT) :: valid
998 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: used
1000 REAL(kind=
dp),
DIMENSION(3) :: diff, spos
1001 REAL(kind=
dp),
DIMENSION(3, 3) :: rfrac
1004 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
1005 rfrac(1:3, 1:3) = real(rot(1:3, 1:3), kind=
dp)
1006 ALLOCATE (used(nat))
1012 spos(1:3) = matmul(rfrac(1:3, 1:3), csym%scoord(1:3, i)) + trans(1:3)
1016 IF (csym%atype(i) /= csym%atype(j)) cycle
1017 diff(1:3) = spos(1:3) - csym%scoord(1:3, j)
1018 diff(1:3) = diff(1:3) - anint(diff(1:3))
1019 IF (all(abs(diff(1:3)) < eps))
THEN
1026 IF (.NOT. found)
THEN
1034 END SUBROUTINE spglib_atom_permutation
1045 SUBROUTINE reduce_spglib_kpoint_mesh(csym, xkp, wkp, kpop, srot, nrot)
1047 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: xkp
1048 REAL(kind=
dp),
DIMENSION(:) :: wkp
1049 INTEGER,
DIMENSION(:) :: kpop
1050 INTEGER,
DIMENSION(:, :, :),
INTENT(IN) :: srot
1051 INTEGER,
INTENT(IN) :: nrot
1053 INTEGER :: i, iop, isign, j, kr, nkpts, score
1054 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kscore
1055 INTEGER,
DIMENSION(3, 3) :: krot
1056 REAL(kind=
dp) :: eps
1057 REAL(kind=
dp),
DIMENSION(3) :: diff, rr
1060 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
1061 ALLOCATE (kscore(nkpts))
1065 csym%kplink(1, :) = 0
1069 IF (csym%kplink(1, i) /= 0) cycle
1071 csym%kplink(1, i) = i
1077 kr = csym%ibrot(iop)
1078 krot = reciprocal_rotation(srot(:, :, kr))
1079 score = spglib_operation_score(csym, iop, srot(:, :, kr))
1081 rr(1:3) = matmul(real(krot(1:3, 1:3), kind=
dp), xkp(1:3, i))
1082 IF (isign == 2)
THEN
1084 kr = -csym%ibrot(iop)
1086 kr = csym%ibrot(iop)
1090 diff(1:3) = xkp(1:3, j) - rr(1:3)
1091 diff(1:3) = diff(1:3) - anint(diff(1:3))
1092 IF (all(abs(diff(1:3)) < eps))
THEN
1093 IF (csym%kplink(1, j) == 0)
THEN
1094 csym%kplink(1, j) = i
1095 wkp(i) = wkp(i) + 1.0_dp
1099 cpassert(csym%kplink(1, j) == i)
1100 IF (score < kscore(j))
THEN
1108 IF (j > nkpts) cycle
1114 cpassert(csym%kplink(1, i) /= 0)
1115 cpassert(kpop(i) /= 0)
1119 END SUBROUTINE reduce_spglib_kpoint_mesh
1127 SUBROUTINE reduce_general_inversion(csym, xkp_full, wkp_full)
1129 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: xkp_full
1130 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: wkp_full
1132 INTEGER :: i, j, nfull, nred
1133 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: rep
1134 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: used
1135 REAL(kind=
dp) :: eps
1136 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: wred
1137 REAL(kind=
dp),
DIMENSION(3) :: diff
1139 nfull =
SIZE(wkp_full)
1140 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
1141 ALLOCATE (rep(nfull), used(nfull), wred(nfull))
1152 csym%kplink(1, i) = i
1154 wred(nred) = wkp_full(i)
1157 diff(1:3) = xkp_full(1:3, j) + xkp_full(1:3, i)
1158 diff(1:3) = diff(1:3) - anint(diff(1:3))
1159 IF (all(abs(diff(1:3)) < eps))
THEN
1160 IF (abs(wkp_full(j) - wkp_full(i)) > eps)
THEN
1161 CALL cp_abort(__location__, &
1162 "KPOINTS%INVERSION_SYMMETRY_ONLY with SCHEME GENERAL requires "// &
1163 "equal weights for inversion-related k-points.")
1166 csym%kplink(1, j) = i
1168 wred(nred) = wred(nred) + wkp_full(j)
1174 ALLOCATE (csym%xkpoint(3, nred), csym%wkpoint(nred))
1176 csym%xkpoint(1:3, i) = xkp_full(1:3, rep(i))
1177 csym%wkpoint(i) = wred(i)
1181 IF (csym%kplink(1, i) == rep(j))
THEN
1182 csym%kplink(2, i) = j
1188 DEALLOCATE (rep, used, wred)
1190 END SUBROUTINE reduce_general_inversion
1197 SUBROUTINE reduce_general_k290(csym, xkp_full)
1199 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: xkp_full
1201 INTEGER :: i, ibsign, iop, j, kr, nfull, nred
1202 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: rep
1204 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: used
1205 REAL(kind=
dp) :: alat, eps
1206 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: wred
1207 REAL(kind=
dp),
DIMENSION(3) :: a1, a2, a3, b1, b2, b3, diff, rr, wcart
1209 nfull =
SIZE(xkp_full, 2)
1210 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
1211 CALL setup_k290_lattice(csym, a1, a2, a3, b1, b2, b3, alat)
1213 ALLOCATE (rep(nfull), used(nfull), wred(nfull))
1224 csym%kplink(1, i) = i
1228 DO iop = 1, csym%nrtot
1230 kr = csym%ibrot(iop)
1231 wcart(1:3) = alat*(xkp_full(1, i)*b1(1:3) + &
1232 xkp_full(2, i)*b2(1:3) + &
1233 xkp_full(3, i)*b3(1:3))
1234 wcart(1:3) = kp_apply_operation(wcart(1:3), csym%rt(1:3, 1:3, iop))
1235 IF (ibsign == 2)
THEN
1236 wcart(1:3) = -wcart(1:3)
1239 rr(1) = dot_product(a1(1:3), wcart(1:3))/alat
1240 rr(2) = dot_product(a2(1:3), wcart(1:3))/alat
1241 rr(3) = dot_product(a3(1:3), wcart(1:3))/alat
1245 diff(1:3) = xkp_full(1:3, j) - rr(1:3)
1246 diff(1:3) = diff(1:3) - anint(diff(1:3))
1247 IF (all(abs(diff(1:3)) < eps))
THEN
1249 IF (.NOT. used(j))
THEN
1251 csym%kplink(1, j) = i
1253 wred(nred) = wred(nred) + 1.0_dp
1255 cpassert(csym%kplink(1, j) == i)
1260 IF (.NOT. found)
THEN
1261 CALL cp_abort(__location__, &
1262 "KPOINTS%SYMMETRY with SCHEME GENERAL requires the explicit k-point set "// &
1263 "to be closed under the K290 symmetry operations.")
1269 CALL store_general_reduction(csym, xkp_full, rep, wred, nred)
1271 DEALLOCATE (rep, used, wred)
1273 END SUBROUTINE reduce_general_k290
1280 SUBROUTINE reduce_general_spglib(csym, xkp_full)
1282 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: xkp_full
1284 INTEGER :: i, iop, isign, j, kr, nfull, nred, nrot
1285 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: rep
1286 INTEGER,
ALLOCATABLE,
DIMENSION(:, :, :) :: srot
1287 INTEGER,
DIMENSION(3, 3) :: krot
1289 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: used
1290 REAL(kind=
dp) :: eps
1291 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: wred
1292 REAL(kind=
dp),
DIMENSION(3) :: diff, rr
1294 nfull =
SIZE(xkp_full, 2)
1295 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
1296 ALLOCATE (srot(3, 3, csym%n_operations))
1297 CALL setup_spglib_operations(csym, srot, nrot)
1299 ALLOCATE (rep(nfull), used(nfull), wred(nfull))
1310 csym%kplink(1, i) = i
1315 kr = csym%ibrot(iop)
1316 krot = reciprocal_rotation(srot(:, :, kr))
1318 rr(1:3) = matmul(real(krot(1:3, 1:3), kind=
dp), xkp_full(1:3, i))
1319 IF (isign == 2)
THEN
1321 kr = -csym%ibrot(iop)
1323 kr = csym%ibrot(iop)
1328 diff(1:3) = xkp_full(1:3, j) - rr(1:3)
1329 diff(1:3) = diff(1:3) - anint(diff(1:3))
1330 IF (all(abs(diff(1:3)) < eps))
THEN
1332 IF (.NOT. used(j))
THEN
1334 csym%kplink(1, j) = i
1336 wred(nred) = wred(nred) + 1.0_dp
1338 cpassert(csym%kplink(1, j) == i)
1343 IF (.NOT. found)
THEN
1344 CALL cp_abort(__location__, &
1345 "KPOINTS%SYMMETRY with SCHEME GENERAL requires the explicit k-point set "// &
1346 "to be closed under the requested symmetry operations.")
1352 CALL store_general_reduction(csym, xkp_full, rep, wred, nred)
1354 DEALLOCATE (rep, srot, used, wred)
1356 END SUBROUTINE reduce_general_spglib
1363 SUBROUTINE reduce_general_spglib_k290(csym, xkp_full)
1365 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: xkp_full
1367 INTEGER :: i, iop, isign, j, k290_op, nfull, nred, &
1369 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: rep
1370 INTEGER,
ALLOCATABLE,
DIMENSION(:, :, :) :: srot
1371 INTEGER,
DIMENSION(3, 3) :: krot
1372 LOGICAL :: found, valid
1373 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: used
1374 REAL(kind=
dp) :: alat, eps
1375 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: wred
1376 REAL(kind=
dp),
DIMENSION(3) :: a1, a2, a3, b1, b2, b3, diff, rr
1378 nfull =
SIZE(xkp_full, 2)
1379 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
1380 CALL setup_k290_lattice(csym, a1, a2, a3, b1, b2, b3, alat)
1381 ALLOCATE (srot(3, 3, csym%n_operations))
1382 CALL setup_spglib_reduction_rotations(csym, srot, nrot)
1384 ALLOCATE (rep(nfull), used(nfull), wred(nfull))
1396 csym%kplink(1, i) = i
1401 krot = reciprocal_rotation(srot(:, :, iop))
1403 rr(1:3) = matmul(real(krot(1:3, 1:3), kind=
dp), xkp_full(1:3, i))
1404 IF (isign == 2) rr(1:3) = -rr(1:3)
1408 diff(1:3) = xkp_full(1:3, j) - rr(1:3)
1409 diff(1:3) = diff(1:3) - anint(diff(1:3))
1410 IF (all(abs(diff(1:3)) < eps))
THEN
1412 CALL find_k290_kpoint_operation(csym, xkp_full(1:3, i), xkp_full(1:3, j), &
1413 a1, a2, a3, b1, b2, b3, alat, &
1415 IF (.NOT. valid)
THEN
1416 nskipped = nskipped + 1
1419 IF (.NOT. used(j))
THEN
1421 csym%kplink(1, j) = i
1422 csym%kpop(j) = k290_op
1423 wred(nred) = wred(nred) + 1.0_dp
1425 cpassert(csym%kplink(1, j) == i)
1430 IF (.NOT. found)
THEN
1431 CALL cp_abort(__location__, &
1432 "KPOINTS%SYMMETRY with SCHEME GENERAL requires the explicit k-point set "// &
1433 "to be closed under the SPGLIB symmetry operations.")
1439 IF (nskipped > 0)
THEN
1440 CALL cp_warn(__location__, &
1441 "Some SPGLIB k-point mappings are not represented by the K290 backend; "// &
1442 "the GENERAL k-point set was reduced only by the compatible mappings.")
1445 CALL store_general_reduction(csym, xkp_full, rep, wred, nred)
1447 DEALLOCATE (rep, srot, used, wred)
1449 END SUBROUTINE reduce_general_spglib_k290
1459 SUBROUTINE store_general_reduction(csym, xkp_full, rep, wred, nred)
1461 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: xkp_full
1462 INTEGER,
DIMENSION(:),
INTENT(IN) :: rep
1463 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: wred
1464 INTEGER,
INTENT(IN) :: nred
1466 INTEGER :: i, j, nfull
1468 nfull =
SIZE(xkp_full, 2)
1470 ALLOCATE (csym%xkpoint(3, nred), csym%wkpoint(nred))
1472 csym%xkpoint(1:3, i) = xkp_full(1:3, rep(i))
1473 csym%wkpoint(i) = wred(i)
1477 IF (csym%kplink(1, i) == rep(j))
THEN
1478 csym%kplink(2, i) = j
1482 cpassert(csym%kplink(2, i) /= 0)
1485 END SUBROUTINE store_general_reduction
1503 SUBROUTINE reduce_spglib_kpoint_mesh_k290(csym, xkp, wkp, kpop, srot, nrot, &
1504 a1, a2, a3, b1, b2, b3, alat)
1506 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: xkp
1507 REAL(kind=
dp),
DIMENSION(:) :: wkp
1508 INTEGER,
DIMENSION(:) :: kpop
1509 INTEGER,
DIMENSION(:, :, :),
INTENT(IN) :: srot
1510 INTEGER,
INTENT(IN) :: nrot
1511 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: a1, a2, a3, b1, b2, b3
1512 REAL(kind=
dp),
INTENT(IN) :: alat
1514 INTEGER :: i, iop, isign, j, k290_op, nkpts, &
1516 INTEGER,
DIMENSION(3, 3) :: krot
1518 REAL(kind=
dp) :: eps
1519 REAL(kind=
dp),
DIMENSION(3) :: diff, rr
1522 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
1527 csym%kplink(1, :) = 0
1530 IF (csym%kplink(1, i) /= 0) cycle
1532 csym%kplink(1, i) = i
1537 krot = reciprocal_rotation(srot(:, :, iop))
1539 rr(1:3) = matmul(real(krot(1:3, 1:3), kind=
dp), xkp(1:3, i))
1540 IF (isign == 2) rr(1:3) = -rr(1:3)
1543 diff(1:3) = xkp(1:3, j) - rr(1:3)
1544 diff(1:3) = diff(1:3) - anint(diff(1:3))
1545 IF (all(abs(diff(1:3)) < eps))
THEN
1547 IF (csym%kplink(1, j) /= 0)
THEN
1548 cpassert(csym%kplink(1, j) == i)
1552 CALL find_k290_kpoint_operation(csym, xkp(1:3, i), xkp(1:3, j), &
1553 a1, a2, a3, b1, b2, b3, alat, &
1555 IF (.NOT. valid)
THEN
1556 nskipped = nskipped + 1
1559 csym%kplink(1, j) = i
1560 wkp(i) = wkp(i) + 1.0_dp
1565 IF (j > nkpts) cycle
1571 cpassert(csym%kplink(1, i) /= 0)
1572 cpassert(kpop(i) /= 0)
1574 IF (nskipped > 0)
THEN
1575 CALL cp_warn(__location__, &
1576 "Some SPGLIB k-point mappings are not represented by the K290 backend; "// &
1577 "the mesh was reduced only by the compatible mappings.")
1580 END SUBROUTINE reduce_spglib_kpoint_mesh_k290
1597 SUBROUTINE find_k290_kpoint_operation(csym, xref, xtarget, a1, a2, a3, b1, b2, b3, alat, &
1600 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: xref, xtarget, a1, a2, a3, b1, b2, b3
1601 REAL(kind=
dp),
INTENT(IN) :: alat
1602 INTEGER,
INTENT(OUT) :: k290_op
1603 LOGICAL,
INTENT(OUT) :: valid
1605 INTEGER :: ibsign, iop, kr
1606 REAL(kind=
dp) :: eps
1607 REAL(kind=
dp),
DIMENSION(3) :: diff, rr, wcart
1609 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
1613 DO iop = 1, csym%nrtot
1614 IF (iop >
SIZE(csym%rt, 3)) cycle
1615 IF (csym%ibrot(iop) == 0) cycle
1617 wcart(1:3) = alat*(xref(1)*b1(1:3) + xref(2)*b2(1:3) + xref(3)*b3(1:3))
1618 wcart(1:3) = kp_apply_operation(wcart(1:3), csym%rt(1:3, 1:3, iop))
1619 IF (ibsign == 2)
THEN
1620 wcart(1:3) = -wcart(1:3)
1621 kr = -csym%ibrot(iop)
1623 kr = csym%ibrot(iop)
1625 rr(1) = dot_product(a1(1:3), wcart(1:3))/alat
1626 rr(2) = dot_product(a2(1:3), wcart(1:3))/alat
1627 rr(3) = dot_product(a3(1:3), wcart(1:3))/alat
1629 diff(1:3) = xtarget(1:3) - rr(1:3)
1630 diff(1:3) = diff(1:3) - anint(diff(1:3))
1631 IF (all(abs(diff(1:3)) < eps))
THEN
1639 END SUBROUTINE find_k290_kpoint_operation
1648 FUNCTION spglib_operation_score(csym, iop, srot)
RESULT(score)
1650 INTEGER,
INTENT(IN) :: iop
1651 INTEGER,
DIMENSION(3, 3),
INTENT(IN) :: srot
1655 INTEGER,
DIMENSION(3, 3) :: eye, r2
1656 REAL(kind=
dp) :: eps
1658 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
1659 nat =
SIZE(csym%f0, 1)
1662 IF (csym%f0(i, iop) /= i) score = score + 100
1664 IF (any(abs(csym%vt(1:3, iop) - anint(csym%vt(1:3, iop))) > eps)) score = score + 10
1670 r2(1:3, 1:3) = matmul(srot(1:3, 1:3), srot(1:3, 1:3))
1671 IF (any(r2(1:3, 1:3) /= eye(1:3, 1:3))) score = score + 1
1673 END FUNCTION spglib_operation_score
1680 FUNCTION reciprocal_rotation(rot)
RESULT(krot)
1681 INTEGER,
DIMENSION(3, 3),
INTENT(IN) :: rot
1682 INTEGER,
DIMENSION(3, 3) :: krot
1684 REAL(kind=
dp),
DIMENSION(3, 3) :: rinv
1686 rinv =
inv_3x3(real(rot(1:3, 1:3), kind=
dp))
1687 krot(1:3, 1:3) = nint(transpose(rinv(1:3, 1:3)))
1689 END FUNCTION reciprocal_rotation
1708 SUBROUTINE reduce_kpoint_mesh(csym, xkp, wkp, kpop, nc, ib, r, a1, a2, a3, b1, b2, b3, alat)
1710 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: xkp
1711 REAL(kind=
dp),
DIMENSION(:) :: wkp
1712 INTEGER,
DIMENSION(:) :: kpop
1713 INTEGER,
INTENT(IN) :: nc
1714 INTEGER,
DIMENSION(48),
INTENT(IN) :: ib
1715 REAL(kind=
dp),
DIMENSION(3, 3, 48),
INTENT(IN) :: r
1716 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN) :: a1, a2, a3, b1, b2, b3
1717 REAL(kind=
dp),
INTENT(IN) :: alat
1719 INTEGER :: i, ibsign, iop, j, kr, nkpts
1720 REAL(kind=
dp) :: eps
1721 REAL(kind=
dp),
DIMENSION(3) :: diff, rr, wcart
1724 eps = max(1.e-12_dp, 10.0_dp*csym%delta)
1728 csym%kplink(1, :) = 0
1731 IF (csym%kplink(1, i) /= 0) cycle
1733 csym%kplink(1, i) = i
1740 wcart(1:3) = alat*(xkp(1, i)*b1(1:3) + xkp(2, i)*b2(1:3) + xkp(3, i)*b3(1:3))
1741 wcart(1:3) = kp_apply_operation(wcart(1:3), r(1:3, 1:3, kr))
1742 IF (ibsign == 2)
THEN
1743 wcart(1:3) = -wcart(1:3)
1746 rr(1) = dot_product(a1(1:3), wcart(1:3))/alat
1747 rr(2) = dot_product(a2(1:3), wcart(1:3))/alat
1748 rr(3) = dot_product(a3(1:3), wcart(1:3))/alat
1751 diff(1:3) = xkp(1:3, j) - rr(1:3)
1752 diff(1:3) = diff(1:3) - anint(diff(1:3))
1753 IF (all(abs(diff(1:3)) < eps))
THEN
1754 IF (csym%kplink(1, j) == 0)
THEN
1755 csym%kplink(1, j) = i
1756 wkp(i) = wkp(i) + 1.0_dp
1759 cpassert(csym%kplink(1, j) == i)
1765 IF (j > nkpts) cycle
1771 cpassert(csym%kplink(1, i) /= 0)
1772 cpassert(kpop(i) /= 0)
1775 END SUBROUTINE reduce_kpoint_mesh
1784 SUBROUTINE full_grid_gen(nk, xkp, wkp, shift, gamma_centered)
1785 INTEGER,
INTENT(IN) :: nk(3)
1786 REAL(kind=
dp),
DIMENSION(:, :) :: xkp
1787 REAL(kind=
dp),
DIMENSION(:) :: wkp
1788 REAL(kind=
dp),
INTENT(IN) :: shift(3)
1789 LOGICAL,
INTENT(IN),
OPTIONAL :: gamma_centered
1791 INTEGER :: i, idim, ix, iy, iz
1792 INTEGER,
DIMENSION(3) :: ik
1793 LOGICAL :: gamma_mesh
1794 REAL(kind=
dp) :: kpt_latt(3)
1796 IF (
PRESENT(gamma_centered))
THEN
1797 gamma_mesh = gamma_centered
1799 gamma_mesh = .false.
1812 IF (gamma_mesh .AND. mod(nk(idim), 2) == 0)
THEN
1813 kpt_latt(idim) = real(2*ik(idim) - nk(idim), kind=
dp)/ &
1814 (2._dp*real(nk(idim), kind=
dp))
1816 kpt_latt(idim) = real(2*ik(idim) - nk(idim) - 1, kind=
dp)/ &
1817 (2._dp*real(nk(idim), kind=
dp))
1820 xkp(1:3, i) = kpt_latt(1:3)
1825 DO i = 1, nk(1)*nk(2)*nk(3)
1826 xkp(1:3, i) = xkp(1:3, i) + shift(1:3)
1829 END SUBROUTINE full_grid_gen
1837 SUBROUTINE inversion_symm(xkp, wkp, link)
1838 REAL(kind=
dp),
DIMENSION(:, :) :: xkp
1839 REAL(kind=
dp),
DIMENSION(:) :: wkp
1840 INTEGER,
DIMENSION(:) :: link
1842 INTEGER :: i, j, nkpts
1843 REAL(kind=
dp),
DIMENSION(3) :: diff
1845 nkpts =
SIZE(wkp, 1)
1849 IF (link(i) == 0) link(i) = i
1851 IF (wkp(j) == 0) cycle
1852 diff(1:3) = xkp(1:3, i) + xkp(1:3, j)
1853 diff(1:3) = diff(1:3) - anint(diff(1:3))
1854 IF (all(abs(diff(1:3)) < 1.e-12_dp))
THEN
1855 wkp(i) = wkp(i) + wkp(j)
1863 END SUBROUTINE inversion_symm
1871 FUNCTION kp_apply_operation(x, r)
RESULT(y)
1872 REAL(kind=
dp),
INTENT(IN) :: x(3), r(3, 3)
1873 REAL(kind=
dp) :: y(3)
1875 y(1) = r(1, 1)*x(1) + r(1, 2)*x(2) + r(1, 3)*x(3)
1876 y(2) = r(2, 1)*x(1) + r(2, 2)*x(2) + r(2, 3)*x(3)
1877 y(3) = r(3, 1)*x(1) + r(3, 2)*x(2) + r(3, 3)*x(3)
1879 END FUNCTION kp_apply_operation
1888 INTEGER :: i, iunit, j, plevel
1891 IF (iunit >= 0)
THEN
1892 plevel = csym%plevel
1893 WRITE (iunit,
"(/,T2,A)")
"Crystal Symmetry Information"
1894 IF (csym%symlib)
THEN
1895 WRITE (iunit,
'(A,T71,A10)')
" International Symbol: ", adjustr(trim(csym%international_symbol))
1896 WRITE (iunit,
'(A,T71,A10)')
" Point Group Symbol: ", adjustr(trim(csym%pointgroup_symbol))
1897 WRITE (iunit,
'(A,T71,A10)')
" Schoenflies Symbol: ", adjustr(trim(csym%schoenflies))
1899 WRITE (iunit,
'(A,T71,I10)')
" Number of Symmetry Operations: ", csym%n_operations
1900 IF (plevel > 0)
THEN
1901 DO i = 1, csym%n_operations
1902 WRITE (iunit,
'(A,i4,T51,3I10,/,T51,3I10,/,T51,3I10)') &
1903 " Rotation #: ", i, (csym%rotations(j, :, i), j=1, 3)
1904 WRITE (iunit,
'(T36,3F15.7)') csym%translations(:, i)
1908 IF (csym%spglib_requested)
THEN
1909 WRITE (iunit,
"(T2,A)")
"SPGLIB for Crystal Symmetry Information determination is not available"
1911 WRITE (iunit,
"(T2,A)")
"SPGLIB Crystal Symmetry Information was not requested"
1925 INTEGER :: i, iunit, nat, nmesh, plevel
1928 IF (iunit >= 0)
THEN
1929 plevel = csym%plevel
1930 WRITE (iunit,
"(/,T2,A)")
"K-point Symmetry Information"
1931 WRITE (iunit,
'(A,T67,I14)')
" Number of Special K-points: ", csym%nkpoint
1932 WRITE (iunit,
'(T19,A,T74,A)')
" Wavevector Basis ",
" Weight"
1933 DO i = 1, csym%nkpoint
1934 WRITE (iunit,
'(T2,i10,3F10.5,T71,I10)') i, csym%xkpoint(1:3, i), nint(csym%wkpoint(i))
1936 nmesh = csym%mesh(1)*csym%mesh(2)*csym%mesh(3)
1938 WRITE (iunit,
'(/,A,T63,3I6)')
" K-point Mesh: ", csym%mesh(1), csym%mesh(2), csym%mesh(3)
1940 nmesh =
SIZE(csym%kpmesh, 2)
1941 WRITE (iunit,
'(/,A,T70,I10)')
" Explicit K-point Set: ", nmesh
1943 WRITE (iunit,
'(T19,A,T54,A)')
" Wavevector Basis ",
" Special Points Rotation"
1945 WRITE (iunit,
'(T2,i10,3F10.5,T45,3I12)') i, csym%kpmesh(1:3, i), &
1946 csym%kplink(1:2, i), csym%kpop(i)
1948 IF (csym%nrtot > 0)
THEN
1949 WRITE (iunit,
'(/,A)')
" Atom Transformation Table"
1950 nat =
SIZE(csym%f0, 1)
1951 DO i = 1, csym%nrtot
1952 WRITE (iunit,
'(T10,A,I5,(T21,12I5))')
" Rot=", csym%ibrot(i), csym%f0(1:nat, i)
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public togo2018
integer, save, public worlton1972
K-points and crystal symmetry routines.
subroutine, public print_crys_symmetry(csym)
...
subroutine, public kpoint_gen(csym, nk, symm, shift, full_grid, gamma_centered, inversion_symmetry_only, use_spglib_reduction, use_spglib_backend)
...
subroutine, public release_csym_type(csym)
Release the CSYM type.
subroutine, public kpoint_gen_general(csym, xkp_in, wkp_in, symm, full_grid, inversion_symmetry_only, use_spglib_reduction, use_spglib_backend)
Reduce an explicitly supplied GENERAL k-point set.
subroutine, public print_kp_symmetry(csym)
...
subroutine, public crys_sym_gen(csym, scoor, types, hmat, delta, iounit, use_spglib)
...
Defines the basic variable types.
integer, parameter, public dp
K-points and crystal symmetry routines based on.
subroutine, public k290s(iout, nat, nkpoint, nsp, iq1, iq2, iq3, istriz, a1, a2, a3, alat, strain, xkapa, rx, tvec, ty, isc, f0, ntvec, wvk0, wvkl, lwght, lrot, nhash, includ, list, rlist, delta)
...
subroutine, public group1s(iout, a1, a2, a3, nat, ty, x, b1, b2, b3, ihg, ihc, isy, li, nc, indpg, ib, ntvec, v, f0, r, tvec, origin, rx, isc, delta)
...
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Collection of simple mathematical functions and subroutines.
pure real(kind=dp) function, dimension(3, 3), public inv_3x3(a)
Returns the inverse of the 3 x 3 matrix a.
Interface for SPGLIB symmetry routines.
integer function, public spg_get_international(symbol, lattice, position, types, num_atom, symprec)
...
integer function, public spg_get_multiplicity(lattice, position, types, num_atom, symprec)
...
integer function, public spg_get_micro_version()
...
integer function, public spg_get_minor_version()
...
integer function, public spg_get_major_version()
...
integer function, public spg_get_pointgroup(symbol, trans_mat, rotations, num_rotations)
...
integer function, public spg_get_symmetry(rotation, translation, max_size, lattice, position, types, num_atom, symprec)
...
integer function, public spg_get_schoenflies(symbol, lattice, position, types, num_atom, symprec)
...
Utilities for string manipulations.
elemental subroutine, public strip_control_codes(string)
Strip control codes and extended characters from a string, i.e. replace them with blanks.