41 INTEGER,
PARAMETER :: default_error_unit = 0, &
42 default_input_unit = 5, &
43 default_output_unit = 6
44 INTEGER :: error_unit = default_error_unit, &
45 input_unit = default_input_unit, &
46 output_unit = default_output_unit
50 CHARACTER(LEN=*),
PARAMETER :: routinen =
"dumpdcd", &
51 version_info = routinen//
" v3.2 (16.06.2022)"
53 INTEGER,
PARAMETER :: dp = selected_real_kind(14, 200), &
54 sp = selected_real_kind(6, 30)
55 INTEGER,
PARAMETER :: default_string_length = 240, &
56 cell_input_unit = 10, &
59 REAL(kind=dp),
PARAMETER :: pi = 3.14159265358979323846264338_dp
60 REAL(kind=dp),
PARAMETER :: angstrom = 0.52917720859_dp, &
61 degree = 180.0_dp/pi, &
62 kelvin = 315774.647902944_dp, &
63 massunit = 1822.88484264550_dp
66 CHARACTER(LEN=4) :: id_dcd
67 CHARACTER(LEN=10) :: unit_string
68 CHARACTER(LEN=17) :: fmt_string
69 CHARACTER(LEN=default_string_length) :: arg, cell_file_name, dcd_file_name, message, out_file_name, &
70 output_format, remark_xyz, string, xyz_file_name
71 CHARACTER(LEN=5),
DIMENSION(:),
ALLOCATABLE :: atomic_label
72 CHARACTER(LEN=80),
DIMENSION(2) :: remark_dcd
73 INTEGER :: first_frame, have_unit_cell, i, iarg, iatom, &
74 iframe, istat, istep_dcd, istride_dcd, last_frame, narg, &
75 natom_dcd, natom_xyz, ndcd_file, nframe, &
76 nframe_read, nremark, stride
77 LOGICAL :: apply_pbc, debug, dump_frame, eformat, ekin, eo, &
78 have_atomic_labels, have_cell_file, ignore_warnings, info, &
79 opened, output_format_dcd, output_format_xmol, pbc0, &
80 print_atomic_displacements, print_scaled_coordinates, &
81 print_scaled_pbc_coordinates, trace_atoms, vel2cord
82 REAL(kind=sp) :: dt_dcd
83 REAL(kind=dp) :: a, a_dcd, alpha, alpha_dcd, b, b_dcd, beta, beta_dcd, c, c_dcd, &
84 cell_volume, dt, energy, eps_angle, eps_geo, eps_out_of_box, &
85 first_step_time,
gamma, gamma_dcd, md_time_step, ndt, step_time, &
87 INTEGER,
DIMENSION(16) :: idum
88 REAL(kind=dp),
DIMENSION(3) :: rdum
89 REAL(kind=dp),
DIMENSION(:),
ALLOCATABLE :: atomic_displacement, atomic_mass, atomic_temperature
90 REAL(kind=dp),
DIMENSION(3, 3) :: h, hinv, hmat
91 REAL(kind=sp),
DIMENSION(:, :),
ALLOCATABLE :: r
92 REAL(kind=dp),
DIMENSION(:, :),
ALLOCATABLE :: r_pbc, r0, s, s_pbc
101 ignore_warnings = .false.
103 trace_atoms = .false.
105 print_atomic_displacements = .false.
106 print_scaled_coordinates = .false.
107 print_scaled_pbc_coordinates = .false.
116 have_atomic_labels = .false.
117 have_cell_file = .false.
125 output_format =
"default"
126 output_format_dcd = .false.
127 output_format_xmol = .false.
139 eps_out_of_box = -huge(0.0_dp)
140 first_step_time = 0.0_dp
141 md_time_step = 0.0_dp
147 narg = command_argument_count()
151 CALL abort_program(routinen,
"No input file(s) specified")
160 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
163 CASE (
"-cell_file",
"-cell")
165 CALL get_command_argument(number=iarg,
VALUE=cell_file_name, status=istat)
166 have_cell_file = .true.
168 CASE (
"-debug",
"-d")
172 CASE (
"-displacements",
"-disp")
173 print_atomic_displacements = .true.
184 CASE (
"-first_frame",
"-first",
"-ff")
186 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
187 READ (unit=arg, fmt=*, err=100) first_frame
188 IF (first_frame <= 0)
THEN
189 CALL abort_program(routinen,
"Invalid number for first frame specified: "// &
190 "first_frame must be greater than zero")
193100
CALL abort_program(routinen,
"Invalid number for first frame specified "// &
194 "(an integer number greater than zero is expected)")
198 CASE (
"-ignore_warnings")
199 ignore_warnings = .true.
204 CASE (
"-last_frame",
"-last",
"-lf")
206 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
207 READ (unit=arg, fmt=*, err=101) last_frame
208 IF (last_frame <= 0)
THEN
209 CALL abort_program(routinen,
"Invalid number for last frame specified: "// &
210 "last_frame must be greater than zero")
213101
CALL abort_program(routinen,
"Invalid number for last frame specified "// &
214 "(an integer number greater than zero is expected)")
215 CASE (
"-md_time_step")
217 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
218 READ (unit=arg, fmt=*, err=102) md_time_step
219 IF (md_time_step <= 0.0_dp)
THEN
220 CALL abort_program(routinen,
"Invalid (negative) MD time step specified")
223102
CALL abort_program(routinen,
"Invalid MD time step specified")
224 CASE (
"-o",
"-output")
226 CALL get_command_argument(number=iarg,
VALUE=out_file_name, status=istat)
228 CASE (
"-output_format",
"-of")
230 CALL get_command_argument(number=iarg,
VALUE=output_format, status=istat)
231 CALL uppercase(output_format)
232 SELECT CASE (output_format)
234 output_format_dcd = .true.
235 output_format_xmol = .false.
237 output_format_dcd = .false.
238 output_format_xmol = .true.
240 CALL abort_program(routinen,
"Invalid output format type specified")
251 CASE (
"-scaled_coordinates",
"-sc")
252 print_scaled_coordinates = .true.
254 CASE (
"-scaled_pbc_coordinates",
"-spc")
255 print_scaled_pbc_coordinates = .true.
259 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
260 READ (unit=arg, fmt=*, err=104) stride
262 CALL abort_program(routinen,
"Invalid stride for frame dump specified: stride must be greater than zero")
265104
CALL abort_program(routinen,
"Invalid stride for frame dump specified "// &
266 "(an integer number greater than 0 is expected)")
267 CASE (
"-trace_atoms")
269 CALL get_command_argument(number=iarg,
VALUE=arg, status=istat)
270 READ (unit=arg, fmt=*, err=108) eps_out_of_box
271 IF (eps_out_of_box <= 0.0_dp)
THEN
272 CALL abort_program(routinen,
"Invalid threshold value for -trace_atoms flag specified")
276108
CALL abort_program(routinen,
"Invalid threshold value for -trace_atoms flag specified")
277 CASE (
"-vel2cord",
"-v2c",
"-frc2cord",
"-f2c")
280 CASE (
"-xyz",
"xyz_file")
282 CALL get_command_argument(number=iarg,
VALUE=xyz_file_name, status=istat)
283 have_atomic_labels = .true.
286 IF (arg(1:1) ==
"-")
THEN
288 CALL abort_program(routinen,
"Unknown command line flag """//trim(arg)//
""" found")
294 IF (first_frame > last_frame)
THEN
295 CALL abort_program(routinen,
"Number of first frame greater than number of last frame")
297 IF ((.NOT. have_atomic_labels) .AND. output_format_xmol)
THEN
298 CALL abort_program(routinen,
"The output format XMOL requires a valid xyz file (-xyz flag)")
300 IF (output_format_xmol .AND. ekin)
THEN
301 CALL abort_program(routinen,
"Output format XMOL and the -ekin flag are incompatible")
303 IF (output_format_xmol .AND. print_atomic_displacements)
THEN
304 CALL abort_program(routinen,
"Output format XMOL and the -displacements flag are incompatible")
306 IF (output_format_xmol .AND. eo)
THEN
307 CALL abort_program(routinen,
"The -eo flag is incompatible with the output format XMOL")
309 IF (.NOT. have_atomic_labels .AND. ekin)
THEN
310 CALL abort_program(routinen,
"ekin flag requires also the specification of a valid xyz file (-xyz flag)")
312 IF (.NOT. apply_pbc .AND. trace_atoms)
THEN
313 CALL abort_program(routinen,
"The -trace_atoms flag requires the specification of a -pbc flag")
315 IF (ekin .AND. print_atomic_displacements)
THEN
316 CALL abort_program(routinen,
"The -ekin flag and the -displacements flag are incompatible")
318 IF (print_scaled_coordinates .AND. print_scaled_pbc_coordinates)
THEN
319 CALL abort_program(routinen,
"The -sc flag and the -spc flag are incompatible")
321 IF (.NOT. apply_pbc .AND. print_scaled_coordinates)
THEN
322 CALL abort_program(routinen,
"The -sc flag requires the specification of a -pbc flag")
324 IF (.NOT. apply_pbc .AND. print_scaled_pbc_coordinates)
THEN
325 CALL abort_program(routinen,
"The -spc flag requires the specification of a -pbc flag")
330 fmt_string =
"(A5,3(1X,ES14.6))"
332 fmt_string =
"(A5,3(1X, F14.6))"
336 IF (output_format_dcd)
THEN
338 IF (len_trim(out_file_name) == 0) out_file_name =
"output.dcd"
340 INQUIRE (unit=output_unit, name=string)
341 IF (trim(string) /= trim(out_file_name))
CLOSE (unit=output_unit)
342 INQUIRE (unit=output_unit, opened=opened)
343 IF (.NOT. opened)
THEN
344 OPEN (unit=output_unit, &
345 file=out_file_name, &
347 access=
"SEQUENTIAL", &
348 form=
"UNFORMATTED", &
351 IF (istat /= 0)
CALL abort_program(routinen,
"The unformatted output file could not be opened")
354 IF (eo) error_unit = output_unit
355 IF (len_trim(out_file_name) > 0)
THEN
357 INQUIRE (unit=output_unit, name=string)
358 IF (trim(string) /= trim(out_file_name))
CLOSE (unit=output_unit)
359 INQUIRE (unit=output_unit, opened=opened)
360 IF (.NOT. opened)
THEN
361 OPEN (unit=output_unit, &
362 file=out_file_name, &
364 access=
"SEQUENTIAL", &
369 IF (istat /= 0)
CALL abort_program(routinen,
"The formatted output file could not be opened")
375 IF (trim(dcd_file_name) == trim(out_file_name))
THEN
376 CALL abort_program(routinen,
"Input and output file name cannot be the same")
380 IF (have_atomic_labels)
THEN
383 INQUIRE (unit=xyz_input_unit, name=string)
384 IF (trim(string) /= trim(xyz_file_name))
CLOSE (unit=xyz_input_unit)
385 INQUIRE (unit=xyz_input_unit, opened=opened)
387 IF (.NOT. opened)
THEN
388 OPEN (unit=xyz_input_unit, &
389 file=xyz_file_name, &
391 access=
"SEQUENTIAL", &
396 IF (istat /= 0)
CALL abort_program(routinen,
"The XYZ file could not be opened")
397 IF (info)
WRITE (unit=error_unit, fmt=
"(A)")
"#",
"# Reading XYZ file: "//trim(xyz_file_name)
398 READ (unit=xyz_input_unit, fmt=
"(A)", iostat=istat) arg
400 CALL abort_program(routinen,
"Reading line 1 of the XYZ file (number of atoms) failed")
402 IF (arg(1:1) ==
"#")
THEN
403 READ (unit=arg, fmt=*) string, natom_xyz
405 READ (unit=arg, fmt=*) natom_xyz
408 CALL abort_program(routinen,
"Reading line 1 of the XYZ file (number of atoms) failed")
410 IF (
ALLOCATED(atomic_label))
DEALLOCATE (atomic_label)
411 ALLOCATE (atomic_label(natom_xyz), stat=istat)
412 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the vector atomic_label failed")
415 IF (
ALLOCATED(atomic_mass))
DEALLOCATE (atomic_mass)
416 ALLOCATE (atomic_mass(natom_xyz), stat=istat)
417 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the vector atomic_mass failed")
419 READ (unit=xyz_input_unit, fmt=
"(A)", iostat=istat) remark_xyz
420 IF (istat /= 0)
CALL abort_program(routinen,
"Reading line 2 of the XYZ file (remark line) failed")
423 READ (unit=xyz_input_unit, fmt=*) arg
424 IF (arg(1:1) ==
"#")
THEN
427 backspace(unit=xyz_input_unit)
430 READ (unit=xyz_input_unit, fmt=*, iostat=istat) atomic_label(iatom), rdum(1:3)
433 WRITE (unit=message, fmt=
"(A,I0,A,I0,A)") &
434 "Reading line ", iatom + 2,
" of the XYZ file (atom ", iatom,
") failed"
435 CALL abort_program(routinen, trim(message))
437 CALL uppercase(atomic_label(iatom))
438 IF (len_trim(atomic_label(iatom)) > 1)
CALL lowercase(atomic_label(iatom) (2:2))
439 atomic_label(iatom) = trim(adjustl(atomic_label(iatom)))
440 IF (ekin) atomic_mass(iatom) = get_atomic_mass(atomic_label(iatom))
441 IF (iatom == natom_xyz)
EXIT
444 WRITE (unit=error_unit, fmt=
"(A,I0)") &
445 "# Number of atoms : ", natom_xyz, &
446 "# Remark : "//trim(adjustl(remark_xyz))
452 IF (have_cell_file)
THEN
455 INQUIRE (unit=cell_input_unit, name=string)
456 IF (trim(string) /= trim(cell_file_name))
CLOSE (unit=cell_input_unit)
457 INQUIRE (unit=cell_input_unit, opened=opened)
459 IF (.NOT. opened)
THEN
460 OPEN (unit=cell_input_unit, &
461 file=cell_file_name, &
463 access=
"SEQUENTIAL", &
468 IF (istat /= 0)
CALL abort_program(routinen,
"The cell file could not be opened")
469 IF (info)
WRITE (unit=error_unit, fmt=
"(A)")
"#",
"# Reading cell file: "//trim(cell_file_name)
474 ndcd_file = ndcd_file + 1
477 OPEN (unit=input_unit, &
478 file=dcd_file_name, &
480 form=
"UNFORMATTED", &
484 IF (istat /= 0)
CALL abort_program(routinen,
"The DCD file could not be opened")
486 WRITE (unit=error_unit, fmt=
"(A,/,(A,I0))") &
488 "# DCD file number : ", ndcd_file, &
489 "# Reading DCD file: "//trim(dcd_file_name)
493 READ (unit=input_unit) id_dcd, idum(1), istep_dcd, istride_dcd, idum(2:7), dt_dcd, have_unit_cell, idum(8:16)
495 WRITE (unit=error_unit, fmt=
"(A,2(/,A,I0),/,A,F9.3,/,A,I0)") &
496 "# DCD id string : "//id_dcd, &
497 "# Step : ", istep_dcd, &
498 "# Print frequency : ", istride_dcd, &
499 "# Time step [fs] : ", dt_dcd, &
500 "# Unit cell : ", have_unit_cell
503 IF (ekin .AND. trim(adjustl(id_dcd)) /=
"VEL")
THEN
504 CALL abort_program(routinen,
"ekin flag requires a DCD file with VELocities")
506 IF (apply_pbc .AND. (have_unit_cell /= 1))
THEN
507 CALL abort_program(routinen,
"pbc flags require that unit cell information is available")
510 IF ((trim(adjustl(id_dcd)) ==
"FRC") .OR. (trim(adjustl(id_dcd)) ==
"VEL"))
THEN
511 unit_string =
"[a.u.]"
512 IF (apply_pbc)
CALL abort_program(routinen,
"pbc flags require a DCD file with COoRDinates")
513 ELSE IF (trim(adjustl(id_dcd)) ==
"CORD")
THEN
514 unit_string =
"[Angstrom]"
516 CALL abort_program(routinen,
"Unknown DCD id found (use -debug or -info flag for details)")
520 READ (unit=input_unit) nremark, remark_dcd(1), remark_dcd(2)
523 WRITE (unit=error_unit, fmt=
"(A,I1,A)") &
524 "# Remark ", i,
" : "//trim(remark_dcd(i))
529 READ (unit=input_unit) natom_dcd
531 WRITE (unit=error_unit, fmt=
"(A,I0)") &
532 "# Number of atoms : ", natom_dcd
535 IF (have_atomic_labels)
THEN
536 IF (natom_dcd /= natom_xyz)
CALL abort_program(routinen,
"Number of atoms in XYZ and DCD file differ")
538 IF (.NOT.
ALLOCATED(atomic_label))
THEN
539 ALLOCATE (atomic_label(natom_dcd), stat=istat)
540 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the vector atomic_label failed")
546 IF (md_time_step > 0.0_dp)
THEN
547 dt_dcd = real(md_time_step, kind=sp)
550 dt = real(dt_dcd, kind=dp)
554 IF (output_format_dcd)
THEN
555 IF (vel2cord) id_dcd =
"CORD"
557 WRITE (unit=output_unit) id_dcd, idum(1), istep_dcd, istride_dcd, idum(2:7), dt_dcd, have_unit_cell, idum(8:16)
558 WRITE (unit=output_unit) nremark, remark_dcd(1), remark_dcd(2)
559 WRITE (unit=output_unit) natom_dcd
566 IF (nframe < first_frame)
THEN
569 IF (
modulo(nframe - first_frame, stride) == 0)
THEN
577 IF (have_unit_cell == 1)
THEN
578 READ (unit=input_unit, iostat=istat) a,
gamma, b, beta, alpha, c
579 IF (istat < 0)
EXIT frame_loop
581 IF (have_cell_file)
THEN
584 READ (unit=cell_input_unit, fmt=*, iostat=istat) string
587 WRITE (unit=message, fmt=
"(A)") &
588 "Reading frame (step) from cell file "//trim(cell_file_name)//
" failed"
589 CALL abort_program(routinen, trim(message))
591 IF (string(1:1) ==
"#")
THEN
594 backspace(unit=cell_input_unit)
598 READ (unit=cell_input_unit, fmt=*, iostat=istat) iframe, step_time, hmat(1:3, 1:3), cell_volume
600 WRITE (unit=error_unit, fmt=
"(/,T2,A,I0)") &
601 "IOSTAT = ", istat, &
602 "Line read: """//trim(string)//
""""
604 WRITE (unit=message, fmt=
"(A)") &
605 "Invalid cell information read from cell file "//trim(cell_file_name)
606 CALL abort_program(routinen, trim(message))
609 IF (nframe == first_frame) first_step_time = step_time
611 IF ((nframe >= first_frame) .AND. (nframe <= last_frame))
THEN
613 IF (have_unit_cell == 1)
THEN
622 a = norm2(hmat(1:3, 1))
623 b = norm2(hmat(1:3, 2))
624 c = norm2(hmat(1:3, 3))
626 IF (unit_string ==
"[a.u.]")
THEN
631 alpha = angle(hmat(1:3, 2), hmat(1:3, 3))*degree
632 beta = angle(hmat(1:3, 3), hmat(1:3, 1))*degree
633 gamma = angle(hmat(1:3, 1), hmat(1:3, 2))*degree
634 IF (have_unit_cell == 1)
THEN
636 IF (.NOT. ignore_warnings)
THEN
637 IF (md_time_step > 0.0_dp)
THEN
638 string =
"Time step (requested) ="
640 string =
"Time step (DCD header) ="
642 ndt = (step_time - first_step_time)/dt
643 IF (abs(ndt - anint(ndt)) > 0.01_dp)
THEN
644 WRITE (unit=error_unit, fmt=
"(/,T2,A,I8,/,(T2,A,F15.6,A))") &
645 "Step number (CELL file) = ", iframe, &
646 "Step time (CELL file) = ", step_time,
" fs", &
647 "First step (CELL file) = ", first_step_time,
" fs", &
648 "Time since first step = ", step_time - first_step_time,
" fs", &
649 "Steps since first step = ", ndt,
"", &
650 trim(string)//
" ", dt,
" fs"
651 WRITE (unit=error_unit, fmt=
"(/,T2,A)") &
652 "*** WARNING: MD step time in cell file is not a multiple of the MD time step in the DCD file header ***"
656 IF (abs(a - a_dcd) > eps_geo)
THEN
657 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
658 "a (CELL file) = ", a, &
659 "a (DCD header) = ", a_dcd
660 CALL abort_program(routinen,
"Cell file and DCD file information for lattice constant ""a"" differ")
662 IF (abs(b - b_dcd) > eps_geo)
THEN
663 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
664 "b (CELL file) = ", b, &
665 "b (DCD header) = ", b_dcd
666 CALL abort_program(routinen,
"Cell file and DCD file information for lattice constant ""b"" differ")
668 IF (abs(c - c_dcd) > eps_geo)
THEN
669 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
670 "c (CELL file) = ", c, &
671 "c (DCD header) = ", c_dcd
672 CALL abort_program(routinen,
"Cell file and DCD file information for lattice constant ""c"" differ")
674 eps_angle = 1.0e-4_dp
675 IF (abs(alpha - alpha_dcd) > eps_angle)
THEN
676 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
677 "alpha (CELL file) = ", alpha, &
678 "alpha (DCD header) = ", alpha_dcd
679 CALL abort_program(routinen,
"Cell file and DCD file information for cell angle ""alpha"" differ")
681 IF (abs(beta - beta_dcd) > eps_angle)
THEN
682 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
683 "beta (CELL file) = ", beta, &
684 "beta (DCD header) = ", beta_dcd
685 CALL abort_program(routinen,
"Cell file and DCD file information for cell angle ""beta"" differ")
687 IF (abs(
gamma - gamma_dcd) > eps_angle)
THEN
688 WRITE (unit=error_unit, fmt=
"(/,(T2,A,F14.6))") &
689 "gamma (CELL file) = ",
gamma, &
690 "gamma (DCD header) = ", gamma_dcd
691 CALL abort_program(routinen,
"Cell file and DCD file information for cell angle ""beta"" differ")
697 IF ((info .OR. trace_atoms) .AND. dump_frame)
THEN
698 WRITE (unit=error_unit, fmt=
"(A,/,A,I0)") &
699 "#",
"# Frame number : ", nframe
703 IF (info .AND. dump_frame)
THEN
704 IF (have_unit_cell == 1)
THEN
705 WRITE (unit=error_unit, fmt=
"(A,/,(A,T19,A,F12.6))") &
707 "# a "//trim(unit_string),
": ", a, &
708 "# b "//trim(unit_string),
": ", b, &
709 "# c "//trim(unit_string),
": ", c
710 WRITE (unit=error_unit, fmt=
"(A,F12.6)") &
711 "# alpha [degree] : ", alpha, &
712 "# beta [degree] : ", beta, &
713 "# gamma [degree] : ",
gamma
718 IF (.NOT.
ALLOCATED(r))
THEN
719 ALLOCATE (r(natom_dcd, 3), stat=istat)
720 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the array r failed")
724 READ (unit=input_unit, iostat=istat) r(1:natom_dcd, 1)
725 IF (istat < 0)
EXIT frame_loop
726 READ (unit=input_unit) r(1:natom_dcd, 2)
727 READ (unit=input_unit) r(1:natom_dcd, 3)
731 IF ((nframe == 1) .AND. print_atomic_displacements)
THEN
732 IF (.NOT.
ALLOCATED(r0))
THEN
733 ALLOCATE (r0(natom_dcd, 3), stat=istat)
734 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the array r0 failed")
737 IF (.NOT.
ALLOCATED(atomic_displacement))
THEN
738 ALLOCATE (atomic_displacement(natom_dcd), stat=istat)
740 CALL abort_program(routinen,
"Allocation of the vector atomic_displacement failed")
743 atomic_displacement(:) = 0.0_dp
746 IF (ekin .AND. trim(adjustl(id_dcd)) ==
"VEL")
THEN
751 IF (.NOT.
ALLOCATED(atomic_temperature))
THEN
752 ALLOCATE (atomic_temperature(natom_dcd), stat=istat)
754 CALL abort_program(routinen,
"Allocation of the vector atomic_temperature failed")
756 atomic_temperature(:) = 0.0_dp
760 WRITE (unit=error_unit, fmt=
"(A)") &
766 DO iatom = 1, natom_dcd
767 atomic_temperature(iatom) = atomic_mass(iatom)*(r(iatom, 1)*r(iatom, 1) + &
768 r(iatom, 2)*r(iatom, 2) + &
769 r(iatom, 3)*r(iatom, 3))*kelvin/3.0_dp
770 tavg_frame = tavg_frame + atomic_temperature(iatom)
772 tavg_frame = tavg_frame/real(natom_dcd, kind=dp)
774 IF (output_format_dcd)
THEN
775 IF (have_unit_cell == 1)
THEN
776 WRITE (unit=output_unit) a,
gamma, b, beta, alpha, c
780 WRITE (unit=output_unit) real(atomic_temperature(:), kind=sp)
782 atomic_temperature(:) = 0.0_dp
783 WRITE (unit=output_unit) real(atomic_temperature(:), kind=sp)
784 WRITE (unit=output_unit) real(atomic_temperature(:), kind=sp)
786 DO iatom = 1, natom_dcd
787 WRITE (unit=output_unit, fmt=
"(A5,5X,F25.3)") adjustl(atomic_label(iatom)), atomic_temperature
792 WRITE (unit=error_unit, fmt=
"(A,F12.3)") &
793 "# T [K] this frame: ", tavg_frame
796 tavg = tavg + tavg_frame
806 IF (.NOT.
ALLOCATED(r_pbc))
THEN
807 ALLOCATE (r_pbc(natom_dcd, 3), stat=istat)
808 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the array r_pbc failed")
811 IF (.NOT.
ALLOCATED(s))
THEN
812 ALLOCATE (s(natom_dcd, 3), stat=istat)
813 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the array s failed")
816 IF (.NOT.
ALLOCATED(s_pbc))
THEN
817 ALLOCATE (s_pbc(natom_dcd, 3), stat=istat)
818 IF (istat /= 0)
CALL abort_program(routinen,
"Allocation of the array s_pbc failed")
821 CALL pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta,
gamma, debug, info, pbc0, h, hinv)
822 CALL write_out_of_box_atoms(atomic_label, r, s, eps_out_of_box, h)
824 r(:, :) = real(r_pbc(:, :), kind=sp)
829 IF (print_atomic_displacements)
THEN
830 DO iatom = 1, natom_dcd
831 atomic_displacement(iatom) = sqrt((r(iatom, 1) - r0(iatom, 1))**2 + &
832 (r(iatom, 2) - r0(iatom, 2))**2 + &
833 (r(iatom, 3) - r0(iatom, 3))**2)
838 IF (output_format_dcd)
THEN
839 IF (have_unit_cell == 1)
THEN
840 WRITE (unit=output_unit) a,
gamma, b, beta, alpha, c
842 IF (print_atomic_displacements)
THEN
845 WRITE (unit=output_unit) real(atomic_displacement(:), kind=sp)
847 atomic_displacement(:) = 0.0_dp
848 WRITE (unit=output_unit) real(atomic_displacement(:), kind=sp)
849 WRITE (unit=output_unit) real(atomic_displacement(:), kind=sp)
853 WRITE (unit=output_unit) r(:, i)
857 IF (print_atomic_displacements)
THEN
859 WRITE (unit=error_unit, fmt=
"(A,2(/,A),T15,A)") &
861 "# Displacements :", &
862 "# "//trim(unit_string),
"|r|"
864 IF (have_atomic_labels)
THEN
865 DO iatom = 1, natom_dcd
866 WRITE (unit=output_unit, fmt=
"(A5,5X,F25.6)") adjustl(atomic_label(iatom)), atomic_displacement(iatom)
869 DO iatom = 1, natom_dcd
870 WRITE (unit=output_unit, fmt=
"(10X,F25.6)") atomic_displacement(iatom)
874 IF (output_format_xmol)
THEN
875 IF (have_cell_file)
THEN
876 WRITE (unit=output_unit, fmt=
"(T2,I0,/,3(1X,F14.6),3(1X,F9.3))") &
877 natom_dcd, a, b, c, alpha, beta,
gamma
879 IF (have_unit_cell == 1)
THEN
880 WRITE (unit=output_unit, fmt=
"(T2,I0,/,A,I8,A,F12.3,A,F20.10,3(A,F14.6),3(A,F8.3))") &
881 natom_dcd,
" i = ", istep_dcd + nframe - 1, &
882 ", time = ", real((nframe - 1)**istride_dcd, kind=dp)*dt, &
887 ", alpha = ", alpha, &
891 WRITE (unit=output_unit, fmt=
"(T2,I0,/,A,I8,A,F12.3,A,F20.10)") &
892 natom_dcd,
" i = ", istep_dcd + nframe - 1, &
893 ", time = ", real((nframe - 1)**istride_dcd, kind=dp)*dt, &
897 DO iatom = 1, natom_dcd
898 WRITE (unit=output_unit, fmt=fmt_string) adjustl(atomic_label(iatom)), r(iatom, 1:3)
902 WRITE (unit=error_unit, fmt=
"(A,T20,A)") &
903 "# "//trim(unit_string),
"x y z"
905 IF (print_scaled_coordinates)
THEN
906 DO iatom = 1, natom_dcd
907 WRITE (unit=output_unit, fmt=fmt_string) adjustl(atomic_label(iatom)), s(iatom, 1:3)
909 ELSE IF (print_scaled_pbc_coordinates)
THEN
910 DO iatom = 1, natom_dcd
911 WRITE (unit=output_unit, fmt=fmt_string) adjustl(atomic_label(iatom)), s_pbc(iatom, 1:3)
914 DO iatom = 1, natom_dcd
915 WRITE (unit=output_unit, fmt=fmt_string) adjustl(atomic_label(iatom)), r(iatom, 1:3)
926 IF (dump_frame) nframe_read = nframe_read + 1
929 IF (nframe >= last_frame)
THEN
931 CLOSE (unit=input_unit)
939 CLOSE (unit=input_unit)
941 IF (iarg >= narg)
EXIT dcd_file_loop
946 WRITE (unit=error_unit, fmt=
"(A,/,A,I0)") &
948 "# Frames processed: ", nframe_read
951 IF (ekin .AND. trim(adjustl(id_dcd)) ==
"VEL")
THEN
953 WRITE (unit=error_unit, fmt=
"(A,/,A,F12.3)") &
955 "# T [K] all frames: ", tavg/real(nframe_read, kind=dp)
961 WRITE (unit=error_unit, fmt=
"(A)") &
963 "# Normal termination of "//trim(version_info)
967 IF (have_atomic_labels)
CLOSE (unit=xyz_input_unit)
968 IF (len_trim(out_file_name) > 0)
CLOSE (unit=output_unit)
971 IF (
ALLOCATED(atomic_label))
DEALLOCATE (atomic_label)
972 IF (
ALLOCATED(atomic_displacement))
DEALLOCATE (atomic_displacement)
973 IF (
ALLOCATED(atomic_mass))
DEALLOCATE (atomic_mass)
974 IF (
ALLOCATED(atomic_temperature))
DEALLOCATE (atomic_temperature)
975 IF (
ALLOCATED(r))
DEALLOCATE (r)
976 IF (
ALLOCATED(r0))
DEALLOCATE (r0)
977 IF (
ALLOCATED(r_pbc))
DEALLOCATE (r_pbc)
978 IF (
ALLOCATED(s))
DEALLOCATE (s)
979 IF (
ALLOCATED(s_pbc))
DEALLOCATE (s_pbc)
988 SUBROUTINE abort_program(routine, message)
991 CHARACTER(LEN=*),
INTENT(IN) :: routine, message
993 CHARACTER(LEN=2*default_string_length) :: error_message
995 error_message =
"*** ERROR in "//trim(routine)//
": "//trim(message)//
" ***"
996 WRITE (unit=default_error_unit, fmt=
"(/,A,/)") trim(error_message)
997 stop
"*** ABNORMAL PROGRAM TERMINATION of dumpdcd v3.2 ***"
999 END SUBROUTINE abort_program
1008 PURE FUNCTION angle(a, b)
RESULT(angle_ab)
1010 REAL(kind=dp),
DIMENSION(:),
INTENT(IN) :: a, b
1011 REAL(kind=dp) :: angle_ab
1013 REAL(kind=dp),
PARAMETER :: eps_geo = 1.0e-6_dp
1015 REAL(kind=dp) :: length_of_a, length_of_b
1016 REAL(kind=dp),
DIMENSION(SIZE(a, 1)) :: a_norm, b_norm
1018 length_of_a = norm2(a)
1019 length_of_b = norm2(b)
1021 IF ((length_of_a > eps_geo) .AND. (length_of_b > eps_geo))
THEN
1022 a_norm(:) = a(:)/length_of_a
1023 b_norm(:) = b(:)/length_of_b
1024 angle_ab = acos(min(max(dot_product(a_norm, b_norm), -1.0_dp), 1.0_dp))
1041 SUBROUTINE build_h_matrix(a, b, c, alpha, beta, gamma, h)
1046 REAL(kind=dp),
INTENT(IN) :: a, b, c, alpha, beta,
gamma
1047 REAL(kind=dp),
DIMENSION(3, 3),
INTENT(OUT) :: h
1049 CHARACTER(LEN=*),
PARAMETER :: routinen =
'build_h_matrix'
1051 REAL(kind=dp) :: cosa, cosb, cosg, sing
1053 cosa = cos(alpha/degree)
1054 IF (abs(cosa) < epsilon(0.0_dp)) cosa = 0.0_dp
1056 cosb = cos(beta/degree)
1057 IF (abs(cosb) < epsilon(0.0_dp)) cosb = 0.0_dp
1059 cosg = cos(
gamma/degree)
1060 IF (abs(cosg) < epsilon(0.0_dp)) cosg = 0.0_dp
1062 sing = sin(
gamma/degree)
1063 IF (abs(sing) < epsilon(0.0_dp)) sing = 0.0_dp
1074 h(2, 3) = (cosa - cosg*cosb)/sing
1075 IF ((1.0_dp - h(1, 3)**2 - h(2, 3)**2) < 0.0_dp)
THEN
1076 CALL abort_program(routinen,
"Build of the h matrix failed, check cell information")
1078 h(3, 3) = sqrt(1.0_dp - h(1, 3)**2 - h(2, 3)**2)
1084 END SUBROUTINE build_h_matrix
1091 FUNCTION det_3x3(a)
RESULT(det_a)
1094 REAL(kind=dp),
DIMENSION(3, 3),
INTENT(IN) :: a
1095 REAL(kind=dp) :: det_a
1097 det_a = a(1, 1)*(a(2, 2)*a(3, 3) - a(2, 3)*a(3, 2)) + &
1098 a(1, 2)*(a(2, 3)*a(3, 1) - a(2, 1)*a(3, 3)) + &
1099 a(1, 3)*(a(2, 1)*a(3, 2) - a(2, 2)*a(3, 1))
1101 END FUNCTION det_3x3
1108 FUNCTION get_atomic_mass(element_symbol)
RESULT(amass)
1111 CHARACTER(LEN=*),
INTENT(IN) :: element_symbol
1112 REAL(kind=dp) :: amass
1114 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_atomic_mass'
1116 SELECT CASE (trim(element_symbol))
1120 amass = 238.02891_dp
1122 CALL abort_program(routinen,
"Unknown element symbol found")
1125 amass = amass*massunit
1127 END FUNCTION get_atomic_mass
1135 SUBROUTINE invert_matrix_3x3(h, hinv, deth)
1138 REAL(kind=dp),
DIMENSION(3, 3),
INTENT(IN) :: h
1139 REAL(kind=dp),
DIMENSION(3, 3),
INTENT(OUT) :: hinv
1140 REAL(kind=dp),
INTENT(OUT) :: deth
1142 CHARACTER(LEN=*),
PARAMETER :: routinen =
'invert_matrix_3x3'
1148 IF (deth < 1.0e-10_dp)
THEN
1149 CALL abort_program(routinen,
"Invalid h matrix for cell found; det(h) < 1.0E-10")
1152 hinv(1, 1) = (h(2, 2)*h(3, 3) - h(3, 2)*h(2, 3))/deth
1153 hinv(2, 1) = (h(2, 3)*h(3, 1) - h(3, 3)*h(2, 1))/deth
1154 hinv(3, 1) = (h(2, 1)*h(3, 2) - h(3, 1)*h(2, 2))/deth
1156 hinv(1, 2) = (h(1, 3)*h(3, 2) - h(3, 3)*h(1, 2))/deth
1157 hinv(2, 2) = (h(1, 1)*h(3, 3) - h(3, 1)*h(1, 3))/deth
1158 hinv(3, 2) = (h(1, 2)*h(3, 1) - h(3, 2)*h(1, 1))/deth
1160 hinv(1, 3) = (h(1, 2)*h(2, 3) - h(2, 2)*h(1, 3))/deth
1161 hinv(2, 3) = (h(1, 3)*h(2, 1) - h(2, 3)*h(1, 1))/deth
1162 hinv(3, 3) = (h(1, 1)*h(2, 2) - h(2, 1)*h(1, 2))/deth
1164 END SUBROUTINE invert_matrix_3x3
1170 SUBROUTINE lowercase(string)
1172 CHARACTER(LEN=*),
INTENT(INOUT) :: string
1174 INTEGER :: i, iascii
1176 DO i = 1, len_trim(string)
1177 iascii = ichar(string(i:i))
1178 IF ((iascii >= 65) .AND. (iascii <= 90))
THEN
1179 string(i:i) = char(iascii + 32)
1183 END SUBROUTINE lowercase
1203 SUBROUTINE pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta, gamma, debug, info, pbc0, h, hinv)
1212 REAL(kind=sp),
DIMENSION(:, :),
INTENT(IN) :: r
1213 REAL(kind=dp),
DIMENSION(:, :),
INTENT(OUT) :: r_pbc, s, s_pbc
1214 REAL(kind=dp),
INTENT(IN) :: a, b, c, alpha, beta,
gamma
1215 LOGICAL,
INTENT(IN) :: debug, info, pbc0
1216 REAL(kind=dp),
DIMENSION(3, 3),
INTENT(OUT) :: h, hinv
1218 CHARACTER(LEN=*),
PARAMETER :: routinen =
'pbc'
1221 LOGICAL :: orthorhombic
1222 REAL(kind=dp) :: deth
1225 IF (
SIZE(r, 2) /= 3)
CALL abort_program(routinen,
"Array dimension for r must be 3")
1231 IF ((abs(alpha - 90.0_dp) < epsilon(0.0_dp)) .AND. &
1232 (abs(beta - 90.0_dp) < epsilon(0.0_dp)) .AND. &
1233 (abs(
gamma - 90.0_dp) < epsilon(0.0_dp)))
THEN
1234 orthorhombic = .true.
1239 orthorhombic = .false.
1240 CALL build_h_matrix(a, b, c, alpha, beta,
gamma, h)
1245 CALL invert_matrix_3x3(h, hinv, deth)
1248 WRITE (unit=error_unit, fmt=
"(A)")
"#"
1249 IF (orthorhombic)
THEN
1250 WRITE (unit=error_unit, fmt=
"(A)")
"# Cell symmetry : orthorhombic"
1252 WRITE (unit=error_unit, fmt=
"(A)")
"# Cell symmetry : non-orthorhombic"
1255 WRITE (unit=error_unit, fmt=
"(A)")
"#"
1256 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# / ", h(1, :),
" \"
1257 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# h = | ", h(2, :),
" |"
1258 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# \ ", h(3, :),
" /"
1259 WRITE (unit=error_unit, fmt=
"(A)")
"#"
1260 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# / ", hinv(1, :),
" \"
1261 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# Inv(h) = | ", hinv(2, :),
" |"
1262 WRITE (unit=error_unit, fmt=
"(A,3F12.6,A)")
"# \ ", hinv(3, :),
" /"
1263 WRITE (unit=error_unit, fmt=
"(A)")
"#"
1264 WRITE (unit=error_unit, fmt=
"(A,F0.6)")
"# det(h) = ", deth
1269 IF (orthorhombic)
THEN
1272 s(:, i) = r(:, i)*hinv(i, i)
1275 s(:, :) = matmul(r(:, :), transpose(hinv(:, :)))
1279 s_pbc(:, :) = s(:, :) - anint(s(:, :))
1281 s_pbc(:, :) = s(:, :) - floor(s(:, :))
1284 IF (orthorhombic)
THEN
1286 r_pbc(:, i) = s_pbc(:, i)*h(i, i)
1289 r_pbc(:, :) = matmul(s_pbc(:, :), transpose(h(:, :)))
1297 SUBROUTINE print_help()
1301 WRITE (unit=*, fmt=
"(T2,A)") &
1303 "Program flags for "//trim(version_info)//
":", &
1305 " -cell_file, -cell : Input file with cell information in CP2K format (.cell)", &
1306 " -debug, -d : Print debug information", &
1307 " -ekin : Dump just the ""temperature"" of each atom", &
1308 " -eformat : Print coordinates in scientific format", &
1309 " -eo : Write standard output and standard error to the same logical unit", &
1310 " -first_frame, -ff <int> : Number of the first frame which is dumped", &
1311 " -help, -h : Print this information", &
1312 " -ignore_warnings : Do not print warning messages, e.g. about inconsistencies", &
1313 " -info, -i : Print additional information for each frame (see also -debug flag)", &
1314 " -last_frame, -lf <int> : Number of the last frame which is dumped", &
1315 " -md_time_step <real> : Use this MD time step instead of the one from the DCD header", &
1316 " -output, -o <file_name> : Name of the output file (default is stdout)", &
1317 " -output_format, -of <DCD|XMOL> : Output format for dump", &
1318 " -pbc : Apply the periodic boundary conditions (PBC) to each frame before it is dumped", &
1319 " (origin at lower left)", &
1320 " -pbc0 : Apply the periodic boundary conditions (PBC) to each frame before it is dumped", &
1321 " (origin at box centre)", &
1322 " -stride <int> : Stride for frame dump (allows to skip frames, e.g. by dumping each 10th frame)", &
1323 " -trace_atoms <real> : Print atoms which left the simulation box given a threshold value in scaled units", &
1324 " -vel2cord, -v2c : Dump a VELocity DCD file as COoRDinate DCD file (hack which allows a digest by VMD)", &
1325 " -xyz_file, -xyz <file_name> : Name of a reference XYZ file in XMOL format that provides the atomic labels", &
1328 WRITE (unit=*, fmt=
"(T2,A)") &
1329 "Usage examples:", &
1331 " dumpdcd <optional flags> <DCD file(s)>", &
1333 "Specific usage examples:", &
1335 " dumpdcd project-pos-1.dcd (without atomic labels from XYZ file)", &
1336 " dumpdcd -xyz project.xyz project-pos-1.dcd (single DCD file)", &
1337 " dumpdcd -xyz project.xyz project-pos-1.dcd project-pos-2.dcd ... (multiple DCD files are dumped consecutively)", &
1338 " dumpdcd -xyz project.xyz -cell_file project-1.cell -of xmol project-pos-1.dcd (check and print cell parameters in ", &
1339 " XMOL comment line, e.g. for TRAVIS, instead of the default REFTRAJ information)", &
1340 " dumpdcd -info -xyz project.xyz project-pos-1.dcd project-pos-2.dcd (print additional information)", &
1341 " dumpdcd -debug -xyz project.xyz project-pos-1.dcd project-pos-2.dcd (print debug information)", &
1342 " dumpdcd -ekin -d -xyz project.xyz project-vel-1.dcd (print the ""temperature"" of each atom)", &
1343 " dumpdcd -ekin -xyz project.xyz project-vel-1.dcd (print just the temperature of each atom)", &
1344 " dumpdcd -first_frame 5 -last_frame 10 project-pos-1.dcd (just dump frame 5 to 10, ie. 6 frames in total)", &
1345 " dumpdcd -o outfile.xyz project-pos-1.dcd (write output to the file ""outfile.xyz"" instead of stdout)", &
1346 " dumpdcd -o test.xyz -output_format xmol -xyz ref.xyz -first 10 -last 10 test.dcd (dump 10th frame in XMOL format)", &
1347 " 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)", &
1348 " 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)", &
1349 " dumpdcd -o part.dcd -of dcd -first 10 -lf 100 -stride 10 test.dcd (dump the frames 10,..., 100 to the file part.dcd)", &
1350 " dumpdcd -output new.dcd -output_format dcd -pbc old.dcd (dump all frames applying PBC to the output file new.dcd)", &
1351 " dumpdcd -o new.dcd -of dcd -pbc -trace_atoms 0.02 old.dcd (all atoms more than 2% out of the box are listed)", &
1352 " 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)", &
1353 " 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)", &
1354 " 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)", &
1355 " dumpdcd -i -disp project-pos-1.dcd (dump the displacements of all atoms w.r.t. their positions in the first frame)", &
1356 " dumpdcd -i -of dcd -disp project-pos-1.dcd (dump the atomic displacements as x-coordinates of a DCD CORD file)", &
1357 " dumpdcd -i -of dcd -ekin -v2c -xyz project.xyz project-vel-1.dcd (dump the atomic temperatures as x-coordinates of a ", &
1358 " DCD CORD file -> hack for VMD)", &
1361 WRITE (unit=*, fmt=
"(T2,A)") &
1364 " - For -ekin a XYZ file is required to obtain the atomic labels", &
1365 " - The -info and the -debug flags provide a more detailed output which is especially handy for tracing problems", &
1366 " - The output in DCD format is in binary format", &
1367 " - The input coordinates should be in Angstrom. Velocities and forces are expected to be in atomic units", &
1370 END SUBROUTINE print_help
1376 SUBROUTINE uppercase(string)
1379 CHARACTER(LEN=*),
INTENT(INOUT) :: string
1381 INTEGER :: i, iascii
1383 DO i = 1, len_trim(string)
1384 iascii = ichar(string(i:i))
1385 IF ((iascii >= 97) .AND. (iascii <= 122))
THEN
1386 string(i:i) = char(iascii - 32)
1390 END SUBROUTINE uppercase
1400 SUBROUTINE write_out_of_box_atoms(atomic_label, r, s, eps_out_of_box, h)
1403 CHARACTER(LEN=5),
DIMENSION(:),
INTENT(IN) :: atomic_label
1404 REAL(kind=sp),
DIMENSION(:, :),
INTENT(IN) :: r
1405 REAL(kind=dp),
DIMENSION(:, :),
INTENT(IN) :: s
1406 REAL(kind=dp),
INTENT(IN) :: eps_out_of_box
1407 REAL(kind=dp),
DIMENSION(3, 3),
INTENT(IN) :: h
1409 INTEGER :: i, iatom, natom, ncount
1410 REAL(kind=dp) :: rl, s_max, s_min, sl
1411 REAL(kind=dp),
DIMENSION(3) :: dr, ds
1414 IF (eps_out_of_box <= 0.0_dp)
RETURN
1416 s_max = 1.0_dp + eps_out_of_box
1417 s_min = -eps_out_of_box
1421 IF (any(s(iatom, :) < s_min) .OR. &
1422 any(s(iatom, :) > s_max))
THEN
1424 IF (ncount == 1)
THEN
1425 WRITE (unit=error_unit, fmt=
"(A)") &
1427 "# Atoms out of box:", &
1428 "# Atom index label x y z |dr| |ds|"
1432 IF (s(iatom, i) < 0.0_dp) ds(i) = 0.0_dp
1433 IF (s(iatom, i) >= 1.0_dp) ds(i) = 1.0_dp
1435 ds(:) = s(iatom, :) - ds(:)
1436 sl = sqrt(ds(1)**2 + ds(2)**2 + ds(3)**2)
1437 dr(:) = matmul(h(:, :), ds(:))
1438 rl = sqrt(dr(1)**2 + dr(2)**2 + dr(3)**2)
1439 WRITE (unit=error_unit, fmt=
"(A,I10,1X,A5,5(1X,F14.6))") &
1440 "# ", iatom, adjustr(atomic_label(iatom)), r(iatom, :), rl, sl
1443 WRITE (unit=error_unit, fmt=
"(A,I0,A)")
"# ", ncount,
" atom(s) out of box"
1445 END SUBROUTINE write_out_of_box_atoms
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...