40 INTEGER,
PARAMETER :: default_error_unit = 0, &
41 default_input_unit = 5, &
42 default_output_unit = 6
43 INTEGER :: error_unit = default_error_unit, &
44 input_unit = default_input_unit, &
45 output_unit = default_output_unit
49 CHARACTER(LEN=*),
PARAMETER :: routinen =
"dumpdcd", &
50 version_info = routinen//
" v3.2 (16.06.2022)"
52 INTEGER,
PARAMETER :: dp = selected_real_kind(14, 200), &
53 sp = selected_real_kind(6, 30)
54 INTEGER,
PARAMETER :: default_string_length = 240, &
55 cell_input_unit = 10, &
58 REAL(kind=dp),
PARAMETER :: pi = 3.14159265358979323846264338_dp
59 REAL(kind=dp),
PARAMETER :: angstrom = 0.52917720859_dp, &
60 degree = 180.0_dp/pi, &
61 kelvin = 315774.647902944_dp, &
62 massunit = 1822.88484264550_dp
65 CHARACTER(LEN=4) :: id_dcd
66 CHARACTER(LEN=10) :: unit_string
67 CHARACTER(LEN=17) :: fmt_string
68 CHARACTER(LEN=default_string_length) :: arg, cell_file_name, dcd_file_name, message, out_file_name, &
69 output_format, remark_xyz, string, xyz_file_name
70 CHARACTER(LEN=5),
DIMENSION(:),
ALLOCATABLE :: atomic_label
71 CHARACTER(LEN=80),
DIMENSION(2) :: remark_dcd
72 INTEGER :: first_frame, have_unit_cell, i, iarg, iatom, &
73 iframe, istat, istep_dcd, istride_dcd, last_frame, narg, &
74 natom_dcd, natom_xyz, ndcd_file, nframe, &
75 nframe_read, nremark, stride
76 LOGICAL :: apply_pbc, debug, dump_frame, eformat, ekin, eo, &
77 have_atomic_labels, have_cell_file, ignore_warnings, info, &
78 opened, output_format_dcd, output_format_xmol, pbc0, &
79 print_atomic_displacements, print_scaled_coordinates, &
80 print_scaled_pbc_coordinates, trace_atoms, vel2cord
81 REAL(kind=sp) :: dt_dcd
82 REAL(kind=dp) :: a, a_dcd, alpha, alpha_dcd, b, b_dcd, beta, beta_dcd, c, c_dcd, &
83 cell_volume, dt, energy, eps_angle, eps_geo, eps_out_of_box, &
84 first_step_time,
gamma, gamma_dcd, md_time_step, ndt, step_time, &
86 INTEGER,
DIMENSION(16) :: idum
87 REAL(kind=dp),
DIMENSION(3) :: rdum
88 REAL(kind=dp),
DIMENSION(:),
ALLOCATABLE :: atomic_displacement, atomic_mass, atomic_temperature
89 REAL(kind=dp),
DIMENSION(3, 3) :: h, hinv, hmat
90 REAL(kind=sp),
DIMENSION(:, :),
ALLOCATABLE :: r
91 REAL(kind=dp),
DIMENSION(:, :),
ALLOCATABLE :: r_pbc, r0, s, s_pbc
100 ignore_warnings = .false.
102 trace_atoms = .false.
104 print_atomic_displacements = .false.
105 print_scaled_coordinates = .false.
106 print_scaled_pbc_coordinates = .false.
115 have_atomic_labels = .false.
116 have_cell_file = .false.
124 output_format =
"default"
125 output_format_dcd = .false.
126 output_format_xmol = .false.
138 eps_out_of_box = -huge(0.0_dp)
139 first_step_time = 0.0_dp
140 md_time_step = 0.0_dp
146 narg = command_argument_count()
159 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
162 CASE (
"-cell_file",
"-cell")
164 CALL get_command_argument(number=iarg,
VALUE=cell_file_name, status=istat)
165 have_cell_file = .true.
167 CASE (
"-debug",
"-d")
171 CASE (
"-displacements",
"-disp")
172 print_atomic_displacements = .true.
183 CASE (
"-first_frame",
"-first",
"-ff")
185 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
186 READ (unit=arg, fmt=*, err=100) first_frame
187 IF (first_frame <= 0)
THEN
188 CALL abort_program(routinen,
"Invalid number for first frame specified: "// &
189 "first_frame must be greater than zero")
192 100
CALL abort_program(routinen,
"Invalid number for first frame specified "// &
193 "(an integer number greater than zero is expected)")
197 CASE (
"-ignore_warnings")
198 ignore_warnings = .true.
203 CASE (
"-last_frame",
"-last",
"-lf")
205 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
206 READ (unit=arg, fmt=*, err=101) last_frame
207 IF (last_frame <= 0)
THEN
208 CALL abort_program(routinen,
"Invalid number for last frame specified: "// &
209 "last_frame must be greater than zero")
212 101
CALL abort_program(routinen,
"Invalid number for last frame specified "// &
213 "(an integer number greater than zero is expected)")
214 CASE (
"-md_time_step")
216 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
217 READ (unit=arg, fmt=*, err=102) md_time_step
218 IF (md_time_step <= 0.0_dp)
THEN
219 CALL abort_program(routinen,
"Invalid (negative) MD time step specified")
222 102
CALL abort_program(routinen,
"Invalid MD time step specified")
223 CASE (
"-o",
"-output")
225 CALL get_command_argument(number=iarg,
VALUE=out_file_name, status=istat)
227 CASE (
"-output_format",
"-of")
229 CALL get_command_argument(number=iarg,
VALUE=output_format, status=istat)
231 SELECT CASE (output_format)
233 output_format_dcd = .true.
234 output_format_xmol = .false.
236 output_format_dcd = .false.
237 output_format_xmol = .true.
239 CALL abort_program(routinen,
"Invalid output format type specified")
250 CASE (
"-scaled_coordinates",
"-sc")
251 print_scaled_coordinates = .true.
253 CASE (
"-scaled_pbc_coordinates",
"-spc")
254 print_scaled_pbc_coordinates = .true.
258 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
259 READ (unit=arg, fmt=*, err=104) stride
261 CALL abort_program(routinen,
"Invalid stride for frame dump specified: stride must be greater than zero")
264 104
CALL abort_program(routinen,
"Invalid stride for frame dump specified "// &
265 "(an integer number greater than 0 is expected)")
266 CASE (
"-trace_atoms")
268 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
269 READ (unit=arg, fmt=*, err=108) eps_out_of_box
270 IF (eps_out_of_box <= 0.0_dp)
THEN
271 CALL abort_program(routinen,
"Invalid threshold value for -trace_atoms flag specified")
275 108
CALL abort_program(routinen,
"Invalid threshold value for -trace_atoms flag specified")
276 CASE (
"-vel2cord",
"-v2c",
"-frc2cord",
"-f2c")
279 CASE (
"-xyz",
"xyz_file")
281 CALL get_command_argument(number=iarg,
VALUE=xyz_file_name, status=istat)
282 have_atomic_labels = .true.
285 IF (arg(1:1) ==
"-")
THEN
287 CALL abort_program(routinen,
"Unknown command line flag """//trim(arg)//
""" found")
293 IF (first_frame > last_frame)
THEN
294 CALL abort_program(routinen,
"Number of first frame greater than number of last frame")
296 IF ((.NOT. have_atomic_labels) .AND. output_format_xmol)
THEN
297 CALL abort_program(routinen,
"The output format XMOL requires a valid xyz file (-xyz flag)")
299 IF (output_format_xmol .AND. ekin)
THEN
300 CALL abort_program(routinen,
"Output format XMOL and the -ekin flag are incompatible")
302 IF (output_format_xmol .AND. print_atomic_displacements)
THEN
303 CALL abort_program(routinen,
"Output format XMOL and the -displacements flag are incompatible")
305 IF (output_format_xmol .AND. eo)
THEN
306 CALL abort_program(routinen,
"The -eo flag is incompatible with the output format XMOL")
308 IF (.NOT. have_atomic_labels .AND. ekin)
THEN
309 CALL abort_program(routinen,
"ekin flag requires also the specification of a valid xyz file (-xyz flag)")
311 IF (.NOT. apply_pbc .AND. trace_atoms)
THEN
312 CALL abort_program(routinen,
"The -trace_atoms flag requires the specification of a -pbc flag")
314 IF (ekin .AND. print_atomic_displacements)
THEN
315 CALL abort_program(routinen,
"The -ekin flag and the -displacements flag are incompatible")
317 IF (print_scaled_coordinates .AND. print_scaled_pbc_coordinates)
THEN
318 CALL abort_program(routinen,
"The -sc flag and the -spc flag are incompatible")
320 IF (.NOT. apply_pbc .AND. print_scaled_coordinates)
THEN
321 CALL abort_program(routinen,
"The -sc flag requires the specification of a -pbc flag")
323 IF (.NOT. apply_pbc .AND. print_scaled_pbc_coordinates)
THEN
324 CALL abort_program(routinen,
"The -spc flag requires the specification of a -pbc flag")
329 fmt_string =
"(A5,3(1X,ES14.6))"
331 fmt_string =
"(A5,3(1X, F14.6))"
335 IF (output_format_dcd)
THEN
337 IF (len_trim(out_file_name) == 0) out_file_name =
"output.dcd"
339 INQUIRE (unit=output_unit, name=string)
340 IF (trim(string) /= trim(out_file_name))
CLOSE (unit=output_unit)
341 INQUIRE (unit=output_unit, opened=opened)
342 IF (.NOT. opened)
THEN
343 OPEN (unit=output_unit, &
344 file=out_file_name, &
346 access=
"SEQUENTIAL", &
347 form=
"UNFORMATTED", &
350 IF (istat /= 0)
CALL abort_program(routinen,
"The unformatted output file could not be opened")
353 IF (eo) error_unit = output_unit
354 IF (len_trim(out_file_name) > 0)
THEN
356 INQUIRE (unit=output_unit, name=string)
357 IF (trim(string) /= trim(out_file_name))
CLOSE (unit=output_unit)
358 INQUIRE (unit=output_unit, opened=opened)
359 IF (.NOT. opened)
THEN
360 OPEN (unit=output_unit, &
361 file=out_file_name, &
363 access=
"SEQUENTIAL", &
368 IF (istat /= 0)
CALL abort_program(routinen,
"The formatted output file could not be opened")
374 IF (trim(dcd_file_name) == trim(out_file_name))
THEN
375 CALL abort_program(routinen,
"Input and output file name cannot be the same")
379 IF (have_atomic_labels)
THEN
382 INQUIRE (unit=xyz_input_unit, name=string)
383 IF (trim(string) /= trim(xyz_file_name))
CLOSE (unit=xyz_input_unit)
384 INQUIRE (unit=xyz_input_unit, opened=opened)
386 IF (.NOT. opened)
THEN
387 OPEN (unit=xyz_input_unit, &
388 file=xyz_file_name, &
390 access=
"SEQUENTIAL", &
395 IF (istat /= 0)
CALL abort_program(routinen,
"The XYZ file could not be opened")
396 IF (info)
WRITE (unit=error_unit, fmt=
"(A)")
"#",
"# Reading XYZ file: "//trim(xyz_file_name)
397 READ (unit=xyz_input_unit, fmt=
"(A)", iostat=istat) arg
399 CALL abort_program(routinen,
"Reading line 1 of the XYZ file (number of atoms) failed")
401 IF (arg(1:1) ==
"#")
THEN
402 READ (unit=arg, fmt=*) string, natom_xyz
404 READ (unit=arg, fmt=*) natom_xyz
407 CALL abort_program(routinen,
"Reading line 1 of the XYZ file (number of atoms) failed")
409 IF (
ALLOCATED(atomic_label))
DEALLOCATE (atomic_label)
410 ALLOCATE (atomic_label(natom_xyz), stat=istat)
411 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the vector atomic_label failed")
414 IF (
ALLOCATED(atomic_mass))
DEALLOCATE (atomic_mass)
415 ALLOCATE (atomic_mass(natom_xyz), stat=istat)
416 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the vector atomic_mass failed")
418 READ (unit=xyz_input_unit, fmt=
"(A)", iostat=istat) remark_xyz
419 IF (istat /= 0)
CALL abort_program(routinen,
"Reading line 2 of the XYZ file (remark line) failed")
422 READ (unit=xyz_input_unit, fmt=*) arg
423 IF (arg(1:1) ==
"#")
THEN
426 backspace(unit=xyz_input_unit)
429 READ (unit=xyz_input_unit, fmt=*, iostat=istat) atomic_label(iatom), rdum(1:3)
432 WRITE (unit=message, fmt=
"(A,I0,A,I0,A)") &
433 "Reading line ", iatom + 2,
" of the XYZ file (atom ", iatom,
") failed"
437 IF (len_trim(atomic_label(iatom)) > 1)
CALL lowercase(atomic_label(iatom) (2:2))
438 atomic_label(iatom) = trim(adjustl(atomic_label(iatom)))
440 IF (iatom == natom_xyz)
EXIT
443 WRITE (unit=error_unit, fmt=
"(A,I0)") &
444 "# Number of atoms : ", natom_xyz, &
445 "# Remark : "//trim(adjustl(remark_xyz))
451 IF (have_cell_file)
THEN
454 INQUIRE (unit=cell_input_unit, name=string)
455 IF (trim(string) /= trim(cell_file_name))
CLOSE (unit=cell_input_unit)
456 INQUIRE (unit=cell_input_unit, opened=opened)
458 IF (.NOT. opened)
THEN
459 OPEN (unit=cell_input_unit, &
460 file=cell_file_name, &
462 access=
"SEQUENTIAL", &
467 IF (istat /= 0)
CALL abort_program(routinen,
"The cell file could not be opened")
468 IF (info)
WRITE (unit=error_unit, fmt=
"(A)")
"#",
"# Reading cell file: "//trim(cell_file_name)
473 ndcd_file = ndcd_file + 1
476 OPEN (unit=input_unit, &
477 file=dcd_file_name, &
479 form=
"UNFORMATTED", &
483 IF (istat /= 0)
CALL abort_program(routinen,
"The DCD file could not be opened")
485 WRITE (unit=error_unit, fmt=
"(A,/,(A,I0))") &
487 "# DCD file number : ", ndcd_file, &
488 "# Reading DCD file: "//trim(dcd_file_name)
492 READ (unit=input_unit) id_dcd, idum(1), istep_dcd, istride_dcd, idum(2:7), dt_dcd, have_unit_cell, idum(8:16)
494 WRITE (unit=error_unit, fmt=
"(A,2(/,A,I0),/,A,F9.3,/,A,I0)") &
495 "# DCD id string : "//id_dcd, &
496 "# Step : ", istep_dcd, &
497 "# Print frequency : ", istride_dcd, &
498 "# Time step [fs] : ", dt_dcd, &
499 "# Unit cell : ", have_unit_cell
502 IF (ekin .AND. trim(adjustl(id_dcd)) /=
"VEL")
THEN
503 CALL abort_program(routinen,
"ekin flag requires a DCD file with VELocities")
505 IF (apply_pbc .AND. (have_unit_cell /= 1))
THEN
506 CALL abort_program(routinen,
"pbc flags require that unit cell information is available")
509 IF ((trim(adjustl(id_dcd)) ==
"FRC") .OR. (trim(adjustl(id_dcd)) ==
"VEL"))
THEN
510 unit_string =
"[a.u.]"
511 IF (apply_pbc)
CALL abort_program(routinen,
"pbc flags require a DCD file with COoRDinates")
512 ELSE IF (trim(adjustl(id_dcd)) ==
"CORD")
THEN
513 unit_string =
"[Angstrom]"
515 CALL abort_program(routinen,
"Unknown DCD id found (use -debug or -info flag for details)")
519 READ (unit=input_unit) nremark, remark_dcd(1), remark_dcd(2)
522 WRITE (unit=error_unit, fmt=
"(A,I1,A)") &
523 "# Remark ", i,
" : "//trim(remark_dcd(i))
528 READ (unit=input_unit) natom_dcd
530 WRITE (unit=error_unit, fmt=
"(A,I0)") &
531 "# Number of atoms : ", natom_dcd
534 IF (have_atomic_labels)
THEN
535 IF (natom_dcd /= natom_xyz)
CALL abort_program(routinen,
"Number of atoms in XYZ and DCD file differ")
537 IF (.NOT.
ALLOCATED(atomic_label))
THEN
538 ALLOCATE (atomic_label(natom_dcd), stat=istat)
539 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the vector atomic_label failed")
545 IF (md_time_step > 0.0_dp)
THEN
546 dt_dcd = real(md_time_step, kind=sp)
549 dt = real(dt_dcd, kind=dp)
553 IF (output_format_dcd)
THEN
554 IF (vel2cord) id_dcd =
"CORD"
556 WRITE (unit=output_unit) id_dcd, idum(1), istep_dcd, istride_dcd, idum(2:7), dt_dcd, have_unit_cell, idum(8:16)
557 WRITE (unit=output_unit) nremark, remark_dcd(1), remark_dcd(2)
558 WRITE (unit=output_unit) natom_dcd
565 IF (nframe < first_frame)
THEN
568 IF (
modulo(nframe - first_frame, stride) == 0)
THEN
576 IF (have_unit_cell == 1)
THEN
577 READ (unit=input_unit, iostat=istat) a,
gamma, b, beta, alpha, c
578 IF (istat < 0)
EXIT frame_loop
580 IF (have_cell_file)
THEN
583 READ (unit=cell_input_unit, fmt=*, iostat=istat) string
586 WRITE (unit=message, fmt=
"(A)") &
587 "Reading frame (step) from cell file "//trim(cell_file_name)//
" failed"
590 IF (string(1:1) ==
"#")
THEN
593 backspace(unit=cell_input_unit)
597 READ (unit=cell_input_unit, fmt=*, iostat=istat) iframe, step_time, hmat(1:3, 1:3), cell_volume
599 WRITE (unit=error_unit, fmt=
"(/,T2,A,I0)") &
600 "IOSTAT = ", istat, &
601 "Line read: """//trim(string)//
""""
603 WRITE (unit=message, fmt=
"(A)") &
604 "Invalid cell information read from cell file "//trim(cell_file_name)
608 IF (nframe == first_frame) first_step_time = step_time
610 IF ((nframe >= first_frame) .AND. (nframe <= last_frame))
THEN
612 IF (have_unit_cell == 1)
THEN
621 a = sqrt(dot_product(hmat(1:3, 1), hmat(1:3, 1)))
622 b = sqrt(dot_product(hmat(1:3, 2), hmat(1:3, 2)))
623 c = sqrt(dot_product(hmat(1:3, 3), hmat(1:3, 3)))
625 IF (unit_string ==
"[a.u.]")
THEN
630 alpha =
angle(hmat(1:3, 2), hmat(1:3, 3))*degree
631 beta =
angle(hmat(1:3, 3), hmat(1:3, 1))*degree
632 gamma =
angle(hmat(1:3, 1), hmat(1:3, 2))*degree
633 IF (have_unit_cell == 1)
THEN
635 IF (.NOT. ignore_warnings)
THEN
636 IF (md_time_step > 0.0_dp)
THEN
637 string =
"Time step (requested) ="
639 string =
"Time step (DCD header) ="
641 ndt = (step_time - first_step_time)/dt
642 IF (abs(ndt - anint(ndt)) > 0.01_dp)
THEN
643 WRITE (unit=error_unit, fmt=
"(/,T2,A,I8,/,(T2,A,F15.6,A))") &
644 "Step number (CELL file) = ", iframe, &
645 "Step time (CELL file) = ", step_time,
" fs", &
646 "First step (CELL file) = ", first_step_time,
" fs", &
647 "Time since first step = ", step_time - first_step_time,
" fs", &
648 "Steps since first step = ", ndt,
"", &
649 trim(string)//
" ", dt,
" fs"
650 WRITE (unit=error_unit, fmt=
"(/,T2,A)") &
651 "*** WARNING: MD step time in cell file is not a multiple of the MD time step in the DCD file header ***"
655 IF (abs(a - a_dcd) > eps_geo)
THEN
656 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
657 "a (CELL file) = ", a, &
658 "a (DCD header) = ", a_dcd
659 CALL abort_program(routinen,
"Cell file and DCD file information for lattice constant ""a"" differ")
661 IF (abs(b - b_dcd) > eps_geo)
THEN
662 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
663 "b (CELL file) = ", b, &
664 "b (DCD header) = ", b_dcd
665 CALL abort_program(routinen,
"Cell file and DCD file information for lattice constant ""b"" differ")
667 IF (abs(c - c_dcd) > eps_geo)
THEN
668 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
669 "c (CELL file) = ", c, &
670 "c (DCD header) = ", c_dcd
671 CALL abort_program(routinen,
"Cell file and DCD file information for lattice constant ""c"" differ")
673 eps_angle = 1.0e-4_dp
674 IF (abs(alpha - alpha_dcd) > eps_angle)
THEN
675 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
676 "alpha (CELL file) = ", alpha, &
677 "alpha (DCD header) = ", alpha_dcd
678 CALL abort_program(routinen,
"Cell file and DCD file information for cell angle ""alpha"" differ")
680 IF (abs(beta - beta_dcd) > eps_angle)
THEN
681 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
682 "beta (CELL file) = ", beta, &
683 "beta (DCD header) = ", beta_dcd
684 CALL abort_program(routinen,
"Cell file and DCD file information for cell angle ""beta"" differ")
686 IF (abs(
gamma - gamma_dcd) > eps_angle)
THEN
687 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
688 "gamma (CELL file) = ",
gamma, &
689 "gamma (DCD header) = ", gamma_dcd
690 CALL abort_program(routinen,
"Cell file and DCD file information for cell angle ""beta"" differ")
696 IF ((info .OR. trace_atoms) .AND. dump_frame)
THEN
697 WRITE (unit=error_unit, fmt=
"(A,/,A,I0)") &
698 "#",
"# Frame number : ", nframe
702 IF (info .AND. dump_frame)
THEN
703 IF (have_unit_cell == 1)
THEN
704 WRITE (unit=error_unit, fmt=
"(A,/,(A,T19,A,F12.6))") &
706 "# a "//trim(unit_string),
": ", a, &
707 "# b "//trim(unit_string),
": ", b, &
708 "# c "//trim(unit_string),
": ", c
709 WRITE (unit=error_unit, fmt=
"(A,F12.6)") &
710 "# alpha [degree] : ", alpha, &
711 "# beta [degree] : ", beta, &
712 "# gamma [degree] : ",
gamma
717 IF (.NOT.
ALLOCATED(r))
THEN
718 ALLOCATE (r(natom_dcd, 3), stat=istat)
719 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the array r failed")
723 READ (unit=input_unit, iostat=istat) r(1:natom_dcd, 1)
724 IF (istat < 0)
EXIT frame_loop
725 READ (unit=input_unit) r(1:natom_dcd, 2)
726 READ (unit=input_unit) r(1:natom_dcd, 3)
730 IF ((nframe == 1) .AND. print_atomic_displacements)
THEN
731 IF (.NOT.
ALLOCATED(r0))
THEN
732 ALLOCATE (r0(natom_dcd, 3), stat=istat)
733 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the array r0 failed")
736 IF (.NOT.
ALLOCATED(atomic_displacement))
THEN
737 ALLOCATE (atomic_displacement(natom_dcd), stat=istat)
739 CALL abort_program(routinen,
"Allocation of the vector atomic_displacement failed")
742 atomic_displacement(:) = 0.0_dp
745 IF (ekin .AND. trim(adjustl(id_dcd)) ==
"VEL")
THEN
750 IF (.NOT.
ALLOCATED(atomic_temperature))
THEN
751 ALLOCATE (atomic_temperature(natom_dcd), stat=istat)
753 CALL abort_program(routinen,
"Allocation of the vector atomic_temperature failed")
755 atomic_temperature(:) = 0.0_dp
759 WRITE (unit=error_unit, fmt=
"(A)") &
765 DO iatom = 1, natom_dcd
766 atomic_temperature(iatom) = atomic_mass(iatom)*(r(iatom, 1)*r(iatom, 1) + &
767 r(iatom, 2)*r(iatom, 2) + &
768 r(iatom, 3)*r(iatom, 3))*kelvin/3.0_dp
769 tavg_frame = tavg_frame + atomic_temperature(iatom)
771 tavg_frame = tavg_frame/real(natom_dcd, kind=dp)
773 IF (output_format_dcd)
THEN
774 IF (have_unit_cell == 1)
THEN
775 WRITE (unit=output_unit) a,
gamma, b, beta, alpha, c
779 WRITE (unit=output_unit) real(atomic_temperature(:), kind=sp)
781 atomic_temperature(:) = 0.0_dp
782 WRITE (unit=output_unit) real(atomic_temperature(:), kind=sp)
783 WRITE (unit=output_unit) real(atomic_temperature(:), kind=sp)
785 DO iatom = 1, natom_dcd
786 WRITE (unit=output_unit, fmt=
"(A5,5X,F25.3)") adjustl(atomic_label(iatom)), atomic_temperature
791 WRITE (unit=error_unit, fmt=
"(A,F12.3)") &
792 "# T [K] this frame: ", tavg_frame
795 tavg = tavg + tavg_frame
805 IF (.NOT.
ALLOCATED(r_pbc))
THEN
806 ALLOCATE (r_pbc(natom_dcd, 3), stat=istat)
807 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the array r_pbc failed")
810 IF (.NOT.
ALLOCATED(s))
THEN
811 ALLOCATE (s(natom_dcd, 3), stat=istat)
812 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the array s failed")
815 IF (.NOT.
ALLOCATED(s_pbc))
THEN
816 ALLOCATE (s_pbc(natom_dcd, 3), stat=istat)
817 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the array s_pbc failed")
820 CALL pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta,
gamma, debug, info, pbc0, h, hinv)
823 r(:, :) = real(r_pbc(:, :), kind=sp)
828 IF (print_atomic_displacements)
THEN
829 DO iatom = 1, natom_dcd
830 atomic_displacement(iatom) = sqrt((r(iatom, 1) - r0(iatom, 1))**2 + &
831 (r(iatom, 2) - r0(iatom, 2))**2 + &
832 (r(iatom, 3) - r0(iatom, 3))**2)
837 IF (output_format_dcd)
THEN
838 IF (have_unit_cell == 1)
THEN
839 WRITE (unit=output_unit) a,
gamma, b, beta, alpha, c
841 IF (print_atomic_displacements)
THEN
844 WRITE (unit=output_unit) real(atomic_displacement(:), kind=sp)
846 atomic_displacement(:) = 0.0_dp
847 WRITE (unit=output_unit) real(atomic_displacement(:), kind=sp)
848 WRITE (unit=output_unit) real(atomic_displacement(:), kind=sp)
852 WRITE (unit=output_unit) r(:, i)
856 IF (print_atomic_displacements)
THEN
858 WRITE (unit=error_unit, fmt=
"(A,2(/,A),T15,A)") &
860 "# Displacements :", &
861 "# "//trim(unit_string),
"|r|"
863 IF (have_atomic_labels)
THEN
864 DO iatom = 1, natom_dcd
865 WRITE (unit=output_unit, fmt=
"(A5,5X,F25.6)") adjustl(atomic_label(iatom)), atomic_displacement(iatom)
868 DO iatom = 1, natom_dcd
869 WRITE (unit=output_unit, fmt=
"(10X,F25.6)") atomic_displacement(iatom)
873 IF (output_format_xmol)
THEN
874 IF (have_cell_file)
THEN
875 WRITE (unit=output_unit, fmt=
"(T2,I0,/,3(1X,F14.6),3(1X,F9.3))") &
876 natom_dcd, a, b, c, alpha, beta,
gamma
878 IF (have_unit_cell == 1)
THEN
879 WRITE (unit=output_unit, fmt=
"(T2,I0,/,A,I8,A,F12.3,A,F20.10,3(A,F14.6),3(A,F8.3))") &
880 natom_dcd,
" i = ", istep_dcd + nframe - 1, &
881 ", time = ", real((nframe - 1)**istride_dcd, kind=dp)*dt, &
886 ", alpha = ", alpha, &
890 WRITE (unit=output_unit, fmt=
"(T2,I0,/,A,I8,A,F12.3,A,F20.10)") &
891 natom_dcd,
" i = ", istep_dcd + nframe - 1, &
892 ", time = ", real((nframe - 1)**istride_dcd, kind=dp)*dt, &
896 DO iatom = 1, natom_dcd
897 WRITE (unit=output_unit, fmt=fmt_string) adjustl(atomic_label(iatom)), r(iatom, 1:3)
901 WRITE (unit=error_unit, fmt=
"(A,T20,A)") &
902 "# "//trim(unit_string),
"x y z"
904 IF (print_scaled_coordinates)
THEN
905 DO iatom = 1, natom_dcd
906 WRITE (unit=output_unit, fmt=fmt_string) adjustl(atomic_label(iatom)), s(iatom, 1:3)
908 ELSE IF (print_scaled_pbc_coordinates)
THEN
909 DO iatom = 1, natom_dcd
910 WRITE (unit=output_unit, fmt=fmt_string) adjustl(atomic_label(iatom)), s_pbc(iatom, 1:3)
913 DO iatom = 1, natom_dcd
914 WRITE (unit=output_unit, fmt=fmt_string) adjustl(atomic_label(iatom)), r(iatom, 1:3)
925 IF (dump_frame) nframe_read = nframe_read + 1
928 IF (nframe >= last_frame)
THEN
930 CLOSE (unit=input_unit)
938 CLOSE (unit=input_unit)
940 IF (iarg >= narg)
EXIT dcd_file_loop
945 WRITE (unit=error_unit, fmt=
"(A,/,A,I0)") &
947 "# Frames processed: ", nframe_read
950 IF (ekin .AND. trim(adjustl(id_dcd)) ==
"VEL")
THEN
952 WRITE (unit=error_unit, fmt=
"(A,/,A,F12.3)") &
954 "# T [K] all frames: ", tavg/real(nframe_read, kind=dp)
960 WRITE (unit=error_unit, fmt=
"(A)") &
962 "# Normal termination of "//trim(version_info)
966 IF (have_atomic_labels)
CLOSE (unit=xyz_input_unit)
967 IF (len_trim(out_file_name) > 0)
CLOSE (unit=output_unit)
970 IF (
ALLOCATED(atomic_label))
DEALLOCATE (atomic_label)
971 IF (
ALLOCATED(atomic_displacement))
DEALLOCATE (atomic_displacement)
972 IF (
ALLOCATED(atomic_mass))
DEALLOCATE (atomic_mass)
973 IF (
ALLOCATED(atomic_temperature))
DEALLOCATE (atomic_temperature)
974 IF (
ALLOCATED(r))
DEALLOCATE (r)
975 IF (
ALLOCATED(r0))
DEALLOCATE (r0)
976 IF (
ALLOCATED(r_pbc))
DEALLOCATE (r_pbc)
977 IF (
ALLOCATED(s))
DEALLOCATE (s)
978 IF (
ALLOCATED(s_pbc))
DEALLOCATE (s_pbc)
990 CHARACTER(LEN=*),
INTENT(IN) :: routine, message
992 CHARACTER(LEN=2*default_string_length) :: error_message
994 error_message =
"*** ERROR in "//trim(routine)//
": "//trim(message)//
" ***"
995 WRITE (unit=default_error_unit, fmt=
"(/,A,/)") trim(error_message)
996 stop
"*** ABNORMAL PROGRAM TERMINATION of dumpdcd v3.2 ***"
1007 PURE FUNCTION angle(a, b)
RESULT(angle_ab)
1009 REAL(kind=dp),
DIMENSION(:),
INTENT(IN) :: a, b
1010 REAL(kind=dp) :: angle_ab
1012 REAL(kind=dp),
PARAMETER :: eps_geo = 1.0e-6_dp
1014 REAL(kind=dp) :: length_of_a, length_of_b
1015 REAL(kind=dp),
DIMENSION(SIZE(a, 1)) :: a_norm, b_norm
1017 length_of_a = sqrt(dot_product(a, a))
1018 length_of_b = sqrt(dot_product(b, b))
1020 IF ((length_of_a > eps_geo) .AND. (length_of_b > eps_geo))
THEN
1021 a_norm(:) = a(:)/length_of_a
1022 b_norm(:) = b(:)/length_of_b
1023 angle_ab = acos(min(max(dot_product(a_norm, b_norm), -1.0_dp), 1.0_dp))
1045 REAL(KIND=dp),
INTENT(IN) :: a, b, c, alpha, beta,
gamma
1046 REAL(KIND=dp),
DIMENSION(3, 3),
INTENT(OUT) :: h
1048 CHARACTER(LEN=*),
PARAMETER :: routineN =
'build_h_matrix'
1050 REAL(KIND=dp) :: cosa, cosb, cosg, sing
1052 cosa = cos(alpha/degree)
1053 IF (abs(cosa) < epsilon(0.0_dp)) cosa = 0.0_dp
1055 cosb = cos(beta/degree)
1056 IF (abs(cosb) < epsilon(0.0_dp)) cosb = 0.0_dp
1058 cosg = cos(
gamma/degree)
1059 IF (abs(cosg) < epsilon(0.0_dp)) cosg = 0.0_dp
1061 sing = sin(
gamma/degree)
1062 IF (abs(sing) < epsilon(0.0_dp)) sing = 0.0_dp
1073 h(2, 3) = (cosa - cosg*cosb)/sing
1074 IF ((1.0_dp - h(1, 3)**2 - h(2, 3)**2) < 0.0_dp)
THEN
1075 CALL abort_program(routinen,
"Build of the h matrix failed, check cell information")
1077 h(3, 3) = sqrt(1.0_dp - h(1, 3)**2 - h(2, 3)**2)
1093 REAL(kind=dp),
DIMENSION(3, 3),
INTENT(IN) :: a
1094 REAL(kind=dp) :: det_a
1096 det_a = a(1, 1)*(a(2, 2)*a(3, 3) - a(2, 3)*a(3, 2)) + &
1097 a(1, 2)*(a(2, 3)*a(3, 1) - a(2, 1)*a(3, 3)) + &
1098 a(1, 3)*(a(2, 1)*a(3, 2) - a(2, 2)*a(3, 1))
1110 CHARACTER(LEN=*),
INTENT(IN) :: element_symbol
1111 REAL(kind=dp) :: amass
1113 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_atomic_mass'
1115 SELECT CASE (trim(element_symbol))
1119 amass = 238.02891_dp
1121 CALL abort_program(routinen,
"Unknown element symbol found")
1124 amass = amass*massunit
1137 REAL(KIND=dp),
DIMENSION(3, 3),
INTENT(IN) :: h
1138 REAL(KIND=dp),
DIMENSION(3, 3),
INTENT(OUT) :: hinv
1139 REAL(KIND=dp),
INTENT(OUT) :: deth
1141 CHARACTER(LEN=*),
PARAMETER :: routineN =
'invert_matrix_3x3'
1147 IF (deth < 1.0e-10_dp)
THEN
1148 CALL abort_program(routinen,
"Invalid h matrix for cell found; det(h) < 1.0E-10")
1151 hinv(1, 1) = (h(2, 2)*h(3, 3) - h(3, 2)*h(2, 3))/deth
1152 hinv(2, 1) = (h(2, 3)*h(3, 1) - h(3, 3)*h(2, 1))/deth
1153 hinv(3, 1) = (h(2, 1)*h(3, 2) - h(3, 1)*h(2, 2))/deth
1155 hinv(1, 2) = (h(1, 3)*h(3, 2) - h(3, 3)*h(1, 2))/deth
1156 hinv(2, 2) = (h(1, 1)*h(3, 3) - h(3, 1)*h(1, 3))/deth
1157 hinv(3, 2) = (h(1, 2)*h(3, 1) - h(3, 2)*h(1, 1))/deth
1159 hinv(1, 3) = (h(1, 2)*h(2, 3) - h(2, 2)*h(1, 3))/deth
1160 hinv(2, 3) = (h(1, 3)*h(2, 1) - h(2, 3)*h(1, 1))/deth
1161 hinv(3, 3) = (h(1, 1)*h(2, 2) - h(2, 1)*h(1, 2))/deth
1171 CHARACTER(LEN=*),
INTENT(INOUT) :: string
1173 INTEGER :: i, iascii
1175 DO i = 1, len_trim(string)
1176 iascii = ichar(string(i:i))
1177 IF ((iascii >= 65) .AND. (iascii <= 90))
THEN
1178 string(i:i) = char(iascii + 32)
1202 SUBROUTINE pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta, gamma, debug, info, pbc0, h, hinv)
1211 REAL(KIND=sp),
DIMENSION(:, :),
INTENT(IN) :: r
1212 REAL(KIND=dp),
DIMENSION(:, :),
INTENT(OUT) :: r_pbc, s, s_pbc
1213 REAL(KIND=dp),
INTENT(IN) :: a, b, c, alpha, beta,
gamma
1214 LOGICAL,
INTENT(IN) :: debug, info, pbc0
1215 REAL(KIND=dp),
DIMENSION(3, 3),
INTENT(OUT) :: h, hinv
1217 CHARACTER(LEN=*),
PARAMETER :: routineN =
'pbc'
1220 LOGICAL :: orthorhombic
1221 REAL(KIND=dp) :: deth
1224 IF (
SIZE(r, 2) /= 3)
CALL abort_program(routinen,
"Array dimension for r must be 3")
1230 IF ((abs(alpha - 90.0_dp) < epsilon(0.0_dp)) .AND. &
1231 (abs(beta - 90.0_dp) < epsilon(0.0_dp)) .AND. &
1232 (abs(
gamma - 90.0_dp) < epsilon(0.0_dp)))
THEN
1233 orthorhombic = .true.
1238 orthorhombic = .false.
1247 WRITE (unit=error_unit, fmt=
"(A)")
"#"
1248 IF (orthorhombic)
THEN
1249 WRITE (unit=error_unit, fmt=
"(A)")
"# Cell symmetry : orthorhombic"
1251 WRITE (unit=error_unit, fmt=
"(A)")
"# Cell symmetry : non-orthorhombic"
1254 WRITE (unit=error_unit, fmt=
"(A)")
"#"
1255 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# / ", h(1, :),
" \"
1256 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# h = | ", h(2, :),
" |"
1257 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# \ ", h(3, :),
" /"
1258 WRITE (unit=error_unit, fmt=
"(A)")
"#"
1259 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# / ", hinv(1, :),
" \"
1260 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# Inv(h) = | ", hinv(2, :),
" |"
1261 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# \ ", hinv(3, :),
" /"
1262 WRITE (unit=error_unit, fmt=
"(A)")
"#"
1263 WRITE (unit=error_unit, fmt=
"(A,F0.6)")
"# det(h) = ", deth
1268 IF (orthorhombic)
THEN
1271 s(:, i) = r(:, i)*hinv(i, i)
1274 s(:, :) = matmul(r(:, :), transpose(hinv(:, :)))
1278 s_pbc(:, :) = s(:, :) - anint(s(:, :))
1280 s_pbc(:, :) = s(:, :) - floor(s(:, :))
1283 IF (orthorhombic)
THEN
1285 r_pbc(:, i) = s_pbc(:, i)*h(i, i)
1288 r_pbc(:, :) = matmul(s_pbc(:, :), transpose(h(:, :)))
1300 WRITE (unit=*, fmt=
"(T2,A)") &
1302 "Program flags for "//trim(version_info)//
":", &
1304 " -cell_file, -cell : Input file with cell information in CP2K format (.cell)", &
1305 " -debug, -d : Print debug information", &
1306 " -ekin : Dump just the ""temperature"" of each atom", &
1307 " -eformat : Print coordinates in scientific format", &
1308 " -eo : Write standard output and standard error to the same logical unit", &
1309 " -first_frame, -ff <int> : Number of the first frame which is dumped", &
1310 " -help, -h : Print this information", &
1311 " -ignore_warnings : Do not print warning messages, e.g. about inconsistencies", &
1312 " -info, -i : Print additional information for each frame (see also -debug flag)", &
1313 " -last_frame, -lf <int> : Number of the last frame which is dumped", &
1314 " -md_time_step <real> : Use this MD time step instead of the one from the DCD header", &
1315 " -output, -o <file_name> : Name of the output file (default is stdout)", &
1316 " -output_format, -of <DCD|XMOL> : Output format for dump", &
1317 " -pbc : Apply the periodic boundary conditions (PBC) to each frame before it is dumped", &
1318 " (origin at lower left)", &
1319 " -pbc0 : Apply the periodic boundary conditions (PBC) to each frame before it is dumped", &
1320 " (origin at box centre)", &
1321 " -stride <int> : Stride for frame dump (allows to skip frames, e.g. by dumping each 10th frame)", &
1322 " -trace_atoms <real> : Print atoms which left the simulation box given a threshold value in scaled units", &
1323 " -vel2cord, -v2c : Dump a VELocity DCD file as COoRDinate DCD file (hack which allows a digest by VMD)", &
1324 " -xyz_file, -xyz <file_name> : Name of a reference XYZ file in XMOL format that provides the atomic labels", &
1327 WRITE (unit=*, fmt=
"(T2,A)") &
1328 "Usage examples:", &
1330 " dumpdcd <optional flags> <DCD file(s)>", &
1332 "Specific usage examples:", &
1334 " dumpdcd project-pos-1.dcd (without atomic labels from XYZ file)", &
1335 " dumpdcd -xyz project.xyz project-pos-1.dcd (single DCD file)", &
1336 " dumpdcd -xyz project.xyz project-pos-1.dcd project-pos-2.dcd ... (multiple DCD files are dumped consecutively)", &
1337 " dumpdcd -xyz project.xyz -cell_file project-1.cell -of xmol project-pos-1.dcd (check and print cell parameters in ", &
1338 " XMOL comment line, e.g. for TRAVIS, instead of the default REFTRAJ information)", &
1339 " dumpdcd -info -xyz project.xyz project-pos-1.dcd project-pos-2.dcd (print additional information)", &
1340 " dumpdcd -debug -xyz project.xyz project-pos-1.dcd project-pos-2.dcd (print debug information)", &
1341 " dumpdcd -ekin -d -xyz project.xyz project-vel-1.dcd (print the ""temperature"" of each atom)", &
1342 " dumpdcd -ekin -xyz project.xyz project-vel-1.dcd (print just the temperature of each atom)", &
1343 " dumpdcd -first_frame 5 -last_frame 10 project-pos-1.dcd (just dump frame 5 to 10, ie. 6 frames in total)", &
1344 " dumpdcd -o outfile.xyz project-pos-1.dcd (write output to the file ""outfile.xyz"" instead of stdout)", &
1345 " dumpdcd -o test.xyz -output_format xmol -xyz ref.xyz -first 10 -last 10 test.dcd (dump 10th frame in XMOL format)", &
1346 " dumpdcd -of dcd -ff 10 -lf 20 test.dcd (dump the frames 10 to 20 in DCD format to the default output file output.dcd)", &
1347 " dumpdcd -o part.dcd -of dcd -ff 1 -lf 3 test.dcd (dump the frames 1 to 3 in DCD format to the output file part.dcd)", &
1348 " dumpdcd -o part.dcd -of dcd -first 10 -lf 100 -stride 10 test.dcd (dump the frames 10,..., 100 to the file part.dcd)", &
1349 " dumpdcd -output new.dcd -output_format dcd -pbc old.dcd (dump all frames applying PBC to the output file new.dcd)", &
1350 " dumpdcd -o new.dcd -of dcd -pbc -trace_atoms 0.02 old.dcd (all atoms more than 2% out of the box are listed)", &
1351 " dumpdcd -o new.dcd -e out_of_box.log -of dcd -pbc -trace_atoms 0.1 old.dcd (atoms >10% out of the box are listed)", &
1352 " dumpdcd -o new.dcd -of dcd -vel2cord old.dcd (dump old.dcd as new.dcd and change only the DCD id from VEL to CORD)", &
1353 " dumpdcd -o new.dcd -of dcd -frc2cord old.dcd (dump old.dcd as new.dcd and change only the DCD id from FRC to CORD)", &
1354 " dumpdcd -i -disp project-pos-1.dcd (dump the displacements of all atoms w.r.t. their positions in the first frame)", &
1355 " dumpdcd -i -of dcd -disp project-pos-1.dcd (dump the atomic displacements as x-coordinates of a DCD CORD file)", &
1356 " dumpdcd -i -of dcd -ekin -v2c -xyz project.xyz project-vel-1.dcd (dump the atomic temperatures as x-coordinates of a ", &
1357 " DCD CORD file -> hack for VMD)", &
1360 WRITE (unit=*, fmt=
"(T2,A)") &
1363 " - For -ekin a XYZ file is required to obtain the atomic labels", &
1364 " - The -info and the -debug flags provide a more detailed output which is especially handy for tracing problems", &
1365 " - The output in DCD format is in binary format", &
1366 " - The input coordinates should be in Angstrom. Velocities and forces are expected to be in atomic units", &
1378 CHARACTER(LEN=*),
INTENT(INOUT) :: string
1380 INTEGER :: i, iascii
1382 DO i = 1, len_trim(string)
1383 iascii = ichar(string(i:i))
1384 IF ((iascii >= 97) .AND. (iascii <= 122))
THEN
1385 string(i:i) = char(iascii - 32)
1402 CHARACTER(LEN=5),
DIMENSION(:),
INTENT(IN) :: atomic_label
1403 REAL(KIND=sp),
DIMENSION(:, :),
INTENT(IN) :: r
1404 REAL(KIND=dp),
DIMENSION(:, :),
INTENT(IN) :: s
1405 REAL(KIND=dp),
INTENT(IN) :: eps_out_of_box
1406 REAL(KIND=dp),
DIMENSION(3, 3),
INTENT(IN) :: h
1408 INTEGER :: i, iatom, natom, ncount
1409 REAL(KIND=dp) :: rl, s_max, s_min, sl
1410 REAL(KIND=dp),
DIMENSION(3) :: dr, ds
1413 IF (eps_out_of_box <= 0.0_dp)
RETURN
1415 s_max = 1.0_dp + eps_out_of_box
1416 s_min = -eps_out_of_box
1420 IF (any(s(iatom, :) < s_min) .OR. &
1421 any(s(iatom, :) > s_max))
THEN
1423 IF (ncount == 1)
THEN
1424 WRITE (unit=error_unit, fmt=
"(A)") &
1426 "# Atoms out of box:", &
1427 "# Atom index label x y z |dr| |ds|"
1431 IF (s(iatom, i) < 0.0_dp) ds(i) = 0.0_dp
1432 IF (s(iatom, i) >= 1.0_dp) ds(i) = 1.0_dp
1434 ds(:) = s(iatom, :) - ds(:)
1435 sl = sqrt(ds(1)**2 + ds(2)**2 + ds(3)**2)
1436 dr(:) = matmul(h(:, :), ds(:))
1437 rl = sqrt(dr(1)**2 + dr(2)**2 + dr(3)**2)
1438 WRITE (unit=error_unit, fmt=
"(A,I10,1X,A5,5(1X,F14.6))") &
1439 "# ", iatom, adjustr(atomic_label(iatom)), r(iatom, :), rl, sl
1442 WRITE (unit=error_unit, fmt=
"(A,I0,A)")
"# ", ncount,
" atom(s) out of box"
subroutine abort_program(routine, message)
...
subroutine write_out_of_box_atoms(atomic_label, r, s, eps_out_of_box, h)
...
subroutine invert_matrix_3x3(h, hinv, deth)
...
subroutine build_h_matrix(a, b, c, alpha, beta, gamma, h)
...
real(kind=dp) function det_3x3(a)
...
subroutine print_help()
...
real(kind=dp) function get_atomic_mass(element_symbol)
...
subroutine pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta, gamma, debug, info, pbc0, h, hinv)
...
subroutine lowercase(string)
...
pure real(kind=dp) function angle(a, b)
Calculation of the angle between the vectors a and b. The angle is returned in radians.
subroutine uppercase(string)
...
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Calculation of the incomplete Gamma function F_n(t) for multi-center integrals over Cartesian Gaussia...