48 #include "../base/base_uses.f90"
54 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'space_groups'
81 SUBROUTINE spgr_create(scoor, types, cell, gopt_env, eps_symmetry, pol, ranges, &
82 nparticle, n_atom, n_core, n_shell, iunit, print_atoms)
84 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: scoor
85 INTEGER,
DIMENSION(:),
INTENT(IN) :: types
86 TYPE(cell_type),
INTENT(IN),
POINTER :: cell
87 TYPE(gopt_f_type),
INTENT(IN),
POINTER :: gopt_env
88 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: eps_symmetry
89 REAL(kind=
dp),
DIMENSION(3),
INTENT(IN),
OPTIONAL :: pol
90 INTEGER,
DIMENSION(:, :),
INTENT(IN),
OPTIONAL :: ranges
91 INTEGER,
INTENT(IN),
OPTIONAL :: nparticle, n_atom, n_core, n_shell
92 INTEGER,
INTENT(IN) :: iunit
93 LOGICAL,
INTENT(IN) :: print_atoms
95 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_create'
97 CHARACTER(LEN=1000) :: buffer
98 INTEGER :: ierr, nchars, nop, tra_mat(3, 3)
100 INTEGER :: handle, i, j, n_sr_rep
101 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: tmp_types
103 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: tmp_coor
104 TYPE(spgr_type),
POINTER :: spgr
106 CALL timeset(routinen, handle)
108 spgr => gopt_env%spgr
109 cpassert(
ASSOCIATED(spgr))
112 IF (
PRESENT(nparticle))
THEN
113 cpassert(nparticle ==
SIZE(scoor, 2))
114 spgr%nparticle = nparticle
116 spgr%nparticle =
SIZE(scoor, 2)
119 IF (
PRESENT(n_atom))
THEN
121 ELSE IF (
PRESENT(n_core))
THEN
122 spgr%n_atom = spgr%nparticle - n_core
123 ELSE IF (
PRESENT(n_shell))
THEN
124 spgr%n_atom = spgr%nparticle - n_shell
126 spgr%n_atom = spgr%nparticle
129 IF (
PRESENT(n_core))
THEN
131 ELSE IF (
PRESENT(n_shell))
THEN
132 spgr%n_core = n_shell
135 IF (
PRESENT(n_shell))
THEN
136 spgr%n_shell = n_shell
137 ELSE IF (
PRESENT(n_core))
THEN
138 spgr%n_shell = n_core
141 IF (.NOT. (spgr%nparticle == (spgr%n_atom + spgr%n_shell)))
THEN
142 cpabort(
"spgr_create: nparticle not equal to natom + nshell.")
145 spgr%nparticle_sym = spgr%nparticle
146 spgr%n_atom_sym = spgr%n_atom
147 spgr%n_core_sym = spgr%n_core
148 spgr%n_shell_sym = spgr%n_shell
151 spgr%print_atoms = print_atoms
154 IF (
PRESENT(eps_symmetry))
THEN
155 spgr%eps_symmetry = eps_symmetry
159 IF (
PRESENT(pol))
THEN
165 ALLOCATE (spgr%lat(spgr%nparticle))
168 IF (
PRESENT(ranges))
THEN
169 n_sr_rep =
SIZE(ranges, 2)
171 DO j = ranges(1, i), ranges(2, i)
172 spgr%lat(j) = .false.
173 spgr%nparticle_sym = spgr%nparticle_sym - 1
174 IF (j <= spgr%n_atom)
THEN
175 spgr%n_atom_sym = spgr%n_atom_sym - 1
176 ELSE IF (j > spgr%n_atom .AND. j <= spgr%nparticle)
THEN
177 spgr%n_core_sym = spgr%n_core_sym - 1
178 spgr%n_shell_sym = spgr%n_shell_sym - 1
180 cpabort(
"Symmetry exclusion range larger than actual number of particles.")
186 ALLOCATE (tmp_coor(3, spgr%n_atom_sym), tmp_types(spgr%n_atom_sym))
189 DO i = 1, spgr%n_atom
190 IF (spgr%lat(i))
THEN
192 tmp_coor(:, j) = scoor(:, i)
193 tmp_types(j) = types(i)
198 NULLIFY (spgr%cell_ref)
200 CALL cell_copy(cell, spgr%cell_ref, tag=
"CELL_OPT_REF")
201 SELECT CASE (gopt_env%type_id)
203 CALL init_cell(spgr%cell_ref, hmat=cell%hmat)
205 SELECT CASE (gopt_env%cell_method_id)
207 CALL init_cell(spgr%cell_ref, hmat=gopt_env%h_ref)
209 cpabort(
"SPACE_GROUP_SYMMETRY should not be invoked during the cell step.")
211 cpabort(
"SPACE_GROUP_SYMMETRY is not compatible with md.")
213 cpabort(
"SPACE_GROUP_SYMMETRY invoked with an unknown optimization method.")
216 cpabort(
"SPACE_GROUP_SYMMETRY is not compatible with md.")
220 ALLOCATE (spgr%atype(spgr%nparticle))
221 spgr%atype(1:spgr%nparticle) = types(1:spgr%nparticle)
223 spgr%n_operations = 0
228 spgr%space_group_number =
spg_get_international(spgr%international_symbol, transpose(cell%hmat), tmp_coor, tmp_types, &
229 spgr%n_atom_sym, eps_symmetry)
231 nchars =
strlcpy_c2f(buffer, spgr%international_symbol)
232 spgr%international_symbol = buffer(1:nchars)
233 IF (spgr%space_group_number == 0)
THEN
234 cpabort(
"Symmetry Library SPGLIB failed, most likely due a problem with the coordinates.")
238 spgr%n_atom_sym, eps_symmetry)
239 ALLOCATE (spgr%rotations(3, 3, nop), spgr%translations(3, nop))
240 ALLOCATE (spgr%eqatom(nop, spgr%nparticle))
241 ALLOCATE (spgr%lop(nop))
242 spgr%n_operations = nop
244 ierr =
spg_get_symmetry(spgr%rotations, spgr%translations, nop, transpose(cell%hmat), &
245 tmp_coor, tmp_types, spgr%n_atom_sym, eps_symmetry)
248 spgr%n_atom_sym, eps_symmetry)
251 spgr%schoenflies = buffer(1:nchars)
256 spgr%rotations, spgr%n_operations)
258 nchars =
strlcpy_c2f(buffer, spgr%pointgroup_symbol)
259 spgr%pointgroup_symbol = buffer(1:nchars)
262 cpabort(
"Symmetry library SPGLIB not available")
267 DEALLOCATE (tmp_coor, tmp_types)
269 CALL timestop(handle)
287 TYPE(cp_subsys_type),
INTENT(IN),
POINTER :: subsys
288 TYPE(section_vals_type),
INTENT(IN),
POINTER :: geo_section
289 TYPE(gopt_f_type),
INTENT(IN),
POINTER :: gopt_env
290 INTEGER,
INTENT(IN) :: iunit
292 CHARACTER(LEN=*),
PARAMETER :: routinen =
'identify_space_group'
294 INTEGER :: handle, i, k, n_atom, n_core, n_shell, &
295 n_sr_rep, nparticle, shell_index
296 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atype
297 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: ranges
298 INTEGER,
DIMENSION(:),
POINTER :: tmp
299 LOGICAL :: print_atoms
300 REAL(kind=
dp) :: eps_symmetry
301 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: scoord
302 REAL(kind=
dp),
DIMENSION(:),
POINTER :: pol
303 TYPE(cell_type),
POINTER :: cell
304 TYPE(particle_list_type),
POINTER :: core_particles, particles, &
306 TYPE(spgr_type),
POINTER :: spgr
308 CALL timeset(routinen, handle)
317 NULLIFY (core_particles)
318 NULLIFY (shell_particles)
322 cpassert(
ASSOCIATED(cell))
324 CALL cp_subsys_get(subsys, particles=particles, shell_particles=shell_particles, core_particles=core_particles)
326 cpassert(
ASSOCIATED(particles))
327 n_atom = particles%n_els
329 IF (
ASSOCIATED(shell_particles))
THEN
330 n_shell = shell_particles%n_els
331 cpassert(
ASSOCIATED(core_particles))
332 n_core = subsys%core_particles%n_els
334 cpassert(n_core == n_shell)
335 ELSE IF (
ASSOCIATED(core_particles))
THEN
337 cpabort(
"Core particles should not be defined without corresponding shell particles.")
343 nparticle = n_atom + n_shell
344 ALLOCATE (scoord(3, nparticle), atype(nparticle))
346 shell_index = particles%els(i)%shell_index
347 IF (shell_index == 0)
THEN
348 CALL real_to_scaled(scoord(1:3, i), particles%els(i)%r(1:3), cell)
349 CALL get_atomic_kind(atomic_kind=particles%els(i)%atomic_kind, kind_number=atype(i))
351 CALL real_to_scaled(scoord(1:3, i), core_particles%els(shell_index)%r(1:3), cell)
352 CALL get_atomic_kind(atomic_kind=core_particles%els(shell_index)%atomic_kind, kind_number=atype(i))
353 k = n_atom + shell_index
354 CALL real_to_scaled(scoord(1:3, k), shell_particles%els(shell_index)%r(1:3), cell)
355 CALL get_atomic_kind(atomic_kind=shell_particles%els(shell_index)%atomic_kind, kind_number=atype(k))
363 IF (n_sr_rep > 0)
THEN
364 ALLOCATE (ranges(2, n_sr_rep))
367 ranges(:, i) = tmp(:)
369 CALL spgr_create(scoord, atype, cell, gopt_env, eps_symmetry=eps_symmetry, pol=pol(1:3), &
370 ranges=ranges, nparticle=nparticle, n_atom=n_atom, &
371 n_core=n_core, n_shell=n_shell, iunit=iunit, print_atoms=print_atoms)
374 CALL spgr_create(scoord, atype, cell, gopt_env, eps_symmetry=eps_symmetry, pol=pol(1:3), &
375 nparticle=nparticle, n_atom=n_atom, &
376 n_core=n_core, n_shell=n_shell, iunit=iunit, print_atoms=print_atoms)
380 spgr => gopt_env%spgr
383 CALL spgr_reduce_symm(spgr)
384 CALL spgr_rotations_subset(spgr)
386 DEALLOCATE (scoord, atype)
388 CALL timestop(handle)
402 TYPE(spgr_type),
INTENT(INOUT),
POINTER :: spgr
403 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
406 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_find_equivalent_atoms'
408 INTEGER :: handle, i, ia, ib, ir, j, natom, nop, &
410 REAL(kind=
dp) :: diff
411 REAL(kind=
dp),
DIMENSION(3) :: rb, ri, ro, tr
412 REAL(kind=
dp),
DIMENSION(3, 3) :: rot
414 CALL timeset(routinen, handle)
416 nop = spgr%n_operations
418 nshell = spgr%n_shell
420 IF (.NOT. (spgr%nparticle == (natom + nshell)))
THEN
421 cpabort(
"spgr_find_equivalent_atoms: nparticle not equal to natom + nshell.")
424 DO ia = 1, spgr%nparticle
425 spgr%eqatom(:, ia) = ia
430 IF (.NOT. spgr%lat(ia)) cycle
431 ri(1:3) = scoord(1:3, ia)
433 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
434 tr(1:3) = spgr%translations(1:3, ir)
436 IF (.NOT. spgr%lat(ib)) cycle
437 rb(1:3) = scoord(1:3, ib)
438 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)
439 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)
440 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)
441 ro(1) = ro(1) - real(nint(ro(1) - ri(1)),
dp)
442 ro(2) = ro(2) - real(nint(ro(2) - ri(2)),
dp)
443 ro(3) = ro(3) - real(nint(ro(3) - ri(3)),
dp)
444 diff = norm2(ri(:) - ro(:))
445 IF ((diff < spgr%eps_symmetry) .AND. (spgr%atype(ia) == spgr%atype(ib)))
THEN
446 spgr%eqatom(ir, ia) = ib
457 IF (.NOT. spgr%lat(ia)) cycle
458 ri(1:3) = scoord(1:3, ia)
460 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
461 tr(1:3) = spgr%translations(1:3, ir)
464 IF (.NOT. spgr%lat(ib)) cycle
465 rb(1:3) = scoord(1:3, ib)
466 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)
467 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)
468 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)
469 ro(1) = ro(1) - real(nint(ro(1) - ri(1)),
dp)
470 ro(2) = ro(2) - real(nint(ro(2) - ri(2)),
dp)
471 ro(3) = ro(3) - real(nint(ro(3) - ri(3)),
dp)
472 diff = norm2(ri(:) - ro(:))
473 IF ((diff < spgr%eps_symmetry) .AND. (spgr%atype(ia) == spgr%atype(ib)))
THEN
474 spgr%eqatom(ir, ia) = ib
482 CALL timestop(handle)
493 SUBROUTINE spgr_reduce_symm(spgr)
495 TYPE(spgr_type),
INTENT(INOUT),
POINTER :: spgr
497 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_reduce_symm'
499 INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
501 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: x, xold
502 REAL(kind=
dp),
DIMENSION(3) :: ri, ro
503 REAL(kind=
dp),
DIMENSION(3, 3) :: rot
505 CALL timeset(routinen, handle)
507 nop = spgr%n_operations
508 nparticle = spgr%nparticle
509 ALLOCATE (x(3*nparticle), xold(3*nparticle))
513 x(ja + 1) = x(ja + 1) + spgr%pol(1)
514 x(ja + 2) = x(ja + 2) + spgr%pol(2)
515 x(ja + 3) = x(ja + 3) + spgr%pol(3)
522 spgr%lop(ir) = .true.
523 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
525 IF (.NOT. spgr%lat(ia)) cycle
527 ri(1:3) = xold(ja + 1:ja + 3)
528 ro(1) = real(rot(1, 1),
dp)*ri(1) + real(rot(2, 1),
dp)*ri(2) + real(rot(3, 1),
dp)*ri(3)
529 ro(2) = real(rot(1, 2),
dp)*ri(1) + real(rot(2, 2),
dp)*ri(2) + real(rot(3, 2),
dp)*ri(3)
530 ro(3) = real(rot(1, 3),
dp)*ri(1) + real(rot(2, 3),
dp)*ri(2) + real(rot(3, 3),
dp)*ri(3)
531 x(ja + 1:ja + 3) = ro(1:3)
534 IF (.NOT. spgr%lat(ia)) cycle
535 ib = spgr%eqatom(ir, ia)
538 ro = x(jb + 1:jb + 3) - xold(ja + 1:ja + 3)
539 spgr%lop(ir) = (spgr%lop(ir) .AND. (abs(ro(1)) < spgr%eps_symmetry) &
540 .AND. (abs(ro(2)) < spgr%eps_symmetry) &
541 .AND. (abs(ro(3)) < spgr%eps_symmetry))
543 IF (spgr%lop(ir)) nops = nops + 1
546 spgr%n_reduced_operations = nops
549 CALL timestop(handle)
551 END SUBROUTINE spgr_reduce_symm
561 SUBROUTINE spgr_rotations_subset(spgr)
563 TYPE(spgr_type),
INTENT(INOUT),
POINTER :: spgr
565 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_rotations_subset'
567 INTEGER :: handle, i, j
568 INTEGER,
DIMENSION(3, 3) :: d
569 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: mask
571 CALL timeset(routinen, handle)
573 ALLOCATE (mask(spgr%n_operations))
576 DO i = 1, spgr%n_operations
577 IF (.NOT. spgr%lop(i)) mask(i) = .false.
580 DO i = 1, spgr%n_operations - 1
581 IF (.NOT. mask(i)) cycle
582 DO j = i + 1, spgr%n_operations
583 IF (.NOT. mask(j)) cycle
584 d(:, :) = spgr%rotations(:, :, j) - spgr%rotations(:, :, i)
585 IF (sum(abs(d)) == 0) mask(j) = .false.
589 spgr%n_operations_subset = 0
590 DO i = 1, spgr%n_operations
591 IF (mask(i)) spgr%n_operations_subset = spgr%n_operations_subset + 1
594 ALLOCATE (spgr%rotations_subset(3, 3, spgr%n_operations_subset))
597 DO i = 1, spgr%n_operations
600 spgr%rotations_subset(:, :, j) = spgr%rotations(:, :, i)
605 CALL timestop(handle)
607 END SUBROUTINE spgr_rotations_subset
619 TYPE(spgr_type),
INTENT(IN),
POINTER :: spgr
620 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: coord
622 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_apply_rotations_coord'
624 INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
626 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cold
627 REAL(kind=
dp),
DIMENSION(3) :: rf, ri, rn, ro, tr
628 REAL(kind=
dp),
DIMENSION(3, 3) :: rot
630 CALL timeset(routinen, handle)
632 ALLOCATE (cold(
SIZE(coord)))
635 nop = spgr%n_operations
636 nparticle = spgr%nparticle
637 nops = spgr%n_reduced_operations
641 IF (.NOT. spgr%lat(ia)) cycle
646 IF (.NOT. spgr%lop(ir)) cycle
647 ib = spgr%eqatom(ir, ia)
648 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
649 tr(1:3) = spgr%translations(1:3, ir)
652 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)
653 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)
654 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)
655 ro(1) = ro(1) - real(nint(ro(1) - rf(1)),
dp)
656 ro(2) = ro(2) - real(nint(ro(2) - rf(2)),
dp)
657 ro(3) = ro(3) - real(nint(ro(3) - rf(3)),
dp)
658 rn(1:3) = rn(1:3) + ro(1:3)
660 rn = rn/real(nops,
dp)
666 CALL timestop(handle)
680 TYPE(spgr_type),
INTENT(IN),
POINTER :: spgr
681 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: force
683 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_apply_rotations_force'
685 INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
687 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: fold
688 REAL(kind=
dp),
DIMENSION(3) :: ri, rn, ro
689 REAL(kind=
dp),
DIMENSION(3, 3) :: rot
691 CALL timeset(routinen, handle)
693 ALLOCATE (fold(
SIZE(force)))
696 nop = spgr%n_operations
697 nparticle = spgr%nparticle
698 nops = spgr%n_reduced_operations
702 IF (.NOT. spgr%lat(ia)) cycle
706 IF (.NOT. spgr%lop(ir)) cycle
707 ib = spgr%eqatom(ir, ia)
708 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
711 ro(1) = real(rot(1, 1),
dp)*ri(1) + real(rot(2, 1),
dp)*ri(2) + real(rot(3, 1),
dp)*ri(3)
712 ro(2) = real(rot(1, 2),
dp)*ri(1) + real(rot(2, 2),
dp)*ri(2) + real(rot(3, 2),
dp)*ri(3)
713 ro(3) = real(rot(1, 3),
dp)*ri(1) + real(rot(2, 3),
dp)*ri(2) + real(rot(3, 3),
dp)*ri(3)
714 rn(1:3) = rn(1:3) + ro(1:3)
716 rn = rn/real(nops,
dp)
722 CALL timestop(handle)
734 SUBROUTINE spgr_change_basis(roti, roto, nop, h1, h2)
736 INTEGER,
DIMENSION(:, :, :) :: roti
737 REAL(kind=
dp),
DIMENSION(:, :, :) :: roto
739 REAL(kind=
dp),
DIMENSION(3, 3) :: h1, h2
741 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_change_basis'
743 INTEGER :: handle, ir
744 REAL(kind=
dp),
DIMENSION(3, 3) :: h1ih2, h2ih1, ih1, ih2, r, s
746 CALL timeset(routinen, handle)
750 h2ih1 = matmul(h2, ih1)
751 h1ih2 = matmul(h1, ih2)
754 r(:, :) = roti(:, :, ir)
757 roto(:, :, ir) = r(:, :)
760 CALL timestop(handle)
762 END SUBROUTINE spgr_change_basis
775 TYPE(spgr_type),
INTENT(IN),
POINTER :: spgr
776 TYPE(cell_type),
INTENT(IN),
POINTER :: cell
777 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(INOUT) :: stress
779 CHARACTER(LEN=*),
PARAMETER :: routinen =
'spgr_apply_rotations_stress'
781 INTEGER :: handle, i, ir, j, k, l, nop
782 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: roto
783 REAL(kind=
dp),
DIMENSION(3, 3) :: hmat1, hmat2, r, stin
785 CALL timeset(routinen, handle)
787 hmat1 = transpose(cell%hmat)
794 nop = spgr%n_operations_subset
796 ALLOCATE (roto(3, 3, nop))
798 CALL spgr_change_basis(spgr%rotations_subset, roto, spgr%n_operations_subset, hmat1, hmat2)
803 r(:, :) = roto(:, :, ir)
808 stress(i, j) = stress(i, j) + (r(k, i)*r(l, j)*stin(k, l))
814 stress = stress/real(nop,
dp)
818 CALL timestop(handle)
831 TYPE(spgr_type),
INTENT(IN),
POINTER :: spgr
835 IF (spgr%iunit > 0)
THEN
836 WRITE (spgr%iunit,
'(/,T2,A,A)')
"----------------------------------------", &
837 "---------------------------------------"
838 WRITE (spgr%iunit,
"(T2,A,T25,A,T77,A)")
"----",
"SPACE GROUP SYMMETRY INFORMATION",
"----"
839 WRITE (spgr%iunit,
'(T2,A,A)')
"----------------------------------------", &
840 "---------------------------------------"
841 IF (spgr%symlib)
THEN
842 WRITE (spgr%iunit,
'(T2,A,T73,I8)')
"SPGR| SPACE GROUP NUMBER:", &
843 spgr%space_group_number
844 WRITE (spgr%iunit,
'(T2,A,T70,A11)')
"SPGR| INTERNATIONAL SYMBOL:", &
845 trim(adjustr(spgr%international_symbol))
846 WRITE (spgr%iunit,
'(T2,A,T75,A6)')
"SPGR| POINT GROUP SYMBOL:", &
847 trim(adjustr(spgr%pointgroup_symbol))
848 WRITE (spgr%iunit,
'(T2,A,T74,A7)')
"SPGR| SCHOENFLIES SYMBOL:", &
849 trim(adjustr(spgr%schoenflies))
850 WRITE (spgr%iunit,
'(T2,A,T73,I8)')
"SPGR| NUMBER OF SYMMETRY OPERATIONS:", &
852 WRITE (spgr%iunit,
'(T2,A,T73,I8)')
"SPGR| NUMBER OF UNIQUE ROTATIONS:", &
853 spgr%n_operations_subset
854 WRITE (spgr%iunit,
'(T2,A,T73,I8)')
"SPGR| NUMBER OF REDUCED SYMMETRY OPERATIONS:", &
855 spgr%n_reduced_operations
856 WRITE (spgr%iunit,
'(T2,A,T65,I8,I8)')
"SPGR| NUMBER OF PARTICLES AND SYMMETRIZED PARTICLES:", &
857 spgr%nparticle, spgr%nparticle_sym
858 WRITE (spgr%iunit,
'(T2,A,T65,I8,I8)')
"SPGR| NUMBER OF ATOMS AND SYMMETRIZED ATOMS:", &
859 spgr%n_atom, spgr%n_atom_sym
860 WRITE (spgr%iunit,
'(T2,A,T65,I8,I8)')
"SPGR| NUMBER OF CORES AND SYMMETRIZED CORES:", &
861 spgr%n_core, spgr%n_core_sym
862 WRITE (spgr%iunit,
'(T2,A,T65,I8,I8)')
"SPGR| NUMBER OF SHELLS AND SYMMETRIZED SHELLS:", &
863 spgr%n_shell, spgr%n_shell_sym
864 IF (spgr%print_atoms)
THEN
865 WRITE (spgr%iunit, *)
"SPGR| ACTIVE REDUCED SYMMETRY OPERATIONS:", spgr%lop
866 WRITE (spgr%iunit,
'(/,T2,A,A)')
"----------------------------------------", &
867 "---------------------------------------"
868 WRITE (spgr%iunit,
'(T2,A,T34,A,T77,A)')
"----",
"EQUIVALENT ATOMS",
"----"
869 WRITE (spgr%iunit,
'(T2,A,A)')
"----------------------------------------", &
870 "---------------------------------------"
871 DO i = 1, spgr%nparticle
872 DO j = 1, spgr%n_operations
873 WRITE (spgr%iunit,
'(T2,A,T52,I8,I8,I8)')
"SPGR| ATOM | SYMMETRY OPERATION | EQUIVALENT ATOM", &
874 i, j, spgr%eqatom(j, i)
877 WRITE (spgr%iunit,
'(T2,A,A)')
"----------------------------------------", &
878 "---------------------------------------"
879 DO i = 1, spgr%n_operations
880 WRITE (spgr%iunit,
'(T2,A,T46,i4,T51,3I10,/,T51,3I10,/,T51,3I10)') &
881 "SPGR| SYMMETRY OPERATION #:", i, (spgr%rotations(j, :, i), j=1, 3)
882 WRITE (spgr%iunit,
'(T51,3F10.5)') spgr%translations(:, i)
886 WRITE (spgr%iunit,
"(T2,A)")
"SPGLIB for Crystal Symmetry Information determination is not availale"
903 REAL(kind=
dp),
DIMENSION(3, 3),
INTENT(IN) :: stress
904 TYPE(spgr_type),
INTENT(IN),
POINTER :: spgr
906 REAL(kind=
dp),
DIMENSION(3) :: eigval
907 REAL(kind=
dp),
DIMENSION(3, 3) :: eigvec, stress_tensor
909 stress_tensor(:, :) = stress(:, :)*
pascal*1.0e-9_dp
911 IF (spgr%iunit > 0)
THEN
912 WRITE (unit=spgr%iunit, fmt=
'(/,T2,A)') &
913 'SPGR STRESS| Symmetrized stress tensor [GPa]'
914 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T19,3(19X,A1))') &
915 'SPGR STRESS|',
'x',
'y',
'z'
916 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,ES19.11))') &
917 'SPGR STRESS| x', stress_tensor(1, 1:3)
918 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,ES19.11))') &
919 'SPGR STRESS| y', stress_tensor(2, 1:3)
920 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,ES19.11))') &
921 'SPGR STRESS| z', stress_tensor(3, 1:3)
922 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T66,ES20.11)') &
923 'SPGR STRESS| 1/3 Trace', (stress_tensor(1, 1) + &
924 stress_tensor(2, 2) + &
925 stress_tensor(3, 3))/3.0_dp
926 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T66,ES20.11)') &
927 'SPGR STRESS| Determinant',
det_3x3(stress_tensor(1:3, 1), &
928 stress_tensor(1:3, 2), &
929 stress_tensor(1:3, 3))
931 eigvec(:, :) = 0.0_dp
932 CALL jacobi(stress_tensor, eigval, eigvec)
933 WRITE (unit=spgr%iunit, fmt=
'(/,T2,A)') &
934 'SPGR STRESS| Eigenvectors and eigenvalues of the symmetrized stress tensor [GPa]'
935 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T19,3(1X,I19))') &
936 'SPGR STRESS|', 1, 2, 3
937 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,ES19.11))') &
938 'SPGR STRESS| Eigenvalues', eigval(1:3)
939 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,F19.12))') &
940 'SPGR STRESS| x', eigvec(1, 1:3)
941 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,F19.12))') &
942 'SPGR STRESS| y', eigvec(2, 1:3)
943 WRITE (unit=spgr%iunit, fmt=
'(T2,A,T26,3(1X,F19.12))') &
944 'SPGR STRESS| z', eigvec(3, 1:3)
real(kind=dp) function det_3x3(a)
...
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 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)
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)
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_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.