(git:6d276e9)
Loading...
Searching...
No Matches
space_groups.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 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,&
21 USE cell_types, ONLY: cell_copy,&
22 cell_type,&
27 USE gopt_f_types, ONLY: gopt_f_type
33 USE kinds, ONLY: dp
34 USE mathlib, ONLY: det_3x3,&
35 inv_3x3,&
36 jacobi
38 USE physcon, ONLY: pascal
47#include "../base/base_uses.f90"
48
49 IMPLICIT NONE
50
51 PRIVATE
52
53 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'space_groups'
54
58
59CONTAINS
60
61! **************************************************************************************************
62!> \brief routine creates the space group structure
63!> \param scoor ...
64!> \param types ...
65!> \param cell ...
66!> \param gopt_env ...
67!> \param eps_symmetry ...
68!> \param pol ...
69!> \param ranges ...
70!> \param nparticle ...
71!> \param n_atom ...
72!> \param n_core ...
73!> \param n_shell ...
74!> \param iunit ...
75!> \param print_atoms ...
76!> \par History
77!> 01.2020 created [pcazade]
78!> \author Pierre-André Cazade (first version)
79! **************************************************************************************************
80 SUBROUTINE spgr_create(scoor, types, cell, gopt_env, eps_symmetry, pol, ranges, &
81 nparticle, n_atom, n_core, n_shell, iunit, print_atoms)
82
83 REAL(kind=dp), DIMENSION(:, :), INTENT(IN) :: scoor
84 INTEGER, DIMENSION(:), INTENT(IN) :: types
85 TYPE(cell_type), INTENT(IN), POINTER :: cell
86 TYPE(gopt_f_type), INTENT(IN), POINTER :: gopt_env
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
93
94 CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_create'
95#ifdef __SPGLIB
96 CHARACTER(LEN=1000) :: buffer
97 INTEGER :: ierr, nchars, nop, tra_mat(3, 3)
98#endif
99 INTEGER :: handle, i, j, n_sr_rep
100 INTEGER, ALLOCATABLE, DIMENSION(:) :: tmp_types
101 LOGICAL :: spglib
102 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: tmp_coor
103 TYPE(spgr_type), POINTER :: spgr
104
105 CALL timeset(routinen, handle)
106
107 spgr => gopt_env%spgr
108 cpassert(ASSOCIATED(spgr))
109
110 CALL cleanup_spgr_type(spgr)
111
112 !..total number of particles (atoms plus shells)
113 IF (PRESENT(nparticle)) THEN
114 cpassert(nparticle == SIZE(scoor, 2))
115 spgr%nparticle = nparticle
116 ELSE
117 spgr%nparticle = SIZE(scoor, 2)
118 END IF
119
120 IF (PRESENT(n_atom)) THEN
121 spgr%n_atom = n_atom
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
126 ELSE
127 spgr%n_atom = spgr%nparticle
128 END IF
129
130 IF (PRESENT(n_core)) THEN
131 spgr%n_core = n_core
132 ELSE IF (PRESENT(n_shell)) THEN
133 spgr%n_core = n_shell
134 END IF
135
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
140 END IF
141
142 IF (.NOT. (spgr%nparticle == (spgr%n_atom + spgr%n_shell))) THEN
143 cpabort("spgr_create: nparticle not equal to natom + nshell.")
144 END IF
145
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
150
151 spgr%iunit = iunit
152 spgr%print_atoms = print_atoms
153
154 ! accuracy for symmetry
155 IF (PRESENT(eps_symmetry)) THEN
156 spgr%eps_symmetry = eps_symmetry
157 END IF
158
159 ! vector to test reduced symmetry
160 IF (PRESENT(pol)) THEN
161 spgr%pol(1) = pol(1)
162 spgr%pol(2) = pol(2)
163 spgr%pol(3) = pol(3)
164 END IF
165
166 ALLOCATE (spgr%lat(spgr%nparticle))
167 spgr%lat = .true.
168
169 IF (PRESENT(ranges)) THEN
170 n_sr_rep = SIZE(ranges, 2)
171 DO i = 1, n_sr_rep
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
180 ELSE
181 cpabort("Symmetry exclusion range larger than actual number of particles.")
182 END IF
183 END DO
184 END DO
185 END IF
186
187 ALLOCATE (tmp_coor(3, spgr%n_atom_sym), tmp_types(spgr%n_atom_sym))
188
189 j = 0
190 DO i = 1, spgr%n_atom
191 IF (spgr%lat(i)) THEN
192 j = j + 1
193 tmp_coor(:, j) = scoor(:, i)
194 tmp_types(j) = types(i)
195 END IF
196 END DO
197
198 !..set cell values
199 NULLIFY (spgr%cell_ref)
200 CALL cell_create(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)
207 CASE DEFAULT
208 cpabort("SPACE_GROUP_SYMMETRY is not compatible with md.")
209 END SELECT
210
211 ! atom types
212 ALLOCATE (spgr%atype(spgr%nparticle))
213 spgr%atype(1:spgr%nparticle) = types(1:spgr%nparticle)
214
215 spgr%n_operations = 0
216
217#ifdef __SPGLIB
218 spglib = .true.
219 CALL cite_reference(togo2018)
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)
222 buffer = ''
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.")
227 spglib = .false.
228 ELSE
229 nop = spg_get_multiplicity(transpose(cell%hmat), tmp_coor, tmp_types, &
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
235 spgr%lop = .true.
236 ierr = spg_get_symmetry(spgr%rotations, spgr%translations, nop, transpose(cell%hmat), &
237 tmp_coor, tmp_types, spgr%n_atom_sym, eps_symmetry)
238 ! Schoenflies Symbol
239 ierr = spg_get_schoenflies(spgr%schoenflies, transpose(cell%hmat), tmp_coor, tmp_types, &
240 spgr%n_atom_sym, eps_symmetry)
241 buffer = ''
242 nchars = strlcpy_c2f(buffer, spgr%schoenflies)
243 spgr%schoenflies = buffer(1:nchars)
244
245 ! Point Group
246 tra_mat = 0
247 ierr = spg_get_pointgroup(spgr%pointgroup_symbol, tra_mat, &
248 spgr%rotations, spgr%n_operations)
249 buffer = ''
250 nchars = strlcpy_c2f(buffer, spgr%pointgroup_symbol)
251 spgr%pointgroup_symbol = buffer(1:nchars)
252 END IF
253#else
254 cpabort("Symmetry library SPGLIB not available")
255 spglib = .false.
256#endif
257 spgr%symlib = spglib
258
259 DEALLOCATE (tmp_coor, tmp_types)
260
261 CALL timestop(handle)
262
263 END SUBROUTINE spgr_create
264
265! **************************************************************************************************
266!> \brief routine indentifies the space group and finds rotation matrices.
267!> \param subsys ...
268!> \param geo_section ...
269!> \param gopt_env ...
270!> \param iunit ...
271!> \par History
272!> 01.2020 created [pcazade]
273!> \author Pierre-André Cazade (first version)
274!> \note rotation matrices innclude translations and translation symmetry:
275!> it works with supercells as well.
276! **************************************************************************************************
277 SUBROUTINE identify_space_group(subsys, geo_section, gopt_env, iunit)
278
279 TYPE(cp_subsys_type), INTENT(IN), POINTER :: subsys
280 TYPE(section_vals_type), INTENT(IN), POINTER :: geo_section
281 TYPE(gopt_f_type), INTENT(IN), POINTER :: gopt_env
282 INTEGER, INTENT(IN) :: iunit
283
284 CHARACTER(LEN=*), PARAMETER :: routinen = 'identify_space_group'
285
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
295 TYPE(cell_type), POINTER :: cell
296 TYPE(particle_list_type), POINTER :: core_particles, particles, &
297 shell_particles
298 TYPE(spgr_type), POINTER :: spgr
299
300 CALL timeset(routinen, handle)
301
302 n_sr_rep = 0
303 nparticle = 0
304 n_atom = 0
305 n_core = 0
306 n_shell = 0
307
308 NULLIFY (particles)
309 NULLIFY (core_particles)
310 NULLIFY (shell_particles)
311
312 NULLIFY (cell)
313 cell => subsys%cell
314 cpassert(ASSOCIATED(cell))
315
316 CALL cp_subsys_get(subsys, particles=particles, shell_particles=shell_particles, core_particles=core_particles)
317
318 cpassert(ASSOCIATED(particles))
319 n_atom = particles%n_els
320 ! Check if we have other kinds of particles in this subsystem
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
325 ! The same number of shell and core particles is assumed
326 cpassert(n_core == n_shell)
327 ELSE IF (ASSOCIATED(core_particles)) THEN
328 ! This case should not occur at the moment
329 cpabort("Core particles should not be defined without corresponding shell particles.")
330 ELSE
331 n_core = 0
332 n_shell = 0
333 END IF
334
335 nparticle = n_atom + n_shell
336 ALLOCATE (scoord(3, nparticle), atype(nparticle))
337 DO i = 1, n_atom
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))
342 ELSE
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))
348 END IF
349 END DO
350
351 CALL section_vals_val_get(geo_section, "SPGR_PRINT_ATOMS", l_val=print_atoms)
352 CALL section_vals_val_get(geo_section, "EPS_SYMMETRY", r_val=eps_symmetry)
353 CALL section_vals_val_get(geo_section, "SYMM_REDUCTION", r_vals=pol)
354 CALL section_vals_val_get(geo_section, "SYMM_EXCLUDE_RANGE", n_rep_val=n_sr_rep)
355 IF (n_sr_rep > 0) THEN
356 ALLOCATE (ranges(2, n_sr_rep))
357 DO i = 1, n_sr_rep
358 CALL section_vals_val_get(geo_section, "SYMM_EXCLUDE_RANGE", i_rep_val=i, i_vals=tmp)
359 ranges(:, i) = tmp(:)
360 END DO
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)
364 DEALLOCATE (ranges)
365 ELSE
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)
369 END IF
370
371 NULLIFY (spgr)
372 spgr => gopt_env%spgr
373
374 CALL spgr_find_equivalent_atoms(spgr, scoord)
375 CALL spgr_reduce_symm(spgr)
376 CALL spgr_rotations_subset(spgr)
377
378 DEALLOCATE (scoord, atype)
379
380 CALL timestop(handle)
381
382 END SUBROUTINE identify_space_group
383
384! **************************************************************************************************
385!> \brief routine indentifies the equivalent atoms for each rotation matrix.
386!> \param spgr ...
387!> \param scoord ...
388!> \par History
389!> 01.2020 created [pcazade]
390!> \author Pierre-André Cazade (first version)
391! **************************************************************************************************
392 SUBROUTINE spgr_find_equivalent_atoms(spgr, scoord)
393
394 TYPE(spgr_type), INTENT(INOUT), POINTER :: spgr
395 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :), &
396 INTENT(IN) :: scoord
397
398 CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_find_equivalent_atoms'
399
400 INTEGER :: handle, i, ia, ib, ir, j, natom, nop, &
401 nshell
402 REAL(kind=dp) :: diff
403 REAL(kind=dp), DIMENSION(3) :: rb, ri, ro, tr
404 REAL(kind=dp), DIMENSION(3, 3) :: rot
405
406 CALL timeset(routinen, handle)
407
408 nop = spgr%n_operations
409 natom = spgr%n_atom
410 nshell = spgr%n_shell
411
412 IF (.NOT. (spgr%nparticle == (natom + nshell))) THEN
413 cpabort("spgr_find_equivalent_atoms: nparticle not equal to natom + nshell.")
414 END IF
415
416 DO ia = 1, spgr%nparticle
417 spgr%eqatom(:, ia) = ia
418 END DO
419
420 !$OMP PARALLEL DO PRIVATE (ia,ib,ir,ri,rb,ro,rot,tr,diff) SHARED (spgr,scoord,natom,nop) DEFAULT(NONE)
421 DO ia = 1, natom
422 IF (.NOT. spgr%lat(ia)) cycle
423 ri(1:3) = scoord(1:3, ia)
424 DO ir = 1, nop
425 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
426 tr(1:3) = spgr%translations(1:3, ir)
427 DO ib = 1, natom
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
439 EXIT
440 END IF
441 END DO
442 END DO
443 END DO
444 !$OMP END PARALLEL DO
445
446 !$OMP PARALLEL DO PRIVATE (i,j,ia,ib,ir,ri,rb,ro,rot,tr,diff) SHARED (spgr,scoord,natom,nshell,nop) DEFAULT(NONE)
447 DO i = 1, nshell
448 ia = natom + i
449 IF (.NOT. spgr%lat(ia)) cycle
450 ri(1:3) = scoord(1:3, ia)
451 DO ir = 1, nop
452 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
453 tr(1:3) = spgr%translations(1:3, ir)
454 DO j = 1, nshell
455 ib = natom + j
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
467 EXIT
468 END IF
469 END DO
470 END DO
471 END DO
472 !$OMP END PARALLEL DO
473
474 CALL timestop(handle)
475
476 END SUBROUTINE spgr_find_equivalent_atoms
477
478! **************************************************************************************************
479!> \brief routine looks for operations compatible with efield
480!> \param spgr ...
481!> \par History
482!> 01.2020 created [pcazade]
483!> \author Pierre-André Cazade (first version)
484! **************************************************************************************************
485 SUBROUTINE spgr_reduce_symm(spgr)
486
487 TYPE(spgr_type), INTENT(INOUT), POINTER :: spgr
488
489 CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_reduce_symm'
490
491 INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
492 nparticle
493 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: x, xold
494 REAL(kind=dp), DIMENSION(3) :: ri, ro
495 REAL(kind=dp), DIMENSION(3, 3) :: rot
496
497 CALL timeset(routinen, handle)
498
499 nop = spgr%n_operations
500 nparticle = spgr%nparticle
501 ALLOCATE (x(3*nparticle), xold(3*nparticle))
502 x = 0.0_dp
503 DO ia = 1, nparticle
504 ja = 3*(ia - 1)
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)
508 END DO
509 xold(:) = x(:)
510
511 nops = 0
512 DO ir = 1, nop
513 x = 0.d0
514 spgr%lop(ir) = .true.
515 rot(1:3, 1:3) = spgr%rotations(1:3, 1:3, ir)
516 DO ia = 1, nparticle
517 IF (.NOT. spgr%lat(ia)) cycle
518 ja = 3*(ia - 1)
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)
524 END DO
525 DO ia = 1, nparticle
526 IF (.NOT. spgr%lat(ia)) cycle
527 ib = spgr%eqatom(ir, ia)
528 ja = 3*(ia - 1)
529 jb = 3*(ib - 1)
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))
534 END DO
535 IF (spgr%lop(ir)) nops = nops + 1
536 END DO
537
538 spgr%n_reduced_operations = nops
539
540 DEALLOCATE (x, xold)
541 CALL timestop(handle)
542
543 END SUBROUTINE spgr_reduce_symm
544
545! **************************************************************************************************
546!> \brief routine looks for unique rotations
547!> \param spgr ...
548!> \par History
549!> 01.2020 created [pcazade]
550!> \author Pierre-André Cazade (first version)
551! **************************************************************************************************
552
553 SUBROUTINE spgr_rotations_subset(spgr)
554
555 TYPE(spgr_type), INTENT(INOUT), POINTER :: spgr
556
557 CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_rotations_subset'
558
559 INTEGER :: handle, i, j
560 INTEGER, DIMENSION(3, 3) :: d
561 LOGICAL, ALLOCATABLE, DIMENSION(:) :: mask
562
563 CALL timeset(routinen, handle)
564
565 ALLOCATE (mask(spgr%n_operations))
566 mask = .true.
567
568 DO i = 1, spgr%n_operations
569 IF (.NOT. spgr%lop(i)) mask(i) = .false.
570 END DO
571
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.
578 END DO
579 END DO
580
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
584 END DO
585
586 ALLOCATE (spgr%rotations_subset(3, 3, spgr%n_operations_subset))
587
588 j = 0
589 DO i = 1, spgr%n_operations
590 IF (mask(i)) THEN
591 j = j + 1
592 spgr%rotations_subset(:, :, j) = spgr%rotations(:, :, i)
593 END IF
594 END DO
595
596 DEALLOCATE (mask)
597 CALL timestop(handle)
598
599 END SUBROUTINE spgr_rotations_subset
600
601! **************************************************************************************************
602!> \brief routine applies the rotation matrices to the coordinates.
603!> \param spgr ...
604!> \param coord ...
605!> \par History
606!> 01.2020 created [pcazade]
607!> \author Pierre-André Cazade (first version)
608! **************************************************************************************************
609 SUBROUTINE spgr_apply_rotations_coord(spgr, coord)
610
611 TYPE(spgr_type), INTENT(IN), POINTER :: spgr
612 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: coord
613
614 CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_apply_rotations_coord'
615
616 INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
617 nparticle
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
621
622 CALL timeset(routinen, handle)
623
624 ALLOCATE (cold(SIZE(coord)))
625 cold(:) = coord(:)
626
627 nop = spgr%n_operations
628 nparticle = spgr%nparticle
629 nops = spgr%n_reduced_operations
630
631 !$OMP PARALLEL DO PRIVATE (ia,ib,ja,jb,ir,ri,ro,rf,rn,rot,tr) SHARED (spgr,coord,nparticle,nop,nops) DEFAULT(NONE)
632 DO ia = 1, nparticle
633 IF (.NOT. spgr%lat(ia)) cycle
634 ja = 3*(ia - 1)
635 CALL real_to_scaled(rf(1:3), coord(ja + 1:ja + 3), spgr%cell_ref)
636 rn(1:3) = 0.d0
637 DO ir = 1, nop
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)
642 jb = 3*(ib - 1)
643 CALL real_to_scaled(ri(1:3), coord(jb + 1:jb + 3), spgr%cell_ref)
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)
651 END DO
652 rn = rn/real(nops, dp)
653 CALL scaled_to_real(coord(ja + 1:ja + 3), rn(1:3), spgr%cell_ref)
654 END DO
655 !$OMP END PARALLEL DO
656
657 DEALLOCATE (cold)
658 CALL timestop(handle)
659
660 END SUBROUTINE spgr_apply_rotations_coord
661
662! **************************************************************************************************
663!> \brief routine applies the rotation matrices to the forces.
664!> \param spgr ...
665!> \param force ...
666!> \par History
667!> 01.2020 created [pcazade]
668!> \author Pierre-André Cazade (first version)
669! **************************************************************************************************
670 SUBROUTINE spgr_apply_rotations_force(spgr, force)
671
672 TYPE(spgr_type), INTENT(IN), POINTER :: spgr
673 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: force
674
675 CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_apply_rotations_force'
676
677 INTEGER :: handle, ia, ib, ir, ja, jb, nop, nops, &
678 nparticle
679 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: fold
680 REAL(kind=dp), DIMENSION(3) :: ri, rn, ro
681 REAL(kind=dp), DIMENSION(3, 3) :: rot
682
683 CALL timeset(routinen, handle)
684
685 ALLOCATE (fold(SIZE(force)))
686 fold(:) = force(:)
687
688 nop = spgr%n_operations
689 nparticle = spgr%nparticle
690 nops = spgr%n_reduced_operations
691
692 !$OMP PARALLEL DO PRIVATE (ia,ib,ja,jb,ir,ri,ro,rn,rot) SHARED (spgr,force,nparticle,nop,nops) DEFAULT(NONE)
693 DO ia = 1, nparticle
694 IF (.NOT. spgr%lat(ia)) cycle
695 ja = 3*(ia - 1)
696 rn(1:3) = 0.d0
697 DO ir = 1, nop
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)
701 jb = 3*(ib - 1)
702 CALL real_to_scaled(ri(1:3), force(jb + 1:jb + 3), spgr%cell_ref)
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)
707 END DO
708 rn = rn/real(nops, dp)
709 CALL scaled_to_real(force(ja + 1:ja + 3), rn(1:3), spgr%cell_ref)
710 END DO
711 !$OMP END PARALLEL DO
712
713 DEALLOCATE (fold)
714 CALL timestop(handle)
715
716 END SUBROUTINE spgr_apply_rotations_force
717
718! **************************************************************************************************
719!> \brief ...
720!> \param roti ...
721!> \param roto ...
722!> \param nop ...
723!> \param h1 ...
724!> \param h2 ...
725! **************************************************************************************************
726 SUBROUTINE spgr_change_basis(roti, roto, nop, h1, h2)
727
728 INTEGER, DIMENSION(:, :, :) :: roti
729 REAL(kind=dp), DIMENSION(:, :, :) :: roto
730 INTEGER :: nop
731 REAL(kind=dp), DIMENSION(3, 3) :: h1, h2
732
733 CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_change_basis'
734
735 INTEGER :: handle, ir
736 REAL(kind=dp), DIMENSION(3, 3) :: h1ih2, h2ih1, ih1, ih2, r, s
737
738 CALL timeset(routinen, handle)
739
740 ih1 = inv_3x3(h1)
741 ih2 = inv_3x3(h2)
742 h2ih1 = matmul(h2, ih1)
743 h1ih2 = matmul(h1, ih2)
744
745 DO ir = 1, nop
746 r(:, :) = roti(:, :, ir)
747 s = matmul(h2ih1, r)
748 r = matmul(s, h1ih2)
749 roto(:, :, ir) = r(:, :)
750 END DO
751
752 CALL timestop(handle)
753
754 END SUBROUTINE spgr_change_basis
755
756! **************************************************************************************************
757!> \brief routine applies the rotation matrices to the stress tensor.
758!> \param spgr ...
759!> \param cell ...
760!> \param stress ...
761!> \par History
762!> 01.2020 created [pcazade]
763!> \author Pierre-André Cazade (first version)
764! **************************************************************************************************
765 SUBROUTINE spgr_apply_rotations_stress(spgr, cell, stress)
766
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
770
771 CHARACTER(LEN=*), PARAMETER :: routinen = 'spgr_apply_rotations_stress'
772
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
776
777 CALL timeset(routinen, handle)
778
779 hmat1 = transpose(cell%hmat)
780
781 hmat2 = 0d0
782 hmat2(1, 1) = 1.d0
783 hmat2(2, 2) = 1.d0
784 hmat2(3, 3) = 1.d0
785
786 nop = spgr%n_operations_subset
787
788 ALLOCATE (roto(3, 3, nop))
789
790 CALL spgr_change_basis(spgr%rotations_subset, roto, spgr%n_operations_subset, hmat1, hmat2)
791
792 stin = stress
793 stress = 0.d0
794 DO ir = 1, nop
795 r(:, :) = roto(:, :, ir)
796 DO i = 1, 3
797 DO j = 1, 3
798 DO k = 1, 3
799 DO l = 1, 3
800 stress(i, j) = stress(i, j) + (r(k, i)*r(l, j)*stin(k, l))
801 END DO
802 END DO
803 END DO
804 END DO
805 END DO
806 stress = stress/real(nop, dp)
807
808 DEALLOCATE (roto)
809
810 CALL timestop(handle)
811
812 END SUBROUTINE spgr_apply_rotations_stress
813
814! **************************************************************************************************
815!> \brief Project a cell onto the metric preserved by the selected space-group rotations.
816!> \param spgr ...
817!> \param cell ...
818! **************************************************************************************************
819 SUBROUTINE spgr_project_cell_metric(spgr, cell)
820
821 TYPE(spgr_type), INTENT(IN), POINTER :: spgr
822 TYPE(cell_type), INTENT(INOUT), POINTER :: cell
823
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
828
829 cpassert(ALLOCATED(spgr%rotations_subset))
830 nop = spgr%n_operations_subset
831 cpassert(nop > 0)
832
833 metric = matmul(transpose(cell%hmat), cell%hmat)
834 metric_sym = 0.0_dp
835 DO ir = 1, nop
836 rot = real(spgr%rotations_subset(:, :, ir), dp)
837 metric_sym = metric_sym + matmul(rot, matmul(metric, transpose(rot)))
838 END DO
839 metric_sym = metric_sym/real(nop, dp)
840
841 ! The group average can change the determinant. Retain the volume of the
842 ! optimizer proposal so KEEP_VOLUME and hydrostatic changes remain intact.
843 scale = (cell%deth**2/det_3x3(metric_sym))**(1.0_dp/3.0_dp)
844 metric_sym = scale*metric_sym
845
846 DO i = 1, 3
847 abc(i) = sqrt(metric_sym(i, i))
848 END DO
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.)
854
855 END SUBROUTINE spgr_project_cell_metric
856
857! **************************************************************************************************
858!> \brief routine prints Space Group Information.
859!> \param spgr ...
860!> \par History
861!> 01.2020 created [pcazade]
862!> \author Pierre-André Cazade (first version)
863! **************************************************************************************************
864 SUBROUTINE print_spgr(spgr)
865
866 TYPE(spgr_type), INTENT(IN), POINTER :: spgr
867
868 INTEGER :: i, j
869
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:", &
886 spgr%n_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)
910 END DO
911 END DO
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)
918 END DO
919 END IF
920 ELSE
921 WRITE (spgr%iunit, "(T2,A)") "SPGLIB for Crystal Symmetry Information determination is not availale"
922 END IF
923 END IF
924
925 END SUBROUTINE print_spgr
926
927! **************************************************************************************************
928!> \brief Variable precision output of the symmetrized stress tensor
929!>
930!> \param stress tensor ...
931!> \param spgr ...
932!> \par History
933!> 07.2020 adapted to spgr [pcazade]
934!> \author MK (26.08.2010).
935! **************************************************************************************************
936 SUBROUTINE spgr_write_stress_tensor(stress, spgr)
937
938 REAL(kind=dp), DIMENSION(3, 3), INTENT(IN) :: stress
939 TYPE(spgr_type), INTENT(IN), POINTER :: spgr
940
941 REAL(kind=dp), DIMENSION(3) :: eigval
942 REAL(kind=dp), DIMENSION(3, 3) :: eigvec, stress_tensor
943
944 stress_tensor(:, :) = stress(:, :)*pascal*1.0e-9_dp
945
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))
965 eigval(:) = 0.0_dp
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)
980 END IF
981
982 END SUBROUTINE spgr_write_stress_tensor
983
984END MODULE space_groups
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.
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:625
subroutine, public real_to_scaled(s, r, cell)
Transform real to scaled cell coordinates. s=h_inv*r.
Definition cell_types.F:595
subroutine, public cell_copy(cell_in, cell_out, tag)
Copy cell variable.
Definition cell_types.F:160
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
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public default_cell_method_id
integer, parameter, public default_minimization_method_id
integer, parameter, public default_ts_method_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:1605
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:524
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)
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.
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.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
represents a system: atoms, molecules, their pos,vel,...
calculates the potential energy of a system, and its derivatives