(git:50ddb19)
Loading...
Searching...
No Matches
cell_methods.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 Handles all functions related to the CELL
10!> \par History
11!> 11.2008 Teodoro Laino [tlaino] - deeply cleaning cell_type from units
12!> 10.2014 Moved many routines to cell_types.F.
13!> \author Matthias KracK (16.01.2002, based on a earlier version of CJM, JGH)
14! **************************************************************************************************
16 USE cell_types, ONLY: &
33 USE cp_units, ONLY: cp_unit_from_cp2k,&
35 USE input_constants, ONLY: &
43 USE input_section_types, ONLY: &
47 USE kinds, ONLY: default_path_length,&
49 dp,&
52 USE mathconstants, ONLY: degree,&
53 sqrt3
54 USE mathlib, ONLY: angle,&
55 det_3x3,&
59#include "./base/base_uses.f90"
60
61 IMPLICIT NONE
62
63 PRIVATE
64
65 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cell_methods'
66
67 PUBLIC :: cell_create, &
70 init_cell, &
71 read_cell, &
79 write_cell, &
81
82CONTAINS
83
84! **************************************************************************************************
85!> \brief allocates and initializes a cell
86!> \param cell the cell to initialize
87!> \param hmat the h matrix that defines the cell
88!> \param periodic periodicity of the cell
89!> \param tag ...
90!> \par History
91!> 09.2003 created [fawzi]
92!> \author Fawzi Mohamed
93! **************************************************************************************************
94 SUBROUTINE cell_create(cell, hmat, periodic, tag)
95
96 TYPE(cell_type), POINTER :: cell
97 REAL(kind=dp), DIMENSION(3, 3), INTENT(IN), &
98 OPTIONAL :: hmat
99 INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL :: periodic
100 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: tag
101
102 cpassert(.NOT. ASSOCIATED(cell))
103 ALLOCATE (cell)
104 cell%ref_count = 1
105 IF (PRESENT(periodic)) THEN
106 cell%perd = periodic
107 ELSE
108 cell%perd = 1
109 END IF
110 cell%orthorhombic = .false.
111 cell%input_cell_canonicalized = .false.
112 cell%input_hmat(:, :) = 0.0_dp
113 cell%input_to_canonical(:, :) = 0.0_dp
114 cell%input_recip_to_canonical(:, :) = 0.0_dp
115 cell%symmetry_id = cell_sym_none
116 IF (PRESENT(hmat)) CALL init_cell(cell, hmat)
117 IF (PRESENT(tag)) cell%tag = tag
118
119 END SUBROUTINE cell_create
120
121! **************************************************************************************************
122!> \brief Store the transform between the user input cell and the canonical cell.
123!> \param cell ...
124!> \param hmat_input ...
125!> \param hmat_canonical ...
126! **************************************************************************************************
127 SUBROUTINE cell_finalize_canonical_input(cell, hmat_input, hmat_canonical)
128
129 TYPE(cell_type), POINTER :: cell
130 REAL(kind=dp), DIMENSION(3, 3), INTENT(IN) :: hmat_input, hmat_canonical
131
132 REAL(kind=dp), PARAMETER :: eps_hmat = 1.0e-12_dp
133
134 REAL(kind=dp), DIMENSION(3, 3) :: tmat
135
136 cpassert(ASSOCIATED(cell))
137
138 IF (maxval(abs(hmat_canonical - hmat_input)) <= eps_hmat) THEN
139 cell%input_cell_canonicalized = .false.
140 cell%input_hmat(:, :) = 0.0_dp
141 cell%input_to_canonical(:, :) = 0.0_dp
142 cell%input_recip_to_canonical(:, :) = 0.0_dp
143 ELSE
144 tmat = matmul(hmat_canonical, inv_3x3(hmat_input))
145 cell%input_cell_canonicalized = .true.
146 cell%input_hmat(:, :) = hmat_input(:, :)
147 cell%input_to_canonical(:, :) = tmat(:, :)
148 cell%input_recip_to_canonical(:, :) = transpose(inv_3x3(tmat))
149 END IF
150
151 END SUBROUTINE cell_finalize_canonical_input
152
153! **************************************************************************************************
154!> \brief Canonicalize a general cell matrix without changing lengths and angles.
155!> \param cell ...
156! **************************************************************************************************
158
159 TYPE(cell_type), POINTER :: cell
160
161 REAL(kind=dp), DIMENSION(3) :: abc, cell_angle
162
163 cpassert(ASSOCIATED(cell))
164
165 CALL get_cell(cell=cell, abc=abc)
166 cell_angle(1) = angle(cell%hmat(:, 2), cell%hmat(:, 3))
167 cell_angle(2) = angle(cell%hmat(:, 1), cell%hmat(:, 3))
168 cell_angle(3) = angle(cell%hmat(:, 1), cell%hmat(:, 2))
169
170 CALL set_cell_param(cell, cell_length=abc, cell_angle=cell_angle, &
171 periodic=cell%perd, do_init_cell=.true.)
172
173 END SUBROUTINE canonicalize_cell_matrix
174
175! **************************************************************************************************
176!> \brief Initialise/readjust a simulation cell after hmat has been changed
177!> \param cell ...
178!> \param hmat ...
179!> \param periodic ...
180!> \date 16.01.2002
181!> \author Matthias Krack
182!> \version 1.0
183! **************************************************************************************************
184 SUBROUTINE init_cell(cell, hmat, periodic)
185
186 TYPE(cell_type), POINTER :: cell
187 REAL(kind=dp), DIMENSION(3, 3), INTENT(IN), &
188 OPTIONAL :: hmat
189 INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL :: periodic
190
191 REAL(kind=dp), PARAMETER :: eps_hmat = 1.0e-14_dp
192
193 INTEGER :: dim
194 REAL(kind=dp) :: a, acosa, acosah, acosg, alpha, asina, &
195 asinah, asing, beta, gamma, norm, &
196 norm_c
197 REAL(kind=dp), DIMENSION(3) :: abc
198
199 cpassert(ASSOCIATED(cell))
200
201 IF (PRESENT(hmat)) cell%hmat(:, :) = hmat(:, :)
202 IF (PRESENT(periodic)) cell%perd(:) = periodic(:)
203
204 cell%deth = abs(det_3x3(cell%hmat))
205
206 IF (cell%deth < 1.0e-10_dp) THEN
207 CALL write_cell_low(cell, "angstrom", default_output_unit)
208 CALL cp_abort(__location__, &
209 "An invalid set of cell vectors was specified. "// &
210 "The cell volume is too small")
211 END IF
212
213 SELECT CASE (cell%symmetry_id)
214 CASE (cell_sym_cubic, &
219 CALL get_cell(cell=cell, abc=abc)
220 abc(2) = plane_distance(0, 1, 0, cell=cell)
221 abc(3) = plane_distance(0, 0, 1, cell=cell)
222 SELECT CASE (cell%symmetry_id)
223 CASE (cell_sym_cubic)
224 abc(1:3) = sum(abc(1:3))/3.0_dp
228 SELECT CASE (cell%symmetry_id)
230 a = 0.5_dp*(abc(1) + abc(2))
231 abc(1) = a
232 abc(2) = a
234 a = 0.5_dp*(abc(1) + abc(3))
235 abc(1) = a
236 abc(3) = a
238 a = 0.5_dp*(abc(2) + abc(3))
239 abc(2) = a
240 abc(3) = a
241 END SELECT
242 END SELECT
243 cell%hmat(1, 1) = abc(1); cell%hmat(1, 2) = 0.0_dp; cell%hmat(1, 3) = 0.0_dp
244 cell%hmat(2, 1) = 0.0_dp; cell%hmat(2, 2) = abc(2); cell%hmat(2, 3) = 0.0_dp
245 cell%hmat(3, 1) = 0.0_dp; cell%hmat(3, 2) = 0.0_dp; cell%hmat(3, 3) = abc(3)
247 CALL get_cell(cell=cell, abc=abc)
248 a = 0.5_dp*(abc(1) + abc(2))
249 acosg = 0.5_dp*a
250 asing = sqrt3*acosg
251 IF (cell%symmetry_id == cell_sym_hexagonal_gamma_120) acosg = -acosg
252 cell%hmat(1, 1) = a; cell%hmat(1, 2) = acosg; cell%hmat(1, 3) = 0.0_dp
253 cell%hmat(2, 1) = 0.0_dp; cell%hmat(2, 2) = asing; cell%hmat(2, 3) = 0.0_dp
254 cell%hmat(3, 1) = 0.0_dp; cell%hmat(3, 2) = 0.0_dp; cell%hmat(3, 3) = abc(3)
256 CALL get_cell(cell=cell, abc=abc)
257 a = sum(abc(1:3))/3.0_dp
258 alpha = (angle(cell%hmat(:, 3), cell%hmat(:, 2)) + &
259 angle(cell%hmat(:, 1), cell%hmat(:, 3)) + &
260 angle(cell%hmat(:, 1), cell%hmat(:, 2)))/3.0_dp
261 acosa = a*cos(alpha)
262 asina = a*sin(alpha)
263 acosah = a*cos(0.5_dp*alpha)
264 asinah = a*sin(0.5_dp*alpha)
265 norm = acosa/acosah
266 norm_c = sqrt(1.0_dp - norm*norm)
267 cell%hmat(1, 1) = a; cell%hmat(1, 2) = acosa; cell%hmat(1, 3) = acosah*norm
268 cell%hmat(2, 1) = 0.0_dp; cell%hmat(2, 2) = asina; cell%hmat(2, 3) = asinah*norm
269 cell%hmat(3, 1) = 0.0_dp; cell%hmat(3, 2) = 0.0_dp; cell%hmat(3, 3) = a*norm_c
271 CALL get_cell(cell=cell, abc=abc)
272 beta = angle(cell%hmat(:, 1), cell%hmat(:, 3))
273 cell%hmat(1, 1) = abc(1); cell%hmat(1, 2) = 0.0_dp; cell%hmat(1, 3) = abc(3)*cos(beta)
274 cell%hmat(2, 1) = 0.0_dp; cell%hmat(2, 2) = abc(2); cell%hmat(2, 3) = 0.0_dp
275 cell%hmat(3, 1) = 0.0_dp; cell%hmat(3, 2) = 0.0_dp; cell%hmat(3, 3) = abc(3)*sin(beta)
277 ! Cell symmetry with a = b, alpha = beta = 90 degree and gammma not equal 90 degree
278 CALL get_cell(cell=cell, abc=abc)
279 a = 0.5_dp*(abc(1) + abc(2))
280 gamma = angle(cell%hmat(:, 1), cell%hmat(:, 2))
281 acosg = a*cos(gamma)
282 asing = a*sin(gamma)
283 cell%hmat(1, 1) = a; cell%hmat(1, 2) = acosg; cell%hmat(1, 3) = 0.0_dp
284 cell%hmat(2, 1) = 0.0_dp; cell%hmat(2, 2) = asing; cell%hmat(2, 3) = 0.0_dp
285 cell%hmat(3, 1) = 0.0_dp; cell%hmat(3, 2) = 0.0_dp; cell%hmat(3, 3) = abc(3)
286 CASE (cell_sym_triclinic)
287 ! Nothing to do
288 END SELECT
289
290 ! Do we have an (almost) orthorhombic cell?
291 IF ((abs(cell%hmat(1, 2)) < eps_hmat) .AND. (abs(cell%hmat(1, 3)) < eps_hmat) .AND. &
292 (abs(cell%hmat(2, 1)) < eps_hmat) .AND. (abs(cell%hmat(2, 3)) < eps_hmat) .AND. &
293 (abs(cell%hmat(3, 1)) < eps_hmat) .AND. (abs(cell%hmat(3, 2)) < eps_hmat)) THEN
294 cell%orthorhombic = .true.
295 ELSE
296 cell%orthorhombic = .false.
297 END IF
298
299 ! Retain an exact orthorhombic cell
300 ! (off-diagonal elements must remain zero identically to keep QS fast)
301 IF (cell%orthorhombic) THEN
302 cell%hmat(1, 2) = 0.0_dp
303 cell%hmat(1, 3) = 0.0_dp
304 cell%hmat(2, 1) = 0.0_dp
305 cell%hmat(2, 3) = 0.0_dp
306 cell%hmat(3, 1) = 0.0_dp
307 cell%hmat(3, 2) = 0.0_dp
308 END IF
309
310 dim = count(cell%perd == 1)
311 IF ((dim == 1) .AND. (.NOT. cell%orthorhombic)) THEN
312 cpabort("Non-orthorhombic and not periodic")
313 END IF
314
315 ! Update deth and hmat_inv with enforced symmetry
316 cell%deth = abs(det_3x3(cell%hmat))
317 IF (cell%deth < 1.0e-10_dp) THEN
318 CALL cp_abort(__location__, &
319 "An invalid set of cell vectors was obtained after applying "// &
320 "the requested cell symmetry. The cell volume is too small")
321 END IF
322 cell%h_inv = inv_3x3(cell%hmat)
323
324 END SUBROUTINE init_cell
325
326! **************************************************************************************************
327!> \brief ...
328!> \param cell ...
329!> \param cell_ref ...
330!> \param use_ref_cell ...
331!> \param cell_section ...
332!> \param topology_section ...
333!> \param check_for_ref ...
334!> \param para_env ...
335!> \par History
336!> 03.2005 created [teo]
337!> 03.2026 revamped logic with pdb and extxyz parsers
338!> \author Teodoro Laino
339! **************************************************************************************************
340 RECURSIVE SUBROUTINE read_cell(cell, cell_ref, use_ref_cell, cell_section, &
341 topology_section, check_for_ref, para_env)
342
343 TYPE(cell_type), POINTER :: cell, cell_ref
344 LOGICAL, INTENT(INOUT), OPTIONAL :: use_ref_cell
345 TYPE(section_vals_type), OPTIONAL, POINTER :: cell_section, topology_section
346 LOGICAL, INTENT(IN), OPTIONAL :: check_for_ref
347 TYPE(mp_para_env_type), POINTER :: para_env
348
349 REAL(kind=dp), PARAMETER :: eps = 1.0e-14_dp
350
351 CHARACTER(LEN=default_path_length) :: cell_file_name, coord_file_name, &
352 error_msg
353 INTEGER :: canonicalize_mode, cell_file_format, &
354 coord_file_format, my_per
355 INTEGER, DIMENSION(:), POINTER :: multiple_unit_cell
356 LOGICAL :: canonicalize_cell, cell_read_a, cell_read_abc, cell_read_alpha_beta_gamma, &
357 cell_read_b, cell_read_c, cell_read_file, my_check_ref, tmp_comb_abc, tmp_comb_cell, &
358 tmp_comb_top, topo_read_coord
359 REAL(kind=dp), DIMENSION(3) :: read_ang, read_len
360 REAL(kind=dp), DIMENSION(3, 3) :: hmat_input, read_mat
361 REAL(kind=dp), DIMENSION(:), POINTER :: cell_par
362 TYPE(cell_type), POINTER :: cell_tmp
363 TYPE(section_vals_type), POINTER :: cell_ref_section
364
365 my_check_ref = .true.
366 NULLIFY (cell_ref_section, cell_par, cell_tmp, multiple_unit_cell)
367 ! cell_tmp has two purposes:
368 ! 1. for transferring matrix of cell vectors from individual
369 ! file parser subroutines to read_mat here, assuming that
370 ! unit conversion has been done in those subroutines;
371 ! 2. for testing whether enforcing symmetry makes a new set
372 ! of cell vectors significantly different from parsed input
373 CALL cell_create(cell_tmp)
374 IF (.NOT. ASSOCIATED(cell)) CALL cell_create(cell, tag="CELL")
375 IF (.NOT. ASSOCIATED(cell_ref)) CALL cell_create(cell_ref, tag="CELL_REF")
376 IF (PRESENT(check_for_ref)) my_check_ref = check_for_ref
377
378 cell%deth = 0.0_dp
379 cell%orthorhombic = .false.
380 cell%perd(:) = 1
381 cell%symmetry_id = cell_sym_none
382 cell%hmat(:, :) = 0.0_dp
383 cell%h_inv(:, :) = 0.0_dp
384 cell%input_cell_canonicalized = .false.
385 cell%input_hmat(:, :) = 0.0_dp
386 cell%input_to_canonical(:, :) = 0.0_dp
387 cell%input_recip_to_canonical(:, :) = 0.0_dp
388 cell_read_file = .false.
389 cell_read_a = .false.
390 cell_read_b = .false.
391 cell_read_c = .false.
392 cell_read_abc = .false.
393 cell_read_alpha_beta_gamma = .false.
394 hmat_input(:, :) = 0.0_dp
395 read_mat(:, :) = 0.0_dp
396 read_ang(:) = 0.0_dp
397 read_len(:) = 0.0_dp
398
399 ! Precedence of retrieving cell information from input:
400 ! 1. CELL/CELL_FILE_NAME
401 ! 2. CELL/ABC and optionally CELL/ALPHA_BETA_GAMMA
402 ! 3. CELL/A, CELL/B, CELL/C
403 ! 4. TOPOLOGY/COORD_FILE_NAME, if topology_section is present
404 ! The actual order of processing is 4 -> 1 -> 2 -> 3, with
405 ! case 4 merged to case 1 (if file format permits) first.
406 ! Store data into either read_mat or read_ang and read_len
407 ! in CP2K units, which will be converted to cell%hmat and A, B, C.
408 CALL section_vals_val_get(cell_section, "A", explicit=cell_read_a)
409 CALL section_vals_val_get(cell_section, "B", explicit=cell_read_b)
410 CALL section_vals_val_get(cell_section, "C", explicit=cell_read_c)
411 CALL section_vals_val_get(cell_section, "ABC", explicit=cell_read_abc)
412 CALL section_vals_val_get(cell_section, "ALPHA_BETA_GAMMA", explicit=cell_read_alpha_beta_gamma)
413 CALL section_vals_val_get(cell_section, "CELL_FILE_NAME", explicit=cell_read_file)
414 CALL section_vals_val_get(cell_section, "CANONICALIZE", i_val=canonicalize_mode)
415 canonicalize_cell = (canonicalize_mode == canonicalize_cell_true)
416
417 ! Case 4
418 tmp_comb_top = (.NOT. (cell_read_file .OR. cell_read_abc))
419 tmp_comb_top = (tmp_comb_top .AND. (.NOT. cell_read_a))
420 tmp_comb_top = (tmp_comb_top .AND. (.NOT. cell_read_b))
421 tmp_comb_top = (tmp_comb_top .AND. (.NOT. cell_read_c))
422 IF (tmp_comb_top) THEN
423 CALL cp_warn(__location__, &
424 "None of the keywords CELL_FILE_NAME, ABC, or A, B, C "// &
425 "are specified in CELL section. CP2K will now attempt to read "// &
426 "TOPOLOGY/COORD_FILE_NAME if its format can be parsed for "// &
427 "cell information.")
428 IF (ASSOCIATED(topology_section)) THEN
429 CALL section_vals_val_get(topology_section, "COORD_FILE_NAME", explicit=topo_read_coord)
430 IF (topo_read_coord) THEN
431 CALL section_vals_val_get(topology_section, "COORD_FILE_NAME", c_val=coord_file_name)
432 CALL section_vals_val_get(topology_section, "COORD_FILE_FORMAT", i_val=coord_file_format)
433 SELECT CASE (coord_file_format) ! Add formats with both cell and coord parser manually
434 CASE (do_coord_cif)
435 CALL section_vals_val_set(cell_section, "CELL_FILE_NAME", c_val=coord_file_name)
436 CALL section_vals_val_set(cell_section, "CELL_FILE_FORMAT", i_val=do_cell_cif)
437 CASE (do_coord_cp2k)
438 CALL section_vals_val_set(cell_section, "CELL_FILE_NAME", c_val=coord_file_name)
439 CALL section_vals_val_set(cell_section, "CELL_FILE_FORMAT", i_val=do_cell_cp2k)
440 CASE (do_coord_pdb)
441 CALL section_vals_val_set(cell_section, "CELL_FILE_NAME", c_val=coord_file_name)
442 CALL section_vals_val_set(cell_section, "CELL_FILE_FORMAT", i_val=do_cell_pdb)
443 CASE (do_coord_xyz)
444 CALL section_vals_val_set(cell_section, "CELL_FILE_NAME", c_val=coord_file_name)
445 CALL section_vals_val_set(cell_section, "CELL_FILE_FORMAT", i_val=do_cell_extxyz)
446 CASE DEFAULT
447 CALL cp_abort(__location__, &
448 "COORD_FILE_FORMAT is not set to one of the implemented "// &
449 "CELL_FILE_FORMAT options and cannot be parsed for cell information!")
450 END SELECT
451 ELSE
452 CALL cp_abort(__location__, &
453 "COORD_FILE_NAME is not set, so no cell information is available!")
454 END IF
455 ELSE
456 CALL cp_warn(__location__, &
457 "TOPOLOGY section is not available, so COORD_FILE_NAME cannot "// &
458 "be parsed for cell information in lieu of missing CELL settings.")
459 END IF
460 END IF
461 ! Former logic in SUBROUTINE read_cell_from_external_file is moved here
462 CALL section_vals_val_get(cell_section, "CELL_FILE_NAME", explicit=cell_read_file)
463 IF (cell_read_file) THEN ! Case 1
464 tmp_comb_cell = (cell_read_abc .OR. (cell_read_a .OR. (cell_read_b .OR. cell_read_c)))
465 IF (tmp_comb_cell) THEN
466 CALL cp_warn(__location__, &
467 "Cell Information provided through A, B, C, or ABC in conjunction "// &
468 "with CELL_FILE_NAME. The definition in external file will override "// &
469 "other ones.")
470 END IF
471 CALL section_vals_val_get(cell_section, "CELL_FILE_NAME", c_val=cell_file_name)
472 CALL section_vals_val_get(cell_section, "CELL_FILE_FORMAT", i_val=cell_file_format)
473 SELECT CASE (cell_file_format)
474 CASE (do_cell_cp2k)
475 CALL read_cell_cp2k(cell_file_name, cell_tmp, para_env)
476 CASE (do_cell_xsc)
477 CALL read_cell_xsc(cell_file_name, cell_tmp, para_env)
478 CASE (do_cell_extxyz)
479 CALL read_cell_xyz(cell_file_name, cell_tmp, para_env)
480 CASE (do_cell_pdb)
481 CALL read_cell_pdb(cell_file_name, cell_tmp, para_env)
482 CASE (do_cell_cif)
483 CALL read_cell_cif(cell_file_name, cell_tmp, para_env)
484 CASE DEFAULT
485 CALL cp_abort(__location__, &
486 "CELL_FILE_FORMAT is not set to one of the implemented "// &
487 "options and cannot be parsed for cell information!")
488 END SELECT
489 read_mat = cell_tmp%hmat
490 ELSE
491 IF (cell_read_abc) THEN ! Case 2
492 CALL section_vals_val_get(cell_section, "ABC", r_vals=cell_par)
493 read_len = cell_par
494 CALL section_vals_val_get(cell_section, "ALPHA_BETA_GAMMA", r_vals=cell_par)
495 read_ang = cell_par
496 IF (cell_read_a .OR. cell_read_b .OR. cell_read_c) THEN
497 CALL cp_warn(__location__, &
498 "Cell information provided through vectors A, B or C in conjunction with ABC. "// &
499 "The definition of the ABC keyword will override the one provided by A, B and C.")
500 END IF
501 ELSE ! Case 3
502 tmp_comb_abc = ((cell_read_a .EQV. cell_read_b) .AND. (cell_read_b .EQV. cell_read_c))
503 IF (tmp_comb_abc) THEN
504 CALL section_vals_val_get(cell_section, "A", r_vals=cell_par)
505 read_mat(:, 1) = cell_par(:)
506 CALL section_vals_val_get(cell_section, "B", r_vals=cell_par)
507 read_mat(:, 2) = cell_par(:)
508 CALL section_vals_val_get(cell_section, "C", r_vals=cell_par)
509 read_mat(:, 3) = cell_par(:)
510 IF (cell_read_alpha_beta_gamma) THEN
511 CALL cp_warn(__location__, &
512 "The keyword ALPHA_BETA_GAMMA is ignored because it was used without the "// &
513 "keyword ABC.")
514 END IF
515 ELSE
516 CALL cp_abort(__location__, &
517 "Neither of the keywords CELL_FILE_NAME or ABC are specified, "// &
518 "and cell vector settings in A, B, C are incomplete!")
519 END IF
520 END IF
521 END IF
522
523 ! Convert read_mat or read_len and read_ang to actual cell%hmat
524 IF (any(read_mat(:, :) > eps)) THEN
525 ! Make a warning before storing cell vectors that
526 ! do not form a triangular matrix.
527 IF (.NOT. canonicalize_cell .AND. &
528 ((abs(read_mat(2, 1)) > eps) .OR. &
529 (abs(read_mat(3, 1)) > eps) .OR. &
530 (abs(read_mat(3, 2)) > eps))) THEN
531 IF (canonicalize_mode == canonicalize_cell_auto) THEN
532 CALL cp_warn(__location__, &
533 "CELL%CANONICALIZE AUTO keeps the general input cell orientation. "// &
534 "The cell matrix is not a lower triangle and does not conform to the "// &
535 "program convention that A lies along the X-axis and B is in the XY plane. "// &
536 "Set CELL%CANONICALIZE TRUE to explicitly transform the cell and supported "// &
537 "cell-dependent input to the canonical internal frame.")
538 ELSE
539 CALL cp_warn(__location__, &
540 "Cell vectors are read but cell matrix is not "// &
541 "a lower triangle, not conforming to the program "// &
542 "convention that A lies along the X-axis and "// &
543 "B is in the XY plane.")
544 END IF
545 END IF
546 cell%hmat = read_mat
547 ELSE
548 IF (any(read_ang(:) > eps) .AND. any(read_len(:) > eps)) THEN
549 CALL set_cell_param(cell, cell_length=read_len, cell_angle=read_ang, &
550 do_init_cell=.false.)
551 ELSE
552 CALL cp_abort(__location__, &
553 "No meaningful cell information is read from parser!")
554 END IF
555 END IF
556 ! Reset cell section so that only A, B, C are kept
557 CALL reset_cell_section_by_cell_mat(cell, cell_section)
558
559 ! Multiple unit cell
560 CALL section_vals_val_get(cell_section, "MULTIPLE_UNIT_CELL", i_vals=multiple_unit_cell)
561 IF (any(multiple_unit_cell /= 1)) CALL set_multiple_unit_cell(cell, multiple_unit_cell)
562
563 CALL section_vals_val_get(cell_section, "PERIODIC", i_val=my_per)
564 SELECT CASE (my_per)
565 CASE (use_perd_x)
566 cell%perd = [1, 0, 0]
567 CASE (use_perd_y)
568 cell%perd = [0, 1, 0]
569 CASE (use_perd_z)
570 cell%perd = [0, 0, 1]
571 CASE (use_perd_xy)
572 cell%perd = [1, 1, 0]
573 CASE (use_perd_xz)
574 cell%perd = [1, 0, 1]
575 CASE (use_perd_yz)
576 cell%perd = [0, 1, 1]
577 CASE (use_perd_xyz)
578 cell%perd = [1, 1, 1]
579 CASE (use_perd_none)
580 cell%perd = [0, 0, 0]
581 CASE DEFAULT
582 cpabort("Invalid or not yet implemented cell periodicity")
583 END SELECT
584
585 ! Load requested cell symmetry
586 CALL section_vals_val_get(cell_section, "SYMMETRY", i_val=cell%symmetry_id)
587 ! Try enforcing symmetry by initializing a temporary copy of cell
588 ! and see if the resulting cell matrix differ significantly
589 hmat_input(:, :) = cell%hmat(:, :)
590 CALL cell_clone(cell, cell_tmp)
591 CALL init_cell(cell_tmp)
592 IF (.NOT. canonicalize_cell .AND. any(abs(cell_tmp%hmat - cell%hmat) > eps)) THEN
593 WRITE (unit=error_msg, fmt="(A)") &
594 "When initializing cell vectors with requested symmetry, one "// &
595 "or more elements of the cell matrix has varied significantly. "// &
596 "The input parameters are either deviating from the symmetry, "// &
597 "or not conforming to the program convention that cell matrix "// &
598 "is a lower triangle. The symmetrized cell vectors will be used "// &
599 "anyway with the input atomic coordinates."
600 CALL cp_warn(__location__, error_msg)
601 END IF
602 IF (canonicalize_cell) THEN
603 CALL canonicalize_cell_matrix(cell_tmp)
604 CALL cell_finalize_canonical_input(cell_tmp, hmat_input, cell_tmp%hmat)
605 END IF
606 CALL cell_clone(cell_tmp, cell)
607 CALL cell_release(cell_tmp)
608 CALL reset_cell_section_by_cell_mat(cell, cell_section)
609
610 IF (my_check_ref) THEN
611 ! Recursive check for reference cell requested
612 cell_ref_section => section_vals_get_subs_vals(cell_section, "CELL_REF")
613 IF (parsed_cp2k_input(cell_ref_section, check_this_section=.true.)) THEN
614 IF (PRESENT(use_ref_cell)) use_ref_cell = .true.
615 CALL read_cell(cell_ref, cell_ref, use_ref_cell=use_ref_cell, &
616 cell_section=cell_ref_section, check_for_ref=.false., &
617 para_env=para_env)
618 ELSE
619 CALL cell_clone(cell, cell_ref, tag="CELL_REF")
620 IF (PRESENT(use_ref_cell)) use_ref_cell = .false.
621 END IF
622 END IF
623
624 END SUBROUTINE read_cell
625
626! **************************************************************************************************
627!> \brief utility function to ease the transition to the new input.
628!> returns true if the new input was parsed
629!> \param input_file the parsed input file
630!> \param check_this_section ...
631!> \return ...
632!> \author fawzi
633! **************************************************************************************************
634 FUNCTION parsed_cp2k_input(input_file, check_this_section) RESULT(res)
635
636 TYPE(section_vals_type), POINTER :: input_file
637 LOGICAL, INTENT(IN), OPTIONAL :: check_this_section
638 LOGICAL :: res
639
640 LOGICAL :: my_check
641 TYPE(section_vals_type), POINTER :: glob_section
642
643 my_check = .false.
644 IF (PRESENT(check_this_section)) my_check = check_this_section
645 res = ASSOCIATED(input_file)
646 IF (res) THEN
647 cpassert(input_file%ref_count > 0)
648 IF (.NOT. my_check) THEN
649 glob_section => section_vals_get_subs_vals(input_file, "GLOBAL")
650 CALL section_vals_get(glob_section, explicit=res)
651 ELSE
652 CALL section_vals_get(input_file, explicit=res)
653 END IF
654 END IF
655
656 END FUNCTION parsed_cp2k_input
657
658! **************************************************************************************************
659!> \brief Sets the cell using the internal parameters (a,b,c) (alpha,beta,gamma)
660!> using the convention: a parallel to the x axis, b in the x-y plane and
661!> and c univoquely determined; gamma is the angle between a and b; beta
662!> is the angle between c and a and alpha is the angle between c and b
663!> \param cell ...
664!> \param cell_length ...
665!> \param cell_angle ...
666!> \param periodic ...
667!> \param do_init_cell ...
668!> \date 03.2008
669!> \author Teodoro Laino
670! **************************************************************************************************
671 SUBROUTINE set_cell_param(cell, cell_length, cell_angle, periodic, do_init_cell)
672
673 TYPE(cell_type), POINTER :: cell
674 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: cell_length, cell_angle
675 INTEGER, DIMENSION(3), INTENT(IN), OPTIONAL :: periodic
676 LOGICAL, INTENT(IN) :: do_init_cell
677
678 REAL(kind=dp), PARAMETER :: eps = epsilon(0.0_dp)
679
680 REAL(kind=dp) :: cos_alpha, cos_beta, cos_gamma, sin_gamma
681
682 cpassert(ASSOCIATED(cell))
683 cpassert(all(cell_angle /= 0.0_dp))
684
685 cos_gamma = cos(cell_angle(3)); IF (abs(cos_gamma) < eps) cos_gamma = 0.0_dp
686 IF (abs(abs(cos_gamma) - 1.0_dp) < eps) cos_gamma = sign(1.0_dp, cos_gamma)
687 sin_gamma = sin(cell_angle(3)); IF (abs(sin_gamma) < eps) sin_gamma = 0.0_dp
688 IF (abs(abs(sin_gamma) - 1.0_dp) < eps) sin_gamma = sign(1.0_dp, sin_gamma)
689 cos_beta = cos(cell_angle(2)); IF (abs(cos_beta) < eps) cos_beta = 0.0_dp
690 IF (abs(abs(cos_beta) - 1.0_dp) < eps) cos_beta = sign(1.0_dp, cos_beta)
691 cos_alpha = cos(cell_angle(1)); IF (abs(cos_alpha) < eps) cos_alpha = 0.0_dp
692 IF (abs(abs(cos_alpha) - 1.0_dp) < eps) cos_alpha = sign(1.0_dp, cos_alpha)
693
694 cell%hmat(:, 1) = [1.0_dp, 0.0_dp, 0.0_dp]
695 cell%hmat(:, 2) = [cos_gamma, sin_gamma, 0.0_dp]
696 cell%hmat(:, 3) = [cos_beta, (cos_alpha - cos_gamma*cos_beta)/sin_gamma, 0.0_dp]
697 cell%hmat(3, 3) = sqrt(1.0_dp - cell%hmat(1, 3)**2 - cell%hmat(2, 3)**2)
698
699 cell%hmat(:, 1) = cell%hmat(:, 1)*cell_length(1)
700 cell%hmat(:, 2) = cell%hmat(:, 2)*cell_length(2)
701 cell%hmat(:, 3) = cell%hmat(:, 3)*cell_length(3)
702
703 IF (do_init_cell) THEN
704 IF (PRESENT(periodic)) THEN
705 CALL init_cell(cell=cell, periodic=periodic)
706 ELSE
707 CALL init_cell(cell=cell)
708 END IF
709 END IF
710
711 END SUBROUTINE set_cell_param
712
713! **************************************************************************************************
714!> \brief Setup of the multiple unit_cell
715!> \param cell ...
716!> \param multiple_unit_cell ...
717!> \date 05.2009
718!> \author Teodoro Laino [tlaino]
719!> \version 1.0
720! **************************************************************************************************
721 SUBROUTINE set_multiple_unit_cell(cell, multiple_unit_cell)
722
723 TYPE(cell_type), POINTER :: cell
724 INTEGER, DIMENSION(:), POINTER :: multiple_unit_cell
725
726 cpassert(ASSOCIATED(cell))
727
728 ! Abort, if one of the value is set to zero
729 IF (any(multiple_unit_cell <= 0)) THEN
730 CALL cp_abort(__location__, &
731 "CELL%MULTIPLE_UNIT_CELL accepts only integer values larger than 0! "// &
732 "A value of 0 or negative is meaningless!")
733 END IF
734
735 ! Scale abc according to user request
736 cell%hmat(:, 1) = cell%hmat(:, 1)*multiple_unit_cell(1)
737 cell%hmat(:, 2) = cell%hmat(:, 2)*multiple_unit_cell(2)
738 cell%hmat(:, 3) = cell%hmat(:, 3)*multiple_unit_cell(3)
739
740 END SUBROUTINE set_multiple_unit_cell
741
742! **************************************************************************************************
743!> \brief Reads cell information from CIF file
744!> \param cif_file_name ...
745!> \param cell ...
746!> \param para_env ...
747!> \date 12.2008
748!> \par Format Information implemented:
749!> _cell_length_a (_cell.length_a)
750!> _cell_length_b (_cell.length_b)
751!> _cell_length_c (_cell.length_c)
752!> _cell_angle_alpha (_cell.length_alpha)
753!> _cell_angle_beta (_cell.length_beta)
754!> _cell_angle_gamma (_cell.length_gamma)
755!>
756!> \author Teodoro Laino [tlaino]
757!> moved from topology_cif (1/2019 JHU)
758! **************************************************************************************************
759 SUBROUTINE read_cell_cif(cif_file_name, cell, para_env)
760
761 CHARACTER(len=*) :: cif_file_name
762 TYPE(cell_type), POINTER :: cell
763 TYPE(mp_para_env_type), POINTER :: para_env
764
765 CHARACTER(len=*), PARAMETER :: routinen = 'read_cell_cif'
766
767 INTEGER :: handle
768 INTEGER, DIMENSION(3) :: periodic
769 LOGICAL :: found
770 REAL(kind=dp), DIMENSION(3) :: cell_angles, cell_lengths
771 TYPE(cp_parser_type) :: parser
772
773 CALL timeset(routinen, handle)
774
775 CALL parser_create(parser, cif_file_name, &
776 para_env=para_env, apply_preprocessing=.false.)
777
778 ! Parsing cell infos
779 periodic = 1
780 ! Check for _cell_length_a or _cell.length_a
781 CALL parser_search_string(parser, "_cell_length_a", ignore_case=.false., found=found, &
782 begin_line=.false., search_from_begin_of_file=.true.)
783 IF (.NOT. found) THEN
784 CALL parser_search_string(parser, "_cell.length_a", ignore_case=.false., found=found, &
785 begin_line=.false., search_from_begin_of_file=.true.)
786 IF (.NOT. found) THEN
787 cpabort("The field _cell_length_a or _cell.length_a was not found in CIF file! ")
788 END IF
789 END IF
790 CALL cif_get_real(parser, cell_lengths(1))
791 cell_lengths(1) = cp_unit_to_cp2k(cell_lengths(1), "angstrom")
792
793 ! Check for _cell_length_b or _cell.length_b
794 CALL parser_search_string(parser, "_cell_length_b", ignore_case=.false., found=found, &
795 begin_line=.false., search_from_begin_of_file=.true.)
796 IF (.NOT. found) THEN
797 CALL parser_search_string(parser, "_cell.length_b", ignore_case=.false., found=found, &
798 begin_line=.false., search_from_begin_of_file=.true.)
799 IF (.NOT. found) THEN
800 cpabort("The field _cell_length_b or _cell.length_b was not found in CIF file! ")
801 END IF
802 END IF
803 CALL cif_get_real(parser, cell_lengths(2))
804 cell_lengths(2) = cp_unit_to_cp2k(cell_lengths(2), "angstrom")
805
806 ! Check for _cell_length_c or _cell.length_c
807 CALL parser_search_string(parser, "_cell_length_c", ignore_case=.false., found=found, &
808 begin_line=.false., search_from_begin_of_file=.true.)
809 IF (.NOT. found) THEN
810 CALL parser_search_string(parser, "_cell.length_c", ignore_case=.false., found=found, &
811 begin_line=.false., search_from_begin_of_file=.true.)
812 IF (.NOT. found) THEN
813 cpabort("The field _cell_length_c or _cell.length_c was not found in CIF file! ")
814 END IF
815 END IF
816 CALL cif_get_real(parser, cell_lengths(3))
817 cell_lengths(3) = cp_unit_to_cp2k(cell_lengths(3), "angstrom")
818
819 ! Check for _cell_angle_alpha or _cell.angle_alpha
820 CALL parser_search_string(parser, "_cell_angle_alpha", ignore_case=.false., found=found, &
821 begin_line=.false., search_from_begin_of_file=.true.)
822 IF (.NOT. found) THEN
823 CALL parser_search_string(parser, "_cell.angle_alpha", ignore_case=.false., found=found, &
824 begin_line=.false., search_from_begin_of_file=.true.)
825 IF (.NOT. found) THEN
826 cpabort("The field _cell_angle_alpha or _cell.angle_alpha was not found in CIF file! ")
827 END IF
828 END IF
829 CALL cif_get_real(parser, cell_angles(1))
830 cell_angles(1) = cp_unit_to_cp2k(cell_angles(1), "deg")
831
832 ! Check for _cell_angle_beta or _cell.angle_beta
833 CALL parser_search_string(parser, "_cell_angle_beta", ignore_case=.false., found=found, &
834 begin_line=.false., search_from_begin_of_file=.true.)
835 IF (.NOT. found) THEN
836 CALL parser_search_string(parser, "_cell.angle_beta", ignore_case=.false., found=found, &
837 begin_line=.false., search_from_begin_of_file=.true.)
838 IF (.NOT. found) THEN
839 cpabort("The field _cell_angle_beta or _cell.angle_beta was not found in CIF file! ")
840 END IF
841 END IF
842 CALL cif_get_real(parser, cell_angles(2))
843 cell_angles(2) = cp_unit_to_cp2k(cell_angles(2), "deg")
844
845 ! Check for _cell_angle_gamma or _cell.angle_gamma
846 CALL parser_search_string(parser, "_cell_angle_gamma", ignore_case=.false., found=found, &
847 begin_line=.false., search_from_begin_of_file=.true.)
848 IF (.NOT. found) THEN
849 CALL parser_search_string(parser, "_cell.angle_gamma", ignore_case=.false., found=found, &
850 begin_line=.false., search_from_begin_of_file=.true.)
851 IF (.NOT. found) THEN
852 cpabort("The field _cell_angle_gamma or _cell.angle_gamma was not found in CIF file! ")
853 END IF
854 END IF
855 CALL cif_get_real(parser, cell_angles(3))
856 cell_angles(3) = cp_unit_to_cp2k(cell_angles(3), "deg")
857
858 ! Create cell
859 CALL set_cell_param(cell, cell_lengths, cell_angles, periodic=periodic, &
860 do_init_cell=.true.)
861
862 CALL parser_release(parser)
863
864 CALL timestop(handle)
865
866 END SUBROUTINE read_cell_cif
867
868! **************************************************************************************************
869!> \brief Reads REAL from the CIF file.. This wrapper is needed in order to
870!> treat properly the accuracy specified in the CIF file, i.e. 3.45(6)
871!> \param parser ...
872!> \param r ...
873!> \date 12.2008
874!> \author Teodoro Laino [tlaino]
875! **************************************************************************************************
876 SUBROUTINE cif_get_real(parser, r)
877
878 TYPE(cp_parser_type), INTENT(INOUT) :: parser
879 REAL(kind=dp), INTENT(OUT) :: r
880
881 CHARACTER(LEN=default_string_length) :: s_tag
882 INTEGER :: iln
883
884 CALL parser_get_object(parser, s_tag)
885 iln = len_trim(s_tag)
886 IF (index(s_tag, "(") /= 0) iln = index(s_tag, "(") - 1
887 READ (s_tag(1:iln), *) r
888
889 END SUBROUTINE cif_get_real
890
891! **************************************************************************************************
892!> \brief Reads xyz file and pass comments on the second line to get cell information
893!> \param xyz_file_name ...
894!> \param cell ...
895!> \param para_env ...
896!> \par History
897!> 03.2026 - Created as read_cell_extxyz with extended XYZ parser
898!> 06.2026 - Refactored the parser to allow for reftraj use
899!> \author HE Zilong
900! **************************************************************************************************
901 SUBROUTINE read_cell_xyz(xyz_file_name, cell, para_env)
902
903 CHARACTER(len=*) :: xyz_file_name
904 TYPE(cell_type), POINTER :: cell
905 TYPE(mp_para_env_type), POINTER :: para_env
906
907 CHARACTER(len=*), PARAMETER :: routinen = 'read_cell_xyz'
908
909 INTEGER :: handle
910 LOGICAL :: has_cell
911 TYPE(cp_parser_type) :: parser
912
913 CALL timeset(routinen, handle)
914
915 CALL parser_create(parser, xyz_file_name, &
916 para_env=para_env, apply_preprocessing=.false.)
917 CALL parser_get_next_line(parser, 2) ! Skip number of atoms
918 CALL read_xyz_comment(parser%input_line, cell, has_cell)
919 IF (.NOT. has_cell) THEN
920 CALL cp_abort(__location__, &
921 "The keyword CELL_FILE_FORMAT requested cell information "// &
922 "from XYZ file, but it is not available from the file <"// &
923 trim(adjustl(xyz_file_name))//"> as CELL_FILE_NAME specified!")
924 END IF
925 CALL parser_release(parser)
926 CALL timestop(handle)
927
928 END SUBROUTINE read_cell_xyz
929
930! **************************************************************************************************
931!> \brief Reads comment line of XYZ files to get cell, step, time and energy info
932!> \param line the single comment line of an XYZ file
933!> \param cell the pointer to which cell is written
934!> \param has_cell a flag for presence of cell information
935!> \param step an integer value for step number, if requested; HUGE(0) if not available
936!> \param time a real value for time, if requested; HUGE(0.0_dp) if not available
937!> \param ener a real value for energy, if requested; HUGE(0.0_dp) if not available
938!> \par Intended for both the FORCE_EVAL/SUBSYS/CELL and MOTION/MD/REFTRAJ.
939!> At minimum, should work with outputs from write_trajectory() in
940!> src/motion_utils.F, around line 879 of src/motion/dumpdcd.F and
941!> write_final_structure() in src/particle_methods.F (for cell only).
942!> Recognized formats (case insensitive, no hard restriction on data width):
943!> (1) Extended xyz format, whose comment on the second line contains fields:
944!> Lattice="Ax Ay Az Bx By Bz Cx Cy Cz"
945!> where Ax, Ay, Az are three Cartesian components of cell vector A,
946!> Bx, By, Bz are components of B, Cx, Cy, Cz are components of C,
947!> all in the unit of angstrom, and must occur;
948!> Step=S
949!> where S is the integer step number;
950!> Time=T
951!> where T is the time in femtoseconds;
952!> Energy=E
953!> where E is the energy.
954!> No whitespace around the = sign is present; the whitespace is used as
955!> the delimiter between fields; apart from lattice= at the front, other
956!> fields are optional and do not have a fixed order.
957!> (2) dumpdcd format, whose comment on the second line contains fields:
958!> a = A, b = B, c = C, alpha = ALPHA, beta = BETA, gamma = GAMMA
959!> where A, B, C are three lengths of cell vectors in angstrom, ALPHA,
960!> BETA, GAMMA are three angles between cell vectors in degrees;
961!> i = I,
962!> where I is the integer step number;
963!> time = T,
964!> where T is the time in femtoseconds;
965!> E = ENER,
966!> where ENER is the energy.
967!> There is one whitespace before and after each equal sign; the comma
968!> is used as the delimiter between fields; the cell information is
969!> optional.
970!>
971!> History
972!> 06.2026 - Created by combining the extxyz parser from former read_cell_extxyz
973!> and the parser for reftraj in src/motion/integrator.F
974!> \author HE Zilong
975! **************************************************************************************************
976 SUBROUTINE read_xyz_comment(line, cell, has_cell, step, time, ener)
977
978 CHARACTER(LEN=*), INTENT(IN) :: line
979 TYPE(cell_type), INTENT(INOUT), POINTER :: cell
980 LOGICAL, INTENT(OUT) :: has_cell
981 INTEGER, INTENT(OUT), OPTIONAL :: step
982 REAL(kind=dp), INTENT(OUT), OPTIONAL :: time, ener
983
984 CHARACTER(LEN=3) :: abc
985 CHARACTER(LEN=max_line_length) :: my_line, raw_str
986 INTEGER :: i, id1, id2, ios, j, my_step
987 REAL(kind=dp) :: my_ener, my_time
988 REAL(kind=dp), DIMENSION(3) :: my_abc, my_albega
989 REAL(kind=dp), DIMENSION(3, 3) :: my_hmat
990
991 has_cell = .false.
992 my_step = huge(0)
993 my_time = huge(0.0_dp)
994 my_ener = huge(0.0_dp)
995 my_hmat = 0.0_dp
996 my_abc = 0.0_dp
997 my_albega = 0.0_dp
998
999 my_line = line
1000 CALL uppercase(my_line)
1001 id1 = index(my_line, "LATTICE=")
1002 IF (id1 > 0) THEN ! Extended XYZ
1003 id2 = index(my_line(id1 + 9:), '"') ! Strip 'LATTICE="' and find the next quote
1004 READ (my_line(id1 + 9:id1 + id2 + 7), '(A)') raw_str
1005 READ (raw_str, *, iostat=ios) my_hmat(:, 1), my_hmat(:, 2), my_hmat(:, 3)
1006 IF (ios /= 0) THEN
1007 CALL cp_abort(__location__, "Error while parsing input line for cell vectors as "// &
1008 "extended XYZ format: expected 9 real values in the <lattice=> "// &
1009 "quoted field, found <"//trim(raw_str)//"> which is invalid!")
1010 ELSE
1011 has_cell = .true.
1012 DO i = 1, 3
1013 DO j = 1, 3
1014 cell%hmat(j, i) = cp_unit_to_cp2k(my_hmat(j, i), "angstrom")
1015 END DO
1016 END DO
1017 END IF
1018 IF (PRESENT(step)) THEN
1019 id1 = index(my_line, "STEP=")
1020 IF (id1 > 0) THEN
1021 READ (my_line(id1 + 5:), '(A)') raw_str
1022 READ (raw_str, *, iostat=ios) my_step
1023 IF (ios /= 0) THEN
1024 CALL cp_abort(__location__, &
1025 "Error while parsing input line for step as extended "// &
1026 "XYZ format: expected 1 integer value in the <step=> "// &
1027 "field, found <"//trim(raw_str)//"> which is invalid!")
1028 END IF
1029 END IF
1030 step = my_step
1031 END IF
1032 IF (PRESENT(time)) THEN
1033 id1 = index(my_line, "TIME=")
1034 IF (id1 > 0) THEN
1035 READ (my_line(id1 + 5:), '(A)') raw_str
1036 READ (raw_str, *, iostat=ios) my_time
1037 IF (ios /= 0) THEN
1038 CALL cp_abort(__location__, &
1039 "Error while parsing input line for time as extended "// &
1040 "XYZ format: expected 1 real value in the <time=> "// &
1041 "field, found <"//trim(raw_str)//"> which is invalid!")
1042 END IF
1043 END IF
1044 time = my_time
1045 END IF
1046 IF (PRESENT(ener)) THEN
1047 id1 = index(my_line, "ENERGY=")
1048 IF (id1 > 0) THEN
1049 READ (my_line(id1 + 7:), '(A)') raw_str
1050 READ (raw_str, *, iostat=ios) my_ener
1051 IF (ios /= 0) THEN
1052 CALL cp_abort(__location__, &
1053 "Error while parsing input line for energy as extended "// &
1054 "XYZ format: expected 1 real value in the <energy=> "// &
1055 "field, found <"//trim(raw_str)//"> which is invalid!")
1056 END IF
1057 END IF
1058 ener = my_ener
1059 END IF
1060 ELSE ! May or may not be dumpdcd format, and may or may not has cell
1061 abc = "ABC"
1062 DO i = 1, 3
1063 id1 = index(my_line, " "//abc(i:i)//" = ")
1064 IF (id1 > 0) THEN
1065 READ (my_line(id1 + 5:), '(A)') raw_str
1066 READ (raw_str, *, iostat=ios) my_abc(i)
1067 IF (ios /= 0) THEN
1068 CALL cp_abort(__location__, &
1069 "Error while parsing input line for cell vector as dumpdcd "// &
1070 "XYZ format: expected 1 real value in the <"//abc(i:i)//" = > "// &
1071 "field, found <"//trim(raw_str)//"> which is invalid!")
1072 ELSE
1073 my_abc(i) = cp_unit_to_cp2k(my_abc(i), "angstrom")
1074 END IF
1075 END IF
1076 END DO
1077 id1 = index(my_line, " ALPHA = ")
1078 IF (id1 > 0) THEN
1079 READ (my_line(id1 + 9:), '(A)') raw_str
1080 READ (raw_str, *, iostat=ios) my_albega(1)
1081 IF (ios /= 0) THEN
1082 CALL cp_abort(__location__, &
1083 "Error while parsing input line for cell angle alpha as dumpdcd "// &
1084 "XYZ format: expected 1 real value in the <alpha = > "// &
1085 "field, found <"//trim(raw_str)//"> which is invalid!")
1086 ELSE
1087 my_albega(1) = cp_unit_to_cp2k(my_albega(1), "deg")
1088 END IF
1089 END IF
1090 id1 = index(my_line, " BETA = ")
1091 IF (id1 > 0) THEN
1092 READ (my_line(id1 + 8:), '(A)') raw_str
1093 READ (raw_str, *, iostat=ios) my_albega(2)
1094 IF (ios /= 0) THEN
1095 CALL cp_abort(__location__, &
1096 "Error while parsing input line for cell angle beta as dumpdcd "// &
1097 "XYZ format: expected 1 real value in the <beta = > "// &
1098 "field, found <"//trim(raw_str)//"> which is invalid!")
1099 ELSE
1100 my_albega(2) = cp_unit_to_cp2k(my_albega(2), "deg")
1101 END IF
1102 END IF
1103 id1 = index(my_line, " GAMMA = ")
1104 IF (id1 > 0) THEN
1105 READ (my_line(id1 + 9:), '(A)') raw_str
1106 READ (raw_str, *, iostat=ios) my_albega(3)
1107 IF (ios /= 0) THEN
1108 CALL cp_abort(__location__, &
1109 "Error while parsing input line for cell angle gamma as dumpdcd "// &
1110 "XYZ format: expected 1 real value in the <gamma = > "// &
1111 "field, found <"//trim(raw_str)//"> which is invalid!")
1112 ELSE
1113 my_albega(3) = cp_unit_to_cp2k(my_albega(3), "deg")
1114 END IF
1115 END IF
1116 IF (all(my_abc(1:3) > 0.0_dp) .AND. all(my_albega(1:3) > 0.0_dp)) THEN
1117 has_cell = .true.
1118 CALL set_cell_param(cell, my_abc, my_albega, do_init_cell=.false.)
1119 END IF
1120 IF (PRESENT(step)) THEN
1121 id1 = index(my_line, " I = ")
1122 IF (id1 > 0) THEN
1123 READ (my_line(id1 + 5:), '(A)') raw_str
1124 READ (raw_str, *, iostat=ios) my_step
1125 IF (ios /= 0) THEN
1126 CALL cp_abort(__location__, &
1127 "Error while parsing input line for step as dumpdcd "// &
1128 "XYZ format: expected 1 integer value in the <i = > "// &
1129 "field, found <"//trim(raw_str)//"> which is invalid!")
1130 END IF
1131 END IF
1132 step = my_step
1133 END IF
1134 IF (PRESENT(time)) THEN
1135 id1 = index(my_line, " TIME = ")
1136 IF (id1 > 0) THEN
1137 READ (my_line(id1 + 8:), '(A)') raw_str
1138 READ (raw_str, *, iostat=ios) my_time
1139 IF (ios /= 0) THEN
1140 CALL cp_abort(__location__, &
1141 "Error while parsing input line for time as dumpdcd "// &
1142 "XYZ format: expected 1 real value in the <time = > "// &
1143 "field, found <"//trim(raw_str)//"> which is invalid!")
1144 END IF
1145 END IF
1146 time = my_time
1147 END IF
1148 IF (PRESENT(ener)) THEN
1149 id1 = index(my_line, " E = ")
1150 IF (id1 > 0) THEN
1151 READ (my_line(id1 + 5:), '(A)') raw_str
1152 READ (raw_str, *, iostat=ios) my_ener
1153 IF (ios /= 0) THEN
1154 CALL cp_abort(__location__, &
1155 "Error while parsing input line for energy as dumpdcd "// &
1156 "XYZ format: expected 1 real value in the <E = > "// &
1157 "field, found <"//trim(raw_str)//"> which is invalid!")
1158 END IF
1159 END IF
1160 ener = my_ener
1161 END IF
1162 END IF
1163
1164 END SUBROUTINE read_xyz_comment
1165
1166! **************************************************************************************************
1167!> \brief Reads cell information from CRYST1 record of PDB file
1168!> \param pdb_file_name ...
1169!> \param cell ...
1170!> \param para_env ...
1171!> \date 03.2026
1172!> \par CRYST1 record may contain space group and Z value at the end,
1173!> but here only the first entries are read:
1174!> COLUMNS DATA TYPE FIELD DEFINITION
1175!> -------------------------------------------------------------
1176!> 1 - 6 Record name "CRYST1"
1177!> 7 - 15 Real(9.3) a a (Angstroms).
1178!> 16 - 24 Real(9.3) b b (Angstroms).
1179!> 25 - 33 Real(9.3) c c (Angstroms).
1180!> 34 - 40 Real(7.2) alpha alpha (degrees).
1181!> 41 - 47 Real(7.2) beta beta (degrees).
1182!> 48 - 54 Real(7.2) gamma gamma (degrees).
1183! **************************************************************************************************
1184 SUBROUTINE read_cell_pdb(pdb_file_name, cell, para_env)
1185
1186 CHARACTER(len=*) :: pdb_file_name
1187 TYPE(cell_type), POINTER :: cell
1188 TYPE(mp_para_env_type), POINTER :: para_env
1189
1190 CHARACTER(len=*), PARAMETER :: routinen = 'read_cell_pdb'
1191
1192 CHARACTER(LEN=default_string_length) :: cryst
1193 INTEGER :: handle, i, ios
1194 INTEGER, DIMENSION(3) :: periodic
1195 LOGICAL :: found
1196 REAL(kind=dp), DIMENSION(3) :: cell_angles, cell_lengths
1197 TYPE(cp_parser_type) :: parser
1198
1199 CALL timeset(routinen, handle)
1200
1201 CALL parser_create(parser, pdb_file_name, &
1202 para_env=para_env, apply_preprocessing=.false.)
1203
1204 CALL parser_search_string(parser, "CRYST1", ignore_case=.false., found=found, &
1205 begin_line=.true., search_from_begin_of_file=.true.)
1206 IF (.NOT. found) THEN
1207 cpabort("The line <CRYST1> was not found in PDB file! ")
1208 END IF
1209
1210 periodic = 1
1211 READ (parser%input_line, *, iostat=ios) cryst, cell_lengths(:), cell_angles(:)
1212 IF (ios /= 0) THEN
1213 CALL cp_abort(__location__, "Error while parsing PDB file "// &
1214 "<"//trim(pdb_file_name)//"> for cell lengths and angles: "// &
1215 "found CRYST1 line as <"//trim(parser%input_line)//">")
1216 END IF
1217 DO i = 1, 3
1218 cell_lengths(i) = cp_unit_to_cp2k(cell_lengths(i), "angstrom")
1219 cell_angles(i) = cp_unit_to_cp2k(cell_angles(i), "deg")
1220 END DO
1221 CALL set_cell_param(cell, cell_lengths, cell_angles, periodic=periodic, &
1222 do_init_cell=.true.)
1223
1224 CALL parser_release(parser)
1225
1226 CALL timestop(handle)
1227
1228 END SUBROUTINE read_cell_pdb
1229
1230! **************************************************************************************************
1231!> \brief Reads cell information from cp2k file
1232!> \param cp2k_file_name ...
1233!> \param cell ...
1234!> \param para_env ...
1235!> \date 03.2026
1236!> \par Isolated from former read_cell_from_external_file
1237! **************************************************************************************************
1238 SUBROUTINE read_cell_cp2k(cp2k_file_name, cell, para_env)
1239
1240 CHARACTER(len=*) :: cp2k_file_name
1241 TYPE(cell_type), POINTER :: cell
1242 TYPE(mp_para_env_type), POINTER :: para_env
1243
1244 CHARACTER(len=*), PARAMETER :: routinen = 'read_cell_cp2k'
1245
1246 INTEGER :: handle, i, idum, j
1247 LOGICAL :: my_end
1248 REAL(kind=dp) :: xdum
1249 REAL(kind=dp), DIMENSION(3, 3) :: hmat
1250 TYPE(cp_parser_type) :: parser
1251
1252 CALL timeset(routinen, handle)
1253
1254 CALL parser_create(parser, cp2k_file_name, &
1255 para_env=para_env, apply_preprocessing=.false.)
1256
1257 CALL parser_get_next_line(parser, 1)
1258 my_end = .false.
1259 DO WHILE (.NOT. my_end)
1260 READ (parser%input_line, *) idum, xdum, hmat(:, 1), hmat(:, 2), hmat(:, 3)
1261 CALL parser_get_next_line(parser, 1, at_end=my_end)
1262 END DO
1263 DO i = 1, 3
1264 DO j = 1, 3
1265 cell%hmat(j, i) = cp_unit_to_cp2k(hmat(j, i), "angstrom")
1266 END DO
1267 END DO
1268
1269 CALL parser_release(parser)
1270
1271 CALL timestop(handle)
1272
1273 END SUBROUTINE read_cell_cp2k
1274
1275! **************************************************************************************************
1276!> \brief Reads cell information from xsc file
1277!> \param xsc_file_name ...
1278!> \param cell ...
1279!> \param para_env ...
1280!> \date 03.2026
1281!> \par Isolated from former read_cell_from_external_file
1282! **************************************************************************************************
1283 SUBROUTINE read_cell_xsc(xsc_file_name, cell, para_env)
1284
1285 CHARACTER(len=*) :: xsc_file_name
1286 TYPE(cell_type), POINTER :: cell
1287 TYPE(mp_para_env_type), POINTER :: para_env
1288
1289 CHARACTER(len=*), PARAMETER :: routinen = 'read_cell_xsc'
1290
1291 INTEGER :: handle, i, idum, j
1292 REAL(kind=dp), DIMENSION(3, 3) :: hmat
1293 TYPE(cp_parser_type) :: parser
1294
1295 CALL timeset(routinen, handle)
1296
1297 CALL parser_create(parser, xsc_file_name, &
1298 para_env=para_env, apply_preprocessing=.false.)
1299
1300 CALL parser_get_next_line(parser, 1)
1301 READ (parser%input_line, *) idum, hmat(:, 1), hmat(:, 2), hmat(:, 3)
1302 DO i = 1, 3
1303 DO j = 1, 3
1304 cell%hmat(j, i) = cp_unit_to_cp2k(hmat(j, i), "angstrom")
1305 END DO
1306 END DO
1307
1308 CALL parser_release(parser)
1309
1310 CALL timestop(handle)
1311
1312 END SUBROUTINE read_cell_xsc
1313
1314! **************************************************************************************************
1315!> \brief Reset cell section by matrix in cell-type pointer
1316!> \param cell ...
1317!> \param cell_section ...
1318!> \date 03.2026
1319!> \par Alternative keywords for cell settings will be unset
1320!> except MULTIPLE_UNIT_CELL, PERIODIC and SYMMETRY.
1321! **************************************************************************************************
1322 SUBROUTINE reset_cell_section_by_cell_mat(cell, cell_section)
1323
1324 TYPE(cell_type), POINTER :: cell
1325 TYPE(section_vals_type), POINTER :: cell_section
1326
1327 REAL(kind=dp), DIMENSION(:), POINTER :: cell_par
1328
1329 CALL section_vals_val_unset(cell_section, "CELL_FILE_NAME")
1330 CALL section_vals_val_unset(cell_section, "CELL_FILE_FORMAT")
1331 CALL section_vals_val_unset(cell_section, "ABC")
1332 CALL section_vals_val_unset(cell_section, "ALPHA_BETA_GAMMA")
1333 CALL section_vals_val_unset(cell_section, "A")
1334 CALL section_vals_val_unset(cell_section, "B")
1335 CALL section_vals_val_unset(cell_section, "C")
1336 ALLOCATE (cell_par(3))
1337 cell_par = cell%hmat(:, 1)
1338 CALL section_vals_val_set(cell_section, "A", r_vals_ptr=cell_par)
1339 ALLOCATE (cell_par(3))
1340 cell_par = cell%hmat(:, 2)
1341 CALL section_vals_val_set(cell_section, "B", r_vals_ptr=cell_par)
1342 ALLOCATE (cell_par(3))
1343 cell_par = cell%hmat(:, 3)
1344 CALL section_vals_val_set(cell_section, "C", r_vals_ptr=cell_par)
1345
1346 END SUBROUTINE reset_cell_section_by_cell_mat
1347
1348! **************************************************************************************************
1349!> \brief Write the cell parameters to the output unit.
1350!> \param cell ...
1351!> \param subsys_section ...
1352!> \param tag ...
1353!> \date 02.06.2000
1354!> \par History
1355!> - 11.2008 Teodoro Laino [tlaino] - rewrite and enabling user driven units
1356!> \author Matthias Krack
1357!> \version 1.0
1358! **************************************************************************************************
1359 SUBROUTINE write_cell(cell, subsys_section, tag)
1360
1361 TYPE(cell_type), POINTER :: cell
1362 TYPE(section_vals_type), POINTER :: subsys_section
1363 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: tag
1364
1365 CHARACTER(LEN=default_string_length) :: label, unit_str
1366 INTEGER :: output_unit
1367 TYPE(cp_logger_type), POINTER :: logger
1368
1369 NULLIFY (logger)
1370 logger => cp_get_default_logger()
1371 IF (PRESENT(tag)) THEN
1372 label = trim(tag)//"|"
1373 ELSE
1374 label = trim(cell%tag)//"|"
1375 END IF
1376
1377 output_unit = cp_print_key_unit_nr(logger, subsys_section, "PRINT%CELL", extension=".Log")
1378 CALL section_vals_val_get(subsys_section, "PRINT%CELL%UNIT", c_val=unit_str)
1379 CALL write_cell_low(cell, unit_str, output_unit, label)
1380 CALL cp_print_key_finished_output(output_unit, logger, subsys_section, "PRINT%CELL")
1381
1382 END SUBROUTINE write_cell
1383
1384! **************************************************************************************************
1385!> \brief Write the cell parameters to the output unit
1386!> \param cell ...
1387!> \param unit_str ...
1388!> \param output_unit ...
1389!> \param label ...
1390!> \date 17.05.2023
1391!> \par History
1392!> - Extracted from write_cell (17.05.2023, MK)
1393!> \version 1.0
1394! **************************************************************************************************
1395 SUBROUTINE write_cell_low(cell, unit_str, output_unit, label)
1396
1397 TYPE(cell_type), POINTER :: cell
1398 CHARACTER(LEN=*), INTENT(IN) :: unit_str
1399 INTEGER, INTENT(IN) :: output_unit
1400 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: label
1401
1402 CHARACTER(LEN=12) :: tag
1403 CHARACTER(LEN=3) :: string
1404 CHARACTER(LEN=default_string_length) :: my_label
1405 REAL(kind=dp) :: alpha, beta, gamma, val
1406 REAL(kind=dp), DIMENSION(3) :: abc
1407 TYPE(enumeration_type), POINTER :: enum
1408 TYPE(keyword_type), POINTER :: keyword
1409 TYPE(section_type), POINTER :: section
1410
1411 NULLIFY (enum)
1412 NULLIFY (keyword)
1413 NULLIFY (section)
1414
1415 IF (output_unit > 0) THEN
1416 CALL get_cell(cell=cell, abc=abc, alpha=alpha, beta=beta, gamma=gamma, tag=tag)
1417 IF (PRESENT(label)) THEN
1418 my_label = label
1419 ELSE
1420 my_label = trim(tag)//"|"
1421 END IF
1422 val = cp_unit_from_cp2k(cell%deth, trim(unit_str)//"^3")
1423 WRITE (unit=output_unit, fmt="(/,T2,A,T61,F20.6)") &
1424 trim(my_label)//" Volume ["//trim(unit_str)//"^3]:", val
1425 val = cp_unit_from_cp2k(1.0_dp, trim(unit_str))
1426 WRITE (unit=output_unit, fmt="(T2,A,T30,3F10.3,3X,A6,F12.6)") &
1427 trim(my_label)//" Vector a ["//trim(unit_str)//"]:", cell%hmat(:, 1)*val, &
1428 "|a| = ", abc(1)*val, &
1429 trim(my_label)//" Vector b ["//trim(unit_str)//"]:", cell%hmat(:, 2)*val, &
1430 "|b| = ", abc(2)*val, &
1431 trim(my_label)//" Vector c ["//trim(unit_str)//"]:", cell%hmat(:, 3)*val, &
1432 "|c| = ", abc(3)*val
1433 WRITE (unit=output_unit, fmt="(T2,A,T69,F12.6)") &
1434 trim(my_label)//" Angle (b,c), alpha [degree]: ", alpha, &
1435 trim(my_label)//" Angle (a,c), beta [degree]: ", beta, &
1436 trim(my_label)//" Angle (a,b), gamma [degree]: ", gamma
1437 IF (cell%symmetry_id /= cell_sym_none) THEN
1438 CALL create_cell_section(section)
1439 keyword => section_get_keyword(section, "SYMMETRY")
1440 CALL keyword_get(keyword, enum=enum)
1441 WRITE (unit=output_unit, fmt="(T2,A,T61,A20)") &
1442 trim(my_label)//" Requested initial symmetry: ", &
1443 adjustr(trim(enum_i2c(enum, cell%symmetry_id)))
1444 CALL section_release(section)
1445 END IF
1446 IF (cell%orthorhombic) THEN
1447 WRITE (unit=output_unit, fmt="(T2,A,T78,A3)") &
1448 trim(my_label)//" Numerically orthorhombic: ", "YES"
1449 ELSE
1450 WRITE (unit=output_unit, fmt="(T2,A,T78,A3)") &
1451 trim(my_label)//" Numerically orthorhombic: ", " NO"
1452 END IF
1453 IF (sum(cell%perd(1:3)) == 0) THEN
1454 WRITE (unit=output_unit, fmt="(T2,A,T77,A4)") &
1455 trim(my_label)//" Periodicity", "NONE"
1456 ELSE
1457 string = ""
1458 IF (cell%perd(1) == 1) string = trim(string)//"X"
1459 IF (cell%perd(2) == 1) string = trim(string)//"Y"
1460 IF (cell%perd(3) == 1) string = trim(string)//"Z"
1461 WRITE (unit=output_unit, fmt="(T2,A,T78,A3)") &
1462 trim(my_label)//" Periodicity", adjustr(string)
1463 END IF
1464 END IF
1465
1466 END SUBROUTINE write_cell_low
1467
1468END MODULE cell_methods
Handles all functions related to the CELL.
subroutine, public write_cell_low(cell, unit_str, output_unit, label)
Write the cell parameters to the output unit.
subroutine, public write_cell(cell, subsys_section, tag)
Write the cell parameters to the output unit.
subroutine, public read_cell_cp2k(cp2k_file_name, cell, para_env)
Reads cell information from cp2k file.
subroutine, public read_cell_cif(cif_file_name, cell, para_env)
Reads cell information from CIF file.
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 read_xyz_comment(line, cell, has_cell, step, time, ener)
Reads comment line of XYZ files to get cell, step, time and energy info.
subroutine, public read_cell_xyz(xyz_file_name, cell, para_env)
Reads xyz file and pass comments on the second line to get cell information.
subroutine, public read_cell_pdb(pdb_file_name, cell, para_env)
Reads cell information from CRYST1 record of PDB file.
subroutine, public cell_finalize_canonical_input(cell, hmat_input, hmat_canonical)
Store the transform between the user input cell and the canonical cell.
recursive subroutine, public read_cell(cell, cell_ref, use_ref_cell, cell_section, topology_section, check_for_ref, para_env)
...
subroutine, public read_cell_xsc(xsc_file_name, cell, para_env)
Reads cell information from xsc file.
subroutine, public init_cell(cell, hmat, periodic)
Initialise/readjust a simulation cell after hmat has been changed.
subroutine, public canonicalize_cell_matrix(cell)
Canonicalize a general cell matrix without changing lengths and angles.
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
integer, parameter, public use_perd_xyz
Definition cell_types.F:42
integer, parameter, public cell_sym_monoclinic
Definition cell_types.F:29
integer, parameter, public use_perd_y
Definition cell_types.F:42
integer, parameter, public cell_sym_triclinic
Definition cell_types.F:29
integer, parameter, public cell_sym_tetragonal_ab
Definition cell_types.F:29
integer, parameter, public use_perd_xz
Definition cell_types.F:42
integer, parameter, public cell_sym_rhombohedral
Definition cell_types.F:29
subroutine, public cell_release(cell)
releases the given cell (see doc/ReferenceCounting.html)
Definition cell_types.F:668
integer, parameter, public use_perd_x
Definition cell_types.F:42
subroutine, public cell_clone(cell_in, cell_out, tag)
Clone cell variable.
Definition cell_types.F:141
integer, parameter, public cell_sym_tetragonal_ac
Definition cell_types.F:29
integer, parameter, public use_perd_z
Definition cell_types.F:42
integer, parameter, public use_perd_yz
Definition cell_types.F:42
subroutine, public get_cell(cell, alpha, beta, gamma, deth, orthorhombic, abc, periodic, h, h_inv, symmetry_id, tag)
Get informations about a simulation cell.
Definition cell_types.F:233
integer, parameter, public use_perd_none
Definition cell_types.F:42
integer, parameter, public cell_sym_hexagonal_gamma_60
Definition cell_types.F:29
integer, parameter, public cell_sym_orthorhombic
Definition cell_types.F:29
integer, parameter, public cell_sym_none
Definition cell_types.F:29
integer, parameter, public cell_sym_hexagonal_gamma_120
Definition cell_types.F:29
integer, parameter, public cell_sym_monoclinic_gamma_ab
Definition cell_types.F:29
integer, parameter, public cell_sym_cubic
Definition cell_types.F:29
integer, parameter, public use_perd_xy
Definition cell_types.F:42
integer, parameter, public cell_sym_tetragonal_bc
Definition cell_types.F:29
real(kind=dp) function, public plane_distance(h, k, l, cell)
Calculate the distance between two lattice planes as defined by a triple of Miller indices (hkl).
Definition cell_types.F:324
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_get_next_line(parser, nline, at_end)
Read the next input line and broadcast the input information. Skip (nline-1) lines and skip also all ...
subroutine, public parser_search_string(parser, string, ignore_case, found, line, begin_line, search_from_begin_of_file)
Search a string pattern in a file defined by its logical unit number "unit". A case sensitive search ...
Utility routines to read data from files. Kept as close as possible to the old parser because.
subroutine, public parser_release(parser)
releases the parser
subroutine, public parser_create(parser, file_name, unit_nr, para_env, end_section_label, separator_chars, comment_char, continuation_char, quote_char, section_char, parse_white_lines, initial_variables, apply_preprocessing)
Start a parser run. Initial variables allow to @SET stuff before opening the file.
unit conversion facility
Definition cp_units.F:30
real(kind=dp) function, public cp_unit_from_cp2k(value, unit_str, defaults, power)
converts from the internal cp2k units to the given unit
Definition cp_units.F:1251
real(kind=dp) function, public cp_unit_to_cp2k(value, unit_str, defaults, power)
converts to the internal cp2k units to the given unit
Definition cp_units.F:1222
Calculation of the incomplete Gamma function F_n(t) for multi-center integrals over Cartesian Gaussia...
Definition gamma.F:15
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_cell_extxyz
integer, parameter, public do_cell_pdb
integer, parameter, public canonicalize_cell_true
integer, parameter, public do_coord_cif
integer, parameter, public do_cell_cif
integer, parameter, public do_cell_xsc
integer, parameter, public do_coord_pdb
integer, parameter, public do_cell_cp2k
integer, parameter, public do_coord_xyz
integer, parameter, public canonicalize_cell_auto
integer, parameter, public do_coord_cp2k
builds the subsystem section of the input
subroutine, public create_cell_section(section, periodic)
creates the cell section
represents an enumeration, i.e. a mapping between integers and strings
character(len=default_string_length) function, public enum_i2c(enum, i)
maps an integer to a string
represents keywords in an input
subroutine, public keyword_get(keyword, names, usage, description, type_of_var, n_var, default_value, lone_keyword_value, repeats, enum, citations)
...
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_unset(section_vals, keyword_name, i_rep_section, i_rep_val)
unsets (removes) the requested value (if it is a keyword repetitions removes the repetition,...
subroutine, public section_vals_val_set(section_vals, keyword_name, i_rep_section, i_rep_val, val, l_val, i_val, r_val, c_val, l_vals_ptr, i_vals_ptr, r_vals_ptr, c_vals_ptr)
sets the requested value
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
recursive subroutine, public section_release(section)
releases the given keyword list (see doc/ReferenceCounting.html)
recursive type(keyword_type) function, pointer, public section_get_keyword(section, keyword_name)
returns the requested keyword
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
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 max_line_length
Definition kinds.F:59
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
integer, parameter, public default_output_unit
Definition machine.F:46
Definition of mathematical constants and functions.
real(kind=dp), parameter, public degree
real(kind=dp), parameter, public sqrt3
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
pure real(kind=dp) function, public angle(a, b)
Calculation of the angle between the vectors a and b. The angle is returned in radians.
Definition mathlib.F:184
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
Interface to the message passing library MPI.
Utilities for string manipulations.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
type of a logger, at the moment it contains just a print level starting at which level it should be l...
represent a keyword in the input
represent a section of the input file
stores all the informations relevant to an mpi environment