47#include "../base/base_uses.f90"
53 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'space_groups'
80 SUBROUTINE spgr_create(scoor, types, cell, gopt_env, eps_symmetry, pol, ranges, &
81 nparticle, n_atom, n_core, n_shell, iunit, print_atoms)
83 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: scoor
84 INTEGER,
DIMENSION(:),
INTENT(IN) :: types
85 TYPE(
cell_type),
INTENT(IN),
POINTER :: cell
87 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_symmetry
88 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN),
OPTIONAL :: pol
89 INTEGER,
DIMENSION(:, :),
INTENT(IN),
OPTIONAL :: ranges
90 INTEGER,
INTENT(IN),
OPTIONAL :: nparticle, n_atom, n_core, n_shell
91 INTEGER,
INTENT(IN) :: iunit
92 LOGICAL,
INTENT(IN) :: print_atoms
94 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_create'
96 CHARACTER(LEN=1000) :: buffer
97 INTEGER :: ierr, nchars, nop, tra_mat(3, 3)
99 INTEGER :: handle, i, j, n_sr_rep
100 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: tmp_types
102 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: tmp_coor
105 CALL timeset(routinen, handle)
107 spgr => gopt_env%spgr
108 cpassert(
ASSOCIATED(spgr))
113 IF (
PRESENT(nparticle))
THEN
114 cpassert(nparticle ==
SIZE(scoor, 2))
115 spgr%nparticle = nparticle
117 spgr%nparticle =
SIZE(scoor, 2)
120 IF (
PRESENT(n_atom))
THEN
122 ELSE IF (
PRESENT(n_core))
THEN
123 spgr%n_atom = spgr%nparticle - n_core
124 ELSE IF (
PRESENT(n_shell))
THEN
125 spgr%n_atom = spgr%nparticle - n_shell
127 spgr%n_atom = spgr%nparticle
130 IF (
PRESENT(n_core))
THEN
132 ELSE IF (
PRESENT(n_shell))
THEN
133 spgr%n_core = n_shell
136 IF (
PRESENT(n_shell))
THEN
137 spgr%n_shell = n_shell
138 ELSE IF (
PRESENT(n_core))
THEN
139 spgr%n_shell = n_core
142 IF (.NOT. (spgr%nparticle == (spgr%n_atom + spgr%n_shell)))
THEN
143 cpabort(
"spgr_create: nparticle not equal to natom + nshell.")
146 spgr%nparticle_sym = spgr%nparticle
147 spgr%n_atom_sym = spgr%n_atom
148 spgr%n_core_sym = spgr%n_core
149 spgr%n_shell_sym = spgr%n_shell
152 spgr%print_atoms = print_atoms
155 IF (
PRESENT(eps_symmetry))
THEN
156 spgr%eps_symmetry = eps_symmetry
160 IF (
PRESENT(pol))
THEN
166 ALLOCATE (spgr%lat(spgr%nparticle))
169 IF (
PRESENT(ranges))
THEN
170 n_sr_rep =
SIZE(ranges, 2)
172 DO j = ranges(1, i), ranges(2, i)
173 spgr%lat(j) = .false.
174 spgr%nparticle_sym = spgr%nparticle_sym - 1
175 IF (j <= spgr%n_atom)
THEN
176 spgr%n_atom_sym = spgr%n_atom_sym - 1
177 ELSE IF (j > spgr%n_atom .AND. j <= spgr%nparticle)
THEN
178 spgr%n_core_sym = spgr%n_core_sym - 1
179 spgr%n_shell_sym = spgr%n_shell_sym - 1
181 cpabort(
"Symmetry exclusion range larger than actual number of particles.")
187 ALLOCATE (tmp_coor(3, spgr%n_atom_sym), tmp_types(spgr%n_atom_sym))
190 DO i = 1, spgr%n_atom
191 IF (spgr%lat(i))
THEN
193 tmp_coor(:, j) = scoor(:, i)
194 tmp_types(j) = types(i)
199 NULLIFY (spgr%cell_ref)
201 CALL cell_copy(cell, spgr%cell_ref, tag=
"CELL_OPT_REF")
202 SELECT CASE (gopt_env%type_id)
204 CALL init_cell(spgr%cell_ref, hmat=cell%hmat)
206 CALL init_cell(spgr%cell_ref, hmat=gopt_env%h_ref)
208 cpabort(
"SPACE_GROUP_SYMMETRY is not compatible with md.")
212 ALLOCATE (spgr%atype(spgr%nparticle))
213 spgr%atype(1:spgr%nparticle) = types(1:spgr%nparticle)
215 spgr%n_operations = 0
220 spgr%space_group_number =
spg_get_international(spgr%international_symbol, transpose(cell%hmat), tmp_coor, tmp_types, &
221 spgr%n_atom_sym, eps_symmetry)
223 nchars =
strlcpy_c2f(buffer, spgr%international_symbol)
224 spgr%international_symbol = buffer(1:nchars)
225 IF (spgr%space_group_number == 0)
THEN
226 cpabort(
"Symmetry Library SPGLIB failed, most likely due a problem with the coordinates.")
230 spgr%n_atom_sym, eps_symmetry)
231 ALLOCATE (spgr%rotations(3, 3, nop), spgr%translations(3, nop))
232 ALLOCATE (spgr%eqatom(nop, spgr%nparticle))
233 ALLOCATE (spgr%lop(nop))
234 spgr%n_operations = nop
236 ierr =
spg_get_symmetry(spgr%rotations, spgr%translations, nop, transpose(cell%hmat), &
237 tmp_coor, tmp_types, spgr%n_atom_sym, eps_symmetry)
240 spgr%n_atom_sym, eps_symmetry)
243 spgr%schoenflies = buffer(1:nchars)
248 spgr%rotations, spgr%n_operations)
250 nchars =
strlcpy_c2f(buffer, spgr%pointgroup_symbol)
251 spgr%pointgroup_symbol = buffer(1:nchars)
254 cpabort(
"Symmetry library SPGLIB not available")
259 DEALLOCATE (tmp_coor, tmp_types)
261 CALL timestop(handle)
282 INTEGER,
INTENT(IN) :: iunit
284 CHARACTER(LEN=*),
PARAMETER :: routinen =
'identify_space_group'
286 INTEGER :: handle, i, k, n_atom, n_core, n_shell, &
287 n_sr_rep, nparticle, shell_index
288 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atype
289 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: ranges
290 INTEGER,
DIMENSION(:),
POINTER :: tmp
291 LOGICAL :: print_atoms
292 REAL(kind=
dp) :: eps_symmetry
293 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: scoord
294 REAL(kind=
dp),
DIMENSION(:),
POINTER :: pol
300 CALL timeset(routinen, handle)
309 NULLIFY (core_particles)
310 NULLIFY (shell_particles)
314 cpassert(
ASSOCIATED(cell))
316 CALL cp_subsys_get(subsys, particles=particles, shell_particles=shell_particles, core_particles=core_particles)
318 cpassert(
ASSOCIATED(particles))
319 n_atom = particles%n_els
321 IF (
ASSOCIATED(shell_particles))
THEN
322 n_shell = shell_particles%n_els
323 cpassert(
ASSOCIATED(core_particles))
324 n_core = subsys%core_particles%n_els
326 cpassert(n_core == n_shell)
327 ELSE IF (
ASSOCIATED(core_particles))
THEN
329 cpabort(
"Core particles should not be defined without corresponding shell particles.")
335 nparticle = n_atom + n_shell
336 ALLOCATE (scoord(3, nparticle), atype(nparticle))
338 shell_index = particles%els(i)%shell_index
339 IF (shell_index == 0)
THEN
340 CALL real_to_scaled(scoord(1:3, i), particles%els(i)%r(1:3), cell)
341 CALL get_atomic_kind(atomic_kind=particles%els(i)%atomic_kind, kind_number=atype(i))
343 CALL real_to_scaled(scoord(1:3, i), core_particles%els(shell_index)%r(1:3), cell)
344 CALL get_atomic_kind(atomic_kind=core_particles%els(shell_index)%atomic_kind, kind_number=atype(i))
345 k = n_atom + shell_index
346 CALL real_to_scaled(scoord(1:3, k), shell_particles%els(shell_index)%r(1:3), cell)
347 CALL get_atomic_kind(atomic_kind=shell_particles%els(shell_index)%atomic_kind, kind_number=atype(k))
355 IF (n_sr_rep > 0)
THEN
356 ALLOCATE (ranges(2, n_sr_rep))
359 ranges(:, i) = tmp(:)
361 CALL spgr_create(scoord, atype, cell, gopt_env, eps_symmetry=eps_symmetry, pol=pol(1:3), &
362 ranges=ranges, nparticle=nparticle, n_atom=n_atom, &
363 n_core=n_core, n_shell=n_shell, iunit=iunit, print_atoms=print_atoms)
366 CALL spgr_create(scoord, atype, cell, gopt_env, eps_symmetry=eps_symmetry, pol=pol(1:3), &
367 nparticle=nparticle, n_atom=n_atom, &
368 n_core=n_core, n_shell=n_shell, iunit=iunit, print_atoms=print_atoms)
372 spgr => gopt_env%spgr
375 CALL spgr_reduce_symm(spgr)
376 CALL spgr_rotations_subset(spgr)
378 DEALLOCATE (scoord, atype)
380 CALL timestop(handle)
394 TYPE(
spgr_type),
INTENT(INOUT),
POINTER :: spgr
395 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
398 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_find_equivalent_atoms'
400 INTEGER :: handle, i, ia, ib, ir, j, natom, nop, &
402 REAL(kind=
dp) :: diff
403 REAL(kind=
dp),
DIMENSION(3) :: rb, ri, ro, tr
404 REAL(kind=
dp),
DIMENSION(3, 3) :: rot
406 CALL timeset(routinen, handle)
408 nop = spgr%n_operations
410 nshell = spgr%n_shell
412 IF (.NOT. (spgr%nparticle == (natom + nshell)))
THEN
413 cpabort(
"spgr_find_equivalent_atoms: nparticle not equal to natom + nshell.")
416 DO ia = 1, spgr%nparticle
417 spgr%eqatom(:, ia) = ia
422 IF (.NOT. spgr%lat(ia)) cycle
423 ri(1:3) = scoord(1:3, ia)
425 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
426 tr(1:3) = spgr%translations(1:3, ir)
428 IF (.NOT. spgr%lat(ib)) cycle
429 rb(1:3) = scoord(1:3, ib)
430 ro(1) = real(rot(1, 1),
dp)*rb(1) + real(rot(2, 1),
dp)*rb(2) + real(rot(3, 1),
dp)*rb(3) + tr(1)
431 ro(2) = real(rot(1, 2),
dp)*rb(1) + real(rot(2, 2),
dp)*rb(2) + real(rot(3, 2),
dp)*rb(3) + tr(2)
432 ro(3) = real(rot(1, 3),
dp)*rb(1) + real(rot(2, 3),
dp)*rb(2) + real(rot(3, 3),
dp)*rb(3) + tr(3)
433 ro(1) = ro(1) - real(nint(ro(1) - ri(1)),
dp)
434 ro(2) = ro(2) - real(nint(ro(2) - ri(2)),
dp)
435 ro(3) = ro(3) - real(nint(ro(3) - ri(3)),
dp)
436 diff = norm2(ri(:) - ro(:))
437 IF ((diff < spgr%eps_symmetry) .AND. (spgr%atype(ia) == spgr%atype(ib)))
THEN
438 spgr%eqatom(ir, ia) = ib
449 IF (.NOT. spgr%lat(ia)) cycle
450 ri(1:3) = scoord(1:3, ia)
452 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
453 tr(1:3) = spgr%translations(1:3, ir)
456 IF (.NOT. spgr%lat(ib)) cycle
457 rb(1:3) = scoord(1:3, ib)
458 ro(1) = real(rot(1, 1),
dp)*rb(1) + real(rot(2, 1),
dp)*rb(2) + real(rot(3, 1),
dp)*rb(3) + tr(1)
459 ro(2) = real(rot(1, 2),
dp)*rb(1) + real(rot(2, 2),
dp)*rb(2) + real(rot(3, 2),
dp)*rb(3) + tr(2)
460 ro(3) = real(rot(1, 3),
dp)*rb(1) + real(rot(2, 3),
dp)*rb(2) + real(rot(3, 3),
dp)*rb(3) + tr(3)
461 ro(1) = ro(1) - real(nint(ro(1) - ri(1)),
dp)
462 ro(2) = ro(2) - real(nint(ro(2) - ri(2)),
dp)
463 ro(3) = ro(3) - real(nint(ro(3) - ri(3)),
dp)
464 diff = norm2(ri(:) - ro(:))
465 IF ((diff < spgr%eps_symmetry) .AND. (spgr%atype(ia) == spgr%atype(ib)))
THEN
466 spgr%eqatom(ir, ia) = ib
474 CALL timestop(handle)
485 SUBROUTINE spgr_reduce_symm(spgr)
487 TYPE(
spgr_type),
INTENT(INOUT),
POINTER :: spgr
489 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_reduce_symm'
491 INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
493 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: x, xold
494 REAL(kind=
dp),
DIMENSION(3) :: ri, ro
495 REAL(kind=
dp),
DIMENSION(3, 3) :: rot
497 CALL timeset(routinen, handle)
499 nop = spgr%n_operations
500 nparticle = spgr%nparticle
501 ALLOCATE (x(3*nparticle), xold(3*nparticle))
505 x(ja + 1) = x(ja + 1) + spgr%pol(1)
506 x(ja + 2) = x(ja + 2) + spgr%pol(2)
507 x(ja + 3) = x(ja + 3) + spgr%pol(3)
514 spgr%lop(ir) = .true.
515 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
517 IF (.NOT. spgr%lat(ia)) cycle
519 ri(1:3) = xold(ja + 1:ja + 3)
520 ro(1) = real(rot(1, 1),
dp)*ri(1) + real(rot(2, 1),
dp)*ri(2) + real(rot(3, 1),
dp)*ri(3)
521 ro(2) = real(rot(1, 2),
dp)*ri(1) + real(rot(2, 2),
dp)*ri(2) + real(rot(3, 2),
dp)*ri(3)
522 ro(3) = real(rot(1, 3),
dp)*ri(1) + real(rot(2, 3),
dp)*ri(2) + real(rot(3, 3),
dp)*ri(3)
523 x(ja + 1:ja + 3) = ro(1:3)
526 IF (.NOT. spgr%lat(ia)) cycle
527 ib = spgr%eqatom(ir, ia)
530 ro = x(jb + 1:jb + 3) - xold(ja + 1:ja + 3)
531 spgr%lop(ir) = (spgr%lop(ir) .AND. (abs(ro(1)) < spgr%eps_symmetry) &
532 .AND. (abs(ro(2)) < spgr%eps_symmetry) &
533 .AND. (abs(ro(3)) < spgr%eps_symmetry))
535 IF (spgr%lop(ir)) nops = nops + 1
538 spgr%n_reduced_operations = nops
541 CALL timestop(handle)
543 END SUBROUTINE spgr_reduce_symm
553 SUBROUTINE spgr_rotations_subset(spgr)
555 TYPE(
spgr_type),
INTENT(INOUT),
POINTER :: spgr
557 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_rotations_subset'
559 INTEGER :: handle, i, j
560 INTEGER,
DIMENSION(3, 3) :: d
561 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: mask
563 CALL timeset(routinen, handle)
565 ALLOCATE (mask(spgr%n_operations))
568 DO i = 1, spgr%n_operations
569 IF (.NOT. spgr%lop(i)) mask(i) = .false.
572 DO i = 1, spgr%n_operations - 1
573 IF (.NOT. mask(i)) cycle
574 DO j = i + 1, spgr%n_operations
575 IF (.NOT. mask(j)) cycle
576 d(:, :) = spgr%rotations(:, :, j) - spgr%rotations(:, :, i)
577 IF (sum(abs(d)) == 0) mask(j) = .false.
581 spgr%n_operations_subset = 0
582 DO i = 1, spgr%n_operations
583 IF (mask(i)) spgr%n_operations_subset = spgr%n_operations_subset + 1
586 ALLOCATE (spgr%rotations_subset(3, 3, spgr%n_operations_subset))
589 DO i = 1, spgr%n_operations
592 spgr%rotations_subset(:, :, j) = spgr%rotations(:, :, i)
597 CALL timestop(handle)
599 END SUBROUTINE spgr_rotations_subset
611 TYPE(
spgr_type),
INTENT(IN),
POINTER :: spgr
612 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: coord
614 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_apply_rotations_coord'
616 INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
618 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cold
619 REAL(kind=
dp),
DIMENSION(3) :: rf, ri, rn, ro, tr
620 REAL(kind=
dp),
DIMENSION(3, 3) :: rot
622 CALL timeset(routinen, handle)
624 ALLOCATE (cold(
SIZE(coord)))
627 nop = spgr%n_operations
628 nparticle = spgr%nparticle
629 nops = spgr%n_reduced_operations
633 IF (.NOT. spgr%lat(ia)) cycle
638 IF (.NOT. spgr%lop(ir)) cycle
639 ib = spgr%eqatom(ir, ia)
640 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
641 tr(1:3) = spgr%translations(1:3, ir)
644 ro(1) = real(rot(1, 1),
dp)*ri(1) + real(rot(2, 1),
dp)*ri(2) + real(rot(3, 1),
dp)*ri(3) + tr(1)
645 ro(2) = real(rot(1, 2),
dp)*ri(1) + real(rot(2, 2),
dp)*ri(2) + real(rot(3, 2),
dp)*ri(3) + tr(2)
646 ro(3) = real(rot(1, 3),
dp)*ri(1) + real(rot(2, 3),
dp)*ri(2) + real(rot(3, 3),
dp)*ri(3) + tr(3)
647 ro(1) = ro(1) - real(nint(ro(1) - rf(1)),
dp)
648 ro(2) = ro(2) - real(nint(ro(2) - rf(2)),
dp)
649 ro(3) = ro(3) - real(nint(ro(3) - rf(3)),
dp)
650 rn(1:3) = rn(1:3) + ro(1:3)
652 rn = rn/real(nops,
dp)
658 CALL timestop(handle)
672 TYPE(
spgr_type),
INTENT(IN),
POINTER :: spgr
673 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: force
675 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_apply_rotations_force'
677 INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
679 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: fold
680 REAL(kind=
dp),
DIMENSION(3) :: ri, rn, ro
681 REAL(kind=
dp),
DIMENSION(3, 3) :: rot
683 CALL timeset(routinen, handle)
685 ALLOCATE (fold(
SIZE(force)))
688 nop = spgr%n_operations
689 nparticle = spgr%nparticle
690 nops = spgr%n_reduced_operations
694 IF (.NOT. spgr%lat(ia)) cycle
698 IF (.NOT. spgr%lop(ir)) cycle
699 ib = spgr%eqatom(ir, ia)
700 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
703 ro(1) = real(rot(1, 1),
dp)*ri(1) + real(rot(2, 1),
dp)*ri(2) + real(rot(3, 1),
dp)*ri(3)
704 ro(2) = real(rot(1, 2),
dp)*ri(1) + real(rot(2, 2),
dp)*ri(2) + real(rot(3, 2),
dp)*ri(3)
705 ro(3) = real(rot(1, 3),
dp)*ri(1) + real(rot(2, 3),
dp)*ri(2) + real(rot(3, 3),
dp)*ri(3)
706 rn(1:3) = rn(1:3) + ro(1:3)
708 rn = rn/real(nops,
dp)
714 CALL timestop(handle)
726 SUBROUTINE spgr_change_basis(roti, roto, nop, h1, h2)
728 INTEGER,
DIMENSION(:, :, :) :: roti
729 REAL(kind=
dp),
DIMENSION(:, :, :) :: roto
731 REAL(kind=
dp),
DIMENSION(3, 3) :: h1, h2
733 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_change_basis'
735 INTEGER :: handle, ir
736 REAL(kind=
dp),
DIMENSION(3, 3) :: h1ih2, h2ih1, ih1, ih2, r, s
738 CALL timeset(routinen, handle)
742 h2ih1 = matmul(h2, ih1)
743 h1ih2 = matmul(h1, ih2)
746 r(:, :) = roti(:, :, ir)
749 roto(:, :, ir) = r(:, :)
752 CALL timestop(handle)
754 END SUBROUTINE spgr_change_basis
767 TYPE(
spgr_type),
INTENT(IN),
POINTER :: spgr
768 TYPE(
cell_type),
INTENT(IN),
POINTER :: cell
769 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(INOUT) :: stress
771 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_apply_rotations_stress'
773 INTEGER :: handle, i, ir, j, k, l, nop
774 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: roto
775 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat1, hmat2, r, stin
777 CALL timeset(routinen, handle)
779 hmat1 = transpose(cell%hmat)
786 nop = spgr%n_operations_subset
788 ALLOCATE (roto(3, 3, nop))
790 CALL spgr_change_basis(spgr%rotations_subset, roto, spgr%n_operations_subset, hmat1, hmat2)
795 r(:, :) = roto(:, :, ir)
800 stress(i, j) = stress(i, j) + (r(k, i)*r(l, j)*stin(k, l))
806 stress = stress/real(nop,
dp)
810 CALL timestop(handle)
821 TYPE(
spgr_type),
INTENT(IN),
POINTER :: spgr
822 TYPE(
cell_type),
INTENT(INOUT),
POINTER :: cell
824 INTEGER :: i, ir, nop
825 REAL(kind=
dp) :: scale
826 REAL(kind=
dp),
DIMENSION(3) :: abc, cell_angle
827 REAL(kind=
dp),
DIMENSION(3, 3) :: metric, metric_sym, rot
829 cpassert(
ALLOCATED(spgr%rotations_subset))
830 nop = spgr%n_operations_subset
833 metric = matmul(transpose(cell%hmat), cell%hmat)
836 rot = real(spgr%rotations_subset(:, :, ir),
dp)
837 metric_sym = metric_sym + matmul(rot, matmul(metric, transpose(rot)))
839 metric_sym = metric_sym/real(nop,
dp)
843 scale = (cell%deth**2/
det_3x3(metric_sym))**(1.0_dp/3.0_dp)
844 metric_sym = scale*metric_sym
847 abc(i) = sqrt(metric_sym(i, i))
849 cell_angle(1) = acos(max(-1.0_dp, min(1.0_dp, metric_sym(2, 3)/(abc(2)*abc(3)))))
850 cell_angle(2) = acos(max(-1.0_dp, min(1.0_dp, metric_sym(1, 3)/(abc(1)*abc(3)))))
851 cell_angle(3) = acos(max(-1.0_dp, min(1.0_dp, metric_sym(1, 2)/(abc(1)*abc(2)))))
852 CALL set_cell_param(cell, cell_length=abc, cell_angle=cell_angle, &
853 periodic=cell%perd, do_init_cell=.true.)
866 TYPE(
spgr_type),
INTENT(IN),
POINTER :: spgr
870 IF (spgr%iunit > 0)
THEN
871 WRITE (spgr%iunit,
'(/,T2,A,A)')
"----------------------------------------", &
872 "---------------------------------------"
873 WRITE (spgr%iunit,
"(T2,A,T25,A,T77,A)")
"----",
"SPACE GROUP SYMMETRY INFORMATION",
"----"
874 WRITE (spgr%iunit,
'(T2,A,A)')
"----------------------------------------", &
875 "---------------------------------------"
876 IF (spgr%symlib)
THEN
877 WRITE (spgr%iunit,
'(T2,A,T73,I8)')
"SPGR| SPACE GROUP NUMBER:", &
878 spgr%space_group_number
879 WRITE (spgr%iunit,
'(T2,A,T70,A11)')
"SPGR| INTERNATIONAL SYMBOL:", &
880 trim(adjustr(spgr%international_symbol))
881 WRITE (spgr%iunit,
'(T2,A,T75,A6)')
"SPGR| POINT GROUP SYMBOL:", &
882 trim(adjustr(spgr%pointgroup_symbol))
883 WRITE (spgr%iunit,
'(T2,A,T74,A7)')
"SPGR| SCHOENFLIES SYMBOL:", &
884 trim(adjustr(spgr%schoenflies))
885 WRITE (spgr%iunit,
'(T2,A,T73,I8)')
"SPGR| NUMBER OF SYMMETRY OPERATIONS:", &
887 WRITE (spgr%iunit,
'(T2,A,T73,I8)')
"SPGR| NUMBER OF UNIQUE ROTATIONS:", &
888 spgr%n_operations_subset
889 WRITE (spgr%iunit,
'(T2,A,T73,I8)')
"SPGR| NUMBER OF REDUCED SYMMETRY OPERATIONS:", &
890 spgr%n_reduced_operations
891 WRITE (spgr%iunit,
'(T2,A,T65,I8,I8)')
"SPGR| NUMBER OF PARTICLES AND SYMMETRIZED PARTICLES:", &
892 spgr%nparticle, spgr%nparticle_sym
893 WRITE (spgr%iunit,
'(T2,A,T65,I8,I8)')
"SPGR| NUMBER OF ATOMS AND SYMMETRIZED ATOMS:", &
894 spgr%n_atom, spgr%n_atom_sym
895 WRITE (spgr%iunit,
'(T2,A,T65,I8,I8)')
"SPGR| NUMBER OF CORES AND SYMMETRIZED CORES:", &
896 spgr%n_core, spgr%n_core_sym
897 WRITE (spgr%iunit,
'(T2,A,T65,I8,I8)')
"SPGR| NUMBER OF SHELLS AND SYMMETRIZED SHELLS:", &
898 spgr%n_shell, spgr%n_shell_sym
899 IF (spgr%print_atoms)
THEN
900 WRITE (spgr%iunit, *)
"SPGR| ACTIVE REDUCED SYMMETRY OPERATIONS:", spgr%lop
901 WRITE (spgr%iunit,
'(/,T2,A,A)')
"----------------------------------------", &
902 "---------------------------------------"
903 WRITE (spgr%iunit,
'(T2,A,T34,A,T77,A)')
"----",
"EQUIVALENT ATOMS",
"----"
904 WRITE (spgr%iunit,
'(T2,A,A)')
"----------------------------------------", &
905 "---------------------------------------"
906 DO i = 1, spgr%nparticle
907 DO j = 1, spgr%n_operations
908 WRITE (spgr%iunit,
'(T2,A,T52,I8,I8,I8)')
"SPGR| ATOM | SYMMETRY OPERATION | EQUIVALENT ATOM", &
909 i, j, spgr%eqatom(j, i)
912 WRITE (spgr%iunit,
'(T2,A,A)')
"----------------------------------------", &
913 "---------------------------------------"
914 DO i = 1, spgr%n_operations
915 WRITE (spgr%iunit,
'(T2,A,T46,i4,T51,3I10,/,T51,3I10,/,T51,3I10)') &
916 "SPGR| SYMMETRY OPERATION #:", i, (spgr%rotations(j, :, i), j=1, 3)
917 WRITE (spgr%iunit,
'(T51,3F10.5)') spgr%translations(:, i)
921 WRITE (spgr%iunit,
"(T2,A)")
"SPGLIB for Crystal Symmetry Information determination is not availale"
938 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: stress
939 TYPE(
spgr_type),
INTENT(IN),
POINTER :: spgr
941 REAL(kind=
dp),
DIMENSION(3) :: eigval
942 REAL(kind=
dp),
DIMENSION(3, 3) :: eigvec, stress_tensor
944 stress_tensor(:, :) = stress(:, :)*
pascal*1.0e-9_dp
946 IF (spgr%iunit > 0)
THEN
947 WRITE (unit=spgr%iunit, fmt=
'(/,T2,A)') &
948 'SPGR STRESS| Symmetrized stress tensor [GPa]'
949 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T19,3(19X,A1))') &
950 'SPGR STRESS|',
'x',
'y',
'z'
951 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,ES19.11))') &
952 'SPGR STRESS| x', stress_tensor(1, 1:3)
953 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,ES19.11))') &
954 'SPGR STRESS| y', stress_tensor(2, 1:3)
955 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,ES19.11))') &
956 'SPGR STRESS| z', stress_tensor(3, 1:3)
957 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T66,ES20.11)') &
958 'SPGR STRESS| 1/3 Trace', (stress_tensor(1, 1) + &
959 stress_tensor(2, 2) + &
960 stress_tensor(3, 3))/3.0_dp
961 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T66,ES20.11)') &
962 'SPGR STRESS| Determinant',
det_3x3(stress_tensor(1:3, 1), &
963 stress_tensor(1:3, 2), &
964 stress_tensor(1:3, 3))
966 eigvec(:, :) = 0.0_dp
967 CALL jacobi(stress_tensor, eigval, eigvec)
968 WRITE (unit=spgr%iunit, fmt=
'(/,T2,A)') &
969 'SPGR STRESS| Eigenvectors and eigenvalues of the symmetrized stress tensor [GPa]'
970 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T19,3(1X,I19))') &
971 'SPGR STRESS|', 1, 2, 3
972 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,ES19.11))') &
973 'SPGR STRESS| Eigenvalues', eigval(1:3)
974 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,F19.12))') &
975 'SPGR STRESS| x', eigvec(1, 1:3)
976 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,F19.12))') &
977 'SPGR STRESS| y', eigvec(2, 1:3)
978 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,F19.12))') &
979 'SPGR STRESS| z', eigvec(3, 1:3)
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public togo2018
Handles all functions related to the CELL.
subroutine, public set_cell_param(cell, cell_length, cell_angle, periodic, do_init_cell)
Sets the cell using the internal parameters (a,b,c) (alpha,beta,gamma) using the convention: a parall...
subroutine, public init_cell(cell, hmat, periodic)
Initialise/readjust a simulation cell after hmat has been changed.
subroutine, public cell_create(cell, hmat, periodic, tag)
allocates and initializes a cell
Handles all functions related to the CELL.
subroutine, public scaled_to_real(r, s, cell)
Transform scaled cell coordinates real coordinates. r=h*s.
subroutine, public real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
subroutine, public cell_copy(cell_in, cell_out, tag)
Copy cell variable.
types that represent a subsys, i.e. a part of the system
subroutine, public cp_subsys_get(subsys, ref_count, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell)
returns information about various attributes of the given subsys
contains a functional that calculates the energy and its derivatives for the geometry optimizer
Defines the basic variable types.
integer, parameter, public dp
Collection of simple mathematical functions and subroutines.
subroutine, public jacobi(a, d, v)
Jacobi matrix diagonalization. The eigenvalues are returned in vector d and the eigenvectors are retu...
pure real(kind=dp) function, dimension(3, 3), public inv_3x3(a)
Returns the inverse of the 3 x 3 matrix a.
represent a simple array based list of the given type
Definition of physical constants:
real(kind=dp), parameter, public pascal
Space Group Symmetry Type Module (version 1.0, Ferbruary 12, 2021)
subroutine, public cleanup_spgr_type(spgr)
Cleanup all buffers the SPGR type.
Space Group Symmetry Module (version 1.0, January 16, 2020)
subroutine, public spgr_create(scoor, types, cell, gopt_env, eps_symmetry, pol, ranges, nparticle, n_atom, n_core, n_shell, iunit, print_atoms)
routine creates the space group structure
subroutine, public spgr_find_equivalent_atoms(spgr, scoord)
routine indentifies the equivalent atoms for each rotation matrix.
subroutine, public print_spgr(spgr)
routine prints Space Group Information.
subroutine, public spgr_apply_rotations_stress(spgr, cell, stress)
routine applies the rotation matrices to the stress tensor.
subroutine, public spgr_project_cell_metric(spgr, cell)
Project a cell onto the metric preserved by the selected space-group rotations.
subroutine, public spgr_apply_rotations_coord(spgr, coord)
routine applies the rotation matrices to the coordinates.
subroutine, public identify_space_group(subsys, geo_section, gopt_env, iunit)
routine indentifies the space group and finds rotation matrices.
subroutine, public spgr_apply_rotations_force(spgr, force)
routine applies the rotation matrices to the forces.
subroutine, public spgr_write_stress_tensor(stress, spgr)
Variable precision output of the symmetrized stress tensor.
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_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.
integer function, public strlcpy_c2f(fstring, cstring)
Copy the content of a \0-terminated C-string to a finite-length Fortran string.
Type defining parameters related to the simulation cell.
represents a system: atoms, molecules, their pos,vel,...
calculates the potential energy of a system, and its derivatives
represent a list of objects