(git:e7e05ae)
space_groups.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief Space Group Symmetry Module (version 1.0, January 16, 2020)
10 !> \par History
11 !> Pierre-André Cazade [pcazade] 01.2020 - University of Limerick
12 !> \author Pierre-André Cazade (first version)
13 ! **************************************************************************************************
16  USE bibliography, ONLY: togo2018,&
17  cite_reference
18  USE cell_methods, ONLY: cell_create,&
19  init_cell
20  USE cell_types, ONLY: cell_copy,&
21  cell_type,&
24  USE cp_subsys_types, ONLY: cp_subsys_get,&
25  cp_subsys_type
26  USE gopt_f_types, ONLY: gopt_f_type
33  USE input_section_types, ONLY: section_vals_type,&
35  USE kinds, ONLY: dp
36  USE mathlib, ONLY: det_3x3,&
37  inv_3x3,&
38  jacobi
39  USE particle_list_types, ONLY: particle_list_type
40  USE physcon, ONLY: pascal
41  USE space_groups_types, ONLY: spgr_type
47  USE string_utilities, ONLY: strlcpy_c2f
48 #include "../base/base_uses.f90"
49 
50  IMPLICIT NONE
51 
52  PRIVATE
53 
54  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'space_groups'
55 
59 
60 CONTAINS
61 
62 ! **************************************************************************************************
63 !> \brief routine creates the space group structure
64 !> \param scoor ...
65 !> \param types ...
66 !> \param cell ...
67 !> \param gopt_env ...
68 !> \param eps_symmetry ...
69 !> \param pol ...
70 !> \param ranges ...
71 !> \param nparticle ...
72 !> \param n_atom ...
73 !> \param n_core ...
74 !> \param n_shell ...
75 !> \param iunit ...
76 !> \param print_atoms ...
77 !> \par History
78 !> 01.2020 created [pcazade]
79 !> \author Pierre-André Cazade (first version)
80 ! **************************************************************************************************
81  SUBROUTINE spgr_create(scoor, types, cell, gopt_env, eps_symmetry, pol, ranges, &
82  nparticle, n_atom, n_core, n_shell, iunit, print_atoms)
83 
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
94 
95  CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_create'
96 #ifdef __SPGLIB
97  CHARACTER(LEN=1000) :: buffer
98  INTEGER :: ierr, nchars, nop, tra_mat(3, 3)
99 #endif
100  INTEGER :: handle, i, j, n_sr_rep
101  INTEGER, ALLOCATABLE, DIMENSION(:) :: tmp_types
102  LOGICAL :: spglib
103  REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: tmp_coor
104  TYPE(spgr_type), POINTER :: spgr
105 
106  CALL timeset(routinen, handle)
107 
108  spgr => gopt_env%spgr
109  cpassert(ASSOCIATED(spgr))
110 
111  !..total number of particles (atoms plus shells)
112  IF (PRESENT(nparticle)) THEN
113  cpassert(nparticle == SIZE(scoor, 2))
114  spgr%nparticle = nparticle
115  ELSE
116  spgr%nparticle = SIZE(scoor, 2)
117  END IF
118 
119  IF (PRESENT(n_atom)) THEN
120  spgr%n_atom = n_atom
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
125  ELSE
126  spgr%n_atom = spgr%nparticle
127  END IF
128 
129  IF (PRESENT(n_core)) THEN
130  spgr%n_core = n_core
131  ELSE IF (PRESENT(n_shell)) THEN
132  spgr%n_core = n_shell
133  END IF
134 
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
139  END IF
140 
141  IF (.NOT. (spgr%nparticle == (spgr%n_atom + spgr%n_shell))) THEN
142  cpabort("spgr_create: nparticle not equal to natom + nshell.")
143  END IF
144 
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
149 
150  spgr%iunit = iunit
151  spgr%print_atoms = print_atoms
152 
153  ! accuracy for symmetry
154  IF (PRESENT(eps_symmetry)) THEN
155  spgr%eps_symmetry = eps_symmetry
156  END IF
157 
158  ! vector to test reduced symmetry
159  IF (PRESENT(pol)) THEN
160  spgr%pol(1) = pol(1)
161  spgr%pol(2) = pol(2)
162  spgr%pol(3) = pol(3)
163  END IF
164 
165  ALLOCATE (spgr%lat(spgr%nparticle))
166  spgr%lat = .true.
167 
168  IF (PRESENT(ranges)) THEN
169  n_sr_rep = SIZE(ranges, 2)
170  DO i = 1, n_sr_rep
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
179  ELSE
180  cpabort("Symmetry exclusion range larger than actual number of particles.")
181  END IF
182  END DO
183  END DO
184  END IF
185 
186  ALLOCATE (tmp_coor(3, spgr%n_atom_sym), tmp_types(spgr%n_atom_sym))
187 
188  j = 0
189  DO i = 1, spgr%n_atom
190  IF (spgr%lat(i)) THEN
191  j = j + 1
192  tmp_coor(:, j) = scoor(:, i)
193  tmp_types(j) = types(i)
194  END IF
195  END DO
196 
197  !..set cell values
198  NULLIFY (spgr%cell_ref)
199  CALL cell_create(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.")
210  CASE (default_cell_md_id)
211  cpabort("SPACE_GROUP_SYMMETRY is not compatible with md.")
212  CASE DEFAULT
213  cpabort("SPACE_GROUP_SYMMETRY invoked with an unknown optimization method.")
214  END SELECT
215  CASE DEFAULT
216  cpabort("SPACE_GROUP_SYMMETRY is not compatible with md.")
217  END SELECT
218 
219  ! atom types
220  ALLOCATE (spgr%atype(spgr%nparticle))
221  spgr%atype(1:spgr%nparticle) = types(1:spgr%nparticle)
222 
223  spgr%n_operations = 0
224 
225 #ifdef __SPGLIB
226  spglib = .true.
227  CALL cite_reference(togo2018)
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)
230  buffer = ''
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.")
235  spglib = .false.
236  ELSE
237  nop = spg_get_multiplicity(transpose(cell%hmat), tmp_coor, tmp_types, &
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
243  spgr%lop = .true.
244  ierr = spg_get_symmetry(spgr%rotations, spgr%translations, nop, transpose(cell%hmat), &
245  tmp_coor, tmp_types, spgr%n_atom_sym, eps_symmetry)
246  ! Schoenflies Symbol
247  ierr = spg_get_schoenflies(spgr%schoenflies, transpose(cell%hmat), tmp_coor, tmp_types, &
248  spgr%n_atom_sym, eps_symmetry)
249  buffer = ''
250  nchars = strlcpy_c2f(buffer, spgr%schoenflies)
251  spgr%schoenflies = buffer(1:nchars)
252 
253  ! Point Group
254  tra_mat = 0
255  ierr = spg_get_pointgroup(spgr%pointgroup_symbol, tra_mat, &
256  spgr%rotations, spgr%n_operations)
257  buffer = ''
258  nchars = strlcpy_c2f(buffer, spgr%pointgroup_symbol)
259  spgr%pointgroup_symbol = buffer(1:nchars)
260  END IF
261 #else
262  cpabort("Symmetry library SPGLIB not available")
263  spglib = .false.
264 #endif
265  spgr%symlib = spglib
266 
267  DEALLOCATE (tmp_coor, tmp_types)
268 
269  CALL timestop(handle)
270 
271  END SUBROUTINE spgr_create
272 
273 ! **************************************************************************************************
274 !> \brief routine indentifies the space group and finds rotation matrices.
275 !> \param subsys ...
276 !> \param geo_section ...
277 !> \param gopt_env ...
278 !> \param iunit ...
279 !> \par History
280 !> 01.2020 created [pcazade]
281 !> \author Pierre-André Cazade (first version)
282 !> \note rotation matrices innclude translations and translation symmetry:
283 !> it works with supercells as well.
284 ! **************************************************************************************************
285  SUBROUTINE identify_space_group(subsys, geo_section, gopt_env, iunit)
286 
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
291 
292  CHARACTER(LEN=*), PARAMETER :: routinen = 'identify_space_group'
293 
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, &
305  shell_particles
306  TYPE(spgr_type), POINTER :: spgr
307 
308  CALL timeset(routinen, handle)
309 
310  n_sr_rep = 0
311  nparticle = 0
312  n_atom = 0
313  n_core = 0
314  n_shell = 0
315 
316  NULLIFY (particles)
317  NULLIFY (core_particles)
318  NULLIFY (shell_particles)
319 
320  NULLIFY (cell)
321  cell => subsys%cell
322  cpassert(ASSOCIATED(cell))
323 
324  CALL cp_subsys_get(subsys, particles=particles, shell_particles=shell_particles, core_particles=core_particles)
325 
326  cpassert(ASSOCIATED(particles))
327  n_atom = particles%n_els
328  ! Check if we have other kinds of particles in this subsystem
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
333  ! The same number of shell and core particles is assumed
334  cpassert(n_core == n_shell)
335  ELSE IF (ASSOCIATED(core_particles)) THEN
336  ! This case should not occur at the moment
337  cpabort("Core particles should not be defined without corresponding shell particles.")
338  ELSE
339  n_core = 0
340  n_shell = 0
341  END IF
342 
343  nparticle = n_atom + n_shell
344  ALLOCATE (scoord(3, nparticle), atype(nparticle))
345  DO i = 1, n_atom
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))
350  ELSE
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))
356  END IF
357  END DO
358 
359  CALL section_vals_val_get(geo_section, "SPGR_PRINT_ATOMS", l_val=print_atoms)
360  CALL section_vals_val_get(geo_section, "EPS_SYMMETRY", r_val=eps_symmetry)
361  CALL section_vals_val_get(geo_section, "SYMM_REDUCTION", r_vals=pol)
362  CALL section_vals_val_get(geo_section, "SYMM_EXCLUDE_RANGE", n_rep_val=n_sr_rep)
363  IF (n_sr_rep > 0) THEN
364  ALLOCATE (ranges(2, n_sr_rep))
365  DO i = 1, n_sr_rep
366  CALL section_vals_val_get(geo_section, "SYMM_EXCLUDE_RANGE", i_rep_val=i, i_vals=tmp)
367  ranges(:, i) = tmp(:)
368  END DO
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)
372  DEALLOCATE (ranges)
373  ELSE
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)
377  END IF
378 
379  NULLIFY (spgr)
380  spgr => gopt_env%spgr
381 
382  CALL spgr_find_equivalent_atoms(spgr, scoord)
383  CALL spgr_reduce_symm(spgr)
384  CALL spgr_rotations_subset(spgr)
385 
386  DEALLOCATE (scoord, atype)
387 
388  CALL timestop(handle)
389 
390  END SUBROUTINE identify_space_group
391 
392 ! **************************************************************************************************
393 !> \brief routine indentifies the equivalent atoms for each rotation matrix.
394 !> \param spgr ...
395 !> \param scoord ...
396 !> \par History
397 !> 01.2020 created [pcazade]
398 !> \author Pierre-André Cazade (first version)
399 ! **************************************************************************************************
400  SUBROUTINE spgr_find_equivalent_atoms(spgr, scoord)
401 
402  TYPE(spgr_type), INTENT(INOUT), POINTER :: spgr
403  REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :), &
404  INTENT(IN) :: scoord
405 
406  CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_find_equivalent_atoms'
407 
408  INTEGER :: handle, i, ia, ib, ir, j, natom, nop, &
409  nshell
410  REAL(kind=dp) :: diff
411  REAL(kind=dp), DIMENSION(3) :: rb, ri, ro, tr
412  REAL(kind=dp), DIMENSION(3, 3) :: rot
413 
414  CALL timeset(routinen, handle)
415 
416  nop = spgr%n_operations
417  natom = spgr%n_atom
418  nshell = spgr%n_shell
419 
420  IF (.NOT. (spgr%nparticle == (natom + nshell))) THEN
421  cpabort("spgr_find_equivalent_atoms: nparticle not equal to natom + nshell.")
422  END IF
423 
424  DO ia = 1, spgr%nparticle
425  spgr%eqatom(:, ia) = ia
426  END DO
427 
428  !$OMP PARALLEL DO PRIVATE (ia,ib,ir,ri,rb,ro,rot,tr,diff) SHARED (spgr,scoord,natom,nop) DEFAULT(NONE)
429  DO ia = 1, natom
430  IF (.NOT. spgr%lat(ia)) cycle
431  ri(1:3) = scoord(1:3, ia)
432  DO ir = 1, nop
433  rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
434  tr(1:3) = spgr%translations(1:3, ir)
435  DO ib = 1, natom
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
447  EXIT
448  END IF
449  END DO
450  END DO
451  END DO
452  !$OMP END PARALLEL DO
453 
454  !$OMP PARALLEL DO PRIVATE (i,j,ia,ib,ir,ri,rb,ro,rot,tr,diff) SHARED (spgr,scoord,natom,nshell,nop) DEFAULT(NONE)
455  DO i = 1, nshell
456  ia = natom + i
457  IF (.NOT. spgr%lat(ia)) cycle
458  ri(1:3) = scoord(1:3, ia)
459  DO ir = 1, nop
460  rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
461  tr(1:3) = spgr%translations(1:3, ir)
462  DO j = 1, nshell
463  ib = natom + j
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
475  EXIT
476  END IF
477  END DO
478  END DO
479  END DO
480  !$OMP END PARALLEL DO
481 
482  CALL timestop(handle)
483 
484  END SUBROUTINE spgr_find_equivalent_atoms
485 
486 ! **************************************************************************************************
487 !> \brief routine looks for operations compatible with efield
488 !> \param spgr ...
489 !> \par History
490 !> 01.2020 created [pcazade]
491 !> \author Pierre-André Cazade (first version)
492 ! **************************************************************************************************
493  SUBROUTINE spgr_reduce_symm(spgr)
494 
495  TYPE(spgr_type), INTENT(INOUT), POINTER :: spgr
496 
497  CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_reduce_symm'
498 
499  INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
500  nparticle
501  REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: x, xold
502  REAL(kind=dp), DIMENSION(3) :: ri, ro
503  REAL(kind=dp), DIMENSION(3, 3) :: rot
504 
505  CALL timeset(routinen, handle)
506 
507  nop = spgr%n_operations
508  nparticle = spgr%nparticle
509  ALLOCATE (x(3*nparticle), xold(3*nparticle))
510  x = 0.0_dp
511  DO ia = 1, nparticle
512  ja = 3*(ia - 1)
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)
516  END DO
517  xold(:) = x(:)
518 
519  nops = 0
520  DO ir = 1, nop
521  x = 0.d0
522  spgr%lop(ir) = .true.
523  rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
524  DO ia = 1, nparticle
525  IF (.NOT. spgr%lat(ia)) cycle
526  ja = 3*(ia - 1)
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)
532  END DO
533  DO ia = 1, nparticle
534  IF (.NOT. spgr%lat(ia)) cycle
535  ib = spgr%eqatom(ir, ia)
536  ja = 3*(ia - 1)
537  jb = 3*(ib - 1)
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))
542  END DO
543  IF (spgr%lop(ir)) nops = nops + 1
544  END DO
545 
546  spgr%n_reduced_operations = nops
547 
548  DEALLOCATE (x, xold)
549  CALL timestop(handle)
550 
551  END SUBROUTINE spgr_reduce_symm
552 
553 ! **************************************************************************************************
554 !> \brief routine looks for unique rotations
555 !> \param spgr ...
556 !> \par History
557 !> 01.2020 created [pcazade]
558 !> \author Pierre-André Cazade (first version)
559 ! **************************************************************************************************
560 
561  SUBROUTINE spgr_rotations_subset(spgr)
562 
563  TYPE(spgr_type), INTENT(INOUT), POINTER :: spgr
564 
565  CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_rotations_subset'
566 
567  INTEGER :: handle, i, j
568  INTEGER, DIMENSION(3, 3) :: d
569  LOGICAL, ALLOCATABLE, DIMENSION(:) :: mask
570 
571  CALL timeset(routinen, handle)
572 
573  ALLOCATE (mask(spgr%n_operations))
574  mask = .true.
575 
576  DO i = 1, spgr%n_operations
577  IF (.NOT. spgr%lop(i)) mask(i) = .false.
578  END DO
579 
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.
586  END DO
587  END DO
588 
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
592  END DO
593 
594  ALLOCATE (spgr%rotations_subset(3, 3, spgr%n_operations_subset))
595 
596  j = 0
597  DO i = 1, spgr%n_operations
598  IF (mask(i)) THEN
599  j = j + 1
600  spgr%rotations_subset(:, :, j) = spgr%rotations(:, :, i)
601  END IF
602  END DO
603 
604  DEALLOCATE (mask)
605  CALL timestop(handle)
606 
607  END SUBROUTINE spgr_rotations_subset
608 
609 ! **************************************************************************************************
610 !> \brief routine applies the rotation matrices to the coordinates.
611 !> \param spgr ...
612 !> \param coord ...
613 !> \par History
614 !> 01.2020 created [pcazade]
615 !> \author Pierre-André Cazade (first version)
616 ! **************************************************************************************************
617  SUBROUTINE spgr_apply_rotations_coord(spgr, coord)
618 
619  TYPE(spgr_type), INTENT(IN), POINTER :: spgr
620  REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: coord
621 
622  CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_apply_rotations_coord'
623 
624  INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
625  nparticle
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
629 
630  CALL timeset(routinen, handle)
631 
632  ALLOCATE (cold(SIZE(coord)))
633  cold(:) = coord(:)
634 
635  nop = spgr%n_operations
636  nparticle = spgr%nparticle
637  nops = spgr%n_reduced_operations
638 
639  !$OMP PARALLEL DO PRIVATE (ia,ib,ja,jb,ir,ri,ro,rf,rn,rot,tr) SHARED (spgr,coord,nparticle,nop,nops) DEFAULT(NONE)
640  DO ia = 1, nparticle
641  IF (.NOT. spgr%lat(ia)) cycle
642  ja = 3*(ia - 1)
643  CALL real_to_scaled(rf(1:3), coord(ja + 1:ja + 3), spgr%cell_ref)
644  rn(1:3) = 0.d0
645  DO ir = 1, nop
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)
650  jb = 3*(ib - 1)
651  CALL real_to_scaled(ri(1:3), coord(jb + 1:jb + 3), spgr%cell_ref)
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)
659  END DO
660  rn = rn/real(nops, dp)
661  CALL scaled_to_real(coord(ja + 1:ja + 3), rn(1:3), spgr%cell_ref)
662  END DO
663  !$OMP END PARALLEL DO
664 
665  DEALLOCATE (cold)
666  CALL timestop(handle)
667 
668  END SUBROUTINE spgr_apply_rotations_coord
669 
670 ! **************************************************************************************************
671 !> \brief routine applies the rotation matrices to the forces.
672 !> \param spgr ...
673 !> \param force ...
674 !> \par History
675 !> 01.2020 created [pcazade]
676 !> \author Pierre-André Cazade (first version)
677 ! **************************************************************************************************
678  SUBROUTINE spgr_apply_rotations_force(spgr, force)
679 
680  TYPE(spgr_type), INTENT(IN), POINTER :: spgr
681  REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: force
682 
683  CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_apply_rotations_force'
684 
685  INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
686  nparticle
687  REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: fold
688  REAL(kind=dp), DIMENSION(3) :: ri, rn, ro
689  REAL(kind=dp), DIMENSION(3, 3) :: rot
690 
691  CALL timeset(routinen, handle)
692 
693  ALLOCATE (fold(SIZE(force)))
694  fold(:) = force(:)
695 
696  nop = spgr%n_operations
697  nparticle = spgr%nparticle
698  nops = spgr%n_reduced_operations
699 
700  !$OMP PARALLEL DO PRIVATE (ia,ib,ja,jb,ir,ri,ro,rn,rot) SHARED (spgr,force,nparticle,nop,nops) DEFAULT(NONE)
701  DO ia = 1, nparticle
702  IF (.NOT. spgr%lat(ia)) cycle
703  ja = 3*(ia - 1)
704  rn(1:3) = 0.d0
705  DO ir = 1, nop
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)
709  jb = 3*(ib - 1)
710  CALL real_to_scaled(ri(1:3), force(jb + 1:jb + 3), spgr%cell_ref)
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)
715  END DO
716  rn = rn/real(nops, dp)
717  CALL scaled_to_real(force(ja + 1:ja + 3), rn(1:3), spgr%cell_ref)
718  END DO
719  !$OMP END PARALLEL DO
720 
721  DEALLOCATE (fold)
722  CALL timestop(handle)
723 
724  END SUBROUTINE spgr_apply_rotations_force
725 
726 ! **************************************************************************************************
727 !> \brief ...
728 !> \param roti ...
729 !> \param roto ...
730 !> \param nop ...
731 !> \param h1 ...
732 !> \param h2 ...
733 ! **************************************************************************************************
734  SUBROUTINE spgr_change_basis(roti, roto, nop, h1, h2)
735 
736  INTEGER, DIMENSION(:, :, :) :: roti
737  REAL(kind=dp), DIMENSION(:, :, :) :: roto
738  INTEGER :: nop
739  REAL(kind=dp), DIMENSION(3, 3) :: h1, h2
740 
741  CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_change_basis'
742 
743  INTEGER :: handle, ir
744  REAL(kind=dp), DIMENSION(3, 3) :: h1ih2, h2ih1, ih1, ih2, r, s
745 
746  CALL timeset(routinen, handle)
747 
748  ih1 = inv_3x3(h1)
749  ih2 = inv_3x3(h2)
750  h2ih1 = matmul(h2, ih1)
751  h1ih2 = matmul(h1, ih2)
752 
753  DO ir = 1, nop
754  r(:, :) = roti(:, :, ir)
755  s = matmul(h2ih1, r)
756  r = matmul(s, h1ih2)
757  roto(:, :, ir) = r(:, :)
758  END DO
759 
760  CALL timestop(handle)
761 
762  END SUBROUTINE spgr_change_basis
763 
764 ! **************************************************************************************************
765 !> \brief routine applies the rotation matrices to the stress tensor.
766 !> \param spgr ...
767 !> \param cell ...
768 !> \param stress ...
769 !> \par History
770 !> 01.2020 created [pcazade]
771 !> \author Pierre-André Cazade (first version)
772 ! **************************************************************************************************
773  SUBROUTINE spgr_apply_rotations_stress(spgr, cell, stress)
774 
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
778 
779  CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_apply_rotations_stress'
780 
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
784 
785  CALL timeset(routinen, handle)
786 
787  hmat1 = transpose(cell%hmat)
788 
789  hmat2 = 0d0
790  hmat2(1, 1) = 1.d0
791  hmat2(2, 2) = 1.d0
792  hmat2(3, 3) = 1.d0
793 
794  nop = spgr%n_operations_subset
795 
796  ALLOCATE (roto(3, 3, nop))
797 
798  CALL spgr_change_basis(spgr%rotations_subset, roto, spgr%n_operations_subset, hmat1, hmat2)
799 
800  stin = stress
801  stress = 0.d0
802  DO ir = 1, nop
803  r(:, :) = roto(:, :, ir)
804  DO i = 1, 3
805  DO j = 1, 3
806  DO k = 1, 3
807  DO l = 1, 3
808  stress(i, j) = stress(i, j) + (r(k, i)*r(l, j)*stin(k, l))
809  END DO
810  END DO
811  END DO
812  END DO
813  END DO
814  stress = stress/real(nop, dp)
815 
816  DEALLOCATE (roto)
817 
818  CALL timestop(handle)
819 
820  END SUBROUTINE spgr_apply_rotations_stress
821 
822 ! **************************************************************************************************
823 !> \brief routine prints Space Group Information.
824 !> \param spgr ...
825 !> \par History
826 !> 01.2020 created [pcazade]
827 !> \author Pierre-André Cazade (first version)
828 ! **************************************************************************************************
829  SUBROUTINE print_spgr(spgr)
830 
831  TYPE(spgr_type), INTENT(IN), POINTER :: spgr
832 
833  INTEGER :: i, j
834 
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:", &
851  spgr%n_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)
875  END DO
876  END DO
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)
883  END DO
884  END IF
885  ELSE
886  WRITE (spgr%iunit, "(T2,A)") "SPGLIB for Crystal Symmetry Information determination is not availale"
887  END IF
888  END IF
889 
890  END SUBROUTINE print_spgr
891 
892 ! **************************************************************************************************
893 !> \brief Variable precision output of the symmetrized stress tensor
894 !>
895 !> \param stress tensor ...
896 !> \param spgr ...
897 !> \par History
898 !> 07.2020 adapted to spgr [pcazade]
899 !> \author MK (26.08.2010).
900 ! **************************************************************************************************
901  SUBROUTINE spgr_write_stress_tensor(stress, spgr)
902 
903  REAL(kind=dp), DIMENSION(3, 3), INTENT(IN) :: stress
904  TYPE(spgr_type), INTENT(IN), POINTER :: spgr
905 
906  REAL(kind=dp), DIMENSION(3) :: eigval
907  REAL(kind=dp), DIMENSION(3, 3) :: eigvec, stress_tensor
908 
909  stress_tensor(:, :) = stress(:, :)*pascal*1.0e-9_dp
910 
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))
930  eigval(:) = 0.0_dp
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)
945  END IF
946 
947  END SUBROUTINE spgr_write_stress_tensor
948 
949 END MODULE space_groups
real(kind=dp) function det_3x3(a)
...
Definition: dumpdcd.F:1091
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...
Definition: bibliography.F:28
integer, save, public togo2018
Definition: bibliography.F:43
Handles all functions related to the CELL.
Definition: cell_methods.F:15
subroutine, public init_cell(cell, hmat, periodic)
Initialise/readjust a simulation cell after hmat has been changed.
Definition: cell_methods.F:117
subroutine, public cell_create(cell, hmat, periodic, tag)
allocates and initializes a cell
Definition: cell_methods.F:85
Handles all functions related to the CELL.
Definition: cell_types.F:15
subroutine, public scaled_to_real(r, s, cell)
Transform scaled cell coordinates real coordinates. r=h*s.
Definition: cell_types.F:516
subroutine, public real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
Definition: cell_types.F:486
subroutine, public cell_copy(cell_in, cell_out, tag)
Copy cell variable.
Definition: cell_types.F:126
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
Definition: gopt_f_types.F:15
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public default_cell_geo_opt_id
integer, parameter, public default_cell_method_id
integer, parameter, public default_minimization_method_id
integer, parameter, public default_ts_method_id
integer, parameter, public default_cell_md_id
integer, parameter, public default_cell_direct_id
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
Collection of simple mathematical functions and subroutines.
Definition: mathlib.F:15
subroutine, public jacobi(a, d, v)
Jacobi matrix diagonalization. The eigenvalues are returned in vector d and the eigenvectors are retu...
Definition: mathlib.F:1487
pure real(kind=dp) function, dimension(3, 3), public inv_3x3(a)
Returns the inverse of the 3 x 3 matrix a.
Definition: mathlib.F:520
represent a simple array based list of the given type
Definition of physical constants:
Definition: physcon.F:68
real(kind=dp), parameter, public pascal
Definition: physcon.F:174
Space Group Symmetry Type Module (version 1.0, Ferbruary 12, 2021)
Space Group Symmetry Module (version 1.0, January 16, 2020)
Definition: space_groups.F:14
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
Definition: space_groups.F:83
subroutine, public spgr_find_equivalent_atoms(spgr, scoord)
routine indentifies the equivalent atoms for each rotation matrix.
Definition: space_groups.F:401
subroutine, public print_spgr(spgr)
routine prints Space Group Information.
Definition: space_groups.F:830
subroutine, public spgr_apply_rotations_stress(spgr, cell, stress)
routine applies the rotation matrices to the stress tensor.
Definition: space_groups.F:774
subroutine, public spgr_apply_rotations_coord(spgr, coord)
routine applies the rotation matrices to the coordinates.
Definition: space_groups.F:618
subroutine, public identify_space_group(subsys, geo_section, gopt_env, iunit)
routine indentifies the space group and finds rotation matrices.
Definition: space_groups.F:286
subroutine, public spgr_apply_rotations_force(spgr, force)
routine applies the rotation matrices to the forces.
Definition: space_groups.F:679
subroutine, public spgr_write_stress_tensor(stress, spgr)
Variable precision output of the symmetrized stress tensor.
Definition: space_groups.F:902
Interface for SPGLIB symmetry routines.
Definition: spglib_f08.F:119
integer function, public spg_get_international(symbol, lattice, position, types, num_atom, symprec)
...
Definition: spglib_f08.F:202
integer function, public spg_get_multiplicity(lattice, position, types, num_atom, symprec)
...
Definition: spglib_f08.F:177
integer function, public spg_get_pointgroup(symbol, trans_mat, rotations, num_rotations)
...
Definition: spglib_f08.F:256
integer function, public spg_get_symmetry(rotation, translation, max_size, lattice, position, types, num_atom, symprec)
...
Definition: spglib_f08.F:147
integer function, public spg_get_schoenflies(symbol, lattice, position, types, num_atom, symprec)
...
Definition: spglib_f08.F:230
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.