(git:374b731)
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-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,&
20 USE cell_types, ONLY: cell_copy,&
21 cell_type,&
26 USE gopt_f_types, ONLY: gopt_f_type
35 USE kinds, ONLY: dp
36 USE mathlib, ONLY: det_3x3,&
37 inv_3x3,&
38 jacobi
40 USE physcon, ONLY: pascal
48#include "../base/base_uses.f90"
49
50 IMPLICIT NONE
51
52 PRIVATE
53
54 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'space_groups'
55
59
60CONTAINS
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
949END 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 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: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
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:1479
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:516
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)
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.
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:55
represents a system: atoms, molecules, their pos,vel,...
calculates the potential energy of a system, and its derivatives